From c57d912a479a1b33b1c326a7ae43be39b4b40001 Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Mon, 14 Sep 2026 08:52:39 +0200 Subject: [PATCH 1/2] Retire the superseded Custom Local API, and send queued bytes verbatim Nineteen of LocalController's thirty-one routes had no caller anywhere in src/ and had been documented as deprecated for a release: the eight /api/v1/stream/* and /account/{username}/stream timelines, the two /local/v1/post reads, the like pair, /current/info, /current/followers and /following, /account/summary, /global/actor/info and /header, and /local/v1/search. They go, and with them the whole query layer only they used -- the nine StreamService::getStream*() methods and the seven StreamRequest::getTimeline*_dep() / getTimelineLiked() / getTimelineTag() queries, which were also the last timeline reads on the wide SELECT DISTINCT -- plus six constructor dependencies LocalController no longer touches. docs/API.md keeps the table of what replaced each route, as the release note. The twelve routes the frontend does call stay. Delivery also stops re-encoding what it sends. bodyFromQueue() returned json_encode(json_decode($activity)), which defeated ForwardService on purpose: it queues a third party's getSource() verbatim so their Linked Data signature still verifies on arrival, and re-encoding is exactly what breaks such a signature. What this instance writes itself is encoded once at queue time, so nothing it sends changes; the digest covers the same bytes. ActivityServiceTest now asserts the body byte for byte. Signed-off-by: Frank Karlitschek Co-Authored-By: Claude Fable 5.1 --- docs/API.md | 53 +-- docs/Technical-Debt.md | 45 ++- lib/Controller/ApiController.php | 2 +- lib/Controller/LocalController.php | 434 ----------------------- lib/Db/StreamRequest.php | 196 ---------- lib/Service/ActivityService.php | 14 +- lib/Service/FollowService.php | 10 +- lib/Service/StreamService.php | 113 ------ tests/Controller/LocalControllerTest.php | 309 ++-------------- tests/Service/ActivityServiceTest.php | 7 +- tests/Service/StreamServiceTest.php | 15 - 11 files changed, 74 insertions(+), 1124 deletions(-) diff --git a/docs/API.md b/docs/API.md index d9a708bf5..2f318c8f6 100644 --- a/docs/API.md +++ b/docs/API.md @@ -17,13 +17,16 @@ None of these are OCS routes: `#[ApiRoute]` would put them under `/ocsapp`, whic `GET /api/v1/accounts/{id}` is the one route still declared in `appinfo/routes.php`. Its `{id}` accepts slashes, so it also matches `/api/v1/accounts/{account}/lists` and `/api/v1/accounts/{account}/featured_tags`, and it has to be offered to the matcher after them; those two belong to other controllers, and attribute routes are contributed one controller at a time in filesystem order. The array file is loaded after every attribute route of the app, which is the guarantee that route needs. -### Deprecated: the superseded half of the Custom Local API +### Removed: the superseded half of the Custom Local API -The Custom Local API predates the Mastodon-compatible one, and the frontend has -moved off most of it. Eighteen of `LocalController`'s thirty-one routes now have -no caller anywhere in `src/`: +The Custom Local API predates the Mastodon-compatible one, and the frontend +moved off most of it. Nineteen of `LocalController`'s thirty-one routes had no +caller anywhere in `src/` and were documented here as deprecated for a release; +**as of 0.19.39 they are gone**, and with them the `getStream*()` / +`getTimeline*_dep()` query layer that only they used. A caller of one of these +gets a 404 and should move to the Mastodon route beside it: -| Deprecated | Use instead | +| Removed | Use instead | |---|---| | `GET /api/v1/stream/home` | `GET /api/v1/timelines/home` | | `GET /api/v1/stream/timeline` | `GET /api/v1/timelines/public?local=true` | @@ -32,6 +35,7 @@ no caller anywhere in `src/`: | `GET /api/v1/stream/direct` | `GET /api/v1/conversations` | | `GET /api/v1/stream/liked` | `GET /api/v1/favourites` | | `GET /api/v1/stream/notifications` | `GET /api/v1/notifications` | +| `GET /api/v1/account/{username}/stream` | `GET /api/v1/accounts/{account}/statuses` | | `GET /local/v1/post`, `GET /local/v1/post/replies` | `GET /api/v1/statuses/{nid}`, `…/context` | | `POST`/`DELETE /api/v1/post/like` | `POST /api/v1/statuses/{nid}/favourite`, `…/unfavourite` | | `GET /api/v1/current/info` | `GET /api/v1/accounts/verify_credentials` | @@ -41,15 +45,10 @@ no caller anywhere in `src/`: | `PUT /api/v1/account/summary` | `PATCH /api/v1/accounts/update_credentials` | | `GET /local/v1/search` | `GET /api/v2/search` | -They still work and are still listed in the tables below. They are documented as -deprecated rather than removed because they are a published surface; nothing in -this app calls them, so the replacement column is what a caller should move to. - -The thirteen that the frontend still uses -- the banner uploads, the +The twelve that the frontend still uses -- the banner uploads, the `global/account` and `global/tags` searches, the profile field and avatar -endpoints, `POST`/`DELETE /api/v1/post`, `/api/v1/current/follow` and -`/api/v1/account/{username}/stream` -- have no Mastodon equivalent yet and are -not deprecated. +endpoints, `POST`/`DELETE /api/v1/post` and `/api/v1/current/follow` -- have no +Mastodon equivalent yet and stay. --- @@ -126,7 +125,7 @@ A `Relationship` carries `id` as a **string**, like every other id on the wire: | Method | Route | Auth | Parameters | Description | |--------|-------|------|------------|-------------| -| GET | `/api/v1/search` | public, no-csrf (viewer required) | `q` (required), `type`, `limit` (20, capped at 40), `resolve` | Mastodon's v1 search; identical to `/api/v2/search`, which it delegates to. This path used to be the app's own web-UI search, which answered a client with a Nextcloud envelope and a `content` key — a 200 a client could make nothing of. That search moved to `/local/v1/search`. | +| GET | `/api/v1/search` | public, no-csrf (viewer required) | `q` (required), `type`, `limit` (20, capped at 40), `resolve` | Mastodon's v1 search; identical to `/api/v2/search`, which it delegates to. This path used to be the app's own web-UI search, which answered a client with a Nextcloud envelope and a `content` key — a 200 a client could make nothing of. That search moved to `GET /local/v1/search`. | | GET | `/api/v2/search` | public, no-csrf (viewer required) | `q` (required), `type` (`accounts`/`statuses`/`hashtags`, empty = all), `limit` (20, capped at 40), `resolve` | Mastodon's search entity: `accounts` (URI + name search over cached actors), `statuses` (the viewer-bounded full-text search), `hashtags` (Tag entities with an empty `history`). `resolve` asks the server to go and get something it has never seen, which is how a reader who pasted a link to a remote post can reply to it or boost it here at all. It only ever fires for a `q` that is an `http(s)` address and only when the local search found nothing; the document fetched has to claim the very address it was fetched from (a document is evidence about itself and nothing else) and has to be a `Note` or a `Question`, or it is refused and the answer is empty. The author is cached before the post is stored, so it renders as theirs. An account named by its actor URL is resolved whether or not `resolve` is set — that predates this parameter. The route requires a viewer, so no anonymous caller can use it to make this instance fetch for them, and it is rate-limited both per user and per anonymous caller. Pagination offsets are accepted but ignored. Rate-limited per user and per anonymous caller. | ### Statuses @@ -507,7 +506,6 @@ Every key of a `MediaAttachment` is always present, `null` when there is nothing | Method | Route | Auth | Parameters | Description | |--------|-------|------|------------|-------------| -| GET | `/local/v1/search` | user, no-csrf | `search` (required) | `{"result": {"accounts": [...], "hashtags": [...], "content": [...]}, "status": 1}` — the app's own web-UI search. It used to sit on `/api/v1/search`, where a Mastodon client got a 200 in a shape it could make nothing of; that path is now Mastodon's v1 search. The app's frontend does not call this route: `Search.vue` uses `/api/v2/search`. | | GET | `/api/v1/global/accounts/search` | user | `search` (required) | `{"result": {"accounts": [...], "exact": }, "status": 1}`. A leading `@` is stripped; an empty query returns empty lists. | | GET | `/api/v1/global/tags/search` | user | `search` (required) | `{"result": {"tags": [...], "exact": }, "status": 1}`. A leading `#` is stripped. | @@ -534,31 +532,12 @@ Link: , "token": ""}, "status": 1}`. | | DELETE | `/api/v1/post` | user | `id` (required) | Deletes an own post; `{"result": [], "status": 1}`. Rejects posts not attributed to the caller. | -| POST | `/api/v1/post/like` | user | `postId` (required) | Likes a post; `{"result": {"like": , "token": "…"}, "status": 1}`. | -| DELETE | `/api/v1/post/like` | user | `postId` (required) | Removes the like; same shape. | Boosting from a client goes through `POST /api/v1/statuses/{nid}/{act}` with `reblog`. @@ -566,11 +545,7 @@ Boosting from a client goes through `POST /api/v1/statuses/{nid}/{act}` with `re | Method | Route | Auth | Parameters | Description | |--------|-------|------|------------|-------------| -| GET | `/api/v1/current/info` | user | — | `{"result": {"account": }, "status": 1}`; refreshes the local actor cache first. | -| GET | `/api/v1/current/followers` | user | — | `{"result": [actors], "status": 1}`. At most 500 of them: the route takes no cursor, so there is nothing to page with, and an account with more followers than that would otherwise load every one of them into a single request. Superseded by `/api/v1/accounts/{account}/followers`, which pages. | -| GET | `/api/v1/current/following` | user | — | `{"result": [actors], "status": 1}`. | | PUT | `/api/v1/account/fields` | user | `fields` (list of `{name, value}`) | Replaces the profile metadata fields (at most four name/value pairs; entries with an empty half are dropped, names capped at 255 and values at 500 characters). Federated as `PropertyValue` attachments on the actor. `{"result": {"account": }, "status": 1}`. | -| PUT | `/api/v1/account/summary` | user | `summary` (string, default `''`) | Replaces the bio. It is stored as **plain text, exactly as it was typed**, and cut to 500 characters (Mastodon's limit), counted in characters rather than bytes. Nothing is stripped on the way in: every path that renders it escapes it, so a stripping pass had nothing to protect and a great deal to break — `strip_tags()` reads a bare `<` as the start of a tag and eats the rest of the line, which turned `Maths: ac` into `Maths: ac`. The actor document carries it as HTML in `summary`, the account entity as HTML in `note` and as the stored plain text in `source.note`, and an `Update{Person}` goes out to the followers. `{"result": {"account": }, "status": 1}`. | | PUT | `/api/v1/current/follow` | user | `account` (required) | Follows an account; `{"result": [], "status": 1}`. | | DELETE | `/api/v1/current/follow` | user | `account` (required) | Unfollows an account; `{"result": [], "status": 1}`. | @@ -580,9 +555,7 @@ Boosting from a client goes through `POST /api/v1/statuses/{nid}/{act}` with `re |--------|-------|------|------------|-------------| | GET | `/api/v1/account/{username}/info` | user, public | — | Local account with complete details, returned **unwrapped** as a `Person`; rebuilds the actor cache if it is missing. | | GET | `/api/v1/global/account/info` | user, public | `account` (required, e.g. `user` or `user@domain`) | Local or remote account, returned **unwrapped**. A leading `@` is stripped; remote accounts get follower/following/post counts fetched. A local actor is created on demand only when the logged-in viewer asks about their **own** account — the route is public, so creating for anyone would let anonymous visitors force a Fediverse identity onto any Nextcloud user. Rate-limited: 10 per five minutes anonymously, 120 per minute per user, because a handle this instance has never seen costs a host-meta, a WebFinger and four signed actor fetches against a host the caller names. | -| GET | `/api/v1/global/actor/info` | user, public | `id` (required, ActivityPub actor id) | `{"result": {"actor": }, "status": 1}`. | | GET | `/api/v1/global/actor/avatar` | user, public, no-csrf | `id` (required) | Streams the cached avatar with a 24 h cache header; 404 (envelope shape) when the actor has no icon. | -| GET | `/api/v1/global/actor/header` | user, public, no-csrf | `id` (required) | HTTP **redirect** to the actor's header URL, 24 h cache; 404 when unset. | The followers and following lists of an arbitrary account are reachable through the Mastodon-compatible `/api/v1/accounts/{account}/followers` and `/api/v1/accounts/{account}/following`. diff --git a/docs/Technical-Debt.md b/docs/Technical-Debt.md index 47a8a62a3..75762f5c8 100644 --- a/docs/Technical-Debt.md +++ b/docs/Technical-Debt.md @@ -33,8 +33,6 @@ JavaScript and Vue across 81 files in `src/`. | Theme | Severity | Size | |---|---|---| -| The superseded half of the Custom Local API | Medium | 18 routes | -| Delivery re-encodes the bytes it was asked to preserve | Medium | 1 call | | Translation catalogue covers under 40 % of source strings | Low | — | | PHPUnit 12 | Low | ~3,100 stub migrations | @@ -92,13 +90,14 @@ So `/api/v1/stream/home` (local: `since`/`limit` cursor, default page size 5, no `/api/v1/timelines/home` (Mastodon: `max_id`/`since_id`, page size 20, `Link` header, bare entity). -**18 of `LocalController`'s 31 routes have no caller anywhere in `src/`**, -including all seven `/api/v1/stream/*` endpoints — the ones still backed by the -`_dep` query methods. They are marked deprecated in [API.md](API.md) with the Mastodon route -to use instead, and kept rather than removed because they are a published -surface. Retiring them retires that whole query layer; it needs a deprecation -cycle and a release note, which is a decision about the app's compatibility -promise rather than a cleanup. +**Nineteen of `LocalController`'s 31 routes had no caller anywhere in `src/`**, +including all eight `/api/v1/stream/*` and `/account/{username}/stream` +endpoints — the ones backed by the `_dep` query methods. They were marked +deprecated in [API.md](API.md) for a release and are **removed in 0.19.39**, +with the whole query layer behind them: the nine `StreamService::getStream*()` +methods and the seven `StreamRequest::getTimeline*_dep()` / `getTimelineLiked()` +/ `getTimelineTag()` queries. API.md keeps the table of what replaced them. The +twelve routes the frontend does call stay. ### Routes are attributes now @@ -363,6 +362,14 @@ sixty when twenty survive the check. ### Since then +- **Delivery sends the stored bytes** (0.19.39). `ActivityService::bodyFromQueue()` + returned `json_encode(json_decode(...))`; it returns the queued string. What + this instance writes is encoded once at queue time, so nothing it sends + changes; what `ForwardService` queues verbatim now arrives verbatim, which is + the only way a third party's Linked Data signature survives. +- **The superseded Custom Local API is gone** (0.19.39): nineteen routes, the + nine `getStream*()` methods and the seven `_dep` queries, and their tests. + | Item | Outcome | |---|---| | ESLint 8 (end of life) | [#2129](https://github.com/nextcloud/social/pull/2129): ESLint 10, `@nextcloud/eslint-config` 9, flat config. | @@ -401,21 +408,11 @@ sixty when twenty survive the check. ## Rough order of value for what is left -1. **Send a queued activity's stored bytes.** Delivery decodes and re-encodes - the activity it queued, which defeats `ForwardService` on purpose-built - input: that service queues `getSource()` precisely so a third party's - signature survives, and the transport re-encodes it anyway. It is a wire - change, so it wants a real peer to test against. -2. **Retire the 18 uncalled Custom Local API routes**, and the five - `getStream*()` / `getTimeline*_dep()` methods with them. A decision rather - than a task: they are a published surface, so either the URLs go with a - release note, or they stay and are re-pointed at the modern query path, - which changes their paging semantics. -3. Collapse the two cache-actor joins, with a database to check against. -4. Finish the l10n round trip — a Transifex round trip, not a code change. -5. `vue-tsc`, so the single-file components are type-checked too. -6. PHPUnit 12, which means `createMock` -> `createStub` across the suite. -7. The last migration squash candidate, if an instance upgrading from 0.15 is +1. Collapse the two cache-actor joins, with a database to check against. +2. Finish the l10n round trip — a Transifex round trip, not a code change. +3. `vue-tsc`, so the single-file components are type-checked too. +4. PHPUnit 12, which means `createMock` -> `createStub` across the suite. +5. The last migration squash candidate, if an instance upgrading from 0.15 is no longer a case worth supporting. --- diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php index 3372b35c1..5ff8d843b 100644 --- a/lib/Controller/ApiController.php +++ b/lib/Controller/ApiController.php @@ -2199,7 +2199,7 @@ public function accountUnfollow(string $id): DataResponse { * Nextcloud envelope, `content` where a client looks for `statuses`, `search=` * where a client sends `q=`, and no bearer token accepted — so a client got * a 200 it could make no sense of, which is worse than a 404. The web UI's - * own search now lives at `/local/v1/search`, beside its siblings. + * own search goes through `/api/v2/search` like any client's. */ #[PublicPage] #[NoCSRFRequired] diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index 2477b975b..709c39084 100644 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -27,20 +27,14 @@ use OCA\Social\Model\Post; use OCA\Social\Security\RemoteAddress; use OCA\Social\Service\AccountService; -use OCA\Social\Service\ActivityService; -use OCA\Social\Service\ActorService; use OCA\Social\Service\BannerService; -use OCA\Social\Service\BoostService; use OCA\Social\Service\CacheActorService; use OCA\Social\Service\CacheDocumentService; use OCA\Social\Service\ConfigService; use OCA\Social\Service\DocumentService; use OCA\Social\Service\FollowService; use OCA\Social\Service\HashtagService; -use OCA\Social\Service\LikeService; -use OCA\Social\Service\MiscService; use OCA\Social\Service\PostService; -use OCA\Social\Service\SearchService; use OCA\Social\Service\StreamService; use OCA\Social\Tools\Traits\TArrayTools; use OCA\Social\Tools\Traits\TNCDataResponse; @@ -54,7 +48,6 @@ use OCP\AppFramework\Http\Attribute\UserRateLimit; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\FileDisplayResponse; -use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\Response; use OCP\IRequest; use OCP\Util; @@ -85,15 +78,9 @@ public function __construct( private FollowService $followService, private PostService $postService, private StreamService $streamService, - private SearchService $searchService, - private BoostService $boostService, - private LikeService $likeService, private DocumentService $documentService, - private MiscService $miscService, private ConfigService $configService, private LoggerInterface $logger, - private ActorService $actorService, - private ActivityService $activityService, private CacheDocumentService $cacheDocumentService, private BannerService $bannerService, ) { @@ -384,51 +371,6 @@ public function postCreate(string $content = '', array $to = [], ?string $type = } } - /** - * Get info about a post (limited to viewer rights). - * - */ - #[NoAdminRequired] - #[PublicPage] - #[NoCSRFRequired] - #[FrontpageRoute(verb: 'GET', url: '/local/v1/post')] - public function postGet(string $id): DataResponse { - $this->logger->debug('[LocalController] postGet called', ['id' => $id]); - try { - $this->initViewer(false); - $stream = $this->streamService->getStreamById($id, true); - $this->logger->debug('[LocalController] Post retrieved', [ - 'id' => $id, - 'streamId' => $stream->getId() - ]); - - return $this->directSuccess($stream); - } catch (Exception $e) { - $this->logger->error('[LocalController] postGet failed', [ - 'id' => $id, - 'exception' => $e->getMessage() - ]); - return $this->fail($e); - } - } - - /** - * Get replies about a post (limited to viewer rights). - * - */ - #[NoAdminRequired] - #[NoCSRFRequired] - #[FrontpageRoute(verb: 'GET', url: '/local/v1/post/replies')] - public function postReplies(string $id, int $since = 0, int $limit = 5): DataResponse { - try { - $this->initViewer(true); - - return $this->success($this->streamService->getRepliesByParentId($id, $since, $limit, true)); - } catch (Exception $e) { - return $this->fail($e); - } - } - /** * Delete your own post. * @@ -458,217 +400,6 @@ public function postDelete(string $id): DataResponse { } } - /** - * Like a post. - * - */ - #[NoAdminRequired] - #[FrontpageRoute(verb: 'POST', url: '/api/v1/post/like')] - public function postLike(string $postId): DataResponse { - try { - $this->initViewer(true); - $token = ''; - $announce = $this->likeService->create($this->viewer, $postId, $token); - - return $this->success( - [ - 'like' => $announce, - 'token' => $token - ] - ); - } catch (Exception $e) { - return $this->fail($e); - } - } - - /** - * Unlike a post. - * - */ - #[NoAdminRequired] - #[FrontpageRoute(verb: 'DELETE', url: '/api/v1/post/like')] - public function postUnlike(string $postId): DataResponse { - try { - $this->initViewer(true); - $token = ''; - $like = $this->likeService->delete($this->viewer, $postId, $token); - - return $this->success( - [ - 'like' => $like, - 'token' => $token - ] - ); - } catch (Exception $e) { - return $this->fail($e); - } - } - - #[NoCSRFRequired] - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/stream/home')] - public function streamHome(int $since = 0, int $limit = 5): DataResponse { - $this->logger->debug('[LocalController] streamHome called', [ - 'since' => $since, - 'limit' => $limit, - 'userId' => $this->userId - ]); - try { - $this->initViewer(true); - $posts = $this->streamService->getStreamHome($since, $limit); - $this->logger->debug('[LocalController] streamHome returned', [ - 'postsCount' => count($posts) - ]); - - return $this->success($posts); - } catch (Exception $e) { - $this->logger->error('[LocalController] streamHome failed', [ - 'exception' => $e->getMessage() - ]); - return $this->fail($e); - } - } - - #[NoCSRFRequired] - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/stream/notifications')] - public function streamNotifications(int $since = 0, int $limit = 5): DataResponse { - try { - $this->initViewer(true); - $posts = $this->streamService->getStreamNotifications($since, $limit); - - return $this->success($posts); - } catch (Exception $e) { - return $this->fail($e); - } - } - - /** - * A profile timeline, which first asks the account's own server for its outbox. - * - * Anyone may call this and the handle names the server that is fetched, so the - * throttle has to be real: without it one anonymous request per second keeps a - * worker busy fetching from, and ingesting into, whatever host the caller picked. - */ - #[NoAdminRequired] - #[PublicPage] - #[AnonRateLimit(limit: 30, period: 60)] - #[UserRateLimit(limit: 300, period: 60)] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/account/{username}/stream', requirements: ['username' => '.+'])] - public function streamAccount(string $username, int $since = 0, int $limit = 5): DataResponse { - try { - $this->initViewer(); - - $account = $this->cacheActorService->getFromAccount($username); - // Best-effort: a slow or unreachable remote must not fail the profile - // view — it falls back to whatever is already cached. - try { - $this->streamService->syncRemoteTimeline($account); - } catch (\Exception $e) { - $this->logger->debug('[LocalController] outbox sync skipped', ['exception' => $e]); - } - $posts = $this->streamService->getStreamAccount($account->getId(), $since, $limit); - - return $this->success($posts); - } catch (Exception $e) { - return $this->fail($e); - } - } - - #[NoAdminRequired] - #[NoCSRFRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/stream/direct')] - public function streamDirect(int $since = 0, int $limit = 5): DataResponse { - try { - $this->initViewer(true); - $posts = $this->streamService->getStreamDirect($since, $limit); - - return $this->success($posts); - } catch (Exception $e) { - return $this->fail($e); - } - } - - /** - * Get timeline - * - */ - #[NoAdminRequired] - #[NoCSRFRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/stream/timeline')] - public function streamTimeline(int $since = 0, int $limit = 5): DataResponse { - $this->logger->debug('[LocalController] streamTimeline called', [ - 'since' => $since, - 'limit' => $limit, - 'userId' => $this->userId - ]); - try { - $this->initViewer(true); - $posts = $this->streamService->getStreamLocalTimeline($since, $limit); - $this->logger->debug('[LocalController] streamTimeline returned', [ - 'postsCount' => count($posts) - ]); - - return $this->success($posts); - } catch (Exception $e) { - $this->logger->error('[LocalController] streamTimeline failed', [ - 'exception' => $e->getMessage() - ]); - return $this->fail($e); - } - } - - /** - * Get timeline - * - */ - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/stream/tag/{hashtag}/')] - public function streamTag(string $hashtag, int $since = 0, int $limit = 5): DataResponse { - try { - $this->initViewer(true); - $posts = $this->streamService-> getStreamLocalTag($hashtag, $since, $limit); - - return $this->success($posts); - } catch (Exception $e) { - return $this->fail($e); - } - } - - /** - * Get timeline - * - */ - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/stream/federated')] - public function streamFederated(int $since = 0, int $limit = 5): DataResponse { - try { - $this->initViewer(true); - $posts = $this->streamService->getStreamGlobalTimeline($since, $limit); - - return $this->success($posts); - } catch (Exception $e) { - return $this->fail($e); - } - } - - /** - * Get liked post - * - */ - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/stream/liked')] - public function streamLiked(int $since = 0, int $limit = 5): DataResponse { - try { - $this->initViewer(true); - $posts = $this->streamService->getStreamLiked($since, $limit); - - return $this->success($posts); - } catch (Exception $e) { - return $this->fail($e); - } - } - #[NoAdminRequired] #[FrontpageRoute(verb: 'PUT', url: '/api/v1/current/follow')] public function actionFollow(string $account): DataResponse { @@ -703,27 +434,6 @@ public function actionUnfollow(string $account): DataResponse { } } - /** - * - * @return DataResponse - */ - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/current/info')] - public function currentInfo(): DataResponse { - try { - if ($this->userId === null) { - throw new AccountDoesNotExistException('User not logged in'); - } - $local = $this->accountService->getActorFromUserId($this->userId); - $this->accountService->cacheLocalActorByUsername($local->getPreferredUsername()); - $actor = $this->cacheActorService->getFromLocalAccount($local->getPreferredUsername()); - - return $this->success(['account' => $actor]); - } catch (Exception $e) { - return $this->fail($e); - } - } - /** * Replace the current user's profile metadata fields (the name/value * table under the bio, at most four entries). @@ -748,69 +458,6 @@ public function accountFields(array $fields = []): DataResponse { } } - /** - * Replace the current user's bio — the text under the display name. - * - * Plain text, at most 500 characters; `AccountService::setSummary()` - * flattens any markup and cuts what is over the limit, then federates the - * change to the followers. - * - * @param string $summary the bio as plain text - */ - #[NoAdminRequired] - #[FrontpageRoute(verb: 'PUT', url: '/api/v1/account/summary')] - public function accountSummary(string $summary = ''): DataResponse { - try { - if ($this->userId === null) { - throw new AccountDoesNotExistException('User not logged in'); - } - $this->accountService->setSummary($this->userId, $summary); - - $local = $this->accountService->getActorFromUserId($this->userId); - $actor = $this->cacheActorService->getFromLocalAccount($local->getPreferredUsername()); - - return $this->success(['account' => $actor]); - } catch (Exception $e) { - return $this->fail($e); - } - } - - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/current/followers')] - public function currentFollowers(): DataResponse { - try { - if ($this->userId === null) { - throw new AccountDoesNotExistException('User not logged in'); - } - $this->initViewer(); - - $actor = $this->accountService->getActorFromUserId($this->userId); - $followers = $this->followService->getFollowers($actor); - - return $this->success($followers); - } catch (Exception $e) { - return $this->fail($e); - } - } - - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/current/following')] - public function currentFollowing(): DataResponse { - try { - if ($this->userId === null) { - throw new AccountDoesNotExistException('User not logged in'); - } - $this->initViewer(); - - $actor = $this->accountService->getActorFromUserId($this->userId); - $following = $this->followService->getFollowing($actor); - - return $this->success($following); - } catch (Exception $e) { - return $this->fail($e); - } - } - #[NoAdminRequired] #[PublicPage] #[FrontpageRoute(verb: 'GET', url: '/api/v1/account/{username}/info')] @@ -913,20 +560,6 @@ public function globalAccountInfo(string $account): DataResponse { } } - #[NoAdminRequired] - #[PublicPage] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/global/actor/info')] - public function globalActorInfo(string $id): DataResponse { - try { - $this->initViewer(); - $actor = $this->knownActor($id); - - return $this->success(['actor' => $actor]); - } catch (Exception $e) { - return $this->fail($e); - } - } - /** * The actor an id names, resolving it remotely only for a caller with a * session. @@ -1001,53 +634,6 @@ public function globalActorAvatar(string $id): Response { } } - #[NoCSRFRequired] - #[NoAdminRequired] - #[PublicPage] - #[FrontpageRoute(verb: 'GET', url: '/api/v1/global/actor/header')] - public function globalActorHeader(string $id): Response { - try { - $actor = $this->knownActor($id); - $headerUrl = $actor->getHeader(); - if ($headerUrl === '') { - throw new InvalidResourceException('no header for this Actor'); - } - - // The value comes from another instance's JSON, and this route lives - // on the Nextcloud origin the user trusts: a redirect to it must not - // be a way to send that user anywhere at all. - $scheme = strtolower((string)parse_url($headerUrl, PHP_URL_SCHEME)); - if (!in_array($scheme, ['http', 'https'], true)) { - throw new InvalidResourceException('unsupported header address'); - } - - // Prefer the copy this instance holds: no redirect off-origin at all, - // and the reader's address is not handed to the remote host. - try { - $mime = ''; - $cached = $this->documentService->getCachedFromUrl($headerUrl, $mime); - $response = new FileDisplayResponse( - $cached, Http::STATUS_OK, ['Content-Type' => $mime === '' ? 'application/octet-stream' : $mime] - ); - $response->cacheFor(86400); - - return $response; - } catch (Exception $e) { - $this->logger->debug('[LocalController] header is not cached locally', [ - 'id' => $actor->getId(), - 'error' => $e->getMessage(), - ]); - } - - $response = new RedirectResponse($headerUrl); - $response->cacheFor(86400); - - return $response; - } catch (Exception $e) { - return $this->fail($e, [], Http::STATUS_NOT_FOUND, false); - } - } - /** * @throws Exception */ @@ -1112,26 +698,6 @@ public function globalTagsSearch(string $search): DataResponse { } } - /** - * TODO - remove this tag - * @throws Exception - */ - #[NoCSRFRequired] - #[NoAdminRequired] - #[FrontpageRoute(verb: 'GET', url: '/local/v1/search')] - public function search(string $search): DataResponse { - $search = trim($search); - $this->initViewer(); - - $result = [ - 'accounts' => $this->searchService->searchAccounts($search), - 'hashtags' => $this->searchService->searchHashtags($search), - 'content' => $this->searchService->searchStreamContent($search) - ]; - - return $this->success($result); - } - /** * @throws AccountDoesNotExistException */ diff --git a/lib/Db/StreamRequest.php b/lib/Db/StreamRequest.php index 54c116992..35d8f58f1 100644 --- a/lib/Db/StreamRequest.php +++ b/lib/Db/StreamRequest.php @@ -1333,36 +1333,6 @@ private function filterMutedConversations(SocialQueryBuilder $qb, string $actorI ); } - /** - * Should return: - * * Own posts, - * * Followed accounts - * - * @param int $since - * @param int $limit - * @param int $format - * - * @return Stream[] - * @throws DateTimeException - * @deprecated - use getTimelineHome() - */ - public function getTimelineHome_dep( - int $since = 0, int $limit = 5, int $format = Stream::FORMAT_ACTIVITYPUB, - ): array { - $qb = $this->getStreamSelectSql($format); - - $qb->filterType(SocialAppNotification::TYPE); - $qb->limitPaginate($since, $limit); - - $qb->limitToViewer('sd', 'f', false); - $this->timelineHomeLinkCacheActor($qb, 'ca', 'f'); - - $qb->leftJoinStreamAction('sa'); - $qb->filterDuplicate(); - - return $this->getStreamsFromRequest($qb); - } - /** * Should return: * * Public/Unlisted/Followers-only post where current $actor is tagged, @@ -1411,78 +1381,6 @@ public function countNotificationsSince(Person $actor, int $sinceNid, int $cap = return $count; } - public function getTimelineNotifications_dep(int $since = 0, int $limit = 5): array { - $qb = $this->getStreamSelectSql(); - - $actor = $qb->getViewer(); - - $qb->limitPaginate($since, $limit); - - $qb->selectDestFollowing('sd', ''); - $qb->limitToDest($actor->getId(), 'notif', '', 'sd'); - $qb->limitToType(SocialAppNotification::TYPE); - - $qb->linkToCacheActors('ca', 's.attributed_to_prim'); - $qb->leftJoinStreamAction(); - - return $this->getStreamsFromRequest($qb); - } - - /** - * Should return: - * * public message from actorId. - * - to followers-only if follower is logged. (not yet (check ?)) - * - * @param string $actorId - * @param int $since - * @param int $limit - * - * @return Stream[] - * @throws DateTimeException - */ - public function getTimelineAccount_dep(string $actorId, int $since = 0, int $limit = 5): array { - $qb = $this->getStreamSelectSql(); - $qb->limitPaginate($since, $limit); - - $qb->limitToAttributedTo($actorId); - - $qb->selectDestFollowing('sd', ''); - $qb->innerJoinStreamDest('recipient', 'id_prim', 'sd', 's'); - $accountIsViewer = ($qb->hasViewer() && $qb->getViewer()->getId() === $actorId); - $qb->limitToDest($accountIsViewer ? '' : ACore::CONTEXT_PUBLIC, 'recipient', '', 'sd'); - - $qb->linkToCacheActors('ca', 's.attributed_to_prim'); - $qb->leftJoinStreamAction(); - - return $this->getStreamsFromRequest($qb); - } - - /** - * Should return: - * * Private message. - * - group messages. (not yet) - * - * @param int $since - * @param int $limit - * - * @return Stream[] - * @throws DateTimeException - */ - public function getTimelineDirect_dep(int $since = 0, int $limit = 5): array { - $qb = $this->getStreamSelectSql(); - - $qb->filterType(SocialAppNotification::TYPE); - $qb->limitPaginate($since, $limit); - - $qb->linkToCacheActors('ca', 's.attributed_to_prim'); - - $viewer = $qb->getViewer(); - $qb->selectDestFollowing('sd', ''); - $qb->limitToDest($viewer->getId(), 'dm', '', 'sd'); - - return $this->getStreamsFromRequest($qb); - } - /** * Should return: * * All local public/federated posts @@ -1594,100 +1492,6 @@ private function getTimelinePublic(ProbeOptions $options): array { return $this->getStreamsFromRequest($qb); } - /** - * Should returns: - * * All local public/federated posts - * - * @param int $since - * @param int $limit - * @param bool $localOnly - * - * @return Stream[] - * @throws DateTimeException - * @deprecated - use getTimelinePublic() - */ - public function getTimelineGlobal_dep(int $since = 0, int $limit = 5, bool $localOnly = true, - ): array { - $qb = $this->getStreamSelectSql(); - $qb->limitPaginate($since, $limit); - - $qb->limitToLocal($localOnly); - $qb->limitToStatusTypes(); - - $qb->linkToCacheActors('ca', 's.attributed_to_prim'); - $qb->leftJoinStreamAction(); - - $qb->selectDestFollowing('sd', ''); - $qb->innerJoinStreamDest('recipient', 'id_prim', 'sd', 's'); - $qb->limitToDest(ACore::CONTEXT_PUBLIC, 'recipient', 'to', 'sd'); - - return $this->getStreamsFromRequest($qb); - } - - /** - * Should returns: - * * All liked posts - * - * @param int $since - * @param int $limit - * - * @return Stream[] - * @throws DateTimeException - */ - public function getTimelineLiked(int $since = 0, int $limit = 5): array { - $qb = $this->getStreamSelectSql(); - if (!$qb->hasViewer()) { - return []; - } - - $actor = $qb->getViewer(); - - $qb->limitToStatusTypes(); - $qb->limitPaginate($since, $limit); - - $expr = $qb->expr(); - $qb->linkToCacheActors('ca', 's.attributed_to_prim'); - - $qb->selectStreamActions('sa'); - $qb->andWhere($expr->eq('sa.stream_id_prim', 's.id_prim')); - $qb->andWhere($expr->eq('sa.actor_id_prim', $qb->createNamedParameter($qb->prim($actor->getId())))); - $qb->andWhere($expr->eq('sa.liked', $qb->createNamedParameter(1))); - - return $this->getStreamsFromRequest($qb); - } - - /** - * Should return: - * - All public post related to a tag (not yet) - * - direct message related to a tag (not yet) - * - message to followers related to a tag (not yet) - * - * @param string $hashtag - * @param int $since - * @param int $limit - * - * @return Stream[] - * @throws DateTimeException - */ - public function getTimelineTag(string $hashtag, int $since = 0, int $limit = 5): array { - $qb = $this->getStreamSelectSql(); - - $expr = $qb->expr(); - $qb->linkToCacheActors('ca', 's.attributed_to_prim'); - $qb->linkToStreamTags('st', 's.id_prim'); - $qb->limitPaginate($since, $limit); - - $qb->andWhere($qb->exprLimitToDBField('type', Note::TYPE)); - $qb->andWhere($qb->exprLimitToDBField('hashtag', $hashtag, true, false, 'st')); - - $qb->limitToViewer('sd', 'f', true); - $qb->andWhere($expr->eq('s.attributed_to_prim', 'ca.id_prim')); - - $qb->leftJoinStreamAction('sa'); - - return $this->getStreamsFromRequest($qb); - } - /** * How often each hashtag was used since a point in time. * diff --git a/lib/Service/ActivityService.php b/lib/Service/ActivityService.php index cb5a332d3..ca997048a 100644 --- a/lib/Service/ActivityService.php +++ b/lib/Service/ActivityService.php @@ -418,12 +418,18 @@ private function methodFromQueue(RequestQueue $queue): string { } /** - * The bytes the delivery puts on the wire: the stored activity, decoded and - * re-encoded with unescaped slashes, which is what the transport has always - * sent and therefore what the digest has always covered. + * The bytes the delivery puts on the wire: the stored activity, as stored. + * + * They used to be decoded and re-encoded here, which defeated + * `ForwardService` on purpose: it queues a third party's `getSource()` + * verbatim so that their Linked Data signature still verifies on arrival, + * and re-encoding -- key order, escaping, whitespace -- is exactly what + * breaks such a signature. What this instance writes itself is encoded once, + * with unescaped slashes, when it is queued (`generateRequestQueue()`), so + * nothing it sends changes; the digest is computed over these same bytes. */ private function bodyFromQueue(RequestQueue $queue): string { - return (string)json_encode(json_decode($queue->getActivity(), true), JSON_UNESCAPED_SLASHES); + return $queue->getActivity(); } /** diff --git a/lib/Service/FollowService.php b/lib/Service/FollowService.php index e4c044425..03fe35b37 100644 --- a/lib/Service/FollowService.php +++ b/lib/Service/FollowService.php @@ -48,11 +48,11 @@ class FollowService { use TArrayTools; /** - * The most followers one read of the legacy `/api/v1/current/followers` - * answers with. It has no cursor to page on — Mastodon's - * `/api/v1/accounts/{account}/followers` is the route with one, and this - * one is listed as superseded by it in docs/API.md — so the choice was a - * bound or an account with fifty thousand followers loading all of them, + * The most followers one uncursored read (`getFollowers()`) answers with. + * Mastodon's `/api/v1/accounts/{account}/followers` is the route with a + * cursor; the legacy `/api/v1/current/followers` that this bounded was + * retired with the rest of the superseded Custom Local API. The choice was + * a bound or an account with fifty thousand followers loading all of them, * hydrated, into the memory of one request. */ public const FOLLOWERS_PAGE = 500; diff --git a/lib/Service/StreamService.php b/lib/Service/StreamService.php index 7eeb0b3aa..a23468e4c 100644 --- a/lib/Service/StreamService.php +++ b/lib/Service/StreamService.php @@ -513,23 +513,6 @@ public function getRepliesByParentId( return $this->streamRequest->getRepliesByParentId($id, $since, $limit, $asViewer); } - /** - * @param int $since - * @param int $limit - * @param int $format - * - * @return Note[] - * @throws DateTimeException - * @deprecated - */ - public function getStreamHome( - int $since = 0, - int $limit = 5, - int $format = Stream::FORMAT_ACTIVITYPUB, - ): array { - return $this->streamRequest->getTimelineHome_dep($since, $limit, $format); - } - /** * @param ProbeOptions $options * @@ -612,102 +595,6 @@ public function attachCard(Stream $post): Stream { return $post; } - /** - * @param int $since - * @param int $limit - * - * @return Note[] - * @throws Exception - * @deprecated - */ - public function getStreamNotifications(int $since = 0, int $limit = 5): array { - return $this->streamRequest->getTimelineNotifications_dep($since, $limit); - } - - /** - * @param string $actorId - * @param int $since - * @param int $limit - * - * @return Note[] - * @throws Exception - * @deprecated - */ - public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array { - return $this->streamRequest->getTimelineAccount_dep($actorId, $since, $limit); - } - - /** - * @param int $since - * @param int $limit - * - * @return Note[] - * @throws Exception - * @deprecated - */ - public function getStreamDirect(int $since = 0, int $limit = 5): array { - return $this->streamRequest->getTimelineDirect_dep($since, $limit); - } - - /** - * @param int $since - * @param int $limit - * - * @return Note[] - * @throws Exception - * @deprecated - */ - public function getStreamLocalTimeline(int $since = 0, int $limit = 5): array { - return $this->streamRequest->getTimelineGlobal_dep($since, $limit, true); - } - - /** - * @param string $hashtag - * @param int $since - * @param int $limit - * - * @return Note[] - * @throws Exception - */ - public function getStreamLocalTag(string $hashtag, int $since = 0, int $limit = 5): array { - return $this->streamRequest->getTimelineTag($hashtag, $since, $limit); - } - - /** - * @param int $since - * @param int $limit - * - * @return Note[] - */ - public function getStreamInternalTimeline(int $since = 0, int $limit = 5): array { - // TODO - admin should be able to provide a list of 'friendly/internal' instance of ActivityPub - return []; - } - - /** - * - * @param int $since - * @param int $limit - * - * @return Note[] - * @throws Exception - */ - public function getStreamGlobalTimeline(int $since = 0, int $limit = 5): array { - return $this->streamRequest->getTimelineGlobal_dep($since, $limit, false); - } - - /** - * - * @param int $since - * @param int $limit - * - * @return Note[] - * @throws Exception - */ - public function getStreamLiked(int $since = 0, int $limit = 5): array { - return $this->streamRequest->getTimelineLiked($since, $limit); - } - /** * @param $noteId * diff --git a/tests/Controller/LocalControllerTest.php b/tests/Controller/LocalControllerTest.php index a6a2d81c9..3722ae67c 100644 --- a/tests/Controller/LocalControllerTest.php +++ b/tests/Controller/LocalControllerTest.php @@ -17,7 +17,6 @@ use OCA\Social\Exceptions\FollowSameAccountException; use OCA\Social\Exceptions\InvalidActionException; use OCA\Social\Exceptions\InvalidResourceException; -use OCA\Social\Exceptions\StreamNotFoundException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\ActivityPub\Object\Document; @@ -37,7 +36,6 @@ use OCA\Social\Service\FollowService; use OCA\Social\Service\HashtagService; use OCA\Social\Service\LikeService; -use OCA\Social\Service\MiscService; use OCA\Social\Service\PostService; use OCA\Social\Service\SearchService; use OCA\Social\Service\StreamService; @@ -47,7 +45,6 @@ use OCP\AppFramework\Http\Attribute\UserRateLimit; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\FileDisplayResponse; -use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Files\SimpleFS\ISimpleFile; use OCP\IRequest; @@ -163,15 +160,9 @@ private function controller(?string $userId = 'alice'): LocalController { $this->followService, $this->postService, $this->streamService, - $this->searchService, - $this->boostService, - $this->likeService, $this->documentService, - $this->createMock(MiscService::class), $this->configService, new NullLogger(), - $this->actorService, - $this->activityService, $this->cacheDocumentService, $this->bannerService ); @@ -325,40 +316,7 @@ public function testPostCreateReportsServiceFailures(): void { $this->assertFailure($this->controller()->postCreate('x'), \RuntimeException::class, 'cannot post'); } - // postGet() / postReplies() / postDelete() - - public function testPostGetReturnsTheStreamDirectly(): void { - $this->actorForUser(); - $stream = $this->createMock(Stream::class); - $this->streamService->method('getStreamById')->with('https://x/n/1', true)->willReturn($stream); - - $response = $this->controller()->postGet('https://x/n/1'); - - $this->assertSame(Http::STATUS_OK, $response->getStatus()); - $this->assertSame($stream, $response->getData()); - } - - public function testPostGetWorksAnonymously(): void { - $stream = $this->createMock(Stream::class); - $this->streamService->method('getStreamById')->willReturn($stream); - $this->accountService->expects($this->never())->method('getActorFromUserId'); - - $this->assertSame($stream, $this->controller(null)->postGet('https://x/n/1')->getData()); - } - - public function testPostGetOfUnknownStreamFails(): void { - $this->streamService->method('getStreamById')->willThrowException(new StreamNotFoundException()); - - $this->assertFailure($this->controller(null)->postGet('https://x/n/404'), StreamNotFoundException::class); - } - - public function testPostRepliesPassPagination(): void { - $this->actorForUser(); - $this->streamService->expects($this->once())->method('getRepliesByParentId') - ->with('https://x/n/1', 100, 20, true)->willReturn(['r']); - - $this->assertSuccess($this->controller()->postReplies('https://x/n/1', 100, 20), ['r']); - } + // postDelete() public function testPostDeleteRemovesTheUsersOwnNote(): void { $this->actorForUser(); @@ -386,44 +344,6 @@ public function testPostDeleteRequiresALoggedInUser(): void { $this->assertNotLoggedIn($this->controller(null)->postDelete('https://x/n/1')); } - // like / boost - - /** @return iterable */ - public static function reactions(): iterable { - yield 'like' => ['postLike', 'likeService', 'create', 'like']; - yield 'unlike' => ['postUnlike', 'likeService', 'delete', 'like']; - } - - #[DataProvider('reactions')] - public function testReactionsAreCreatedForTheViewer(string $action, string $service, string $method, string $key): void { - $viewer = $this->actorForUser(); - $activity = $this->createMock(ACore::class); - $this->$service->expects($this->once())->method($method) - ->willReturnCallback(function (Person $actor, string $postId, string &$token) use ($viewer, $activity): ACore { - $this->assertSame($viewer, $actor); - $this->assertSame('https://x/n/1', $postId); - $token = 'tok'; - - return $activity; - }); - - $this->assertSuccess($this->controller()->$action('https://x/n/1'), [$key => $activity, 'token' => 'tok']); - } - - #[DataProvider('reactions')] - public function testReactionsRequireALoggedInUser(string $action, string $service, string $method): void { - $this->$service->expects($this->never())->method($method); - - $this->assertFailure($this->controller(null)->$action('https://x/n/1'), AccountDoesNotExistException::class, 'userId not defined'); - } - - public function testReactionFailuresAreReported(): void { - $this->actorForUser(); - $this->likeService->method('create')->willThrowException(new StreamNotFoundException('no such post')); - - $this->assertFailure($this->controller()->postLike('https://x/n/404'), StreamNotFoundException::class, 'no such post'); - } - // follow / unfollow public function testActionFollowFollowsAndRefreshesCounters(): void { @@ -465,111 +385,8 @@ public function testActionUnfollowMapsServiceExceptionsToFailures(): void { // stream*() - /** @return iterable */ - public static function streams(): iterable { - yield 'home' => ['streamHome', [10, 25], 'getStreamHome', [10, 25]]; - yield 'notifications' => ['streamNotifications', [3, 7], 'getStreamNotifications', [3, 7]]; - yield 'direct' => ['streamDirect', [1, 2], 'getStreamDirect', [1, 2]]; - yield 'local timeline' => ['streamTimeline', [5, 15], 'getStreamLocalTimeline', [5, 15]]; - yield 'tag' => ['streamTag', ['nextcloud', 4, 8], 'getStreamLocalTag', ['nextcloud', 4, 8]]; - yield 'federated' => ['streamFederated', [9, 9], 'getStreamGlobalTimeline', [9, 9]]; - yield 'liked' => ['streamLiked', [0, 5], 'getStreamLiked', [0, 5]]; - } - - #[DataProvider('streams')] - public function testStreamEndpointsPassSinceAndLimitToTheService(string $action, array $args, string $method, array $expected): void { - $viewer = $this->actorForUser(); - $this->streamService->expects($this->once())->method('setViewer')->with($viewer); - $posts = [$this->createMock(Stream::class)]; - $this->streamService->expects($this->once())->method($method)->with(...$expected)->willReturn($posts); - - $this->assertSuccess($this->controller()->$action(...$args), $posts); - } - - #[DataProvider('streams')] - public function testStreamEndpointsRequireALoggedInUser(string $action, array $args, string $method): void { - $this->streamService->expects($this->never())->method($method); - - $this->assertFailure($this->controller(null)->$action(...$args), AccountDoesNotExistException::class, 'userId not defined'); - } - - public function testStreamEndpointsFailWhenTheViewerCannotBeResolved(): void { - $this->accountService->method('getActorFromUserId')->willThrowException(new AccountDoesNotExistException('no actor')); - - $response = $this->controller()->streamHome(); - - $this->assertFailure($response, AccountDoesNotExistException::class); - } - - public function testStreamAccountSyncsTheRemoteTimelineFirst(): void { - $account = $this->createMock(Person::class); - $account->method('getId')->willReturn('https://remote.example/users/bob'); - $this->cacheActorService->method('getFromAccount')->with('bob@remote.example')->willReturn($account); - $this->streamService->expects($this->once())->method('syncRemoteTimeline')->with($account); - $this->streamService->expects($this->once())->method('getStreamAccount') - ->with('https://remote.example/users/bob', 2, 6)->willReturn(['p']); - - $this->assertSuccess($this->controller(null)->streamAccount('bob@remote.example', 2, 6), ['p']); - } - // current* / account* / global* - public function testCurrentInfoRefreshesAndReturnsTheCachedActor(): void { - $this->actorForUser(); - $cached = $this->createMock(Person::class); - $this->accountService->expects($this->once())->method('cacheLocalActorByUsername')->with('alice'); - $this->cacheActorService->method('getFromLocalAccount')->with('alice')->willReturn($cached); - - $this->assertSuccess($this->controller()->currentInfo(), ['account' => $cached]); - } - - public function testCurrentInfoRequiresALoggedInUser(): void { - $this->assertNotLoggedIn($this->controller(null)->currentInfo()); - } - - public function testAccountSummaryStoresTheBioAndReturnsTheRefreshedAccount(): void { - $this->actorForUser(); - $cached = $this->createMock(Person::class); - $this->accountService->expects($this->once())->method('setSummary') - ->with('alice', 'I keep bees.'); - $this->cacheActorService->method('getFromLocalAccount')->with('alice')->willReturn($cached); - - $this->assertSuccess( - $this->controller()->accountSummary('I keep bees.'), - ['account' => $cached] - ); - } - - public function testAccountSummaryRequiresALoggedInUser(): void { - $this->accountService->expects($this->never())->method('setSummary'); - - $this->assertNotLoggedIn($this->controller(null)->accountSummary('I keep bees.')); - } - - public function testAccountSummaryReportsServiceFailures(): void { - $this->actorForUser(); - $this->accountService->method('setSummary') - ->willThrowException(new InvalidResourceException('nope')); - - $this->assertFailure( - $this->controller()->accountSummary('I keep bees.'), InvalidResourceException::class - ); - } - - public function testCurrentFollowersAndFollowingListTheUsersRelations(): void { - $actor = $this->actorForUser(); - $this->followService->method('getFollowers')->with($actor)->willReturn(['f1']); - $this->followService->method('getFollowing')->with($actor)->willReturn(['f2']); - - $this->assertSuccess($this->controller()->currentFollowers(), ['f1']); - $this->assertSuccess($this->controller()->currentFollowing(), ['f2']); - } - - public function testCurrentFollowersRequireALoggedInUser(): void { - $this->assertNotLoggedIn($this->controller(null)->currentFollowers()); - $this->assertNotLoggedIn($this->controller(null)->currentFollowing()); - } - public function testAccountInfoReturnsTheCompleteLocalActor(): void { $actor = $this->createMock(Person::class); $this->accountService->method('getCachedLocalActor')->with('bob')->willReturn($actor); @@ -667,29 +484,16 @@ public function testGlobalAccountInfoOfUnknownRemoteAccountFails(): void { $this->assertFailure($this->controller(null)->globalAccountInfo('ghost@remote.example'), CacheActorDoesNotExistException::class); } - public function testGlobalActorInfoLooksUpAnActorThisInstanceKnows(): void { - $actor = $this->createMock(Person::class); - $this->localActors['https://remote.example/users/bob'] = $actor; - $this->cacheActorService->expects($this->never())->method('getFromId'); - - $this->assertSuccess($this->controller(null)->globalActorInfo('https://remote.example/users/bob'), ['actor' => $actor]); - } - - public function testGlobalActorInfoOfUnknownIdFails(): void { - $this->cacheActorService->method('getFromId')->willThrowException(new CacheActorDoesNotExistException()); - - $this->assertFailure($this->controller('alice')->globalActorInfo('https://x'), CacheActorDoesNotExistException::class); - } + // knownActor(), through the one public route left on it: the avatar public function testAnAnonymousCallerCannotMakeTheInstanceResolveAnUnknownActor(): void { // resolving an id fetches whatever url it names and downloads the // actor's icon: not something anybody may trigger without a session $this->cacheActorService->expects($this->never())->method('getFromId'); - $this->assertFailure( - $this->controller(null)->globalActorInfo('https://evil.test/a/1'), - CacheActorDoesNotExistException::class, 'unknown actor' - ); + $response = $this->controller(null)->globalActorAvatar('https://evil.test/a/1'); + + $this->assertSame(Http::STATUS_NOT_FOUND, $response->getStatus()); } public function testALoggedInCallerStillResolvesAnUnknownActor(): void { @@ -697,20 +501,19 @@ public function testALoggedInCallerStillResolvesAnUnknownActor(): void { $this->cacheActorService->expects($this->once())->method('getFromId') ->with('https://remote.example/users/new')->willReturn($actor); - $this->assertSuccess( - $this->controller('alice')->globalActorInfo('https://remote.example/users/new'), - ['actor' => $actor] - ); + // resolved -- and then a 404 for the avatar it does not have, which is + // the route's answer and not a refusal to look + $this->assertSame(Http::STATUS_NOT_FOUND, $this->controller('alice')->globalActorAvatar('https://remote.example/users/new')->getStatus()); } public function testTheKeyFragmentIsNotPartOfTheActorId(): void { - $actor = $this->createMock(Person::class); - $this->localActors['https://remote.example/users/bob'] = $actor; + // a keyId names the actor plus `#main-key`; the actor is found by the + // id alone, from the cache, without asking the network for the fragment + $this->localActors['https://remote.example/users/bob'] = $this->createMock(Person::class); + $this->cacheActorService->expects($this->never())->method('getFromId'); - $this->assertSuccess( - $this->controller(null)->globalActorInfo('https://remote.example/users/bob#main-key'), - ['actor' => $actor] - ); + $this->controller('alice')->globalActorAvatar('https://remote.example/users/bob#main-key'); + $this->addToAssertionCount(1); } // avatar / header @@ -764,66 +567,6 @@ public function testGlobalActorAvatarOfAnUnknownActorIs404ForAnonymousCallers(): ); } - public function testGlobalActorHeaderRedirectsToTheHeaderImage(): void { - \OC::$server->register(ITimeFactory::class, $this->createMock(ITimeFactory::class)); - $actor = $this->createMock(Person::class); - $actor->method('getHeader')->willReturn('https://remote.example/header.jpg'); - $this->localActors['https://x'] = $actor; - - $response = $this->controller(null)->globalActorHeader('https://x'); - - $this->assertInstanceOf(RedirectResponse::class, $response); - $this->assertSame('https://remote.example/header.jpg', $response->getRedirectURL()); - $this->assertStringContainsString('max-age=86400', $response->getHeaders()['Cache-Control']); - } - - public function testGlobalActorHeaderPrefersTheCopyThisInstanceHolds(): void { - \OC::$server->register(ITimeFactory::class, $this->createMock(ITimeFactory::class)); - $actor = $this->createMock(Person::class); - $actor->method('getHeader')->willReturn('https://remote.example/header.jpg'); - $this->localActors['https://x'] = $actor; - $file = $this->createMock(ISimpleFile::class); - $file->method('getName')->willReturn('header'); - $this->cachedRemoteFiles['https://remote.example/header.jpg'] = $file; - - $response = $this->controller(null)->globalActorHeader('https://x'); - - $this->assertInstanceOf(FileDisplayResponse::class, $response); - $this->assertSame('image/jpeg', $response->getHeaders()['Content-Type']); - } - - #[DataProvider('provideUnusableHeaderAddresses')] - public function testGlobalActorHeaderRefusesAnAddressThatIsNotWebContent(string $header): void { - // the value is remote JSON, and this route answers from the origin the - // user trusts: it must not become a redirect to anywhere at all - $actor = $this->createMock(Person::class); - $actor->method('getHeader')->willReturn($header); - $this->localActors['https://x'] = $actor; - - $this->assertFailure( - $this->controller(null)->globalActorHeader('https://x'), - InvalidResourceException::class, 'unsupported header address', Http::STATUS_NOT_FOUND - ); - } - - public static function provideUnusableHeaderAddresses(): iterable { - yield 'javascript' => ['javascript:alert(1)']; - yield 'data' => ['data:text/html;base64,PHNjcmlwdD4=']; - yield 'file' => ['file:///etc/passwd']; - yield 'scheme-relative' => ['//evil.test/header.jpg']; - } - - public function testGlobalActorHeaderIs404WithoutHeader(): void { - $actor = $this->createMock(Person::class); - $actor->method('getHeader')->willReturn(''); - $this->localActors['https://x'] = $actor; - - $this->assertFailure( - $this->controller(null)->globalActorHeader('https://x'), - InvalidResourceException::class, 'no header for this Actor', Http::STATUS_NOT_FOUND - ); - } - // search public function testGlobalAccountsSearchWithEmptyTermIsEmpty(): void { @@ -868,17 +611,6 @@ public function testGlobalTagsSearchStripsTheHashAndReturnsExactMatch(): void { ); } - public function testSearchTrimsTheTermAndQueriesAllKinds(): void { - $this->searchService->method('searchAccounts')->with('term')->willReturn(['a']); - $this->searchService->method('searchHashtags')->with('term')->willReturn(['h']); - $this->searchService->method('searchStreamContent')->with('term')->willReturn(['c']); - - $this->assertSuccess( - $this->controller(null)->search(' term '), - ['accounts' => ['a'], 'hashtags' => ['h'], 'content' => ['c']] - ); - } - // documents / uploads public function testUploadBannerRequiresALoggedInUser(): void { @@ -1035,14 +767,15 @@ public function testUploadBannerByUrlRefusesAnOversizedDownload(): void { } public function testPublicRoutesThatReachOutToRemoteServersAreRateLimited(): void { - // Both are #[PublicPage] and both fetch from whatever host the handle names: - // globalAccountInfo signs half a dozen outbound requests per call and - // streamAccount pulls and ingests a remote outbox. An anonymous throttle is - // all that stands between one HTTP request and that work being repeated at - // will, the way OStatusController::getLink is already throttled. + // #[PublicPage], and it fetches from whatever host the handle names: + // globalAccountInfo signs half a dozen outbound requests per call. An + // anonymous throttle is all that stands between one HTTP request and + // that work being repeated at will, the way OStatusController::getLink + // is already throttled. (streamAccount, which pulled a remote outbox, + // was retired with the rest of the superseded Custom Local API.) $reflection = new \ReflectionClass(LocalController::class); - foreach (['streamAccount', 'globalAccountInfo'] as $route) { + foreach (['globalAccountInfo'] as $route) { $attributes = array_map( fn (\ReflectionAttribute $attribute): string => $attribute->getName(), $reflection->getMethod($route)->getAttributes() diff --git a/tests/Service/ActivityServiceTest.php b/tests/Service/ActivityServiceTest.php index 8212f19a9..0ecc07304 100644 --- a/tests/Service/ActivityServiceTest.php +++ b/tests/Service/ActivityServiceTest.php @@ -625,10 +625,9 @@ public function testManageRequestPostsSignedActivityToInboxAndEndsRequestOnSucce $this->assertSame(self::BOB_INBOX, $sent['url']); $this->assertSame(10, $sent['options']['timeout']); $this->assertSame(['Signature' => 'keyId="k"'], $sent['options']['headers']); - $this->assertSame( - json_decode($queue->getActivity(), true), - json_decode($sent['options']['body'], true) - ); + // byte for byte, not merely the same JSON: a forwarded activity's Linked + // Data signature survives only if nothing here re-encodes it + $this->assertSame($queue->getActivity(), $sent['options']['body']); } /** diff --git a/tests/Service/StreamServiceTest.php b/tests/Service/StreamServiceTest.php index cdd0bbb8d..a0ea734e6 100644 --- a/tests/Service/StreamServiceTest.php +++ b/tests/Service/StreamServiceTest.php @@ -802,15 +802,6 @@ public function testNotificationsAreNotDeduplicated(): void { */ public static function timelineDelegationProvider(): array { return [ - 'home' => ['getStreamHome', [10, 20, ACore::FORMAT_LOCAL], 'getTimelineHome_dep', [10, 20, ACore::FORMAT_LOCAL]], - 'home defaults' => ['getStreamHome', [], 'getTimelineHome_dep', [0, 5, ACore::FORMAT_ACTIVITYPUB]], - 'notifications' => ['getStreamNotifications', [10, 20], 'getTimelineNotifications_dep', [10, 20]], - 'account' => ['getStreamAccount', ['https://remote.example/users/bob', 10, 20], 'getTimelineAccount_dep', ['https://remote.example/users/bob', 10, 20]], - 'direct' => ['getStreamDirect', [10, 20], 'getTimelineDirect_dep', [10, 20]], - 'local timeline restricts to local posts' => ['getStreamLocalTimeline', [10, 20], 'getTimelineGlobal_dep', [10, 20, true]], - 'global timeline includes remote posts' => ['getStreamGlobalTimeline', [10, 20], 'getTimelineGlobal_dep', [10, 20, false]], - 'tag' => ['getStreamLocalTag', ['nextcloud', 10, 20], 'getTimelineTag', ['nextcloud', 10, 20]], - 'liked' => ['getStreamLiked', [10, 20], 'getTimelineLiked', [10, 20]], 'replies' => ['getRepliesByParentId', ['https://social.example/@alice/1', 10, 20, true], 'getRepliesByParentId', ['https://social.example/@alice/1', 10, 20, true]], 'replies defaults' => ['getRepliesByParentId', ['https://social.example/@alice/1'], 'getRepliesByParentId', ['https://social.example/@alice/1', 0, 5, false]], ]; @@ -832,12 +823,6 @@ public function testTimelineGettersPassFiltersThrough( $this->assertSame([$note], $this->service->$serviceMethod(...$args)); } - public function testInternalTimelineIsNotImplementedYet(): void { - $this->streamRequest->expects($this->never())->method($this->anything()); - - $this->assertSame([], $this->service->getStreamInternalTimeline(0, 20)); - } - // getContextByNid() public function testGetContextByNidCollectsAncestorsInThreadOrderAndDescendants(): void { From 297dcb27d650828e2f687dedb6da797c89178b2c Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Mon, 14 Sep 2026 08:52:39 +0200 Subject: [PATCH 2/2] 0.19.39, rebuilt bundle Signed-off-by: Frank Karlitschek Co-Authored-By: Claude Fable 5.1 --- appinfo/info.xml | 2 +- composer.json | 2 +- docs/Architecture.md | 2 +- js/social-social.js | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index aee19e710..e821e90d8 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -31,7 +31,7 @@ What it does: - 👋 A short introduction on the first visit: your address, who to follow, and a way to bring the follows you already have You can pin your own posts to the top of your profile, bookmark any post, and see which hashtags the instance is using most. This is a partial implementation of ActivityPub and of the Mastodon client API. Blocking, muting and reporting (with a moderation panel in the administration settings) are supported, as are locked accounts with approvable follow requests. Polls are fully supported: create your own, and view and vote on federated ones. Profiles carry an avatar, a banner image and up to four profile metadata fields. Posts that link somewhere get a link preview card. Image (JPEG, PNG, GIF, WebP, AVIF, and HEIC from an iPhone where the server can read it), video (MP4, WebM, QuickTime) and audio attachments are supported, up to ten per post, each with alt text and a focal point. It does not offer lists.]]> - 0.19.38 + 0.19.40 agpl Benedikt Schächner Social diff --git a/composer.json b/composer.json index 22c2635da..489dd35dc 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "nextcloud/social", "description": "Social app", "license": "AGPL-3.0-or-later", - "version": "0.19.38", + "version": "0.19.40", "minimum-stability": "stable", "authors": [ { diff --git a/docs/Architecture.md b/docs/Architecture.md index 8e6be1a3e..8e64f26d0 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -7,7 +7,7 @@ Nextcloud Social is a federated social networking app built on the W3C ActivityP **App ID:** `social` **Namespace:** `OCA\Social` **License:** AGPL-3.0-or-later -**App version:** 0.19.38 +**App version:** 0.19.40 **Supported Nextcloud versions:** 35 – 36 **Supported PHP versions:** 8.3 – 8.5 diff --git a/js/social-social.js b/js/social-social.js index 384733a02..22437829b 100644 --- a/js/social-social.js +++ b/js/social-social.js @@ -1,3 +1,3 @@ /*! For license information please see social-social.js.LICENSE.txt */ -(()=>{"use strict";var e={43758(e,t,n){var a=n(20641),i=n(90033),o=n(33564);const r={name:"ArrowRightIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},s=["aria-hidden","aria-label"],l=["fill","width","height"],c={d:"M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"},d={key:0};const p=(0,o._)(r,[["render",function(e,t,n,o,r,p){return(0,a.uX)(),(0,a.CE)("span",(0,a.v6)(e.$attrs,{"aria-hidden":n.title?null:"true","aria-label":n.title,class:"material-design-icon arrow-right-icon",role:"img",onClick:t[0]||(t[0]=t=>e.$emit("click",t))}),[((0,a.uX)(),(0,a.CE)("svg",{fill:n.fillColor,class:"material-design-icon__svg",width:n.size,height:n.size,viewBox:"0 0 24 24"},[(0,a.Lk)("path",c,[n.title?((0,a.uX)(),(0,a.CE)("title",d,(0,i.v_)(n.title),1)):(0,a.Q3)("",!0)])],8,l))],16,s)}]]);n.d(t,["I",0,p])},83958(e,t,n){var a=n(20641),i=n(90033),o=n(33564);const r={name:"ChevronDownIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},s=["aria-hidden","aria-label"],l=["fill","width","height"],c={d:"M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"},d={key:0};const p=(0,o._)(r,[["render",function(e,t,n,o,r,p){return(0,a.uX)(),(0,a.CE)("span",(0,a.v6)(e.$attrs,{"aria-hidden":n.title?null:"true","aria-label":n.title,class:"material-design-icon chevron-down-icon",role:"img",onClick:t[0]||(t[0]=t=>e.$emit("click",t))}),[((0,a.uX)(),(0,a.CE)("svg",{fill:n.fillColor,class:"material-design-icon__svg",width:n.size,height:n.size,viewBox:"0 0 24 24"},[(0,a.Lk)("path",c,[n.title?((0,a.uX)(),(0,a.CE)("title",d,(0,i.v_)(n.title),1)):(0,a.Q3)("",!0)])],8,l))],16,s)}]]);n.d(t,["C",0,p])},14165(e,t,n){var a=n(20641),i=n(90033),o=n(33564);const r={name:"ChevronUpIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},s=["aria-hidden","aria-label"],l=["fill","width","height"],c={d:"M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z"},d={key:0};const p=(0,o._)(r,[["render",function(e,t,n,o,r,p){return(0,a.uX)(),(0,a.CE)("span",(0,a.v6)(e.$attrs,{"aria-hidden":n.title?null:"true","aria-label":n.title,class:"material-design-icon chevron-up-icon",role:"img",onClick:t[0]||(t[0]=t=>e.$emit("click",t))}),[((0,a.uX)(),(0,a.CE)("svg",{fill:n.fillColor,class:"material-design-icon__svg",width:n.size,height:n.size,viewBox:"0 0 24 24"},[(0,a.Lk)("path",c,[n.title?((0,a.uX)(),(0,a.CE)("title",d,(0,i.v_)(n.title),1)):(0,a.Q3)("",!0)])],8,l))],16,s)}]]);n.d(t,["C",0,p])},79859(e,t,n){var a=n(20641),i=n(90033),o=n(33564);const r={name:"CloseIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},s=["aria-hidden","aria-label"],l=["fill","width","height"],c={d:"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"},d={key:0};const p=(0,o._)(r,[["render",function(e,t,n,o,r,p){return(0,a.uX)(),(0,a.CE)("span",(0,a.v6)(e.$attrs,{"aria-hidden":n.title?null:"true","aria-label":n.title,class:"material-design-icon close-icon",role:"img",onClick:t[0]||(t[0]=t=>e.$emit("click",t))}),[((0,a.uX)(),(0,a.CE)("svg",{fill:n.fillColor,class:"material-design-icon__svg",width:n.size,height:n.size,viewBox:"0 0 24 24"},[(0,a.Lk)("path",c,[n.title?((0,a.uX)(),(0,a.CE)("title",d,(0,i.v_)(n.title),1)):(0,a.Q3)("",!0)])],8,l))],16,s)}]]);n.d(t,["I",0,p])},69052(e,t,n){n(40276);var a=n(80474),i=n(26158),o=n(24239),r=n(83868),s=n(54540),l=n(20641),c=n(50953),d=n(53751),p=n(90033),u=n(70711),A=n(12793),h=n(50979),v=n(50744),m=n(20720),f=n(33564),g=n(44783),C=n(54949),b=n(60701);n(78600);(0,h.r)(h.H);const _=(0,l.pM)({__name:"NcAppContentDetailsToggle",setup(e){const t=(0,A.al)();function n(e=!0){const t=document.querySelector(".app-navigation .app-navigation-toggle");t&&(t.style.display=e?"none":"",!0===e&&(0,o.Ic)("toggle-navigation",{open:!1}))}return(0,l.wB)(t,n),(0,l.sV)(()=>{n(t.value)}),(0,l.xo)(()=>{t.value&&n(!1)}),(e,n)=>((0,l.uX)(),(0,l.Wv)((0,c.R1)(v.N),{"aria-label":(0,c.R1)(h.a)("Go back to the list"),class:(0,p.C4)(["app-details-toggle",{"app-details-toggle--mobile":(0,c.R1)(t)}]),title:(0,c.R1)(h.a)("Go back to the list"),variant:"tertiary"},{icon:(0,l.k6)(()=>[(0,l.bF)((0,c.R1)(m.N),{directional:"",path:(0,c.R1)(u.m)},null,8,["path"])]),_:1},8,["aria-label","class","title"]))}}),y=(0,f._)(_,[["__scopeId","data-v-a28923a1"]]),x=(0,a.c0)("nextcloud").persist().build(),w=(0,i.F)().theming?.name??"Nextcloud",E={name:"NcAppContent",components:{NcAppContentDetailsToggle:y,Pane:s.Z,Splitpanes:s.S},props:{disableSwipe:{type:Boolean,default:!1},listSize:{type:Number,default:20},listMinWidth:{type:Number,default:15},listMaxWidth:{type:Number,default:40},paneConfigKey:{type:String,default:""},showDetails:{type:Boolean,default:!0},layout:{type:String,default:"vertical-split",validator:e=>["no-split","vertical-split","horizontal-split"].includes(e)},pageHeading:{type:String,default:null},pageTitle:{type:String,default:null}},emits:["update:showDetails","resizeList"],setup:()=>({appName:(0,g.a)(),localizedAppName:(0,g.u)(),isMobile:(0,A.al)(),isRtl:b.i}),data(){return{contentHeight:0,swiping:{},listPaneSize:this.restorePaneConfig()}},computed:{paneConfigID(){if(""!==this.paneConfigKey)return`pane-list-size-${this.paneConfigKey}`;try{return`pane-list-size-${this.appName}`}catch{return C.l.info("[NcAppContent]: falling back to global nextcloud pane config"),"pane-list-size-nextcloud"}},detailsPaneSize(){return this.listPaneSize?100-this.listPaneSize:this.paneDefaults.details.size},paneDefaults(){return{list:{size:this.listSize,min:this.listMinWidth,max:this.listMaxWidth},details:{size:100-this.listSize,min:100-this.listMaxWidth,max:100-this.listMinWidth}}},realPageTitle(){const e=new Set;if(this.pageTitle)for(const t of this.pageTitle.split(" - "))e.add(t);else{if(!this.pageHeading)return null;for(const t of this.pageHeading.split(" - "))e.add(t);e.size>0&&e.add(this.localizedAppName)}return e.add(w),[...e.values()].join(" - ")}},watch:{realPageTitle:{immediate:!0,handler(){null!==this.realPageTitle&&(document.title=this.realPageTitle)}},paneConfigKey:{immediate:!0,handler(){this.restorePaneConfig()}}},mounted(){this.disableSwipe||(this.swiping=(0,r.o__)(this.$el,{onSwipeEnd:this.handleSwipe})),this.restorePaneConfig()},methods:{handleSwipe(e,t){Math.abs(this.swiping.lengthX)>70&&(this.swiping.coordsStart.x<150&&"right"===t?(0,o.Ic)("toggle-navigation",{open:!0}):this.swiping.coordsStart.x<450&&"left"===t&&(0,o.Ic)("toggle-navigation",{open:!1}))},handlePaneResize(e){const t=parseInt(e.panes[0].size,10);x.setItem(this.paneConfigID,JSON.stringify(t)),this.listPaneSize=t,this.$emit("resizeList",{size:t}),C.l.debug("[NcAppContent] pane config",{listPaneSize:t})},restorePaneConfig(){const e=parseInt(x.getItem(this.paneConfigID),10);if(!isNaN(e)&&e!==this.listPaneSize)return C.l.debug("[NcAppContent] pane config",{listPaneSize:e}),this.listPaneSize=e,e},hideDetails(){this.$emit("update:showDetails",!1)}}},k={key:0,class:"hidden-visually"},B={class:"app-content-wrapper__list"},S={key:1,class:"app-content-wrapper"};const D=(0,f._)(E,[["render",function(e,t,n,a,i,o){const r=(0,l.g2)("NcAppContentDetailsToggle"),s=(0,l.g2)("Pane"),c=(0,l.g2)("Splitpanes");return(0,l.uX)(),(0,l.CE)("main",{id:"app-content-vue",class:(0,p.C4)(["app-content no-snapper",{"app-content--has-list":!!e.$slots.list}])},[n.pageHeading?((0,l.uX)(),(0,l.CE)("h1",k,(0,p.v_)(n.pageHeading),1)):(0,l.Q3)("",!0),e.$slots.list?((0,l.uX)(),(0,l.CE)(l.FK,{key:1},[a.isMobile||"no-split"===n.layout?((0,l.uX)(),(0,l.CE)("div",{key:0,class:(0,p.C4)(["app-content-wrapper app-content-wrapper--no-split",{"app-content-wrapper--show-details":n.showDetails,"app-content-wrapper--show-list":!n.showDetails,"app-content-wrapper--mobile":a.isMobile}])},[n.showDetails?((0,l.uX)(),(0,l.Wv)(r,{key:0,onClick:(0,d.D$)(o.hideDetails,["stop","prevent"])},null,8,["onClick"])):(0,l.Q3)("",!0),(0,l.bo)((0,l.Lk)("div",B,[(0,l.RG)(e.$slots,"list",{},void 0,!0)],512),[[d.aG,!n.showDetails]]),n.showDetails?(0,l.RG)(e.$slots,"default",{},void 0,!0,1):(0,l.Q3)("",!0)],2)):"vertical-split"===n.layout||"horizontal-split"===n.layout?((0,l.uX)(),(0,l.CE)("div",S,[(0,l.bF)(c,{horizontal:"horizontal-split"===n.layout,class:(0,p.C4)(["default-theme",{"splitpanes--horizontal":"horizontal-split"===n.layout,"splitpanes--vertical":"vertical-split"===n.layout}]),rtl:a.isRtl,onResized:o.handlePaneResize},{default:(0,l.k6)(()=>[(0,l.bF)(s,{class:"splitpanes__pane-list",size:i.listPaneSize||o.paneDefaults.list.size,minSize:o.paneDefaults.list.min,maxSize:o.paneDefaults.list.max},{default:(0,l.k6)(()=>[(0,l.RG)(e.$slots,"list",{},void 0,!0)]),_:3},8,["size","minSize","maxSize"]),(0,l.bF)(s,{class:"splitpanes__pane-details",size:o.detailsPaneSize,minSize:o.paneDefaults.details.min,maxSize:o.paneDefaults.details.max},{default:(0,l.k6)(()=>[(0,l.RG)(e.$slots,"default",{},void 0,!0)]),_:3},8,["size","minSize","maxSize"])]),_:3},8,["horizontal","class","rtl","onResized"])])):(0,l.Q3)("",!0)],64)):(0,l.Q3)("",!0),e.$slots.list?(0,l.Q3)("",!0):(0,l.RG)(e.$slots,"default",{},void 0,!0,2)],2)}],["__scopeId","data-v-51427d61"]]);n.d(t,["N",0,D])},5019(e,t,n){n(70257);var a=n(20641),i=n(50953),o=n(53751),r=n(90033),s=n(24239),l=n(52697),c=n(53411),d=n(70711),p=n(20720),u=n(50979),A=n(50744),h=n(33564),v=n(12793),m=n(90766),f=n(49784),g=n(11122);(0,u.r)(u.Q);const C={class:"app-navigation-toggle-wrapper"},b=(0,a.pM)({__name:"NcAppNavigationToggle",props:{open:{type:Boolean,required:!0},openModifiers:{}},emits:["update:open"],setup(e){const t=(0,a.fn)(e,"open"),n=(0,a.EW)(()=>t.value?(0,u.a)("Close navigation"):(0,u.a)("Open navigation"));return(e,o)=>((0,a.uX)(),(0,a.CE)("div",C,[(0,a.bF)((0,i.R1)(A.N),{class:"app-navigation-toggle","aria-controls":"app-navigation-vue","aria-expanded":t.value?"true":"false","aria-label":n.value,title:n.value,variant:"tertiary",onClick:o[0]||(o[0]=e=>t.value=!t.value)},{icon:(0,a.k6)(()=>[(0,a.bF)(p.N,{path:(0,i.R1)(d.D),directional:""},null,8,["path"])]),_:1},8,["aria-expanded","aria-label","title"])]))}}),_=(0,h._)(b,[["__scopeId","data-v-e8177cc7"]]),y=["aria-hidden","aria-label","aria-labelledby","inert"],x={class:"app-navigation__search"},w=(0,a.pM)({__name:"NcAppNavigation",props:{ariaLabel:{},ariaLabelledby:{}},setup(e){const t=e;let n;const d=(0,a.WQ)(g.H,()=>(0,a.R8)("NcAppNavigation is not mounted inside NcContent, this is probably an error."),!1),p=(0,a.rk)("appNavigationContainer"),u=(0,v.al)(),A=(0,i.KR)(!u.value),h=(0,a.EW)(()=>u.value&&A.value);function C(e){if(A.value===e)return void(0,s.Ic)("navigation-toggled",{open:A.value});A.value=void 0===e?!A.value:e;const t=getComputedStyle(document.body),n=parseInt(t.getPropertyValue("--animation-slow"))||200;setTimeout(()=>{(0,s.Ic)("navigation-toggled",{open:A.value})},1.5*n)}function b({open:e}){return C(e)}function w(){h.value?n.activate():n.deactivate()}function E(){u.value&&C(!1)}return(0,a.nT)(()=>{t.ariaLabel||t.ariaLabelledby||(0,a.R8)("NcAppNavigation requires either `ariaLabel` or `ariaLabelledby` to be set for accessibility.")}),(0,a.wB)(u,()=>{A.value=!u.value}),(0,a.wB)(h,()=>{w()}),(0,a.sV)(()=>{d(!0),(0,s.B1)("toggle-navigation",b),(0,s.Ic)("navigation-toggled",{open:A.value}),n=(0,l.K)(p.value,{allowOutsideClick:!0,clickOutsideDeactivates:()=>(u.value&&(n.deactivate({returnFocus:!1}),C(!1)),!1),fallbackFocus:p.value,trapStack:(0,m.g)(),escapeDeactivates:!1}),w()}),(0,a.hi)(()=>{d(!1),(0,s.al)("toggle-navigation",b),n.deactivate()}),(t,n)=>((0,a.uX)(),(0,a.CE)("div",{ref:"appNavigationContainer",class:(0,r.C4)(["app-navigation",{"app-navigation--closed":!A.value,"app-navigation--legacy":(0,i.R1)(f.i)}])},[(0,a.Lk)("nav",{id:"app-navigation-vue","aria-hidden":A.value?"false":"true","aria-label":e.ariaLabel||void 0,"aria-labelledby":e.ariaLabelledby||void 0,class:"app-navigation__content",inert:!A.value||void 0,onKeydown:(0,o.jR)(E,["esc"])},[(0,a.Lk)("div",x,[(0,a.RG)(t.$slots,"search",{},void 0,!0)]),(0,a.Lk)("div",{class:(0,r.C4)(["app-navigation__body",{"app-navigation__body--no-list":!t.$slots.list}])},[(0,a.RG)(t.$slots,"default",{},void 0,!0)],2),t.$slots.list?((0,a.uX)(),(0,a.Wv)(c.N,{key:0,class:"app-navigation__list"},{default:(0,a.k6)(()=>[(0,a.RG)(t.$slots,"list",{},void 0,!0)]),_:3})):(0,a.Q3)("",!0),(0,a.RG)(t.$slots,"footer",{},void 0,!0)],40,y),(0,a.bF)(_,{open:A.value,"onUpdate:open":C},null,8,["open"])],2))}}),E=(0,h._)(w,[["__scopeId","data-v-37908cd4"]]);n.d(t,["N",0,E])},74795(e,t,n){n(90023);var a=n(10925),i=n(20641),o=n(90033),r=n(33564);const s={name:"NcAppNavigationCaption",components:{NcActions:a.N},props:{name:{type:String,required:!0},headingId:{type:String,default:null},isHeading:{type:Boolean,default:!1},headingLevel:{type:Number,default:2},...a.N.props},computed:{actionsProps(){const e=Object.keys(a.N.props),t=Object.entries(this.$props).filter(([t,n])=>e.includes(t));return Object.fromEntries(t)},wrapperTag(){return this.isHeading?"div":"li"},captionTag(){const e=Math.max(2,this.headingLevel);return this.isHeading?`h${e}`:"span"}}},l={key:0,class:"app-navigation-caption__actions"};const c=(0,r._)(s,[["render",function(e,t,n,a,r,s){const c=(0,i.g2)("NcActions");return(0,i.uX)(),(0,i.Wv)((0,i.$y)(s.wrapperTag),{class:(0,o.C4)(["app-navigation-caption",{"app-navigation-caption--heading":n.isHeading}])},{default:(0,i.k6)(()=>[((0,i.uX)(),(0,i.Wv)((0,i.$y)(s.captionTag),{id:n.headingId,class:"app-navigation-caption__name"},{default:(0,i.k6)(()=>[(0,i.eW)((0,o.v_)(n.name),1)]),_:1},8,["id"])),e.$slots.actions?((0,i.uX)(),(0,i.CE)("div",l,[(0,i.bF)(c,(0,o._B)((0,i.Ng)(s.actionsProps)),{icon:(0,i.k6)(()=>[(0,i.RG)(e.$slots,"actionsTriggerIcon",{},void 0,!0)]),default:(0,i.k6)(()=>[(0,i.RG)(e.$slots,"actions",{},void 0,!0)]),_:3},16)])):(0,i.Q3)("",!0)]),_:3},8,["class"])}],["__scopeId","data-v-f0e411c2"]]);n.d(t,["N",0,c])},96070(e,t,n){n(6888);var a=n(24239),i=n(20641),o=n(53751),r=n(90033),s=n(33564),l=n(83958),c=n(14165),d=n(50979),p=n(49784),u=n(50744),A=n(62754),h=n(12793),v=n(5116),m=n(47178),f=n(10925),g=n(29175),C=n(82108);const b={name:"PencilIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},_=["aria-hidden","aria-label"],y=["fill","width","height"],x={d:"M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z"},w={key:0};const E=(0,s._)(b,[["render",function(e,t,n,a,o,s){return(0,i.uX)(),(0,i.CE)("span",(0,i.v6)(e.$attrs,{"aria-hidden":n.title?null:"true","aria-label":n.title,class:"material-design-icon pencil-icon",role:"img",onClick:t[0]||(t[0]=t=>e.$emit("click",t))}),[((0,i.uX)(),(0,i.CE)("svg",{fill:n.fillColor,class:"material-design-icon__svg",width:n.size,height:n.size,viewBox:"0 0 24 24"},[(0,i.Lk)("path",x,[n.title?((0,i.uX)(),(0,i.CE)("title",w,(0,r.v_)(n.title),1)):(0,i.Q3)("",!0)])],8,y))],16,_)}]]),k={name:"UndoIcon",emits:["click"],props:{title:{type:String},fillColor:{type:String,default:"currentColor"},size:{type:Number,default:24}}},B=["aria-hidden","aria-label"],S=["fill","width","height"],D={d:"M12.5,8C9.85,8 7.45,9 5.6,10.6L2,7V16H11L7.38,12.38C8.77,11.22 10.54,10.5 12.5,10.5C16.04,10.5 19.05,12.81 20.1,16L22.47,15.22C21.08,11.03 17.15,8 12.5,8Z"},N={key:0};const z=(0,s._)(k,[["render",function(e,t,n,a,o,s){return(0,i.uX)(),(0,i.CE)("span",(0,i.v6)(e.$attrs,{"aria-hidden":n.title?null:"true","aria-label":n.title,class:"material-design-icon undo-icon",role:"img",onClick:t[0]||(t[0]=t=>e.$emit("click",t))}),[((0,i.uX)(),(0,i.CE)("svg",{fill:n.fillColor,class:"material-design-icon__svg",width:n.size,height:n.size,viewBox:"0 0 24 24"},[(0,i.Lk)("path",D,[n.title?((0,i.uX)(),(0,i.CE)("title",N,(0,r.v_)(n.title),1)):(0,i.Q3)("",!0)])],8,S))],16,B)}]]);(0,d.r)(d.O);const L={name:"NcAppNavigationIconCollapsible",components:{NcButton:u.N,ChevronDown:l.C,ChevronUp:c.C},props:{open:{type:Boolean,required:!0},active:{type:Boolean,required:!0}},emits:["click"],setup:()=>({isLegacy34:p.i}),computed:{labelButton(){return this.open?(0,d.a)("Collapse menu"):(0,d.a)("Open menu")}},methods:{onClick(e){this.$emit("click",e)}}};const P=(0,s._)(L,[["render",function(e,t,n,a,o,s){const l=(0,i.g2)("ChevronUp"),c=(0,i.g2)("ChevronDown"),d=(0,i.g2)("NcButton");return(0,i.uX)(),(0,i.Wv)(d,{class:(0,r.C4)(["icon-collapse",{"icon-collapse--active":n.active,"icon-collapse--open":n.open}]),"aria-label":s.labelButton,variant:n.active&&a.isLegacy34?"tertiary-on-primary":"tertiary",onClick:s.onClick},{icon:(0,i.k6)(()=>[n.open?((0,i.uX)(),(0,i.Wv)(l,{key:0,size:20})):((0,i.uX)(),(0,i.Wv)(c,{key:1,size:20}))]),_:1},8,["class","aria-label","variant","onClick"])}],["__scopeId","data-v-cfbd3794"]]);(0,d.r)(d.P,d.b);const I={name:"NcAppNavigationItem",components:{NcActions:f.N,NcActionButton:m.N,NcAppNavigationIconCollapsible:P,NcInputConfirmCancel:A.N,NcLoadingIcon:g.N,NcVNodes:C._,Pencil:E,Undo:z},props:{active:{type:Boolean,default:!1},name:{type:String,required:!0},title:{type:String,default:null},id:{type:String,default:()=>(0,v.c)(),validator:e=>""!==e.trim()},icon:{type:String,default:""},loading:{type:Boolean,default:!1},to:{type:[String,Object],default:null},href:{type:String,default:null},allowCollapse:{type:Boolean,default:!1},editable:{type:Boolean,default:!1},editLabel:{type:String,default:""},editPlaceholder:{type:String,default:""},pinned:{type:Boolean,default:!1},undo:{type:Boolean,default:!1},open:{type:Boolean,default:!1},menuOpen:{type:Boolean,default:!1},forceMenu:{type:Boolean,default:!1},menuIcon:{type:String,default:void 0},menuPlacement:{type:String,default:"bottom"},ariaDescription:{type:String,default:null},forceDisplayActions:{type:Boolean,default:!1},inlineActions:{type:Number,default:0}},emits:["update:menuOpen","update:open","update:name","click","undo"],setup:()=>({isMobile:(0,h.al)(),isLegacy34:p.i}),data(){return{actionsBoundariesElement:void 0,editingValue:"",opened:this.open,editingActive:!1,menuOpenLocalValue:!1,focused:!1}},computed:{isRouterLink(){return this.to&&!this.href},canHaveChildren(){return"AppNavigationItem"!==this.$parent.$options._componentTag},editButtonAriaLabel(){return this.editLabel?this.editLabel:(0,d.a)("Edit item")},undoButtonAriaLabel:()=>(0,d.a)("Undo changes")},watch:{open(e){this.opened=e}},mounted(){this.actionsBoundariesElement=document.querySelector("#content-vue")||void 0},methods:{onMenuToggle(e){this.$emit("update:menuOpen",e),this.menuOpenLocalValue=e},toggleCollapse(){this.opened=!this.opened,this.$emit("update:open",this.opened)},onClick(e,t,n){this.$emit("click",e),e.metaKey||e.altKey||e.ctrlKey||e.shiftKey||n&&(t?.(e),e.preventDefault(),this.isMobile&&(0,a.Ic)("toggle-navigation",{open:!1}))},handleEdit(){this.editingValue=this.name,this.editingActive=!0,this.onMenuToggle(!1),this.$nextTick(()=>{this.$refs.editingInput.focusInput()})},cancelEditing(){this.editingActive=!1},handleEditingDone(){this.$emit("update:name",this.editingValue),this.editingValue="",this.editingActive=!1},handleUndo(){this.$emit("undo")},handleFocus(){this.focused=!0},handleBlur(){this.focused=!1},handleTab(e){if(this.editingActive)return;const t=this.$el?.querySelector(".app-navigation-entry__utils");if(!t)return;const n=t.querySelector("button");this.focused&&n&&(e.preventDefault(),n.focus(),this.focused=!1)},isExternal:e=>e&&e.match(/[a-z]+:\/\//i)}},F=["id"],j=["aria-current","aria-description","aria-expanded","href","target","title","onClick"],T={key:0,class:"editingContainer"},X={key:1,class:"app-navigation-entry__deleted"},G={class:"app-navigation-entry__deleted-description"},M={key:0,class:"app-navigation-entry__counter-wrapper"},H={key:0,class:"app-navigation-entry__children"};const $=(0,s._)(I,[["render",function(e,t,n,a,s,l){const c=(0,i.g2)("NcLoadingIcon"),d=(0,i.g2)("NcInputConfirmCancel"),p=(0,i.g2)("Pencil"),u=(0,i.g2)("NcActionButton"),A=(0,i.g2)("Undo"),h=(0,i.g2)("NcActions"),v=(0,i.g2)("NcAppNavigationIconCollapsible");return(0,i.uX)(),(0,i.CE)("li",{id:n.id,class:(0,r.C4)([{"app-navigation-entry--opened":s.opened,"app-navigation-entry--pinned":n.pinned,"app-navigation-entry--collapsible":n.allowCollapse&&!!e.$slots.default},"app-navigation-entry-wrapper"])},[((0,i.uX)(),(0,i.Wv)((0,i.$y)(l.isRouterLink?"router-link":"NcVNodes"),(0,r._B)((0,i.Ng)({...l.isRouterLink&&{custom:!0,to:n.to}})),{default:(0,i.k6)(({href:m,navigate:f,isActive:g})=>[(0,i.Lk)("div",{class:(0,r.C4)(["app-navigation-entry",{"app-navigation-entry--editing":s.editingActive,"app-navigation-entry--deleted":n.undo,"app-navigation-entry--legacy":a.isLegacy34,active:n.to&&g||n.active}])},[n.undo?(0,i.Q3)("",!0):((0,i.uX)(),(0,i.CE)("a",{key:0,class:"app-navigation-entry-link","aria-current":n.active||n.to&&g?"page":void 0,"aria-description":n.ariaDescription,"aria-expanded":e.$slots.default?s.opened.toString():void 0,href:n.href||m||"#",target:l.isExternal(n.href)?"_blank":void 0,title:n.title||n.name,onBlur:t[1]||(t[1]=(...e)=>l.handleBlur&&l.handleBlur(...e)),onClick:e=>l.onClick(e,f,m),onFocus:t[2]||(t[2]=(...e)=>l.handleFocus&&l.handleFocus(...e)),onKeydown:t[3]||(t[3]=(0,o.jR)((0,o.D$)((...e)=>l.handleTab&&l.handleTab(...e),["exact"]),["tab"]))},[(0,i.Lk)("div",{class:(0,r.C4)(["app-navigation-entry-icon",{[n.icon]:n.icon}])},[n.loading?((0,i.uX)(),(0,i.Wv)(c,{key:0})):(0,i.RG)(e.$slots,"icon",{active:n.active||n.to&&g},void 0,!0,1)],2),(0,i.Lk)("span",{class:(0,r.C4)(["app-navigation-entry__name",{"hidden-visually":s.editingActive}])},(0,r.v_)(n.name),3),s.editingActive?((0,i.uX)(),(0,i.CE)("div",T,[(0,i.bF)(d,{ref:"editingInput",modelValue:s.editingValue,"onUpdate:modelValue":t[0]||(t[0]=e=>s.editingValue=e),placeholder:""!==n.editPlaceholder?n.editPlaceholder:n.name,primary:n.to&&g||n.active,onCancel:l.cancelEditing,onConfirm:l.handleEditingDone},null,8,["modelValue","placeholder","primary","onCancel","onConfirm"])])):(0,i.Q3)("",!0)],40,j)),n.undo?((0,i.uX)(),(0,i.CE)("div",X,[(0,i.Lk)("div",G,(0,r.v_)(n.name),1)])):(0,i.Q3)("",!0),(e.$slots.actions||e.$slots.counter||n.editable||n.undo)&&!s.editingActive?((0,i.uX)(),(0,i.CE)("div",{key:2,class:(0,r.C4)(["app-navigation-entry__utils",{"app-navigation-entry__utils--display-actions":n.forceDisplayActions||s.menuOpenLocalValue||n.menuOpen}])},[e.$slots.counter?((0,i.uX)(),(0,i.CE)("div",M,[(0,i.RG)(e.$slots,"counter",{},void 0,!0)])):(0,i.Q3)("",!0),e.$slots.actions||n.editable&&!s.editingActive||n.undo?((0,i.uX)(),(0,i.Wv)(h,{key:1,ref:"actions",class:"app-navigation-entry__actions",container:"#app-navigation-vue",boundariesElement:s.actionsBoundariesElement,inline:n.inlineActions,placement:n.menuPlacement,open:n.menuOpen,forceMenu:n.forceMenu,defaultIcon:n.menuIcon,variant:"tertiary","onUpdate:open":l.onMenuToggle},{icon:(0,i.k6)(()=>[(0,i.RG)(e.$slots,"menu-icon",{},void 0,!0)]),default:(0,i.k6)(()=>[n.editable&&!s.editingActive?((0,i.uX)(),(0,i.Wv)(u,{key:0,"aria-label":l.editButtonAriaLabel,onClick:l.handleEdit},{icon:(0,i.k6)(()=>[(0,i.bF)(p,{size:20})]),default:(0,i.k6)(()=>[(0,i.eW)(" "+(0,r.v_)(n.editLabel),1)]),_:1},8,["aria-label","onClick"])):(0,i.Q3)("",!0),n.undo?((0,i.uX)(),(0,i.Wv)(u,{key:1,"aria-label":l.undoButtonAriaLabel,onClick:l.handleUndo},{icon:(0,i.k6)(()=>[(0,i.bF)(A,{size:20})]),_:1},8,["aria-label","onClick"])):(0,i.Q3)("",!0),(0,i.RG)(e.$slots,"actions",{},void 0,!0)]),_:3},8,["boundariesElement","inline","placement","open","forceMenu","defaultIcon","onUpdate:open"])):(0,i.Q3)("",!0)],2)):(0,i.Q3)("",!0),n.allowCollapse&&e.$slots.default?((0,i.uX)(),(0,i.Wv)(v,{key:3,active:n.to&&g||n.active,open:s.opened,onClick:(0,o.D$)(l.toggleCollapse,["prevent","stop"])},null,8,["active","open","onClick"])):(0,i.Q3)("",!0),(0,i.RG)(e.$slots,"extra",{},void 0,!0)],2)]),_:3},16)),l.canHaveChildren&&e.$slots.default?((0,i.uX)(),(0,i.CE)("ul",H,[(0,i.RG)(e.$slots,"default",{},void 0,!0)])):(0,i.Q3)("",!0)],10,F)}],["__scopeId","data-v-6cae7342"]]);n.d(t,["N",0,$])},53411(e,t,n){n(61149);var a=n(20641),i=n(33564);const o={name:"NcAppNavigationList"},r={class:"app-navigation-list"};const s=(0,i._)(o,[["render",function(e,t,n,i,o,s){return(0,a.uX)(),(0,a.CE)("ul",r,[(0,a.RG)(e.$slots,"default",{},void 0,!0)])}],["__scopeId","data-v-d72957ed"]]);n.d(t,["N",0,s])},46123(e,t,n){n(20681);var a=n(20641),i=n(50953),o=n(90033),r=n(83868),s=n(79859),l=n(34512),c=n(50979),d=n(33564);(0,c.r)(c.v,c.C);const p=(0,a.pM)({__name:"NcAppNavigationSearch",props:(0,a.zz)({label:{type:String,default:(0,c.a)("Search …")},placeholder:{type:String,default:null}},{modelValue:{default:""},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const t=(0,a.fn)(e,"modelValue"),n=(0,a.Ht)(),d=(0,i.KR)(),{focused:p}=(0,r.RbW)(d),u=Number.parseInt(window.getComputedStyle(window.document.body).getPropertyValue("--animation-quick"))||100,A=(0,a.rk)("actionsContainer"),h=()=>!!n.actions?.({}),v=(0,i.KR)(!0),m=(0,i.KR)(),f=(0,i.KR)(!1);function g(){t.value="",h()&&(v.value=!0,(0,a.dY)(()=>A.value?.querySelector("button")?.focus()))}return(0,a.wB)(p,()=>{v.value=!p.value,window.clearTimeout(m.value),v.value?f.value=!1:window.setTimeout(()=>{f.value=!v.value},u)}),(n,r)=>((0,a.uX)(),(0,a.CE)("div",{class:(0,o.C4)(["app-navigation-search",{"app-navigation-search--has-actions":h()}])},[(0,a.bF)(l.N,{ref_key:"inputElement",ref:d,modelValue:t.value,"onUpdate:modelValue":r[0]||(r[0]=e=>t.value=e),"aria-label":e.label,class:"app-navigation-search__input",labelOutside:"",placeholder:e.placeholder??e.label,showTrailingButton:t.value.length>0,trailingButtonLabel:(0,i.R1)(c.a)("Clear search"),type:"search",onTrailingButtonClick:g},{"trailing-button-icon":(0,a.k6)(()=>[(0,a.bF)(s.I,{size:20})]),_:1},8,["modelValue","aria-label","placeholder","showTrailingButton","trailingButtonLabel"]),h()?((0,a.uX)(),(0,a.CE)("div",{key:0,ref:"actionsContainer",class:(0,o.C4)(["app-navigation-search__actions",{"app-navigation-search__actions--hidden":!v.value,"hidden-visually":f.value}])},[(0,a.RG)(n.$slots,"actions",{},void 0,!0)],2)):(0,a.Q3)("",!0)],2))}}),u=(0,d._)(p,[["__scopeId","data-v-191b6717"]]);n.d(t,["N",0,u])},4992(e,t,n){n(57674);var a=n(20641),i=n(50953),o=n(53751),r=n(90033),s=n(70711),l=n(83868),c=n(50744),d=n(20720),p=n(50979),u=n(5116),A=n(49784),h=n(33564);(0,p.r)(p.B);const v=["id"],m=(0,a.pM)({__name:"NcAppNavigationSettings",props:{excludeClickOutsideSelectors:{default:()=>[]},name:{default:()=>(0,p.a)("Settings")}},setup(e){const t=(0,u.c)(),n=(0,i.KR)(!1),p=(0,a.rk)("wrapperElement"),h=(0,a.EW)(()=>Array.isArray(e.excludeClickOutsideSelectors)?e.excludeClickOutsideSelectors:e.excludeClickOutsideSelectors.split(" "));return(0,l.X2F)(p,()=>{n.value=!1},{ignore:h}),(l,p)=>((0,a.uX)(),(0,a.CE)("div",{ref:"wrapperElement",class:(0,r.C4)(l.$style.container)},[(0,a.Lk)("div",{class:(0,r.C4)(l.$style.header)},[(0,a.bF)(c.N,{"aria-controls":(0,i.R1)(t),"aria-expanded":n.value?"true":"false",class:(0,r.C4)(l.$style.button),alignment:"start",variant:"tertiary",wide:"",onClick:p[0]||(p[0]=e=>n.value=!n.value)},{icon:(0,a.k6)(()=>[(0,a.bF)(d.N,{path:(0,i.R1)(A.a)?(0,i.R1)(s.x):(0,i.R1)(s.y)},null,8,["path"])]),default:(0,a.k6)(()=>[(0,a.eW)(" "+(0,r.v_)(e.name),1)]),_:1},8,["aria-controls","aria-expanded","class"])],2),(0,a.bF)(o.eB,{enterActiveClass:l.$style.animationActive,leaveActiveClass:l.$style.animationActive,enterFromClass:l.$style.animationStop,leaveToClass:l.$style.animationStop},{default:(0,a.k6)(()=>[(0,a.bo)((0,a.Lk)("div",{id:(0,i.R1)(t),class:(0,r.C4)(l.$style.content)},[(0,a.RG)(l.$slots,"default")],10,v),[[o.aG,n.value]])]),_:3},8,["enterActiveClass","leaveActiveClass","enterFromClass","leaveToClass"])],2))}}),f={$style:{container:"_container_2uWBM",header:"_header_jtpAp",button:"_button_9llR-",content:"_content_CW2CF",animationActive:"_animationActive_Lz0UV",animationStop:"_animationStop_lwpSi"}},g=(0,h._)(m,[["__cssModules",f]]);n.d(t,["N",0,g])},44159(e,t,n){n(6249);var a=n(20641),i=n(33564);const o={class:"app-navigation-spacer"},r=(0,a.pM)({__name:"NcAppNavigationSpacer",setup:e=>(e,t)=>((0,a.uX)(),(0,a.CE)("li",o))}),s=(0,i._)(r,[["__scopeId","data-v-277fa710"]]);n.d(t,["N",0,s])},84479(e,t,n){n(24677);var a=n(20641),i=n(50953),o=n(53751),r=n(90033),s=n(24239),l=n(50744),c=n(20720),d=n(12793),p=n(50979),u=n(49784),A=n(11122),h=n(33564);(0,p.r)(p.I);const v={class:"vue-skip-actions__container"},m={class:"vue-skip-actions__headline"},f={class:"vue-skip-actions__buttons"},g=(0,a.pM)({__name:"NcContent",props:{appName:{}},setup(e){const t=e;(0,a.Gt)(A.H,function(e){h.value=e,g.value||(g.value="navigation")}),(0,a.Gt)(A.C,"#content-vue"),(0,a.Gt)("appName",(0,a.EW)(()=>t.appName));const n=(0,d.al)(),h=(0,i.KR)(!1),g=(0,i.KR)(),C=(0,a.EW)(()=>"navigation"===g.value?'\x3c!--\n - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n--\x3e\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n':'\x3c!--\n - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n--\x3e\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n');function b(){(0,s.Ic)("toggle-navigation",{open:!0}),(0,a.dY)(()=>{window.location.hash="app-navigation-vue",document.getElementById("app-navigation-vue").focus()})}return(0,a.KC)(()=>{const e=document.getElementById("skip-actions");e&&(e.innerHTML="",e.classList.add("vue-skip-actions"))}),(t,s)=>((0,a.uX)(),(0,a.CE)("div",{id:"content-vue",class:(0,r.C4)(["content",[`app-${e.appName.toLowerCase()}`,{"content--legacy":(0,i.R1)(u.i)}]])},[((0,a.uX)(),(0,a.Wv)(a.Im,{to:"#skip-actions"},[(0,a.Lk)("div",v,[(0,a.Lk)("div",m,(0,r.v_)((0,i.R1)(p.a)("Keyboard navigation help")),1),(0,a.Lk)("div",f,[(0,a.bo)((0,a.bF)(l.N,{href:"#app-navigation-vue",variant:"tertiary",onClick:(0,o.D$)(b,["prevent"]),onFocusin:s[0]||(s[0]=e=>g.value="navigation"),onMouseover:s[1]||(s[1]=e=>g.value="navigation")},{default:(0,a.k6)(()=>[(0,a.eW)((0,r.v_)((0,i.R1)(p.a)("Skip to app navigation")),1)]),_:1},512),[[o.aG,h.value]]),(0,a.bF)(l.N,{href:"#app-content-vue",variant:"tertiary",onFocusin:s[2]||(s[2]=e=>g.value="content"),onMouseover:s[3]||(s[3]=e=>g.value="content")},{default:(0,a.k6)(()=>[(0,a.eW)((0,r.v_)((0,i.R1)(p.a)("Skip to main content")),1)]),_:1})]),(0,a.bo)((0,a.bF)(c.N,{class:"vue-skip-actions__image",svg:C.value,size:"auto"},null,8,["svg"]),[[o.aG,!(0,i.R1)(n)]])])])),(0,a.RG)(t.$slots,"default",{},void 0,!0)],2))}}),C=(0,h._)(g,[["__scopeId","data-v-d13dcb98"]]);n.d(t,["N",0,C])},5914(e,t,n){n(32404);var a=n(20641),i=n(90033),o=n(71085),r=n(33564);const s=["title"],l=(0,a.pM)({__name:"NcCounterBubble",props:{count:{},active:{type:Boolean},type:{default:""},raw:{type:Boolean}},setup(e){const t=e,n=(0,a.EW)(()=>{if(t.raw)return t.count.toString();return new Intl.NumberFormat((0,o.lO)(),{notation:"compact",compactDisplay:"short"}).format(t.count)}),r=(0,a.EW)(()=>{if(t.raw)return;const e=t.count.toString();return e!==n.value?e:void 0});return(t,o)=>((0,a.uX)(),(0,a.CE)("div",{class:(0,i.C4)(["counter-bubble__counter",{active:e.active,"counter-bubble__counter--highlighted":"highlighted"===e.type,"counter-bubble__counter--outlined":"outlined"===e.type}]),title:r.value},(0,i.v_)(n.value),11,s))}}),c=(0,r._)(l,[["__scopeId","data-v-36ffc13f"]]);n.d(t,["N",0,c])},62754(e,t,n){n(66322);var a=n(43758),i=n(79859),o=n(50979),r=n(49784),s=n(50744),l=n(20641),c=n(53751),d=n(90033),p=n(33564);(0,o.r)(o.k);const u={name:"NcInputConfirmCancel",components:{IconArrowRight:a.I,IconClose:i.I,NcButton:s.N},props:{primary:{default:!1,type:Boolean},placeholder:{default:"",type:String},modelValue:{default:"",type:String}},emits:["cancel","confirm","update:modelValue"],setup:()=>({isLegacy34:r.i}),data:()=>({labelConfirm:(0,o.a)("Confirm changes"),labelCancel:(0,o.a)("Cancel changes")}),computed:{valueModel:{get(){return this.modelValue},set(e){this.$emit("update:modelValue",e)}}},methods:{confirm(){this.$emit("confirm")},cancel(){this.$emit("cancel")},focusInput(){this.$refs.input.focus()}}},A=["placeholder"];const h=(0,p._)(u,[["render",function(e,t,n,a,i,o){const r=(0,l.g2)("IconArrowRight"),s=(0,l.g2)("NcButton"),p=(0,l.g2)("IconClose");return(0,l.uX)(),(0,l.CE)("div",{class:(0,d.C4)(["app-navigation-input-confirm",{"app-navigation-input-confirm--legacy":a.isLegacy34}])},[(0,l.Lk)("form",{onSubmit:t[1]||(t[1]=(0,c.D$)((...e)=>o.confirm&&o.confirm(...e),["prevent"])),onKeydown:t[2]||(t[2]=(0,c.jR)((0,c.D$)((...e)=>o.cancel&&o.cancel(...e),["exact","stop","prevent"]),["esc"])),onClick:t[3]||(t[3]=(0,c.D$)(()=>{},["stop","prevent"]))},[(0,l.bo)((0,l.Lk)("input",{ref:"input","onUpdate:modelValue":t[0]||(t[0]=e=>o.valueModel=e),type:"text",class:"app-navigation-input-confirm__input",placeholder:n.placeholder},null,8,A),[[c.Jo,o.valueModel]]),(0,l.bF)(s,{"aria-label":i.labelConfirm,type:"submit",variant:"primary",onClick:(0,c.D$)(o.confirm,["stop","prevent"])},{icon:(0,l.k6)(()=>[(0,l.bF)(r,{size:20})]),_:1},8,["aria-label","onClick"]),(0,l.bF)(s,{"aria-label":i.labelCancel,type:"reset",variant:n.primary?"primary":"tertiary",onClick:(0,c.D$)(o.cancel,["stop","prevent"])},{icon:(0,l.k6)(()=>[(0,l.bF)(p,{size:20})]),_:1},8,["aria-label","variant","onClick"])],32)],2)}],["__scopeId","data-v-6926a0b8"]]);n.d(t,["N",0,h])},34512(e,t,n){n(67288);var a=n(20641),i=n(50953),o=n(53751),r=n(90033),s=n(70711),l=n(50744),c=n(20720),d=n(5116),p=n(49784),u=n(33564);const A={class:"input-field__main-wrapper"},h=["id","aria-describedby","disabled","placeholder","type","value"],v=["for"],m={class:"input-field__icon input-field__icon--leading"},f={key:2,class:"input-field__icon input-field__icon--trailing"},g=["id"],C=(0,a.pM)({inheritAttrs:!1,__name:"NcInputField",props:(0,a.zz)({class:{default:""},inputClass:{default:""},id:{default:()=>(0,d.c)()},label:{default:void 0},labelOutside:{type:Boolean},type:{default:"text"},placeholder:{default:void 0},showTrailingButton:{type:Boolean},trailingButtonLabel:{default:void 0},success:{type:Boolean},error:{type:Boolean},helperText:{default:""},disabled:{type:Boolean},pill:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:(0,a.zz)(["trailingButtonClick"],["update:modelValue"]),setup(e,{expose:t,emit:n}){const d=(0,a.fn)(e,"modelValue"),u=e,C=n;t({focus:function(e){_.value.focus(e)},select:function(){_.value.select()}});const b=(0,a.OA)(),_=(0,a.rk)("input"),y=(0,a.EW)(()=>u.showTrailingButton||u.success),x=(0,a.EW)(()=>u.placeholder?u.placeholder:u.label?p.a?u.label:"":void 0),w=(0,a.EW)(()=>{const e=u.label||u.labelOutside;return e||(0,a.R8)("You need to add a label to the NcInputField component. Either use the prop label or use an external one, as per the example in the documentation."),e}),E=(0,a.EW)(()=>{const e=[];return u.helperText&&e.push(`${u.id}-helper-text`),b["aria-describedby"]&&e.push(String(b["aria-describedby"])),e.join(" ")||void 0});function k(e){const t=e.target;d.value="number"===u.type&&"number"==typeof d.value?parseFloat(t.value):t.value}return(t,n)=>((0,a.uX)(),(0,a.CE)("div",{class:(0,r.C4)(["input-field",[{"input-field--disabled":e.disabled,"input-field--error":e.error,"input-field--label-outside":e.labelOutside||!w.value,"input-field--leading-icon":!!t.$slots.icon,"input-field--trailing-icon":y.value,"input-field--pill":e.pill,"input-field--success":e.success,"input-field--legacy":(0,i.R1)(p.a)},t.$props.class]])},[(0,a.Lk)("div",A,[(0,a.Lk)("input",(0,a.v6)(t.$attrs,{id:e.id,ref:"input","aria-describedby":E.value,"aria-live":"polite",class:["input-field__input",e.inputClass],disabled:e.disabled,placeholder:x.value,type:e.type,value:d.value.toString(),onInput:k}),null,16,h),!e.labelOutside&&w.value?((0,a.uX)(),(0,a.CE)("label",{key:0,class:"input-field__label",for:e.id},(0,r.v_)(e.label),9,v)):(0,a.Q3)("",!0),(0,a.bo)((0,a.Lk)("div",m,[(0,a.RG)(t.$slots,"icon",{},void 0,!0)],512),[[o.aG,!!t.$slots.icon]]),e.showTrailingButton?((0,a.uX)(),(0,a.Wv)(l.N,{key:1,class:"input-field__trailing-button","aria-label":e.trailingButtonLabel,disabled:e.disabled,variant:"tertiary-no-background",onClick:n[0]||(n[0]=e=>C("trailingButtonClick",e))},{icon:(0,a.k6)(()=>[(0,a.RG)(t.$slots,"trailing-button-icon",{},void 0,!0)]),_:3},8,["aria-label","disabled"])):e.success||e.error?((0,a.uX)(),(0,a.CE)("div",f,[e.success?((0,a.uX)(),(0,a.Wv)(c.N,{key:0,path:(0,i.R1)(s.d)},null,8,["path"])):((0,a.uX)(),(0,a.Wv)(c.N,{key:1,path:(0,i.R1)(s.j)},null,8,["path"]))])):(0,a.Q3)("",!0)]),e.helperText?((0,a.uX)(),(0,a.CE)("p",{key:0,id:`${e.id}-helper-text`,class:"input-field__helper-text-message"},[e.success?((0,a.uX)(),(0,a.Wv)(c.N,{key:0,class:"input-field__helper-text-message__icon",path:(0,i.R1)(s.d),inline:""},null,8,["path"])):e.error?((0,a.uX)(),(0,a.Wv)(c.N,{key:1,class:"input-field__helper-text-message__icon",path:(0,i.R1)(s.j),inline:""},null,8,["path"])):(0,a.Q3)("",!0),(0,a.eW)(" "+(0,r.v_)(e.helperText),1)],8,g)):(0,a.Q3)("",!0)],2))}}),b=(0,u._)(C,[["__scopeId","data-v-feb04bef"]]);n.d(t,["N",0,b])},82108(e,t,n){const a=(0,n(20641).pM)({name:"NcVNodes",props:{vnodes:{type:[Array,Object],default:null}},render(){return this.vnodes||this.$slots?.default?.({})}});n.d(t,["_",0,a])},44783(e,t,n){n.d(t,{a:()=>c});var a=n(81222),i=n(20641),o=n(54949);let r="missing-app-name";try{r="social"}catch{o.l.error("The `@nextcloud/vue` library was used without setting / replacing the `appName`.")}const s=r;let l="";try{l="0.19.38"}catch{o.l.error("The `@nextcloud/vue` library was used without setting / replacing the `appVersion`.")}function c(){return(0,i.WQ)("appName",s)}const d=function(e){let t,n=!1;return(...a)=>(n||(n=!0,t=e(...a)),t)}(()=>{const e=(0,a.C)("core","apps",[]),t=c();return e.find(({id:e})=>e===t)?.name??t});n.d(t,["u",0,d])},11122(e,t,n){const a=Symbol.for("NcContent:setHasAppNavigation"),i=Symbol.for("NcContent:selector");n.d(t,["C",0,i,"H",0,a])},39671(e,t,n){n.d(t,{A:()=>a.N});var a=n(69052)},66828(e,t,n){n.d(t,{A:()=>a.N});var a=n(5019)},92652(e,t,n){n.d(t,{A:()=>a.N});var a=n(74795)},26985(e,t,n){n.d(t,{A:()=>a.N});var a=n(96070)},47824(e,t,n){n.d(t,{A:()=>a.N});var a=n(46123)},56643(e,t,n){n.d(t,{A:()=>a.N});var a=n(4992)},43220(e,t,n){n.d(t,{A:()=>a.N});var a=n(44159)},14676(e,t,n){n.d(t,{A:()=>a.N});var a=n(84479)},26933(e,t,n){n.d(t,{A:()=>a.N});var a=n(5914)},51773(e,t,n){var a=n(14676),i=n(39671),o=n(23447),r=n(52541),s=n(85336),l=n(57253),c=n(33953),d=n(44894),p=n(70642),u=n(81222),A=n(55705),h=n(96231),v=n(44744),m=n(89274),f=n(49124),g=n(92069),C=n(59512);const b={name:"App",components:{NcContent:a.A,NcAppContent:i.A,NcButton:o.A,Navigation:r.A,ShortcutHelp:s.A,SetupChecks:l.A},setup(){const{serverData:e}=(0,C.H)(),{cloudId:t}=(0,g.i)();return{serverData:e,cloudId:t}},data:()=>({infoHidden:!1,state:[],cloudAddress:"",shortcutHelpOpen:!1,stopShortcuts:null}),computed:{...(0,h.n2)(v.E,m.C,f.A)},watch:{$route(e){this.timelineStore.setSearchQuery("search"===e.name?String(e.params.term??""):"")}},mounted(){this.stopShortcuts=(0,c._E)(),d.A.on("shortcut:help",this.toggleShortcutHelp),d.A.on("shortcut:home",this.goHome)},unmounted(){this.stopShortcuts?.(),d.A.off("shortcut:help",this.toggleShortcutHelp),d.A.off("shortcut:home",this.goHome)},beforeMount(){if(this.settingsStore.setServerData((0,u.C)("social","serverData")),!this.serverData.public){const e=(0,u.C)("social","currentAccount",null);e?.url?(this.accountStore.setCurrentAccount(this.cloudId),this.accountStore.addAccount({actorId:e.url,data:e})):this.accountStore.fetchCurrentAccountInfo(this.cloudId)}OCA.Push&&OCA.Push.isEnabled()&&OCA.Push.addCallback(this.fromPushApp,"social")},methods:{toggleShortcutHelp(){this.shortcutHelpOpen=!this.shortcutHelpOpen},goHome(){("timeline"!==this.$route.name||this.$route.params.type)&&this.$router.push({name:"timeline"})},hideInfo(){this.infoHidden=!0},setCloudAddress(){p.Ay.post((0,A.Jv)("apps/social/api/v1/config/cloudAddress"),{cloudAddress:this.cloudAddress}).then(()=>{this.settingsStore.setServerDataEntry({key:"setup",value:!1}),this.settingsStore.setServerDataEntry({key:"cloudAddress",value:this.cloudAddress})})},search(e){const t=(e??"").trim();if(this.timelineStore.setSearchQuery(t),""===t)return void("search"===this.$route.name&&this.$router.push({name:"timeline"}));("search"===this.$route.name?this.$router.replace:this.$router.push).call(this.$router,{name:"search",params:{term:t}})},fromPushApp(e){let t="home";"tags"===this.$route.name?t="tags":this.$route.params.type&&(t=this.$route.params.type),"timeline.home"===e.source&&"home"===t&&this.timelineStore.addToTimeline([e.payload]),"timeline.direct"===e.source&&"direct"===t&&this.timelineStore.addToTimeline([e.payload])}}};n.d(t,["A",0,b])},23529(e,n,a){var i=a(66828),o=a(47824),r=a(26985),s=a(92652),l=a(43220),c=a(56643),d=a(7880),p=a(61456),u=a(23447),A=a(26933),h=a(20641),v=a(29256),m=a(15979),f=a(50752),g=a(49942),C=a(32422),b=a(97081),_=a(29390),y=a(27916),x=a(94935),w=a(81893),E=a(83265),k=a(95621),B=a(11755),S=a(38743),D=a(20818),N=a(71085),z=a(68012),L=a(70642),P=a(55705),I=a(98991),F=a(20686),j=a(57277),T=a(96231),X=a(44744),G=a(29944),M=a(85623),H=a(49124),$=a(92069);const R=(0,h.$V)(()=>Promise.all([a.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-5a196b"),a.e("src_components_ActorAvatar_vue"),a.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),a.e("composer")]).then(()=>a(51018))),W={name:"Navigation",components:{NcAppNavigation:i.A,NcAppNavigationSearch:o.A,NcAppNavigationItem:r.A,NcAppNavigationCaption:s.A,NcAppNavigationSpacer:l.A,NcAppNavigationSettings:c.A,NcAvatar:d.A,NcModal:p.A,NcButton:u.A,NcCounterBubble:A.A,Composer:R,IconHome:v.A,IconAccountCircle:_.A,IconBell:C.A,IconCommentAccount:b.A,IconHeart:x.A,IconPlus:w.A,IconBookmark:E.A,IconPound:k.A,IconAccountGroup:B.A,IconFormatListBulleted:S.A,IconCancel:I.A,IconCog:F.A,IconAlertCircle:j.A},emits:["search"],setup(){const{currentUser:e}=(0,$.i)();return{currentUser:e}},data:()=>({trending:[],lists:[],localSearch:"",showComposer:!1,composerPaths:[],showErrors:!1,stopListening:null,pollTimer:null,searchTimer:null}),computed:{...(0,T.n2)(X.E,G.O,M.t,H.A),hasErrors(){return this.errorsStore.hasErrors},errorCount(){return this.errorsStore.appErrors.length},unreadNotifications(){return this.notificationsStore.unreadNotifications},appErrors(){return this.errorsStore.appErrors},profileName(){return this.currentAccount?.display_name||this.currentUser?.displayName||this.currentUser?.uid||""},avatarUrl(){const e=this.currentUser?.uid;return e?(0,P.Jv)("/avatar/{uid}/64",{uid:e}):""},currentAccount(){return this.accountStore.currentAccount},searchQuery(){return this.timelineStore.getSearchQuery??""},menu(){return{timelines:[{key:"social-home",icon:v.A,title:t("social","My Feed"),to:{name:"timeline"},covers:["","timeline","federated"]},{key:"social-photos",icon:f.A,title:t("social","Photos"),to:{name:"timeline",params:{type:"photos"}}},{key:"social-videos",icon:g.A,title:t("social","Videos"),to:{name:"timeline",params:{type:"videos"}}},{key:"social-notifications",icon:C.A,title:t("social","Activities"),to:{name:"timeline",params:{type:"notifications"}},counter:this.unreadNotifications},{key:"social-direct",icon:b.A,title:t("social","Direct messages"),to:{name:"timeline",params:{type:"direct"}}},{key:"social-discover",icon:m.A,title:t("social","Discover"),to:{name:"discover"}}],more:[{key:"social-profile",icon:_.A,title:t("social","My profile"),to:{name:"profile",params:{account:this.currentUser?.uid}}},{key:"social-follow-requests",icon:y.A,title:t("social","Follow requests"),to:{name:"follow-requests"}},{key:"social-liked",icon:x.A,title:t("social","Liked posts"),to:{name:"timeline",params:{type:"favourites"}}},{key:"social-bookmarks",icon:E.A,title:t("social","Bookmarks"),to:{name:"timeline",params:{type:"bookmarks"}}},{key:"social-statistics",icon:D.A,title:t("social","Statistics"),to:{name:"statistics"}}]}}},watch:{showComposer(e){e||(this.composerPaths=[])},searchQuery:{immediate:!0,handler(e){this.localSearch=e}}},mounted(){this.fetchTrending(),this.fetchLists(),this.notificationsStore.fetchUnreadNotifications(),this.openComposerFromQuery(),this.stopListening=(0,z.K)("social_timeline",()=>{this.notificationsStore.fetchUnreadNotifications()}),this.stopListening||(this.pollTimer=setInterval(()=>this.notificationsStore.fetchUnreadNotifications(),6e4))},beforeUnmount(){"function"==typeof this.stopListening&&this.stopListening(),null!==this.pollTimer&&clearInterval(this.pollTimer),null!==this.searchTimer&&window.clearTimeout(this.searchTimer)},methods:{openComposerFromQuery(){const e=this.$route?.query?.attach,t=(Array.isArray(e)?e:[e]).filter(e=>"string"==typeof e&&""!==e);if(0===t.length)return;this.composerPaths=t,this.showComposer=!0;const n={...this.$route.query};delete n.attach,this.$router?.replace?.({...this.$route,query:n})},t:N.Tl,n:N.zw,async fetchTrending(){try{const{data:e}=await L.Ay.get((0,P.Jv)("apps/social/api/v1/trends/tags"),{params:{limit:5}});this.trending=Array.isArray(e)?e:[]}catch{this.trending=[]}},async fetchLists(){try{const{data:e}=await L.Ay.get((0,P.Jv)("apps/social/api/v1/lists")),t=Array.isArray(e)?e:[];this.lists=[...t.filter(e=>e.nextcloud_group),...t.filter(e=>!e.nextcloud_group)]}catch{this.lists=[]}},isListActive(e){return"list"===this.$route.name&&String(this.$route.params.id??"")===String(e.id)},usesOf:e=>Number.parseInt(e.history?.[0]?.uses??0)||0,hrefFor(e){return this.$router.resolve(e).href},navigate(e,t){t&&(t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.button>0)||(t?.preventDefault(),this.$router.push(e))},isTagActive(e){return"tags"===this.$route?.name&&this.$route?.params?.tag===e.name},dismissError(e){this.errorsStore.dismissAppError(e)},clearAllErrors(){this.errorsStore.clearErrors()},onSearchInput(){null!==this.searchTimer&&window.clearTimeout(this.searchTimer),this.searchTimer=window.setTimeout(()=>{this.searchTimer=null,this.$emit("search",this.localSearch)},300)},isActive(e){const t=this.$route,n=e.to,a=String(t.name??"");if(a!==n.name&&!a.startsWith(n.name+"."))return!1;if(void 0!==e.covers)return e.covers.includes(String(t.params.type??""));const i=n.params??{},o=t.params??{};for(const e of new Set([...Object.keys(i),...Object.keys(o)]))if(String(i[e]??"")!==String(o[e]??""))return!1;return!0}}};a.d(n,["A",0,W])},24139(e,t,n){var a=n(71085);const i={name:"SetupChecks",props:{checks:{type:Object,required:!0},addresses:{type:Object,default:()=>({configured:"",expected:""})}},computed:{addressExplanation(){return(0,a.Tl)("social","Social builds every account and post address from {configured}, but this server now reports that it lives at {expected}. Nobody looking for an account here under the address the server advertises will find it.",{configured:this.addresses.configured,expected:this.addresses.expected})}},methods:{t:a.Tl}};n.d(t,["A",0,i])},28016(e,t,n){var a=n(61456),i=n(71085),o=n(12533);const r={name:"ShortcutHelp",components:{NcModal:a.A,ShortcutList:o.A},props:{open:{type:Boolean,default:!1}},emits:["close"],methods:{t:i.Tl}};n.d(t,["A",0,r])},13549(e,t,n){var a=n(71085),i=n(33953);const o={name:"ShortcutList",computed:{shortcuts:()=>i.Ar},methods:{t:a.Tl}};n.d(t,["A",0,o])},95103(e,t,n){n.d(t,{X:()=>c});var a=n(20641),i=n(53751),o=n(90033);const r={key:0,class:"setup social__wrapper"},s={class:"hidden",for:"setup-cloud-address"},l=["placeholder"];function c(e,t,n,c,d,p){const u=(0,a.g2)("Navigation"),A=(0,a.g2)("ShortcutHelp"),h=(0,a.g2)("SetupChecks"),v=(0,a.g2)("router-view"),m=(0,a.g2)("NcAppContent"),f=(0,a.g2)("NcContent"),g=(0,a.g2)("NcButton");return c.serverData.setup?((0,a.uX)(),(0,a.Wv)(f,{key:1,appName:"social"},{default:(0,a.k6)(()=>[c.serverData.isAdmin?((0,a.uX)(),(0,a.Wv)(m,{key:0,class:"setup"},{default:(0,a.k6)(()=>[(0,a.Lk)("h2",null,(0,o.v_)(e.t("social","Social app setup")),1),(0,a.Lk)("p",null,(0,o.v_)(e.t("social","ActivityPub requires a fixed URL to make entries unique. Note that this cannot be changed later without resetting the Social app.")),1),(0,a.Lk)("form",{onSubmit:t[2]||(t[2]=(0,i.D$)((...e)=>p.setCloudAddress&&p.setCloudAddress(...e),["prevent"]))},[(0,a.Lk)("p",null,[(0,a.Lk)("label",s,(0,o.v_)(e.t("social","ActivityPub URL base")),1),(0,a.bo)((0,a.Lk)("input",{id:"setup-cloud-address","onUpdate:modelValue":t[1]||(t[1]=e=>d.cloudAddress=e),placeholder:c.serverData.cliUrl,type:"url",class:"setup-input",required:""},null,8,l),[[i.Jo,d.cloudAddress]]),(0,a.bF)(g,{variant:"primary",type:"submit"},{default:(0,a.k6)(()=>[(0,a.eW)((0,o.v_)(e.t("social","Finish setup")),1)]),_:1})]),c.serverData.checks.success?(0,a.Q3)("",!0):((0,a.uX)(),(0,a.Wv)(h,{key:0,checks:c.serverData.checks.checks,addresses:c.serverData.checks.addresses},null,8,["checks","addresses"]))],32)]),_:1})):((0,a.uX)(),(0,a.Wv)(m,{key:1,class:"setup"},{default:(0,a.k6)(()=>[(0,a.Lk)("p",null,(0,o.v_)(e.t("social","The Social app needs to be set up by the server administrator.")),1)]),_:1}))]),_:1})):((0,a.uX)(),(0,a.Wv)(f,{key:0,appName:"social",class:(0,o.C4)({public:c.serverData.public})},{default:(0,a.k6)(()=>[c.serverData.public?(0,a.Q3)("",!0):((0,a.uX)(),(0,a.Wv)(u,{key:0,onSearch:p.search},null,8,["onSearch"])),(0,a.bF)(A,{open:d.shortcutHelpOpen,onClose:t[0]||(t[0]=e=>d.shortcutHelpOpen=!1)},null,8,["open"]),(0,a.bF)(m,null,{default:(0,a.k6)(()=>[c.serverData.isAdmin&&!c.serverData.checks.success?((0,a.uX)(),(0,a.CE)("div",r,[(0,a.bF)(h,{checks:c.serverData.checks.checks,addresses:c.serverData.checks.addresses},null,8,["checks","addresses"])])):(0,a.Q3)("",!0),(0,a.bF)(v)]),_:1})]),_:1},8,["class"]))}},55e3(e,t,n){n.d(t,{X:()=>u});var a=n(20641),i=n(53751),o=n(90033);const r={class:"navigation__subname"},s={class:"navigation__footer"},l={class:"modal-composer"},c={class:"modal-errors"},d={class:"modal-errors__title"},p={class:"modal-errors__message"};function u(e,t,n,u,A,h){const v=(0,a.g2)("NcAppNavigationSearch"),m=(0,a.g2)("IconPlus"),f=(0,a.g2)("NcButton"),g=(0,a.g2)("IconAlertCircle"),C=(0,a.g2)("NcCounterBubble"),b=(0,a.g2)("NcAppNavigationItem"),_=(0,a.g2)("NcAppNavigationSpacer"),y=(0,a.g2)("NcAppNavigationCaption"),x=(0,a.g2)("IconPound"),w=(0,a.g2)("IconAccountGroup"),E=(0,a.g2)("IconFormatListBulleted"),k=(0,a.g2)("IconCancel"),B=(0,a.g2)("IconCog"),S=(0,a.g2)("NcAppNavigationSettings"),D=(0,a.g2)("NcAppNavigation"),N=(0,a.g2)("Composer"),z=(0,a.g2)("NcModal");return(0,a.uX)(),(0,a.CE)(a.FK,null,[(0,a.bF)(D,null,{search:(0,a.k6)(()=>[(0,a.bF)(v,{modelValue:A.localSearch,"onUpdate:modelValue":[t[0]||(t[0]=e=>A.localSearch=e),h.onSearchInput],label:h.t("social","Search …")},null,8,["modelValue","label","onUpdate:modelValue"])]),list:(0,a.k6)(()=>[(0,a.bF)(f,{class:"navigation__compose",variant:"primary",wide:"",alignment:"start",onClick:t[1]||(t[1]=e=>A.showComposer=!0)},{icon:(0,a.k6)(()=>[(0,a.bF)(m,{size:20})]),default:(0,a.k6)(()=>[(0,a.eW)(" "+(0,o.v_)(h.t("social","New post")),1)]),_:1}),h.hasErrors?((0,a.uX)(),(0,a.Wv)(b,{key:0,name:h.t("social","Errors"),onClick:t[2]||(t[2]=(0,i.D$)(e=>A.showErrors=!0,["prevent"]))},{icon:(0,a.k6)(()=>[(0,a.bF)(g,{class:"error-icon",size:20})]),counter:(0,a.k6)(()=>[(0,a.bF)(C,{count:h.errorCount,type:"highlighted"},null,8,["count"])]),_:1},8,["name"])):(0,a.Q3)("",!0),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(h.menu.timelines,e=>((0,a.uX)(),(0,a.Wv)(b,{key:e.key,name:e.title,href:h.hrefFor(e.to),active:h.isActive(e),onClick:t=>h.navigate(e.to,t)},(0,a.eX)({icon:(0,a.k6)(()=>[((0,a.uX)(),(0,a.Wv)((0,a.$y)(e.icon),{size:20}))]),_:2},[e.counter>0?{name:"counter",fn:(0,a.k6)(()=>[(0,a.bF)(C,{count:e.counter,type:"highlighted"},null,8,["count"])]),key:"0"}:void 0]),1032,["name","href","active","onClick"]))),128)),(0,a.bF)(_),A.trending.length>0?((0,a.uX)(),(0,a.Wv)(y,{key:1,name:h.t("social","Trending")},null,8,["name"])):(0,a.Q3)("",!0),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(A.trending,e=>((0,a.uX)(),(0,a.Wv)(b,{key:`trend-${e.name}`,class:"navigation__trend",name:`#${e.name}`,href:h.hrefFor({name:"tags",params:{tag:e.name}}),active:h.isTagActive(e),onClick:t=>h.navigate({name:"tags",params:{tag:e.name}},t)},{icon:(0,a.k6)(()=>[(0,a.bF)(x,{size:20})]),extra:(0,a.k6)(()=>[(0,a.Lk)("span",r,(0,o.v_)(h.n("social","%n post","%n posts",h.usesOf(e))),1)]),_:2},1032,["name","href","active","onClick"]))),128)),A.trending.length>0?((0,a.uX)(),(0,a.Wv)(_,{key:2})):(0,a.Q3)("",!0),A.lists.length>0?((0,a.uX)(),(0,a.Wv)(y,{key:3,name:h.t("social","Lists")},null,8,["name"])):(0,a.Q3)("",!0),((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(A.lists,e=>((0,a.uX)(),(0,a.Wv)(b,{key:`list-${e.id}`,class:"navigation__list",name:e.title,title:e.nextcloud_group?h.t("social","Everyone in the Nextcloud group {group} who has a Social account",{group:e.title}):void 0,href:h.hrefFor({name:"list",params:{id:e.id}}),active:h.isListActive(e),onClick:t=>h.navigate({name:"list",params:{id:e.id}},t)},{icon:(0,a.k6)(()=>[e.nextcloud_group?((0,a.uX)(),(0,a.Wv)(w,{key:0,size:20})):((0,a.uX)(),(0,a.Wv)(E,{key:1,size:20}))]),_:2},1032,["name","title","href","active","onClick"]))),128)),A.lists.length>0?((0,a.uX)(),(0,a.Wv)(_,{key:4})):(0,a.Q3)("",!0)]),footer:(0,a.k6)(()=>[(0,a.Lk)("div",s,[(0,a.bF)(S,{class:"navigation__more",style:(0,o.Tr)({"--social-face":`url(${h.avatarUrl})`}),name:h.profileName},{default:(0,a.k6)(()=>[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(h.menu.more,(e,t)=>((0,a.uX)(),(0,a.Wv)(b,{key:e.key,style:(0,o.Tr)({"--entry-index":t}),name:e.title,href:h.hrefFor(e.to),active:h.isActive(e),onClick:t=>h.navigate(e.to,t)},(0,a.eX)({icon:(0,a.k6)(()=>[((0,a.uX)(),(0,a.Wv)((0,a.$y)(e.icon),{size:20}))]),_:2},[e.counter>0?{name:"counter",fn:(0,a.k6)(()=>[(0,a.bF)(C,{count:e.counter,type:"highlighted"},null,8,["count"])]),key:"0"}:void 0]),1032,["style","name","href","active","onClick"]))),128)),(0,a.bF)(b,{style:(0,o.Tr)({"--entry-index":h.menu.more.length}),name:h.t("social","Blocked and muted accounts"),href:h.hrefFor({name:"blocked-accounts"}),active:h.isActive({to:{name:"blocked-accounts"}}),onClick:t[3]||(t[3]=e=>h.navigate({name:"blocked-accounts"},e))},{icon:(0,a.k6)(()=>[(0,a.bF)(k,{size:20})]),_:1},8,["style","name","href","active"]),(0,a.bF)(b,{style:(0,o.Tr)({"--entry-index":h.menu.more.length+1}),name:h.t("social","Settings"),href:h.hrefFor({name:"settings"}),active:h.isActive({to:{name:"settings"}}),onClick:t[4]||(t[4]=e=>h.navigate({name:"settings"},e))},{icon:(0,a.k6)(()=>[(0,a.bF)(B,{size:20})]),_:1},8,["style","name","href","active"])]),_:1},8,["style","name"])])]),_:1}),A.showComposer?((0,a.uX)(),(0,a.Wv)(z,{key:0,name:h.t("social","New post"),onClose:t[6]||(t[6]=e=>A.showComposer=!1)},{default:(0,a.k6)(()=>[(0,a.Lk)("div",l,[(0,a.bF)(N,{startExpanded:"",initialPaths:A.composerPaths,onPosted:t[5]||(t[5]=e=>A.showComposer=!1)},null,8,["initialPaths"])])]),_:1},8,["name"])):(0,a.Q3)("",!0),A.showErrors?((0,a.uX)(),(0,a.Wv)(z,{key:1,name:h.t("social","Errors"),onClose:t[7]||(t[7]=e=>A.showErrors=!1)},{default:(0,a.k6)(()=>[(0,a.Lk)("div",c,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(h.appErrors,e=>((0,a.uX)(),(0,a.CE)("div",{key:e.id,class:"modal-errors__item"},[(0,a.Lk)("div",d,(0,o.v_)(e.title),1),(0,a.Lk)("div",p,(0,o.v_)(e.message),1),(0,a.bF)(f,{variant:"tertiary",onClick:t=>h.dismissError(e.id)},{default:(0,a.k6)(()=>[(0,a.eW)((0,o.v_)(h.t("social","Dismiss")),1)]),_:1},8,["onClick"])]))),128)),h.appErrors.length>1?((0,a.uX)(),(0,a.Wv)(f,{key:0,variant:"tertiary",onClick:h.clearAllErrors},{default:(0,a.k6)(()=>[(0,a.eW)((0,o.v_)(h.t("social","Dismiss all")),1)]),_:1},8,["onClick"])):(0,a.Q3)("",!0)])]),_:1},8,["name"])):(0,a.Q3)("",!0)],64)}},74836(e,t,n){n.d(t,{X:()=>s});var a=n(20641),i=n(90033);const o={class:"setup-checks"},r={class:"external_link",href:"https://docs.nextcloud.com/server/latest/go.php?to=admin-setup-well-known-URL",target:"_blank",rel:"noreferrer noopener"};function s(e,t,n,s,l,c){return(0,a.uX)(),(0,a.CE)("div",o,[n.checks.wellknown?(0,a.Q3)("",!0):((0,a.uX)(),(0,a.CE)(a.FK,{key:0},[(0,a.Lk)("h3",null,(0,i.v_)(c.t("social",".well-known/webfinger isn't properly set up!")),1),(0,a.Lk)("p",null,[(0,a.eW)((0,i.v_)(c.t("social","Social needs the .well-known automatic discovery to be properly set up. If Nextcloud is not installed in the root of the domain, it is often the case that Nextcloud cannot configure this automatically. To use Social, the administrator of this Nextcloud instance needs to manually configure the .well-known redirects:"))+" ",1),(0,a.Lk)("a",r,(0,i.v_)(c.t("social","Open documentation"))+" ↗ ",1)])],64)),!1===n.checks.cloudAddress?((0,a.uX)(),(0,a.CE)(a.FK,{key:1},[(0,a.Lk)("h3",null,(0,i.v_)(c.t("social","Social is set up for a different address than this server")),1),(0,a.Lk)("p",null,(0,i.v_)(c.addressExplanation),1),(0,a.Lk)("p",null,(0,i.v_)(c.t("social",'Changing it renames every account and post that already exists here, so Social will not do it on its own. Either point the server back at the address Social knows, or reset Social with "occ social:reset" — which deletes everything it holds.')),1)],64)):(0,a.Q3)("",!0)])}},1587(e,t,n){n.d(t,{X:()=>r});var a=n(20641),i=n(90033);const o={class:"shortcuts"};function r(e,t,n,r,s,l){const c=(0,a.g2)("ShortcutList"),d=(0,a.g2)("NcModal");return n.open?((0,a.uX)(),(0,a.Wv)(d,{key:0,name:l.t("social","Keyboard shortcuts"),onClose:t[0]||(t[0]=t=>e.$emit("close"))},{default:(0,a.k6)(()=>[(0,a.Lk)("div",o,[(0,a.Lk)("h2",null,(0,i.v_)(l.t("social","Keyboard shortcuts")),1),(0,a.bF)(c)])]),_:1},8,["name"])):(0,a.Q3)("",!0)}},91655(e,t,n){n.d(t,{X:()=>s});var a=n(20641),i=n(90033);const o={class:"shortcut-list"},r={class:"shortcut-list__hint"};function s(e,t,n,s,l,c){return(0,a.uX)(),(0,a.CE)("div",o,[(0,a.Lk)("dl",null,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(c.shortcuts,e=>((0,a.uX)(),(0,a.CE)("div",{key:e.event,class:"shortcut-list__row"},[(0,a.Lk)("dt",null,[((0,a.uX)(!0),(0,a.CE)(a.FK,null,(0,a.pI)(e.keys,e=>((0,a.uX)(),(0,a.CE)("kbd",{key:e},(0,i.v_)(e),1))),128))]),(0,a.Lk)("dd",null,(0,i.v_)(e.label),1)]))),128))]),(0,a.Lk)("p",r,(0,i.v_)(c.t("social","Shortcuts are off while you are writing.")),1)])}},92069(e,t,n){n.d(t,{i:()=>r});var a=n(47606),i=n(20641),o=n(59512);function r(){const{hostname:e}=(0,o.H)(),t=(0,i.EW)(()=>(0,a.HW)()),n=(0,i.EW)(()=>t.value.uid+"@"+e.value),r=(0,i.EW)(()=>"@"+n.value);return{currentUser:t,cloudId:n,socialId:r}}},59512(e,t,n){n.d(t,{H:()=>o});var a=n(20641),i=n(89274);function o(){const e=(0,i.C)(),t=(0,a.EW)(()=>e.getServerData),n=(0,a.EW)(()=>{const e=document.createElement("a");return e.setAttribute("href",t.value.cloudAddress),e.hostname});return{serverData:t,hostname:n}}},44096(e,a,i){var o=i(53751),r=i(48089),s=i(76783),l=i(39912);const c=window.OC?.requestToken;c&&(i.nc=btoa(c)),i.p=window.OC?.linkTo("social","js/")??"/apps/social/js/";const d=(0,o.Ef)(r.A);d.config.globalProperties.t=t,d.config.globalProperties.n=n,d.config.globalProperties.OC=window.OC,d.config.globalProperties.OCA=window.OCA,d.use(s.Ay),d.use(l.A),d.mount("#content")},39912(e,t,n){var a=n(42229),i=n(55705);const o=()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--0da044"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("profile")]).then(()=>n(37512)),r=()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--0da044"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("profile")]).then(()=>n(87893)),s=()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--0da044"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("profile")]).then(()=>n(77705));const l=(0,a.aE)({history:(0,a.LA)((0,i.Jv)("/apps/social").replace(/\/+$/,"")),linkActiveClass:"active",scrollBehavior:(e,t,n)=>n||(e.hash?{el:e.hash,behavior:"smooth"}:{top:0}),routes:[{path:"/",redirect:{name:"timeline"}},{path:"/timeline/:type?",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--dbebb5"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("src_components_HashtagFollowButton_vue-src_components_TimelineSwitcher_vue"),n.e("node_modules_vue-material-design-icons_ArrowUp_vue-src_views_Timeline_vue")]).then(()=>n(49408))},props:!0,name:"timeline",children:[{path:"tags/:tag",name:"tags"},{path:"list/:id",name:"list"}]},{path:"/@:account",components:{default:o,details:r},props:!0,children:[{path:"",name:"profile",components:{details:r}},{path:"followers",name:"profile.followers",components:{details:s}},{path:"following",name:"profile.following",components:{details:s}}]},{path:"/discover",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--dbebb5"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_HashtagFollowButton_vue-src_components_TimelineSwitcher_vue"),n.e("node_modules_nextcloud_vue_dist_components_NcPopover_index_mjs-node_modules_vue-material-desi-6fd727")]).then(()=>n(24008))},name:"discover"},{path:"/follow_requests",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--0da044"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("profile")]).then(()=>n(66144))},name:"follow-requests"},{path:"/blocked",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--0da044"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("profile")]).then(()=>n(52283))},name:"blocked-accounts"},{path:"/settings",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--0da044"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("profile")]).then(()=>n(32742))},name:"settings"},{path:"/migration",redirect:{name:"settings"}},{path:"/statistics",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--0da044"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("profile")]).then(()=>n(49852))},name:"statistics"},{path:"/search/:term?",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_Search_vue")]).then(()=>n(10247))},props:!0,name:"search"},{path:"/@:account/:id",components:{default:()=>Promise.all([n.e("vendors-node_modules_nextcloud_vue_dist_components_NcActionButton_index_mjs-node_modules_next-9572c9"),n.e("vendors-node_modules_nextcloud_vue_dist_components_NcEmptyContent_index_mjs-node_modules_vue--dbebb5"),n.e("src_components_ActorAvatar_vue"),n.e("src_components_Visibility_VisibilitiesInfos_js-src_components_MediaAttachment_vue-src_compone-71be4a"),n.e("src_components_TimelineEntry_vue"),n.e("src_components_TimelineList_vue"),n.e("node_modules_vue-material-design-icons_ArrowUp_vue-src_views_TimelineSinglePost_vue")]).then(()=>n(17406))},props:!0,name:"single-post"},{path:"/ostatus/follow",components:{default:o,details:r},props:!0}]});n.d(t,["A",0,l])},44894(e,t,n){const a=(0,n(49071).A)();n.d(t,["A",0,a])},63360(e,t,n){var a=n(47606),i=n(23128);const o=null===(r=(0,a.HW)())?(0,i.YK)().setApp("social").build():(0,i.YK)().setApp("social").setUid(r.uid).build();var r;n.d(t,["A",0,o])},33953(e,n,a){a.d(n,{_E:()=>p});var i=a(44894);const o=[{keys:["j"],event:"shortcut:next",label:t("social","Next post")},{keys:["k"],event:"shortcut:previous",label:t("social","Previous post")},{keys:["l","f"],event:"shortcut:like",label:t("social","Like the post in focus")},{keys:["b"],event:"shortcut:boost",label:t("social","Boost the post in focus")},{keys:["r"],event:"shortcut:reply",label:t("social","Reply to the post in focus")},{keys:["o","Enter"],event:"shortcut:open",label:t("social","Open the post in focus")},{keys:["n"],event:"shortcut:compose",label:t("social","Write a new post")},{keys:["g"],event:"shortcut:home",label:t("social","Go to the home timeline")},{keys:["?"],event:"shortcut:help",label:t("social","Show these shortcuts")}],r=["input","textarea","select"],s=["button","a","summary","details","option","label"],l=["button","link","menuitem","menuitemcheckbox","menuitemradio","checkbox","radio","switch","tab","option","treeitem"],c=["Enter"," ","Spacebar"];function d(e){if(function(e){if(e.ctrlKey||e.metaKey||e.altKey)return!0;const t=e.target;return!(!t||"string"!=typeof t.tagName)&&(r.includes(t.tagName.toLowerCase())||!0===t.isContentEditable)}(e)||function(e){if(!c.includes(e.key))return!1;const t=e.target;if(!t||"string"!=typeof t.tagName)return!1;if(s.includes(t.tagName.toLowerCase()))return!0;const n="function"==typeof t.getAttribute?t.getAttribute("role"):null;return null!==n&&l.includes(n)}(e))return"";const t=o.find(({keys:t})=>t.includes(e.key));return void 0===t?"":t.event}function p(){const e=e=>{const t=d(e);""!==t&&(e.preventDefault(),i.A.emit(t))};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)}a.d(n,["Ar",0,o])},66981(e,t,n){function a(){return Promise.all([Promise.all([n.e("vendors-node_modules_mdi_js_mdi_js-node_modules_nextcloud_vue_dist_chunks_NcDialogButton_vue_-bd7251"),n.e("vendors-node_modules_nextcloud_dialogs_dist_index_mjs"),n.e("vendors-node_modules_nextcloud_capabilities_dist_index_mjs-node_modules_nextcloud_l10n_dist_g-2544a4"),n.e("toast")]).then(()=>n(84973)),Promise.all([n.e("vendors-node_modules_mdi_js_mdi_js-node_modules_nextcloud_vue_dist_chunks_NcDialogButton_vue_-bd7251"),n.e("vendors-node_modules_nextcloud_dialogs_dist_index_mjs"),n.e("vendors-node_modules_nextcloud_capabilities_dist_index_mjs-node_modules_nextcloud_l10n_dist_g-2544a4"),n.e("toast")]).then(()=>n(18205))]).then(([e])=>e)}async function i(e,t){return(await a()).showError(e,t)}async function o(e,t){return(await a()).showSuccess(e,t)}n.d(t,{Qg:()=>i,Te:()=>o})},44744(e,t,n){n.d(t,{E:()=>g});var a=n(70642),i=n(66981),o=n(71085),r=n(55705),s=n(96231),l=n(63360),c=n(29944),d=n(49124);function p(e,t){return{id:e,following:t,note:"",languages:[],showing_reblogs:!1,notifying:!1,followed_by:!1,blocking:!1,blocked_by:!1,muting:!1,muting_notifications:!1,requested:!1,domain_blocking:!1,endorsed:!1}}function u(e,t){return e.accountIdMap[t]}function A(e,t){return u(e,t)||t}function h(e,{actorId:t,data:n}){if(e.accounts={...e.accounts,[t]:{...e.accounts[t],...n}},void 0===e.accountsFollowers[t]&&(e.accountsFollowers={...e.accountsFollowers,[t]:[]}),void 0===e.accountsFollowings[t]&&(e.accountsFollowings={...e.accountsFollowings,[t]:[]}),!n.acct)return;const a=-1===n.acct.indexOf("@")?n.acct+"@"+new URL(n.url).hostname:n.acct;e.accountIdMap={...e.accountIdMap,[a]:n.url}}function v(e,t){const n=[];let a="";for(const i of t)n.push(i.url),h(e,{actorId:i.url,data:i}),a=i.id;return{users:n,lastId:a}}let m=new Set,f=null;const g=(0,s.nY)("account",{state:()=>({currentAccountHandle:"",accounts:{},accountsFollowers:{},accountsFollowings:{},accountsRelationships:{},accountIdMap:{},accountsFollowersMaxId:{},accountsFollowingsMaxId:{},accountsFollowersLoading:{},accountsFollowingsLoading:{},accountsFollowersAllLoaded:{},accountsFollowingsAllLoaded:{}}),getters:{getAllAccounts:e=>()=>e.accounts,getAccount:e=>t=>e.accounts[u(e,t)],getRelationshipWith:e=>t=>e.accountsRelationships[t],currentAccount(){return this.getAccount(this.currentAccountHandle)},getAccountFollowers:e=>t=>(e.accountsFollowers[A(e,t)]||[]).map(t=>e.accounts[t]).filter(Boolean),getAccountFollowing:e=>t=>(e.accountsFollowings[A(e,t)]||[]).map(t=>e.accounts[t]).filter(Boolean),getActorIdForAccount:e=>t=>u(e,t),isFollowingUser:e=>t=>{const n=u(e,t),a=n&&e.accounts[n]?.id||t;return e.accountsRelationships[a]?.following||!1}},actions:{setCurrentAccount(e){this.currentAccountHandle=e},addAccount({actorId:e,data:t}){h(this,{actorId:e,data:t})},addRelationship({actorId:e,data:t}){this.accountsRelationships={...this.accountsRelationships,[e]:t}},setFollowersLoading({actorId:e,loading:t}){this.accountsFollowersLoading={...this.accountsFollowersLoading,[e]:t}},setFollowingsLoading({actorId:e,loading:t}){this.accountsFollowingsLoading={...this.accountsFollowingsLoading,[e]:t}},setFollowersAllLoaded({actorId:e,loaded:t}){this.accountsFollowersAllLoaded={...this.accountsFollowersAllLoaded,[e]:t}},setFollowingsAllLoaded({actorId:e,loaded:t}){this.accountsFollowingsAllLoaded={...this.accountsFollowingsAllLoaded,[e]:t}},addFollowers({account:e,data:t}){const n=A(this,e),{users:a,lastId:i}=v(this,t);this.accountsFollowers={...this.accountsFollowers,[n]:a},this.accountsFollowersMaxId={...this.accountsFollowersMaxId,[n]:i},this.accountsFollowersAllLoaded={...this.accountsFollowersAllLoaded,[n]:!1}},addFollowersAppend({account:e,data:t}){const n=A(this,e),a=[...this.accountsFollowers[n]||[]],{users:i,lastId:o}=v(this,t);this.accountsFollowers={...this.accountsFollowers,[n]:[...a,...i]},this.accountsFollowersMaxId={...this.accountsFollowersMaxId,[n]:o}},addFollowing({account:e,data:t}){const n=A(this,e),{users:a,lastId:i}=v(this,t);this.accountsFollowings={...this.accountsFollowings,[n]:a},this.accountsFollowingsMaxId={...this.accountsFollowingsMaxId,[n]:i},this.accountsFollowingsAllLoaded={...this.accountsFollowingsAllLoaded,[n]:!1}},addFollowingAppend({account:e,data:t}){const n=A(this,e),a=[...this.accountsFollowings[n]||[]],{users:i,lastId:o}=v(this,t);this.accountsFollowings={...this.accountsFollowings,[n]:[...a,...i]},this.accountsFollowingsMaxId={...this.accountsFollowingsMaxId,[n]:o}},markAccountFollowed(e){const t=u(this,e),n=this.accountsFollowings[t]||[];if(this.accountsFollowings={...this.accountsFollowings,[t]:[...n,e]},t&&this.accounts[t]){const e=this.accounts[t].id;this.accountsRelationships[e]?this.accountsRelationships={...this.accountsRelationships,[e]:{...this.accountsRelationships[e],following:!0}}:e&&(this.accountsRelationships={...this.accountsRelationships,[e]:p(e,!0)})}},markAccountUnfollowed(e){const t=u(this,e),n=this.accountsFollowings[t]||[],a=n.indexOf(e);if(-1!==a){const e=[...n];e.splice(a,1),this.accountsFollowings={...this.accountsFollowings,[t]:e}}if(t&&this.accounts[t]){const e=this.accounts[t].id;this.accountsRelationships[e]?this.accountsRelationships={...this.accountsRelationships,[e]:{...this.accountsRelationships[e],following:!1}}:e&&(this.accountsRelationships={...this.accountsRelationships,[e]:p(e,!1)})}},async fetchAccountInfo(e){try{const t=await a.Ay.get((0,r.Jv)(`apps/social/api/v1/global/account/info?account=${e}`));return this.addAccount({actorId:t.data.url,data:t.data}),t.data}catch(t){l.A.error("Failed to load account details",{error:t}),(0,c.O)().addAppError({title:(0,o.Tl)("social","Account lookup failed"),message:(0,o.Tl)("social","Could not load account {account}. The remote server may be unreachable.",{account:e})})}},async fetchAccountRelationshipInfo(e){const t=(Array.isArray(e)?e:[e]).filter(e=>null!=e);if(0===t.length)return[];try{l.A.debug("Loading relationships",{count:t.length});const e=await a.Ay.get((0,r.Jv)("apps/social/api/v1/accounts/relationships"),{params:{id:t}});return e.data.forEach(e=>{this.addRelationship({actorId:e.id,data:e})}),e.data}catch(e){l.A.error("Failed to load relationship info",{error:e}),(0,i.Qg)((0,o.Tl)("social","Could not load the relationship with this account"))}},fetchRelationship(e){return null==e||void 0!==this.getRelationshipWith(e)?Promise.resolve([]):(m.add(e),null===f&&(f=new Promise(e=>{window.setTimeout(()=>{const t=[...m];m=new Set,f=null,e(this.fetchAccountRelationshipInfo(t))},30)})),f)},async fetchPublicAccountInfo(e){try{const t=await a.Ay.get((0,r.Jv)(`apps/social/api/v1/account/${e}/info`));return this.addAccount({actorId:t.data.url,data:t.data}),t.data}catch(t){l.A.error("Failed to load public account details",{error:t}),(0,c.O)().addAppError({title:(0,o.Tl)("social","Account lookup failed"),message:(0,o.Tl)("social","Could not load account {account}. The remote server may be unreachable.",{account:e})})}},fetchCurrentAccountInfo(e){this.setCurrentAccount(e),this.fetchAccountInfo(e)},async followAccount({accountToFollow:e}){try{const t=(0,r.Jv)("/apps/social/api/v1/current/follow?account="+encodeURIComponent(e)),n=await a.Ay.put(t);if(-1===n.data.status)throw new Error("The server refused the follow");return this.markAccountFollowed(e),n}catch(t){(0,i.Qg)((0,o.Tl)("social","Could not follow {account}",{account:e})),l.A.error(`Failed to follow user ${e}`,{error:t})}},async unfollowAccount({accountToUnfollow:e}){try{const t=(0,r.Jv)("/apps/social/api/v1/current/follow?account="+encodeURIComponent(e)),n=await a.Ay.delete(t);if(-1===n.data.status)throw new Error("The server refused the unfollow");return this.markAccountUnfollowed(e),n}catch(t){return(0,i.Qg)((0,o.Tl)("social","Could not unfollow {account}",{account:e})),l.A.error(`Failed to unfollow user ${e}`,{error:t}),t}},async blockAccount({id:e}){try{const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/accounts/${e}/block`));return t.data?.id&&(this.addRelationship({actorId:t.data.id,data:t.data}),(0,d.A)().removeStatusesByActor(t.data.id)),t.data}catch(e){(0,i.Qg)((0,o.Tl)("social","Failed to block the account")),l.A.error("Failed to block the account",{error:e})}},async unblockAccount({id:e}){try{const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/accounts/${e}/unblock`));return t.data?.id&&this.addRelationship({actorId:t.data.id,data:t.data}),t.data}catch(e){(0,i.Qg)((0,o.Tl)("social","Failed to unblock the account")),l.A.error("Failed to unblock the account",{error:e})}},async muteAccount({id:e}){try{const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/accounts/${e}/mute`));return t.data?.id&&(this.addRelationship({actorId:t.data.id,data:t.data}),(0,d.A)().removeStatusesByActor(t.data.id)),t.data}catch(e){(0,i.Qg)((0,o.Tl)("social","Failed to mute the account")),l.A.error("Failed to mute the account",{error:e})}},async unmuteAccount({id:e}){try{const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/accounts/${e}/unmute`));return t.data?.id&&this.addRelationship({actorId:t.data.id,data:t.data}),t.data}catch(e){(0,i.Qg)((0,o.Tl)("social","Failed to unmute the account")),l.A.error("Failed to unmute the account",{error:e})}},async fetchAccountFollowers({account:e,maxId:t}={}){const n=A(this,e);if(!this.accountsFollowersLoading[n]){this.setFollowersLoading({actorId:n,loading:!0});try{const i={};t&&(i.max_id=t);const o=await a.Ay.get((0,r.Jv)(`apps/social/api/v1/accounts/${e}/followers`),{params:i});return t?this.addFollowersAppend({account:e,data:o.data}):this.addFollowers({account:e,data:o.data}),o.data.length<20&&this.setFollowersAllLoaded({actorId:n,loaded:!0}),o.data}catch(t){(0,i.Qg)((0,o.Tl)("social","Could not load the list of followers")),l.A.error(`Failed to fetch followers list for user ${e}`,{error:t})}finally{this.setFollowersLoading({actorId:n,loading:!1})}}},async fetchAccountFollowing({account:e,maxId:t}={}){const n=A(this,e);if(!this.accountsFollowingsLoading[n]){this.setFollowingsLoading({actorId:n,loading:!0});try{const i={};t&&(i.max_id=t);const o=await a.Ay.get((0,r.Jv)(`apps/social/api/v1/accounts/${e}/following`),{params:i});return t?this.addFollowingAppend({account:e,data:o.data}):this.addFollowing({account:e,data:o.data}),o.data.length<20&&this.setFollowingsAllLoaded({actorId:n,loaded:!0}),o.data}catch(t){(0,i.Qg)((0,o.Tl)("social","Could not load the list of followed accounts")),l.A.error(`Failed to fetch following list for user ${e}`,{error:t})}finally{this.setFollowingsLoading({actorId:n,loading:!1})}}}}})},29944(e,t,n){var a=n(96231),i=n(63360);let o=0;const r=(0,a.nY)("errors",{state:()=>({errors:[]}),getters:{appErrors:e=>e.errors,hasErrors:e=>e.errors.length>0},actions:{addError({title:e,message:t}){this.errors=[...this.errors,{id:++o,title:e,message:t}]},dismissError(e){this.errors=this.errors.filter(t=>t.id!==e)},clearErrors(){this.errors=[]},addAppError({title:e,message:t}){i.A.error("App error",{title:e,message:t}),this.addError({title:e,message:t})},dismissAppError(e){this.dismissError(e)}}});n.d(t,["O",0,r])},76783(e,t,n){var a=n(96231);n(44744),n(29944),n(85623),n(89274),n(49124);const i=(0,a.Ey)();n.d(t,["Ay",0,i])},85623(e,t,n){var a=n(70642),i=n(66981),o=n(71085),r=n(55705),s=n(96231),l=n(63360);const c=(0,s.nY)("notifications",{state:()=>({unread:0}),getters:{unreadNotifications:e=>e.unread},actions:{setUnreadNotifications(e){this.unread=e},async fetchUnreadNotifications(){try{const{data:e}=await a.Ay.get((0,r.Jv)("apps/social/api/v1/notifications/unread_count"));this.setUnreadNotifications(Number(e?.count)||0)}catch(e){l.A.error("Failed to read the unread notification count",{error:e})}},async markNotificationsRead(e){if(e){this.setUnreadNotifications(0);try{await a.Ay.post((0,r.Jv)("apps/social/api/v1/markers"),{notifications:{last_read_id:String(e)}})}catch(e){(0,i.Qg)((0,o.Tl)("social","Could not save your place in the notifications")),l.A.error("Failed to move the notifications marker",{error:e}),this.fetchUnreadNotifications()}}}}});n.d(t,["t",0,c])},89274(e,t,n){const a=(0,n(96231).nY)("settings",{state:()=>({serverData:{}}),getters:{getServerData:e=>e.serverData},actions:{setServerData(e){this.serverData=e},setServerDataEntry({key:e,value:t}){this.serverData[e]=t}}});n.d(t,["C",0,a])},49124(e,t,n){n.d(t,{A:()=>h});var a=n(70642),i=n(66981),o=n(71085),r=n(55705),s=n(96231),l=n(63360),c=n(44744);const d="social.firstPostCelebrated";function p(e,t){null!=t&&void 0!==t.id&&(e.statuses[t.id]=t,void 0!==t.reblog&&null!==t.reblog&&(e.statuses[t.reblog.id]=t.reblog))}function u(e,t){return t.map(t=>e.statuses[t]).filter(Boolean).map(e=>({status:e,at:Date.parse(e.created_at)})).sort((e,t)=>t.at-e.at).map(e=>e.status)}function A(e,t){const n=new Set(e);for(const a of t)n.has(a.id)||(n.add(a.id),e.push(a.id))}const h=(0,s.nY)("timeline",{state:()=>({statuses:{},timeline:[],parentsTimeline:[],removedFrom:{},type:"home",params:{},account:"",composerDisplayStatus:!1,searchQuery:"",firstPostCelebration:!1,firstPostCelebrated:!1}),getters:{getComposerDisplayStatus:e=>e.composerDisplayStatus,getTimeline:e=>u(e,e.timeline),getParentsTimeline:e=>u(e,e.parentsTimeline),getSearchQuery:e=>e.searchQuery,isCelebratingFirstPost:e=>e.firstPostCelebration,getTimelineIdentity:e=>JSON.stringify([e.type,e.account,e.params]),getStatus:e=>t=>e.statuses[t],getSinglePost:e=>e.statuses[e.params.singlePost],getPostFromTimeline:e=>t=>{if(void 0!==e.statuses[t])return e.statuses[t];l.A.warn("Could not find status in timeline",{statusId:t})}},actions:{addToStatuses(e){p(this,e)},addToTimeline(e){Array.isArray(e)?(e.forEach(e=>p(this,e)),A(this.timeline,e)):(e.descendants.forEach(e=>p(this,e)),e.ancestors.forEach(e=>p(this,e)),A(this.timeline,e.descendants),A(this.parentsTimeline,e.ancestors))},removeStatus(e){const t=this.timeline.indexOf(e.id);-1!==t&&this.timeline.splice(t,1);const n=this.parentsTimeline.indexOf(e.id);-1!==n&&this.parentsTimeline.splice(n,1),this.removedFrom={...this.removedFrom,[e.id]:-1!==n?"parents":"timeline"},delete this.statuses[e.id]},restoreStatus(e){p(this,e);const t="parents"===this.removedFrom?.[e.id]?"parentsTimeline":"timeline";-1===this[t].indexOf(e.id)&&this[t].push(e.id);const n={...this.removedFrom};delete n[e.id],this.removedFrom=n},forgetRemoval(e){if(void 0===this.removedFrom[e.id])return;const t={...this.removedFrom};delete t[e.id],this.removedFrom=t},removeStatusesByActor(e){const t=String(e),n=new Set(Object.values(this.statuses).filter(e=>String(e?.account?.id)===t||e?.reblog&&String(e.reblog.account?.id)===t).map(e=>e.id));if(0===n.size)return;this.timeline=this.timeline.filter(e=>!n.has(e)),this.parentsTimeline=this.parentsTimeline.filter(e=>!n.has(e));const a={...this.statuses};n.forEach(e=>delete a[e]),this.statuses=a},resetTimeline(){this.timeline=[],this.parentsTimeline=[],this.statuses={},this.removedFrom={}},setTimelineType(e){this.type=e},setTimelineParams(e){this.params=e},setComposerDisplayStatus(e){this.composerDisplayStatus=e},setAccount(e){this.account=e},setSearchQuery(e){this.searchQuery=e},startFirstPostCelebration(){this.firstPostCelebration=!0,this.firstPostCelebrated=!0},likeStatus({status:e}){const t=this.statuses[e.id];void 0!==t&&(this.statuses[e.id]={...t,favourited:!0,favourites_count:(t.favourites_count??0)+1})},unlikeStatus({status:e}){const t=this.statuses[e.id];void 0!==t&&(this.statuses[e.id]={...t,favourited:!1,favourites_count:Math.max((t.favourites_count??0)-1,0)})},boostStatus({status:e}){const t=this.statuses[e.id];void 0!==t&&(this.statuses[e.id]={...t,reblogged:!0,reblogs_count:(t.reblogs_count??0)+1})},unboostStatus({status:e}){const t=this.statuses[e.id];void 0!==t&&(this.statuses[e.id]={...t,reblogged:!1,reblogs_count:Math.max((t.reblogs_count??0)-1,0)})},updateStatusPoll({statusId:e,poll:t}){const n=this.statuses[e];void 0!==n&&(this.statuses[e]={...n,poll:t})},bookmarkStatus({status:e,bookmarked:t}){void 0!==this.statuses[e.id]&&(this.statuses[e.id]={...this.statuses[e.id],bookmarked:t})},pinStatus({status:e,pinned:t}){void 0!==this.statuses[e.id]&&(this.statuses[e.id]={...this.statuses[e.id],pinned:t})},updateStatus(e){void 0!==this.statuses[e.id]&&(this.statuses[e.id]=e)},celebrateFirstPost(){return!this.firstPostCelebration&&!this.firstPostCelebrated&&(0===(0,c.E)().currentAccount?.statuses_count&&(!function(){try{return null!==window.localStorage.getItem(d)}catch{return!1}}()&&(function(){try{window.localStorage.setItem(d,String(Date.now()))}catch{}}(),this.startFirstPostCelebration(),!0)))},endFirstPostCelebration(){this.firstPostCelebration=!1},changeTimelineType({type:e,params:t}){this.resetTimeline(),this.setTimelineType(e),this.setTimelineParams(t),this.setAccount("")},changeTimelineTypeAccount(e,t=""){this.resetTimeline(),this.setTimelineType("account"),this.setTimelineParams(""===t?{}:{media:t}),this.setAccount(e)},async describeMedia({id:e,description:t}){try{await a.Ay.put((0,r.Jv)("apps/social/api/v1/media/"+e),{description:t})}catch(e){(0,i.Qg)((0,o.Tl)("social","Could not save the description of an attachment")),l.A.error("Failed to describe a media",{error:e})}},async createMedia(e){const t=e instanceof File?e:e.file,n=e instanceof File?void 0:e.onProgress;try{const e=new FormData;e.append("file",t);const{data:i}=await a.Ay.post((0,r.Jv)("apps/social/api/v1/media"),e,{headers:{"Content-Type":"multipart/form-data"},onUploadProgress:"function"==typeof n?e=>n(e.total?Math.min(e.loaded/e.total,1):0):void 0});return l.A.info("Media created with id "+i.id),i}catch(e){(0,i.Qg)((0,o.Tl)("social","Could not upload the attachment")),l.A.error("Failed to create a media",{error:e})}},async createMediaFromFile({path:e,description:t=""}){try{const{data:n}=await a.Ay.post((0,r.Jv)("apps/social/api/v1/media/from-file"),{path:e,description:t});return l.A.info("Media created from "+e+" with id "+n.id),n}catch(t){(0,i.Qg)((0,o.Tl)("social","Could not attach {file}",{file:e})),l.A.error("Failed to attach a file from Nextcloud",{error:t})}},async post(e){try{const{data:t}=await a.Ay.post((0,r.Jv)("apps/social/api/v1/statuses"),e);return l.A.info("Post created",t.id),t}catch(e){(0,i.Qg)((0,o.Tl)("social","Could not send the post")),l.A.error("Failed to create a status",{error:e})}},async postEdit({status:e,content:t,spoiler_text:n,sensitive:s}){try{const i=await a.Ay.put((0,r.Jv)(`apps/social/api/v1/statuses/${e.id}`),{status:t,spoiler_text:n,sensitive:s});return this.updateStatus(i.data),l.A.info("Post edited",i.data.id),i}catch(e){(0,i.Qg)((0,o.Tl)("social","Could not save the changes to the post")),l.A.error("Failed to edit the status",{error:e})}},async postDelete(e){try{this.removeStatus(e);const t=await a.Ay.delete((0,r.Jv)(`apps/social/api/v1/post?id=${e.uri}`));l.A.info("Post deleted with token "+t.data.result.token)}catch(t){this.restoreStatus(e),(0,i.Qg)((0,o.Tl)("social","Could not delete the post")),l.A.error("Failed to delete the status",{error:t})}},async fetchStatus(e){try{const t=await a.Ay.get((0,r.Jv)(`apps/social/api/v1/statuses/${e}`));return this.addToStatuses(t.data),t.data}catch(t){return l.A.debug("Could not load a single status",{error:t,id:e}),null}},async postLike({status:e}){try{this.likeStatus({status:e});const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/statuses/${e.id}/favourite`));return l.A.info("Post liked"),this.addToStatuses(t.data),t}catch(t){this.unlikeStatus({status:e}),(0,i.Qg)((0,o.Tl)("social","Could not like the post")),l.A.error("Failed to like status",{error:t})}},async postUnlike({status:e}){try{"favourites"===this.type&&this.removeStatus(e),this.unlikeStatus({status:e});const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/statuses/${e.id}/unfavourite`));return l.A.info("Post unliked"),this.addToStatuses(t.data),this.forgetRemoval(e),t}catch(t){"favourites"===this.type?this.restoreStatus(e):this.likeStatus({status:e}),(0,i.Qg)((0,o.Tl)("social","Could not remove the like")),l.A.error("Failed to unlike status",{error:t})}},async postBoost({status:e}){try{this.boostStatus({status:e});const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/statuses/${e.id}/reblog`));return l.A.info("Post boosted"),this.addToStatuses(t.data),t}catch(t){this.unboostStatus({status:e}),(0,i.Qg)((0,o.Tl)("social","Could not boost the post")),l.A.error("Failed to create a boost status",{error:t})}},async postUnBoost({status:e}){try{this.unboostStatus({status:e});const t=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/statuses/${e.id}/unreblog`));return l.A.info("Boost deleted"),this.addToStatuses(t.data),t}catch(t){this.boostStatus({status:e}),(0,i.Qg)((0,o.Tl)("social","Could not undo the boost")),l.A.error("Failed to delete the boost",{error:t})}},async postBookmark({status:e,bookmarked:t}){this.bookmarkStatus({status:e,bookmarked:t});try{const n=t?"bookmark":"unbookmark",i=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/statuses/${e.id}/${n}`));return l.A.info(t?"Post bookmarked":"Bookmark removed"),this.addToStatuses(i.data),t||"bookmarks"!==this.type||(this.removeStatus(e),this.forgetRemoval(e)),i}catch(n){this.bookmarkStatus({status:e,bookmarked:!t}),(0,i.Qg)(t?(0,o.Tl)("social","Could not bookmark the post"):(0,o.Tl)("social","Could not remove the bookmark")),l.A.error("Failed to change the bookmark",{error:n})}},async postPin({status:e,pinned:t}){this.pinStatus({status:e,pinned:t});try{const n=t?"pin":"unpin",i=await a.Ay.post((0,r.Jv)(`apps/social/api/v1/statuses/${e.id}/${n}`));return l.A.info(t?"Post pinned":"Post unpinned"),this.addToStatuses(i.data),i}catch(n){this.pinStatus({status:e,pinned:!t}),(0,i.Qg)(t?(0,o.Tl)("social","Could not pin the post"):(0,o.Tl)("social","Could not unpin the post")),l.A.error("Failed to change the pinned state",{error:n})}},refreshTimeline(){return this.fetchTimeline()},async fetchTimeline(e={}){let t;switch(void 0===e.limit&&(e.limit=15),this.type){case"account":t=(0,r.Jv)(`apps/social/api/v1/accounts/${this.account}/statuses`),"image"!==this.params.media&&"video"!==this.params.media||(e.only_media=!0,e.media_type=this.params.media);break;case"tags":t=(0,r.Jv)(`apps/social/api/v1/timelines/tag/${this.params.tag}`);break;case"list":t=(0,r.Jv)(`apps/social/api/v1/timelines/list/${this.params.id}`);break;case"single-post":t=(0,r.Jv)(`apps/social/api/v1/statuses/${this.params.id}/context`);break;case"timeline":t=(0,r.Jv)("apps/social/api/v1/timelines/public"),e.local=!0;break;case"federated":t=(0,r.Jv)("apps/social/api/v1/timelines/public");break;case"photos":case"videos":"timeline"===this.params.scope||"federated"===this.params.scope?(t=(0,r.Jv)("apps/social/api/v1/timelines/public"),"timeline"===this.params.scope&&(e.local=!0)):t=(0,r.Jv)("apps/social/api/v1/timelines/home"),e.only_media=!0,"videos"===this.type&&(e.only_video=!0);break;case"notifications":t=(0,r.Jv)("apps/social/api/v1/notifications");break;case"bookmarks":t=(0,r.Jv)("apps/social/api/v1/bookmarks");break;default:t=(0,r.Jv)(`apps/social/api/v1/timelines/${this.type}`)}const n=this.getTimelineIdentity,i=await a.Ay.get(t,{params:e});return this.getTimelineIdentity!==n?(l.A.debug("Dropped a page that belongs to a timeline no longer on screen",{identity:n}),[]):(this.addToTimeline(i.data),i.data)}}})},8173(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-a28923a1] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-details-toggle[data-v-a28923a1] {\n position: sticky;\n width: var(--default-clickable-area);\n height: var(--default-clickable-area);\n padding: calc((var(--default-clickable-area) - 16px) / 2);\n cursor: pointer;\n opacity: 0.6;\n transform: rotate(180deg);\n background-color: var(--color-main-background);\n z-index: 2000;\n top: var(--app-navigation-padding);\n inset-inline-start: calc(var(--default-clickable-area) + var(--app-navigation-padding) * 2);\n}\n.app-details-toggle--mobile[data-v-a28923a1] {\n inset-inline-start: var(--app-navigation-padding);\n}\n.app-details-toggle[data-v-a28923a1]:active, .app-details-toggle[data-v-a28923a1]:hover, .app-details-toggle[data-v-a28923a1]:focus {\n opacity: 1;\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-51427d61] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-content[data-v-51427d61] {\n position: initial;\n z-index: 1000;\n flex-basis: 100vw;\n height: 100%;\n margin: 0 !important;\n background-color: var(--color-main-background);\n min-width: 0;\n}\n.app-content[data-v-51427d61]:not(.app-content--has-list) {\n overflow: auto;\n}\n.app-content-wrapper[data-v-51427d61] {\n position: relative;\n width: 100%;\n height: 100%;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-list[data-v-51427d61] .app-content-list {\n display: flex;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-list[data-v-51427d61] .app-content-details {\n display: none;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-details[data-v-51427d61] .app-content-list {\n display: none;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-details[data-v-51427d61] .app-content-details {\n display: block;\n}\n[data-v-51427d61] .splitpanes.default-theme .app-content-list {\n max-width: none;\n /* Thin scrollbar is hard to catch on resizable columns */\n scrollbar-width: auto;\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane {\n background-color: transparent;\n transition: none;\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-list {\n min-width: 300px;\n position: sticky;\n}\n@media only screen and (width < 1024px) {\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-list {\n display: none;\n}\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-details {\n overflow-y: auto;\n}\n@media only screen and (width < 1024px) {\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-details {\n min-width: 100%;\n}\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__splitter {\n background-color: var(--color-main-background);\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__splitter::before,[data-v-51427d61] .splitpanes.default-theme .splitpanes__splitter::after {\n background-color: var(--color-border);\n}\n[data-v-51427d61] .splitpanes.default-theme.splitpanes--vertical .splitpanes__splitter {\n border-inline-start: 1px solid var(--color-border);\n}\n[data-v-51427d61] .splitpanes.default-theme.splitpanes--horizontal .splitpanes__splitter {\n border-top: 1px solid var(--color-border);\n}\n.app-content-wrapper--show-list[data-v-51427d61] .app-content-list {\n max-width: none;\n}\n.app-content-wrapper__list[data-v-51427d61] {\n height: 100%;\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppContent.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,gBAAgB;EAChB,oCAAoC;EACpC,qCAAqC;EACrC,yDAAyD;EACzD,eAAe;EACf,YAAY;EACZ,yBAAyB;EACzB,8CAA8C;EAC9C,aAAa;EACb,kCAAkC;EAClC,2FAA2F;AAC7F;AACA;EACE,iDAAiD;AACnD;AACA;EACE,UAAU;AACZ,CAAC;;;EAGC;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,iBAAiB;EACjB,aAAa;EACb,iBAAiB;EACjB,YAAY;EACZ,oBAAoB;EACpB,8CAA8C;EAC9C,YAAY;AACd;AACA;EACE,cAAc;AAChB;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,YAAY;AACd;AACA;EACE,aAAa;AACf;AACA;EACE,aAAa;AACf;AACA;EACE,aAAa;AACf;AACA;EACE,cAAc;AAChB;AACA;EACE,eAAe;EACf,yDAAyD;EACzD,qBAAqB;AACvB;AACA;EACE,6BAA6B;EAC7B,gBAAgB;AAClB;AACA;EACE,gBAAgB;EAChB,gBAAgB;AAClB;AACA;AACA;IACI,aAAa;AACjB;AACA;AACA;EACE,gBAAgB;AAClB;AACA;AACA;IACI,eAAe;AACnB;AACA;AACA;EACE,8CAA8C;AAChD;AACA;EACE,qCAAqC;AACvC;AACA;EACE,kDAAkD;AACpD;AACA;EACE,yCAAyC;AAC3C;AACA;EACE,eAAe;AACjB;AACA;EACE,YAAY;AACd",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-a28923a1] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-details-toggle[data-v-a28923a1] {\n position: sticky;\n width: var(--default-clickable-area);\n height: var(--default-clickable-area);\n padding: calc((var(--default-clickable-area) - 16px) / 2);\n cursor: pointer;\n opacity: 0.6;\n transform: rotate(180deg);\n background-color: var(--color-main-background);\n z-index: 2000;\n top: var(--app-navigation-padding);\n inset-inline-start: calc(var(--default-clickable-area) + var(--app-navigation-padding) * 2);\n}\n.app-details-toggle--mobile[data-v-a28923a1] {\n inset-inline-start: var(--app-navigation-padding);\n}\n.app-details-toggle[data-v-a28923a1]:active, .app-details-toggle[data-v-a28923a1]:hover, .app-details-toggle[data-v-a28923a1]:focus {\n opacity: 1;\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-51427d61] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-content[data-v-51427d61] {\n position: initial;\n z-index: 1000;\n flex-basis: 100vw;\n height: 100%;\n margin: 0 !important;\n background-color: var(--color-main-background);\n min-width: 0;\n}\n.app-content[data-v-51427d61]:not(.app-content--has-list) {\n overflow: auto;\n}\n.app-content-wrapper[data-v-51427d61] {\n position: relative;\n width: 100%;\n height: 100%;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-list[data-v-51427d61] .app-content-list {\n display: flex;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-list[data-v-51427d61] .app-content-details {\n display: none;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-details[data-v-51427d61] .app-content-list {\n display: none;\n}\n.app-content-wrapper--no-split.app-content-wrapper--show-details[data-v-51427d61] .app-content-details {\n display: block;\n}\n[data-v-51427d61] .splitpanes.default-theme .app-content-list {\n max-width: none;\n /* Thin scrollbar is hard to catch on resizable columns */\n scrollbar-width: auto;\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane {\n background-color: transparent;\n transition: none;\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-list {\n min-width: 300px;\n position: sticky;\n}\n@media only screen and (width < 1024px) {\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-list {\n display: none;\n}\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-details {\n overflow-y: auto;\n}\n@media only screen and (width < 1024px) {\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__pane-details {\n min-width: 100%;\n}\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__splitter {\n background-color: var(--color-main-background);\n}\n[data-v-51427d61] .splitpanes.default-theme .splitpanes__splitter::before,[data-v-51427d61] .splitpanes.default-theme .splitpanes__splitter::after {\n background-color: var(--color-border);\n}\n[data-v-51427d61] .splitpanes.default-theme.splitpanes--vertical .splitpanes__splitter {\n border-inline-start: 1px solid var(--color-border);\n}\n[data-v-51427d61] .splitpanes.default-theme.splitpanes--horizontal .splitpanes__splitter {\n border-top: 1px solid var(--color-border);\n}\n.app-content-wrapper--show-list[data-v-51427d61] .app-content-list {\n max-width: none;\n}\n.app-content-wrapper__list[data-v-51427d61] {\n height: 100%;\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},3370(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-e8177cc7] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-toggle-wrapper[data-v-e8177cc7] {\n position: absolute;\n top: var(--app-navigation-padding);\n inset-inline-end: calc(0px - var(--app-navigation-padding));\n margin-inline-end: calc(-1 * var(--default-clickable-area));\n}\nbutton.app-navigation-toggle[data-v-e8177cc7] {\n background-color: var(--color-main-background);\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation,\n.app-content {\n /** Distance of the app navigation toggle and the first navigation item to the top edge of the app content container */\n --app-navigation-padding: calc(var(--default-grid-baseline, 4px) * 2);\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-37908cd4] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation[data-v-37908cd4] {\n --color-text-maxcontrast: var(--color-text-maxcontrast-background-blur, var(--color-text-maxcontrast-default));\n transition: transform var(--animation-slow), margin var(--animation-slow);\n width: 300px;\n --app-navigation-max-width: calc(100vw - (var(--app-navigation-padding) + var(--default-clickable-area) + var(--default-grid-baseline)));\n max-width: var(--app-navigation-max-width);\n position: relative;\n top: 0;\n inset-inline-start: 0;\n padding: 0px;\n z-index: 1800;\n height: 100%;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n flex-grow: 0;\n flex-shrink: 0;\n background-color: transparent;\n}\n.app-navigation--legacy[data-v-37908cd4] {\n background-color: var(--color-main-background-blur, var(--color-main-background));\n backdrop-filter: var(--filter-background-blur, none);\n}\n.app-navigation--closed[data-v-37908cd4] {\n margin-inline-start: calc(-1 * min(300px, var(--app-navigation-max-width)));\n}\n.app-navigation__search[data-v-37908cd4] {\n width: 100%;\n}\n.app-navigation__body[data-v-37908cd4] {\n overflow-y: scroll;\n}\n.app-navigation__content > ul[data-v-37908cd4] {\n position: relative;\n width: 100%;\n overflow-x: hidden;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: var(--default-grid-baseline, 4px);\n padding: var(--app-navigation-padding);\n}\n.app-navigation .app-navigation__list[data-v-37908cd4] {\n height: 100%;\n}\n.app-navigation__body--no-list[data-v-37908cd4] {\n flex: 1 1 auto;\n overflow: auto;\n height: 100%;\n}\n.app-navigation__content[data-v-37908cd4] {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n[data-themes*=highcontrast] .app-navigation[data-v-37908cd4] {\n border-inline-end: 1px solid var(--color-border);\n}\n@media only screen and (width < 1024px) {\n.app-navigation[data-v-37908cd4] {\n position: absolute;\n border-inline-end: 1px solid var(--color-border);\n background-color: var(--color-main-background-blur, var(--color-main-background));\n backdrop-filter: var(--filter-background-blur, none);\n}\n}\n@media only screen and (max-width: 512px) {\n.app-navigation[data-v-37908cd4] {\n z-index: 1400;\n}\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppNavigation.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,kBAAkB;EAClB,kCAAkC;EAClC,2DAA2D;EAC3D,2DAA2D;AAC7D;AACA;EACE,8CAA8C;AAChD,CAAC;;;EAGC;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;;EAEE,sHAAsH;EACtH,qEAAqE;AACvE,CAAC;;;EAGC;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,8GAA8G;EAC9G,yEAAyE;EACzE,YAAY;EACZ,wIAAwI;EACxI,0CAA0C;EAC1C,kBAAkB;EAClB,MAAM;EACN,qBAAqB;EACrB,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,yBAAyB;EACzB,sBAAsB;EACtB,qBAAqB;EACrB,iBAAiB;EACjB,YAAY;EACZ,cAAc;EACd,6BAA6B;AAC/B;AACA;EACE,iFAAiF;EACjF,oDAAoD;AACtD;AACA;EACE,2EAA2E;AAC7E;AACA;EACE,WAAW;AACb;AACA;EACE,kBAAkB;AACpB;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,kBAAkB;EAClB,gBAAgB;EAChB,aAAa;EACb,sBAAsB;EACtB,sCAAsC;EACtC,sCAAsC;AACxC;AACA;EACE,YAAY;AACd;AACA;EACE,cAAc;EACd,cAAc;EACd,YAAY;AACd;AACA;EACE,YAAY;EACZ,aAAa;EACb,sBAAsB;AACxB;AACA;EACE,gDAAgD;AAClD;AACA;AACA;IACI,kBAAkB;IAClB,gDAAgD;IAChD,iFAAiF;IACjF,oDAAoD;AACxD;AACA;AACA;AACA;IACI,aAAa;AACjB;AACA",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-e8177cc7] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-toggle-wrapper[data-v-e8177cc7] {\n position: absolute;\n top: var(--app-navigation-padding);\n inset-inline-end: calc(0px - var(--app-navigation-padding));\n margin-inline-end: calc(-1 * var(--default-clickable-area));\n}\nbutton.app-navigation-toggle[data-v-e8177cc7] {\n background-color: var(--color-main-background);\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation,\n.app-content {\n /** Distance of the app navigation toggle and the first navigation item to the top edge of the app content container */\n --app-navigation-padding: calc(var(--default-grid-baseline, 4px) * 2);\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-37908cd4] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation[data-v-37908cd4] {\n --color-text-maxcontrast: var(--color-text-maxcontrast-background-blur, var(--color-text-maxcontrast-default));\n transition: transform var(--animation-slow), margin var(--animation-slow);\n width: 300px;\n --app-navigation-max-width: calc(100vw - (var(--app-navigation-padding) + var(--default-clickable-area) + var(--default-grid-baseline)));\n max-width: var(--app-navigation-max-width);\n position: relative;\n top: 0;\n inset-inline-start: 0;\n padding: 0px;\n z-index: 1800;\n height: 100%;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n flex-grow: 0;\n flex-shrink: 0;\n background-color: transparent;\n}\n.app-navigation--legacy[data-v-37908cd4] {\n background-color: var(--color-main-background-blur, var(--color-main-background));\n backdrop-filter: var(--filter-background-blur, none);\n}\n.app-navigation--closed[data-v-37908cd4] {\n margin-inline-start: calc(-1 * min(300px, var(--app-navigation-max-width)));\n}\n.app-navigation__search[data-v-37908cd4] {\n width: 100%;\n}\n.app-navigation__body[data-v-37908cd4] {\n overflow-y: scroll;\n}\n.app-navigation__content > ul[data-v-37908cd4] {\n position: relative;\n width: 100%;\n overflow-x: hidden;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: var(--default-grid-baseline, 4px);\n padding: var(--app-navigation-padding);\n}\n.app-navigation .app-navigation__list[data-v-37908cd4] {\n height: 100%;\n}\n.app-navigation__body--no-list[data-v-37908cd4] {\n flex: 1 1 auto;\n overflow: auto;\n height: 100%;\n}\n.app-navigation__content[data-v-37908cd4] {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n[data-themes*=highcontrast] .app-navigation[data-v-37908cd4] {\n border-inline-end: 1px solid var(--color-border);\n}\n@media only screen and (width < 1024px) {\n.app-navigation[data-v-37908cd4] {\n position: absolute;\n border-inline-end: 1px solid var(--color-border);\n background-color: var(--color-main-background-blur, var(--color-main-background));\n backdrop-filter: var(--filter-background-blur, none);\n}\n}\n@media only screen and (max-width: 512px) {\n.app-navigation[data-v-37908cd4] {\n z-index: 1400;\n}\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},66458(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-f0e411c2] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-caption[data-v-f0e411c2] {\n display: flex;\n justify-content: space-between;\n}\n.app-navigation-caption--heading[data-v-f0e411c2] {\n padding: var(--app-navigation-padding);\n}\n.app-navigation-caption--heading[data-v-f0e411c2]:not(:first-child):not(:last-child) {\n padding: 0 var(--app-navigation-padding);\n}\n.app-navigation-caption__name[data-v-f0e411c2] {\n font-weight: var(--font-weight-heading, bold);\n color: var(--color-main-text);\n font-size: var(--default-font-size);\n line-height: var(--default-clickable-area);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n box-shadow: none !important;\n flex-shrink: 0;\n padding-block: 0;\n padding-inline: calc(var(--default-grid-baseline, 4px) * 2) 0;\n margin-top: 0px;\n margin-bottom: var(--default-grid-baseline);\n}\n.app-navigation-caption__actions[data-v-f0e411c2] {\n flex: 0 0 var(--default-clickable-area);\n}\n.app-navigation-caption[data-v-f0e411c2]:not(:first-child) {\n margin-top: calc(var(--default-clickable-area) / 2);\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppNavigationCaption.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,aAAa;EACb,8BAA8B;AAChC;AACA;EACE,sCAAsC;AACxC;AACA;EACE,wCAAwC;AAC1C;AACA;EACE,6CAA6C;EAC7C,6BAA6B;EAC7B,mCAAmC;EACnC,0CAA0C;EAC1C,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;EACvB,2BAA2B;EAC3B,cAAc;EACd,gBAAgB;EAChB,6DAA6D;EAC7D,eAAe;EACf,2CAA2C;AAC7C;AACA;EACE,uCAAuC;AACzC;AACA;EACE,mDAAmD;AACrD",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-f0e411c2] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-caption[data-v-f0e411c2] {\n display: flex;\n justify-content: space-between;\n}\n.app-navigation-caption--heading[data-v-f0e411c2] {\n padding: var(--app-navigation-padding);\n}\n.app-navigation-caption--heading[data-v-f0e411c2]:not(:first-child):not(:last-child) {\n padding: 0 var(--app-navigation-padding);\n}\n.app-navigation-caption__name[data-v-f0e411c2] {\n font-weight: var(--font-weight-heading, bold);\n color: var(--color-main-text);\n font-size: var(--default-font-size);\n line-height: var(--default-clickable-area);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n box-shadow: none !important;\n flex-shrink: 0;\n padding-block: 0;\n padding-inline: calc(var(--default-grid-baseline, 4px) * 2) 0;\n margin-top: 0px;\n margin-bottom: var(--default-grid-baseline);\n}\n.app-navigation-caption__actions[data-v-f0e411c2] {\n flex: 0 0 var(--default-clickable-area);\n}\n.app-navigation-caption[data-v-f0e411c2]:not(:first-child) {\n margin-top: calc(var(--default-clickable-area) / 2);\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},66923(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,'/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-cfbd3794] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.icon-collapse[data-v-cfbd3794] {\n position: relative;\n inset-inline-end: 0;\n}\n.icon-collapse[data-v-cfbd3794]:hover {\n background-color: var(--color-background-dark) !important;\n}\n.icon-collapse--active[data-v-cfbd3794]:hover {\n background-color: var(--color-primary-element) !important;\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-6cae7342] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n\n/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n.app-navigation-entry[data-v-6cae7342] {\n position: relative;\n display: flex;\n flex-shrink: 0;\n flex-wrap: wrap;\n width: 100%;\n min-height: var(--default-clickable-area);\n transition: background-color var(--animation-quick) ease-in-out;\n transition: background-color 200ms ease-in-out;\n border-radius: var(--border-radius-element);\n}\n.app-navigation-entry-wrapper[data-v-6cae7342] {\n position: relative;\n display: flex;\n flex-shrink: 0;\n flex-wrap: wrap;\n width: 100%;\n}\n.app-navigation-entry-wrapper.app-navigation-entry--collapsible:not(.app-navigation-entry--opened) > ul[data-v-6cae7342] {\n display: none;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active[data-v-6cae7342] {\n background-color: color-mix(in srgb, var(--color-primary-element) 16%, transparent) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active[data-v-6cae7342]:hover {\n background-color: color-mix(in srgb, var(--color-primary-element) 22%, transparent) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active:not(.app-navigation-entry--editing) .app-navigation-entry-link[data-v-6cae7342],\n.app-navigation-entry:not(.app-navigation-entry--legacy).active:not(.app-navigation-entry--editing) .app-navigation-entry-button[data-v-6cae7342] {\n color: var(--color-main-text) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active[data-v-6cae7342]:not(.app-navigation-entry--editing)::before {\n content: "";\n position: absolute;\n inset-block: calc(var(--default-grid-baseline, 4px) * 2);\n inset-inline-start: 0;\n width: 3px;\n background-color: var(--color-primary-element);\n border-radius: 999px;\n animation: nc-nav-stripe-in-6cae7342 var(--animation-quick, 200ms) ease-out;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active[data-v-6cae7342] {\n background-color: var(--color-primary-element) !important;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active[data-v-6cae7342]:hover {\n background-color: var(--color-primary-element-hover) !important;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active .app-navigation-entry-link[data-v-6cae7342], .app-navigation-entry.app-navigation-entry--legacy.active .app-navigation-entry-button[data-v-6cae7342] {\n color: var(--color-primary-element-text) !important;\n}\n.app-navigation-entry[data-v-6cae7342]:focus-within, .app-navigation-entry[data-v-6cae7342]:hover {\n background-color: var(--color-background-hover);\n}\n.app-navigation-entry[data-v-6cae7342]:not(.app-navigation-entry--legacy):focus-within, .app-navigation-entry[data-v-6cae7342]:not(.app-navigation-entry--legacy):hover {\n background-color: color-mix(in srgb, var(--color-primary-element) 8%, transparent);\n}\n.app-navigation-entry.active .app-navigation-entry__children[data-v-6cae7342], .app-navigation-entry:focus-within .app-navigation-entry__children[data-v-6cae7342], .app-navigation-entry:hover .app-navigation-entry__children[data-v-6cae7342] {\n background-color: var(--color-main-background);\n}\n.app-navigation-entry.active .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry.app-navigation-entry--deleted .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry:focus .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry:focus-within .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry:hover .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342] {\n position: relative;\n opacity: 1;\n pointer-events: auto;\n}\n.app-navigation-entry .app-navigation-entry__actions[data-v-6cae7342]:hover .button-vue {\n background-color: var(--color-background-dark) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active .app-navigation-entry__actions[data-v-6cae7342]:hover .button-vue {\n background-color: var(--color-background-dark) !important;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active .app-navigation-entry__actions[data-v-6cae7342]:hover .button-vue {\n background-color: var(--color-primary-element) !important;\n}\n.app-navigation-entry[data-v-6cae7342] {\n /* hide deletion/collapse of subitems */\n}\n.app-navigation-entry.app-navigation-entry--deleted > ul[data-v-6cae7342] {\n display: none;\n}\n.app-navigation-entry:not(.app-navigation-entry--editing) .app-navigation-entry-link[data-v-6cae7342], .app-navigation-entry:not(.app-navigation-entry--editing) .app-navigation-entry-button[data-v-6cae7342] {\n padding-inline-end: calc((var(--default-clickable-area) - 16px) / 2);\n}\n.app-navigation-entry .app-navigation-entry-link[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button[data-v-6cae7342] {\n z-index: 100; /* above the bullet to allow click*/\n display: flex;\n overflow: hidden;\n flex: 1 1 0;\n min-height: var(--default-clickable-area);\n padding: 0;\n white-space: nowrap;\n color: var(--color-main-text);\n font-weight: 500;\n background-repeat: no-repeat;\n background-position: calc((var(--default-clickable-area) - 16px) / 2) center;\n background-size: 16px 16px;\n line-height: var(--default-clickable-area);\n}\n.app-navigation-entry .app-navigation-entry-link .app-navigation-entry-icon[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button .app-navigation-entry-icon[data-v-6cae7342] {\n display: flex;\n align-items: center;\n flex: 0 0 var(--default-clickable-area);\n justify-content: center;\n width: var(--default-clickable-area);\n height: var(--default-clickable-area);\n background-size: 16px 16px;\n background-repeat: no-repeat;\n background-position: calc((var(--default-clickable-area) - 16px) / 2) center;\n}\n.app-navigation-entry .app-navigation-entry-link .app-navigation-entry__name[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button .app-navigation-entry__name[data-v-6cae7342] {\n overflow: hidden;\n max-width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-weight: var(--font-weight-element, normal);\n}\n.app-navigation-entry .app-navigation-entry-link .editingContainer[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button .editingContainer[data-v-6cae7342] {\n width: calc(100% - var(--default-clickable-area));\n margin: auto;\n}\n.app-navigation-entry .app-navigation-entry-link[data-v-6cae7342]:focus-visible, .app-navigation-entry .app-navigation-entry-button[data-v-6cae7342]:focus-visible {\n box-shadow: 0 0 0 4px var(--color-main-background);\n outline: 2px solid var(--color-main-text);\n border-radius: var(--border-radius-element);\n}\n\n/* Second level nesting for lists */\n.app-navigation-entry__children[data-v-6cae7342] {\n --app-navigation-item-child-offset: 10px;\n position: relative;\n display: flex;\n flex: 0 1 auto;\n flex-direction: column;\n width: 100%;\n gap: var(--default-grid-baseline, 4px);\n padding-inline-start: var(--app-navigation-item-child-offset);\n}\n.app-navigation-entry__children .app-navigation-entry[data-v-6cae7342] {\n display: inline-flex;\n flex-wrap: wrap;\n}\n.app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children[data-v-6cae7342] {\n --app-navigation-item-child-offset: 0;\n}\n\n/* Deleted entries */\n.app-navigation-entry__deleted[data-v-6cae7342] {\n display: inline-flex;\n flex: 1 1 0;\n padding-inline-start: calc(var(--default-clickable-area) - (var(--default-clickable-area) - 16px) / 2) !important;\n}\n.app-navigation-entry__deleted .app-navigation-entry__deleted-description[data-v-6cae7342] {\n position: relative;\n overflow: hidden;\n flex: 1 1 0;\n white-space: nowrap;\n text-overflow: ellipsis;\n line-height: var(--default-clickable-area);\n}\n\n/* counter and actions */\n.app-navigation-entry__utils[data-v-6cae7342] {\n display: flex;\n min-width: var(--default-clickable-area);\n align-items: center;\n flex: 0 1 auto;\n justify-content: flex-end;\n}\n.app-navigation-entry__utils.app-navigation-entry__utils--display-actions .action-item.app-navigation-entry__actions[data-v-6cae7342] {\n position: relative;\n opacity: 1;\n pointer-events: auto;\n}\n.app-navigation-entry__utils[data-v-6cae7342] {\n /* counter */\n}\n.app-navigation-entry__utils .app-navigation-entry__counter-wrapper[data-v-6cae7342] {\n margin-inline-end: calc(var(--default-grid-baseline) * 2);\n display: flex;\n align-items: center;\n flex: 0 1 auto;\n}\n.app-navigation-entry__utils[data-v-6cae7342] {\n /* actions */\n}\n.app-navigation-entry__utils .action-item.app-navigation-entry__actions[data-v-6cae7342] {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n/* editing state */\n.app-navigation-entry--editing .app-navigation-entry-edit[data-v-6cae7342] {\n z-index: 250;\n opacity: 1;\n}\n\n/* deleted state */\n.app-navigation-entry--deleted .app-navigation-entry-deleted[data-v-6cae7342] {\n z-index: 250;\n transform: translateX(0);\n}\n\n/* pinned state */\n.app-navigation-entry--pinned[data-v-6cae7342] {\n order: 2;\n margin-top: auto;\n}\n.app-navigation-entry--pinned ~ .app-navigation-entry--pinned[data-v-6cae7342] {\n margin-top: 0;\n}\n[data-themes*=highcontrast] .app-navigation-entry[data-v-6cae7342]:active {\n background-color: var(--color-primary-element-light-hover) !important;\n}\n@keyframes nc-nav-stripe-in-6cae7342 {\nfrom {\n transform: scaleY(0);\n opacity: 0;\n}\nto {\n transform: scaleY(1);\n opacity: 1;\n}\n}',"",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppNavigationItem.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,kBAAkB;EAClB,mBAAmB;AACrB;AACA;EACE,yDAAyD;AAC3D;AACA;EACE,yDAAyD;AAC3D,CAAC;;;EAGC;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;;AAEA;;;EAGE;AACF;EACE,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,eAAe;EACf,WAAW;EACX,yCAAyC;EACzC,+DAA+D;EAC/D,8CAA8C;EAC9C,2CAA2C;AAC7C;AACA;EACE,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,eAAe;EACf,WAAW;AACb;AACA;EACE,aAAa;AACf;AACA;EACE,8FAA8F;AAChG;AACA;EACE,8FAA8F;AAChG;AACA;;EAEE,wCAAwC;AAC1C;AACA;EACE,WAAW;EACX,kBAAkB;EAClB,wDAAwD;EACxD,qBAAqB;EACrB,UAAU;EACV,8CAA8C;EAC9C,oBAAoB;EACpB,2EAA2E;AAC7E;AACA;EACE,yDAAyD;AAC3D;AACA;EACE,+DAA+D;AACjE;AACA;EACE,mDAAmD;AACrD;AACA;EACE,+CAA+C;AACjD;AACA;EACE,kFAAkF;AACpF;AACA;EACE,8CAA8C;AAChD;AACA;EACE,kBAAkB;EAClB,UAAU;EACV,oBAAoB;AACtB;AACA;EACE,yDAAyD;AAC3D;AACA;EACE,yDAAyD;AAC3D;AACA;EACE,yDAAyD;AAC3D;AACA;EACE,uCAAuC;AACzC;AACA;EACE,aAAa;AACf;AACA;EACE,oEAAoE;AACtE;AACA;EACE,YAAY,EAAE,mCAAmC;EACjD,aAAa;EACb,gBAAgB;EAChB,WAAW;EACX,yCAAyC;EACzC,UAAU;EACV,mBAAmB;EACnB,6BAA6B;EAC7B,gBAAgB;EAChB,4BAA4B;EAC5B,4EAA4E;EAC5E,0BAA0B;EAC1B,0CAA0C;AAC5C;AACA;EACE,aAAa;EACb,mBAAmB;EACnB,uCAAuC;EACvC,uBAAuB;EACvB,oCAAoC;EACpC,qCAAqC;EACrC,0BAA0B;EAC1B,4BAA4B;EAC5B,4EAA4E;AAC9E;AACA;EACE,gBAAgB;EAChB,eAAe;EACf,mBAAmB;EACnB,uBAAuB;EACvB,+CAA+C;AACjD;AACA;EACE,iDAAiD;EACjD,YAAY;AACd;AACA;EACE,kDAAkD;EAClD,yCAAyC;EACzC,2CAA2C;AAC7C;;AAEA,mCAAmC;AACnC;EACE,wCAAwC;EACxC,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,sBAAsB;EACtB,WAAW;EACX,sCAAsC;EACtC,6DAA6D;AAC/D;AACA;EACE,oBAAoB;EACpB,eAAe;AACjB;AACA;EACE,qCAAqC;AACvC;;AAEA,oBAAoB;AACpB;EACE,oBAAoB;EACpB,WAAW;EACX,iHAAiH;AACnH;AACA;EACE,kBAAkB;EAClB,gBAAgB;EAChB,WAAW;EACX,mBAAmB;EACnB,uBAAuB;EACvB,0CAA0C;AAC5C;;AAEA,wBAAwB;AACxB;EACE,aAAa;EACb,wCAAwC;EACxC,mBAAmB;EACnB,cAAc;EACd,yBAAyB;AAC3B;AACA;EACE,kBAAkB;EAClB,UAAU;EACV,oBAAoB;AACtB;AACA;EACE,YAAY;AACd;AACA;EACE,yDAAyD;EACzD,aAAa;EACb,mBAAmB;EACnB,cAAc;AAChB;AACA;EACE,YAAY;AACd;AACA;EACE,kBAAkB;EAClB,UAAU;EACV,oBAAoB;AACtB;;AAEA,kBAAkB;AAClB;EACE,YAAY;EACZ,UAAU;AACZ;;AAEA,kBAAkB;AAClB;EACE,YAAY;EACZ,wBAAwB;AAC1B;;AAEA,iBAAiB;AACjB;EACE,QAAQ;EACR,gBAAgB;AAClB;AACA;EACE,aAAa;AACf;AACA;EACE,qEAAqE;AACvE;AACA;AACA;IACI,oBAAoB;IACpB,UAAU;AACd;AACA;IACI,oBAAoB;IACpB,UAAU;AACd;AACA",sourcesContent:['/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-cfbd3794] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.icon-collapse[data-v-cfbd3794] {\n position: relative;\n inset-inline-end: 0;\n}\n.icon-collapse[data-v-cfbd3794]:hover {\n background-color: var(--color-background-dark) !important;\n}\n.icon-collapse--active[data-v-cfbd3794]:hover {\n background-color: var(--color-primary-element) !important;\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-6cae7342] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n\n/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n.app-navigation-entry[data-v-6cae7342] {\n position: relative;\n display: flex;\n flex-shrink: 0;\n flex-wrap: wrap;\n width: 100%;\n min-height: var(--default-clickable-area);\n transition: background-color var(--animation-quick) ease-in-out;\n transition: background-color 200ms ease-in-out;\n border-radius: var(--border-radius-element);\n}\n.app-navigation-entry-wrapper[data-v-6cae7342] {\n position: relative;\n display: flex;\n flex-shrink: 0;\n flex-wrap: wrap;\n width: 100%;\n}\n.app-navigation-entry-wrapper.app-navigation-entry--collapsible:not(.app-navigation-entry--opened) > ul[data-v-6cae7342] {\n display: none;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active[data-v-6cae7342] {\n background-color: color-mix(in srgb, var(--color-primary-element) 16%, transparent) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active[data-v-6cae7342]:hover {\n background-color: color-mix(in srgb, var(--color-primary-element) 22%, transparent) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active:not(.app-navigation-entry--editing) .app-navigation-entry-link[data-v-6cae7342],\n.app-navigation-entry:not(.app-navigation-entry--legacy).active:not(.app-navigation-entry--editing) .app-navigation-entry-button[data-v-6cae7342] {\n color: var(--color-main-text) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active[data-v-6cae7342]:not(.app-navigation-entry--editing)::before {\n content: "";\n position: absolute;\n inset-block: calc(var(--default-grid-baseline, 4px) * 2);\n inset-inline-start: 0;\n width: 3px;\n background-color: var(--color-primary-element);\n border-radius: 999px;\n animation: nc-nav-stripe-in-6cae7342 var(--animation-quick, 200ms) ease-out;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active[data-v-6cae7342] {\n background-color: var(--color-primary-element) !important;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active[data-v-6cae7342]:hover {\n background-color: var(--color-primary-element-hover) !important;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active .app-navigation-entry-link[data-v-6cae7342], .app-navigation-entry.app-navigation-entry--legacy.active .app-navigation-entry-button[data-v-6cae7342] {\n color: var(--color-primary-element-text) !important;\n}\n.app-navigation-entry[data-v-6cae7342]:focus-within, .app-navigation-entry[data-v-6cae7342]:hover {\n background-color: var(--color-background-hover);\n}\n.app-navigation-entry[data-v-6cae7342]:not(.app-navigation-entry--legacy):focus-within, .app-navigation-entry[data-v-6cae7342]:not(.app-navigation-entry--legacy):hover {\n background-color: color-mix(in srgb, var(--color-primary-element) 8%, transparent);\n}\n.app-navigation-entry.active .app-navigation-entry__children[data-v-6cae7342], .app-navigation-entry:focus-within .app-navigation-entry__children[data-v-6cae7342], .app-navigation-entry:hover .app-navigation-entry__children[data-v-6cae7342] {\n background-color: var(--color-main-background);\n}\n.app-navigation-entry.active .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry.app-navigation-entry--deleted .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry:focus .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry:focus-within .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342], .app-navigation-entry:hover .app-navigation-entry__utils .app-navigation-entry__actions[data-v-6cae7342] {\n position: relative;\n opacity: 1;\n pointer-events: auto;\n}\n.app-navigation-entry .app-navigation-entry__actions[data-v-6cae7342]:hover .button-vue {\n background-color: var(--color-background-dark) !important;\n}\n.app-navigation-entry:not(.app-navigation-entry--legacy).active .app-navigation-entry__actions[data-v-6cae7342]:hover .button-vue {\n background-color: var(--color-background-dark) !important;\n}\n.app-navigation-entry.app-navigation-entry--legacy.active .app-navigation-entry__actions[data-v-6cae7342]:hover .button-vue {\n background-color: var(--color-primary-element) !important;\n}\n.app-navigation-entry[data-v-6cae7342] {\n /* hide deletion/collapse of subitems */\n}\n.app-navigation-entry.app-navigation-entry--deleted > ul[data-v-6cae7342] {\n display: none;\n}\n.app-navigation-entry:not(.app-navigation-entry--editing) .app-navigation-entry-link[data-v-6cae7342], .app-navigation-entry:not(.app-navigation-entry--editing) .app-navigation-entry-button[data-v-6cae7342] {\n padding-inline-end: calc((var(--default-clickable-area) - 16px) / 2);\n}\n.app-navigation-entry .app-navigation-entry-link[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button[data-v-6cae7342] {\n z-index: 100; /* above the bullet to allow click*/\n display: flex;\n overflow: hidden;\n flex: 1 1 0;\n min-height: var(--default-clickable-area);\n padding: 0;\n white-space: nowrap;\n color: var(--color-main-text);\n font-weight: 500;\n background-repeat: no-repeat;\n background-position: calc((var(--default-clickable-area) - 16px) / 2) center;\n background-size: 16px 16px;\n line-height: var(--default-clickable-area);\n}\n.app-navigation-entry .app-navigation-entry-link .app-navigation-entry-icon[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button .app-navigation-entry-icon[data-v-6cae7342] {\n display: flex;\n align-items: center;\n flex: 0 0 var(--default-clickable-area);\n justify-content: center;\n width: var(--default-clickable-area);\n height: var(--default-clickable-area);\n background-size: 16px 16px;\n background-repeat: no-repeat;\n background-position: calc((var(--default-clickable-area) - 16px) / 2) center;\n}\n.app-navigation-entry .app-navigation-entry-link .app-navigation-entry__name[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button .app-navigation-entry__name[data-v-6cae7342] {\n overflow: hidden;\n max-width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-weight: var(--font-weight-element, normal);\n}\n.app-navigation-entry .app-navigation-entry-link .editingContainer[data-v-6cae7342], .app-navigation-entry .app-navigation-entry-button .editingContainer[data-v-6cae7342] {\n width: calc(100% - var(--default-clickable-area));\n margin: auto;\n}\n.app-navigation-entry .app-navigation-entry-link[data-v-6cae7342]:focus-visible, .app-navigation-entry .app-navigation-entry-button[data-v-6cae7342]:focus-visible {\n box-shadow: 0 0 0 4px var(--color-main-background);\n outline: 2px solid var(--color-main-text);\n border-radius: var(--border-radius-element);\n}\n\n/* Second level nesting for lists */\n.app-navigation-entry__children[data-v-6cae7342] {\n --app-navigation-item-child-offset: 10px;\n position: relative;\n display: flex;\n flex: 0 1 auto;\n flex-direction: column;\n width: 100%;\n gap: var(--default-grid-baseline, 4px);\n padding-inline-start: var(--app-navigation-item-child-offset);\n}\n.app-navigation-entry__children .app-navigation-entry[data-v-6cae7342] {\n display: inline-flex;\n flex-wrap: wrap;\n}\n.app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children .app-navigation-entry__children[data-v-6cae7342] {\n --app-navigation-item-child-offset: 0;\n}\n\n/* Deleted entries */\n.app-navigation-entry__deleted[data-v-6cae7342] {\n display: inline-flex;\n flex: 1 1 0;\n padding-inline-start: calc(var(--default-clickable-area) - (var(--default-clickable-area) - 16px) / 2) !important;\n}\n.app-navigation-entry__deleted .app-navigation-entry__deleted-description[data-v-6cae7342] {\n position: relative;\n overflow: hidden;\n flex: 1 1 0;\n white-space: nowrap;\n text-overflow: ellipsis;\n line-height: var(--default-clickable-area);\n}\n\n/* counter and actions */\n.app-navigation-entry__utils[data-v-6cae7342] {\n display: flex;\n min-width: var(--default-clickable-area);\n align-items: center;\n flex: 0 1 auto;\n justify-content: flex-end;\n}\n.app-navigation-entry__utils.app-navigation-entry__utils--display-actions .action-item.app-navigation-entry__actions[data-v-6cae7342] {\n position: relative;\n opacity: 1;\n pointer-events: auto;\n}\n.app-navigation-entry__utils[data-v-6cae7342] {\n /* counter */\n}\n.app-navigation-entry__utils .app-navigation-entry__counter-wrapper[data-v-6cae7342] {\n margin-inline-end: calc(var(--default-grid-baseline) * 2);\n display: flex;\n align-items: center;\n flex: 0 1 auto;\n}\n.app-navigation-entry__utils[data-v-6cae7342] {\n /* actions */\n}\n.app-navigation-entry__utils .action-item.app-navigation-entry__actions[data-v-6cae7342] {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n/* editing state */\n.app-navigation-entry--editing .app-navigation-entry-edit[data-v-6cae7342] {\n z-index: 250;\n opacity: 1;\n}\n\n/* deleted state */\n.app-navigation-entry--deleted .app-navigation-entry-deleted[data-v-6cae7342] {\n z-index: 250;\n transform: translateX(0);\n}\n\n/* pinned state */\n.app-navigation-entry--pinned[data-v-6cae7342] {\n order: 2;\n margin-top: auto;\n}\n.app-navigation-entry--pinned ~ .app-navigation-entry--pinned[data-v-6cae7342] {\n margin-top: 0;\n}\n[data-themes*=highcontrast] .app-navigation-entry[data-v-6cae7342]:active {\n background-color: var(--color-primary-element-light-hover) !important;\n}\n@keyframes nc-nav-stripe-in-6cae7342 {\nfrom {\n transform: scaleY(0);\n opacity: 0;\n}\nto {\n transform: scaleY(1);\n opacity: 1;\n}\n}'],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},55730(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-d72957ed] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-list[data-v-d72957ed] {\n position: relative;\n width: 100%;\n overflow-x: hidden;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: var(--default-grid-baseline, 4px);\n padding: var(--app-navigation-padding);\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppNavigationList.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,kBAAkB;EAClB,gBAAgB;EAChB,aAAa;EACb,sBAAsB;EACtB,sCAAsC;EACtC,sCAAsC;AACxC",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-d72957ed] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-list[data-v-d72957ed] {\n position: relative;\n width: 100%;\n overflow-x: hidden;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: var(--default-grid-baseline, 4px);\n padding: var(--app-navigation-padding);\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},60922(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-191b6717] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-search[data-v-191b6717] {\n display: flex;\n gap: var(--app-navigation-padding);\n padding: var(--app-navigation-padding);\n}\n.app-navigation-search__input[data-v-191b6717] {\n --input-padding-end: calc(var(--default-clickable-area) - var(--default-grid-baseline));\n}\n.app-navigation-search--has-actions .app-navigation-search__input[data-v-191b6717] {\n flex-grow: 1;\n z-index: 3;\n}\n.app-navigation-search__actions[data-v-191b6717] {\n display: flex;\n gap: var(--default-grid-baseline);\n margin-inline-start: 0;\n max-width: calc(2 * var(--default-clickable-area) + var(--default-grid-baseline));\n max-height: var(--default-clickable-area);\n transition: margin-inline-start var(--animation-quick);\n}\n.app-navigation-search__actions--hidden[data-v-191b6717] {\n margin-inline-start: calc(-1 * var(--default-clickable-area));\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppNavigationSearch.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,aAAa;EACb,kCAAkC;EAClC,sCAAsC;AACxC;AACA;EACE,uFAAuF;AACzF;AACA;EACE,YAAY;EACZ,UAAU;AACZ;AACA;EACE,aAAa;EACb,iCAAiC;EACjC,sBAAsB;EACtB,iFAAiF;EACjF,yCAAyC;EACzC,sDAAsD;AACxD;AACA;EACE,6DAA6D;AAC/D",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-191b6717] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-search[data-v-191b6717] {\n display: flex;\n gap: var(--app-navigation-padding);\n padding: var(--app-navigation-padding);\n}\n.app-navigation-search__input[data-v-191b6717] {\n --input-padding-end: calc(var(--default-clickable-area) - var(--default-grid-baseline));\n}\n.app-navigation-search--has-actions .app-navigation-search__input[data-v-191b6717] {\n flex-grow: 1;\n z-index: 3;\n}\n.app-navigation-search__actions[data-v-191b6717] {\n display: flex;\n gap: var(--default-grid-baseline);\n margin-inline-start: 0;\n max-width: calc(2 * var(--default-clickable-area) + var(--default-grid-baseline));\n max-height: var(--default-clickable-area);\n transition: margin-inline-start var(--animation-quick);\n}\n.app-navigation-search__actions--hidden[data-v-191b6717] {\n margin-inline-start: calc(-1 * var(--default-clickable-area));\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},83337(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"\n._container_2uWBM {\n\tmargin-top: auto;\n\tpadding: var(--default-grid-baseline);\n}\n._header_jtpAp {\n\tmargin-block: 0 var(--default-grid-baseline);\n\tmargin-inline: var(--default-grid-baseline);\n}\n\n/* Overwrite the padding to match NcAppNavigationItem */\n._button_9llR- {\n\tpadding-inline: 0 calc((var(--default-clickable-area) - 16px) / 2) !important;\n.button-vue__text {\n\t\tfont-weight: var(--font-weight-default, normal);\n}\n}\n._content_CW2CF {\n\tdisplay: block;\n\tpadding: 10px;\n\n\t/* prevent scrolled contents from stopping too early */\n\tmargin-bottom: calc(-1 * var(--default-grid-baseline));\n\n\t/* restrict height of settings and make scrollable */\n\tmax-height: 300px;\n\toverflow-y: auto;\n}\n._animationActive_Lz0UV {\n\ttransition-duration: var(--animation-slow);\n\ttransition-property: max-height, padding;\n\toverflow-y: hidden !important;\n}\n._animationStop_lwpSi {\n\tmax-height: 0 !important;\n\tpadding: 0 10px !important;\n}\n","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppNavigationSettings.css"],names:[],mappings:";AACA;CACC,gBAAgB;CAChB,qCAAqC;AACtC;AACA;CACC,4CAA4C;CAC5C,2CAA2C;AAC5C;;AAEA,uDAAuD;AACvD;CACC,6EAA6E;AAC9E;EACE,+CAA+C;AACjD;AACA;AACA;CACC,cAAc;CACd,aAAa;;CAEb,sDAAsD;CACtD,sDAAsD;;CAEtD,oDAAoD;CACpD,iBAAiB;CACjB,gBAAgB;AACjB;AACA;CACC,0CAA0C;CAC1C,wCAAwC;CACxC,6BAA6B;AAC9B;AACA;CACC,wBAAwB;CACxB,0BAA0B;AAC3B",sourcesContent:["\n._container_2uWBM {\n\tmargin-top: auto;\n\tpadding: var(--default-grid-baseline);\n}\n._header_jtpAp {\n\tmargin-block: 0 var(--default-grid-baseline);\n\tmargin-inline: var(--default-grid-baseline);\n}\n\n/* Overwrite the padding to match NcAppNavigationItem */\n._button_9llR- {\n\tpadding-inline: 0 calc((var(--default-clickable-area) - 16px) / 2) !important;\n.button-vue__text {\n\t\tfont-weight: var(--font-weight-default, normal);\n}\n}\n._content_CW2CF {\n\tdisplay: block;\n\tpadding: 10px;\n\n\t/* prevent scrolled contents from stopping too early */\n\tmargin-bottom: calc(-1 * var(--default-grid-baseline));\n\n\t/* restrict height of settings and make scrollable */\n\tmax-height: 300px;\n\toverflow-y: auto;\n}\n._animationActive_Lz0UV {\n\ttransition-duration: var(--animation-slow);\n\ttransition-property: max-height, padding;\n\toverflow-y: hidden !important;\n}\n._animationStop_lwpSi {\n\tmax-height: 0 !important;\n\tpadding: 0 10px !important;\n}\n"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},86102(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"\n.app-navigation-spacer[data-v-277fa710] {\n\t\tflex-shrink: 0;\n\t\theight: 22px;\n}\n\n","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcAppNavigationSpacer.css"],names:[],mappings:";AACA;EACE,cAAc;EACd,YAAY;AACd",sourcesContent:["\n.app-navigation-spacer[data-v-277fa710] {\n\t\tflex-shrink: 0;\n\t\theight: 22px;\n}\n\n"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},33238(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n#skip-actions.vue-skip-actions:focus-within {\n top: 0 !important;\n inset-inline-start: 0 !important;\n width: 100vw;\n height: 100vh;\n padding: var(--body-container-margin) !important;\n backdrop-filter: brightness(50%);\n}\n@media only screen and (min-width: 1024px) {\n.content:not(.content--legacy) .app-navigation:not(.app-navigation--closed):not(.app-navigation--close) ~ .app-content {\n border-inline-start: 1px solid var(--color-border);\n border-start-start-radius: var(--body-container-radius);\n border-end-start-radius: var(--body-container-radius);\n}\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-d13dcb98] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.vue-skip-actions__container[data-v-d13dcb98] {\n background-color: var(--color-main-background);\n border-radius: var(--border-radius-element);\n padding: 22px;\n}\n.vue-skip-actions__headline[data-v-d13dcb98] {\n font-weight: var(--font-weight-heading, bold);\n font-size: 20px;\n line-height: 30px;\n margin-bottom: 12px;\n}\n.vue-skip-actions__buttons[data-v-d13dcb98] {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n}\n.vue-skip-actions__buttons[data-v-d13dcb98] > * {\n flex: 1 0 fit-content;\n}\n.vue-skip-actions__image[data-v-d13dcb98] {\n margin-top: 12px;\n}\n.vue-skip-actions__image[data-v-d13dcb98]:dir(rtl) {\n transform: rotateY(180deg);\n}\n.content[data-v-d13dcb98] {\n display: flex;\n width: calc(100% - var(--body-container-margin) * 2);\n border-radius: var(--body-container-radius);\n height: var(--body-height);\n overflow: hidden;\n padding: 0;\n}\n.content[data-v-d13dcb98]:not(.content--legacy) {\n background-color: var(--color-main-background-blur, var(--color-main-background));\n backdrop-filter: var(--filter-background-blur, none);\n}\n.content[data-v-d13dcb98]:not(.with-sidebar--full) {\n position: fixed;\n}\n.content[data-v-d13dcb98], .content[data-v-d13dcb98] * {\n box-sizing: border-box;\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcContent.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,iBAAiB;EACjB,gCAAgC;EAChC,YAAY;EACZ,aAAa;EACb,gDAAgD;EAChD,gCAAgC;AAClC;AACA;AACA;IACI,kDAAkD;IAClD,uDAAuD;IACvD,qDAAqD;AACzD;AACA,CAAC;;;EAGC;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,8CAA8C;EAC9C,2CAA2C;EAC3C,aAAa;AACf;AACA;EACE,6CAA6C;EAC7C,eAAe;EACf,iBAAiB;EACjB,mBAAmB;AACrB;AACA;EACE,aAAa;EACb,eAAe;EACf,SAAS;AACX;AACA;EACE,qBAAqB;AACvB;AACA;EACE,gBAAgB;AAClB;AACA;EACE,0BAA0B;AAC5B;AACA;EACE,aAAa;EACb,oDAAoD;EACpD,2CAA2C;EAC3C,0BAA0B;EAC1B,gBAAgB;EAChB,UAAU;AACZ;AACA;EACE,iFAAiF;EACjF,oDAAoD;AACtD;AACA;EACE,eAAe;AACjB;AACA;EACE,sBAAsB;AACxB",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n#skip-actions.vue-skip-actions:focus-within {\n top: 0 !important;\n inset-inline-start: 0 !important;\n width: 100vw;\n height: 100vh;\n padding: var(--body-container-margin) !important;\n backdrop-filter: brightness(50%);\n}\n@media only screen and (min-width: 1024px) {\n.content:not(.content--legacy) .app-navigation:not(.app-navigation--closed):not(.app-navigation--close) ~ .app-content {\n border-inline-start: 1px solid var(--color-border);\n border-start-start-radius: var(--body-container-radius);\n border-end-start-radius: var(--body-container-radius);\n}\n}/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-d13dcb98] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.vue-skip-actions__container[data-v-d13dcb98] {\n background-color: var(--color-main-background);\n border-radius: var(--border-radius-element);\n padding: 22px;\n}\n.vue-skip-actions__headline[data-v-d13dcb98] {\n font-weight: var(--font-weight-heading, bold);\n font-size: 20px;\n line-height: 30px;\n margin-bottom: 12px;\n}\n.vue-skip-actions__buttons[data-v-d13dcb98] {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n}\n.vue-skip-actions__buttons[data-v-d13dcb98] > * {\n flex: 1 0 fit-content;\n}\n.vue-skip-actions__image[data-v-d13dcb98] {\n margin-top: 12px;\n}\n.vue-skip-actions__image[data-v-d13dcb98]:dir(rtl) {\n transform: rotateY(180deg);\n}\n.content[data-v-d13dcb98] {\n display: flex;\n width: calc(100% - var(--body-container-margin) * 2);\n border-radius: var(--body-container-radius);\n height: var(--body-height);\n overflow: hidden;\n padding: 0;\n}\n.content[data-v-d13dcb98]:not(.content--legacy) {\n background-color: var(--color-main-background-blur, var(--color-main-background));\n backdrop-filter: var(--filter-background-blur, none);\n}\n.content[data-v-d13dcb98]:not(.with-sidebar--full) {\n position: fixed;\n}\n.content[data-v-d13dcb98], .content[data-v-d13dcb98] * {\n box-sizing: border-box;\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},60887(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-36ffc13f] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.counter-bubble__counter[data-v-36ffc13f] {\n --counter-bubble-height: 22px;\n font-size: var(--font-size-small, 13px);\n overflow: hidden;\n width: fit-content;\n min-width: var(--counter-bubble-height);\n text-align: center;\n line-height: var(--counter-bubble-height);\n padding: 0 calc(1.5 * var(--default-grid-baseline));\n border-radius: 0.5lh;\n background-color: var(--color-primary-element-light);\n font-weight: bold;\n color: var(--color-primary-element-light-text);\n}\n.counter-bubble__counter .active[data-v-36ffc13f] {\n color: var(--color-main-background);\n background-color: var(--color-primary-element-light);\n}\n.counter-bubble__counter--highlighted[data-v-36ffc13f] {\n color: var(--color-primary-element-text);\n background-color: var(--color-primary-element);\n}\n.counter-bubble__counter--highlighted.active[data-v-36ffc13f] {\n color: var(--color-primary-element);\n background-color: var(--color-main-background);\n}\n.counter-bubble__counter--outlined[data-v-36ffc13f] {\n color: var(--color-primary-element);\n background: transparent;\n box-shadow: inset 0 0 0 2px;\n}\n.counter-bubble__counter--outlined.active[data-v-36ffc13f] {\n color: var(--color-main-background);\n box-shadow: inset 0 0 0 2px;\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcCounterBubble.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,6BAA6B;EAC7B,uCAAuC;EACvC,gBAAgB;EAChB,kBAAkB;EAClB,uCAAuC;EACvC,kBAAkB;EAClB,yCAAyC;EACzC,mDAAmD;EACnD,oBAAoB;EACpB,oDAAoD;EACpD,iBAAiB;EACjB,8CAA8C;AAChD;AACA;EACE,mCAAmC;EACnC,oDAAoD;AACtD;AACA;EACE,wCAAwC;EACxC,8CAA8C;AAChD;AACA;EACE,mCAAmC;EACnC,8CAA8C;AAChD;AACA;EACE,mCAAmC;EACnC,uBAAuB;EACvB,2BAA2B;AAC7B;AACA;EACE,mCAAmC;EACnC,2BAA2B;AAC7B",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-36ffc13f] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.counter-bubble__counter[data-v-36ffc13f] {\n --counter-bubble-height: 22px;\n font-size: var(--font-size-small, 13px);\n overflow: hidden;\n width: fit-content;\n min-width: var(--counter-bubble-height);\n text-align: center;\n line-height: var(--counter-bubble-height);\n padding: 0 calc(1.5 * var(--default-grid-baseline));\n border-radius: 0.5lh;\n background-color: var(--color-primary-element-light);\n font-weight: bold;\n color: var(--color-primary-element-light-text);\n}\n.counter-bubble__counter .active[data-v-36ffc13f] {\n color: var(--color-main-background);\n background-color: var(--color-primary-element-light);\n}\n.counter-bubble__counter--highlighted[data-v-36ffc13f] {\n color: var(--color-primary-element-text);\n background-color: var(--color-primary-element);\n}\n.counter-bubble__counter--highlighted.active[data-v-36ffc13f] {\n color: var(--color-primary-element);\n background-color: var(--color-main-background);\n}\n.counter-bubble__counter--outlined[data-v-36ffc13f] {\n color: var(--color-primary-element);\n background: transparent;\n box-shadow: inset 0 0 0 2px;\n}\n.counter-bubble__counter--outlined.active[data-v-36ffc13f] {\n color: var(--color-main-background);\n box-shadow: inset 0 0 0 2px;\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},8735(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-6926a0b8] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-input-confirm[data-v-6926a0b8] {\n flex: 1 0 100%;\n width: 100%;\n}\n.app-navigation-input-confirm form[data-v-6926a0b8] {\n display: flex;\n}\n.app-navigation-input-confirm__input[data-v-6926a0b8] {\n height: 34px;\n flex: 1 1 100%;\n font-size: 100% !important;\n margin: 5px !important;\n margin-inline-start: -8px !important;\n padding: 7px !important;\n}\n.app-navigation-input-confirm__input[data-v-6926a0b8]:active, .app-navigation-input-confirm__input[data-v-6926a0b8]:focus, .app-navigation-input-confirm__input[data-v-6926a0b8]:hover {\n outline: none;\n background-color: var(--color-main-background);\n color: var(--color-main-text);\n border-color: var(--color-primary-element);\n}\n.app-navigation-input-confirm:not(.app-navigation-input-confirm--legacy) form[data-v-6926a0b8] {\n align-items: center;\n gap: 5px;\n padding-inline-end: 5px;\n}\n.app-navigation-input-confirm:not(.app-navigation-input-confirm--legacy) .app-navigation-input-confirm__input[data-v-6926a0b8] {\n margin-inline-end: 0 !important;\n}\n.app-navigation-input-confirm[data-v-6926a0b8]:not(.app-navigation-input-confirm--legacy) .button-vue {\n width: 34px !important;\n min-width: 34px !important;\n height: 34px !important;\n flex: 0 0 34px;\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcInputConfirmCancel.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;AACA;EACE,cAAc;EACd,WAAW;AACb;AACA;EACE,aAAa;AACf;AACA;EACE,YAAY;EACZ,cAAc;EACd,0BAA0B;EAC1B,sBAAsB;EACtB,oCAAoC;EACpC,uBAAuB;AACzB;AACA;EACE,aAAa;EACb,8CAA8C;EAC9C,6BAA6B;EAC7B,0CAA0C;AAC5C;AACA;EACE,mBAAmB;EACnB,QAAQ;EACR,uBAAuB;AACzB;AACA;EACE,+BAA+B;AACjC;AACA;EACE,sBAAsB;EACtB,0BAA0B;EAC1B,uBAAuB;EACvB,cAAc;AAChB",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-6926a0b8] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n.app-navigation-input-confirm[data-v-6926a0b8] {\n flex: 1 0 100%;\n width: 100%;\n}\n.app-navigation-input-confirm form[data-v-6926a0b8] {\n display: flex;\n}\n.app-navigation-input-confirm__input[data-v-6926a0b8] {\n height: 34px;\n flex: 1 1 100%;\n font-size: 100% !important;\n margin: 5px !important;\n margin-inline-start: -8px !important;\n padding: 7px !important;\n}\n.app-navigation-input-confirm__input[data-v-6926a0b8]:active, .app-navigation-input-confirm__input[data-v-6926a0b8]:focus, .app-navigation-input-confirm__input[data-v-6926a0b8]:hover {\n outline: none;\n background-color: var(--color-main-background);\n color: var(--color-main-text);\n border-color: var(--color-primary-element);\n}\n.app-navigation-input-confirm:not(.app-navigation-input-confirm--legacy) form[data-v-6926a0b8] {\n align-items: center;\n gap: 5px;\n padding-inline-end: 5px;\n}\n.app-navigation-input-confirm:not(.app-navigation-input-confirm--legacy) .app-navigation-input-confirm__input[data-v-6926a0b8] {\n margin-inline-end: 0 !important;\n}\n.app-navigation-input-confirm[data-v-6926a0b8]:not(.app-navigation-input-confirm--legacy) .button-vue {\n width: 34px !important;\n min-width: 34px !important;\n height: 34px !important;\n flex: 0 0 34px;\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},75417(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,"/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-feb04bef] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n\n/*!\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * Similar as inputBorder but without active styles.\n */\n/**\n * Create a consistent border for an input element.\n * With Nextcloud 32+ there is no real border anymore but we use a box-shadow.\n */\n.input-field[data-v-feb04bef] {\n --input-border-color: var(--color-border-maxcontrast);\n --input-border-radius: var(--border-radius-element);\n --input-padding-start: var(--border-radius-element);\n --input-padding-end: var(--border-radius-element);\n position: relative;\n width: 100%;\n margin-block-start: 6px;\n}\n.input-field--disabled[data-v-feb04bef] {\n opacity: 0.4;\n filter: saturate(0.4);\n}\n.input-field--label-outside[data-v-feb04bef] {\n margin-block-start: 0;\n}\n.input-field--leading-icon[data-v-feb04bef] {\n --input-padding-start: calc(var(--default-clickable-area) - var(--default-grid-baseline));\n}\n.input-field--trailing-icon[data-v-feb04bef] {\n --input-padding-end: calc(var(--default-clickable-area) - var(--default-grid-baseline));\n}\n.input-field--pill[data-v-feb04bef] {\n --input-border-radius: var(--border-radius-pill);\n}\n.input-field__main-wrapper[data-v-feb04bef] {\n height: var(--default-clickable-area);\n padding: var(--border-width-input-focused, 2px);\n position: relative;\n}\n.input-field__input[data-v-feb04bef] {\n --input-border-box-shadow-light: 0 -1px var(--input-border-color),\n \t0 0 0 1px color-mix(in srgb, var(--input-border-color), 65% transparent);\n --input-border-box-shadow-dark: 0 1px var(--input-border-color),\n \t0 0 0 1px color-mix(in srgb, var(--input-border-color), 65% transparent);\n --input-border-box-shadow: var(--input-border-box-shadow-light);\n border: none;\n border-radius: var(--border-radius-element);\n box-shadow: var(--input-border-box-shadow);\n}\n.input-field__input[data-v-feb04bef]:hover:not([disabled]) {\n box-shadow: 0 0 0 1px var(--input-border-color);\n}\n@media (prefers-color-scheme: dark) {\n.input-field__input .input-field__input[data-v-feb04bef] {\n --input-border-box-shadow: var(--input-border-box-shadow-dark);\n}\n}\n[data-theme-dark] .input-field__input[data-v-feb04bef] {\n --input-border-box-shadow: var(--input-border-box-shadow-dark);\n}\n[data-theme-light] .input-field__input[data-v-feb04bef] {\n --input-border-box-shadow: var(--input-border-box-shadow-light);\n}\n.input-field--legacy .input-field__input[data-v-feb04bef] {\n box-shadow: 0 0 0 1px var(--input-border-color);\n}\n.input-field--legacy .input-field__input[data-v-feb04bef]:hover:not([disabled]) {\n box-shadow: 0 0 0 2px var(--input-border-color);\n}\n.input-field__input[data-v-feb04bef]:focus-within:not([disabled]), .input-field__input[data-v-feb04bef]:active:not([disabled]) {\n box-shadow: 0 0 0 2px var(--input-border-color), 0 0 0 4px var(--color-main-background) !important;\n}\n.input-field__input[data-v-feb04bef] {\n background-color: var(--color-main-background);\n color: var(--color-main-text);\n border-radius: var(--input-border-radius);\n cursor: pointer;\n -webkit-appearance: textfield !important;\n -moz-appearance: textfield !important;\n appearance: textfield !important;\n font-size: var(--default-font-size);\n text-overflow: ellipsis;\n padding-block: 0;\n padding-inline: var(--input-padding-start) var(--input-padding-end);\n height: 100% !important;\n min-height: unset;\n width: 100%;\n}\n.input-field__input[data-v-feb04bef]::placeholder {\n color: var(--color-text-maxcontrast);\n}\n.input-field__input[data-v-feb04bef]::-webkit-search-cancel-button {\n display: none;\n}\n.input-field__input[data-v-feb04bef]::-webkit-search-decoration, .input-field__input[data-v-feb04bef]::-webkit-search-results-button, .input-field__input[data-v-feb04bef]::-webkit-search-results-decoration, .input-field__input[data-v-feb04bef]::-ms-clear {\n display: none;\n}\n.input-field__input[data-v-feb04bef]:active:not([disabled]), .input-field__input[data-v-feb04bef]:focus:not([disabled]) {\n --input-border-color: var(--color-main-text);\n}\n.input-field__input:focus + .input-field__label[data-v-feb04bef], .input-field__input:hover:not(:placeholder-shown) + .input-field__label[data-v-feb04bef] {\n color: var(--color-main-text);\n}\n.input-field__input[data-v-feb04bef]:focus {\n cursor: text;\n}\n.input-field__input[data-v-feb04bef]:disabled {\n cursor: default;\n}\n.input-field__input[data-v-feb04bef]:focus-visible {\n box-shadow: unset !important;\n}\n.input-field:not(.input-field--label-outside) .input-field__input[data-v-feb04bef]:not(:focus)::placeholder {\n opacity: 0;\n}\n.input-field__label[data-v-feb04bef] {\n --input-label-font-size: var(--default-font-size);\n font-size: var(--input-label-font-size);\n position: absolute;\n margin-inline: var(--input-padding-start) var(--input-padding-end);\n max-width: fit-content;\n inset-block-start: calc((var(--default-clickable-area) - 1lh) / 2);\n inset-inline: var(--border-width-input-focused, 2px);\n color: var(--color-text-maxcontrast);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n transition: height var(--animation-quick), inset-block-start var(--animation-quick), font-size var(--animation-quick), color var(--animation-quick), background-color var(--animation-quick) var(--animation-slow);\n}\n.input-field__input:focus + .input-field__label[data-v-feb04bef], .input-field__input:not(:placeholder-shown) + .input-field__label[data-v-feb04bef] {\n --input-label-font-size: 13px;\n line-height: 1.5;\n inset-block-start: calc(-1.5 * var(--input-label-font-size) / 2);\n font-weight: var(--font-weight-element, 500);\n border-radius: var(--default-grid-baseline) var(--default-grid-baseline) 0 0;\n background-color: var(--color-main-background);\n padding-inline: var(--default-grid-baseline);\n margin-inline: calc(var(--input-padding-start) - var(--default-grid-baseline)) calc(var(--input-padding-end) - var(--default-grid-baseline));\n transition: height var(--animation-quick), inset-block-start var(--animation-quick), font-size var(--animation-quick), color var(--animation-quick);\n}\n.input-field__icon[data-v-feb04bef] {\n position: absolute;\n height: var(--default-clickable-area);\n width: var(--default-clickable-area);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.7;\n inset-block-end: 0;\n}\n.input-field__icon--leading[data-v-feb04bef] {\n inset-inline-start: 0px;\n}\n.input-field__icon--trailing[data-v-feb04bef] {\n inset-inline-end: 0px;\n}\n.input-field__trailing-button[data-v-feb04bef] {\n --button-size: calc(var(--default-clickable-area) - 2 * var(--border-width-input-focused, 2px)) !important;\n --button-radius: calc(var(--input-border-radius) - var(--border-width-input-focused, 2px));\n}\n.input-field__trailing-button.button-vue[data-v-feb04bef] {\n position: absolute;\n top: var(--border-width-input-focused, 2px);\n inset-inline-end: var(--border-width-input-focused, 2px);\n}\n.input-field__trailing-button.button-vue[data-v-feb04bef]:focus-visible {\n box-shadow: none !important;\n}\n.input-field__helper-text-message[data-v-feb04bef] {\n padding-block: 4px;\n padding-inline: var(--border-radius-element);\n display: flex;\n align-items: center;\n color: var(--color-text-maxcontrast);\n overflow-wrap: anywhere;\n}\n.input-field__helper-text-message__icon[data-v-feb04bef] {\n margin-inline-end: 8px;\n}\n.input-field--error .input-field__helper-text-message[data-v-feb04bef],\n.input-field--error .input-field__icon--trailing[data-v-feb04bef] {\n color: var(--color-text-error, var(--color-error));\n}\n.input-field--error .input-field__input[data-v-feb04bef], .input-field__input[data-v-feb04bef]:user-invalid {\n --input-border-color: var(--color-border-error, var(--color-error)) !important;\n}\n.input-field--error .input-field__input[data-v-feb04bef]:focus-visible, .input-field__input[data-v-feb04bef]:user-invalid:focus-visible {\n box-shadow: rgb(248, 250, 252) 0px 0px 0px 2px, var(--color-primary-element) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;\n}\n.input-field--success .input-field__input[data-v-feb04bef] {\n --input-border-color: var(--color-border-success, var(--color-success)) !important;\n}\n.input-field--success .input-field__input[data-v-feb04bef]:focus-visible {\n box-shadow: rgb(248, 250, 252) 0px 0px 0px 2px, var(--color-primary-element) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;\n}\n.input-field--success .input-field__helper-text-message__icon[data-v-feb04bef] {\n color: var(--color-border-success, var(--color-success));\n}","",{version:3,sources:["webpack://./node_modules/@nextcloud/vue/dist/assets/NcInputField.css"],names:[],mappings:"AAAA;;;EAGE;AACF;;;EAGE;AACF;;CAEC;AACD;EACE,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,uBAAuB;AACzB;;AAEA;;;EAGE;AACF;;EAEE;AACF;;;EAGE;AACF;EACE,qDAAqD;EACrD,mDAAmD;EACnD,mDAAmD;EACnD,iDAAiD;EACjD,kBAAkB;EAClB,WAAW;EACX,uBAAuB;AACzB;AACA;EACE,YAAY;EACZ,qBAAqB;AACvB;AACA;EACE,qBAAqB;AACvB;AACA;EACE,yFAAyF;AAC3F;AACA;EACE,uFAAuF;AACzF;AACA;EACE,gDAAgD;AAClD;AACA;EACE,qCAAqC;EACrC,+CAA+C;EAC/C,kBAAkB;AACpB;AACA;EACE;2EACyE;EACzE;2EACyE;EACzE,+DAA+D;EAC/D,YAAY;EACZ,2CAA2C;EAC3C,0CAA0C;AAC5C;AACA;EACE,+CAA+C;AACjD;AACA;AACA;IACI,8DAA8D;AAClE;AACA;AACA;EACE,8DAA8D;AAChE;AACA;EACE,+DAA+D;AACjE;AACA;EACE,+CAA+C;AACjD;AACA;EACE,+CAA+C;AACjD;AACA;EACE,kGAAkG;AACpG;AACA;EACE,8CAA8C;EAC9C,6BAA6B;EAC7B,yCAAyC;EACzC,eAAe;EACf,wCAAwC;EACxC,qCAAqC;EACrC,gCAAgC;EAChC,mCAAmC;EACnC,uBAAuB;EACvB,gBAAgB;EAChB,mEAAmE;EACnE,uBAAuB;EACvB,iBAAiB;EACjB,WAAW;AACb;AACA;EACE,oCAAoC;AACtC;AACA;EACE,aAAa;AACf;AACA;EACE,aAAa;AACf;AACA;EACE,4CAA4C;AAC9C;AACA;EACE,6BAA6B;AAC/B;AACA;EACE,YAAY;AACd;AACA;EACE,eAAe;AACjB;AACA;EACE,4BAA4B;AAC9B;AACA;EACE,UAAU;AACZ;AACA;EACE,iDAAiD;EACjD,uCAAuC;EACvC,kBAAkB;EAClB,kEAAkE;EAClE,sBAAsB;EACtB,kEAAkE;EAClE,oDAAoD;EACpD,oCAAoC;EACpC,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;EACvB,oBAAoB;EACpB,kNAAkN;AACpN;AACA;EACE,6BAA6B;EAC7B,gBAAgB;EAChB,gEAAgE;EAChE,4CAA4C;EAC5C,4EAA4E;EAC5E,8CAA8C;EAC9C,4CAA4C;EAC5C,4IAA4I;EAC5I,mJAAmJ;AACrJ;AACA;EACE,kBAAkB;EAClB,qCAAqC;EACrC,oCAAoC;EACpC,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,YAAY;EACZ,kBAAkB;AACpB;AACA;EACE,uBAAuB;AACzB;AACA;EACE,qBAAqB;AACvB;AACA;EACE,0GAA0G;EAC1G,0FAA0F;AAC5F;AACA;EACE,kBAAkB;EAClB,2CAA2C;EAC3C,wDAAwD;AAC1D;AACA;EACE,2BAA2B;AAC7B;AACA;EACE,kBAAkB;EAClB,4CAA4C;EAC5C,aAAa;EACb,mBAAmB;EACnB,oCAAoC;EACpC,uBAAuB;AACzB;AACA;EACE,sBAAsB;AACxB;AACA;;EAEE,kDAAkD;AACpD;AACA;EACE,8EAA8E;AAChF;AACA;EACE,iIAAiI;AACnI;AACA;EACE,kFAAkF;AACpF;AACA;EACE,iIAAiI;AACnI;AACA;EACE,wDAAwD;AAC1D",sourcesContent:["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/*\n* Ensure proper alignment of the vue material icons\n*/\n.material-design-icon[data-v-feb04bef] {\n display: flex;\n align-self: center;\n justify-self: center;\n align-items: center;\n justify-content: center;\n}\n\n/*!\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n/**\n * Similar as inputBorder but without active styles.\n */\n/**\n * Create a consistent border for an input element.\n * With Nextcloud 32+ there is no real border anymore but we use a box-shadow.\n */\n.input-field[data-v-feb04bef] {\n --input-border-color: var(--color-border-maxcontrast);\n --input-border-radius: var(--border-radius-element);\n --input-padding-start: var(--border-radius-element);\n --input-padding-end: var(--border-radius-element);\n position: relative;\n width: 100%;\n margin-block-start: 6px;\n}\n.input-field--disabled[data-v-feb04bef] {\n opacity: 0.4;\n filter: saturate(0.4);\n}\n.input-field--label-outside[data-v-feb04bef] {\n margin-block-start: 0;\n}\n.input-field--leading-icon[data-v-feb04bef] {\n --input-padding-start: calc(var(--default-clickable-area) - var(--default-grid-baseline));\n}\n.input-field--trailing-icon[data-v-feb04bef] {\n --input-padding-end: calc(var(--default-clickable-area) - var(--default-grid-baseline));\n}\n.input-field--pill[data-v-feb04bef] {\n --input-border-radius: var(--border-radius-pill);\n}\n.input-field__main-wrapper[data-v-feb04bef] {\n height: var(--default-clickable-area);\n padding: var(--border-width-input-focused, 2px);\n position: relative;\n}\n.input-field__input[data-v-feb04bef] {\n --input-border-box-shadow-light: 0 -1px var(--input-border-color),\n \t0 0 0 1px color-mix(in srgb, var(--input-border-color), 65% transparent);\n --input-border-box-shadow-dark: 0 1px var(--input-border-color),\n \t0 0 0 1px color-mix(in srgb, var(--input-border-color), 65% transparent);\n --input-border-box-shadow: var(--input-border-box-shadow-light);\n border: none;\n border-radius: var(--border-radius-element);\n box-shadow: var(--input-border-box-shadow);\n}\n.input-field__input[data-v-feb04bef]:hover:not([disabled]) {\n box-shadow: 0 0 0 1px var(--input-border-color);\n}\n@media (prefers-color-scheme: dark) {\n.input-field__input .input-field__input[data-v-feb04bef] {\n --input-border-box-shadow: var(--input-border-box-shadow-dark);\n}\n}\n[data-theme-dark] .input-field__input[data-v-feb04bef] {\n --input-border-box-shadow: var(--input-border-box-shadow-dark);\n}\n[data-theme-light] .input-field__input[data-v-feb04bef] {\n --input-border-box-shadow: var(--input-border-box-shadow-light);\n}\n.input-field--legacy .input-field__input[data-v-feb04bef] {\n box-shadow: 0 0 0 1px var(--input-border-color);\n}\n.input-field--legacy .input-field__input[data-v-feb04bef]:hover:not([disabled]) {\n box-shadow: 0 0 0 2px var(--input-border-color);\n}\n.input-field__input[data-v-feb04bef]:focus-within:not([disabled]), .input-field__input[data-v-feb04bef]:active:not([disabled]) {\n box-shadow: 0 0 0 2px var(--input-border-color), 0 0 0 4px var(--color-main-background) !important;\n}\n.input-field__input[data-v-feb04bef] {\n background-color: var(--color-main-background);\n color: var(--color-main-text);\n border-radius: var(--input-border-radius);\n cursor: pointer;\n -webkit-appearance: textfield !important;\n -moz-appearance: textfield !important;\n appearance: textfield !important;\n font-size: var(--default-font-size);\n text-overflow: ellipsis;\n padding-block: 0;\n padding-inline: var(--input-padding-start) var(--input-padding-end);\n height: 100% !important;\n min-height: unset;\n width: 100%;\n}\n.input-field__input[data-v-feb04bef]::placeholder {\n color: var(--color-text-maxcontrast);\n}\n.input-field__input[data-v-feb04bef]::-webkit-search-cancel-button {\n display: none;\n}\n.input-field__input[data-v-feb04bef]::-webkit-search-decoration, .input-field__input[data-v-feb04bef]::-webkit-search-results-button, .input-field__input[data-v-feb04bef]::-webkit-search-results-decoration, .input-field__input[data-v-feb04bef]::-ms-clear {\n display: none;\n}\n.input-field__input[data-v-feb04bef]:active:not([disabled]), .input-field__input[data-v-feb04bef]:focus:not([disabled]) {\n --input-border-color: var(--color-main-text);\n}\n.input-field__input:focus + .input-field__label[data-v-feb04bef], .input-field__input:hover:not(:placeholder-shown) + .input-field__label[data-v-feb04bef] {\n color: var(--color-main-text);\n}\n.input-field__input[data-v-feb04bef]:focus {\n cursor: text;\n}\n.input-field__input[data-v-feb04bef]:disabled {\n cursor: default;\n}\n.input-field__input[data-v-feb04bef]:focus-visible {\n box-shadow: unset !important;\n}\n.input-field:not(.input-field--label-outside) .input-field__input[data-v-feb04bef]:not(:focus)::placeholder {\n opacity: 0;\n}\n.input-field__label[data-v-feb04bef] {\n --input-label-font-size: var(--default-font-size);\n font-size: var(--input-label-font-size);\n position: absolute;\n margin-inline: var(--input-padding-start) var(--input-padding-end);\n max-width: fit-content;\n inset-block-start: calc((var(--default-clickable-area) - 1lh) / 2);\n inset-inline: var(--border-width-input-focused, 2px);\n color: var(--color-text-maxcontrast);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n pointer-events: none;\n transition: height var(--animation-quick), inset-block-start var(--animation-quick), font-size var(--animation-quick), color var(--animation-quick), background-color var(--animation-quick) var(--animation-slow);\n}\n.input-field__input:focus + .input-field__label[data-v-feb04bef], .input-field__input:not(:placeholder-shown) + .input-field__label[data-v-feb04bef] {\n --input-label-font-size: 13px;\n line-height: 1.5;\n inset-block-start: calc(-1.5 * var(--input-label-font-size) / 2);\n font-weight: var(--font-weight-element, 500);\n border-radius: var(--default-grid-baseline) var(--default-grid-baseline) 0 0;\n background-color: var(--color-main-background);\n padding-inline: var(--default-grid-baseline);\n margin-inline: calc(var(--input-padding-start) - var(--default-grid-baseline)) calc(var(--input-padding-end) - var(--default-grid-baseline));\n transition: height var(--animation-quick), inset-block-start var(--animation-quick), font-size var(--animation-quick), color var(--animation-quick);\n}\n.input-field__icon[data-v-feb04bef] {\n position: absolute;\n height: var(--default-clickable-area);\n width: var(--default-clickable-area);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.7;\n inset-block-end: 0;\n}\n.input-field__icon--leading[data-v-feb04bef] {\n inset-inline-start: 0px;\n}\n.input-field__icon--trailing[data-v-feb04bef] {\n inset-inline-end: 0px;\n}\n.input-field__trailing-button[data-v-feb04bef] {\n --button-size: calc(var(--default-clickable-area) - 2 * var(--border-width-input-focused, 2px)) !important;\n --button-radius: calc(var(--input-border-radius) - var(--border-width-input-focused, 2px));\n}\n.input-field__trailing-button.button-vue[data-v-feb04bef] {\n position: absolute;\n top: var(--border-width-input-focused, 2px);\n inset-inline-end: var(--border-width-input-focused, 2px);\n}\n.input-field__trailing-button.button-vue[data-v-feb04bef]:focus-visible {\n box-shadow: none !important;\n}\n.input-field__helper-text-message[data-v-feb04bef] {\n padding-block: 4px;\n padding-inline: var(--border-radius-element);\n display: flex;\n align-items: center;\n color: var(--color-text-maxcontrast);\n overflow-wrap: anywhere;\n}\n.input-field__helper-text-message__icon[data-v-feb04bef] {\n margin-inline-end: 8px;\n}\n.input-field--error .input-field__helper-text-message[data-v-feb04bef],\n.input-field--error .input-field__icon--trailing[data-v-feb04bef] {\n color: var(--color-text-error, var(--color-error));\n}\n.input-field--error .input-field__input[data-v-feb04bef], .input-field__input[data-v-feb04bef]:user-invalid {\n --input-border-color: var(--color-border-error, var(--color-error)) !important;\n}\n.input-field--error .input-field__input[data-v-feb04bef]:focus-visible, .input-field__input[data-v-feb04bef]:user-invalid:focus-visible {\n box-shadow: rgb(248, 250, 252) 0px 0px 0px 2px, var(--color-primary-element) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;\n}\n.input-field--success .input-field__input[data-v-feb04bef] {\n --input-border-color: var(--color-border-success, var(--color-success)) !important;\n}\n.input-field--success .input-field__input[data-v-feb04bef]:focus-visible {\n box-shadow: rgb(248, 250, 252) 0px 0px 0px 2px, var(--color-primary-element) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;\n}\n.input-field--success .input-field__helper-text-message__icon[data-v-feb04bef] {\n color: var(--color-border-success, var(--color-success));\n}"],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},67507(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,'.splitpanes{width:100%;height:100%;display:flex}.splitpanes--vertical{flex-direction:row}.splitpanes--horizontal{flex-direction:column}.splitpanes--dragging .splitpanes__pane{-webkit-user-select:none;user-select:none;pointer-events:none}:has(.splitpanes--dragging){-webkit-user-select:none;user-select:none;pointer-events:none}.splitpanes__pane{width:100%;height:100%;overflow:hidden}.splitpanes--ready .splitpanes__pane{will-change:width, height;transition:width .2s ease-out,height .2s ease-out}.splitpanes--ready.splitpanes--dragging .splitpanes__pane{transition:none}.splitpanes__splitter{touch-action:none}.splitpanes__splitter:focus{outline:none}.splitpanes--vertical>.splitpanes__splitter{cursor:col-resize;min-width:1px}.splitpanes--horizontal>.splitpanes__splitter{cursor:row-resize;min-height:1px}.default-theme.splitpanes .splitpanes__pane{background-color:#f2f2f2}.default-theme.splitpanes .splitpanes__splitter{box-sizing:border-box;background-color:#fff;flex-shrink:0;position:relative}.default-theme.splitpanes .splitpanes__splitter:focus-visible{outline-offset:-2px;outline:2px solid #3b82f6}.default-theme.splitpanes .splitpanes__splitter:before,.default-theme.splitpanes .splitpanes__splitter:after{content:"";background-color:#00000026;transition:background-color .3s;position:absolute;top:50%;left:50%}.default-theme.splitpanes .splitpanes__splitter:hover:before,.default-theme.splitpanes .splitpanes__splitter:hover:after{background-color:#00000040}.default-theme.splitpanes .splitpanes__splitter:first-child{cursor:auto}.default-theme.splitpanes .splitpanes .splitpanes__splitter{z-index:1}.default-theme.splitpanes--vertical>.splitpanes__splitter,.default-theme .splitpanes--vertical>.splitpanes__splitter{border-left:1px solid #eee;width:7px;margin-left:-1px}.default-theme.splitpanes--vertical>.splitpanes__splitter:before,.default-theme.splitpanes--vertical>.splitpanes__splitter:after,.default-theme .splitpanes--vertical>.splitpanes__splitter:before,.default-theme .splitpanes--vertical>.splitpanes__splitter:after{width:1px;height:30px;transform:translateY(-50%)}.default-theme.splitpanes--vertical>.splitpanes__splitter:before,.default-theme .splitpanes--vertical>.splitpanes__splitter:before{margin-left:-2px}.default-theme.splitpanes--vertical>.splitpanes__splitter:after,.default-theme .splitpanes--vertical>.splitpanes__splitter:after{margin-left:1px}.default-theme.splitpanes--horizontal>.splitpanes__splitter,.default-theme .splitpanes--horizontal>.splitpanes__splitter{border-top:1px solid #eee;height:7px;margin-top:-1px}.default-theme.splitpanes--horizontal>.splitpanes__splitter:before,.default-theme.splitpanes--horizontal>.splitpanes__splitter:after,.default-theme .splitpanes--horizontal>.splitpanes__splitter:before,.default-theme .splitpanes--horizontal>.splitpanes__splitter:after{width:30px;height:1px;transform:translate(-50%)}.default-theme.splitpanes--horizontal>.splitpanes__splitter:before,.default-theme .splitpanes--horizontal>.splitpanes__splitter:before{margin-top:-2px}.default-theme.splitpanes--horizontal>.splitpanes__splitter:after,.default-theme .splitpanes--horizontal>.splitpanes__splitter:after{margin-top:1px}\n/*$vite$:1*/',"",{version:3,sources:["webpack://./node_modules/splitpanes/dist/splitpanes.css"],names:[],mappings:"AAAA,YAAY,UAAU,CAAC,WAAW,CAAC,YAAY,CAAC,sBAAsB,kBAAkB,CAAC,wBAAwB,qBAAqB,CAAC,wCAAwC,wBAAwB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,4BAA4B,wBAAwB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,kBAAkB,UAAU,CAAC,WAAW,CAAC,eAAe,CAAC,qCAAqC,yBAAyB,CAAC,iDAAiD,CAAC,0DAA0D,eAAe,CAAC,sBAAsB,iBAAiB,CAAC,4BAA4B,YAAY,CAAC,4CAA4C,iBAAiB,CAAC,aAAa,CAAC,8CAA8C,iBAAiB,CAAC,cAAc,CAAC,4CAA4C,wBAAwB,CAAC,gDAAgD,qBAAqB,CAAC,qBAAqB,CAAC,aAAa,CAAC,iBAAiB,CAAC,8DAA8D,mBAAmB,CAAC,yBAAyB,CAAC,6GAA6G,UAAU,CAAC,0BAA0B,CAAC,+BAA+B,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,yHAAyH,0BAA0B,CAAC,4DAA4D,WAAW,CAAC,4DAA4D,SAAS,CAAC,qHAAqH,0BAA0B,CAAC,SAAS,CAAC,gBAAgB,CAAC,oQAAoQ,SAAS,CAAC,WAAW,CAAC,0BAA0B,CAAC,mIAAmI,gBAAgB,CAAC,iIAAiI,eAAe,CAAC,yHAAyH,yBAAyB,CAAC,UAAU,CAAC,eAAe,CAAC,4QAA4Q,UAAU,CAAC,UAAU,CAAC,yBAAyB,CAAC,uIAAuI,eAAe,CAAC,qIAAqI,cAAc;AACrmG,WAAW",sourcesContent:['.splitpanes{width:100%;height:100%;display:flex}.splitpanes--vertical{flex-direction:row}.splitpanes--horizontal{flex-direction:column}.splitpanes--dragging .splitpanes__pane{-webkit-user-select:none;user-select:none;pointer-events:none}:has(.splitpanes--dragging){-webkit-user-select:none;user-select:none;pointer-events:none}.splitpanes__pane{width:100%;height:100%;overflow:hidden}.splitpanes--ready .splitpanes__pane{will-change:width, height;transition:width .2s ease-out,height .2s ease-out}.splitpanes--ready.splitpanes--dragging .splitpanes__pane{transition:none}.splitpanes__splitter{touch-action:none}.splitpanes__splitter:focus{outline:none}.splitpanes--vertical>.splitpanes__splitter{cursor:col-resize;min-width:1px}.splitpanes--horizontal>.splitpanes__splitter{cursor:row-resize;min-height:1px}.default-theme.splitpanes .splitpanes__pane{background-color:#f2f2f2}.default-theme.splitpanes .splitpanes__splitter{box-sizing:border-box;background-color:#fff;flex-shrink:0;position:relative}.default-theme.splitpanes .splitpanes__splitter:focus-visible{outline-offset:-2px;outline:2px solid #3b82f6}.default-theme.splitpanes .splitpanes__splitter:before,.default-theme.splitpanes .splitpanes__splitter:after{content:"";background-color:#00000026;transition:background-color .3s;position:absolute;top:50%;left:50%}.default-theme.splitpanes .splitpanes__splitter:hover:before,.default-theme.splitpanes .splitpanes__splitter:hover:after{background-color:#00000040}.default-theme.splitpanes .splitpanes__splitter:first-child{cursor:auto}.default-theme.splitpanes .splitpanes .splitpanes__splitter{z-index:1}.default-theme.splitpanes--vertical>.splitpanes__splitter,.default-theme .splitpanes--vertical>.splitpanes__splitter{border-left:1px solid #eee;width:7px;margin-left:-1px}.default-theme.splitpanes--vertical>.splitpanes__splitter:before,.default-theme.splitpanes--vertical>.splitpanes__splitter:after,.default-theme .splitpanes--vertical>.splitpanes__splitter:before,.default-theme .splitpanes--vertical>.splitpanes__splitter:after{width:1px;height:30px;transform:translateY(-50%)}.default-theme.splitpanes--vertical>.splitpanes__splitter:before,.default-theme .splitpanes--vertical>.splitpanes__splitter:before{margin-left:-2px}.default-theme.splitpanes--vertical>.splitpanes__splitter:after,.default-theme .splitpanes--vertical>.splitpanes__splitter:after{margin-left:1px}.default-theme.splitpanes--horizontal>.splitpanes__splitter,.default-theme .splitpanes--horizontal>.splitpanes__splitter{border-top:1px solid #eee;height:7px;margin-top:-1px}.default-theme.splitpanes--horizontal>.splitpanes__splitter:before,.default-theme.splitpanes--horizontal>.splitpanes__splitter:after,.default-theme .splitpanes--horizontal>.splitpanes__splitter:before,.default-theme .splitpanes--horizontal>.splitpanes__splitter:after{width:30px;height:1px;transform:translate(-50%)}.default-theme.splitpanes--horizontal>.splitpanes__splitter:before,.default-theme .splitpanes--horizontal>.splitpanes__splitter:before{margin-top:-2px}.default-theme.splitpanes--horizontal>.splitpanes__splitter:after,.default-theme .splitpanes--horizontal>.splitpanes__splitter:after{margin-top:1px}\n/*$vite$:1*/'],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},63226(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o),s=n(4417),l=n.n(s),c=new URL(n(36118),n.b),d=r()(i()),p=l()(c);d.push([e.id,`#app-content-vue .social__wrapper[data-v-7bd29a96]{padding:calc(var(--default-grid-baseline)*4);max-width:800px;margin:auto}.setup[data-v-7bd29a96]{margin:0 auto !important;padding:calc(var(--default-grid-baseline)*4);max-width:800px;display:flex;flex-direction:column;gap:20px}.setup h2[data-v-7bd29a96]{font-size:24px;font-weight:700;margin-bottom:8px}.setup p[data-v-7bd29a96]{color:var(--color-text-lighter);line-height:1.6}.setup-input[data-v-7bd29a96]{width:300px;max-width:100%;margin-inline-end:10px;border-radius:var(--border-radius-element)}#social-spacer a[data-v-7bd29a96]:hover,#social-spacer a[data-v-7bd29a96]:focus{border:none !important}a.external_link[data-v-7bd29a96]{text-decoration:underline}[data-v-7bd29a96] .app-navigation-entry .app-navigation-entry__title{font-size:14px}[data-v-7bd29a96] .app-navigation-entry__subname{font-size:12px;color:var(--color-text-lighter);margin-top:-2px}[data-v-7bd29a96] .app-navigation-entry-icon{display:flex;align-items:center;justify-content:center}[data-v-7bd29a96] .app-navigation-entry-icon .avatardiv{margin:0}.icon-social[data-v-7bd29a96]{background-image:url(${p});filter:var(--background-invert-if-dark)}`,"",{version:3,sources:["webpack://./src/App.vue"],names:[],mappings:"AACA,mDACC,4CAAA,CACA,eAAA,CACA,WAAA,CAGD,wBACC,wBAAA,CACA,4CAAA,CACA,eAAA,CACA,YAAA,CACA,qBAAA,CACA,QAAA,CAEA,2BACC,cAAA,CACA,eAAA,CACA,iBAAA,CAGD,0BACC,+BAAA,CACA,eAAA,CAIF,8BACC,WAAA,CACA,cAAA,CACA,sBAAA,CACA,0CAAA,CAGD,gFAEC,sBAAA,CAGD,iCACC,yBAAA,CAIA,qEACC,cAAA,CAIF,iDACC,cAAA,CACA,+BAAA,CACA,eAAA,CAGD,6CACC,YAAA,CACA,kBAAA,CACA,sBAAA,CAEA,wDACC,QAAA,CAIF,8BACC,wDAAA,CACA,uCAAA",sourcesContent:["\n#app-content-vue .social__wrapper {\n\tpadding: calc(var(--default-grid-baseline) * 4);\n\tmax-width: 800px;\n\tmargin: auto;\n}\n\n.setup {\n\tmargin: 0 auto !important;\n\tpadding: calc(var(--default-grid-baseline) * 4);\n\tmax-width: 800px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 20px;\n\n\th2 {\n\t\tfont-size: 24px;\n\t\tfont-weight: 700;\n\t\tmargin-bottom: 8px;\n\t}\n\n\tp {\n\t\tcolor: var(--color-text-lighter);\n\t\tline-height: 1.6;\n\t}\n}\n\n.setup-input {\n\twidth: 300px;\n\tmax-width: 100%;\n\tmargin-inline-end: 10px;\n\tborder-radius: var(--border-radius-element);\n}\n\n#social-spacer a:hover,\n#social-spacer a:focus {\n\tborder: none !important;\n}\n\na.external_link {\n\ttext-decoration: underline;\n}\n\n:deep(.app-navigation-entry) {\n\t.app-navigation-entry__title {\n\t\tfont-size: 14px;\n\t}\n}\n\n:deep(.app-navigation-entry__subname) {\n\tfont-size: 12px;\n\tcolor: var(--color-text-lighter);\n\tmargin-top: -2px;\n}\n\n:deep(.app-navigation-entry-icon) {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\n\t.avatardiv {\n\t\tmargin: 0;\n\t}\n}\n\n.icon-social {\n\tbackground-image: url('../img/social-dark.svg');\n\tfilter: var(--background-invert-if-dark);\n}\n"],sourceRoot:""}]);const u=d;n.d(t,["A",0,u])},56276(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,":root{--social-elevation-resting: 0 1px 2px color-mix(in srgb, var(--color-box-shadow) 14%, transparent), 0 2px 6px color-mix(in srgb, var(--color-box-shadow) 9%, transparent);--social-elevation-raised: 0 2px 4px color-mix(in srgb, var(--color-box-shadow) 20%, transparent), 0 6px 16px color-mix(in srgb, var(--color-box-shadow) 12%, transparent);--social-column: 900px;--social-column-gutter: calc(var(--default-grid-baseline, 4px) * 2)}img.emoji{margin:3px;width:16px;vertical-align:text-bottom}.social__timeline .social__wrapper{padding:0;max-width:var(--social-column);margin:0 auto}.social__timeline .timeline-entry{list-style:none}.list-enter-active,.list-leave-active,.list-move{transition:opacity .2s ease,transform .2s ease}.list-enter-from,.list-leave-to{opacity:0;transform:translateY(-6px)}@media(prefers-reduced-motion: reduce){.list-enter-active,.list-leave-active,.list-move{transition:none}}@supports(animation-timeline: view()){@media(prefers-reduced-motion: no-preference){@keyframes timeline-entry-rise{from{opacity:0;transform:translateY(12px) scale(0.99)}to{opacity:1;transform:none}}.social__timeline .timeline-entry{animation:timeline-entry-rise linear both;animation-timeline:view();animation-range:entry 0% entry 45%}}}.social__welcome{background:var(--color-main-background);border:1px solid var(--color-border);border-radius:8px;margin:calc(var(--default-grid-baseline)*4) auto;padding:calc(var(--default-grid-baseline)*5);max-width:var(--social-column)}.social__welcome h2{font-size:22px;font-weight:700;margin-bottom:12px}.social__welcome p{color:var(--color-text-lighter);line-height:1.7}.new-post{background:var(--color-main-background);border:1px solid var(--color-border);border-radius:8px;margin:calc(var(--default-grid-baseline)*3) auto;padding:calc(var(--default-grid-baseline)*3);max-width:var(--social-column);position:sticky;top:0;z-index:100}.app-navigation .app-navigation-entry .app-navigation-entry__title{font-size:14px}.app-navigation .app-navigation-entry .app-navigation-entry__subname{font-size:12px;color:var(--color-text-lighter)}.navigation__subname{font-size:12px;color:var(--color-text-lighter)}","",{version:3,sources:["webpack://./src/App.vue"],names:[],mappings:"AAYA,MACC,yKAAA,CAGA,0KAAA,CAcA,sBAAA,CACA,mEAAA,CAGD,UACC,UAAA,CACA,UAAA,CACA,0BAAA,CAIA,mCACC,SAAA,CACA,8BAAA,CACA,aAAA,CAGD,kCACC,eAAA,CAWF,iDAGC,8CAAA,CAGD,gCAEC,SAAA,CACA,0BAAA,CAGD,uCACC,iDAGC,eAAA,CAAA,CAUF,sCACC,8CACC,+BACC,KACC,SAAA,CACA,sCAAA,CAGD,GACC,SAAA,CACA,cAAA,CAAA,CAIF,kCACC,yCAAA,CACA,yBAAA,CAEA,kCAAA,CAAA,CAAA,CAKH,iBACC,uCAAA,CACA,oCAAA,CACA,iBAAA,CACA,gDAAA,CACA,4CAAA,CACA,8BAAA,CAEA,oBACC,cAAA,CACA,eAAA,CACA,kBAAA,CAGD,mBACC,+BAAA,CACA,eAAA,CAIF,UACC,uCAAA,CACA,oCAAA,CACA,iBAAA,CACA,gDAAA,CACA,4CAAA,CACA,8BAAA,CACA,eAAA,CACA,KAAA,CACA,WAAA,CAKC,mEACC,cAAA,CAGD,qEACC,cAAA,CACA,+BAAA,CAKH,qBACC,cAAA,CACA,+BAAA",sourcesContent:['\n/**\n * Two levels of elevation, defined once, so every card in the app agrees about\n * what "resting" and "lifted" look like.\n *\n * Nextcloud\'s own --color-box-shadow is built for modals: rgba(77,77,77,.5) in\n * the light theme and solid black in the dark one. Used raw under a timeline it\n * would put a hard slab under every post, so it is thinned with color-mix and\n * split in two — a tight contact shadow that seats the card on the page, and a\n * wider ambient one that gives it depth. A browser without color-mix drops the\n * declaration and gets the borders, which is what the app looked like before.\n */\n:root {\n\t--social-elevation-resting:\n\t\t0 1px 2px color-mix(in srgb, var(--color-box-shadow) 14%, transparent),\n\t\t0 2px 6px color-mix(in srgb, var(--color-box-shadow) 9%, transparent);\n\t--social-elevation-raised:\n\t\t0 2px 4px color-mix(in srgb, var(--color-box-shadow) 20%, transparent),\n\t\t0 6px 16px color-mix(in srgb, var(--color-box-shadow) 12%, transparent);\n\n\t/*\n\t * One column, stated once. The composer and the timeline used to each\n\t * carry their own max-width — the same number, but the list also had a\n\t * horizontal padding and the composer did not, so the two boxes were a\n\t * gutter\'s width apart at both edges and nothing on the page lined up.\n\t * Anything that sits in the column is `--social-column` wide. The list\n\t * keeps a gutter inside that, so a post is narrower than the column by\n\t * `--social-column-gutter` on each side and the composer, which takes the\n\t * column whole, stands that much proud of the posts beneath it.\n\t */\n\t--social-column: 900px;\n\t--social-column-gutter: calc(var(--default-grid-baseline, 4px) * 2);\n}\n\nimg.emoji {\n\tmargin: 3px;\n\twidth: 16px;\n\tvertical-align: text-bottom;\n}\n\n.social__timeline {\n\t.social__wrapper {\n\t\tpadding: 0;\n\t\tmax-width: var(--social-column);\n\t\tmargin: 0 auto;\n\t}\n\n\t.timeline-entry {\n\t\tlist-style: none;\n\t}\n}\n\n/**\n * The transition both timeline s use, defined once here\n * because this style block is global. Vue 3 names the starting class\n * `-enter-from` (Vue 2 called it `-enter`, which never matched and left the\n * enter animation dead), and `-move` is what makes the surrounding entries\n * slide when one is inserted or removed instead of jumping.\n */\n.list-enter-active,\n.list-leave-active,\n.list-move {\n\ttransition: opacity .2s ease, transform .2s ease;\n}\n\n.list-enter-from,\n.list-leave-to {\n\topacity: 0;\n\ttransform: translateY(-6px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n\t.list-enter-active,\n\t.list-leave-active,\n\t.list-move {\n\t\ttransition: none;\n\t}\n}\n\n/**\n * Posts ease in as they scroll into view. The browser drives this off the\n * scroll position on the compositor — no scroll listener, no observer, no\n * work on the main thread — and where the property is missing nothing\n * happens at all, which is why it needs no fallback.\n */\n@supports (animation-timeline: view()) {\n\t@media (prefers-reduced-motion: no-preference) {\n\t\t@keyframes timeline-entry-rise {\n\t\t\tfrom {\n\t\t\t\topacity: 0;\n\t\t\t\ttransform: translateY(12px) scale(.99);\n\t\t\t}\n\n\t\t\tto {\n\t\t\t\topacity: 1;\n\t\t\t\ttransform: none;\n\t\t\t}\n\t\t}\n\n\t\t.social__timeline .timeline-entry {\n\t\t\tanimation: timeline-entry-rise linear both;\n\t\t\tanimation-timeline: view();\n\t\t\t/* only the arrival is animated, not the departure */\n\t\t\tanimation-range: entry 0% entry 45%;\n\t\t}\n\t}\n}\n\n.social__welcome {\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: 8px;\n\tmargin: calc(var(--default-grid-baseline) * 4) auto;\n\tpadding: calc(var(--default-grid-baseline) * 5);\n\tmax-width: var(--social-column);\n\n\th2 {\n\t\tfont-size: 22px;\n\t\tfont-weight: 700;\n\t\tmargin-bottom: 12px;\n\t}\n\n\tp {\n\t\tcolor: var(--color-text-lighter);\n\t\tline-height: 1.7;\n\t}\n}\n\n.new-post {\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: 8px;\n\tmargin: calc(var(--default-grid-baseline) * 3) auto;\n\tpadding: calc(var(--default-grid-baseline) * 3);\n\tmax-width: var(--social-column);\n\tposition: sticky;\n\ttop: 0;\n\tz-index: 100;\n}\n\n.app-navigation {\n\t.app-navigation-entry {\n\t\t.app-navigation-entry__title {\n\t\t\tfont-size: 14px;\n\t\t}\n\n\t\t.app-navigation-entry__subname {\n\t\t\tfont-size: 12px;\n\t\t\tcolor: var(--color-text-lighter);\n\t\t}\n\t}\n}\n\n.navigation__subname {\n\tfont-size: 12px;\n\tcolor: var(--color-text-lighter);\n}\n\n'],sourceRoot:""}]);const s=r;n.d(t,["A",0,s])},30241(e,t,n){var a=n(71354),i=n.n(a),o=n(76314),r=n.n(o)()(i());r.push([e.id,'.navigation__more[data-v-6b6b846c] .button-vue__icon{background-image:var(--social-face);background-position:center;background-size:cover;border-radius:50%;overflow:hidden}.navigation__more[data-v-6b6b846c] .button-vue__icon svg{visibility:hidden}.navigation__more[data-v-6b6b846c] .button-vue__text{margin-inline-start:8px;font-weight:600}.navigation__subname[data-v-6b6b846c]{font-size:12px;color:var(--color-text-lighter)}@supports selector(:has(*)){.navigation__more[data-v-6b6b846c] .app-navigation-entry{opacity:0;transform:translateX(calc(var(--social-menu-slide, 1) * -14px));transition:opacity .24s ease,transform .34s cubic-bezier(0.3, 1.25, 0.5, 1)}[dir=rtl] .navigation__more[data-v-6b6b846c]{--social-menu-slide: -1}.navigation__more[data-v-6b6b846c]:has(button[aria-expanded=true]) .app-navigation-entry{opacity:1;transform:none;transition-delay:calc(var(--entry-index, 0)*34ms)}@media(prefers-reduced-motion: reduce){.navigation__more[data-v-6b6b846c] .app-navigation-entry{transition:none;transform:none}.navigation__more[data-v-6b6b846c]:has(button[aria-expanded=true]) .app-navigation-entry{transition-delay:0ms}}}.modal-composer[data-v-6b6b846c] .new-post{margin:0;padding:0;max-width:none;position:static;border:0;border-radius:0;box-shadow:none}.modal-composer[data-v-6b6b846c] .new-post:focus-within{box-shadow:none}.modal-errors[data-v-6b6b846c]{padding:calc(var(--default-grid-baseline)*4)}.modal-errors__item[data-v-6b6b846c]{padding:calc(var(--default-grid-baseline)*2) 0;border-bottom:1px solid var(--color-border)}.modal-errors__title[data-v-6b6b846c]{font-weight:700;margin-bottom:4px}.modal-errors__message[data-v-6b6b846c]{color:var(--color-text-lighter);margin-bottom:8px;overflow-wrap:break-word}.error-icon[data-v-6b6b846c]{color:var(--color-error)}[data-v-6b6b846c] .app-navigation-entry{border-radius:8px;margin:2px 0}[data-v-6b6b846c] .app-navigation-entry:hover{background:var(--color-background-hover)}[data-v-6b6b846c] .app-navigation-entry.active{background:var(--color-background-dark)}.navigation__compose.navigation__compose[data-v-6b6b846c]{position:relative;margin:2px 4px 8px;width:calc(100% - 8px);font-weight:600;min-height:44px;border-radius:999px;border:0;padding-inline:8px;overflow:visible;transition:transform .32s cubic-bezier(0.22, 1.2, 0.48, 1)}.navigation__compose[data-v-6b6b846c]::after{content:"";position:absolute;z-index:-1;inset:0;border-radius:inherit;box-shadow:0 0 0 3px color-mix(in srgb, var(--color-primary-element) 34%, transparent),0 0 0 9px color-mix(in srgb, var(--color-primary-element) 14%, transparent);opacity:0;transform:scale(0.94);transition:opacity .28s ease,transform .32s cubic-bezier(0.22, 1.2, 0.48, 1);pointer-events:none;will-change:opacity,transform}.navigation__compose.navigation__compose[data-v-6b6b846c]:is(:hover,:focus-visible){transform:translateY(-1px)}.navigation__compose[data-v-6b6b846c]:is(:hover,:focus-visible)::after{opacity:1;transform:scale(1)}.navigation__compose.navigation__compose[data-v-6b6b846c]:active{transform:translateY(0) scale(0.985)}.navigation__compose[data-v-6b6b846c]:active::after{transform:scale(0.97)}.navigation__compose[data-v-6b6b846c] .plus-icon{width:28px;height:28px;border-radius:50%;background:color-mix(in srgb, var(--color-primary-element-text) 22%, transparent);transition:background-color .2s ease,transform .32s cubic-bezier(0.22, 1.2, 0.48, 1)}.navigation__compose[data-v-6b6b846c] .button-vue__text{margin-inline-start:6px}.navigation__compose[data-v-6b6b846c]:is(:hover,:focus-visible) .plus-icon{transform:scale(1.12);background:color-mix(in srgb, var(--color-primary-element-text) 32%, transparent)}@media(prefers-reduced-motion: reduce){.navigation__compose.navigation__compose[data-v-6b6b846c],.navigation__compose[data-v-6b6b846c]::after,.navigation__compose[data-v-6b6b846c] .plus-icon{transition:none}.navigation__compose[data-v-6b6b846c]:is(:hover,:focus-visible)::after{transform:none}.navigation__compose.navigation__compose[data-v-6b6b846c]:is(:hover,:focus-visible),.navigation__compose.navigation__compose[data-v-6b6b846c]:active{transform:none}.navigation__compose[data-v-6b6b846c]:is(:hover,:focus-visible) .plus-icon{transform:none}}',"",{version:3,sources:["webpack://./src/components/Navigation.vue"],names:[],mappings:"AAMA,qDACC,mCAAA,CACA,0BAAA,CACA,qBAAA,CACA,iBAAA,CAGA,eAAA,CAEA,yDACC,iBAAA,CAIF,qDAGC,uBAAA,CACA,eAAA,CAGD,sCACC,cAAA,CACA,+BAAA,CA4BD,4BACC,yDACC,SAAA,CAEA,+DAAA,CACA,2EACC,CAIF,6CACC,uBAAA,CAGD,yFACC,SAAA,CACA,cAAA,CACA,iDAAA,CAOD,uCACC,yDACC,eAAA,CACA,cAAA,CAGD,yFACC,oBAAA,CAAA,CAAA,CAkBH,2CACC,QAAA,CACA,SAAA,CACA,cAAA,CACA,eAAA,CACA,QAAA,CACA,eAAA,CACA,eAAA,CAID,wDACC,eAAA,CAGD,+BACC,4CAAA,CAEA,qCACC,8CAAA,CACA,2CAAA,CAGD,sCACC,eAAA,CACA,iBAAA,CAGD,wCACC,+BAAA,CACA,iBAAA,CACA,wBAAA,CAIF,6BACC,wBAAA,CAGD,wCACC,iBAAA,CACA,YAAA,CAEA,8CACC,wCAAA,CAGD,+CACC,uCAAA,CA8BF,0DACC,iBAAA,CACA,kBAAA,CAQA,sBAAA,CACA,eAAA,CAYA,eAAA,CAEA,mBAAA,CAIA,QAAA,CAIA,kBAAA,CAKA,gBAAA,CACA,0DAAA,CAwBD,6CACC,UAAA,CACA,iBAAA,CACA,UAAA,CACA,OAAA,CACA,qBAAA,CACA,kKACC,CAED,SAAA,CACA,qBAAA,CACA,4EACC,CAED,mBAAA,CAGA,6BAAA,CAOD,oFACC,0BAAA,CAGD,uEACC,SAAA,CACA,kBAAA,CAGD,iEACC,oCAAA,CAGD,oDACC,qBAAA,CAUD,iDACC,UAAA,CACA,WAAA,CACA,iBAAA,CAGA,iFAAA,CACA,oFACC,CAKF,wDACC,uBAAA,CAGD,2EACC,qBAAA,CACA,iFAAA,CAGD,uCACC,wJAGC,eAAA,CAID,uEACC,cAAA,CAGD,qJAEC,cAAA,CAGD,2EACC,cAAA,CAAA",sourcesContent:["\n/* The button the More menu hangs off is the reader's own account: their\n portrait where the cog was, and the name they publish under beside it.\n `NcAppNavigationSettings` renders that cog from a hard-coded path with no\n slot to replace it, so the icon box carries the picture as its background\n and the cog inside it is hidden rather than fought with. */\n.navigation__more :deep(.button-vue__icon) {\n\tbackground-image: var(--social-face);\n\tbackground-position: center;\n\tbackground-size: cover;\n\tborder-radius: 50%;\n\t// the picture is the icon, so the glyph that was there must not show\n\t// through it — including its own background, which is not transparent\n\toverflow: hidden;\n\n\tsvg {\n\t\tvisibility: hidden;\n\t}\n}\n\n.navigation__more :deep(.button-vue__text) {\n\t// the button's wrapper has no gap of its own, so the name sits against the\n\t// portrait unless it is given one\n\tmargin-inline-start: 8px;\n\tfont-weight: 600;\n}\n\n.navigation__subname {\n\tfont-size: 12px;\n\tcolor: var(--color-text-lighter);\n}\n\n/*\n * The account menu opens as a drawer: the rows come in from the leading edge,\n * one behind the next.\n *\n * `NcAppNavigationSettings` animates its own `max-height`, so the panel grew\n * and the rows inside it were simply there when it finished -- the container\n * moved and its contents did not. These slide in behind it, 34ms apart, in the\n * direction the sidebar itself runs.\n *\n * Driven off `aria-expanded`, which is the accordion's own state and the only\n * hook it offers: there is no `open` prop and no event, and the component's\n * internal class names are content-hashed, so anything keyed on those would\n * break on the next release of the library.\n *\n * The delay comes from `--entry-index`, set in the template. The DOM cannot be\n * counted here: `NcAppNavigationItem` puts every entry in a wrapper of its own,\n * so each one is its parent's first child and `nth-child` hands them all the\n * same delay. There is a test that they are laid out that way, so that this\n * comment stops being true loudly rather than quietly.\n *\n * All of it sits inside `@supports selector(:has(*))` on purpose. Without\n * `:has()` the browser drops the rule that brings the rows *back*, and a bare\n * `opacity: 0` would leave the menu permanently empty -- so where it is not\n * supported, nothing animates and the menu behaves exactly as it does today.\n */\n@supports selector(:has(*)) {\n\t.navigation__more :deep(.app-navigation-entry) {\n\t\topacity: 0;\n\t\t/* the leading edge, whichever side that is */\n\t\ttransform: translateX(calc(var(--social-menu-slide, 1) * -14px));\n\t\ttransition:\n\t\t\topacity .24s ease,\n\t\t\ttransform .34s cubic-bezier(.3, 1.25, .5, 1);\n\t}\n\n\t[dir=\"rtl\"] .navigation__more {\n\t\t--social-menu-slide: -1;\n\t}\n\n\t.navigation__more:has(button[aria-expanded=\"true\"]) :deep(.app-navigation-entry) {\n\t\topacity: 1;\n\t\ttransform: none;\n\t\ttransition-delay: calc(var(--entry-index, 0) * 34ms);\n\t}\n\n\t/* A reader who asked for no movement still gets the menu, all at once and\n\t without the stagger: a row that fades in a fifth of a second after the\n\t one above it is the movement they turned off, even though nothing\n\t travels. */\n\t@media (prefers-reduced-motion: reduce) {\n\t\t.navigation__more :deep(.app-navigation-entry) {\n\t\t\ttransition: none;\n\t\t\ttransform: none;\n\t\t}\n\n\t\t.navigation__more:has(button[aria-expanded=\"true\"]) :deep(.app-navigation-entry) {\n\t\t\ttransition-delay: 0ms;\n\t\t}\n\t}\n}\n\n/*\n * The composer draws its own frame, and in a dialog that is one frame too many.\n *\n * In a timeline it is a card among cards: a border, a radius and the app's\n * resting shadow are how it says it is the box that makes the posts below it,\n * and `position: sticky` keeps it at the top while they scroll past. A dialog\n * has already said all of that -- it is a panel over a dimmed page, with its\n * own edge -- so the inner border reads as a box drawn inside a box, and\n * sticking to the top of something that does not scroll does nothing at all.\n *\n * Undone here rather than in the composer: what changes is not the composer but\n * where it is, and this is the only place that knows.\n */\n.modal-composer :deep(.new-post) {\n\tmargin: 0;\n\tpadding: 0;\n\tmax-width: none;\n\tposition: static;\n\tborder: 0;\n\tborder-radius: 0;\n\tbox-shadow: none;\n}\n\n/* the lift on focus goes with it: there is nothing left to lift */\n.modal-composer :deep(.new-post:focus-within) {\n\tbox-shadow: none;\n}\n\n.modal-errors {\n\tpadding: calc(var(--default-grid-baseline) * 4);\n\n\t&__item {\n\t\tpadding: calc(var(--default-grid-baseline) * 2) 0;\n\t\tborder-bottom: 1px solid var(--color-border);\n\t}\n\n\t&__title {\n\t\tfont-weight: 700;\n\t\tmargin-bottom: 4px;\n\t}\n\n\t&__message {\n\t\tcolor: var(--color-text-lighter);\n\t\tmargin-bottom: 8px;\n\t\toverflow-wrap: break-word;\n\t}\n}\n\n.error-icon {\n\tcolor: var(--color-error);\n}\n\n:deep(.app-navigation-entry) {\n\tborder-radius: 8px;\n\tmargin: 2px 0;\n\n\t&:hover {\n\t\tbackground: var(--color-background-hover);\n\t}\n\n\t&.active {\n\t\tbackground: var(--color-background-dark);\n\t}\n}\n\n/* The call to action.\n *\n * Concentric: a pill that becomes briefly larger than itself. Two rings open\n * outward from its own outline while the disc grows inside it, so everything on\n * screen expands from the same two centres at once. Nothing fills, nothing\n * sweeps, no colour changes hands — the button is the primary colour at rest and\n * the primary colour when reached for, and the only thing that happens is size.\n *\n * The shape is why it works. At 44px tall a full pill is a 22px radius, so its\n * end caps are arcs of a 22px circle; the plus already sits in a 28px disc, a\n * 14px circle, with 8px of air around it. Rounded all the way, the two are the\n * same family of curve and a ring drawn around the outside is concentric with\n * the badge inside. At the 8px corner this button used to have, the same ring\n * cut across the disc instead of agreeing with it.\n *\n * Rings rather than a blurred shadow: `0 0 0 ` is a hard outline offset\n * from the border box, which is the only kind of shadow that stays the button's\n * own shape at any distance from it.\n */\n\n/* The class is written twice because it has to win, not because it is two\n * things. `.button-vue[data-v-…]` sets `border-radius`, `font-weight` and\n * `transition` at exactly the specificity a single scoped class has, which\n * leaves the winner to source order — and the order of this component's styles\n * against the library's is not something this file gets to decide. Everything\n * that would otherwise be a silent tie lives in here. */\n.navigation__compose.navigation__compose {\n\tposition: relative;\n\tmargin: 2px 4px 8px;\n\t/* `wide` sets `width: 100%`, which is the container's full content width --\n\t and the margin above it has nowhere to go. The button was as wide as the\n\t whole list *and* shifted 4px right, so its right edge overhung the rows\n\t below it and ran into the edge of the sidebar; the left looked correct\n\t because there the margin pushed it inward. The width has to come off\n\t explicitly: `auto` is no use on a `