From d1d654ebac2d51e3841675faeb56480e440f622f Mon Sep 17 00:00:00 2001
From: Wolfgang Müller
Date: Tue, 5 Mar 2024 18:08:09 +0100
Subject: Initial commit
---
frontend/src/app.css | 180 ++
frontend/src/app.d.ts | 12 +
frontend/src/app.html | 13 +
frontend/src/gql/Mutations.ts | 244 +++
frontend/src/gql/Queries.ts | 243 +++
frontend/src/gql/Utils.ts | 74 +
frontend/src/gql/graphql.ts | 1764 ++++++++++++++++++++
frontend/src/lib/Actions.ts | 109 ++
frontend/src/lib/Enums.ts | 325 ++++
frontend/src/lib/Filter.ts | 365 ++++
frontend/src/lib/Meta.ts | 1 +
frontend/src/lib/Navigation.ts | 114 ++
frontend/src/lib/Pagination.ts | 31 +
frontend/src/lib/Reader.ts | 62 +
frontend/src/lib/Scraper.ts | 156 ++
frontend/src/lib/Selection.ts | 141 ++
frontend/src/lib/Shortcuts.ts | 153 ++
frontend/src/lib/Sort.ts | 42 +
frontend/src/lib/Tabs.ts | 18 +
frontend/src/lib/Toasts.ts | 19 +
frontend/src/lib/Transitions.ts | 10 +
frontend/src/lib/Update.ts | 97 ++
frontend/src/lib/Utils.ts | 108 ++
frontend/src/lib/assets/logo.webp | Bin 0 -> 89322 bytes
frontend/src/lib/components/AddButton.svelte | 7 +
frontend/src/lib/components/Badge.svelte | 15 +
frontend/src/lib/components/BookmarkButton.svelte | 9 +
frontend/src/lib/components/Card.svelte | 106 ++
frontend/src/lib/components/Cardlet.svelte | 37 +
frontend/src/lib/components/DeleteButton.svelte | 15 +
frontend/src/lib/components/Dialog.svelte | 36 +
frontend/src/lib/components/Dropdown.svelte | 18 +
frontend/src/lib/components/Empty.svelte | 10 +
frontend/src/lib/components/Expander.svelte | 17 +
frontend/src/lib/components/Guard.svelte | 13 +
frontend/src/lib/components/Head.svelte | 12 +
frontend/src/lib/components/Labelled.svelte | 10 +
frontend/src/lib/components/LabelledBlock.svelte | 18 +
frontend/src/lib/components/OrganizedButton.svelte | 9 +
frontend/src/lib/components/RefreshButton.svelte | 3 +
.../src/lib/components/RemovePageButton.svelte | 13 +
frontend/src/lib/components/Select.svelte | 55 +
frontend/src/lib/components/Spinner.svelte | 36 +
frontend/src/lib/components/SubmitButton.svelte | 7 +
frontend/src/lib/components/Titlebar.svelte | 32 +
frontend/src/lib/containers/Cardlets.svelte | 11 +
frontend/src/lib/containers/Cards.svelte | 8 +
frontend/src/lib/containers/Carousel.svelte | 15 +
frontend/src/lib/containers/Column.svelte | 3 +
frontend/src/lib/containers/Grid.svelte | 23 +
frontend/src/lib/dialogs/AddArtist.svelte | 30 +
frontend/src/lib/dialogs/AddCharacter.svelte | 30 +
frontend/src/lib/dialogs/AddCircle.svelte | 30 +
frontend/src/lib/dialogs/AddNamespace.svelte | 30 +
frontend/src/lib/dialogs/AddTag.svelte | 30 +
frontend/src/lib/dialogs/AddWorld.svelte | 30 +
frontend/src/lib/dialogs/ConfirmDeletion.svelte | 51 +
frontend/src/lib/dialogs/EditArtist.svelte | 46 +
frontend/src/lib/dialogs/EditCharacter.svelte | 46 +
frontend/src/lib/dialogs/EditCircle.svelte | 46 +
frontend/src/lib/dialogs/EditNamespace.svelte | 46 +
frontend/src/lib/dialogs/EditTag.svelte | 44 +
frontend/src/lib/dialogs/EditWorld.svelte | 46 +
frontend/src/lib/dialogs/UpdateComics.svelte | 96 ++
frontend/src/lib/dialogs/UpdateTags.svelte | 45 +
.../dialogs/components/UpdateModeSelector.svelte | 24 +
frontend/src/lib/filter/ComicFilterForm.svelte | 48 +
frontend/src/lib/filter/TagFilterForm.svelte | 31 +
.../lib/filter/components/ComicFilterGroup.svelte | 27 +
frontend/src/lib/filter/components/Filter.svelte | 77 +
.../src/lib/filter/components/FilterForm.svelte | 47 +
.../lib/filter/components/TagFilterGroup.svelte | 14 +
frontend/src/lib/forms/ArtistForm.svelte | 25 +
frontend/src/lib/forms/CharacterForm.svelte | 25 +
frontend/src/lib/forms/CircleForm.svelte | 25 +
frontend/src/lib/forms/ComicForm.svelte | 100 ++
frontend/src/lib/forms/NamespaceForm.svelte | 28 +
frontend/src/lib/forms/TagForm.svelte | 42 +
frontend/src/lib/forms/WorldForm.svelte | 25 +
frontend/src/lib/gallery/Gallery.svelte | 42 +
frontend/src/lib/gallery/GalleryPage.svelte | 93 ++
frontend/src/lib/icons/Bookmark.svelte | 10 +
frontend/src/lib/icons/Female.svelte | 1 +
frontend/src/lib/icons/Location.svelte | 1 +
frontend/src/lib/icons/Male.svelte | 1 +
frontend/src/lib/icons/Organized.svelte | 21 +
frontend/src/lib/icons/Star.svelte | 25 +
frontend/src/lib/icons/Transgender.svelte | 1 +
frontend/src/lib/navigation/Link.svelte | 20 +
frontend/src/lib/navigation/Navigation.svelte | 5 +
frontend/src/lib/pagination/Pagination.svelte | 45 +
frontend/src/lib/pagination/Target.svelte | 21 +
frontend/src/lib/pills/AssociationPill.svelte | 30 +
frontend/src/lib/pills/ComicPills.svelte | 37 +
frontend/src/lib/pills/Pill.svelte | 40 +
frontend/src/lib/pills/TagPill.svelte | 40 +
frontend/src/lib/reader/PageView.svelte | 67 +
frontend/src/lib/reader/Reader.svelte | 39 +
frontend/src/lib/reader/ReaderPage.svelte | 24 +
.../lib/reader/components/CloseReaderButton.svelte | 19 +
.../lib/reader/components/ReaderMenuButton.svelte | 16 +
frontend/src/lib/scraper/ComicScrapeForm.svelte | 138 ++
.../lib/scraper/components/SelectorButton.svelte | 22 +
.../lib/scraper/components/SelectorGroup.svelte | 35 +
.../src/lib/scraper/components/SelectorItem.svelte | 24 +
frontend/src/lib/selection/Selectable.svelte | 24 +
frontend/src/lib/selection/SelectionOverlay.svelte | 34 +
frontend/src/lib/tabs/AddOverlay.svelte | 36 +
frontend/src/lib/tabs/ArchiveDelete.svelte | 42 +
frontend/src/lib/tabs/ArchiveDetails.svelte | 50 +
frontend/src/lib/tabs/ArchiveEdit.svelte | 68 +
frontend/src/lib/tabs/ComicDelete.svelte | 34 +
frontend/src/lib/tabs/ComicDetails.svelte | 121 ++
frontend/src/lib/tabs/DetailsHeader.svelte | 11 +
frontend/src/lib/tabs/DetailsSection.svelte | 10 +
frontend/src/lib/tabs/Tab.svelte | 14 +
frontend/src/lib/tabs/Tabs.svelte | 40 +
frontend/src/lib/toolbar/DeleteSelection.svelte | 26 +
frontend/src/lib/toolbar/EditSelection.svelte | 29 +
frontend/src/lib/toolbar/FilterBookmarked.svelte | 24 +
frontend/src/lib/toolbar/FilterFavourites.svelte | 24 +
frontend/src/lib/toolbar/FilterOrganized.svelte | 30 +
frontend/src/lib/toolbar/MarkBookmark.svelte | 27 +
frontend/src/lib/toolbar/MarkFavourite.svelte | 27 +
frontend/src/lib/toolbar/MarkOrganized.svelte | 27 +
frontend/src/lib/toolbar/MarkSelection.svelte | 24 +
frontend/src/lib/toolbar/Search.svelte | 21 +
frontend/src/lib/toolbar/SelectItems.svelte | 19 +
frontend/src/lib/toolbar/SelectSort.svelte | 61 +
frontend/src/lib/toolbar/SelectionControls.svelte | 57 +
.../src/lib/toolbar/ToggleAdvancedFilters.svelte | 40 +
frontend/src/lib/toolbar/Toolbar.svelte | 42 +
frontend/src/routes/+layout.svelte | 95 ++
frontend/src/routes/+layout.ts | 1 +
frontend/src/routes/+page.svelte | 66 +
frontend/src/routes/archives/+page.svelte | 119 ++
frontend/src/routes/archives/+page.ts | 12 +
frontend/src/routes/archives/[id]/+page.svelte | 99 ++
frontend/src/routes/archives/[id]/+page.ts | 5 +
frontend/src/routes/artists/+page.svelte | 101 ++
frontend/src/routes/artists/+page.ts | 12 +
frontend/src/routes/characters/+page.svelte | 101 ++
frontend/src/routes/characters/+page.ts | 12 +
frontend/src/routes/circles/+page.svelte | 101 ++
frontend/src/routes/circles/+page.ts | 12 +
frontend/src/routes/comics/+page.svelte | 116 ++
frontend/src/routes/comics/+page.ts | 12 +
frontend/src/routes/comics/[id]/+page.svelte | 176 ++
frontend/src/routes/comics/[id]/+page.ts | 5 +
frontend/src/routes/namespaces/+page.svelte | 101 ++
frontend/src/routes/namespaces/+page.ts | 12 +
frontend/src/routes/tags/+page.svelte | 109 ++
frontend/src/routes/tags/+page.ts | 12 +
frontend/src/routes/worlds/+page.svelte | 102 ++
frontend/src/routes/worlds/+page.ts | 12 +
155 files changed, 9175 insertions(+)
create mode 100644 frontend/src/app.css
create mode 100644 frontend/src/app.d.ts
create mode 100644 frontend/src/app.html
create mode 100644 frontend/src/gql/Mutations.ts
create mode 100644 frontend/src/gql/Queries.ts
create mode 100644 frontend/src/gql/Utils.ts
create mode 100644 frontend/src/gql/graphql.ts
create mode 100644 frontend/src/lib/Actions.ts
create mode 100644 frontend/src/lib/Enums.ts
create mode 100644 frontend/src/lib/Filter.ts
create mode 100644 frontend/src/lib/Meta.ts
create mode 100644 frontend/src/lib/Navigation.ts
create mode 100644 frontend/src/lib/Pagination.ts
create mode 100644 frontend/src/lib/Reader.ts
create mode 100644 frontend/src/lib/Scraper.ts
create mode 100644 frontend/src/lib/Selection.ts
create mode 100644 frontend/src/lib/Shortcuts.ts
create mode 100644 frontend/src/lib/Sort.ts
create mode 100644 frontend/src/lib/Tabs.ts
create mode 100644 frontend/src/lib/Toasts.ts
create mode 100644 frontend/src/lib/Transitions.ts
create mode 100644 frontend/src/lib/Update.ts
create mode 100644 frontend/src/lib/Utils.ts
create mode 100644 frontend/src/lib/assets/logo.webp
create mode 100644 frontend/src/lib/components/AddButton.svelte
create mode 100644 frontend/src/lib/components/Badge.svelte
create mode 100644 frontend/src/lib/components/BookmarkButton.svelte
create mode 100644 frontend/src/lib/components/Card.svelte
create mode 100644 frontend/src/lib/components/Cardlet.svelte
create mode 100644 frontend/src/lib/components/DeleteButton.svelte
create mode 100644 frontend/src/lib/components/Dialog.svelte
create mode 100644 frontend/src/lib/components/Dropdown.svelte
create mode 100644 frontend/src/lib/components/Empty.svelte
create mode 100644 frontend/src/lib/components/Expander.svelte
create mode 100644 frontend/src/lib/components/Guard.svelte
create mode 100644 frontend/src/lib/components/Head.svelte
create mode 100644 frontend/src/lib/components/Labelled.svelte
create mode 100644 frontend/src/lib/components/LabelledBlock.svelte
create mode 100644 frontend/src/lib/components/OrganizedButton.svelte
create mode 100644 frontend/src/lib/components/RefreshButton.svelte
create mode 100644 frontend/src/lib/components/RemovePageButton.svelte
create mode 100644 frontend/src/lib/components/Select.svelte
create mode 100644 frontend/src/lib/components/Spinner.svelte
create mode 100644 frontend/src/lib/components/SubmitButton.svelte
create mode 100644 frontend/src/lib/components/Titlebar.svelte
create mode 100644 frontend/src/lib/containers/Cardlets.svelte
create mode 100644 frontend/src/lib/containers/Cards.svelte
create mode 100644 frontend/src/lib/containers/Carousel.svelte
create mode 100644 frontend/src/lib/containers/Column.svelte
create mode 100644 frontend/src/lib/containers/Grid.svelte
create mode 100644 frontend/src/lib/dialogs/AddArtist.svelte
create mode 100644 frontend/src/lib/dialogs/AddCharacter.svelte
create mode 100644 frontend/src/lib/dialogs/AddCircle.svelte
create mode 100644 frontend/src/lib/dialogs/AddNamespace.svelte
create mode 100644 frontend/src/lib/dialogs/AddTag.svelte
create mode 100644 frontend/src/lib/dialogs/AddWorld.svelte
create mode 100644 frontend/src/lib/dialogs/ConfirmDeletion.svelte
create mode 100644 frontend/src/lib/dialogs/EditArtist.svelte
create mode 100644 frontend/src/lib/dialogs/EditCharacter.svelte
create mode 100644 frontend/src/lib/dialogs/EditCircle.svelte
create mode 100644 frontend/src/lib/dialogs/EditNamespace.svelte
create mode 100644 frontend/src/lib/dialogs/EditTag.svelte
create mode 100644 frontend/src/lib/dialogs/EditWorld.svelte
create mode 100644 frontend/src/lib/dialogs/UpdateComics.svelte
create mode 100644 frontend/src/lib/dialogs/UpdateTags.svelte
create mode 100644 frontend/src/lib/dialogs/components/UpdateModeSelector.svelte
create mode 100644 frontend/src/lib/filter/ComicFilterForm.svelte
create mode 100644 frontend/src/lib/filter/TagFilterForm.svelte
create mode 100644 frontend/src/lib/filter/components/ComicFilterGroup.svelte
create mode 100644 frontend/src/lib/filter/components/Filter.svelte
create mode 100644 frontend/src/lib/filter/components/FilterForm.svelte
create mode 100644 frontend/src/lib/filter/components/TagFilterGroup.svelte
create mode 100644 frontend/src/lib/forms/ArtistForm.svelte
create mode 100644 frontend/src/lib/forms/CharacterForm.svelte
create mode 100644 frontend/src/lib/forms/CircleForm.svelte
create mode 100644 frontend/src/lib/forms/ComicForm.svelte
create mode 100644 frontend/src/lib/forms/NamespaceForm.svelte
create mode 100644 frontend/src/lib/forms/TagForm.svelte
create mode 100644 frontend/src/lib/forms/WorldForm.svelte
create mode 100644 frontend/src/lib/gallery/Gallery.svelte
create mode 100644 frontend/src/lib/gallery/GalleryPage.svelte
create mode 100644 frontend/src/lib/icons/Bookmark.svelte
create mode 100644 frontend/src/lib/icons/Female.svelte
create mode 100644 frontend/src/lib/icons/Location.svelte
create mode 100644 frontend/src/lib/icons/Male.svelte
create mode 100644 frontend/src/lib/icons/Organized.svelte
create mode 100644 frontend/src/lib/icons/Star.svelte
create mode 100644 frontend/src/lib/icons/Transgender.svelte
create mode 100644 frontend/src/lib/navigation/Link.svelte
create mode 100644 frontend/src/lib/navigation/Navigation.svelte
create mode 100644 frontend/src/lib/pagination/Pagination.svelte
create mode 100644 frontend/src/lib/pagination/Target.svelte
create mode 100644 frontend/src/lib/pills/AssociationPill.svelte
create mode 100644 frontend/src/lib/pills/ComicPills.svelte
create mode 100644 frontend/src/lib/pills/Pill.svelte
create mode 100644 frontend/src/lib/pills/TagPill.svelte
create mode 100644 frontend/src/lib/reader/PageView.svelte
create mode 100644 frontend/src/lib/reader/Reader.svelte
create mode 100644 frontend/src/lib/reader/ReaderPage.svelte
create mode 100644 frontend/src/lib/reader/components/CloseReaderButton.svelte
create mode 100644 frontend/src/lib/reader/components/ReaderMenuButton.svelte
create mode 100644 frontend/src/lib/scraper/ComicScrapeForm.svelte
create mode 100644 frontend/src/lib/scraper/components/SelectorButton.svelte
create mode 100644 frontend/src/lib/scraper/components/SelectorGroup.svelte
create mode 100644 frontend/src/lib/scraper/components/SelectorItem.svelte
create mode 100644 frontend/src/lib/selection/Selectable.svelte
create mode 100644 frontend/src/lib/selection/SelectionOverlay.svelte
create mode 100644 frontend/src/lib/tabs/AddOverlay.svelte
create mode 100644 frontend/src/lib/tabs/ArchiveDelete.svelte
create mode 100644 frontend/src/lib/tabs/ArchiveDetails.svelte
create mode 100644 frontend/src/lib/tabs/ArchiveEdit.svelte
create mode 100644 frontend/src/lib/tabs/ComicDelete.svelte
create mode 100644 frontend/src/lib/tabs/ComicDetails.svelte
create mode 100644 frontend/src/lib/tabs/DetailsHeader.svelte
create mode 100644 frontend/src/lib/tabs/DetailsSection.svelte
create mode 100644 frontend/src/lib/tabs/Tab.svelte
create mode 100644 frontend/src/lib/tabs/Tabs.svelte
create mode 100644 frontend/src/lib/toolbar/DeleteSelection.svelte
create mode 100644 frontend/src/lib/toolbar/EditSelection.svelte
create mode 100644 frontend/src/lib/toolbar/FilterBookmarked.svelte
create mode 100644 frontend/src/lib/toolbar/FilterFavourites.svelte
create mode 100644 frontend/src/lib/toolbar/FilterOrganized.svelte
create mode 100644 frontend/src/lib/toolbar/MarkBookmark.svelte
create mode 100644 frontend/src/lib/toolbar/MarkFavourite.svelte
create mode 100644 frontend/src/lib/toolbar/MarkOrganized.svelte
create mode 100644 frontend/src/lib/toolbar/MarkSelection.svelte
create mode 100644 frontend/src/lib/toolbar/Search.svelte
create mode 100644 frontend/src/lib/toolbar/SelectItems.svelte
create mode 100644 frontend/src/lib/toolbar/SelectSort.svelte
create mode 100644 frontend/src/lib/toolbar/SelectionControls.svelte
create mode 100644 frontend/src/lib/toolbar/ToggleAdvancedFilters.svelte
create mode 100644 frontend/src/lib/toolbar/Toolbar.svelte
create mode 100644 frontend/src/routes/+layout.svelte
create mode 100644 frontend/src/routes/+layout.ts
create mode 100644 frontend/src/routes/+page.svelte
create mode 100644 frontend/src/routes/archives/+page.svelte
create mode 100644 frontend/src/routes/archives/+page.ts
create mode 100644 frontend/src/routes/archives/[id]/+page.svelte
create mode 100644 frontend/src/routes/archives/[id]/+page.ts
create mode 100644 frontend/src/routes/artists/+page.svelte
create mode 100644 frontend/src/routes/artists/+page.ts
create mode 100644 frontend/src/routes/characters/+page.svelte
create mode 100644 frontend/src/routes/characters/+page.ts
create mode 100644 frontend/src/routes/circles/+page.svelte
create mode 100644 frontend/src/routes/circles/+page.ts
create mode 100644 frontend/src/routes/comics/+page.svelte
create mode 100644 frontend/src/routes/comics/+page.ts
create mode 100644 frontend/src/routes/comics/[id]/+page.svelte
create mode 100644 frontend/src/routes/comics/[id]/+page.ts
create mode 100644 frontend/src/routes/namespaces/+page.svelte
create mode 100644 frontend/src/routes/namespaces/+page.ts
create mode 100644 frontend/src/routes/tags/+page.svelte
create mode 100644 frontend/src/routes/tags/+page.ts
create mode 100644 frontend/src/routes/worlds/+page.svelte
create mode 100644 frontend/src/routes/worlds/+page.ts
(limited to 'frontend/src')
diff --git a/frontend/src/app.css b/frontend/src/app.css
new file mode 100644
index 0000000..13a7883
--- /dev/null
+++ b/frontend/src/app.css
@@ -0,0 +1,180 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ body {
+ display: grid;
+ grid-template-columns: 3rem 1fr;
+ scrollbar-color: theme('colors.gray.500') rgba(0, 0, 0, 0);
+ font-family: 'Noto Sans', sans-serif;
+ }
+
+ input,
+ textarea {
+ @apply w-full rounded bg-slate-900 p-[.4rem] focus:outline focus:outline-1 focus:outline-slate-500;
+ }
+
+ label {
+ @apply mb-0.5 inline-block;
+ }
+
+ form {
+ @apply flex flex-col gap-4 p-px text-sm;
+ }
+
+ .rounded-group > * {
+ @apply rounded-none first:rounded-l-sm last:rounded-r-sm !important;
+ }
+
+ .rounded-group-start > * {
+ @apply rounded-none first:rounded-l-sm !important;
+ }
+
+ .rounded-group-end > * {
+ @apply rounded-none last:rounded-r-sm !important;
+ }
+
+ .grid-labels {
+ @apply grid grid-cols-[1fr_5fr] gap-2;
+ }
+
+ header {
+ grid-area: header;
+ }
+
+ aside {
+ overflow: auto;
+ grid-area: sidebar;
+ @apply lg:w-[28rem] xl:w-[32rem] min-[1920px]:w-[36rem];
+ }
+
+ main {
+ grid-area: main;
+ }
+}
+
+@layer components {
+ .btn {
+ @apply flex items-center justify-center rounded-sm p-2 text-white transition-colors disabled:opacity-40;
+ }
+
+ .btn-xs {
+ @apply btn rounded-sm p-0.5 py-0;
+ }
+
+ .btn-blue {
+ @apply btn bg-blue-700 hover:bg-blue-600 disabled:bg-blue-900;
+ }
+
+ .btn-rose {
+ @apply btn bg-rose-700 hover:bg-rose-600 disabled:bg-rose-900;
+ }
+
+ .btn-slate {
+ @apply btn bg-slate-700 hover:bg-slate-600 disabled:bg-slate-800;
+ }
+
+ .btn-indigo {
+ @apply btn bg-indigo-700 hover:bg-indigo-600 disabled:bg-indigo-800;
+ }
+
+ .icon-xs {
+ @apply text-[18px];
+ }
+
+ .icon-base {
+ @apply text-[24px];
+ }
+
+ .icon-lg {
+ @apply text-[28px];
+ }
+
+ .icon-2xl {
+ @apply text-[48px];
+ }
+
+ .icon-gray.hoverable:hover {
+ @apply text-gray-200/80;
+ }
+
+ .icon-gray.dim {
+ @apply text-gray-100/40;
+ }
+
+ .icon-yellow {
+ @apply text-yellow-300;
+ }
+
+ .icon-yellow.hoverable:hover {
+ @apply text-yellow-300/80;
+ }
+
+ .icon-yellow.dim {
+ @apply text-slate-100/40;
+ }
+}
+
+@layer utilities {
+ .toggled {
+ @apply bg-indigo-700 hover:bg-indigo-600;
+ }
+
+ .floating {
+ @apply rounded-full bg-black/50 p-1 text-white/80 backdrop-blur-sm hover:bg-black/50 hover:text-white;
+ }
+
+ .ellipsis-nowrap {
+ @apply overflow-hidden text-ellipsis whitespace-nowrap;
+ }
+
+ .rounded-inherit {
+ border-radius: inherit;
+ }
+
+ .grid-card-h {
+ grid-template-columns: 210px 1fr;
+ grid-template-rows: 300px;
+ }
+
+ .grid-card-cover-only {
+ @apply !grid-card-h;
+ }
+
+ .grid-card-v {
+ grid-template-columns: 1fr;
+ grid-template-rows: 500px 1fr;
+ }
+}
+
+.svelecte-control {
+ --sv-item-color: inherit !important;
+ --sv-bg: theme(colors.slate.900) !important;
+ --sv-disabled-bg: theme(colors.slate.900) !important;
+ --sv-border: 1px solid rgba(0, 0, 0, 0) !important;
+ --sv-disabled-border-color: rgba(0, 0, 0, 0) !important;
+ --sv-border-color: theme(colors.slate.600) !important;
+ --sv-active-border: 1px solid theme(colors.slate.500) !important;
+ --sv-item-selected-bg: theme(colors.indigo.800) !important;
+ --sv-item-active-bg: theme(colors.indigo.800) !important;
+ --sv-highlight-bg: none !important;
+ --sv-item-btn-bg-hover: theme(colors.rose.900) !important;
+ --sv-placeholder-color: theme(colors.gray.500) !important;
+}
+
+.svelecte-control input {
+ @apply !h-8;
+}
+
+.exclude .svelecte-control {
+ --sv-border: 1px solid theme('colors.red.900') !important;
+ --sv-active-border: 1px solid theme('colors.red.700') !important;
+
+ --sv-item-selected-bg: theme(colors.rose.800) !important;
+ --sv-item-active-bg: theme(colors.rose.800) !important;
+}
+
+.sv-dropdown {
+ @apply my-1 !bg-slate-950;
+}
diff --git a/frontend/src/app.d.ts b/frontend/src/app.d.ts
new file mode 100644
index 0000000..41634fe
--- /dev/null
+++ b/frontend/src/app.d.ts
@@ -0,0 +1,12 @@
+///
+///
+
+// See https://kit.svelte.dev/docs/types#app
+// for information about these interfaces
+// and what to do when importing types
+declare namespace App {
+ // interface Locals {}
+ // interface PageData {}
+ // interface Error {}
+ // interface Platform {}
+}
diff --git a/frontend/src/app.html b/frontend/src/app.html
new file mode 100644
index 0000000..6303945
--- /dev/null
+++ b/frontend/src/app.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ hircine
+ %sveltekit.head%
+
+
+ %sveltekit.body%
+
+
diff --git a/frontend/src/gql/Mutations.ts b/frontend/src/gql/Mutations.ts
new file mode 100644
index 0000000..d669b25
--- /dev/null
+++ b/frontend/src/gql/Mutations.ts
@@ -0,0 +1,244 @@
+import { toastSuccess } from '$lib/Toasts';
+import {
+ Client,
+ type AnyVariables,
+ type OperationResult,
+ type OperationResultSource
+} from '@urql/svelte';
+import { isError, isSuccess, type RequiredName } from './Utils';
+import * as gql from './graphql';
+
+export type DeleteMutation = (client: Client, args: { ids: number | number[] }) => Promise;
+
+const comicTypes = ['Comic'];
+const comicUpsertTypes = comicTypes.concat([
+ 'Artist',
+ 'Character',
+ 'Circle',
+ 'Namespace',
+ 'Collection',
+ 'Tag',
+ 'World'
+]);
+
+function handleResult(result: OperationResult): Promise {
+ return new Promise((resolve, reject) => {
+ if (result.error) {
+ return reject(`${result.error.name}: ${result.error.message}`);
+ }
+
+ if (!result.data) {
+ return reject('Mutation resolved, but result contains no data.');
+ }
+
+ const obj = Object.values(result.data)[0];
+
+ if (isError(obj)) {
+ reject(obj.message);
+ } else if (isSuccess(obj)) {
+ toastSuccess(obj.message);
+ resolve(result.data);
+ }
+
+ reject('This should not happen.');
+ });
+}
+
+async function handleMutation(
+ mutation: OperationResultSource>
+) {
+ return await mutation.toPromise().then(handleResult);
+}
+
+export async function addComic(client: Client, args: gql.AddComicMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.AddComicDocument, args, {
+ additionalTypenames: comicTypes.concat('Archive', 'Page')
+ })
+ );
+}
+
+export async function updateComics(client: Client, args: gql.UpdateComicsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.UpdateComicsDocument, args, {
+ additionalTypenames: comicTypes
+ })
+ );
+}
+
+export async function upsertComics(client: Client, args: gql.UpsertComicsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.UpsertComicsDocument, args, {
+ additionalTypenames: comicUpsertTypes
+ })
+ );
+}
+
+export async function updateArchives(client: Client, args: gql.UpdateArchivesMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.UpdateArchivesDocument, args, {
+ additionalTypenames: ['Archive']
+ })
+ );
+}
+
+export async function deleteArchives(client: Client, args: gql.DeleteArchivesMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.DeleteArchivesDocument, args, {
+ additionalTypenames: comicTypes.concat('Archive')
+ })
+ );
+}
+
+export async function deleteComics(client: Client, args: gql.DeleteComicsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.DeleteComicsDocument, args, { additionalTypenames: comicTypes })
+ );
+}
+
+export async function addArtist(client: Client, args: gql.AddArtistMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.AddArtistDocument, args, { additionalTypenames: ['ArtistFilterResult'] })
+ );
+}
+
+export async function updateArtists(client: Client, args: gql.UpdateArtistsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.UpdateArtistsDocument, args, { additionalTypenames: ['Artist'] })
+ );
+}
+
+export async function deleteArtists(client: Client, args: gql.DeleteArtistsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.DeleteArtistsDocument, args, {
+ additionalTypenames: ['Artist']
+ })
+ );
+}
+
+export async function addCharacter(client: Client, args: gql.AddCharacterMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.AddCharacterDocument, args, {
+ additionalTypenames: ['CharacterFilterResult']
+ })
+ );
+}
+
+export async function updateCharacters(
+ client: Client,
+ args: gql.UpdateCharactersMutationVariables
+) {
+ return await handleMutation(
+ client.mutation(gql.UpdateCharactersDocument, args, { additionalTypenames: ['Character'] })
+ );
+}
+
+export async function deleteCharacters(
+ client: Client,
+ args: gql.DeleteCharactersMutationVariables
+) {
+ return await handleMutation(
+ client.mutation(gql.DeleteCharactersDocument, args, {
+ additionalTypenames: ['Character']
+ })
+ );
+}
+
+export async function addCircle(client: Client, args: gql.AddCircleMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.AddCircleDocument, args, { additionalTypenames: ['CircleFilterResult'] })
+ );
+}
+
+export async function updateCircles(client: Client, args: gql.UpdateCirclesMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.UpdateCirclesDocument, args, { additionalTypenames: ['Circle'] })
+ );
+}
+
+export async function deleteCircles(client: Client, args: gql.DeleteCirclesMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.DeleteCirclesDocument, args, {
+ additionalTypenames: ['Circle']
+ })
+ );
+}
+
+export async function addNamespace(client: Client, args: gql.AddNamespaceMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.AddNamespaceDocument, args, {
+ additionalTypenames: ['NamespaceFilterResult', 'ComicTagFilterResult']
+ })
+ );
+}
+
+export async function updateNamespaces(
+ client: Client,
+ args: gql.UpdateNamespacesMutationVariables
+) {
+ return await handleMutation(
+ client.mutation(gql.UpdateNamespacesDocument, args, {
+ additionalTypenames: ['Namespace', 'ComicTag']
+ })
+ );
+}
+
+export async function deleteNamespaces(
+ client: Client,
+ args: gql.DeleteNamespacesMutationVariables
+) {
+ return await handleMutation(
+ client.mutation(gql.DeleteNamespacesDocument, args, {
+ additionalTypenames: ['NamespaceFilterResult', 'ComicTag']
+ })
+ );
+}
+
+export async function addTag(client: Client, args: gql.AddTagMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.AddTagDocument, args, {
+ additionalTypenames: ['TagFilterResult', 'ComicTagFilterResult']
+ })
+ );
+}
+
+export async function updateTags(client: Client, args: gql.UpdateTagsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.UpdateTagsDocument, args, {
+ additionalTypenames: ['Tag', 'ComicTag']
+ })
+ );
+}
+
+export async function deleteTags(client: Client, args: gql.DeleteTagsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.DeleteTagsDocument, args, {
+ additionalTypenames: ['TagFilterResult', 'ComicTag']
+ })
+ );
+}
+
+export async function addWorld(client: Client, args: gql.AddWorldMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.AddWorldDocument, args, { additionalTypenames: ['WorldFilterResult'] })
+ );
+}
+
+export async function updateWorlds(client: Client, args: gql.UpdateWorldsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.UpdateWorldsDocument, args, { additionalTypenames: ['World'] })
+ );
+}
+
+export async function deleteWorlds(client: Client, args: gql.DeleteWorldsMutationVariables) {
+ return await handleMutation(
+ client.mutation(gql.DeleteWorldsDocument, args, { additionalTypenames: ['World'] })
+ );
+}
+
+export type ArtistInput = RequiredName;
+export type CharacterInput = RequiredName;
+export type CircleInput = RequiredName;
+export type NamespaceInput = RequiredName;
+export type TagInput = RequiredName;
+export type WorldInput = RequiredName;
diff --git a/frontend/src/gql/Queries.ts b/frontend/src/gql/Queries.ts
new file mode 100644
index 0000000..cc9dd4c
--- /dev/null
+++ b/frontend/src/gql/Queries.ts
@@ -0,0 +1,243 @@
+import { Client, queryStore, type OperationResult } from '@urql/svelte';
+import { isError } from './Utils';
+import * as gql from './graphql';
+
+function handleResult(result: OperationResult): Promise {
+ return new Promise((resolve, reject) => {
+ if (result.error) {
+ return reject(`${result.error.name}: ${result.error.message}`);
+ }
+
+ if (!result.data) {
+ return reject('Query resolved, but result contains no data.');
+ }
+
+ const data = Object.values(result.data)[0];
+
+ if (isError(data)) {
+ reject(data.message);
+ } else {
+ resolve(data);
+ }
+
+ reject('This should not happen.');
+ });
+}
+
+export function comicTagList(client: Client, args?: gql.ComicTagListQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.ComicTagListDocument,
+ context: {
+ additionalTypenames: ['Namespace', 'Tag']
+ },
+ variables: args
+ });
+}
+
+export function artistList(client: Client) {
+ return queryStore({
+ client: client,
+ query: gql.ArtistListDocument,
+ context: {
+ additionalTypenames: ['Artist']
+ }
+ });
+}
+
+export function characterList(client: Client) {
+ return queryStore({
+ client: client,
+ query: gql.CharacterListDocument,
+ context: {
+ additionalTypenames: ['Character']
+ }
+ });
+}
+
+export function circleList(client: Client) {
+ return queryStore({
+ client: client,
+ query: gql.CircleListDocument,
+ context: {
+ additionalTypenames: ['Circle']
+ }
+ });
+}
+
+export function worldList(client: Client) {
+ return queryStore({
+ client: client,
+ query: gql.WorldListDocument,
+ context: {
+ additionalTypenames: ['World']
+ }
+ });
+}
+
+export function namespaceList(client: Client) {
+ return queryStore({
+ client: client,
+ query: gql.NamespaceListDocument,
+ context: {
+ additionalTypenames: ['Namespace']
+ }
+ });
+}
+
+export function comicScrapersQuery(client: Client, args: gql.ComicScrapersQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.ComicScrapersDocument,
+ variables: args,
+ context: {
+ additionalTypenames: ['Comic']
+ }
+ });
+}
+
+export async function scrapeComic(client: Client, args: gql.ScrapeComicQueryVariables) {
+ return await client
+ .query(gql.ScrapeComicDocument, args, { additionalTypenames: ['Comic'] })
+ .toPromise();
+}
+
+export function archiveQuery(client: Client, args: gql.ArchiveQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.ArchiveDocument,
+ variables: args,
+ context: { additionalTypenames: ['Archive'] }
+ });
+}
+
+export function archivesQuery(client: Client, args: gql.ArchivesQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.ArchivesDocument,
+ variables: args,
+ context: { additionalTypenames: ['Archive'] }
+ });
+}
+
+export function artistsQuery(client: Client, args?: gql.ArtistsQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.ArtistsDocument,
+ variables: args,
+ context: { additionalTypenames: ['Artist'] }
+ });
+}
+
+export function charactersQuery(client: Client, args?: gql.CharactersQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.CharactersDocument,
+ variables: args,
+ context: { additionalTypenames: ['Character'] }
+ });
+}
+
+export function circlesQuery(client: Client, args?: gql.CirclesQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.CirclesDocument,
+ variables: args,
+ context: { additionalTypenames: ['Circle'] }
+ });
+}
+
+export function comicQuery(client: Client, args: gql.ComicQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.ComicDocument,
+ variables: args,
+ context: { additionalTypenames: ['Comic'] }
+ });
+}
+
+export function comicsQuery(client: Client, args?: gql.ComicsQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.ComicsDocument,
+ variables: args,
+ context: { additionalTypenames: ['Comic'] }
+ });
+}
+
+export function namespacesQuery(client: Client, args?: gql.NamespacesQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.NamespacesDocument,
+ variables: args,
+ context: { additionalTypenames: ['Namespace'] }
+ });
+}
+
+export function tagsQuery(client: Client, args?: gql.TagsQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.TagsDocument,
+ variables: args,
+ context: { additionalTypenames: ['Tag'] }
+ });
+}
+
+export function worldsQuery(client: Client, args?: gql.WorldsQueryVariables) {
+ return queryStore({
+ client: client,
+ query: gql.WorldsDocument,
+ variables: args,
+ context: { additionalTypenames: ['World'] }
+ });
+}
+
+export function frontpageQuery(client: Client) {
+ return queryStore({
+ client: client,
+ query: gql.FrontpageDocument,
+ requestPolicy: 'network-only'
+ });
+}
+
+export function fetchArtist(client: Client, id: number) {
+ return client
+ .query(gql.ArtistDocument, { id }, { requestPolicy: 'cache-and-network' })
+ .toPromise()
+ .then(handleResult);
+}
+
+export function fetchCharacter(client: Client, id: number) {
+ return client
+ .query(gql.CharacterDocument, { id }, { requestPolicy: 'cache-and-network' })
+ .toPromise()
+ .then(handleResult);
+}
+
+export function fetchCircle(client: Client, id: number) {
+ return client
+ .query(gql.CircleDocument, { id }, { requestPolicy: 'cache-and-network' })
+ .toPromise()
+ .then(handleResult);
+}
+
+export function fetchNamespace(client: Client, id: number) {
+ return client
+ .query(gql.NamespaceDocument, { id }, { requestPolicy: 'cache-and-network' })
+ .toPromise()
+ .then(handleResult);
+}
+
+export function fetchTag(client: Client, id: number) {
+ return client
+ .query(gql.TagDocument, { id }, { requestPolicy: 'cache-and-network' })
+ .toPromise()
+ .then(handleResult);
+}
+
+export function fetchWorld(client: Client, id: number) {
+ return client
+ .query(gql.WorldDocument, { id }, { requestPolicy: 'cache-and-network' })
+ .toPromise()
+ .then(handleResult);
+}
diff --git a/frontend/src/gql/Utils.ts b/frontend/src/gql/Utils.ts
new file mode 100644
index 0000000..dd21bbe
--- /dev/null
+++ b/frontend/src/gql/Utils.ts
@@ -0,0 +1,74 @@
+import equal from 'fast-deep-equal';
+import * as gql from './graphql';
+
+export type OmitIdentifiers = Omit;
+export type RequiredName = T & { name: string };
+
+export function isSuccess(object: any): object is gql.Success {
+ if (object.__typename === undefined) {
+ return false;
+ }
+
+ return object.__typename.endsWith('Success') && (object as gql.Success).message !== undefined;
+}
+
+export function isError(object: any): object is gql.Error {
+ if (object.__typename === undefined) {
+ return false;
+ }
+ return object.__typename.endsWith('Error') && (object as gql.Error).message !== undefined;
+}
+
+type Item = {
+ id: number | string;
+ name: string;
+};
+
+export function itemEquals(a: Item, b: Item) {
+ return a.name == b.name;
+}
+
+function assocEquals(as: Item[], bs: Item[]) {
+ return equal(
+ as.map((a) => a.id),
+ bs.map((b) => b.id)
+ );
+}
+
+function stringEquals(a: string | null | undefined, b: string | null | undefined) {
+ return (a ? a : null) == (b ? b : null);
+}
+
+export function tagEquals(a: gql.FullTag, b: gql.FullTag) {
+ return (
+ itemEquals(a, b) &&
+ stringEquals(a.description, b.description) &&
+ assocEquals(a.namespaces, b.namespaces)
+ );
+}
+
+export function comicEquals(
+ a: gql.FullComicFragment | undefined,
+ b: gql.FullComicFragment | undefined
+) {
+ if (a === undefined) return b === undefined;
+ if (b === undefined) return a === undefined;
+
+ return (
+ stringEquals(a.title, b.title) &&
+ stringEquals(a.originalTitle, b.originalTitle) &&
+ stringEquals(a.url, b.url) &&
+ stringEquals(a.date, b.date) &&
+ a.category == b.category &&
+ a.rating == b.rating &&
+ a.censorship == b.censorship &&
+ a.language == b.language &&
+ a.direction == b.direction &&
+ a.layout == b.layout &&
+ assocEquals(a.artists, b.artists) &&
+ assocEquals(a.circles, b.circles) &&
+ assocEquals(a.characters, b.characters) &&
+ assocEquals(a.tags, b.tags) &&
+ assocEquals(a.worlds, b.worlds)
+ );
+}
diff --git a/frontend/src/gql/graphql.ts b/frontend/src/gql/graphql.ts
new file mode 100644
index 0000000..139068c
--- /dev/null
+++ b/frontend/src/gql/graphql.ts
@@ -0,0 +1,1764 @@
+import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
+export type Maybe = T | null;
+export type InputMaybe = Maybe;
+export type Exact = { [K in keyof T]: T[K] };
+export type MakeOptional = Omit & { [SubKey in K]?: Maybe };
+export type MakeMaybe = Omit & { [SubKey in K]: Maybe };
+export type MakeEmpty = { [_ in K]?: never };
+export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
+/** All built-in and custom scalars, mapped to their actual values */
+export type Scalars = {
+ ID: { input: string; output: string; }
+ String: { input: string; output: string; }
+ Boolean: { input: boolean; output: boolean; }
+ Int: { input: number; output: number; }
+ Float: { input: number; output: number; }
+ Date: { input: string; output: string; }
+ DateTime: { input: string; output: string; }
+};
+
+export type AddArtistInput = {
+ name: Scalars['String']['input'];
+};
+
+export type AddCharacterInput = {
+ name: Scalars['String']['input'];
+};
+
+export type AddCircleInput = {
+ name: Scalars['String']['input'];
+};
+
+export type AddComicInput = {
+ archive: ArchiveInput;
+ cover: CoverInput;
+ pages: UniquePagesInput;
+ title: Scalars['String']['input'];
+};
+
+export type AddComicResponse = AddComicSuccess | IdNotFoundError | InvalidParameterError | PageClaimedError | PageRemoteError;
+
+export type AddComicSuccess = Success & {
+ __typename?: 'AddComicSuccess';
+ archivePagesRemaining: Scalars['Boolean']['output'];
+ id: Scalars['Int']['output'];
+ message: Scalars['String']['output'];
+};
+
+export type AddNamespaceInput = {
+ name: Scalars['String']['input'];
+ sortName?: InputMaybe;
+};
+
+export type AddResponse = AddSuccess | IdNotFoundError | InvalidParameterError | NameExistsError;
+
+export type AddSuccess = Success & {
+ __typename?: 'AddSuccess';
+ id: Scalars['Int']['output'];
+ message: Scalars['String']['output'];
+};
+
+export type AddTagInput = {
+ description?: InputMaybe;
+ name: Scalars['String']['input'];
+ namespaces?: InputMaybe;
+};
+
+export type AddWorldInput = {
+ name: Scalars['String']['input'];
+};
+
+export type Archive = {
+ __typename?: 'Archive';
+ cover: Image;
+ id: Scalars['Int']['output'];
+ name: Scalars['String']['output'];
+ organized: Scalars['Boolean']['output'];
+ pageCount: Scalars['Int']['output'];
+ path: Scalars['String']['output'];
+ size: Scalars['Int']['output'];
+};
+
+export type ArchiveFilter = {
+ organized?: InputMaybe;
+ path?: InputMaybe;
+};
+
+export type ArchiveFilterInput = {
+ exclude?: InputMaybe;
+ include?: InputMaybe;
+};
+
+export type ArchiveFilterResult = {
+ __typename?: 'ArchiveFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type ArchiveInput = {
+ id: Scalars['Int']['input'];
+};
+
+export type ArchiveResponse = FullArchive | IdNotFoundError;
+
+export enum ArchiveSort {
+ CreatedAt = 'CREATED_AT',
+ PageCount = 'PAGE_COUNT',
+ Path = 'PATH',
+ Random = 'RANDOM',
+ Size = 'SIZE'
+}
+
+export type ArchiveSortInput = {
+ direction?: InputMaybe;
+ on: ArchiveSort;
+ seed?: InputMaybe;
+};
+
+export type Artist = {
+ __typename?: 'Artist';
+ id: Scalars['Int']['output'];
+ name: Scalars['String']['output'];
+};
+
+export type ArtistFilter = {
+ name?: InputMaybe;
+};
+
+export type ArtistFilterInput = {
+ exclude?: InputMaybe;
+ include?: InputMaybe;
+};
+
+export type ArtistFilterResult = {
+ __typename?: 'ArtistFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type ArtistResponse = Artist | IdNotFoundError;
+
+export enum ArtistSort {
+ CreatedAt = 'CREATED_AT',
+ Name = 'NAME',
+ Random = 'RANDOM',
+ UpdatedAt = 'UPDATED_AT'
+}
+
+export type ArtistSortInput = {
+ direction?: InputMaybe;
+ on: ArtistSort;
+ seed?: InputMaybe;
+};
+
+export type ArtistsUpdateInput = {
+ ids: Array;
+ options?: InputMaybe;
+};
+
+export type ArtistsUpsertInput = {
+ names?: Array;
+ options?: InputMaybe;
+};
+
+export type AssociationFilter = {
+ all?: InputMaybe>;
+ any?: InputMaybe>;
+ empty?: InputMaybe;
+ exact?: InputMaybe>;
+};
+
+export enum Category {
+ Artbook = 'ARTBOOK',
+ Comic = 'COMIC',
+ Doujinshi = 'DOUJINSHI',
+ GameCg = 'GAME_CG',
+ ImageSet = 'IMAGE_SET',
+ Manga = 'MANGA',
+ VariantSet = 'VARIANT_SET',
+ Webtoon = 'WEBTOON'
+}
+
+export type CategoryFilter = {
+ any?: InputMaybe>;
+ empty?: InputMaybe;
+};
+
+export enum Censorship {
+ Bar = 'BAR',
+ Full = 'FULL',
+ Mosaic = 'MOSAIC',
+ None = 'NONE'
+}
+
+export type CensorshipFilter = {
+ any?: InputMaybe>;
+ empty?: InputMaybe;
+};
+
+export type Character = {
+ __typename?: 'Character';
+ id: Scalars['Int']['output'];
+ name: Scalars['String']['output'];
+};
+
+export type CharacterFilter = {
+ name?: InputMaybe;
+};
+
+export type CharacterFilterInput = {
+ exclude?: InputMaybe;
+ include?: InputMaybe;
+};
+
+export type CharacterFilterResult = {
+ __typename?: 'CharacterFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type CharacterResponse = Character | IdNotFoundError;
+
+export enum CharacterSort {
+ CreatedAt = 'CREATED_AT',
+ Name = 'NAME',
+ Random = 'RANDOM',
+ UpdatedAt = 'UPDATED_AT'
+}
+
+export type CharacterSortInput = {
+ direction?: InputMaybe;
+ on: CharacterSort;
+ seed?: InputMaybe;
+};
+
+export type CharactersUpdateInput = {
+ ids: Array;
+ options?: InputMaybe;
+};
+
+export type CharactersUpsertInput = {
+ names?: Array;
+ options?: InputMaybe;
+};
+
+export type Circle = {
+ __typename?: 'Circle';
+ id: Scalars['Int']['output'];
+ name: Scalars['String']['output'];
+};
+
+export type CircleFilter = {
+ name?: InputMaybe;
+};
+
+export type CircleFilterInput = {
+ exclude?: InputMaybe;
+ include?: InputMaybe;
+};
+
+export type CircleFilterResult = {
+ __typename?: 'CircleFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type CircleResponse = Circle | IdNotFoundError;
+
+export enum CircleSort {
+ CreatedAt = 'CREATED_AT',
+ Name = 'NAME',
+ Random = 'RANDOM',
+ UpdatedAt = 'UPDATED_AT'
+}
+
+export type CircleSortInput = {
+ direction?: InputMaybe;
+ on: CircleSort;
+ seed?: InputMaybe;
+};
+
+export type CirclesUpdateInput = {
+ ids: Array;
+ options?: InputMaybe;
+};
+
+export type CirclesUpsertInput = {
+ names?: Array;
+ options?: InputMaybe;
+};
+
+export type Comic = {
+ __typename?: 'Comic';
+ artists: Array;
+ bookmarked: Scalars['Boolean']['output'];
+ category?: Maybe;
+ censorship?: Maybe;
+ characters: Array;
+ circles: Array;
+ cover: Image;
+ date?: Maybe;
+ favourite: Scalars['Boolean']['output'];
+ id: Scalars['Int']['output'];
+ language?: Maybe;
+ organized: Scalars['Boolean']['output'];
+ originalTitle?: Maybe;
+ pageCount: Scalars['Int']['output'];
+ rating?: Maybe;
+ tags: Array;
+ title: Scalars['String']['output'];
+ worlds: Array;
+};
+
+export type ComicFilter = {
+ artists?: InputMaybe;
+ bookmarked?: InputMaybe;
+ category?: InputMaybe;
+ censorship?: InputMaybe;
+ characters?: InputMaybe;
+ circles?: InputMaybe;
+ favourite?: InputMaybe;
+ language?: InputMaybe;
+ organized?: InputMaybe;
+ originalTitle?: InputMaybe;
+ rating?: InputMaybe;
+ tags?: InputMaybe;
+ title?: InputMaybe;
+ url?: InputMaybe;
+ worlds?: InputMaybe;
+};
+
+export type ComicFilterInput = {
+ exclude?: InputMaybe;
+ include?: InputMaybe;
+};
+
+export type ComicFilterResult = {
+ __typename?: 'ComicFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type ComicResponse = FullComic | IdNotFoundError;
+
+export type ComicScraper = {
+ __typename?: 'ComicScraper';
+ id: Scalars['String']['output'];
+ name: Scalars['String']['output'];
+};
+
+export enum ComicSort {
+ CreatedAt = 'CREATED_AT',
+ Date = 'DATE',
+ OriginalTitle = 'ORIGINAL_TITLE',
+ PageCount = 'PAGE_COUNT',
+ Random = 'RANDOM',
+ TagCount = 'TAG_COUNT',
+ Title = 'TITLE',
+ UpdatedAt = 'UPDATED_AT'
+}
+
+export type ComicSortInput = {
+ direction?: InputMaybe;
+ on: ComicSort;
+ seed?: InputMaybe;
+};
+
+export type ComicTag = {
+ __typename?: 'ComicTag';
+ description?: Maybe;
+ id: Scalars['String']['output'];
+ name: Scalars['String']['output'];
+};
+
+export type ComicTagFilterResult = {
+ __typename?: 'ComicTagFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type ComicTagsUpdateInput = {
+ ids?: Array;
+ options?: InputMaybe;
+};
+
+export type ComicTagsUpsertInput = {
+ names?: Array;
+ options?: InputMaybe;
+};
+
+export type CoverInput = {
+ id: Scalars['Int']['input'];
+};
+
+export type CoverUpdateInput = {
+ id: Scalars['Int']['input'];
+};
+
+export type DeleteResponse = DeleteSuccess | IdNotFoundError;
+
+export type DeleteSuccess = Success & {
+ __typename?: 'DeleteSuccess';
+ message: Scalars['String']['output'];
+};
+
+export enum Direction {
+ LeftToRight = 'LEFT_TO_RIGHT',
+ RightToLeft = 'RIGHT_TO_LEFT'
+}
+
+export type Error = {
+ message: Scalars['String']['output'];
+};
+
+export type FullArchive = {
+ __typename?: 'FullArchive';
+ comics: Array;
+ cover: Image;
+ createdAt: Scalars['DateTime']['output'];
+ id: Scalars['Int']['output'];
+ mtime: Scalars['DateTime']['output'];
+ name: Scalars['String']['output'];
+ organized: Scalars['Boolean']['output'];
+ pageCount: Scalars['Int']['output'];
+ pages: Array;
+ path: Scalars['String']['output'];
+ size: Scalars['Int']['output'];
+};
+
+export type FullComic = {
+ __typename?: 'FullComic';
+ archive: Archive;
+ artists: Array;
+ bookmarked: Scalars['Boolean']['output'];
+ category?: Maybe;
+ censorship?: Maybe;
+ characters: Array;
+ circles: Array;
+ cover: Image;
+ createdAt: Scalars['DateTime']['output'];
+ date?: Maybe;
+ direction: Direction;
+ favourite: Scalars['Boolean']['output'];
+ id: Scalars['Int']['output'];
+ language?: Maybe;
+ layout: Layout;
+ organized: Scalars['Boolean']['output'];
+ originalTitle?: Maybe;
+ pageCount: Scalars['Int']['output'];
+ pages: Array;
+ rating?: Maybe;
+ tags: Array;
+ title: Scalars['String']['output'];
+ updatedAt: Scalars['DateTime']['output'];
+ url?: Maybe;
+ worlds: Array;
+};
+
+export type FullTag = {
+ __typename?: 'FullTag';
+ description?: Maybe;
+ id: Scalars['Int']['output'];
+ name: Scalars['String']['output'];
+ namespaces: Array;
+};
+
+export type IdNotFoundError = Error & {
+ __typename?: 'IDNotFoundError';
+ id: Scalars['Int']['output'];
+ message: Scalars['String']['output'];
+};
+
+export type Image = {
+ __typename?: 'Image';
+ aspectRatio: Scalars['Float']['output'];
+ hash: Scalars['String']['output'];
+ height: Scalars['Int']['output'];
+ id: Scalars['Int']['output'];
+ width: Scalars['Int']['output'];
+};
+
+export type InvalidParameterError = Error & {
+ __typename?: 'InvalidParameterError';
+ message: Scalars['String']['output'];
+ parameter: Scalars['String']['output'];
+};
+
+export enum Language {
+ Aa = 'AA',
+ Ab = 'AB',
+ Ae = 'AE',
+ Af = 'AF',
+ Ak = 'AK',
+ Am = 'AM',
+ An = 'AN',
+ Ar = 'AR',
+ As = 'AS',
+ Av = 'AV',
+ Ay = 'AY',
+ Az = 'AZ',
+ Ba = 'BA',
+ Be = 'BE',
+ Bg = 'BG',
+ Bh = 'BH',
+ Bi = 'BI',
+ Bm = 'BM',
+ Bn = 'BN',
+ Bo = 'BO',
+ Br = 'BR',
+ Bs = 'BS',
+ Ca = 'CA',
+ Ce = 'CE',
+ Ch = 'CH',
+ Co = 'CO',
+ Cr = 'CR',
+ Cs = 'CS',
+ Cu = 'CU',
+ Cv = 'CV',
+ Cy = 'CY',
+ Da = 'DA',
+ De = 'DE',
+ Dv = 'DV',
+ Dz = 'DZ',
+ Ee = 'EE',
+ El = 'EL',
+ En = 'EN',
+ Eo = 'EO',
+ Es = 'ES',
+ Et = 'ET',
+ Eu = 'EU',
+ Fa = 'FA',
+ Ff = 'FF',
+ Fi = 'FI',
+ Fj = 'FJ',
+ Fo = 'FO',
+ Fr = 'FR',
+ Fy = 'FY',
+ Ga = 'GA',
+ Gd = 'GD',
+ Gl = 'GL',
+ Gn = 'GN',
+ Gu = 'GU',
+ Gv = 'GV',
+ Ha = 'HA',
+ He = 'HE',
+ Hi = 'HI',
+ Ho = 'HO',
+ Hr = 'HR',
+ Ht = 'HT',
+ Hu = 'HU',
+ Hy = 'HY',
+ Hz = 'HZ',
+ Ia = 'IA',
+ Id = 'ID',
+ Ie = 'IE',
+ Ig = 'IG',
+ Ii = 'II',
+ Ik = 'IK',
+ Io = 'IO',
+ Is = 'IS',
+ It = 'IT',
+ Iu = 'IU',
+ Ja = 'JA',
+ Jv = 'JV',
+ Ka = 'KA',
+ Kg = 'KG',
+ Ki = 'KI',
+ Kj = 'KJ',
+ Kk = 'KK',
+ Kl = 'KL',
+ Km = 'KM',
+ Kn = 'KN',
+ Ko = 'KO',
+ Kr = 'KR',
+ Ks = 'KS',
+ Ku = 'KU',
+ Kv = 'KV',
+ Kw = 'KW',
+ Ky = 'KY',
+ La = 'LA',
+ Lb = 'LB',
+ Lg = 'LG',
+ Li = 'LI',
+ Ln = 'LN',
+ Lo = 'LO',
+ Lt = 'LT',
+ Lu = 'LU',
+ Lv = 'LV',
+ Mg = 'MG',
+ Mh = 'MH',
+ Mi = 'MI',
+ Mk = 'MK',
+ Ml = 'ML',
+ Mn = 'MN',
+ Mr = 'MR',
+ Ms = 'MS',
+ Mt = 'MT',
+ My = 'MY',
+ Na = 'NA',
+ Nb = 'NB',
+ Nd = 'ND',
+ Ne = 'NE',
+ Ng = 'NG',
+ Nl = 'NL',
+ Nn = 'NN',
+ No = 'NO',
+ Nr = 'NR',
+ Nv = 'NV',
+ Ny = 'NY',
+ Oc = 'OC',
+ Oj = 'OJ',
+ Om = 'OM',
+ Or = 'OR',
+ Os = 'OS',
+ Pa = 'PA',
+ Pi = 'PI',
+ Pl = 'PL',
+ Ps = 'PS',
+ Pt = 'PT',
+ Qu = 'QU',
+ Rm = 'RM',
+ Rn = 'RN',
+ Ro = 'RO',
+ Ru = 'RU',
+ Rw = 'RW',
+ Sa = 'SA',
+ Sc = 'SC',
+ Sd = 'SD',
+ Se = 'SE',
+ Sg = 'SG',
+ Si = 'SI',
+ Sk = 'SK',
+ Sl = 'SL',
+ Sm = 'SM',
+ Sn = 'SN',
+ So = 'SO',
+ Sq = 'SQ',
+ Sr = 'SR',
+ Ss = 'SS',
+ St = 'ST',
+ Su = 'SU',
+ Sv = 'SV',
+ Sw = 'SW',
+ Ta = 'TA',
+ Te = 'TE',
+ Tg = 'TG',
+ Th = 'TH',
+ Ti = 'TI',
+ Tk = 'TK',
+ Tl = 'TL',
+ Tn = 'TN',
+ To = 'TO',
+ Tr = 'TR',
+ Ts = 'TS',
+ Tt = 'TT',
+ Tw = 'TW',
+ Ty = 'TY',
+ Ug = 'UG',
+ Uk = 'UK',
+ Ur = 'UR',
+ Uz = 'UZ',
+ Ve = 'VE',
+ Vi = 'VI',
+ Vo = 'VO',
+ Wa = 'WA',
+ Wo = 'WO',
+ Xh = 'XH',
+ Yi = 'YI',
+ Yo = 'YO',
+ Za = 'ZA',
+ Zh = 'ZH',
+ Zu = 'ZU'
+}
+
+export type LanguageFilter = {
+ any?: InputMaybe>;
+ empty?: InputMaybe;
+};
+
+export enum Layout {
+ Double = 'DOUBLE',
+ DoubleOffset = 'DOUBLE_OFFSET',
+ Single = 'SINGLE'
+}
+
+export type Mutation = {
+ __typename?: 'Mutation';
+ addArtist: AddResponse;
+ addCharacter: AddResponse;
+ addCircle: AddResponse;
+ addComic: AddComicResponse;
+ addNamespace: AddResponse;
+ addTag: AddResponse;
+ addWorld: AddResponse;
+ deleteArchives: DeleteResponse;
+ deleteArtists: DeleteResponse;
+ deleteCharacters: DeleteResponse;
+ deleteCircles: DeleteResponse;
+ deleteComics: DeleteResponse;
+ deleteNamespaces: DeleteResponse;
+ deleteTags: DeleteResponse;
+ deleteWorlds: DeleteResponse;
+ updateArchives: UpdateResponse;
+ updateArtists: UpdateResponse;
+ updateCharacters: UpdateResponse;
+ updateCircles: UpdateResponse;
+ updateComics: UpdateResponse;
+ updateNamespaces: UpdateResponse;
+ updateTags: UpdateResponse;
+ updateWorlds: UpdateResponse;
+ upsertComics: UpsertResponse;
+};
+
+
+export type MutationAddArtistArgs = {
+ input: AddArtistInput;
+};
+
+
+export type MutationAddCharacterArgs = {
+ input: AddCharacterInput;
+};
+
+
+export type MutationAddCircleArgs = {
+ input: AddCircleInput;
+};
+
+
+export type MutationAddComicArgs = {
+ input: AddComicInput;
+};
+
+
+export type MutationAddNamespaceArgs = {
+ input: AddNamespaceInput;
+};
+
+
+export type MutationAddTagArgs = {
+ input: AddTagInput;
+};
+
+
+export type MutationAddWorldArgs = {
+ input: AddWorldInput;
+};
+
+
+export type MutationDeleteArchivesArgs = {
+ ids: Array;
+};
+
+
+export type MutationDeleteArtistsArgs = {
+ ids: Array;
+};
+
+
+export type MutationDeleteCharactersArgs = {
+ ids: Array;
+};
+
+
+export type MutationDeleteCirclesArgs = {
+ ids: Array;
+};
+
+
+export type MutationDeleteComicsArgs = {
+ ids: Array;
+};
+
+
+export type MutationDeleteNamespacesArgs = {
+ ids: Array;
+};
+
+
+export type MutationDeleteTagsArgs = {
+ ids: Array;
+};
+
+
+export type MutationDeleteWorldsArgs = {
+ ids: Array;
+};
+
+
+export type MutationUpdateArchivesArgs = {
+ ids: Array;
+ input: UpdateArchiveInput;
+};
+
+
+export type MutationUpdateArtistsArgs = {
+ ids: Array;
+ input: UpdateArtistInput;
+};
+
+
+export type MutationUpdateCharactersArgs = {
+ ids: Array;
+ input: UpdateCharacterInput;
+};
+
+
+export type MutationUpdateCirclesArgs = {
+ ids: Array;
+ input: UpdateCircleInput;
+};
+
+
+export type MutationUpdateComicsArgs = {
+ ids: Array;
+ input: UpdateComicInput;
+};
+
+
+export type MutationUpdateNamespacesArgs = {
+ ids: Array;
+ input: UpdateNamespaceInput;
+};
+
+
+export type MutationUpdateTagsArgs = {
+ ids: Array;
+ input: UpdateTagInput;
+};
+
+
+export type MutationUpdateWorldsArgs = {
+ ids: Array;
+ input: UpdateWorldInput;
+};
+
+
+export type MutationUpsertComicsArgs = {
+ ids: Array;
+ input: UpsertComicInput;
+};
+
+export type NameExistsError = Error & {
+ __typename?: 'NameExistsError';
+ message: Scalars['String']['output'];
+};
+
+export type Namespace = {
+ __typename?: 'Namespace';
+ id: Scalars['Int']['output'];
+ name: Scalars['String']['output'];
+ sortName?: Maybe;
+};
+
+export type NamespaceFilter = {
+ name?: InputMaybe;
+};
+
+export type NamespaceFilterInput = {
+ exclude?: InputMaybe;
+ include?: InputMaybe;
+};
+
+export type NamespaceFilterResult = {
+ __typename?: 'NamespaceFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type NamespaceResponse = IdNotFoundError | Namespace;
+
+export enum NamespaceSort {
+ CreatedAt = 'CREATED_AT',
+ Name = 'NAME',
+ Random = 'RANDOM',
+ SortName = 'SORT_NAME',
+ UpdatedAt = 'UPDATED_AT'
+}
+
+export type NamespaceSortInput = {
+ direction?: InputMaybe;
+ on: NamespaceSort;
+ seed?: InputMaybe;
+};
+
+export type NamespacesInput = {
+ ids: Array;
+};
+
+export type NamespacesUpdateInput = {
+ ids: Array;
+ options?: InputMaybe;
+};
+
+export enum OnMissing {
+ Create = 'CREATE',
+ Ignore = 'IGNORE'
+}
+
+export type Page = {
+ __typename?: 'Page';
+ comicId?: Maybe;
+ id: Scalars['Int']['output'];
+ image: Image;
+ path: Scalars['String']['output'];
+};
+
+export type PageClaimedError = Error & {
+ __typename?: 'PageClaimedError';
+ comicId: Scalars['Int']['output'];
+ id: Scalars['Int']['output'];
+ message: Scalars['String']['output'];
+};
+
+export type PageRemoteError = Error & {
+ __typename?: 'PageRemoteError';
+ archiveId: Scalars['Int']['output'];
+ id: Scalars['Int']['output'];
+ message: Scalars['String']['output'];
+};
+
+export type Pagination = {
+ items?: Scalars['Int']['input'];
+ page?: Scalars['Int']['input'];
+};
+
+export type Query = {
+ __typename?: 'Query';
+ archive: ArchiveResponse;
+ archives: ArchiveFilterResult;
+ artist: ArtistResponse;
+ artists: ArtistFilterResult;
+ character: CharacterResponse;
+ characters: CharacterFilterResult;
+ circle: CircleResponse;
+ circles: CircleFilterResult;
+ comic: ComicResponse;
+ comicScrapers: Array;
+ comicTags: ComicTagFilterResult;
+ comics: ComicFilterResult;
+ namespace: NamespaceResponse;
+ namespaces: NamespaceFilterResult;
+ scrapeComic: ScrapeComicResponse;
+ tag: TagResponse;
+ tags: TagFilterResult;
+ world: WorldResponse;
+ worlds: WorldFilterResult;
+};
+
+
+export type QueryArchiveArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryArchivesArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+
+export type QueryArtistArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryArtistsArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+
+export type QueryCharacterArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryCharactersArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+
+export type QueryCircleArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryCirclesArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+
+export type QueryComicArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryComicScrapersArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryComicTagsArgs = {
+ forFilter?: Scalars['Boolean']['input'];
+};
+
+
+export type QueryComicsArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+
+export type QueryNamespaceArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryNamespacesArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+
+export type QueryScrapeComicArgs = {
+ id: Scalars['Int']['input'];
+ scraper: Scalars['String']['input'];
+};
+
+
+export type QueryTagArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryTagsArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+
+export type QueryWorldArgs = {
+ id: Scalars['Int']['input'];
+};
+
+
+export type QueryWorldsArgs = {
+ filter?: InputMaybe;
+ pagination?: InputMaybe;
+ sort?: InputMaybe;
+};
+
+export enum Rating {
+ Explicit = 'EXPLICIT',
+ Questionable = 'QUESTIONABLE',
+ Safe = 'SAFE'
+}
+
+export type RatingFilter = {
+ any?: InputMaybe>;
+ empty?: InputMaybe;
+};
+
+export type ScrapeComicResponse = IdNotFoundError | ScrapeComicResult | ScraperError | ScraperNotAvailableError | ScraperNotFoundError;
+
+export type ScrapeComicResult = {
+ __typename?: 'ScrapeComicResult';
+ data: ScrapedComic;
+ warnings: Array;
+};
+
+export type ScrapedComic = {
+ __typename?: 'ScrapedComic';
+ artists: Array;
+ category?: Maybe;
+ censorship?: Maybe;
+ characters: Array;
+ circles: Array;
+ date?: Maybe;
+ direction?: Maybe;
+ language?: Maybe;
+ layout?: Maybe;
+ originalTitle?: Maybe;
+ rating?: Maybe;
+ tags: Array;
+ title?: Maybe;
+ url?: Maybe;
+ worlds: Array;
+};
+
+export type ScraperError = Error & {
+ __typename?: 'ScraperError';
+ error: Scalars['String']['output'];
+ message: Scalars['String']['output'];
+};
+
+export type ScraperNotAvailableError = Error & {
+ __typename?: 'ScraperNotAvailableError';
+ comicId: Scalars['Int']['output'];
+ message: Scalars['String']['output'];
+ scraper: Scalars['String']['output'];
+};
+
+export type ScraperNotFoundError = Error & {
+ __typename?: 'ScraperNotFoundError';
+ message: Scalars['String']['output'];
+ name: Scalars['String']['output'];
+};
+
+export enum SortDirection {
+ Ascending = 'ASCENDING',
+ Descending = 'DESCENDING'
+}
+
+export type StringFilter = {
+ contains?: InputMaybe;
+};
+
+export type Success = {
+ message: Scalars['String']['output'];
+};
+
+export type Tag = {
+ __typename?: 'Tag';
+ description?: Maybe;
+ id: Scalars['Int']['output'];
+ name: Scalars['String']['output'];
+};
+
+export type TagAssociationFilter = {
+ all?: InputMaybe>;
+ any?: InputMaybe>;
+ empty?: InputMaybe;
+ exact?: InputMaybe>;
+};
+
+export type TagFilter = {
+ name?: InputMaybe;
+ namespaces?: InputMaybe;
+};
+
+export type TagFilterInput = {
+ exclude?: InputMaybe;
+ include?: InputMaybe;
+};
+
+export type TagFilterResult = {
+ __typename?: 'TagFilterResult';
+ count: Scalars['Int']['output'];
+ edges: Array;
+};
+
+export type TagResponse = FullTag | IdNotFoundError;
+
+export enum TagSort {
+ CreatedAt = 'CREATED_AT',
+ Name = 'NAME',
+ Random = 'RANDOM',
+ UpdatedAt = 'UPDATED_AT'
+}
+
+export type TagSortInput = {
+ direction?: InputMaybe;
+ on: TagSort;
+ seed?: InputMaybe;
+};
+
+export type UniquePagesInput = {
+ ids: Array;
+};
+
+export type UniquePagesUpdateInput = {
+ ids: Array;
+ options?: InputMaybe;
+};
+
+export type UpdateArchiveInput = {
+ cover?: InputMaybe;
+ organized?: InputMaybe;
+};
+
+export type UpdateArtistInput = {
+ name?: InputMaybe;
+};
+
+export type UpdateCharacterInput = {
+ name?: InputMaybe;
+};
+
+export type UpdateCircleInput = {
+ name?: InputMaybe;
+};
+
+export type UpdateComicInput = {
+ artists?: InputMaybe;
+ bookmarked?: InputMaybe;
+ category?: InputMaybe;
+ censorship?: InputMaybe;
+ characters?: InputMaybe;
+ circles?: InputMaybe;
+ cover?: InputMaybe;
+ date?: InputMaybe;
+ direction?: InputMaybe;
+ favourite?: InputMaybe;
+ language?: InputMaybe;
+ layout?: InputMaybe;
+ organized?: InputMaybe;
+ originalTitle?: InputMaybe;
+ pages?: InputMaybe;
+ rating?: InputMaybe;
+ tags?: InputMaybe;
+ title?: InputMaybe;
+ url?: InputMaybe;
+ worlds?: InputMaybe;
+};
+
+export enum UpdateMode {
+ Add = 'ADD',
+ Remove = 'REMOVE',
+ Replace = 'REPLACE'
+}
+
+export type UpdateNamespaceInput = {
+ name?: InputMaybe