Compare commits

...

131 Commits
0.6.6 ... main

Author SHA1 Message Date
2e19d5fdeb Update .env 2024-06-08 20:44:20 -04:00
63f31e0f4c Update server.ts 2024-06-08 20:08:25 -04:00
f75d889ee8 Delete page.tsx 2024-06-08 19:51:44 -04:00
8877362484 Update server.ts 2024-06-08 19:50:08 -04:00
082c161959 Update page.tsx 2024-06-08 19:45:31 -04:00
5d96002a2e fix 2024-06-08 19:43:26 -04:00
65ddd704f0 fix 2024-06-08 19:34:52 -04:00
b12d095e3e Update page.tsx 2024-06-08 19:15:21 -04:00
581ceb028a fix 2024-06-08 19:14:31 -04:00
7ac84fc0cf Update page.tsx 2024-06-08 19:13:54 -04:00
164aec1c51 fix: hooked up tiers to galleries page 2024-06-08 19:11:32 -04:00
420e029d66 fix: gallery admin pages 2024-06-08 19:01:55 -04:00
d94f3b825b fix: gallery admin page 2024-06-08 18:53:10 -04:00
7635178e3c fix: gallery pages 2024-06-08 18:45:28 -04:00
a9968ccb03 fix: added ui for managing theme and tiers 2024-06-08 00:26:23 -04:00
4d86b8aeed Update page.tsx 2024-06-04 23:07:20 -04:00
19bee6998a fix: added tier pages 2024-06-04 22:59:02 -04:00
fcf83c6435 Merge branch 'main' of https://github.com/D4M13N-D3V/neroshitron 2024-06-04 00:27:25 -04:00
32ba288463 Update diagrams.drawio 2024-06-04 00:27:23 -04:00
334db37d18
Update README.md 2024-06-04 00:25:36 -04:00
1112191b61
Update README.md 2024-06-04 00:24:08 -04:00
52b7771994
Update README.md 2024-06-04 00:23:21 -04:00
9e76f9315b
Update README.md 2024-06-03 23:50:58 -04:00
c9bf8e8431 Update navigation_bar.tsx 2024-06-03 22:25:21 -04:00
691292becc fix:reactive pages 2024-06-03 22:21:19 -04:00
e8fa3d2ce0 Update page.tsx 2024-06-03 21:45:50 -04:00
fd76220269 fix: adding duplicates 2024-06-03 21:37:05 -04:00
e9e4f25520 Update search_input.tsx 2024-06-03 21:24:42 -04:00
234cc989f1 fixed: nsfw button 2024-06-03 21:23:08 -04:00
e6a81a3bdf fix: tag format 2024-06-03 21:02:48 -04:00
96aeca6242 Update page.tsx 2024-06-03 02:39:11 -04:00
a6d050c35f Update page.tsx 2024-06-03 02:38:20 -04:00
f790a03c27 fix 2024-06-03 02:29:09 -04:00
6f5bf90a0b fix 2024-06-03 02:25:25 -04:00
e5daff376a Update search.tsx 2024-06-03 02:15:13 -04:00
a0a38389a6 Update page.tsx 2024-06-03 02:14:45 -04:00
85c066baec Update page.tsx 2024-06-03 02:13:38 -04:00
9c6bdddd22 Update page.tsx 2024-06-03 02:12:25 -04:00
87ba2e032d fix 2024-06-03 02:10:39 -04:00
28414630a4 feat: gallery management pages 2024-06-03 02:00:05 -04:00
534cbf2957 fix 2024-06-02 23:37:41 -04:00
481b4f698c fix: 2024-06-02 23:14:30 -04:00
172a3015af Merge branch 'main' of https://github.com/D4M13N-D3V/neroshitron 2024-06-02 22:58:53 -04:00
6564be1a60 Update search_input.tsx 2024-06-02 22:58:49 -04:00
fdcaccfbd6
23 replace recenter with back (#37)
* fix:23

* fix

* fix: girl bg

* Update search_input.tsx

* Update search_input.tsx
2024-06-02 22:57:20 -04:00
6541bd94fe
23 replace recenter with back (#36)
* fix:23

* fix

* fix: girl bg

* Update search_input.tsx
2024-06-02 22:52:44 -04:00
82fdd61170
fix:23 (#35) 2024-06-02 20:25:29 -04:00
caca715cc0
fix:22 (#34) 2024-06-02 20:21:12 -04:00
74335ff6cf Update seed.sql 2024-06-02 19:51:45 -04:00
3206a19f7a Delete route.ts 2024-06-02 19:31:51 -04:00
e48d3ebafb fix;admin 2024-06-02 19:26:12 -04:00
168c835a23 fix: animations 2024-06-02 17:58:27 -04:00
0127d00021 fix: locked down navbar options for admin pages and added rls policies 2024-06-02 17:50:08 -04:00
02872252b5 feat: tags admin ui 2024-06-02 17:35:10 -04:00
b6736651c5 fix 2024-06-02 07:54:45 -04:00
78a25ab398 Update right_hand_layout_image.tsx 2024-06-02 07:51:11 -04:00
58d384a3fc fix: shadows 2024-06-02 07:49:41 -04:00
76a09c8e8c fix: nav 2024-06-02 07:43:33 -04:00
73836c5893 fix: styling for tags search 2024-06-02 07:17:14 -04:00
4c972778cd fix: moved anime girl to layout 2024-06-02 06:12:04 -04:00
795fc0f5f7 fix
const [scrollPosition, setScrollPosition] = useState(0);
  const [color, setColor] = useState('black');

  useEffect(() => {
  }, []);
2024-06-02 05:57:18 -04:00
e4dde90da4 fix 2024-06-02 04:56:09 -04:00
fa6bf10249 Update page.tsx 2024-06-02 04:52:32 -04:00
cd5d0bf304 Update page.tsx 2024-06-02 04:50:23 -04:00
4a3c7023ba Update page.tsx 2024-06-02 04:46:42 -04:00
ea3a14a6e4 fix; delete button 2024-06-02 04:46:21 -04:00
451bdd1106 Update page.tsx 2024-06-02 04:42:34 -04:00
2b21c2feff Update page.tsx 2024-06-02 04:37:59 -04:00
02e85c54fc Update page.tsx 2024-06-02 04:35:15 -04:00
ac4007a82e Update page.tsx 2024-06-02 04:31:38 -04:00
e584a43145 Update navigation_bar.tsx 2024-06-02 04:28:52 -04:00
b232be9377 fix: tags 2024-06-02 04:25:36 -04:00
46a20bbd7e Update page.tsx 2024-06-02 03:52:45 -04:00
894fb58c29 fix: create page 2024-06-02 03:51:53 -04:00
2c59660566 feat: create page 2024-06-02 03:48:21 -04:00
666e377cdb Update search_input.tsx 2024-06-02 03:17:05 -04:00
da6fc56b86 fix 2024-06-02 03:15:59 -04:00
5daa585a9e Merge branch 'main' of https://github.com/D4M13N-D3V/neroshitron 2024-06-02 03:09:02 -04:00
d33f36adaf fix 2024-06-02 03:08:55 -04:00
e03816928a
fix:images in gallery (#18) 2024-06-02 02:49:55 -04:00
de08c2ddd0 Update navigation_bar.tsx 2024-06-02 02:20:37 -04:00
9de286f920 fix: added a thing telling user where tags are 2024-06-02 02:13:36 -04:00
45d3b459d8 Update search_input.tsx 2024-06-02 02:11:56 -04:00
712e1ce5cd Update search_input.tsx 2024-06-02 02:07:20 -04:00
912fa157e2 Update search_input.tsx 2024-06-02 02:04:58 -04:00
394163198c Update gallery.tsx 2024-06-02 01:53:31 -04:00
f74d7a8fa9 Update search_input.tsx 2024-06-02 01:49:24 -04:00
cfe47be428 fix: neroshi tag isnt pushed 2024-06-02 01:37:52 -04:00
bd334bcbea fix: first tag 2024-06-02 01:37:03 -04:00
54ec36cebc fix: nsfw button 2024-06-02 01:32:37 -04:00
f175b31976 fix: css themiing 2024-06-02 01:24:14 -04:00
9b5c3d44c5 chore: formatting 2024-06-02 00:36:02 -04:00
97f2a31951 Update gallery_thumbnail.tsx 2024-06-02 00:31:19 -04:00
4c564df94a Update search_input.tsx 2024-06-02 00:25:42 -04:00
2edf752b05 Update search_input.tsx 2024-06-02 00:20:03 -04:00
d7f3330dc2 Merge branch 'main' of https://github.com/D4M13N-D3V/neroshitron 2024-06-02 00:19:43 -04:00
afe4076874 Update search_input.tsx 2024-06-02 00:19:36 -04:00
f86c618b1d
fix: remove scrollbar (#8)
* Update .gitignore

* fix: added a badge for number of tags selected

* Update tag_selector.tsx

* tag search

* fix: search styling
2024-06-02 00:15:21 -04:00
7fec3450d9
fix:add badge showing how many tags selected (#7)
* Update .gitignore

* fix: added a badge for number of tags selected
2024-06-01 16:36:06 -04:00
41c90c2a58
fix: clicking tag breaks tag ui (#6) 2024-06-01 16:30:05 -04:00
bef53cadce
fix: gallery not opening (#5) 2024-06-01 16:29:58 -04:00
f30d2c5a2a
feat: new shit (#4)
* fix: navigation bar code is minimized, started seperating out components and refactoring them

* feat: search components

* Update search.tsx

* fix: autofocus

* fix: tags and search

* Update page_old.tsx

* Update galleries.tsx

* Update tag_selector.tsx

* Update tag_selector.tsx
2024-06-01 06:39:05 -04:00
f2bd76487e
feat: tags
* fix: navigation bar code is minimized, started seperating out components and refactoring them

* feat: search components

* Update search.tsx

* fix: autofocus

* fix: tags and search
2024-06-01 06:21:59 -04:00
92c2317af1 Update NavigationBar.tsx 2024-05-28 00:36:27 -04:00
0b390b7658 Update NavigationBar.tsx 2024-05-28 00:34:14 -04:00
8a994123af Update _middleware.tsx 2024-05-28 00:28:28 -04:00
dcfe7c5676 fix:header 2024-05-28 00:28:03 -04:00
21fa376190 fix: navbar highlight 2024-05-28 00:20:42 -04:00
23137d4e04 Update NavigationBar.tsx 2024-05-28 00:11:45 -04:00
b99f3fa256 Update NavigationBar.tsx 2024-05-28 00:10:45 -04:00
2c036794ff Update NavigationBar.tsx 2024-05-28 00:09:23 -04:00
ee1272b520 Update NavigationBar.tsx 2024-05-28 00:08:42 -04:00
2cccc65a9a Update NavigationBar.tsx 2024-05-28 00:08:32 -04:00
e17aba510c Update NavigationBar.tsx 2024-05-28 00:07:38 -04:00
381009d5c9 chore :analytics 2024-05-28 00:04:45 -04:00
401e3d41dc Update NavigationBar.tsx 2024-05-28 00:02:55 -04:00
82728cbc97 Update NavigationBar.tsx 2024-05-27 23:58:58 -04:00
de0a5a8e73 Update NavigationBar.tsx 2024-05-27 23:55:21 -04:00
057c20cd21 Update NavigationBar.tsx 2024-05-27 23:54:39 -04:00
b2f700280a chore: installed speed insights 2024-05-27 23:47:49 -04:00
e8161fc226 Update NavigationBar.tsx 2024-05-27 23:46:24 -04:00
10f8e5d289 Update NavigationBar.tsx 2024-05-27 23:28:16 -04:00
54a771b47f Update page.tsx 2024-05-27 23:26:41 -04:00
e82305954e Update page.tsx 2024-05-27 23:24:59 -04:00
fe09172881 Update page.tsx 2024-05-27 23:24:18 -04:00
caac354273 Update page.tsx 2024-05-27 23:19:30 -04:00
ea21548c68 Update layout.tsx 2024-05-27 23:16:08 -04:00
eb8df7bed7 Update NavigationBar.tsx 2024-05-27 21:45:17 -04:00
4b0060e5dd cleanup 2024-05-27 21:38:21 -04:00
08ce73e64e chrore ; update 2024-05-27 20:53:24 -04:00
af0dd625b4 feat: nsfw toggle 2024-05-27 20:40:23 -04:00
55 changed files with 4474 additions and 830 deletions

2
.env.production Normal file
View File

@ -0,0 +1,2 @@
NEXT_PUBLIC_SUPABASE_URL=https://cgnmpfjcbhtgdcizgfnc.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNnbm1wZmpjYmh0Z2RjaXpnZm5jIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTY4NTkyNDIsImV4cCI6MjAzMjQzNTI0Mn0.oGf2jp-Twr1qP7GQI4D87iu5EWV6UhL51OEaCLvSMxk

4
.gitignore vendored
View File

@ -23,3 +23,7 @@ yarn-error.log*
/supabase/volumes/db/data
/supabase/volumes/storage
supabase.zip
.idea/copilot/chatSessions/00000000000.xd
.idea/copilot/chatSessions/blobs/version
.idea/copilot/chatSessions/xd.lck
.idea/workspace.xml

5
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# GitHub Copilot persisted chat sessions
/copilot/chatSessions

1
.idea/.name generated Normal file
View File

@ -0,0 +1 @@
page.tsx

17
.idea/aws.xml generated Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="accountSettings">
<option name="activeProfile" value="profile:default" />
<option name="activeRegion" value="us-east-1" />
<option name="recentlyUsedProfiles">
<list>
<option value="profile:default" />
</list>
</option>
<option name="recentlyUsedRegions">
<list>
<option value="us-east-1" />
</list>
</option>
</component>
</project>

4
.idea/encodings.xml generated Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

6
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="openjdk-22" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/neroshitron.iml" filepath="$PROJECT_DIR$/.idea/neroshitron.iml" />
</modules>
</component>
</project>

11
.idea/neroshitron.iml generated Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.idea/copilot/chatSessions" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -49,51 +49,6 @@ Configuration is done through the Owncast administration page located on your se
![image](https://github.com/D4M13N-D3V/neroshitron/assets/13697702/57379445-8bd5-4a7e-8a15-7fa0b3ae42dc)
# Database Diagram
![image](https://github.com/D4M13N-D3V/neroshitron/assets/13697702/3a22f05b-0de3-4f6c-9f95-06e035d03cb5)
# React Components
## Gallery Component
The `Gallery` component is a React component used to display a gallery of images. It fetches images from an API and displays them in a Masonry layout.
### Props
- `id` (number): The ID of the gallery to fetch images from.
- `closeMenu` (function): A function to close the menu.
### State
- `isSingle` (boolean): A state to check if only a single image is to be displayed.
- `loaded` (object): A state to keep track of loaded images.
- `selectedImage` (string | null): A state to keep track of the selected image.
- `images` (string[]): A state to store the fetched images.
- `galleryId` (number): A state to store the gallery ID.
### Functions
- `getData`: An async function to fetch images from the API.
- `generateRandomString`: A function to generate a random string of a given length.
- `handleDownload`: A function to handle the download of an image.
### Usage
The example below will load the images of the the gallery with an ID of `58201557-b392-471e-ac55-dcf6171cd18d` and will call the function for `setIsOpen(false)` when the back button is clicked.
```tsx
<Gallery id={"58201557-b392-471e-ac55-dcf6171cd18d"} closeMenu={() => setIsOpen(false)}></Gallery>
```
![image](https://github.com/D4M13N-D3V/neroshitron/assets/13697702/b3387b77-d8c6-41c4-9fe8-d52dadb6bc5e)
## GalleryThumbnail Component
The `GalleryThumbnail` component is a React component used to display a thumbnail of a gallery. It fetches the thumbnail image from an API and displays it. When clicked, it triggers a callback function with the gallery ID.
### Props
- `id` (string): The ID of the gallery to fetch the thumbnail for.
- `onSelect` (function): A function to be called when the thumbnail is clicked. The gallery ID is passed as an argument.
- `title` (string) : The name of the gallery.
- `subscription` (subscription) : The name of the subscription required for the gallery.
### State
- `galleryId` (string): A state to store the gallery ID.
- `thumbnailUrl` (string): A state to store the fetched thumbnail URL.
- `isLoading` (boolean): A state to keep track of the loading status.
### Functions
- `openGallery`: A function to call the `onSelect` prop with the gallery ID.
- `getData`: An async function to fetch the thumbnail from the API.
### Usage
This will render a thumbnail for the gallery with the ID of "1". When the thumbnail is clicked, it will log the gallery ID to the console.
```tsx
<GalleryThumbnail id="1" onSelect={(id) => //console.log(id)} />
```

4
app/_middleware.tsx Normal file
View File

@ -0,0 +1,4 @@
import { middleware } from './middleware/path-header'
export default middleware

41
app/admin/page.tsx Normal file
View File

@ -0,0 +1,41 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
function PageComponent() {
const supabase = createClient();
const getData = async () => {
}
useEffect(() => {
getData();
}, []);
const router = useRouter();
return (
<div className="w-full text-white flex justify-center items-center animate-in">
<div className="w-2/3 lg:w-1/3 rounded-md bg-primary p-8 mt-32 shadow-lg opacity-90 backdrop-blur-lg">
<div className="w-full flex justify-center">
<span className="text-2xl pb-4">System Settings</span>
</div>
<div className="flex justify-center ">
<button onClick={()=>{ router.push("/admin/tiers") }} className="bg-secondary hover:bg-secondary-dark rounded p-2 mr-1 w-full">Tiers Management</button>
<button onClick={()=>{ router.push("/gallery/admin") }} className="ml-1 bg-secondary hover:bg-secondary-dark rounded p-2 w-full">Gallery Management</button>
</div>
<div className="flex justify-center pt-2">
<button onClick={()=>{ router.push("/admin/theme") }} className="mr-1 bg-secondary hover:bg-secondary-dark rounded p-2 mr-1 w-full">Theme Settings</button>
<button className="bg-secondary hover:bg-secondary-dark rounded p-2 ml-1 w-full">User Management</button>
</div>
<div className="flex justify-center pt-2">
<button className="bg-secondary hover:bg-secondary-dark rounded p-2 w-full mr-1">Payment/Payout Settings</button>
<button className="bg-secondary hover:bg-secondary-dark rounded p-2 w-full ml-1">Comissions Settings</button>
</div>
</div>
</div>
);
}
export default PageComponent;

474
app/admin/theme/page.tsx Normal file
View File

@ -0,0 +1,474 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
function PageComponent() {
const router = useRouter();
const supabase = createClient();
const [primary, setPrimary] = useState('#201240');
const [primaryLight, setPrimaryLight] = useState('#403260');
const [primaryDark, setPrimaryDark] = useState('#100120');
const [secondary, setSecondary] = useState('#4F3D70');
const [secondaryLight, setSecondaryLight] = useState('#6F5D90');
const [secondaryDark, setSecondaryDark] = useState('#2F1D50');
const [error, setError] = useState('#862117');
const [errorLight, setErrorLight] = useState('#C44C4C');
const [errorDark, setErrorDark] = useState('#5C0D0D');
const [changed, setChanged] = useState(false);
const [success, setSuccess] = useState('#00C9A6');
const [successLight, setSuccessLight] = useState('#20E9C6');
const [successDark, setSuccessDark] = useState('#00A986');
const [warning, setWarning] = useState('#E17558');
const [warningLight, setWarningLight] = useState('#E39578');
const [warningDark, setWarningDark] = useState('#C15538');
const [info, setInfo] = useState('#222140');
const [infoLight, setInfoLight] = useState('#424260');
const [infoDark, setInfoDark] = useState('#020120');
const [saving, setSaving] = useState(false);
const getData = async () => {
var primaryConfig = await getColorConfig('primary');
setPrimary(primaryConfig.value);
var primaryLightConfig = await getColorConfig('primary-light');
setPrimaryLight(primaryLightConfig.value);
var primaryDarkConfig = await getColorConfig('primary-dark');
setPrimaryDark(primaryDarkConfig.value);
var secondaryConfig = await getColorConfig('secondary');
setSecondary(secondaryConfig.value);
var secondaryLightConfig = await getColorConfig('secondary-light');
setSecondaryLight(secondaryLightConfig.value);
var secondaryDarkConfig = await getColorConfig('secondary-dark');
setSecondaryDark(secondaryDarkConfig.value);
var errorConfig = await getColorConfig('error');
setError(errorConfig.value);
var errorLightConfig = await getColorConfig('error-light');
setErrorLight(errorLightConfig.value);
var errorDarkConfig = await getColorConfig('error-dark');
setErrorDark(errorDarkConfig.value);
var successConfig = await getColorConfig('success');
setSuccess(successConfig.value);
var successLightConfig = await getColorConfig('success-light');
setSuccessLight(successLightConfig.value);
var successDarkConfig = await getColorConfig('success-dark');
setSuccessDark(successDarkConfig.value);
var warningConfig = await getColorConfig('warning');
setWarning(warningConfig.value);
var warningLightConfig = await getColorConfig('warning-light');
setWarningLight(warningLightConfig.value);
var warningDarkConfig = await getColorConfig('warning-dark');
setWarningDark(warningDarkConfig.value);
var infoConfig = await getColorConfig('info');
setInfo(infoConfig.value);
var infoLightConfig = await getColorConfig('info-light');
setInfoLight(infoLightConfig.value);
var infoDarkConfig = await getColorConfig('info-dark');
setInfoDark(infoDarkConfig.value);
}
const getColorConfig = async (name: string) => {
try {
const response = await fetch(`/api/admin/interface-configs?name=${name}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error('Failed to call GET request');
}
const data = await response.json();
return data;
} catch (error) {
console.error(error);
throw new Error('Failed to call GET request');
}
}
const setColorConfig = async (name: string, value:string) => {
try {
const response = await fetch(`/api/admin/interface-configs`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, value }),
});
if (!response.ok) {
throw new Error('Failed to call GET request');
}
const data = await response.json();
return data;
} catch (error) {
console.error(error);
throw new Error('Failed to call GET request');
}
}
const save = async () => {
setSaving(true);
await Promise.all([
setColorConfig('primary', primary),
setColorConfig('primary-light', primaryLight),
setColorConfig('primary-dark', primaryDark),
setColorConfig('secondary', secondary),
setColorConfig('secondary-light', secondaryLight),
setColorConfig('secondary-dark', secondaryDark),
setColorConfig('error', error),
setColorConfig('error-light', errorLight),
setColorConfig('error-dark', errorDark),
setColorConfig('success', success),
setColorConfig('success-light', successLight),
setColorConfig('success-dark', successDark),
setColorConfig('warning', warning),
setColorConfig('warning-light', warningLight),
setColorConfig('warning-dark', warningDark),
setColorConfig('info', info),
setColorConfig('info-light', infoLight),
setColorConfig('info-dark', infoDark)
]);
window.location.reload();
}
useEffect(() => {
getData();
}, []);
const colorChange = async ()=>{
setChanged(true)
document.documentElement.style.setProperty(`--color-primary`, primary);
document.documentElement.style.setProperty(`--color-primary-light`, primaryLight);
document.documentElement.style.setProperty(`--color-primary-dark`, primaryDark);
document.documentElement.style.setProperty(`--color-secondary`, secondary);
document.documentElement.style.setProperty(`--color-secondary-light`, secondaryLight);
document.documentElement.style.setProperty(`--color-secondary-dark`, secondaryDark);
document.documentElement.style.setProperty(`--color-error`, error);
document.documentElement.style.setProperty(`--color-error-light`, errorLight);
document.documentElement.style.setProperty(`--color-error-dark`, errorDark);
document.documentElement.style.setProperty(`--color-success`, success);
document.documentElement.style.setProperty(`--color-success-light`, successLight);
document.documentElement.style.setProperty(`--color-success-dark`, successDark);
document.documentElement.style.setProperty(`--color-warning`, warning);
document.documentElement.style.setProperty(`--color-warning-light`, warningLight);
document.documentElement.style.setProperty(`--color-warning-dark`, warningDark);
document.documentElement.style.setProperty(`--color-info`, info);
document.documentElement.style.setProperty(`--color-info-light`, infoLight);
document.documentElement.style.setProperty(`--color-info-dark`, infoDark);
}
return (
<div className="w-5/6 h-1/2 text-white lg:flex justify-center items-center animate-in overflow-y-hidden">
<div className=" w-5/6 md:w-4/6 lg:w-3/6 xl:w-2/6 rounded-md bg-primary opacity-90 p-12 m-1 mt-24 shadow-lg backdrop-blur">
<div className="w-full relative">
<span className="text-2xl pb-4">Color Settings</span>
<button onClick={()=>{router.push("/admin")}} className={`float-right bg-error hover:bg-error-light ml-2 rounded p-2`}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor"
className="md:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3" />
</svg>
<span className="hidden md:block">Back</span>
</button>
<button onClick={save} disabled={!changed}
className={`float-right ${changed ? "bg-success hover:bg-success-light" : "bg-success-dark"} rounded p-2`}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor"
className="md:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m4.5 12.75 6 6 9-13.5" />
</svg>
<span className="hidden md:block">{saving?"Saving...":"Save"}</span>
</button>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Primary Color</label>
<div className="flex">
<input
value={primary}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setPrimary(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={primary}
onChange={(e) => { setPrimary(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Primary Light Color</label>
<div className="flex">
<input
value={primaryLight}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setPrimaryLight(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={primaryLight}
onChange={(e) => { setPrimaryLight(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Primary Dark Color</label>
<div className="flex">
<input
value={primaryDark}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setPrimaryDark(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={primaryDark}
onChange={(e) => { setPrimaryDark(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Secondary Color</label>
<div className="flex">
<input
value={secondary}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setSecondary(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={secondary}
onChange={(e) => { setSecondary(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Secondary Dark Color</label>
<div className="flex">
<input
value={secondaryDark}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setSecondaryDark(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={secondaryDark}
onChange={(e) => { setSecondaryDark(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Secondary Light Color</label>
<div className="flex">
<input
value={secondaryLight}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setSecondaryLight(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={secondaryLight}
onChange={(e) => { setSecondaryLight(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Error Color</label>
<div className="flex">
<input
value={error}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setError(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={error}
onChange={(e) => { setError(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Error Dark Color</label>
<div className="flex">
<input
value={errorDark}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setErrorDark(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={errorDark}
onChange={(e) => { setErrorDark(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Error Light Color</label>
<div className="flex">
<input
value={errorLight}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setErrorLight(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={errorLight}
onChange={(e) => { setErrorLight(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Success Color</label>
<div className="flex">
<input
value={success}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setSuccess(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={success}
onChange={(e) => { setSuccess(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Success Dark Color</label>
<div className="flex">
<input
value={successDark}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setSuccessDark(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={successDark}
onChange={(e) => { setSuccessDark(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
<div className="w-full relative">
<label htmlFor="primaryInput">Success Light Color</label>
<div className="flex">
<input
value={successLight}
required
type="text"
className="w-full rounded-md rounded-r-none bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setSuccessLight(e.target.value); colorChange(); }}
placeholder="Choose the primary color"
/>
<input
value={successLight}
onChange={(e) => { setSuccessLight(e.target.value); colorChange(); }}
required
type="color"
className="w-10 h-10 rounded-r p-1"
/>
</div>
</div>
</div>
</div>
);
}
export default PageComponent;

View File

@ -0,0 +1,124 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
function PageComponent() {
const supabase = createClient();
const router = useRouter();
const [name, setName] = useState<string>('');
const [price, setPrice] = useState<number>(0);
const [description, setDescription] = useState<string>('');
const [color, setColor] = useState<string>('#000000');
const getData = async () => {
}
useEffect(() => {
getData();
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const data = {
name,
price,
color,
description
};
const response = await fetch('/api/tiers', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (response.ok) {
const responseData = await response.json();
window.location.href = "/admin/tiers";
} else {
console.log(response);
}
}
return (
<div className="w-full p-8 h-1/2 text-white lg:flex justify-center items-center animate-in">
<div className="w-full lg:w-1/3 rounded-md bg-primary opacity-90 p-12 m-1 mt-32 shadow-lg backdrop-blur">
<form onSubmit={handleSubmit}>
<div className="w-full flex">
<span className="text-2xl pb-4">Creating New Tier</span>
</div>
<div className="w-full flex">
<input
value={name}
required
type="text"
onChange={(e) => { setName(e.target.value) }}
className="mr-2 rounded-md bg-info-bright p-2 w-1/2 text-black shadow-lg"
placeholder="Tag Name"
/>
<div className="flex border border-gray-300 w-1/2 rounded-md">
<span className="flex items-center bg-gray-100 rounded-l-md border-r px-3 text-gray-500">
$
</span>
<input
value={price}
onChange={(e) => { setPrice(Number(e.target.value)) }}
required
placeholder="Price in USD per month"
type="number"
className="flex-1 min-w-0 bg-info-bright rounded-r-md px-3 py-2 text-black focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>
</div>
<div className="w-full pt-2 justify-center flex">
<textarea
value={description}
onChange={(e) => { setDescription(e.target.value) }}
required
placeholder="Description of the tier and what the user gets from subscribing."
rows={3}
className="w-full rounded-md bg-info-bright p-2 w-1/2 text-black shadow-lg"
></textarea>
</div>
<div className="w-full pt-2 justify-center flex">
<div className="w-1/2 relative">
<input
value={color}
required
type="text"
className="w-full rounded-md bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setColor(e.target.value) }}
placeholder="Choose the tiers color"
/>
<input
value={color}
onChange={(e) => { setColor(e.target.value) }}
required
id="colorInput"
type="color"
className="absolute right-0 top-0 w-10 h-full rounded-r p-1"
/>
</div>
<button
type="submit"
className="hover:scale-95 ml-2 shadow-lg w-1/2 h-10 text-center bg-success hover:bg-success-light text-white font-bold rounded flex items-center justify-center"
>
Create
</button>
<button
type="button"
onClick={() => { router.push("/admin/tiers") }}
className="hover:scale-95 shadow-lg ml-2 w-1/2 h-10 text-center bg-error-dark hover:bg-error text-white font-bold rounded flex items-center justify-center"
>
Back
</button>
</div>
</form>
</div>
</div>
);
}
export default PageComponent;

55
app/admin/tiers/page.tsx Normal file
View File

@ -0,0 +1,55 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
function PageComponent() {
const router = useRouter();
const supabase = createClient();
const [tiers, setTiers] = useState<any[]>([]);
const getData = async () => {
try {
const response = await fetch('/api/tiers');
if (response.ok) {
const data = await response.json();
setTiers(data);
} else {
console.error('failed to fetch tiers');
}
} catch (error) {
console.error('Error fetching users:', error);
}
}
useEffect(() => {
getData();
}, []);
return (
<div className="w-2/3 p-8 h-1/2 text-white lg:flex justify-center items-center animate-in">
<div className="w-full lg:w-1/3 rounded-md bg-primary opacity-90 p-8 m-1 mt-32 shadow-lg backdrop-blur">
<div className="w-full flex justify-center">
<span className="text-2xl pb-4">Tiers Management</span>
</div>
<div className="w-full flex justify-center">
<button onClick={() => { router.push("/admin/tiers/create") }} className="bg-success hover:bg-success-light rounded p-2 w-full">New Tier</button>
<button onClick={() => { router.push("/admin") }} className="bg-error hover:bg-error-light rounded p-2 w-full ml-2">Back</button>
</div>
<div className="w-full justify-center pt-8">
{tiers.map((item, index) => (
<div className="w-full flex justify-center">
<div key={index} className="text-white w-full text-stroke mt-2">
<button onClick={() => { router.push("/admin/tiers/view?name=" + item.name) }} className="py-2 w-full rounded hover:scale-105" style={{ backgroundColor: item.color }}>{item.name} - ${item.price}/month</button>
</div>
</div>
))}
</div>
</div>
</div>
);
}
export default PageComponent;

View File

@ -0,0 +1,141 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
function PageComponent() {
const router = useRouter();
const supabase = createClient();
const [tier, setTier] = useState<any[]>([]);
const [users, setUsers] = useState<any[]>([]);
const [name, setName] = useState<string>('');
const [price, setPrice] = useState<number>(0);
const [description, setDescription] = useState<string>('');
const [color, setColor] = useState<string>('#000000');
const getData = async () => {
try {
const searchParams = new URLSearchParams(window.location.search);
const name = searchParams.get('name');
const response = await fetch('/api/tiers/'+name);
if (response.ok) {
const data = await response.json();
setTier(data);
setName(data.name);
setPrice(data.price);
setDescription(data.description);
setColor(data.color);
} else {
console.error('failed to fetch tiers');
}
} catch (error) {
console.error('Error fetching users:', error);
}
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const data = {
newName:name,
price,
color,
description
};
const response = await fetch('/api/tiers/'+name, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (response.ok) {
const responseData = await response.json();
window.location.href = "/admin/tiers";
} else {
console.log(response);
}
}
useEffect(() => {
getData();
}, []);
return (
<div className="w-full p-8 h-1/2 text-white lg:flex justify-center items-center animate-in">
<div className="w-full lg:w-1/3 rounded-md bg-primary opacity-90 p-12 m-1 mt-32 shadow-lg backdrop-blur">
<form onSubmit={handleSubmit}>
<div className="w-full flex">
<span className="text-2xl pb-4">Editing Existing Tier</span>
</div>
<div className="w-full flex">
<input
value={name}
required
type="text"
onChange={(e) => { setName(e.target.value) }}
className="mr-2 rounded-md bg-info-bright p-2 w-1/2 text-black shadow-lg"
placeholder="Tag Name"
/>
<div className="flex border border-gray-300 w-1/2 rounded-md">
<span className="flex items-center bg-gray-100 rounded-l-md border-r px-3 text-gray-500">
$
</span>
<input
value={price}
onChange={(e) => { setPrice(Number(e.target.value)) }}
required
placeholder="Price in USD per month"
type="number"
className="flex-1 min-w-0 bg-info-bright rounded-r-md px-3 py-2 text-black focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>
</div>
<div className="w-full pt-2 justify-center flex">
<textarea
value={description}
onChange={(e) => { setDescription(e.target.value) }}
required
placeholder="Description of the tier and what the user gets from subscribing."
rows={3}
className="w-full rounded-md bg-info-bright p-2 w-1/2 text-black shadow-lg"
></textarea>
</div>
<div className="w-full pt-2 justify-center flex">
<div className="w-1/2 relative">
<input
value={color}
required
type="text"
className="w-full rounded-md bg-info-bright p-2 text-black shadow-lg"
onChange={(e) => { setColor(e.target.value) }}
placeholder="Choose the tiers color"
/>
<input
value={color}
onChange={(e) => { setColor(e.target.value) }}
required
id="colorInput"
type="color"
className="absolute right-0 top-0 w-10 h-full rounded-r p-1"
/>
</div>
<button onClick={() => { }} className="hover:scale-95 shadow-lg ml-2 w-1/2 h-10 text-center bg-warning hover:bg-warning-light text-white font-bold rounded flex items-center justify-center">
Update
</button>
<button type="button" onClick={() => { }} className="hover:scale-95 shadow-lg ml-2 w-1/2 h-10 text-center bg-error hover:bg-error-light text-white font-bold rounded flex items-center justify-center">
Delete
</button>
<button type="button" onClick={() => { router.push("/admin/tiers") }} className="hover:scale-95 shadow-lg ml-2 w-1/2 h-10 text-center bg-error-dark hover:bg-error text-white font-bold rounded flex items-center justify-center">
Back
</button>
</div>
</form>
</div>
</div>
);
}
export default PageComponent;

View File

@ -0,0 +1,26 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { createClient } from "@/utils/supabase/server";
import { NextResponse } from "next/server";
export async function PUT(request: Request) {
const body = await request.json();
console.log(body)
const supabase = createClient();
var value = body.value;
const { error } = await supabase.from('interface_configurations').update({ value }).eq('name', body.name);
console.log(error)
if (error) {
return NextResponse.error();
}
return NextResponse.json({});
}
export async function GET(request: Request) {
const url = new URL(request.url as string, 'http://localhost');
const name = url.searchParams.get('name') || '';
const supabase = createClient();
const { data, error } = await supabase.from('interface_configurations').select('*').eq('name', name).single();
return NextResponse.json(data);
}

View File

@ -0,0 +1,17 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { createClient } from "@/utils/supabase/server";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
try {
const supabase = createClient();
const { data, error } = await supabase.auth.admin.listUsers();
console.log(error)
if (error) {
throw error;
}
return NextResponse.json(data);
} catch (error) {
return NextResponse.error();
}
}

View File

@ -0,0 +1,34 @@
import { NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
const galleryId = params.id;
const supabase = createClient();
const { data: gallery, error: galleryError } = await supabase
.from('galleries')
.select('*')
.eq('name', galleryId)
.single();
// List all files in the galleryId path
let { data: files, error } = await supabase.storage
.from('galleries')
.list(params.id.toLowerCase().replace(/\s+/g, '_'));
if (files == null || error) {
//console.error('Error listing files:', error);
return NextResponse.error();
}
// Extract file names from the list of files
const fileNames = files.map((file) => file.name);
// Return a JSON response with the array of file names
return new Response(JSON.stringify(fileNames), {
headers: { 'content-type': 'application/json' },
});
}

View File

@ -18,7 +18,7 @@ export async function GET(
{ params }: { params: { id: string } }
) {
const galleryId = params.id.toLowerCase().replace(/\s+/g, '_'); const supabase = createClient();
const galleryId = params.id; const supabase = createClient();
const user = await supabase.auth.getUser();
@ -54,8 +54,6 @@ export async function GET(
.select('*')
.eq('user_id', userId)
.single();
console.log(subscription)
console.log(gallery.tier)
switch(gallery.tier){
case "Tier 3":
if(subscription?.tier!="Tier 3"){

View File

@ -17,10 +17,11 @@ export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
const galleryId = params.id.toLowerCase().replace(/\s+/g, '_');
const supabase = createClient();
const user = await supabase.auth.getUser();
const url = new URL(request.url);
const search = url.searchParams.get("nsfw");
const nsfw = search === "true";
const { data: gallery, error: galleryError } = await supabase
.from('galleries')
@ -28,15 +29,17 @@ export async function GET(
.eq('name', params.id)
.single();
let { data: files, error } = await supabase.storage.from('galleries').list(galleryId);
var thumbnailFile = gallery.thumbnail_file;
if(thumbnailFile==null || thumbnailFile==""){
let { data: files, error } = await supabase.storage.from('galleries').list(params.id);
if (files == null || files?.length == 0) {
return NextResponse.error();
}
thumbnailFile = files[0].name;
}
// Loop through each file, download it, convert it to base64, and add the data URL to the array
let { data: blobdata, error: fileError } = await supabase.storage.from('galleries').download(galleryId + "/" + files[0].name);
let { data: blobdata, error: fileError } = await supabase.storage.from('galleries').download(params.id + "/" + thumbnailFile);
if (fileError || blobdata == null) {
//console.error('Error downloading file:', error);
return NextResponse.error();
@ -49,10 +52,10 @@ export async function GET(
.select('*')
.eq('user_id', userId)
.single();
if(gallery.nsfw){
if(nsfw && gallery.nsfw){
blobBuffer = await blurImage(blobBuffer);
}
const contentType = files[0].name.endsWith('.png') ? 'image/png' : 'image/jpeg';
const contentType = thumbnailFile.endsWith('.png') ? 'image/png' : 'image/jpeg';
const dataUrl = `data:${contentType};base64,${blobBuffer.toString('base64')}`;

View File

@ -0,0 +1,110 @@
import { NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";
import path from 'path';
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
const id = params.id;
const supabase = createClient();
const { data: gallery, error } = await supabase.from('galleries').select("*").eq('name', id).single();
return NextResponse.json({ gallery });
}
export async function PUT(
request: Request,
{ params }: { params: { id: string } }){
const supabase = createClient();
const formData = await request.formData();
const tags = JSON.parse(formData.getAll('tags').toString()) as string[];
const originalName = formData.get('originalName');
const name = formData.get('name')?.toString();
const nsfw = formData.get('nsfw')?.toString();
const tier = formData.get('tier')?.toString();
const thumbnail = formData.get('thumbnail');
const { error } = await supabase.from('galleries').update({name, tags, nsfw, tier, thumbnail_file:thumbnail}).eq('name', originalName ?? '');
async function renameFolder(oldFolderName: any, newFolderName: string) {
// Get a list of all files in the old folder
let { data: oldFiles, error } = await supabase.storage.from('galleries').list(oldFolderName);
if (error) {
console.error('Error fetching files:', error);
return;
}
// Move each file to the new folder
if (oldFiles) {
for (let file of oldFiles) {
let oldPath = file.name;
let newPath = newFolderName + '/' + oldPath.split('/').pop();
let { error: moveError } = await supabase.storage.from('galleries').move(oldPath, newPath);
if (moveError) {
console.error(`Error moving file ${oldPath} to ${newPath}:`, moveError);
}
}
}
// Delete the old folder
let { error: deleteError } = await supabase.storage.from('galleries').remove([oldFolderName]);
if (deleteError) {
console.error('Error deleting old folder:', deleteError);
}
}
renameFolder(originalName, name ?? '');
if(error){
return NextResponse.error();
}
let { data: galleries, error:galleriesError } = await supabase
.from('galleries')
.select('*');
return NextResponse.json({ success: true, galleries });
}
export async function DELETE(
request: Request,
{ params }: { params: { id: string } }
) {
const id =params.id;
const supabase = createClient();
const { data: gallery, error } = await supabase.from('galleries').delete().eq('name', id).single();
let { data: galleries, error:galleriesError } = await supabase
.from('galleries')
.select('*');
return NextResponse.json({ success: true, galleries });
}
// const tagsResponse = await fetch(`/api/galleries/tags?search=${search}`);
// const tagsData = await tagsResponse.json();
// const galleriesWithTagData = galleriesData.map((gallery: any) => {
// const tags = tagsData.filter((tag: any) => gallery.tags.includes(tag.name));
// return { ...gallery, tags };
// });
// const formData = new FormData();
// formData.append('name', name);
// formData.append('tags', JSON.stringify(tags));
// files.forEach((file: File) => {
// formData.append('files', file);
// });
// const response = await fetch('/api/galleries', {
// method: 'POST',
// body: formData,
// });
// if (response.ok) {
// const data = await response.json();
// // Handle success
// } else {
// // Handle error
// }

View File

@ -0,0 +1,37 @@
import { NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";
import path from 'path';
export async function GET(request: Request) {
const supabase = createClient();
let { data: galleries, error } = await supabase
.from('galleries')
.select('*');
return NextResponse.json(galleries);
}
export async function POST(request: Request) {
const supabase = createClient();
const formData = await request.formData();
const files = formData.getAll('files');
const tags = JSON.parse(formData.getAll('tags').toString()) as string[];
const name = formData.get('name');
const nsfw = formData.get('nsfw');
const tier = formData.get('tier');
const thumbnail = formData.get('thumbnail');
for (let i = 0; i < files.length; i++) {
const file = files[i] as File; // Cast 'file' to 'File' type
supabase.storage.from('galleries').upload(`${name}/${file.name}`, file);
}
const { data: gallery, error } = await supabase.from('galleries').insert({ name, tags, nsfw, thumbnail_file:thumbnail, tier, column_number: 3 }).single();
let { data: galleries, error: galleriesError } = await supabase
.from('galleries')
.select('*');
return NextResponse.json({ success: true, galleries });
}

View File

@ -13,18 +13,15 @@ export async function POST(request: Request) {
.from('galleries')
.select('*')
.ilike('name', `%${search}%`)
//console.log(error)
return NextResponse.json(galleries);
}
else{
// Rest of the code...
console.log(tags)
let { data: galleries, error } = await supabase
.from('galleries')
.select('*')
.contains('tags', tags) // Fix: Use contains instead of overlaps
.ilike('name', `%${search}%`)
//console.log(error)
return NextResponse.json(galleries);
}

View File

@ -7,6 +7,26 @@ export async function GET(request: Request) {
let { data: tags, error } = await supabase
.from('tags')
.select('*')
.order('name', { ascending: true });
return NextResponse.json(tags)
}
export async function POST(request: Request) {
const supabase = createClient();
const data = await request.json();
const { data: tag, error } = await supabase.from('tags').insert({ name: data.tag }).single();
if (error) {
return NextResponse.error();
}
return NextResponse.json(tag);
}
export async function PUT(request: Request) {
const supabase = createClient();
const data = await request.json();
const { data: tag, error } = await supabase.from('tags').delete().eq('name', data.tag).single();
if (error) {
return NextResponse.error();
}
return NextResponse.json(tag);
}

View File

@ -0,0 +1,36 @@
import { NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";
export async function GET(
request: Request,
{ params }: { params: { name: string } }
) {
const supabase = createClient();
const { data: tier, error: galleryError } = await supabase
.from('tiers')
.select('*')
.eq('name', params.name)
.single();
if(galleryError) {
return NextResponse.error();
}
return NextResponse.json(tier);
}
export async function PUT(
request: Request,
{ params }: { params: { name: string } }
) {
const supabase = createClient();
const { newName, price, color, description } = await request.json();
console.log(newName)
const { error } = await supabase.from('tiers')
.update({ name:newName, price, color, description }).eq('name', params.name);
if (error) {
console.error('Error updating tier:', error);
return NextResponse.error();
}
return NextResponse.json({});
}

26
app/api/tiers/route.ts Normal file
View File

@ -0,0 +1,26 @@
import { NextResponse } from "next/server";
import { createClient } from "@/utils/supabase/server";
export async function GET(request: Request) {
const supabase = createClient();
const { data, error } = await supabase.from('tiers').select('*');
if (error) {
console.error('Error fetching tiers:', error);
return NextResponse.error();
}
const tiers = data ?? [];
return NextResponse.json(tiers);
}
export async function POST(request: Request) {
const supabase = createClient();
const { name, price, color, description } = await request.json();
const { data, error } = await supabase.from('tiers').insert([{ name, price, color, description }]);
if (error) {
console.error('Error inserting tier:', error);
return NextResponse.error();
}
return NextResponse.json(data);
}

View File

@ -0,0 +1,168 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import Masonry from "react-masonry-css";
import SearchInput from "@/components/neroshitron/search_input";
function PageComponent() {
const router = useRouter();
const [selectedGallery, setSelectedGallery] = useState<string | null>(null);
const [filePreviews, setFilePreviews] = useState<string[]>([]);
const [name, setName] = useState<string>('');
const [nsfw, setNsfw] = useState<boolean>(false);
const [tags, setTags] = useState<string[]>([]);
const [tier, setTier] = useState<string>('Free');
const [thumbnail, setThumbnail] = useState<string>("");
const [files, setFiles] = useState<FileList>();
const [tiers, setTiers] = useState<any[]>([]);
const supabase = createClient();
const user = supabase.auth.getUser();
const getData = async () => {
try {
const response = await fetch('/api/tiers');
if (response.ok) {
const data = await response.json();
setTiers(data);
} else {
console.error('failed to fetch tiers');
}
} catch (error) {
console.error('Error fetching users:', error);
}
}
useEffect(() => {
getData();
}, [selectedGallery]);
const closeGallery = () => {
setSelectedGallery(null);
}
const createGallery = async () => {
const formData = new FormData();
formData.append('name', name);
if (files) {
Array.from(files).forEach((file: File) => {
formData.append('files', file);
});
}
formData.append('tags', JSON.stringify(tags));
formData.append('nsfw', nsfw.toString());
formData.append('thumbnail', thumbnail);
formData.append('tier', tier);
const response = await fetch('/api/galleries/admin', {
method: 'POST',
body: formData,
});
if (response.ok) {
const data = await response.json();
window.location.href = "/gallery/admin/view?id="+name;
} else {
console.log(response)
}
}
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const files = event.target.files;
if (files) {
const previews: string[] = [];
for (let i = 0; i < files.length; i++) {
const file = files[i];
const reader = new FileReader();
reader.onload = (e) => {
if (e.target && e.target.result) {
previews.push(e.target.result.toString());
if (previews.length === files.length) {
setFiles(files);
setFilePreviews(previews);
}
}
};
reader.readAsDataURL(file);
}
}
};
return (
<div className="w-full p-8 text-white flex justify-center items-center animate-in">
<div className="w-full lg:w-1/2 rounded-md bg-primary opacity-90 backdrop-blur-lg p-12 mt-32 shadow-lg">
<div className="w-full flex pb-4">
<span className="text-2xl">Creating New Gallery</span>
</div>
<div className="w-full flex">
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
className="mb-8 mr-2 rounded-md bg-secondary p-2 w-1/2 text-white shadow-lg"
placeholder="Gallery Name"
/>
<div className="w-1/4">
<button onClick={() => router.push("/gallery/admin")} className="w-full bg-error hover:bg-error-light text-white rounded-md p-2 shadow-lg">
Back
</button>
</div>
<div className="w-1/4">
<button onClick={()=>{createGallery()}} className="w-full bg-success hover:bg-success-light text-white rounded-md p-2 ml-2 shadow-lg ">
<span></span>Create
</button>
</div>
</div>
<div className="w-full lg:flex">
<div className="w-full lg:w-1/2">
<div className="w-1/2 absolute pr-14">
<SearchInput
placeholderTags={[
{ value: "tags", label: "❗️ click here to add tags" },
]}
startingTags={tags}
nsfwButtonEnabled={true}
searchChanged={(search) => { }}
nsfwChanged={(nsfw) => { }}
tagsChanged={(tags) => { setTags(tags) }}
/>
</div>
</div>
<div className="w-full lg:w-1/2 lg:pt-0 pt-4">
<select value={nsfw ? "NSFW" : "SFW"} className="mb-2 shadow-lg rounded-md bg-secondary p-2 w-full text-white" onChange={e=>{
setNsfw(e.target.value === "NSFW");
}}>
<option value="NSFW" selected={nsfw}>NSFW</option>
<option value="SFW" selected={nsfw}>SFW</option>
</select>
<select onChange={e=>{
setTier(e.target.value);
}} className="mb-2 shadow-lg mr-2 rounded-md bg-secondary p-2 w-full text-white">
<option value="" disabled >Select New Tier</option>
{tiers.map((tier, index) => (
<option key={index} value={tier.name}>{tier.name}</option>
))}
</select>
<select onChange={e=>{setThumbnail(e.target.value)}} className="mb-2 shadow-lg mr-2 rounded-md bg-secondary p-2 w-full text-white">
<option value="" disabled selected>Select Thumbnail</option>
{files && Array.from(files).map((file: File, index: number) => (
<option key={index} value={file.name}>{file.name}</option>
))}
</select>
<input
className="relative m-0 block w-full min-w-0 flex-auto cursor-pointer rounded border border-solid border-secondary-lighter bg-transparent bg-clip-padding px-3 py-[0.32rem] text-base font-normal text-surface transition duration-300 ease-in-out file:-mx-3 file:-my-[0.32rem] file:me-3 file:cursor-pointer file:overflow-hidden file:rounded-none file:border-0 file:border-e file:border-solid file:border-inherit file:bg-transparent file:px-3 file:py-[0.32rem] file:text-surface focus:border-primary focus:text-gray-700 focus:shadow-inset focus:outline-none dark:border-white/70 dark:text-white file:dark:text-white"
type="file"
id="formFileMultiple"
multiple
onChange={handleFileChange}
/>
<Masonry breakpointCols={3} className="my-masonry-grid pl-6 col-span-2">
{filePreviews.map((preview, index) => (
<img key={index} src={preview} alt={`Preview ${index}`} />
))}
</Masonry>
</div>
</div>
</div>
</div>
);
}
export default PageComponent;

161
app/gallery/admin/page.tsx Normal file
View File

@ -0,0 +1,161 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import SearchInput from "@/components/neroshitron/search_input";
import { useRouter } from 'next/navigation';
function PageComponent() {
const router = useRouter();
const supabase = createClient();
const user = supabase.auth.getUser();
const [tags, setTags] = useState<any[]>([]);
const [nsfwState, setNsfwState] = useState<boolean>(false);
const [tagsState, setTagsState] = useState<string[]>([]);
const [searchState, setSearchState] = useState<string>("");
const [galleries, setGalleries] = useState([]);
const [tagSearch, setTagSearch] = useState<string>('');
const [newTagName, setNewTagName] = useState<string>('');
const getData = async () => {
const tagsResponse = await fetch(`/api/galleries/tags`);
const tagsData = await tagsResponse.json();
setTags(tagsData);
const galleriesResponse = await fetch(`/api/galleries?search=` + searchState + '&nsfw=' + nsfwState, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ tags: tagsState })
});
const galleriesData = await galleriesResponse.json();
setGalleries(galleriesData);
}
const createTag = async () => {
let formattedTag = newTagName.toLowerCase().replace(" ", "_");
const tagsResponse = await fetch(`/api/galleries/tags`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ tag: formattedTag })
});
const tagsData = await tagsResponse.json();
setNewTagName('');
getData();
}
const deleteTag = async (tagParam: string) => {
const tagsResponse = await fetch(`/api/galleries/tags`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ tag:tagParam })
});
const tagsData = await tagsResponse.json();
getData();
}
useEffect(() => {
getData();
}, [tagsState, newTagName]);
return (
<div className="w-full p-8 h-max text-white lg:flex justify-center items-start animate-in mt-32">
<div className="w-full h-max lg:w-1/3 rounded-md bg-primary opacity-90 p-8 m-1 shadow-lg backdrop-blur">
<span className="text-2xl">Tags Management</span>
<div className="w-full flex pt-4">
<form onSubmit={createTag} className="flex w-full">
<input value={newTagName} required type="text" onChange={(e)=>{setNewTagName(e.target.value)}} className=" mb-8 mr-2 rounded-md bg-info-bright p-2 w-1/2 text-black shadow-lg" placeholder="Tag Name" />
<button className=" ml-2 shadow-lg w-1/2 h-10 text-center bg-success hover:bg-success-light text-white font-bold rounded flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="lg:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
<span className="lg:hidden block">Tag</span>
<span className="lg:block hidden">New Tag</span>
</button>
</form>
</div>
<div className="w-full flex">
<input type="text" value={tagSearch} onChange={(e)=>{setTagSearch(e.target.value)}} className=" mb-8 shadow-lg mr-2 rounded-md bg-info-bright p-2 w-full text-black" placeholder="Search all tags by name" />
</div>
<div className="w-full h-96 overflow-y-scroll no-scrollbar">
<table className="w-full bg-primary-light rounded">
<tbody>
{tags.filter((value,index,array)=>{
return value.name.toLowerCase().includes(tagSearch.toLowerCase());
}).map((item:any) => (
<tr key={item.name} className="hover:bg-secondary-dark animate-in shadow">
<td className="px-4 py-2">{item.name}</td>
<td className="px-4 py-2">
<button onClick={()=>{deleteTag(item.name)}} className=" bg-error shadow-lg hover:bg-error-light text-white font-bold py-2 px-4 rounded float-right">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
<div className="w-full h-max lg:w-1/2 rounded-md bg-primary opacity-90 backdrop-blur-lg p-8 m-1 shadow-lg">
<div className="w-full pb-2 flex justify-between">
<span className="text-2xl">Galleries Management</span>
<div>
<button onClick={()=>{router.push("/admin/")}} className="ml-2 p-2 shadow-lg h-10 text-center bg-error hover:bg-error-light text-white font-bold rounded">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="xl:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
<span className="xl:block hidden">Back</span>
</button>
<button onClick={()=>{router.push("/gallery/admin/create")}} className="ml-2 p-2 shadow-lg h-10 text-center bg-success hover:bg-success-light text-white font-bold rounded">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="xl:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
<span className="xl:block hidden">New Gallery</span>
</button>
</div>
</div>
<div className="w-full pb-2 flex">
<div className="absolute w-full z-20 pr-16">
<SearchInput
startingTags={[]}
placeholderTags={[
{ value: "tags", label: "❗️ click here to add tags to search" }
]} nsfwButtonEnabled={false} searchChanged={(search) => { setSearchState(search) }} nsfwChanged={(nsfw) => { setNsfwState(nsfw) }} tagsChanged={(tags) => { setTagsState(tags) }} />
</div>
</div>
<div className="w-full h-96 overflow-y-scroll no-scrollbar">
<table className="w-full mt-20 bg-primary-light rounded">
<tbody>
{/* Replace this with your data mapping logic */}
{galleries.map((item: { name: string, imageCount: number, tier: string }) => (
<tr key={item.name} className="hover:bg-secondary-dark shadow animate-in">
<td className="px-4 py-2" style={{ width: '65%' }}>{item.name}</td>
<td className="px-4 py-2">{item.imageCount}</td>
<td className="px-4 py-2">{item.tier}</td>
<td className="px-4 py-2">
<button onClick={()=>{ router.push(`/gallery/admin/view?id=${encodeURIComponent(item.name)}`)}} className="bg-secondary shadow-lg hover:bg-secondary-light text-white font-bold py-2 px-4 rounded float-right">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m5.231 13.481L15 17.25m-4.5-15H5.625c-.621 0-1.125.504-1.125 1.125v16.5c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Zm3.75 11.625a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
</svg>
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
export default PageComponent;

View File

@ -0,0 +1,271 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import Gallery from "@/components/neroshitron/gallery";
import SearchInput from "@/components/neroshitron/search_input";
import GalleryThumbnail from "@/components/neroshitron/gallery_thumbnail";
function PageComponent() {
const [filePreviews, setFilePreviews] = useState<string[]>([]);
const supabase = createClient();
const user = supabase.auth.getUser();
const [gallery , setGallery] = useState<any>(null);
const [originalName, setOriginalGalleryName] = useState<string>('');
const [galleryName, setGalleryName] = useState<string>('');
const [nsfw, setNsfw] = useState<boolean>(false);
const [tags, setTags] = useState<string[]>([]);
const [tier, setTier] = useState<string>('Free');
const [thumbnail, setThumbnail] = useState<string>();
const [fileNames, setFileNames] = useState<string[]>([]);
const [selectedTags, setSelectedTags] = useState<string[]>([]);
const router = useRouter();
const [tiers, setTiers] = useState<any[]>([]);
const [open, setOpen] = useState<boolean>(false);
const [images, setImages] = useState<string[]>([]);
const getData = async () => {
try {
const response = await fetch('/api/tiers');
if (response.ok) {
const data = await response.json();
setTiers(data);
} else {
console.error('failed to fetch tiers');
}
} catch (error) {
console.error('Error fetching users:', error);
}
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const galleryResponse = await fetch(`/api/galleries/admin/${id}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const galleryData = await galleryResponse.json();
setGallery(galleryData.gallery);
const filesResponse = await fetch(`/api/galleries/${id}/images/names`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const filesData = await filesResponse.json();
setFileNames(filesData);
setNsfw(galleryData.gallery.nsfw);
setTags(galleryData.gallery.tags);
setTier(galleryData.gallery.tier);
setGalleryName(galleryData.gallery.name);
if(originalName === ''){
setOriginalGalleryName(galleryData.gallery.name);
}
const imagesResponse = await fetch('/api/galleries/' + galleryData.gallery.name+ '/images');
const imagesUrls = await imagesResponse.json() as string[];
setImages(imagesUrls);
}
useEffect(() => {
getData();
}, []);
useEffect(() => {
}, [gallery]);
useEffect(() => {
}, [gallery, ]);
useEffect(() => {
}, [ nsfw ]);
useEffect(() => {
}, [tags ]);
useEffect(() => {
}, [galleryName]);
useEffect(() => {
}, [ tier]);
const updateGallery = async () => {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const formData = new FormData();
formData.append('id', gallery.name);
formData.append('name', galleryName);
formData.append('thumbnail', thumbnail ?? '');
formData.append('originalName', originalName);
formData.append('tags', JSON.stringify(selectedTags));
formData.append('nsfw', nsfw.toString());
formData.append('tier', tier);
const response = await fetch(`/api/galleries/admin/${originalName}`, {
method: 'PUT',
body: formData
});
if (response.ok) {
console.log(response)
const data = await response.json();
} else {
console.log(response)
}
if(originalName != galleryName){
router.push(`/gallery/admin/view?id=${galleryName}`)
}
else{
window.location.reload();
}
}
const deleteGallery = async () => {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const response = await fetch(`/api/gallery/admin/${gallery.name}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
});
if (response.ok) {
const data = await response.json();
router.push("/gallery/admin");
} else {
console.log(response)
}
}
const tierObj = tiers.find((tier) => tier.name == gallery.tier);
const subscriptionColor = tier ? tierObj.color : null;
return (
<div className="w-full p-8 h-screen text-white flex justify-center items-center animate-in">
<div className="w-full lg:w-1/2 rounded-md p-12 mt-14 ">
<div className="w-full lg:pt-0 pt-32 flex pb-60 justify-center"> {/* Center the gallery thumbnail */}
{gallery != null && (
<GalleryThumbnail
key={"galleryThumbnail"+galleryName+"-"+tags.join("")}
id={originalName}
columns={3}
onSelect={function (id: string, columns: number): void { setOpen(true) }}
title={galleryName}
subscription={tier}
tags={tags}
subscriptionColor={subscriptionColor}
showNsfw={false}
nsfw={nsfw}
></GalleryThumbnail>
)}
</div>
<div className="w-full opacity-90 backdrop-blur-lg bg-primary shadow-lg p-8 pb-0 rounded">
<span className="text-2xl">Editing Gallery</span>
<div className="w-full flex justify-end">
<div className="w-1/2 flex">
<input
type="text"
className="mb-8 mr-2 rounded-md bg-secondary p-2 w-full text-white"
placeholder="Gallery Name"
value={galleryName}
onChange={(e) => setGalleryName(e.target.value)}
/>
</div>
<div className="w-1/2 flex">
<button
onClick={() => deleteGallery()}
className="h-10 text-center w-full bg-error hover:bg-error-light text-white rounded-md p-2 flex items-center justify-center"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5}
stroke="currentColor" className="md:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
<span className="md:block hidden">Delete</span>
</button>
<button
onClick={() => (router.push("/gallery/admin"))}
className="h-10 w-full bg-error-dark hover:bg-error text-white rounded-md p-2 ml-2 flex items-center justify-center"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5}
stroke="currentColor" className="md:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3" />
</svg>
<span className="md:block hidden">Back</span>
</button>
<button onClick={()=>{updateGallery()}} className="h-10 w-full bg-warning hover:bg-warning-light text-white rounded-md p-2 ml-2">
<span>Update</span>
</button>
</div>
</div>
</div>
<div className="w-full lg:flex opacity-90 backdrop-blur-lg bg-primary shadow-lg p-8 pt-0 rounded">
<div className="w-full lg:w-1/2 mr-44">
<div className="w-1/2 fixed mr-8">
{gallery &&(
<SearchInput
placeholderTags={[
{ value: "tags", label: "❗️ click here to add tags" },
]}
startingTags={gallery.tags}
nsfwButtonEnabled={true}
searchChanged={(search) => {}}
nsfwChanged={(nsfw) => {}}
tagsChanged={(tags) => { setSelectedTags(tags) }}
/>
)}
</div>
</div>
<div className="w-full lg:w-1/2 pt-4">
{gallery != null && (<>
<select value={nsfw ? "NSFW" : "SFW"} className="mb-2 shadow-lg rounded-md bg-secondary p-2 w-full text-white" onChange={e=>{
setNsfw(e.target.value == "NSFW");
}}>
<option value="" disabled >Set NSFW</option>
<option value="NSFW" selected={nsfw}>NSFW</option>
<option value="SFW" selected={!nsfw}>SFW</option>
</select>
<select onChange={e=>{
setTier(e.target.value);
}} className="mb-2 shadow-lg mr-2 rounded-md bg-secondary p-2 w-full text-white">
<option value="" disabled >Select New Tier</option>
{tiers.map((tier, index) => (
<option selected={tier.name==gallery.tier} key={index} value={tier.name}>{tier.name}</option>
))}
</select>
<select onChange={e=>{setThumbnail(e.target.value)}} className="mb-2 shadow-lg mr-2 rounded-md bg-secondary p-2 w-full text-white">
<option value="" disabled selected>Select New Thumbnail</option>
{fileNames.map((name, index) => (
<option selected={name==gallery.thumbnail_file} key={index} value={name}>{name}</option>
))}
</select>
</>
)}
</div>
</div>
{(open) && (
<>
{/*
This is the modal for holding the gallery
*/}
<div
className={`fixed inset-0 transition-opacity z-30 animate-in`}
aria-hidden="true"
>
<div
className="absolute w-full h-full inset-0 bg-secondary-dark opacity-70 z-30"
onClick={() => setOpen(true)}
></div>
<div className="absolute inset-0 overflow-y-auto overflow-x-hidden no-scrollbar pt-2 w-full p-20 h-full z-30">
<Gallery
id={gallery.name}
columns={3}
closeMenu={() => setOpen(false)}
></Gallery>
</div>
</div>
</>
)}
</div>
</div>
);
}
export default PageComponent;

View File

@ -1,161 +1,50 @@
"use client";
import { createClient } from "@/utils/supabase/client";
import { redirect } from "next/navigation";
import GalleryThumbnail from "@/components/ui/gallery_thumbnail";
import React, { useState, useEffect } from 'react';
import { User } from "@supabase/supabase-js";
import Gallery from "@/components/ui/gallery";
import Search from "@/components/neroshitron/search";
import Gallery from "@/components/neroshitron/gallery";
import Link from "next/link";
function PageComponent() {
const [selectedGallery, setSelectedGallery] = useState<string | null>(null);
const supabase = createClient();
const [randomIds, setRandomIds] = useState<string[]>([]); // replace any with your gallery type
const [isOpen, setIsOpen] = useState<boolean>(false);
const [galleries, setGalleries] = useState<any[]>([]); // replace any with your gallery type
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [selectedGallery, setSelectedGallery] = useState<string | null>(null);
const [tags, setTags] = useState<any[]>([]);
const [search, setSearch] = useState<string>('');
const [galleryColumns, setColumns] = useState<number>(0);
const [selectedTags, setSelectedTags] = useState<number[]>([]);
const generateRandomString = function (length:number) {
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let charactersLength = characters.length;
for ( let i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
const getData = async () => {
}
return result;
}
const selectGallery = (gallery:string, columns:number) => {
setRandomIds([generateRandomString(3), generateRandomString(3), generateRandomString(3), generateRandomString(3)]);
setSelectedGallery(gallery);
setColumns(columns);
setIsOpen(true);
};
useEffect(() => {
getData();
}, [selectedGallery]);
const closeGallery = () => {
setSelectedGallery(null);
setColumns(0);
setIsOpen(false);
}
const getData = async () => {
let { data: { user } } = await supabase.auth.getUser();
const galleriesResponse = await fetch(`/api/galleries?search=`+search, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ tags:selectedTags })
});
//console.log(galleriesResponse)
const galleriesData = await galleriesResponse.json();
const tagsResponse = await fetch(`/api/galleries/tags`);
const tagsData = await tagsResponse.json();
setGalleries(galleriesData);
setTags(tagsData);
setUser(user);
setLoading(false);
}
useEffect(() => {
getData();
}, [selectedTags,search]);
const handleTagClick = (tag: number) => {
if (selectedTags.includes(tag)) {
setSelectedTags(selectedTags.filter((selectedTag) => selectedTag !== tag));
} else {
setSelectedTags([...selectedTags, tag]);
}
//console.log(selectedTags)
};
return (
<div>
<div className="fixed w-full h-full overflow-hidden z-0 animate-fade-left animate-fade-left animate-once animate-duration-[2000ms] animate-normal animate-fill-forwards">
<img
src="gallery_girl.png"
className="float-right object-cover h-screen w-6/6 md:w-5/6 lg:w-3/6 opacity-50 overflow-hidden"
alt="Background"
/>
<div className="w-full">
<div className="w-2/4">
<Search gallerySelected={(gallery:string)=>{setSelectedGallery(gallery)}}/>
</div>
<section className="flex items-center w-full p-8 pt-20 opacity-90 animate-jump-in animate-once animate-duration-500">
{(tags.length>0) ? (
<div className="container mx-auto py-8">
<input
className=" w-full md:w-1/2 text-neroshi-blue-950 h-16 px-3 rounded mb-8 focus:outline-none focus:shadow-outline text-xl px-8 shadow-lg mx-auto"
type="search"
placeholder="Search by title..."
onChange={(e) => setSearch(e.target.value)}
style={{
animation: 'expandFromLeft 2s ease-out forwards'
}}
/>
{(tags.length>0) ? (
<nav className="grid grid-cols-4 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-4 justify-items-center">
{tags.map((tag, index) => (
<a
key={index}
className={`w-full rounded-lg no-underline text-white py-3 px-4 font-medium text-center animate-jump-in animate-once animate-duration-500 animate-ease-out ${
selectedTags.includes(tag.name) ? 'bg-neroshi-blue-950 hover:bg-neroshi-blue-900' : 'bg-neroshi-blue-800 hover:bg-neroshi-blue-700'
}`}
href="#"
onClick={() => handleTagClick(tag.name)}
>
{tag.name}
</a>
))}
</nav>
):(
<div className="flex justify-center">
<p className="text-white">Loading Tags...</p>
</div>
)}
</div>
):(
<div className="animate-pulse bg-neroshi-blue-950 rounded-3xl w-full p-8 mt-10 h-48" ></div>
)}
</section>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-60 gap-x-5 h-full mb-96 animate-in">
{galleries && galleries.map((gallery, index) => (
<div className="mx-auto">
<GalleryThumbnail
key={gallery.name}
id={gallery.name}
title={gallery.name}
tags={gallery.tags}
columns={gallery.columns}
subscription={gallery.tier as string}
onSelect={selectGallery}
nsfw={gallery.nsfw}
></GalleryThumbnail>
</div>
))}
</div>
{isOpen ? (
{selectedGallery!=null ? (
<>
{/*
This is the modal for holding the gallery
*/}
<div
className={`fixed inset-0 transition-opacity z-30 ${
isOpen ? 'animate-in' : 'fade-out'
}`}
className={`fixed inset-0 transition-opacity z-30 animate-in`}
aria-hidden="true"
>
<div
className="absolute inset-0 bg-neroshi-blue-900 opacity-70 z-30"
onClick={() => setIsOpen(false)}
className="absolute inset-0 bg-secondary-dark opacity-70 z-30"
onClick={() => closeGallery()}
></div>
<div className="absolute inset-0 overflow-y-auto overflow-x-hidden no-scrollbar pt-2 w-full p-20 z-30">
<Gallery
id={selectedGallery as string}
columns={galleryColumns}
columns={3}
closeMenu={() => closeGallery()}
></Gallery>
</div>

View File

@ -16,23 +16,7 @@
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.my-masonry-grid {
display: -webkit-box; /* Not needed if autoprefixing */
display: -ms-flexbox; /* Not needed if autoprefixing */
display: flex;
margin-left: -30px; /* gutter size offset */
width: auto;
}
.my-masonry-grid_column {
padding-left: 30px; /* gutter size */
background-clip: padding-box;
}
/* Style your items */
.my-masonry-grid_column > div { /* change div to reference your elements you put in <Masonry> */
background: grey;
margin-bottom: 30px;
}
/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
@ -63,10 +47,22 @@
}
}
@layer base {
* {
@apply border-foreground/20;
}
.my-masonry-grid {
display: -webkit-box; /* Not needed if autoprefixing */
display: -ms-flexbox; /* Not needed if autoprefixing */
display: flex;
margin-left: -30px; /* gutter size offset */
width: auto;
}
.my-masonry-grid_column {
padding-left: 30px; /* gutter size */
background-clip: padding-box;
}
/* Style your items */
.my-masonry-grid_column > div { /* change div to reference your elements you put in <Masonry> */
background: grey;
margin-bottom: 30px;
}
.animate-in {
@ -83,3 +79,33 @@
transform: translateY(0);
}
}
button:disabled {
filter: grayscale(50%);
}
:root {
--color-primary: #201240;
--color-primary-light: #403260;
--color-primary-dark: #100120;
--color-secondary: #4F3D70;
--color-secondary-light: #6F5D90;
--color-secondary-dark: #2F1D50;
--color-error: #862117;
--color-error-light: #C44C4C;
--color-error-dark: #5C0D0D;
--color-success: #00C9A6;
--color-success-light: #20E9C6;
--color-success-dark: #00A986;
--color-warning: #E17558;
--color-warning-light: #E39578;
--color-warning-dark: #C15538;
--color-info: #222140;
--color-info-light: #424260;
--color-info-dark: #020120;
}

View File

@ -1,7 +1,11 @@
import { GeistSans } from "geist/font/sans";
import "./globals.css";
import NavigationBar from "@/components/NavigationBar";
import { createClient } from "@/utils/supabase/client";
import NavigationBar from "@/components/neroshitron/navigation_bar";
import { SpeedInsights } from "@vercel/speed-insights/next"
import { Analytics } from "@vercel/analytics/react"
import RightHandLayoutImage from "@/components/neroshitron/right_hand_layout_image";
import Theme from "@/components/theme";
const defaultUrl = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: "http://localhost:3000";
@ -12,6 +16,10 @@ export const metadata = {
description: "The fastest way to build apps with Next.js and Supabase",
};
const supabase = createClient();
export default function RootLayout({
children,
}: {
@ -20,10 +28,14 @@ export default function RootLayout({
return (
<html lang="en" className={GeistSans.className}>
<body className="bg-background text-foreground">
<div className="w-full fixed z-30">
<Theme/>
<RightHandLayoutImage/>
<div className="w-full fixed z-30 text-white white">
<NavigationBar/>
<SpeedInsights/>
<Analytics/>
</div>
<main className="min-h-screen flex flex-col items-center bg-gradient-to-r from-neroshi-blue-900 to-neroshi-blue-950 overflow-hidden">
<main className="min-h-screen flex flex-col items-center bg-gradient-to-r from-primary to-secondary overflow-hidden">
{children}
</main>
</body>

View File

@ -30,7 +30,6 @@ export default async function Login({
password,
});
//console.log(error);
if (error) {
return redirect("/login?message=Could not authenticate user");
}
@ -54,7 +53,6 @@ export default async function Login({
},
});
//console.log(error);
if (error) {
return redirect("/login?message=Could not authenticate user");
}
@ -66,11 +64,11 @@ export default async function Login({
<div className="flex-1 w-full flex flex-col gap-20 items-center animate-in"> <div className="flex-1 flex flex-col w-full px-8 sm:max-w-md justify-center gap-2">
<form className="animate-in flex-1 flex flex-col w-full my-32 gap-2 text-foreground">
<form className="animate-in flex-1 flex flex-col w-full my-32 gap-2 text-white">
<Link
href="/"
className="absolute left-1 top-44 py-2 px-4 rounded-md no-underline text-foreground flex items-center group text-sm"
className="absolute left-1 top-44 py-2 px-4 rounded-md no-underline text-white flex items-center group text-sm"
>
<svg
xmlns="http://www.w3.org/2000/svg"
@ -89,36 +87,36 @@ export default async function Login({
Back
</Link>
<input
className="rounded-md px-4 py-2 bg-inherit border mb-2 mx-1"
className="rounded-md px-4 py-2 bg-inherit border mb-2 mx-1 w-full sm:w-auto"
name="email"
placeholder="Email Address"
required
/>
<input
className="rounded-md px-4 py-2 bg-inherit border mb-2 mx-1"
className="rounded-md px-4 py-2 bg-inherit border mb-2 mx-1 w-full sm:w-auto"
type="password"
name="password"
placeholder="Password "
required
/>
<div className="flex">
<div className="flex text-white white">
<SubmitButton
formAction={signIn}
className="bg-neroshi-blue-500 hover:bg-neroshi-blue-400 rounded-md px-4 py-2 text-foreground mb-2 mx-1 w-1/2"
className="bg-success hover:bg-success-light rounded-md px-4 py-2 text-white mb-2 mx-1 w-1/2"
pendingText="Signing In..."
>
Sign In
</SubmitButton>
<SubmitButton
formAction={signUp}
className="bg-neroshi-blue-300 hover:bg-neroshi-blue-200 border border-foreground/20 rounded-md px-4 py-2 text-foreground mb-2 mx-1 w-1/2"
className="bg-info hover:bg-info-light border border-foreground/20 rounded-md px-4 py-2 text-white mb-2 mx-1 w-1/2"
pendingText="Signing Up..."
>
Sign Up
</SubmitButton>
</div>
{searchParams?.message && (
<p className="mt-4 bg-foreground/10 mt-14 p-2 text-foreground text-center">
<p className="mt-4 bg-foreground/10 mt-14 p-2 text-white text-center">
{searchParams.message}
</p>
)}

View File

@ -0,0 +1,12 @@
import { NextRequest, NextResponse } from 'next/server'
export function middleware(req:NextRequest, res:NextResponse) {
const requestHeaders = new Headers(req.headers)
requestHeaders.set('x-path', req.nextUrl.pathname)
return NextResponse.next({
request: {
headers: requestHeaders
}
})
}

View File

@ -1,137 +0,0 @@
import { createClient } from "@/utils/supabase/server";
import Link from "next/link";
import { redirect } from "next/navigation";
import crypto from 'crypto';
export default async function AuthButton() {
const supabase = createClient();
const {
data: { user },
} = await supabase.auth.getUser();
const signOut = async () => {
"use server";
const supabase = createClient();
await supabase.auth.signOut();
return redirect("/login");
};
if(user){
let email = user.email;
if(email != null){
const emailHash = crypto.createHash('md5').update(email.trim().toLowerCase()).digest('hex');
const gravatarUrl = `https://www.gravatar.com/avatar/${emailHash}`;
return(
<div className="flex justify-center items-center pt-2 ">
<nav className="w-auto bg-neroshi-blue-300 bg-opacity-10 flex justify-center z-10 h-16 animate-in rounded-3xl" style={{ backdropFilter: 'blur(10px)' }}>
<div className="w-full max-w-2xl flex justify-between items-center p-3 text-sm">
<div className="flex items-center gap-2 z-10">
<Link
href="/gallery"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
</svg>
<span className="hidden lg:block">Gallery</span>
</Link>
<Link
href="/livestream"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z" />
</svg>
<span className="hidden lg:block">Livestream</span>
</Link>
<Link
href="/commissions"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 10.5V6a3.75 3.75 0 1 0-7.5 0v4.5m11.356-1.993 1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 0 1-1.12-1.243l1.264-12A1.125 1.125 0 0 1 5.513 7.5h12.974c.576 0 1.059.435 1.119 1.007ZM8.625 10.5a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm7.5 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
</svg>
<span className="hidden lg:block">Commissions</span>
</Link>
<Link
href="/subscriptions"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>
<span className="hidden lg:block">Subscription</span>
</Link>
</div>
<div className="flex items-center gap-2">
<form action={signOut}>
<button className="py-2 px-4 ml-2 rounded-3xl no-underline bg-pink-950 hover:bg-pink-900">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="lg:hidden block size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15M12 9l-3 3m0 0 3 3m-3-3h12.75" />
</svg>
<span className="hidden lg:block">Logout</span>
</button>
</form>
<img src={gravatarUrl} alt="Profile" className="w-10 h-10 object-cover rounded-full cursor-pointer" />
</div>
</div>
</nav>
</div>)
}
}
else{
return( <div className="flex justify-center items-center pt-2 ">
<nav className="w-1/3 bg-neroshi-blue-300 bg-opacity-10 flex justify-center h-16 animate-in rounded-3xl" style={{ backdropFilter: 'blur(10px)' }}>
<div className="w-full max-w-2xl flex justify-between items-center p-3 text-sm">
<div className="flex items-center gap-2 ">
<Link
href="/gallery"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
Gallery
</Link>
<Link
href="/livestream"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
Stream
</Link>
<Link
href="/commissions"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
Commissions
</Link>
<Link
href="/subscriptions"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
Subscription
</Link>
</div>
<div className="flex items-center gap-2">
<Link
href="/login"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
Login
</Link>
<Link
href="/login"
className="py-2 px-3 flex rounded-3xl no-underline bg-neroshi-blue-900 hover:bg-neroshi-blue-800"
>
Signup
</Link>
</div>
</div>
</nav>
</div>)
}
}

View File

@ -0,0 +1,81 @@
"use client;"
import React, { useState, useEffect } from 'react';
import GalleryThumbnail from './gallery_thumbnail';
interface TagProps {
nsfw: boolean;
tags: string[];
search: string;
gallerySelected: (gallery: string) => void;
}
const Galleries = ({ nsfw, tags, search, gallerySelected }: TagProps) => {
const [galleries, setGalleries] = useState([]);
const [nsfwState, setNsfwState] = useState<boolean>(nsfw);
const [tagsState, setTagsState] = useState<string[]>(tags);
const [searchState, setSearchState] = useState<string>(search);
const [selectedGallery, setSelectedGallery] = useState<string | null>(null);
const [tiers, setTiers] = useState<any[]>([]);
const selectGallery = (gallery: string) => {
setSelectedGallery(gallery);
gallerySelected(gallery);
};
const getData = async () => {
try {
const response = await fetch('/api/tiers');
if (response.ok) {
const data = await response.json();
setTiers(data);
} else {
console.error('failed to fetch tiers');
}
} catch (error) {
console.error('Error fetching users:', error);
}
const galleriesResponse = await fetch(`/api/galleries?search=` + searchState + '&nsfw=' + nsfwState, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ tags: tagsState })
});
const galleriesData = await galleriesResponse.json();
setGalleries(galleriesData);
}
useEffect(() => {
getData();
}, [tagsState]);
return (
<div className="absolute inset-0 mx-auto ml-16 md:ml-0 pt-48 p-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-y-48 gap-x-4 animate-in overflow-y-scroll no-scrollbar z-0">
{galleries && galleries.map((gallery: any, index) => {
const tier = tiers.find((tier) => tier.name == gallery.tier);
const subscriptionColor = tier ? tier.color : null;
return (
<GalleryThumbnail
key={gallery.name + " " + nsfw}
id={gallery.name}
title={gallery.name}
tags={gallery.tags}
columns={gallery.columns}
showNsfw={nsfw}
subscription={gallery.tier as string}
subscriptionColor={subscriptionColor}
onSelect={selectGallery}
nsfw={gallery.nsfw}
></GalleryThumbnail>
);
})}
</div>
);
};
export default Galleries;

View File

@ -12,18 +12,11 @@ interface GalleryProps {
const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
const [isSingle, setIsSingle] = useState<boolean>(false);
const [loaded, setLoaded] = useState({})
const [selectedImage, setSelectedImage] = useState<string | null>(null);
const [images, setImages] = useState<string[]>([]);
const [galleryId, setGalleryId] = useState(id as string);
const [currentIndex, setCurrentIndex] = useState(0);
const getData = async () => {
const thumbnailResponse = await fetch('/api/galleries/' + String(galleryId) + '/images');
const thumbnailUrl = await thumbnailResponse.json() as string[];
setImages(thumbnailUrl);
}
const panZoomRef = useRef<any>(null);
const next = () => {
if (currentIndex < images.length - 1) {
@ -41,50 +34,6 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
}
}
const renderButtons = () => {
return (
<div className="z-20 bottom-10 fixed pt-4 bg-purple-900 bg-opacity-40 animate-in rounded-2xl" style={{ backdropFilter: 'blur(10px)' }}>
<div className='grid grid-cols-4 pl-4 gap-4 pr-4'>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 bg-neroshi-blue-900 hover:bg-neroshi-blue-800`}
onClick={() => close()}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
</button>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 ${!selectedImage ? 'opacity-50 cursor-not-allowed bg-gray-800' : 'bg-pink-700 hover:bg-pink-600'}`}
onClick={() => previous()}
disabled={!selectedImage}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5" />
</svg>
</button>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 ${!selectedImage ? 'opacity-50 cursor-not-allowed bg-gray-800' : 'bg-pink-700 hover:bg-pink-600'}`}
onClick={() => next()}
disabled={!selectedImage}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5" />
</svg>
</button>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 ${!selectedImage ? 'opacity-50 cursor-not-allowed bg-gray-800' : 'bg-purple-700 hover:bg-purple-600'}`}
onClick={() => selectedImage && handleDownload(selectedImage)}
disabled={!selectedImage}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m9 13.5 3 3m0 0 3-3m-3 3v-6m1.06-4.19-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z" />
</svg>
</button>
</div>
</div>
);
};
const handleDownload = (image: string) => {
const link = document.createElement('a');
link.href = image;
@ -95,6 +44,13 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
link.click();
document.body.removeChild(link);
};
const getData = async () => {
const thumbnailResponse = await fetch('/api/galleries/' + String(galleryId) + '/images');
const thumbnailUrl = await thumbnailResponse.json() as string[];
setImages(thumbnailUrl);
}
useEffect(() => {
getData();
const handleKeyDown = (event: KeyboardEvent) => {
@ -125,29 +81,15 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [selectedImage,currentIndex]);
}, [selectedImage, currentIndex]);
const handleClick = (image: string) => {
setSelectedImage(image);
setCurrentIndex(images.indexOf(image));
};
const open = () => {
if (selectedImage === null) return;
//console.log(selectedImage)
let base64Image = selectedImage.split(';base64,').pop();
if (!base64Image) return;
let blob = new Blob([Uint8Array.from(atob(base64Image), c => c.charCodeAt(0))], { type: 'image/jpeg' }); // adjust the type as needed
let url = URL.createObjectURL(blob);
window.open(url, '_blank');
}
const panZoomRef = useRef<any>(null);
const resetPanZoom = (event: any) => {
if (panZoomRef.current && event.target.id != "image-container") {
const resetPanZoom = () => {
panZoomRef.current.autoCenter();
}
};
const close = () => {
@ -158,15 +100,72 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
else {
closeMenu();
}
}
const breakpointColumnsObj = {
default: 3
};
const back_page = () => {
if (selectedImage != null) {
setSelectedImage(null);
setImages([]);
}
};
const renderButtons = () => {
return (
<div className="z-20 bottom-10 fixed text-white pt-4 bg-primary bg-opacity-90 animate-in rounded-md" style={{ backdropFilter: 'blur(10px)' }}>
<div className='grid grid-cols-5 pl-4 gap-4 pr-4'>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 bg-error hover:bg-error-light`}
onClick={() => close()}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
</button>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 ${!selectedImage ? 'opacity-50 cursor-not-allowed bg-gray-800' : 'bg-secondary hover:bg-secondary-light'}`}
onClick={() => resetPanZoom()}
disabled={!selectedImage}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M9 9V4.5M9 9H4.5M9 9 3.75 3.75M9 15v4.5M9 15H4.5M9 15l-5.25 5.25M15 9h4.5M15 9V4.5M15 9l5.25-5.25M15 15h4.5M15 15v4.5m0-4.5 5.25 5.25" />
</svg>
</button>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 ${!selectedImage ? 'opacity-50 cursor-not-allowed bg-gray-800' : 'bg-secondary hover:bg-secondary-light'}`}
onClick={() => previous()}
disabled={!selectedImage}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5" />
</svg>
</button>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 ${!selectedImage ? 'opacity-50 cursor-not-allowed bg-gray-800' : 'bg-secondary hover:bg-secondary-light'}`}
onClick={() => next()}
disabled={!selectedImage}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5" />
</svg>
</button>
<button
className={`justify-center text-center w-full animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse mb-4 py-2 px-4 rounded-lg no-underline flex items-center z-50 ${!selectedImage ? 'opacity-50 cursor-not-allowed bg-gray-800' : 'bg-success hover:bg-success-light'}`}
onClick={() => selectedImage && handleDownload(selectedImage)}
disabled={!selectedImage}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m9 13.5 3 3m0 0 3-3m-3 3v-6m1.06-4.19-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z" />
</svg>
</button>
</div>
</div>
);
};
return (
<div >
<div className="z-20"
onClick={resetPanZoom} style={{ width: selectedImage ? "100%" : "auto", height: selectedImage ? "100%" : "auto" }}>
<div className="z-20" style={{ width: selectedImage ? "100%" : "auto", height: selectedImage ? "100%" : "auto" }}>
<div className='flex justify-center items-center pt-2 pb-20'>
{renderButtons()}
</div>
@ -177,14 +176,10 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
autoCenter={true}
ref={panZoomRef}
>
{/*
<div
onClick={() => resetPanZoom()} className='w-full h-full z-10'>
</div> */}
<div id="image-container" >
<img
src={images[currentIndex]}
style={{ objectFit: "contain", maxWidth: "100%", maxHeight: "calc(100vh - 20px)", pointerEvents:"none" }}
style={{ objectFit: "contain", maxWidth: "100%", maxHeight: "calc(100vh - 20px)", pointerEvents: "none" }}
className="cursor-pointer animate-in w-full h-auto"
>
</img>
@ -201,7 +196,7 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
> <div className='flex justify-center items-center pt-2 '>
<Masonry
breakpointCols={columns}
breakpointCols={3}
className="my-masonry-grid pl-6 "
style={{ width: selectedImage ? "50%" : "100%" }}
>
@ -209,6 +204,7 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
.filter((img) => img !== selectedImage)
.map((image, index) => (
<img
key={index}
src={image}
onClick={() => handleClick(image)}
className={`animate-in animate-once animate-duration-1000 animate-ease-out animate-reverse hover:scale-105 p-2 cursor-pointer my-2 transition-all opacity-100 duration-500 ease-in-out transform`}
@ -216,8 +212,6 @@ const Gallery = ({ id, columns, closeMenu }: GalleryProps) => {
))}
</Masonry>
</div>
<>
</>
</div>
)}
</div>

View File

@ -6,28 +6,32 @@ interface GalleryThumbnailProps {
onSelect: (id: string, columns: number) => void;
title: string;
subscription: string;
subscriptionColor: string;
tags: string[];
showNsfw: boolean;
nsfw: boolean;
}
const GalleryThumbnail = ({ id, columns, onSelect, title,nsfw, subscription, tags }: GalleryThumbnailProps) => {
const GalleryThumbnail = ({ id, columns, onSelect, title, showNsfw, nsfw, subscription, subscriptionColor, tags }: GalleryThumbnailProps) => {
const [galleryId, setGalleryId] = useState<string>(id);
const [thumbnailUrl, setThumbnailUrl] = useState<string>('');
const [isLoading, setIsLoading] = useState<boolean>(true);
const [galleryCollumns, setColumns] = useState<number>(columns);
const [imageCount, setImageCount] = useState<number>(0);
const [nsfwState, setNsfw] = useState<boolean>(nsfw);
const [showNsfwState, setShowNsfw] = useState<boolean>(showNsfw);
const [subscriptionState, setSubscription] = useState<string>(subscription);
const [tagsState, setTags] = useState<string[]>(tags);
console.log(subscriptionColor)
const openGallery = () => {
onSelect(galleryId, galleryCollumns);
};
const getData = async () => {
setIsLoading(true);
const thumbnailResponse = await fetch('/api/galleries/' + title + '/thumbnail');
const thumbnailResponse = await fetch('/api/galleries/' + id + '/thumbnail?nsfw=' + showNsfwState);
const thumbnailUrl = await thumbnailResponse.text();
const imagesCountResponse = await fetch('/api/galleries/' + title + '/images/count');
const imagesCountResponse = await fetch('/api/galleries/' + id + '/images/count');
const imageCount = await imagesCountResponse.json() as number;
setImageCount(imageCount);
setThumbnailUrl(thumbnailUrl);
@ -39,12 +43,12 @@ const GalleryThumbnail = ({ id, columns, onSelect, title,nsfw, subscription, tag
}, [galleryId]);
return (
<div className="py-3 sm:max-w-xl sm:mx-auto flex-3 animate-in">
<div className="h-48 overflow-visible w-full relative hover:scale-95 rounded-3xl">
<div className=" py-3 sm:max-w-xl sm:mx-auto flex-3 animate-fade-up animate-once animate-duration-1000 animate-ease-out animate-normal animate-fill-forwards">
<div className="h-48 overflow-visible w-full relative hover:scale-95 rounded-3xl" style={{ cursor: 'pointer'}}>
{!isLoading ? (
<>
<img
className={`aspect-content rounded-3xl`}
className={`aspect-content rounded-3xl shadow-lg`}
src={thumbnailUrl}
alt=""
onClick={openGallery}
@ -55,42 +59,32 @@ const GalleryThumbnail = ({ id, columns, onSelect, title,nsfw, subscription, tag
<div className="text-white flex justify-between">
<div>
<div className="flex">
<h3 className="animate-jump-in animate-once animate-duration-500 animate-ease-out pr-4 text-lg font-bold break-words" style={{ lineHeight: '2rem', textShadow: '0 0 2px black' }}>{title}</h3>
<h3 className=" pr-4 text-lg font-bold break-words" style={{ lineHeight: '2rem', textShadow: '0 0 2px black' }}>{title}</h3>
</div>
</div>
</div>
<div className="text-white flex justify-between">
<div className="flex items-center">
<span className="bg-neroshi-blue-900 animate-jump-in animate-once animate-duration-500 animate-ease-out text-white mr-2 px-2 py-1 rounded-md text-sm flex items-center h-full">
<span className="bg-secondary text-white mr-2 px-2 py-1 rounded-md text-sm flex items-center h-full">
<span className="text-center">{imageCount}</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="pl-2 size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
</svg>
</span>
{nsfwState && (
<span className="animate-jump-in animate-once animate-duration-500 animate-ease-out bg-red-900 text-white px-2 py-1 mr-2 rounded-md text-sm h-full flex items-center">NSFW</span>
)}
{subscription === "Free" && (
<span className="animate-jump-in animate-once animate-duration-500 animate-ease-out bg-gray-900 text-white px-2 py-1 rounded-md text-sm h-full flex items-center">Free</span>
)}
{subscription === "Tier 1" && (
<span className="animate-jump-in animate-once animate-duration-500 animate-ease-out bg-purple-600 text-white px-2 py-1 rounded-md text-sm h-full flex items-center">Tier 1</span>
)}
{subscription === "Tier 2" && (
<span className="animate-jump-in animate-once animate-duration-500 animate-ease-out bg-pink-700 text-white px-2 py-1 rounded-md text-sm h-full flex items-center">Tier 2</span>
)}
{subscription === "Tier 3" && (
<span className="animate-jump-in animate-once animate-duration-500 animate-ease-out bg-fuchsia-500 text-white px-2 py-1 rounded-md text-sm h-full flex items-center">Tier 3</span>
<span className=" bg-error text-white px-2 py-1 mr-2 rounded-md text-sm h-full flex items-center">NSFW</span>
)}
<span className="text-white px-2 py-1 rounded-md text-sm h-full flex items-center" style={{ cursor: 'pointer', backgroundColor: subscriptionColor }}>Free</span>
</div>
</div>
<div className="text-white flex justify-between">
{/* <div className="text-white flex justify-between">
<div>
<div className="flex">
{tagsState.map((tag, index) => (
<span
key={index}
className={`animate-jump-in animate-once animate-duration-500 animate-delay-[${4+(index)}000ms] animate-ease-out pr-4 text-sm font-bold break-words"
className={`pr-4 text-sm font-bold break-words"
style={{ lineHeight: '2rem', textShadow: '0 0 2px black' }`}
>
{tag}
@ -98,11 +92,11 @@ const GalleryThumbnail = ({ id, columns, onSelect, title,nsfw, subscription, tag
))}
</div>
</div>
</div>
</div> */}
</div>
</>
) : (
<div className="animate-pulse bg-neroshi-blue-950 rounded-3xl" style={{ width: '20rem', height: '20rem' }}></div>
<div className="animate-pulse bg-secondary-light rounded-3xl" style={{ width: '20rem', height: '20rem' }}></div>
)}
</div>
</div>

View File

@ -0,0 +1,149 @@
import { createClient } from "@/utils/supabase/server";
import Link from "next/link";
import { redirect, useRouter } from "next/navigation";
import crypto from 'crypto';
import { headers } from "next/headers";
export default async function AuthButton() {
const supabase = createClient();
const {
data: { user },
} = await supabase.auth.getUser();
const signOut = async () => {
"use server";
const supabase = createClient();
await supabase.auth.signOut();
return redirect("/login");
};
const heads = headers()
const currentPage = heads.get('x-path')
const getGravatarUrl = () => {
if (user == null) {
return;
}
let email = user.email;
if (email != null) {
const emailHash = crypto.createHash('md5').update(email.trim().toLowerCase()).digest('hex');
return `https://www.gravatar.com/avatar/${emailHash}`;
}
return "";
}
const url = getGravatarUrl();
const admins = await supabase.from('admins').select('user_id');
let isAdmin = false;
if(!admins.error) {
for (const admin of admins.data) {
if (admin.user_id == user?.id) {
isAdmin = true;
break;
}
}
}
return (
<div className="flex justify-center items-center pt-2 ">
<nav className="w-auto bg-primary bg-opacity-40 flex justify-center z-10 h-16 animate-in rounded-md shadow-lg" style={{ backdropFilter: 'blur(10px)' }}>
<div className="w-auto flex justify-between items-center p-3 text-sm">
<div className="flex items-center gap-2 z-10">
{/* This is admin stuff */}
{(isAdmin) && (
<>
<Link
href="/gallery/admin/"
className={`py-2 px-3 w-38 text-center flex rounded-md no-underline bg-secondary hover:bg-secondary-light`}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="lg:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M11.42 15.17 17.25 21A2.652 2.652 0 0 0 21 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 1 1-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 0 0 4.486-6.336l-3.276 3.277a3.004 3.004 0 0 1-2.25-2.25l3.276-3.276a4.5 4.5 0 0 0-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437 1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008Z" />
</svg>
<span className="hidden lg:block">Gallery Admin</span>
</Link>
<Link
href="/admin/"
className={`py-2 px-3 w-38 text-center flex rounded-md no-underline bg-secondary hover:bg-secondary-light`}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="lg:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
<span className="hidden lg:block">System Settings</span>
</Link>
</>
)}
<Link
href="/gallery"
className={`py-2 px-3 flex rounded-md no-underline ${currentPage!="gallery" ? 'bg-primary hover:bg-primary-light' : 'bg-secondary hover:bg-secondary-light'}`}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
</svg>
<span className="hidden lg:block">Gallery</span>
</Link>
<Link
href="/livestream"
className={`py-2 px-3 flex rounded-md no-underline ${currentPage!="livestream" ? 'bg-primary hover:bg-primary-light' : 'bg-secondary hover:bg-secondary-light'}`}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z" />
</svg>
<span className="hidden lg:block">Livestream</span>
</Link>
<Link
href="/commissions"
className={`py-2 px-3 flex rounded-md no-underline ${currentPage!="commissions" ? 'bg-primary hover:bg-primary-light' : 'bg-secondary hover:bg-secondary-light'}`}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 10.5V6a3.75 3.75 0 1 0-7.5 0v4.5m11.356-1.993 1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 0 1-1.12-1.243l1.264-12A1.125 1.125 0 0 1 5.513 7.5h12.974c.576 0 1.059.435 1.119 1.007ZM8.625 10.5a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm7.5 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
</svg>
<span className="hidden lg:block">Commissions</span>
</Link>
<Link
href="/subscriptions"
className={`py-2 px-3 flex rounded-md no-underline ${currentPage!="subscriptions" ? 'bg-primary hover:bg-primary-light' : 'bg-secondary hover:bg-secondary-light'}`}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>
<span className="hidden lg:block">Subscription</span>
</Link>
</div>
<div className="flex items-center gap-2">
{(user != null) ? (
<>
<form action={signOut}>
<button className="py-2 px-4 ml-2 rounded-md no-underline bg-error hover:bg-error-light">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden ">
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 10.5V6.75a4.5 4.5 0 1 1 9 0v3.75M3.75 21.75h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H3.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z" />
</svg>
<span className="hidden lg:block">Logout</span>
</button>
</form>
<a href="https://gravatar.com/" target="_blank">
<img src={url} alt="Profile" className="w-10 h-10 object-cover rounded-full cursor-pointer" />
</a>
</>
) : (
<Link
href="/subscriptions"
className={`ml-2 py-2 px-3 flex rounded-md no-underline bg-success hover:bg-success-light`}
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
<path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>
<span className="hidden lg:block">Login</span>
</Link>
)}
</div>
</div>
</nav>
</div>)
}

View File

@ -0,0 +1,16 @@
"use client;"
import React from 'react';
const RightHandLayoutImage: React.FC = () => {
return (
<div className="fixed w-full h-full overflow-hidden z-0 animate-fade-left animate-once animate-duration-[2000ms] animate-normal animate-fill-forwards">
<img
src="/gallery_girl.png"
className="float-right object-cover h-screen w-full lg:w-5/6 xl:w-3/6 opacity-50 overflow-hidden"
alt="Background"
/>
</div>
);
};
export default RightHandLayoutImage;

View File

@ -0,0 +1,60 @@
"use client;"
import React, { useState, useEffect } from 'react';
import SearchInput from '@/components/neroshitron/search_input';
import Galleries from './galleries';
interface SearchProps {
gallerySelected: (gallery: string) => void;
}
const Search = ({ gallerySelected }: SearchProps) => {
const [tags, setTags] = useState<string[]>([]);
const [search, setSearch] = useState<string>('');
const [nsfw, setNsfw] = useState<boolean>(false);
const [gallery, setGallery] = useState<string | null>(null);
const getData = async () => {
}
useEffect(() => {
getData();
}, [search]);
useEffect(() => {
getData();
}, [nsfw]);
useEffect(() => {
getData();
}, [tags]);
useEffect(() => {
getData();
if (gallery != null)
gallerySelected(gallery);
}, [gallery]);
//TRY TESTING WITH THIS REMOVED!
useEffect(() => {
getData();
}, []);
return (
<>
<Galleries gallerySelected={(gallery: string) => { setGallery(gallery) }} key={search + "-" + tags.length + "-" + nsfw} search={search} nsfw={nsfw} tags={tags} />
<section className="fixed flex items-center w-full p-8 pt-20 opacity-90 animate-in animate-once animate-duration-500">
<div className="container mx-auto py-8">
<SearchInput
startingTags={[]}
placeholderTags={[
{ value: "neroshi", label: "🧑‍🎨 neroshi" },
{ value: "neroshi", label: "❗️ click here for tags to search!" },
]} nsfwButtonEnabled={true} searchChanged={(search) => { setSearch(search) }} nsfwChanged={(nsfw) => { setNsfw(nsfw) }} tagsChanged={(tags) => { setTags(tags); }} />
</div>
</section>
</>
);
};
export default Search;

View File

@ -0,0 +1,190 @@
"use client;"
import React, { useState, useEffect, useRef, forwardRef } from 'react';
import TagSelector from '../neroshitron/tag_selector';
import Select from "react-tailwindcss-select";
import { SelectValue } from 'react-tailwindcss-select/dist/components/type';
import { Option } from 'react-tailwindcss-select/dist/components/type';
interface SearchInputProps {
tagsChanged: (tags: string[]) => void;
searchChanged: (search: string) => void;
nsfwChanged: (nsfw: boolean) => void;
nsfwButtonEnabled: boolean | null;
placeholderTags: Option[];
startingTags: string[] | null;
}
const SearchInput = ({ tagsChanged, searchChanged, nsfwChanged, nsfwButtonEnabled, placeholderTags, startingTags }: SearchInputProps) => {
const [tagSearch, setTagSearch] = useState<string>('');
const [nsfw, setNsfw] = useState<boolean>(false);
const [selectedTags, setSelectedTags] = useState<string[]>(startingTags ?? []);
const [selectedTagsInput, setSelectedTagsInput] = useState<Option[]>([...placeholderTags, ...(startingTags ?? []).map((tag) => ({ value: tag, label: tag }))]);
const [selectingTags, setSelectingTags] = useState<boolean>(false);
const tagSelectorRef = React.useRef(null);
const [tags, setTags] = useState<any[]>([]);
const getData = async () => {
const tagsResponse = await fetch(`/api/galleries/tags`);
const tagsData = await tagsResponse.json();
setTags(tagsData);
}
const updateTags = (newTags: string[]) => {
setSelectedTags(newTags)
}
const onTagsClosed = (tags: string[]) => {
setSelectingTags(false);
}
const openTags = () => {
setSelectingTags(true);
if (selectingTags) {
onTagsClosed(selectedTags);
}
}
useEffect(() => {
tagsChanged(selectedTags.filter(tag => tag != "neroshi"));
}, [selectedTags]);
useEffect(() => {
nsfwChanged(nsfw);
}, [nsfw]);
useEffect(() => {
getData();
}, []);
const [color, setColor] = useState('black');
const selectRef = useRef(null);
const [currentTag, setCurrentTag] = useState<string>('');
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'ArrowUp') {
const currentIndex = tags.findIndex(tag => tag.name === currentTag);
const newIndex = currentIndex === 0 ? tags.length - 1 : currentIndex - 1;
setCurrentTag(tags[newIndex].name);
} else if (event.key === 'ArrowDown') {
const currentIndex = tags.findIndex(tag => tag.name === currentTag);
const newIndex = currentIndex === tags.length - 1 ? 0 : currentIndex + 1;
setCurrentTag(tags[newIndex].name);
} else if (event.key === 'Enter') {
const currentIndex = tags.findIndex(tag => tag.name === currentTag);
if (currentIndex !== -1 && !selectedTags.includes(tags[currentIndex].name)) {
setSelectedTags([...selectedTags, tags[currentIndex].name]);
const tagsInput = selectedTagsInput;
tagsInput.push({ value: tags[currentIndex].name, label: tags[currentIndex].name });
setSelectedTagsInput(tagsInput);
setCurrentTag('');
}
}
};
window.addEventListener('keydown', handleKeyDown);
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [currentTag, tags]);
const tagOptions = tags.map((tag: { name: string; }) => ({ value: tag.name, label: tag.name }));
return (
<>
<div className={` opacity 0 relative w-full flex flex-col items-center justify-center z-10`}>
<div className="search-box mx-auto my-auto w-full">
<div className={`flex flex-row`}>
{(selectingTags) ? (
<>
<input autoFocus value={tagSearch} onChange={(e) => setTagSearch(e.target.value)} className="rounded-l-md h-16 bg-gray-100 text-grey-darker py-2 font-normal text-grey-darkest border border-gray-100 font-bold w-full py-1 px-2 outline-none text-lg text-gray-600" type="text" placeholder="Looking for specific tag?" />
<span className="flex items-center bg-gray-100 rounded rounded-l-none border-0 px-3 font-bold text-grey-100">
<button key="back" onClick={() => { openTags() }} type="button" className={`animate-in bg-pink-900 hover:bg-pink-800 text-lg text-white font-bold py-3 px-6 rounded`}>
Back
</button>
</span>
</>
)
: (
<>
<div className="w-full top-0">
<Select isMultiple isSearchable isClearable searchInputPlaceholder='Start typing to search tags...'
options={tagOptions}
placeholder="Select tags for your search"
onChange={(value: Option | Option[] | null) => {
if (value === null) {
setSelectedTags([]);
setSelectedTagsInput([]);
}
if (Array.isArray(value)) {
setSelectedTags(value.map((option) => option.value));
setSelectedTagsInput(value as Option[])
} else if (value) {
setSelectedTags([value.value]);
setSelectedTagsInput([value])
}
if (Array.isArray(value)) {
setSelectedTags(value.map((option) => option.value));
setSelectedTagsInput(value.filter((option) => option.value !== 'placeholder'));
} else if (value) {
setSelectedTags([value.value]);
setSelectedTagsInput([value]);
}
}}
onSearchInputChange={(value) => {
}}
classNames={{
menu: "bg-secondary-dark text-white pb-4 rounded",
searchBox: "rounded-md bg-secondary w-1/2 text-white w-full mt-2 p-2 mb-2 animate-in",
searchIcon: "hidden",
tagItem: (value) => "hover:scale-95 bg-primary-light rounded-md pl-2 p-1 m-1 flex",
tagItemText: "text-white animate-in",
closeIcon: "text-white",
tagItemIconContainer:"animate-in"
}}
formatOptionLabel={data => (
<li key={"tag-" + data.value}
className={`animate-in block transition rounded duration-200 px-2 py-2 cursor-pointer select-none truncate pt-2 bg-primary text-white ${currentTag==data.value ? "bg-primary-light" : ""} hover:bg-primary-light
}`}
>
{data.label}
</li>
)}
value={selectedTagsInput}
primaryColor={"indigo"} />
</div>
{(nsfwButtonEnabled) && (
<span className="w-1/6 border-0 font-bold text-grey-100">
<button
onClick={() => { setNsfw(!nsfw) }}
type="button"
className={`animate-in text-sm text-white font-bold h-full w-16 px-2 rounded rounded-l-none ${nsfw ? "bg-error hover:bg-error-light" : "bg-success hover:bg-success-light"}`}
>
{nsfw ? "NSFW" : "SFW"}
</button>
</span>
)}
</>
)}
</div>
</div>
</div>
{(selectingTags) &&
<TagSelector key={tagSearch} tagSearch={tagSearch} tagsChanged={(newTags: string[]) => { updateTags(newTags) }} selectedTagsInput={selectedTags} ref={tagSelectorRef} />}
</>
);
};
export default SearchInput;

View File

@ -0,0 +1,20 @@
"use client;"
import React, { useState, useEffect } from 'react';
interface TagProps { onTagClicked: (tag: string) => void, selected: boolean, tag: string }
const Tag = ({ onTagClicked, selected, tag, }: TagProps) => {
return (
<button
key={tag}
type="button"
className={`animate-in w-full h-8 rounded-md no-underline text-sm text-white py-1 font-medium text-center ${selected ? 'hover:bg-pink-800 bg-pink-900' : 'hover:bg-pink-600 bg-neroshi-blue-800 border-neroshi-blue-900 border-2'}`}
onClick={() => onTagClicked(tag)}
>
{tag}
</button>
);
};
export default Tag;

View File

@ -0,0 +1,61 @@
"use client;"
import React, { forwardRef, useState, useEffect } from 'react';
import Tag from './tag_pill';
interface TagSelectorProps {
tagSearch: string,
selectedTagsInput: string[],
tagsChanged: (tags: string[]) => void
}
const TagSelector = forwardRef<TagSelectorProps, { tagSearch: string, selectedTagsInput: string[], tagsChanged: (tags: string[]) => void }>((props, ref) => {
const [tags, setTags] = useState<any[]>([]);
const [tagSearch, setTagSearch] = useState<string>(props.tagSearch);
const [selectedTags, setSelectedTags] = useState<string[]>(props.selectedTagsInput);
const handleTag = (tag: string) => {
if (selectedTags.includes(tag)) {
setSelectedTags(selectedTags.filter(t => t !== tag));
} else {
setSelectedTags([...selectedTags, tag]);
}
setTags(selectedTags);
};
const getData = async () => {
const tagsResponse = await fetch(`/api/galleries/tags`);
const tagsData = await tagsResponse.json();
setTags(tagsData);
}
useEffect(() => {
props.tagsChanged(selectedTags);
getData();
}, [selectedTags, tagSearch]);
useEffect(() => {
props.tagsChanged(selectedTags);
getData();
}, [selectedTags, tagSearch]);
useEffect(() => {
getData();
}, []);
return (
<div className="flex md:w-full pt-4 justify-center items-center">
{(tags.length > 0) && (
<div className="z-10 grid p-4 grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-1 w-full max-h-96 overflow-y-scroll no-scrollbar pt-4 bg-neroshi-blue-900 rounded-md opacity-90 backdrop-filter backdrop-blur-md mx-auto">
{tags.map((tag: any) => (
(tagSearch === '' || tag.name.toLowerCase().includes(tagSearch.toLowerCase())) && // Updated condition
<Tag tag={tag.name} selected={selectedTags.includes(tag.name)} onTagClicked={(tag) => handleTag(tag)} />
))}
</div>
)}
</div>
);
});
export default TagSelector;

37
components/theme.tsx Normal file
View File

@ -0,0 +1,37 @@
"use client";
import { useEffect, useState } from 'react';
import { createClient } from '@/utils/supabase/client';
interface GalleryThumbnailProps {}
const ThemeProvider = ({}: GalleryThumbnailProps) => {
const [data, setData] = useState<any[]>([]); // State to store the fetched data
const getData = async () => {
const supabase = createClient();
const { data, error } = await supabase.from('interface_configurations').select('*');
if (error) {
console.error('Error fetching data:', error);
} else {
setData(data || []);
}
};
useEffect(() => {
getData();
}, []);
useEffect(() => {
// Update variables when data changes
for (const config of data) {
if (config.type === 'color') {
document.documentElement.style.setProperty(`--color-${config.name}`, config.value);
}
}
}, [data]);
return <></>;
};
export default ThemeProvider;

503
docs/.$diagrams.drawio.bkp Normal file
View File

@ -0,0 +1,503 @@
<mxfile host="Electron" modified="2024-06-04T04:27:05.636Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.2.5 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36" etag="x7V6P6bjO-UHE86F-Cl3" version="24.2.5" type="device">
<diagram name="Page-1" id="F3YAVjulPUqdYhbqfjdd">
<mxGraphModel dx="1877" dy="2420" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="9zziB1Dtd-V9IfowJO3V-28" value="&lt;h1&gt;Database Design&lt;/h1&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="332.5" y="-70" width="390" height="10" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-29" value="&lt;h1&gt;UX Flow&lt;/h1&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="30" y="620" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-37" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-33" target="9zziB1Dtd-V9IfowJO3V-36" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-33" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
<mxGeometry x="35" y="690" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-39" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-36" target="9zziB1Dtd-V9IfowJO3V-38" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-36" value="Open Site" style="whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="105" y="705" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-42" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-41" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-43" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-42" vertex="1" connectable="0">
<mxGeometry x="0.2533" y="2" relative="1" as="geometry">
<mxPoint x="2" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-72" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-48" vertex="1" connectable="0">
<mxGeometry x="-0.2273" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-73" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-71" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="265" y="740" />
<mxPoint x="265" y="795" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-74" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-73" vertex="1" connectable="0">
<mxGeometry x="0.0411" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-82" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-81" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="305" y="890" />
<mxPoint x="93" y="890" />
<mxPoint x="93" y="940" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-83" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-82" vertex="1" connectable="0">
<mxGeometry x="-0.8649" y="-1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-91" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-93" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-92" vertex="1" connectable="0">
<mxGeometry x="-0.6335" y="-2" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-38" value="&lt;br&gt;Logged&lt;br&gt;In" style="rhombus;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="265" y="680" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-46" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-41" target="9zziB1Dtd-V9IfowJO3V-45" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-41" value="Login/Signup Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#a20025;strokeColor=#6F0000;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="245" y="620" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-49" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-45" target="9zziB1Dtd-V9IfowJO3V-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-50" value="Click Activation&lt;br&gt;Email Link" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-49" vertex="1" connectable="0">
<mxGeometry x="0.1683" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-45" value="Send Confirmation Email" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#a20025;strokeColor=#6F0000;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="235" y="560" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-52" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-47" target="9zziB1Dtd-V9IfowJO3V-51" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="540" y="716.31" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-47" value="Gallery Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="440" y="705" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-54" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-51" target="9zziB1Dtd-V9IfowJO3V-53" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-51" value="Search By Title &amp;amp;&lt;br&gt;Filter By Tag" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="642" y="698.02" width="120" height="45" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-55" value="Refine Search" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-53" target="9zziB1Dtd-V9IfowJO3V-51" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-57" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-53" target="9zziB1Dtd-V9IfowJO3V-56" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-53" value="Browse Galleries" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="704.27" width="120" height="32.5" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-59" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-56" target="9zziB1Dtd-V9IfowJO3V-58" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-56" value="Open Gallery" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="780.52" width="120" height="32.5" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-61" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-60" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-63" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-62" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-65" value="Directional&lt;br&gt;Buttons" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-63" vertex="1" connectable="0">
<mxGeometry x="0.1714" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-69" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-68" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="742" y="850.52" />
<mxPoint x="742" y="840.52" />
<mxPoint x="732" y="840.52" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-58" value="Enlarge Image &amp;amp;&amp;nbsp;&lt;br&gt;Pan/Zoom" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="840.52" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-60" value="Download Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="900.52" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-62" target="9zziB1Dtd-V9IfowJO3V-58" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="672" y="960.52" />
<mxPoint x="782" y="960.52" />
<mxPoint x="782" y="870.52" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-62" value="Next/Previous&lt;br&gt;Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="612" y="890.52" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-70" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-68" target="9zziB1Dtd-V9IfowJO3V-56" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="762" y="797.39" as="sourcePoint" />
<mxPoint x="792" y="796.14" as="targetPoint" />
<Array as="points">
<mxPoint x="762" y="796.52" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-68" value="Close Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="642" y="787.52" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-76" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-71" target="9zziB1Dtd-V9IfowJO3V-75" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-78" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-71" target="9zziB1Dtd-V9IfowJO3V-77" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-71" value="Livestream Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#d80073;strokeColor=#A50040;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="125" y="780" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-75" value="Watch Stream" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#d80073;strokeColor=#A50040;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="125" y="840" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-77" value="Chat" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#d80073;strokeColor=#A50040;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="12.5" y="780" width="75" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-85" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-81" target="9zziB1Dtd-V9IfowJO3V-84" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-87" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-81" target="9zziB1Dtd-V9IfowJO3V-86" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-81" value="Subscriptions Page" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="32.5" y="940" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-84" value="View Current Tier" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="32.5" y="990" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-86" target="9zziB1Dtd-V9IfowJO3V-88" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-86" value="View Available Tiers" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="187.5" y="940" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-90" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-88" target="9zziB1Dtd-V9IfowJO3V-84" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-88" value="Upgrade Tier" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="187.5" y="990" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-95" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-91" target="9zziB1Dtd-V9IfowJO3V-94" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="410" y="810" />
<mxPoint x="360" y="810" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-100" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-91" target="9zziB1Dtd-V9IfowJO3V-99" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-91" value="Commissions Page" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="350" y="770" width="120" height="27.48" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-97" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-94" target="9zziB1Dtd-V9IfowJO3V-96" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-98" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-97" vertex="1" connectable="0">
<mxGeometry x="-0.6109" relative="1" as="geometry">
<mxPoint x="20" y="2" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-105" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-94" target="9zziB1Dtd-V9IfowJO3V-110" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-106" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-105" vertex="1" connectable="0">
<mxGeometry x="-0.1779" y="-2" relative="1" as="geometry">
<mxPoint y="-2" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-94" value="Has Existing&lt;br&gt;Commission" style="rhombus;whiteSpace=wrap;html=1;rounded=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="310" y="830.52" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-101" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-96" target="9zziB1Dtd-V9IfowJO3V-99" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-96" value="View Existing&lt;br&gt;Commission Status" style="whiteSpace=wrap;html=1;rounded=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="350" y="970" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-99" value="View All Commissions" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="500" y="770" width="130" height="27.48" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-109" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-104" target="9zziB1Dtd-V9IfowJO3V-96" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="985" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-104" value="Request New&lt;br&gt;Commission" style="whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;rounded=0;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="470" y="817.52" width="120" height="39.48" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-111" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-110" target="9zziB1Dtd-V9IfowJO3V-96" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="440" y="930" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-112" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-111" vertex="1" connectable="0">
<mxGeometry x="0.0044" relative="1" as="geometry">
<mxPoint y="5" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-113" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-110" target="9zziB1Dtd-V9IfowJO3V-104" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-114" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-113" vertex="1" connectable="0">
<mxGeometry x="-0.5043" y="1" relative="1" as="geometry">
<mxPoint x="3" y="-1" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-110" value="Requests&lt;br&gt;Open" style="rhombus;whiteSpace=wrap;html=1;rounded=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="440" y="860.52" width="79.48" height="79.48" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-5" value="public.tags" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="207.5" y="440" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-6" value="name" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-5">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-9" value="public.admins" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="243" y="60" width="175" height="120" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-10" value="PK FK Unique uuid user_id" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-9">
<mxGeometry y="30" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-11" value="assigned_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-9">
<mxGeometry y="60" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-12" value="assigner_id:uuid?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-9">
<mxGeometry y="90" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-17" value="auth.users" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#0050ef;fontColor=#ffffff;strokeColor=#001DBC;" vertex="1" parent="1">
<mxGeometry x="10" y="120" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-18" value="id" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-17">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-14">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-23" value="public.tier" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#a20025;fontColor=#ffffff;strokeColor=#6F0000;" vertex="1" parent="1">
<mxGeometry x="32.5" y="290" width="140" height="120" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-24" value="PK name:text" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-23">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-25" value="price:decimal" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-23">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-26" value="stripe_product_id:string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-23">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#a20025;strokeColor=#6F0000;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-24" target="1AZqCnQGpeGdDfHHl4o8-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-34" value="public.galleries" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="497.5" y="320" width="140" height="180" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-35" value="PK string name" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-37" value="FK tier string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-38" value="string thumbnail_file" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-41" value="bool nsfw" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="120" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-39" value="text[] tags" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="150" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-42" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#a20025;strokeColor=#6F0000;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-24" target="1AZqCnQGpeGdDfHHl4o8-37">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="207.5" y="335" />
<mxPoint x="207.5" y="395" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-43" value="public.skibs" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="499.5" width="140" height="300" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-44" value="PK AI id:&amp;nbsp;int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-46" value="amount:decimal" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-49" value="user_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-50" value="request_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="120" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-51" value="accepted:bool?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="150" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-58" value="processed_date:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="180" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-52" value="payment_url:string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="210" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-57" value="paidDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="240" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-59" value="completedDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="270" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-48" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;startArrow=classic;startFill=1;fillColor=#1ba1e2;strokeColor=#006EAF;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-6" target="1AZqCnQGpeGdDfHHl4o8-39">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-56" value="No FK Relationship" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontColor=#FFFFFF;labelBackgroundColor=none;" vertex="1" connectable="0" parent="1AZqCnQGpeGdDfHHl4o8-48">
<mxGeometry x="-0.0082" y="2" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-13" value="public.user_subscriptions" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="243" y="203" width="175" height="180" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-14" value="PK FK Unique user_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="30" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-15" value="FK tier:text" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="60" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-54" value="active:bool" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="90" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-53" value="last_paid_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="120" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-47" value="start_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="150" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-55" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-49">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="197.5" y="165" />
<mxPoint x="197.5" y="30" />
<mxPoint x="447.5" y="30" />
<mxPoint x="447.5" y="105" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-60" value="public.commissions" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="697.5" y="30" width="170" height="330" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-61" value="PK AI id:&amp;nbsp;int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="30" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-62" value="amount:decimal" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="60" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-63" value="user_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="90" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-64" value="request_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="120" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-65" value="accepted:bool?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="150" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-66" value="processed_date:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="180" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-67" value="hours:number" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="210" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-70" value="pending_approval:bool false" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="240" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-68" value="paidDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="270" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-69" value="completedDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="300" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-71" value="public.comission_messages" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="957.5" y="180" width="210" height="120" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-72" value="PK AI id:int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-71">
<mxGeometry y="30" width="210" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-73" value="FK comission_id:int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-71">
<mxGeometry y="60" width="210" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-74" value="FK sender_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-71">
<mxGeometry y="90" width="210" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-79" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-63">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="197.5" y="165" />
<mxPoint x="197.5" y="30" />
<mxPoint x="447.5" y="30" />
<mxPoint x="447.5" y="-30" />
<mxPoint x="667.5" y="-30" />
<mxPoint x="667.5" y="135" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-80" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#1ba1e2;strokeColor=#006EAF;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-61" target="1AZqCnQGpeGdDfHHl4o8-73">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-81" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-74">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="197.5" y="165" />
<mxPoint x="197.5" y="30" />
<mxPoint x="447.5" y="30" />
<mxPoint x="447.5" y="-30" />
<mxPoint x="667.5" y="-30" />
<mxPoint x="667.5" y="400" />
<mxPoint x="897.5" y="400" />
<mxPoint x="897.5" y="285" />
</Array>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@ -1,107 +1,44 @@
<mxfile host="app.diagrams.net" modified="2024-05-28T00:00:21.084Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" etag="8DUvRLFdr2zWCX9JS4oW" version="24.2.5" type="device">
<mxfile host="Electron" modified="2024-06-04T04:27:06.049Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.2.5 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36" etag="nuI_NnP1br-4Uuhgp7xU" version="24.2.5" type="device">
<diagram name="Page-1" id="F3YAVjulPUqdYhbqfjdd">
<mxGraphModel dx="1314" dy="865" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<mxGraphModel dx="1877" dy="2420" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="9zziB1Dtd-V9IfowJO3V-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-1" target="9zziB1Dtd-V9IfowJO3V-20">
<mxGeometry relative="1" as="geometry" />
<mxCell id="9zziB1Dtd-V9IfowJO3V-28" value="&lt;h1&gt;Database Design&lt;/h1&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="332.5" y="-70" width="390" height="10" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-1" value="auth.users.id" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="50" y="210" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-2" value="public.galleries" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="280" y="320" width="140" height="180" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-3" value="PK string name" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-2">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-4" value="int8 columns" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-2">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-5" value="tier tier" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-2">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-6" value="bool nsfw" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-2">
<mxGeometry y="120" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-7" value="text[] tags" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-2">
<mxGeometry y="150" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-8" value="public.tags" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="50" y="440" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-9" value="name" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-8">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-9" target="9zziB1Dtd-V9IfowJO3V-7">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-13" value="Custom Type : Tier" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="50" y="260" width="140" height="150" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-14" value="Free" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-13">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-15" value="Tier 1" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-13">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-16" value="Tier 2" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-13">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-17" value="Tier 3" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-13">
<mxGeometry y="120" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1.008;entryY=0.09;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-5" target="9zziB1Dtd-V9IfowJO3V-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-19" value="public.user_subscriptions" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="280" y="180" width="160" height="90" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-20" value="FK PK user_id" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-19">
<mxGeometry y="30" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-21" value="tier tier" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-19">
<mxGeometry y="60" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.989;entryY=0.09;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=classic;startFill=1;endArrow=none;endFill=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-21" target="9zziB1Dtd-V9IfowJO3V-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-28" value="&lt;h1&gt;Database Design&lt;/h1&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="235" y="120" width="390" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-29" value="&lt;h1&gt;UX Flow&lt;/h1&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-29" value="&lt;h1&gt;UX Flow&lt;/h1&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="30" y="620" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-37" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-33" target="9zziB1Dtd-V9IfowJO3V-36">
<mxCell id="9zziB1Dtd-V9IfowJO3V-37" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-33" target="9zziB1Dtd-V9IfowJO3V-36" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-33" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-33" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
<mxGeometry x="35" y="690" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-39" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-36" target="9zziB1Dtd-V9IfowJO3V-38">
<mxCell id="9zziB1Dtd-V9IfowJO3V-39" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-36" target="9zziB1Dtd-V9IfowJO3V-38" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-36" value="Open Site" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-36" value="Open Site" style="whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="105" y="705" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-42" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-41">
<mxCell id="9zziB1Dtd-V9IfowJO3V-42" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-41" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-43" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-42">
<mxCell id="9zziB1Dtd-V9IfowJO3V-43" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-42" vertex="1" connectable="0">
<mxGeometry x="0.2533" y="2" relative="1" as="geometry">
<mxPoint x="2" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-47">
<mxCell id="9zziB1Dtd-V9IfowJO3V-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-72" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-48">
<mxCell id="9zziB1Dtd-V9IfowJO3V-72" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-48" vertex="1" connectable="0">
<mxGeometry x="-0.2273" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-73" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-71">
<mxCell id="9zziB1Dtd-V9IfowJO3V-73" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-71" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="265" y="740" />
@ -109,12 +46,12 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-74" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-73">
<mxCell id="9zziB1Dtd-V9IfowJO3V-74" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-73" vertex="1" connectable="0">
<mxGeometry x="0.0411" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-82" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-81">
<mxCell id="9zziB1Dtd-V9IfowJO3V-82" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-81" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="305" y="890" />
@ -123,80 +60,80 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-83" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-82">
<mxCell id="9zziB1Dtd-V9IfowJO3V-83" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-82" vertex="1" connectable="0">
<mxGeometry x="-0.8649" y="-1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-91">
<mxCell id="9zziB1Dtd-V9IfowJO3V-92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-38" target="9zziB1Dtd-V9IfowJO3V-91" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-93" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-92">
<mxCell id="9zziB1Dtd-V9IfowJO3V-93" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-92" vertex="1" connectable="0">
<mxGeometry x="-0.6335" y="-2" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-38" value="&lt;br&gt;Logged&lt;br&gt;In" style="rhombus;whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-38" value="&lt;br&gt;Logged&lt;br&gt;In" style="rhombus;whiteSpace=wrap;html=1;verticalAlign=top;" parent="1" vertex="1">
<mxGeometry x="265" y="680" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-46" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-41" target="9zziB1Dtd-V9IfowJO3V-45">
<mxCell id="9zziB1Dtd-V9IfowJO3V-46" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-41" target="9zziB1Dtd-V9IfowJO3V-45" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-41" value="Login/Signup Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-41" value="Login/Signup Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#a20025;strokeColor=#6F0000;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="245" y="620" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-49" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-45" target="9zziB1Dtd-V9IfowJO3V-47">
<mxCell id="9zziB1Dtd-V9IfowJO3V-49" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-45" target="9zziB1Dtd-V9IfowJO3V-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-50" value="Click Activation&lt;br&gt;Email Link" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-49">
<mxCell id="9zziB1Dtd-V9IfowJO3V-50" value="Click Activation&lt;br&gt;Email Link" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-49" vertex="1" connectable="0">
<mxGeometry x="0.1683" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-45" value="Send Confirmation Email" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-45" value="Send Confirmation Email" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#a20025;strokeColor=#6F0000;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="235" y="560" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-52" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-47" target="9zziB1Dtd-V9IfowJO3V-51">
<mxCell id="9zziB1Dtd-V9IfowJO3V-52" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-47" target="9zziB1Dtd-V9IfowJO3V-51" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="540" y="716.31" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-47" value="Gallery Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-47" value="Gallery Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="440" y="705" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-54" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-51" target="9zziB1Dtd-V9IfowJO3V-53">
<mxCell id="9zziB1Dtd-V9IfowJO3V-54" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-51" target="9zziB1Dtd-V9IfowJO3V-53" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-51" value="Search By Title &amp;amp;&lt;br&gt;Filter By Tag" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-51" value="Search By Title &amp;amp;&lt;br&gt;Filter By Tag" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="642" y="698.02" width="120" height="45" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-55" value="Refine Search" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-53" target="9zziB1Dtd-V9IfowJO3V-51">
<mxCell id="9zziB1Dtd-V9IfowJO3V-55" value="Refine Search" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-53" target="9zziB1Dtd-V9IfowJO3V-51" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-57" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-53" target="9zziB1Dtd-V9IfowJO3V-56">
<mxCell id="9zziB1Dtd-V9IfowJO3V-57" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-53" target="9zziB1Dtd-V9IfowJO3V-56" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-53" value="Browse Galleries" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-53" value="Browse Galleries" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="704.27" width="120" height="32.5" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-59" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-56" target="9zziB1Dtd-V9IfowJO3V-58">
<mxCell id="9zziB1Dtd-V9IfowJO3V-59" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-56" target="9zziB1Dtd-V9IfowJO3V-58" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-56" value="Open Gallery" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-56" value="Open Gallery" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="780.52" width="120" height="32.5" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-61" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-60">
<mxCell id="9zziB1Dtd-V9IfowJO3V-61" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-60" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-63" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-62">
<mxCell id="9zziB1Dtd-V9IfowJO3V-63" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-62" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-65" value="Directional&lt;br&gt;Buttons" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-63">
<mxCell id="9zziB1Dtd-V9IfowJO3V-65" value="Directional&lt;br&gt;Buttons" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-63" vertex="1" connectable="0">
<mxGeometry x="0.1714" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-69" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-68">
<mxCell id="9zziB1Dtd-V9IfowJO3V-69" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-58" target="9zziB1Dtd-V9IfowJO3V-68" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="742" y="850.52" />
@ -205,13 +142,13 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-58" value="Enlarge Image &amp;amp;&amp;nbsp;&lt;br&gt;Pan/Zoom" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-58" value="Enlarge Image &amp;amp;&amp;nbsp;&lt;br&gt;Pan/Zoom" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="840.52" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-60" value="Download Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-60" value="Download Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="802" y="900.52" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-62" target="9zziB1Dtd-V9IfowJO3V-58">
<mxCell id="9zziB1Dtd-V9IfowJO3V-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-62" target="9zziB1Dtd-V9IfowJO3V-58" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="672" y="960.52" />
@ -220,10 +157,10 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-62" value="Next/Previous&lt;br&gt;Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-62" value="Next/Previous&lt;br&gt;Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="612" y="890.52" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-70" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-68" target="9zziB1Dtd-V9IfowJO3V-56">
<mxCell id="9zziB1Dtd-V9IfowJO3V-70" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-68" target="9zziB1Dtd-V9IfowJO3V-56" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="762" y="797.39" as="sourcePoint" />
<mxPoint x="792" y="796.14" as="targetPoint" />
@ -232,49 +169,49 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-68" value="Close Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-68" value="Close Image" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#1ba1e2;strokeColor=#006EAF;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="642" y="787.52" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-76" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-71" target="9zziB1Dtd-V9IfowJO3V-75">
<mxCell id="9zziB1Dtd-V9IfowJO3V-76" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-71" target="9zziB1Dtd-V9IfowJO3V-75" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-78" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-71" target="9zziB1Dtd-V9IfowJO3V-77">
<mxCell id="9zziB1Dtd-V9IfowJO3V-78" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-71" target="9zziB1Dtd-V9IfowJO3V-77" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-71" value="Livestream Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-71" value="Livestream Page" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#d80073;strokeColor=#A50040;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="125" y="780" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-75" value="Watch Stream" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-75" value="Watch Stream" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#d80073;strokeColor=#A50040;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="125" y="840" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-77" value="Chat" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-77" value="Chat" style="whiteSpace=wrap;html=1;verticalAlign=top;fillColor=#d80073;strokeColor=#A50040;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="12.5" y="780" width="75" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-85" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-81" target="9zziB1Dtd-V9IfowJO3V-84">
<mxCell id="9zziB1Dtd-V9IfowJO3V-85" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-81" target="9zziB1Dtd-V9IfowJO3V-84" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-87" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-81" target="9zziB1Dtd-V9IfowJO3V-86">
<mxCell id="9zziB1Dtd-V9IfowJO3V-87" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-81" target="9zziB1Dtd-V9IfowJO3V-86" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-81" value="Subscriptions Page" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-81" value="Subscriptions Page" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="32.5" y="940" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-84" value="View Current Tier" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-84" value="View Current Tier" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="32.5" y="990" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-86" target="9zziB1Dtd-V9IfowJO3V-88">
<mxCell id="9zziB1Dtd-V9IfowJO3V-89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-86" target="9zziB1Dtd-V9IfowJO3V-88" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-86" value="View Available Tiers" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-86" value="View Available Tiers" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="187.5" y="940" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-90" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-88" target="9zziB1Dtd-V9IfowJO3V-84">
<mxCell id="9zziB1Dtd-V9IfowJO3V-90" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="9zziB1Dtd-V9IfowJO3V-88" target="9zziB1Dtd-V9IfowJO3V-84" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-88" value="Upgrade Tier" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-88" value="Upgrade Tier" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#6a00ff;strokeColor=#3700CC;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="187.5" y="990" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-95" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-91" target="9zziB1Dtd-V9IfowJO3V-94">
<mxCell id="9zziB1Dtd-V9IfowJO3V-95" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-91" target="9zziB1Dtd-V9IfowJO3V-94" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="410" y="810" />
@ -282,100 +219,282 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-100" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-91" target="9zziB1Dtd-V9IfowJO3V-99">
<mxCell id="9zziB1Dtd-V9IfowJO3V-100" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-91" target="9zziB1Dtd-V9IfowJO3V-99" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-91" value="Commissions Page" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-91" value="Commissions Page" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="350" y="770" width="120" height="27.48" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-97" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-94" target="9zziB1Dtd-V9IfowJO3V-96">
<mxCell id="9zziB1Dtd-V9IfowJO3V-97" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="9zziB1Dtd-V9IfowJO3V-94" target="9zziB1Dtd-V9IfowJO3V-96" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-98" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-97">
<mxCell id="9zziB1Dtd-V9IfowJO3V-98" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-97" vertex="1" connectable="0">
<mxGeometry x="-0.6109" relative="1" as="geometry">
<mxPoint x="20" y="2" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-105" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-94" target="9zziB1Dtd-V9IfowJO3V-110">
<mxCell id="9zziB1Dtd-V9IfowJO3V-105" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-94" target="9zziB1Dtd-V9IfowJO3V-110" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-106" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-105">
<mxCell id="9zziB1Dtd-V9IfowJO3V-106" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-105" vertex="1" connectable="0">
<mxGeometry x="-0.1779" y="-2" relative="1" as="geometry">
<mxPoint y="-2" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-94" value="Has Existing&lt;br&gt;Commission" style="rhombus;whiteSpace=wrap;html=1;rounded=0;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-94" value="Has Existing&lt;br&gt;Commission" style="rhombus;whiteSpace=wrap;html=1;rounded=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="310" y="830.52" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-101" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-96" target="9zziB1Dtd-V9IfowJO3V-99">
<mxCell id="9zziB1Dtd-V9IfowJO3V-101" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-96" target="9zziB1Dtd-V9IfowJO3V-99" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-96" value="View Existing&lt;br&gt;Commission Status" style="whiteSpace=wrap;html=1;rounded=0;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-96" value="View Existing&lt;br&gt;Commission Status" style="whiteSpace=wrap;html=1;rounded=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="350" y="970" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-99" value="View All Commissions" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-99" value="View All Commissions" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="500" y="770" width="130" height="27.48" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-109" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-104" target="9zziB1Dtd-V9IfowJO3V-96">
<mxCell id="9zziB1Dtd-V9IfowJO3V-109" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-104" target="9zziB1Dtd-V9IfowJO3V-96" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="560" y="985" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-104" value="Request New&lt;br&gt;Commission" style="whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;rounded=0;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-104" value="Request New&lt;br&gt;Commission" style="whiteSpace=wrap;html=1;fillColor=#60a917;strokeColor=#2D7600;rounded=0;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="470" y="817.52" width="120" height="39.48" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-111" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-110" target="9zziB1Dtd-V9IfowJO3V-96">
<mxCell id="9zziB1Dtd-V9IfowJO3V-111" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=1;exitDx=0;exitDy=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-110" target="9zziB1Dtd-V9IfowJO3V-96" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="440" y="930" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-112" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-111">
<mxCell id="9zziB1Dtd-V9IfowJO3V-112" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-111" vertex="1" connectable="0">
<mxGeometry x="0.0044" relative="1" as="geometry">
<mxPoint y="5" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-113" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-110" target="9zziB1Dtd-V9IfowJO3V-104">
<mxCell id="9zziB1Dtd-V9IfowJO3V-113" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9zziB1Dtd-V9IfowJO3V-110" target="9zziB1Dtd-V9IfowJO3V-104" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-114" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="9zziB1Dtd-V9IfowJO3V-113">
<mxCell id="9zziB1Dtd-V9IfowJO3V-114" value="Yes" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9zziB1Dtd-V9IfowJO3V-113" vertex="1" connectable="0">
<mxGeometry x="-0.5043" y="1" relative="1" as="geometry">
<mxPoint x="3" y="-1" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-110" value="Requests&lt;br&gt;Open" style="rhombus;whiteSpace=wrap;html=1;rounded=0;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxCell id="9zziB1Dtd-V9IfowJO3V-110" value="Requests&lt;br&gt;Open" style="rhombus;whiteSpace=wrap;html=1;rounded=0;fillColor=#60a917;strokeColor=#2D7600;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="440" y="860.52" width="79.48" height="79.48" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-115" value="galleries Supabase Bucket" style="swimlane;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="519.48" y="180" width="291" height="230" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-5" value="public.tags" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="207.5" y="440" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-116" value="image" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-115">
<mxGeometry x="160.52" y="40" width="40" height="50" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-6" value="name" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-5">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-117" value="public.galleries.name" style="sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3D;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.folder;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-115">
<mxGeometry x="40.519999999999996" y="60" width="78" height="71" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-9" value="public.admins" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="243" y="60" width="175" height="120" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-120" value="image" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-115">
<mxGeometry x="220.51999999999998" y="40" width="40" height="50" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-10" value="PK FK Unique uuid user_id" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-9">
<mxGeometry y="30" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-121" value="image" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-115">
<mxGeometry x="160.51999999999998" y="100" width="40" height="50" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-11" value="assigned_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-9">
<mxGeometry y="60" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-122" value="image" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-115">
<mxGeometry x="220.51999999999998" y="100" width="40" height="50" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-12" value="assigner_id:uuid?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-9">
<mxGeometry y="90" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-123" value="image" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-115">
<mxGeometry x="220.51999999999998" y="160" width="40" height="50" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-17" value="auth.users" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#0050ef;fontColor=#ffffff;strokeColor=#001DBC;" vertex="1" parent="1">
<mxGeometry x="10" y="120" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-124" value="image" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="9zziB1Dtd-V9IfowJO3V-115">
<mxGeometry x="160.51999999999998" y="160" width="40" height="50" as="geometry" />
<mxCell id="1AZqCnQGpeGdDfHHl4o8-18" value="id" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-17">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="9zziB1Dtd-V9IfowJO3V-118" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="9zziB1Dtd-V9IfowJO3V-3" target="9zziB1Dtd-V9IfowJO3V-117">
<mxCell id="1AZqCnQGpeGdDfHHl4o8-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-14">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-23" value="public.tier" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#a20025;fontColor=#ffffff;strokeColor=#6F0000;" vertex="1" parent="1">
<mxGeometry x="32.5" y="290" width="140" height="120" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-24" value="PK name:text" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-23">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-25" value="price:decimal" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-23">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-26" value="stripe_product_id:string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-23">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#a20025;strokeColor=#6F0000;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-24" target="1AZqCnQGpeGdDfHHl4o8-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-34" value="public.galleries" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="497.5" y="320" width="140" height="180" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-35" value="PK string name" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-37" value="FK tier string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-38" value="string thumbnail_file" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-41" value="bool nsfw" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="120" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-39" value="text[] tags" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-34">
<mxGeometry y="150" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-42" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#a20025;strokeColor=#6F0000;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-24" target="1AZqCnQGpeGdDfHHl4o8-37">
<mxGeometry relative="1" as="geometry">
<mxPoint x="620" y="320" as="targetPoint" />
<Array as="points">
<mxPoint x="207.5" y="335" />
<mxPoint x="207.5" y="395" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-43" value="public.skibs" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="499.5" width="140" height="300" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-44" value="PK AI id:&amp;nbsp;int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="30" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-46" value="amount:decimal" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="60" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-49" value="user_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="90" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-50" value="request_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="120" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-51" value="accepted:bool?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="150" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-58" value="processed_date:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="180" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-52" value="payment_url:string" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="210" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-57" value="paidDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="240" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-59" value="completedDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-43">
<mxGeometry y="270" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-48" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;startArrow=classic;startFill=1;fillColor=#1ba1e2;strokeColor=#006EAF;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-6" target="1AZqCnQGpeGdDfHHl4o8-39">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-56" value="No FK Relationship" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontColor=#FFFFFF;labelBackgroundColor=none;" vertex="1" connectable="0" parent="1AZqCnQGpeGdDfHHl4o8-48">
<mxGeometry x="-0.0082" y="2" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-13" value="public.user_subscriptions" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="243" y="203" width="175" height="180" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-14" value="PK FK Unique user_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="30" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-15" value="FK tier:text" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="60" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-54" value="active:bool" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="90" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-53" value="last_paid_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="120" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-47" value="start_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-13">
<mxGeometry y="150" width="175" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-55" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-49">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="197.5" y="165" />
<mxPoint x="197.5" y="30" />
<mxPoint x="447.5" y="30" />
<mxPoint x="447.5" y="105" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-60" value="public.commissions" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="697.5" y="30" width="170" height="330" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-61" value="PK AI id:&amp;nbsp;int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="30" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-62" value="amount:decimal" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="60" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-63" value="user_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="90" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-64" value="request_date:date" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="120" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-65" value="accepted:bool?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="150" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-66" value="processed_date:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="180" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-67" value="hours:number" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="210" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-70" value="pending_approval:bool false" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="240" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-68" value="paidDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="270" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-69" value="completedDate:date?" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-60">
<mxGeometry y="300" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-71" value="public.comission_messages" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
<mxGeometry x="957.5" y="180" width="210" height="120" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-72" value="PK AI id:int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-71">
<mxGeometry y="30" width="210" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-73" value="FK comission_id:int8" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-71">
<mxGeometry y="60" width="210" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-74" value="FK sender_id:uuid" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="1AZqCnQGpeGdDfHHl4o8-71">
<mxGeometry y="90" width="210" height="30" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-79" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-63">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="197.5" y="165" />
<mxPoint x="197.5" y="30" />
<mxPoint x="447.5" y="30" />
<mxPoint x="447.5" y="-30" />
<mxPoint x="667.5" y="-30" />
<mxPoint x="667.5" y="135" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-80" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#1ba1e2;strokeColor=#006EAF;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-61" target="1AZqCnQGpeGdDfHHl4o8-73">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="1AZqCnQGpeGdDfHHl4o8-81" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#0050ef;strokeColor=#001DBC;" edge="1" parent="1" source="1AZqCnQGpeGdDfHHl4o8-18" target="1AZqCnQGpeGdDfHHl4o8-74">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="197.5" y="165" />
<mxPoint x="197.5" y="30" />
<mxPoint x="447.5" y="30" />
<mxPoint x="447.5" y="-30" />
<mxPoint x="667.5" y="-30" />
<mxPoint x="667.5" y="400" />
<mxPoint x="897.5" y="400" />
<mxPoint x="897.5" y="285" />
</Array>
</mxGeometry>
</mxCell>
</root>

562
package-lock.json generated
View File

@ -8,6 +8,8 @@
"@supabase/ssr": "latest",
"@supabase/supabase-js": "latest",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@vercel/analytics": "^1.3.1",
"@vercel/speed-insights": "^1.0.11",
"autoprefixer": "10.4.17",
"clsx": "^2.1.1",
"framer-motion": "^11.2.6",
@ -21,6 +23,8 @@
"react-easy-panzoom": "^0.4.4",
"react-masonry-css": "^1.0.16",
"react-responsive-masonry": "^2.2.0",
"react-select": "^5.8.0",
"react-tailwindcss-select": "^1.8.5",
"sharp": "^0.33.4",
"simplex-noise": "^4.0.1",
"tailwind-merge": "^2.3.0",
@ -48,6 +52,102 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@babel/code-frame": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz",
"integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==",
"dependencies": {
"@babel/highlight": "^7.24.6",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz",
"integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==",
"dependencies": {
"@babel/types": "^7.24.6"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz",
"integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz",
"integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz",
"integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==",
"dependencies": {
"@babel/helper-validator-identifier": "^7.24.6",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/runtime": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.6.tgz",
@ -59,6 +159,19 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/types": {
"version": "7.24.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz",
"integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==",
"dependencies": {
"@babel/helper-string-parser": "^7.24.6",
"@babel/helper-validator-identifier": "^7.24.6",
"to-fast-properties": "^2.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz",
@ -68,6 +181,150 @@
"tslib": "^2.4.0"
}
},
"node_modules/@emotion/babel-plugin": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
"integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
"dependencies": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/serialize": "^1.1.2",
"babel-plugin-macros": "^3.1.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^4.0.0",
"find-root": "^1.1.0",
"source-map": "^0.5.7",
"stylis": "4.2.0"
}
},
"node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@emotion/babel-plugin/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@emotion/cache": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
"integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
"dependencies": {
"@emotion/memoize": "^0.8.1",
"@emotion/sheet": "^1.2.2",
"@emotion/utils": "^1.2.1",
"@emotion/weak-memoize": "^0.3.1",
"stylis": "4.2.0"
}
},
"node_modules/@emotion/hash": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
},
"node_modules/@emotion/memoize": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
},
"node_modules/@emotion/react": {
"version": "11.11.4",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz",
"integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==",
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.11.0",
"@emotion/cache": "^11.11.0",
"@emotion/serialize": "^1.1.3",
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
"@emotion/utils": "^1.2.1",
"@emotion/weak-memoize": "^0.3.1",
"hoist-non-react-statics": "^3.3.1"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@emotion/serialize": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz",
"integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==",
"dependencies": {
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/unitless": "^0.8.1",
"@emotion/utils": "^1.2.1",
"csstype": "^3.0.2"
}
},
"node_modules/@emotion/sheet": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
"integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
},
"node_modules/@emotion/unitless": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
},
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@emotion/utils": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
"integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
},
"node_modules/@emotion/weak-memoize": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
"integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
},
"node_modules/@floating-ui/core": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz",
"integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==",
"dependencies": {
"@floating-ui/utils": "^0.2.0"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.5",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz",
"integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==",
"dependencies": {
"@floating-ui/core": "^1.0.0",
"@floating-ui/utils": "^0.2.0"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
"integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
},
"node_modules/@fullhuman/postcss-purgecss": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.3.0.tgz",
@ -928,6 +1185,11 @@
"undici-types": "~5.26.4"
}
},
"node_modules/@types/parse-json": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
"integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="
},
"node_modules/@types/phoenix": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.4.tgz",
@ -936,14 +1198,12 @@
"node_modules/@types/prop-types": {
"version": "15.7.12",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
"dev": true
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
},
"node_modules/@types/react": {
"version": "18.2.48",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz",
"integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -959,11 +1219,18 @@
"@types/react": "*"
}
},
"node_modules/@types/react-transition-group": {
"version": "4.4.10",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz",
"integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==",
"dev": true
"integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw=="
},
"node_modules/@types/ws": {
"version": "8.5.10",
@ -973,6 +1240,60 @@
"@types/node": "*"
}
},
"node_modules/@vercel/analytics": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.3.1.tgz",
"integrity": "sha512-xhSlYgAuJ6Q4WQGkzYTLmXwhYl39sWjoMA3nHxfkvG+WdBT25c563a7QhwwKivEOZtPJXifYHR1m2ihoisbWyA==",
"dependencies": {
"server-only": "^0.0.1"
},
"peerDependencies": {
"next": ">= 13",
"react": "^18 || ^19"
},
"peerDependenciesMeta": {
"next": {
"optional": true
},
"react": {
"optional": true
}
}
},
"node_modules/@vercel/speed-insights": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@vercel/speed-insights/-/speed-insights-1.0.11.tgz",
"integrity": "sha512-l9hzSNmJvb2Yqpgd/BzpiT0J0aQDdtqxOf3Xm+iW4PICxVvhY1ef7Otdx4GXI+88dVkws57qMzXiShz19gXzSQ==",
"hasInstallScript": true,
"peerDependencies": {
"@sveltejs/kit": "^1 || ^2",
"next": ">= 13",
"react": "^18 || ^19",
"svelte": "^4",
"vue": "^3",
"vue-router": "^4"
},
"peerDependenciesMeta": {
"@sveltejs/kit": {
"optional": true
},
"next": {
"optional": true
},
"react": {
"optional": true
},
"svelte": {
"optional": true
},
"vue": {
"optional": true
},
"vue-router": {
"optional": true
}
}
},
"node_modules/acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@ -1082,6 +1403,20 @@
"postcss": "^8.1.0"
}
},
"node_modules/babel-plugin-macros": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"cosmiconfig": "^7.0.0",
"resolve": "^1.19.0"
},
"engines": {
"node": ">=10",
"npm": ">=6"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -1167,6 +1502,14 @@
"node": ">= 0.8"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@ -1338,6 +1681,11 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/convert-source-map": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
},
"node_modules/cookie": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
@ -1346,6 +1694,29 @@
"node": ">= 0.6"
}
},
"node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
"dependencies": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
"parse-json": "^5.0.0",
"path-type": "^4.0.0",
"yaml": "^1.10.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/cosmiconfig/node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"engines": {
"node": ">= 6"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -1386,8 +1757,7 @@
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"dev": true
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/defined": {
"version": "1.0.1",
@ -1431,6 +1801,15 @@
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
},
"node_modules/dom-helpers": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
"dependencies": {
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@ -1455,6 +1834,19 @@
"iconv-lite": "^0.6.2"
}
},
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dependencies": {
"is-arrayish": "^0.2.1"
}
},
"node_modules/error-ex/node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
},
"node_modules/escalade": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
@ -1516,6 +1908,11 @@
"node": ">=8"
}
},
"node_modules/find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
},
"node_modules/foreground-child": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
@ -1670,6 +2067,14 @@
"node": ">= 0.4"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/html-tags": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
@ -1693,6 +2098,21 @@
"node": ">=0.10.0"
}
},
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -1810,6 +2230,11 @@
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
},
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@ -1865,6 +2290,11 @@
"is-buffer": "~1.1.6"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -2081,6 +2511,34 @@
"wrappy": "1"
}
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dependencies": {
"callsites": "^3.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
"json-parse-even-better-errors": "^2.3.0",
"lines-and-columns": "^1.1.6"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@ -2117,6 +2575,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"engines": {
"node": ">=8"
}
},
"node_modules/picocolors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
@ -2633,6 +3099,49 @@
"resolved": "https://registry.npmjs.org/react-responsive-masonry/-/react-responsive-masonry-2.2.0.tgz",
"integrity": "sha512-IYbnfe2tWCZ3pvyTLyBWPj7uv5ZmNOULYMcAZi5a47ZLhSotOck1vkkISq6gP2qiyWdMvPfeMhjvYzUYGw9BOQ=="
},
"node_modules/react-select": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz",
"integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==",
"dependencies": {
"@babel/runtime": "^7.12.0",
"@emotion/cache": "^11.4.0",
"@emotion/react": "^11.8.1",
"@floating-ui/dom": "^1.0.1",
"@types/react-transition-group": "^4.4.0",
"memoize-one": "^6.0.0",
"prop-types": "^15.6.0",
"react-transition-group": "^4.3.0",
"use-isomorphic-layout-effect": "^1.1.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-tailwindcss-select": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/react-tailwindcss-select/-/react-tailwindcss-select-1.8.5.tgz",
"integrity": "sha512-x29IrLiqBT5FnkC9oFQReOr05tEOZHtDtZdha84nlSWcj3qD67yonKFHXIf69yc8ElFlKUxCEv0zCllN8jHBFA==",
"peerDependencies": {
"react": "^18.2.0"
}
},
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
},
"peerDependencies": {
"react": ">=16.6.0",
"react-dom": ">=16.6.0"
}
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@ -2687,6 +3196,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"engines": {
"node": ">=4"
}
},
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@ -2743,6 +3260,11 @@
"node": ">=10"
}
},
"node_modules/server-only": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
"integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="
},
"node_modules/sharp": {
"version": "0.33.4",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz",
@ -2987,6 +3509,11 @@
}
}
},
"node_modules/stylis": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
},
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
@ -3217,6 +3744,14 @@
"node": ">=0.8"
}
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"engines": {
"node": ">=4"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -3297,6 +3832,19 @@
"browserslist": ">= 4.21.0"
}
},
"node_modules/use-isomorphic-layout-effect": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View File

@ -9,6 +9,8 @@
"@supabase/ssr": "latest",
"@supabase/supabase-js": "latest",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@vercel/analytics": "^1.3.1",
"@vercel/speed-insights": "^1.0.11",
"autoprefixer": "10.4.17",
"clsx": "^2.1.1",
"framer-motion": "^11.2.6",
@ -22,6 +24,8 @@
"react-easy-panzoom": "^0.4.4",
"react-masonry-css": "^1.0.16",
"react-responsive-masonry": "^2.2.0",
"react-select": "^5.8.0",
"react-tailwindcss-select": "^1.8.5",
"sharp": "^0.33.4",
"simplex-noise": "^4.0.1",
"tailwind-merge": "^2.3.0",

View File

@ -1,20 +0,0 @@
CREATE TYPE tier AS ENUM ('Free', 'Tier 1', 'Tier 2', 'Tier 3');
CREATE TABLE tags (
name text primary key,
gallery_name text
);
CREATE TABLE user_subscriptions (
user_id uuid primary key references auth.users(id),
tier tier
);
CREATE TABLE galleries (
name text primary key,
column_number int8,
tier tier,
tags text[]
);
ALTER TABLE tags ADD FOREIGN KEY (gallery_name) REFERENCES galleries(name);

View File

@ -0,0 +1,237 @@
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
CREATE EXTENSION IF NOT EXISTS "pg_net" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "pgsodium" WITH SCHEMA "pgsodium";
COMMENT ON SCHEMA "public" IS 'standard public schema';
CREATE EXTENSION IF NOT EXISTS "pg_graphql" WITH SCHEMA "graphql";
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "pgcrypto" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "pgjwt" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "supabase_vault" WITH SCHEMA "vault";
CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA "extensions";
CREATE TYPE "public"."interface_config_option" AS ENUM (
'color',
'image'
);
ALTER TYPE "public"."interface_config_option" OWNER TO "postgres";
CREATE TYPE "public"."tier" AS ENUM (
'Free',
'Tier 1',
'Tier 2',
'Tier 3'
);
ALTER TYPE "public"."tier" OWNER TO "postgres";
SET default_tablespace = '';
SET default_table_access_method = "heap";
CREATE TABLE IF NOT EXISTS "public"."admins" (
"user_id" "uuid" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"assigner" "uuid"
);
ALTER TABLE "public"."admins" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."galleries" (
"name" "text" NOT NULL,
"column_number" bigint,
"tier" "text" DEFAULT 'Free'::"text",
"nsfw" boolean,
"tags" "text"[],
"thumbnail_file" "text" DEFAULT ''::"text"
);
ALTER TABLE "public"."galleries" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."interface_configurations" (
"name" "text" NOT NULL,
"value" "text" NOT NULL,
"type" "public"."interface_config_option" DEFAULT 'color'::"public"."interface_config_option" NOT NULL
);
ALTER TABLE "public"."interface_configurations" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."tags" (
"name" "text" NOT NULL,
"gallery_name" "text"
);
ALTER TABLE "public"."tags" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."tiers" (
"name" "text" NOT NULL,
"price" double precision NOT NULL,
"color" "text" NOT NULL,
"description" "text" NOT NULL
);
ALTER TABLE "public"."tiers" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."user_subscriptions" (
"user_id" "uuid" NOT NULL,
"tier" "public"."tier"
);
ALTER TABLE "public"."user_subscriptions" OWNER TO "postgres";
ALTER TABLE ONLY "public"."admins"
ADD CONSTRAINT "admins_pkey" PRIMARY KEY ("user_id");
ALTER TABLE ONLY "public"."galleries"
ADD CONSTRAINT "galleries_pkey" PRIMARY KEY ("name");
ALTER TABLE ONLY "public"."interface_configurations"
ADD CONSTRAINT "interface_configurations_pkey" PRIMARY KEY ("name");
ALTER TABLE ONLY "public"."tags"
ADD CONSTRAINT "tags_pkey" PRIMARY KEY ("name");
ALTER TABLE ONLY "public"."tiers"
ADD CONSTRAINT "tiers_pkey" PRIMARY KEY ("name");
ALTER TABLE ONLY "public"."user_subscriptions"
ADD CONSTRAINT "user_subscriptions_pkey" PRIMARY KEY ("user_id");
ALTER TABLE ONLY "public"."admins"
ADD CONSTRAINT "admins_assigner_fkey" FOREIGN KEY ("assigner") REFERENCES "auth"."users"("id");
ALTER TABLE ONLY "public"."admins"
ADD CONSTRAINT "admins_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id");
ALTER TABLE ONLY "public"."tags"
ADD CONSTRAINT "tags_gallery_name_fkey" FOREIGN KEY ("gallery_name") REFERENCES "public"."galleries"("name");
ALTER TABLE ONLY "public"."user_subscriptions"
ADD CONSTRAINT "user_subscriptions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id");
CREATE POLICY "Enable delete for admins" ON "public"."tags" FOR DELETE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "Enable delete for users based on admins" ON "public"."galleries" FOR DELETE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "Enable insert for admins" ON "public"."tags" FOR INSERT TO "authenticated" WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "Enable insert for users based admins" ON "public"."galleries" FOR INSERT WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "Enable read access for all users" ON "public"."admins" FOR SELECT USING (true);
CREATE POLICY "Enable read access for all users" ON "public"."galleries" FOR SELECT USING (true);
CREATE POLICY "Enable read access for all users" ON "public"."interface_configurations" FOR SELECT USING (true);
CREATE POLICY "Enable read access for all users" ON "public"."tags" FOR SELECT USING (true);
CREATE POLICY "Enable read access for all users" ON "public"."tiers" FOR SELECT USING (true);
CREATE POLICY "Enable read for users based on user_id" ON "public"."user_subscriptions" FOR SELECT USING (true);
CREATE POLICY "admin insert" ON "public"."tiers" FOR INSERT WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "admin update" ON "public"."tiers" FOR UPDATE USING ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
ALTER TABLE "public"."admins" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "delete for admin" ON "public"."tiers" FOR DELETE USING ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
ALTER TABLE "public"."galleries" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."interface_configurations" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."tags" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."tiers" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "update for admin" ON "public"."galleries" FOR UPDATE USING ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
CREATE POLICY "update theme admin" ON "public"."interface_configurations" FOR UPDATE USING ((EXISTS ( SELECT 1
FROM "public"."admins"
WHERE ("admins"."user_id" = "auth"."uid"()))));
ALTER TABLE "public"."user_subscriptions" ENABLE ROW LEVEL SECURITY;
ALTER PUBLICATION "supabase_realtime" OWNER TO "postgres";
GRANT USAGE ON SCHEMA "public" TO "postgres";
GRANT USAGE ON SCHEMA "public" TO "anon";
GRANT USAGE ON SCHEMA "public" TO "authenticated";
GRANT USAGE ON SCHEMA "public" TO "service_role";
GRANT ALL ON TABLE "public"."admins" TO "anon";
GRANT ALL ON TABLE "public"."admins" TO "authenticated";
GRANT ALL ON TABLE "public"."admins" TO "service_role";
GRANT ALL ON TABLE "public"."galleries" TO "anon";
GRANT ALL ON TABLE "public"."galleries" TO "authenticated";
GRANT ALL ON TABLE "public"."galleries" TO "service_role";
GRANT ALL ON TABLE "public"."interface_configurations" TO "anon";
GRANT ALL ON TABLE "public"."interface_configurations" TO "authenticated";
GRANT ALL ON TABLE "public"."interface_configurations" TO "service_role";
GRANT ALL ON TABLE "public"."tags" TO "anon";
GRANT ALL ON TABLE "public"."tags" TO "authenticated";
GRANT ALL ON TABLE "public"."tags" TO "service_role";
GRANT ALL ON TABLE "public"."tiers" TO "anon";
GRANT ALL ON TABLE "public"."tiers" TO "authenticated";
GRANT ALL ON TABLE "public"."tiers" TO "service_role";
GRANT ALL ON TABLE "public"."user_subscriptions" TO "anon";
GRANT ALL ON TABLE "public"."user_subscriptions" TO "authenticated";
GRANT ALL ON TABLE "public"."user_subscriptions" TO "service_role";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "postgres";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "anon";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "authenticated";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "service_role";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "postgres";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "anon";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "authenticated";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "service_role";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "postgres";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "anon";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "authenticated";
ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "service_role";
RESET ALL;

View File

@ -41,7 +41,108 @@ INSERT INTO "auth"."audit_log_entries" ("instance_id", "id", "payload", "created
('00000000-0000-0000-0000-000000000000', '6f4bb32b-4690-4640-98ac-feb06384ef62', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-27 20:13:20.140291+00', ''),
('00000000-0000-0000-0000-000000000000', 'e6e8d515-e14c-48ff-8c4d-27cea84d33f3', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-27 20:13:20.140793+00', ''),
('00000000-0000-0000-0000-000000000000', 'e878d51d-2524-4796-9288-88bcf8d1982b', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-27 21:11:27.314657+00', ''),
('00000000-0000-0000-0000-000000000000', '0d3f4871-8215-4ae7-920b-c261ba7eaf11', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-27 21:11:27.315598+00', '');
('00000000-0000-0000-0000-000000000000', '0d3f4871-8215-4ae7-920b-c261ba7eaf11', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-27 21:11:27.315598+00', ''),
('00000000-0000-0000-0000-000000000000', 'f70081c9-673b-4e8e-84c6-574d4a6fc095', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-28 00:06:54.425581+00', ''),
('00000000-0000-0000-0000-000000000000', 'ff4e9892-902a-4e6f-9493-976acd87e5ad', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-28 00:06:54.426626+00', ''),
('00000000-0000-0000-0000-000000000000', '13891f74-fb79-45bd-a202-3c3846723eb3', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-28 01:11:09.34946+00', ''),
('00000000-0000-0000-0000-000000000000', '6125acd2-6bd2-4ae1-8b41-4b54b8097a64', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-05-28 01:11:09.350568+00', ''),
('00000000-0000-0000-0000-000000000000', '904b1ae0-83cb-4bce-a1b9-65f4215e0095', '{"action":"logout","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account"}', '2024-05-28 01:45:53.937368+00', ''),
('00000000-0000-0000-0000-000000000000', '16bba433-9af2-4328-b0d2-d59a9d072edb', '{"action":"user_signedup","actor_id":"e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd","actor_username":"damienostler1@gmail.com","actor_via_sso":false,"log_type":"team","traits":{"provider":"email"}}', '2024-05-28 02:01:35.369669+00', ''),
('00000000-0000-0000-0000-000000000000', 'a80de210-524f-41a2-b437-a0a68a5b0dc5', '{"action":"login","actor_id":"e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd","actor_username":"damienostler1@gmail.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-05-28 02:01:35.372417+00', ''),
('00000000-0000-0000-0000-000000000000', '56e9bcfc-28ea-4fbf-aae2-a6c611da2536', '{"action":"token_refreshed","actor_id":"e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd","actor_username":"damienostler1@gmail.com","actor_via_sso":false,"log_type":"token"}', '2024-05-28 03:03:11.47339+00', ''),
('00000000-0000-0000-0000-000000000000', 'f661df3e-4600-4254-a606-dab87b0bf241', '{"action":"token_revoked","actor_id":"e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd","actor_username":"damienostler1@gmail.com","actor_via_sso":false,"log_type":"token"}', '2024-05-28 03:03:11.474173+00', ''),
('00000000-0000-0000-0000-000000000000', 'eccb045f-3fa3-4cc4-92b5-2181ae4c684e', '{"action":"token_refreshed","actor_id":"e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd","actor_username":"damienostler1@gmail.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 01:54:12.341648+00', ''),
('00000000-0000-0000-0000-000000000000', 'bdca3f89-401a-40b5-b1bd-7b053f72f15a', '{"action":"token_revoked","actor_id":"e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd","actor_username":"damienostler1@gmail.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 01:54:12.342909+00', ''),
('00000000-0000-0000-0000-000000000000', 'a76ea115-0732-45e4-a05f-cbf9aec04dab', '{"action":"logout","actor_id":"e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd","actor_username":"damienostler1@gmail.com","actor_via_sso":false,"log_type":"account"}', '2024-06-01 01:54:44.965028+00', ''),
('00000000-0000-0000-0000-000000000000', '73e58d43-80dc-4c40-93b8-66debb2d79f2', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-01 01:54:50.928035+00', ''),
('00000000-0000-0000-0000-000000000000', 'a7b0b5b0-42d0-4970-a799-f918e320a460', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 02:52:51.499031+00', ''),
('00000000-0000-0000-0000-000000000000', 'dd70c686-fc1b-42da-8aa1-91a6d7fbcc14', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 02:52:51.50256+00', ''),
('00000000-0000-0000-0000-000000000000', '09161c6c-3f38-4405-b26e-67fe90bc0005', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 03:51:46.507091+00', ''),
('00000000-0000-0000-0000-000000000000', '7fd17052-1b4a-4178-98b8-3b16b9de930a', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 03:51:46.5081+00', ''),
('00000000-0000-0000-0000-000000000000', '727021f7-1385-43eb-9139-5c8d0984fb07', '{"action":"logout","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account"}', '2024-06-01 04:28:20.313782+00', ''),
('00000000-0000-0000-0000-000000000000', '7df2cdbc-1c84-4847-8142-90477524ee7a', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-01 04:32:18.045015+00', ''),
('00000000-0000-0000-0000-000000000000', 'abb0a2d8-d525-4612-a364-9ba3ea22eabf', '{"action":"logout","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account"}', '2024-06-01 04:32:21.789565+00', ''),
('00000000-0000-0000-0000-000000000000', '21e30d5b-7f03-459f-814d-43757cf3f8bf', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-01 04:33:07.034577+00', ''),
('00000000-0000-0000-0000-000000000000', '1d8fca22-6ef6-42eb-a1e9-659e702e0568', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 05:31:30.614051+00', ''),
('00000000-0000-0000-0000-000000000000', '3a9c811c-fad9-4739-9e2f-807a65f92ebc', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 05:31:30.614956+00', ''),
('00000000-0000-0000-0000-000000000000', '7620c8d4-9662-4c6b-b04f-8bcf5fc37cd2', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 07:21:44.28552+00', ''),
('00000000-0000-0000-0000-000000000000', '4cfcd7b6-8a95-4713-9409-317734ae7b38', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 07:21:44.286437+00', ''),
('00000000-0000-0000-0000-000000000000', '41cd74f2-8882-4e30-ae82-b743901cae3a', '{"action":"logout","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account"}', '2024-06-01 07:37:28.737433+00', ''),
('00000000-0000-0000-0000-000000000000', 'a490a17d-b47e-4820-923d-e7c8bc88efb5', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-01 07:37:35.302764+00', ''),
('00000000-0000-0000-0000-000000000000', '3c44829d-3ec7-4698-95c3-b53597422759', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 08:36:15.774+00', ''),
('00000000-0000-0000-0000-000000000000', '5b2c215f-bfd1-4b59-a782-eaac62d1c458', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 08:36:15.775505+00', ''),
('00000000-0000-0000-0000-000000000000', '0a5a278a-9fd1-4bcc-a041-66f1302ac7e6', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 09:34:29.572756+00', ''),
('00000000-0000-0000-0000-000000000000', '89b87acd-362b-4c51-8c3a-5a5e356ed8e2', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 09:34:29.573904+00', ''),
('00000000-0000-0000-0000-000000000000', '8c413fec-a827-4ede-a533-2409f855d2e0', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 10:35:29.39825+00', ''),
('00000000-0000-0000-0000-000000000000', '786f5ba3-670c-4799-8b5d-9e2536b75ca0', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 10:35:29.399482+00', ''),
('00000000-0000-0000-0000-000000000000', 'da188f51-e5c3-467c-b9c4-7e2ba8430981', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 20:10:45.655684+00', ''),
('00000000-0000-0000-0000-000000000000', 'c415ee23-3497-4445-9b18-b3698dd35e16', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 20:10:45.656475+00', ''),
('00000000-0000-0000-0000-000000000000', '4c5c4c36-a506-4c80-b467-68618dbf10db', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 22:05:34.985137+00', ''),
('00000000-0000-0000-0000-000000000000', '52eb3774-6624-4987-b357-fb07ff22e368', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-01 22:05:34.986175+00', ''),
('00000000-0000-0000-0000-000000000000', '4c493923-b97a-4ca7-ad59-801212c59692', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 03:42:48.403833+00', ''),
('00000000-0000-0000-0000-000000000000', '04114bf3-53c5-447b-bb9d-0cf0e97411ce', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 03:42:48.405516+00', ''),
('00000000-0000-0000-0000-000000000000', '59785eb8-3a22-4596-b534-c76d0aaadf9b', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 04:41:14.398806+00', ''),
('00000000-0000-0000-0000-000000000000', '1da856fa-1582-447b-a033-6dfd6e91ee5b', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 04:41:14.399986+00', ''),
('00000000-0000-0000-0000-000000000000', '3790f005-05d8-439d-a828-fb8e6a22356f', '{"action":"logout","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account"}', '2024-06-02 05:20:51.896435+00', ''),
('00000000-0000-0000-0000-000000000000', '903ece4b-635c-4fd0-9a6d-c60103328e11', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-02 05:21:03.760977+00', ''),
('00000000-0000-0000-0000-000000000000', 'ab8d42bd-c9df-4782-8cbd-14279592fe94', '{"action":"logout","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account"}', '2024-06-02 06:18:43.051255+00', ''),
('00000000-0000-0000-0000-000000000000', '008ae3d1-61c4-4456-8e70-8a2030acbbc4', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-02 07:19:23.344522+00', ''),
('00000000-0000-0000-0000-000000000000', 'bf042910-d447-4f27-bb63-fbd6b80c266f', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 08:17:36.070061+00', ''),
('00000000-0000-0000-0000-000000000000', '55f64c6a-d6bd-4dd4-8627-3c35caa6dc7e', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 08:17:36.071183+00', ''),
('00000000-0000-0000-0000-000000000000', '578dc04e-5665-410c-8c0e-bbf40b397b18', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 09:23:17.276185+00', ''),
('00000000-0000-0000-0000-000000000000', '4ccf2be5-8ecd-48ee-9400-7fef1004dc56', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 09:23:17.277357+00', ''),
('00000000-0000-0000-0000-000000000000', '824ccdf1-4dc0-4cee-8c01-ac66cdea101f', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 10:21:37.85499+00', ''),
('00000000-0000-0000-0000-000000000000', '98aa3855-f2ff-4118-9618-041c82318963', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 10:21:37.856028+00', ''),
('00000000-0000-0000-0000-000000000000', 'f1599f7e-e1c1-4861-87e5-9b8e5e9fa8f7', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 11:20:00.113655+00', ''),
('00000000-0000-0000-0000-000000000000', '84f7562d-151d-4e30-b810-70891f3a8a2b', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 11:20:00.115274+00', ''),
('00000000-0000-0000-0000-000000000000', '7451f114-d011-4552-9b21-bcf6d6df6243', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 20:49:23.877784+00', ''),
('00000000-0000-0000-0000-000000000000', '24b82857-e2fd-4732-a2e8-ac99f67fffa9', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 20:49:23.878598+00', ''),
('00000000-0000-0000-0000-000000000000', 'bf2935a0-244a-449d-925c-ca7ad6bf91d6', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 21:49:06.535623+00', ''),
('00000000-0000-0000-0000-000000000000', '88b130fb-5418-49ec-9e54-7db1df9b9353', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 21:49:06.536554+00', ''),
('00000000-0000-0000-0000-000000000000', '2aafc337-642d-4f4c-b550-b1c88b0f698a', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 22:47:33.949246+00', ''),
('00000000-0000-0000-0000-000000000000', '7b7bc3c1-3751-4e00-a08c-14b5bb3cf892', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-02 22:47:33.950537+00', ''),
('00000000-0000-0000-0000-000000000000', '7b3b5a37-ed60-4b75-84ae-0caba9254581', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-03 00:10:51.713229+00', ''),
('00000000-0000-0000-0000-000000000000', 'd984ff2d-6d96-43d9-9a39-703de7400fd1', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 01:10:47.663131+00', ''),
('00000000-0000-0000-0000-000000000000', 'e996a172-f818-489a-84b3-8dc8b8a1068b', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 01:10:47.663668+00', ''),
('00000000-0000-0000-0000-000000000000', '0f07359e-4c78-40a7-8711-4127dc74c0fb', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 02:08:53.524332+00', ''),
('00000000-0000-0000-0000-000000000000', 'b8f1d6e8-4e3f-473c-b0be-98f4540da6f3', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 02:08:53.525533+00', ''),
('00000000-0000-0000-0000-000000000000', '1043d8ee-0301-46e0-a451-2bb043fe6634', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 03:07:09.462821+00', ''),
('00000000-0000-0000-0000-000000000000', '6924eb3a-0588-46ff-94dc-b45f29a06e74', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 03:07:09.463674+00', ''),
('00000000-0000-0000-0000-000000000000', '3995cc04-3976-47bd-aafb-04fcf8a533db', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 04:05:10.557103+00', ''),
('00000000-0000-0000-0000-000000000000', 'd5cb3c9b-aa2d-4ca6-9067-4c31ecbb7827', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 04:05:10.558474+00', ''),
('00000000-0000-0000-0000-000000000000', '8c7ca4b6-0b87-4704-9508-8cdfaac13c65', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 05:04:07.678559+00', ''),
('00000000-0000-0000-0000-000000000000', '7a1eb770-9f3c-4ac2-a13a-fafe80704bef', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 05:04:07.679535+00', ''),
('00000000-0000-0000-0000-000000000000', 'c4c2ae8b-62eb-4dde-8023-bb4a52fd8402', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 06:02:18.158106+00', ''),
('00000000-0000-0000-0000-000000000000', 'f3deb712-a27b-4652-b3dc-bb782188943c', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-03 06:02:18.159666+00', ''),
('00000000-0000-0000-0000-000000000000', 'db502a30-3a84-4151-8c02-7be7eba0f8d1', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-04 00:29:24.732764+00', ''),
('00000000-0000-0000-0000-000000000000', 'a24f4f60-00aa-48eb-8318-ed131fd44b2e', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-04 00:29:24.734165+00', ''),
('00000000-0000-0000-0000-000000000000', 'f1d4e360-3355-4850-9f9e-64961bb1cadf', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-04 01:27:58.415574+00', ''),
('00000000-0000-0000-0000-000000000000', '45e4135f-e65c-4011-bd07-c6a5bcb33860', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-04 01:27:58.416715+00', ''),
('00000000-0000-0000-0000-000000000000', '95c4b03d-1f15-4ad9-83c1-79f079407908', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-04 02:26:28.440011+00', ''),
('00000000-0000-0000-0000-000000000000', '9b5db737-976a-459f-8f12-eed61184218d', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-04 02:26:28.441438+00', ''),
('00000000-0000-0000-0000-000000000000', '2bbe5699-d14f-4c3f-9c87-52b7f01ed087', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-05 00:52:31.052995+00', ''),
('00000000-0000-0000-0000-000000000000', 'b54ff1b9-6254-43d2-a210-b5d9d2701974', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-05 00:52:31.055077+00', ''),
('00000000-0000-0000-0000-000000000000', 'b0611a51-8bb8-4fab-937e-68a413e02b5e', '{"action":"logout","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account"}', '2024-06-05 01:03:30.844197+00', ''),
('00000000-0000-0000-0000-000000000000', '57f72aa6-2609-4efe-bf06-950681c975f9', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-05 01:03:39.551264+00', ''),
('00000000-0000-0000-0000-000000000000', '3e6b6d3e-c8bd-4cd6-a7ac-b55c59269df1', '{"action":"login","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"account","traits":{"provider":"email"}}', '2024-06-05 01:06:08.194567+00', ''),
('00000000-0000-0000-0000-000000000000', '59805a05-bfba-4dbe-8021-8db6d6b71a4e', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-05 02:02:22.65237+00', ''),
('00000000-0000-0000-0000-000000000000', 'eaf050ba-9bdc-4771-8dcb-1534c38d68b9', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-05 02:02:22.653268+00', ''),
('00000000-0000-0000-0000-000000000000', 'a326a1f9-92f7-472c-bbb7-f10c6f3c1dff', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-05 03:00:26.781265+00', ''),
('00000000-0000-0000-0000-000000000000', '473362fc-dc06-43d5-99df-065c9e671347', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-05 03:00:26.782565+00', ''),
('00000000-0000-0000-0000-000000000000', '3a82cdde-76bf-4cc4-a5e2-b818601100a1', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-07 23:35:28.284863+00', ''),
('00000000-0000-0000-0000-000000000000', 'c3ecf585-5984-4b7e-8115-f57523a31e23', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-07 23:35:28.285858+00', ''),
('00000000-0000-0000-0000-000000000000', 'cc3425df-b1e8-4e7b-8729-80e66eae2b27', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 00:33:56.442635+00', ''),
('00000000-0000-0000-0000-000000000000', 'd991bd91-d600-457c-a887-67a3be188c83', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 00:33:56.44418+00', ''),
('00000000-0000-0000-0000-000000000000', 'a8bd8737-8115-4643-b9a7-f288be170b28', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 02:07:59.069381+00', ''),
('00000000-0000-0000-0000-000000000000', '495056f7-149e-43b3-bc58-1712e3787215', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 02:07:59.070256+00', ''),
('00000000-0000-0000-0000-000000000000', '27ca0341-280d-474a-a3da-39fa4c69748e', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 03:06:06.149018+00', ''),
('00000000-0000-0000-0000-000000000000', 'aa06c3b0-cd66-440a-a184-d44795552f11', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 03:06:06.15067+00', ''),
('00000000-0000-0000-0000-000000000000', '398046e7-2dc1-49e0-92ad-4823c0001271', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 04:04:06.664163+00', ''),
('00000000-0000-0000-0000-000000000000', 'eb481c2d-2f96-4efa-84cb-e715ee547913', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 04:04:06.665465+00', ''),
('00000000-0000-0000-0000-000000000000', '088f4537-0025-44e9-a499-dc85d7034ed3', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 22:08:31.582227+00', ''),
('00000000-0000-0000-0000-000000000000', '7f476998-602e-4d2e-9129-92ea021b1d50', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 22:08:31.583859+00', ''),
('00000000-0000-0000-0000-000000000000', '1c9bf13b-7ecf-4432-a83e-8dcd95eeb6c9', '{"action":"token_refreshed","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 23:06:38.987497+00', ''),
('00000000-0000-0000-0000-000000000000', '07c85a08-4a4b-4238-ac4c-047350db4b7f', '{"action":"token_revoked","actor_id":"893c7701-d5df-4415-80bd-1ec089764400","actor_username":"damienostler1@outlook.com","actor_via_sso":false,"log_type":"token"}', '2024-06-08 23:06:38.988275+00', '');
--
@ -55,8 +156,8 @@ INSERT INTO "auth"."audit_log_entries" ("instance_id", "id", "payload", "created
--
INSERT INTO "auth"."users" ("instance_id", "id", "aud", "role", "email", "encrypted_password", "email_confirmed_at", "invited_at", "confirmation_token", "confirmation_sent_at", "recovery_token", "recovery_sent_at", "email_change_token_new", "email_change", "email_change_sent_at", "last_sign_in_at", "raw_app_meta_data", "raw_user_meta_data", "is_super_admin", "created_at", "updated_at", "phone", "phone_confirmed_at", "phone_change", "phone_change_token", "phone_change_sent_at", "email_change_token_current", "email_change_confirm_status", "banned_until", "reauthentication_token", "reauthentication_sent_at", "is_sso_user", "deleted_at", "is_anonymous") VALUES
('00000000-0000-0000-0000-000000000000', 'e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd', 'authenticated', 'authenticated', 'damienostler1@gmail.com', '', NULL, '2024-05-27 15:44:27.171961+00', 'dd81fbfd6a7ad5d261d7f98fb37620afb3f954f350dacd2cac9f4b56', '2024-05-27 15:44:27.171961+00', '', NULL, '', '', NULL, NULL, '{"provider": "email", "providers": ["email"]}', '{}', NULL, '2024-05-27 15:44:27.167772+00', '2024-05-27 15:44:27.174941+00', NULL, NULL, '', '', NULL, '', 0, NULL, '', NULL, false, NULL, false),
('00000000-0000-0000-0000-000000000000', '893c7701-d5df-4415-80bd-1ec089764400', 'authenticated', 'authenticated', 'damienostler1@outlook.com', '$2a$10$ISYdoWsKL7gxfRz7c5IKDOTsmcjNpGgg9OOApYLMOvtOoNTo4HGM6', '2024-05-27 14:10:29.639017+00', NULL, '', NULL, '', NULL, '', '', NULL, '2024-05-27 17:18:49.039562+00', '{"provider": "email", "providers": ["email"]}', '{"sub": "893c7701-d5df-4415-80bd-1ec089764400", "email": "damienostler1@outlook.com", "email_verified": false, "phone_verified": false}', NULL, '2024-05-27 14:10:29.634157+00', '2024-05-27 21:11:27.317835+00', NULL, NULL, '', '', NULL, '', 0, NULL, '', NULL, false, NULL, false);
('00000000-0000-0000-0000-000000000000', 'e11e6fda-d1fc-4b0a-bd61-80233fcb5cdd', 'authenticated', 'authenticated', 'damienostler1@gmail.com', '', '2024-05-28 02:01:35.370491+00', '2024-05-27 15:44:27.171961+00', '', '2024-05-27 15:44:27.171961+00', '', NULL, '', '', NULL, '2024-05-28 02:01:35.372861+00', '{"provider": "email", "providers": ["email"]}', '{}', NULL, '2024-05-27 15:44:27.167772+00', '2024-06-01 01:54:12.344577+00', NULL, NULL, '', '', NULL, '', 0, NULL, '', NULL, false, NULL, false),
('00000000-0000-0000-0000-000000000000', '893c7701-d5df-4415-80bd-1ec089764400', 'authenticated', 'authenticated', 'damienostler1@outlook.com', '$2a$10$ISYdoWsKL7gxfRz7c5IKDOTsmcjNpGgg9OOApYLMOvtOoNTo4HGM6', '2024-05-27 14:10:29.639017+00', NULL, '', NULL, '', NULL, '', '', NULL, '2024-06-05 01:06:08.194961+00', '{"provider": "email", "providers": ["email"]}', '{"sub": "893c7701-d5df-4415-80bd-1ec089764400", "email": "damienostler1@outlook.com", "email_verified": false, "phone_verified": false}', NULL, '2024-05-27 14:10:29.634157+00', '2024-06-08 23:06:38.990134+00', NULL, NULL, '', '', NULL, '', 0, NULL, '', NULL, false, NULL, false);
--
@ -79,7 +180,8 @@ INSERT INTO "auth"."identities" ("provider_id", "user_id", "identity_data", "pro
--
INSERT INTO "auth"."sessions" ("id", "user_id", "created_at", "updated_at", "factor_id", "aal", "not_after", "refreshed_at", "user_agent", "ip", "tag") VALUES
('ab123eaa-eab2-4fac-a018-82ee972401fd', '893c7701-d5df-4415-80bd-1ec089764400', '2024-05-27 17:18:49.039625+00', '2024-05-27 21:11:27.319339+00', NULL, 'aal1', NULL, '2024-05-27 21:11:27.319282', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', '192.168.65.1', NULL);
('88176780-1709-4810-92de-36f909e3fafb', '893c7701-d5df-4415-80bd-1ec089764400', '2024-06-05 01:06:08.19499+00', '2024-06-05 01:06:08.19499+00', NULL, 'aal1', NULL, NULL, 'node', '192.168.65.1', NULL),
('8de4dae9-a9f9-44ad-bf2a-c42356feb0e2', '893c7701-d5df-4415-80bd-1ec089764400', '2024-06-05 01:03:39.551694+00', '2024-06-08 23:06:38.991049+00', NULL, 'aal1', NULL, '2024-06-08 23:06:38.990997', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', '192.168.65.1', NULL);
--
@ -87,7 +189,8 @@ INSERT INTO "auth"."sessions" ("id", "user_id", "created_at", "updated_at", "fac
--
INSERT INTO "auth"."mfa_amr_claims" ("session_id", "created_at", "updated_at", "authentication_method", "id") VALUES
('ab123eaa-eab2-4fac-a018-82ee972401fd', '2024-05-27 17:18:49.041915+00', '2024-05-27 17:18:49.041915+00', 'password', 'be546f0f-4e91-4f94-97e1-cc15c25191be');
('8de4dae9-a9f9-44ad-bf2a-c42356feb0e2', '2024-06-05 01:03:39.553156+00', '2024-06-05 01:03:39.553156+00', 'password', '70b28b1d-9c1c-42ed-b9b6-4629b4dc6610'),
('88176780-1709-4810-92de-36f909e3fafb', '2024-06-05 01:06:08.195749+00', '2024-06-05 01:06:08.195749+00', 'password', '2d748036-15f9-49a1-ba18-a9636803f795');
--
@ -102,16 +205,28 @@ INSERT INTO "auth"."mfa_amr_claims" ("session_id", "created_at", "updated_at", "
--
-- Data for Name: one_time_tokens; Type: TABLE DATA; Schema: auth; Owner: supabase_auth_admin
--
--
-- Data for Name: refresh_tokens; Type: TABLE DATA; Schema: auth; Owner: supabase_auth_admin
--
INSERT INTO "auth"."refresh_tokens" ("instance_id", "id", "token", "user_id", "revoked", "created_at", "updated_at", "parent", "session_id") VALUES
('00000000-0000-0000-0000-000000000000', 5, 'vG2zuPl4y7OvEwgeItgotw', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-05-27 17:18:49.040453+00', '2024-05-27 18:17:16.201027+00', NULL, 'ab123eaa-eab2-4fac-a018-82ee972401fd'),
('00000000-0000-0000-0000-000000000000', 6, 'd1l7CJUy3osp97yqDTyibw', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-05-27 18:17:16.201648+00', '2024-05-27 19:15:16.232194+00', 'vG2zuPl4y7OvEwgeItgotw', 'ab123eaa-eab2-4fac-a018-82ee972401fd'),
('00000000-0000-0000-0000-000000000000', 7, 'jrCD6NCqj5WFyjkiWG6BTw', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-05-27 19:15:16.232976+00', '2024-05-27 20:13:20.141029+00', 'd1l7CJUy3osp97yqDTyibw', 'ab123eaa-eab2-4fac-a018-82ee972401fd'),
('00000000-0000-0000-0000-000000000000', 8, 'zFVkt2ATfYlYT0nzRKmX0A', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-05-27 20:13:20.141361+00', '2024-05-27 21:11:27.316138+00', 'jrCD6NCqj5WFyjkiWG6BTw', 'ab123eaa-eab2-4fac-a018-82ee972401fd'),
('00000000-0000-0000-0000-000000000000', 9, 'OWwpxx1Pg11r5r4c2ZUhaw', '893c7701-d5df-4415-80bd-1ec089764400', false, '2024-05-27 21:11:27.316818+00', '2024-05-27 21:11:27.316818+00', 'zFVkt2ATfYlYT0nzRKmX0A', 'ab123eaa-eab2-4fac-a018-82ee972401fd');
('00000000-0000-0000-0000-000000000000', 83, 'c6bYIcVnSBosWtn4QX8F6w', '893c7701-d5df-4415-80bd-1ec089764400', false, '2024-06-05 01:06:08.195296+00', '2024-06-05 01:06:08.195296+00', NULL, '88176780-1709-4810-92de-36f909e3fafb'),
('00000000-0000-0000-0000-000000000000', 82, 'vgibpWzclaC1SiIWnkWFTw', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-05 01:03:39.55241+00', '2024-06-05 02:02:22.653721+00', NULL, '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 84, 'kcsINvcmhD18guzedNei0Q', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-05 02:02:22.654159+00', '2024-06-05 03:00:26.783216+00', 'vgibpWzclaC1SiIWnkWFTw', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 85, '4eJVeDMlvmAUk20ZqwdGQA', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-05 03:00:26.784329+00', '2024-06-07 23:35:28.286039+00', 'kcsINvcmhD18guzedNei0Q', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 86, 'Nb0zuvJjDL8keK1lF1xX9Q', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-07 23:35:28.28691+00', '2024-06-08 00:33:56.445064+00', '4eJVeDMlvmAUk20ZqwdGQA', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 119, 'y9oA8pEThLtPyEJW2IK3eA', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-08 00:33:56.446127+00', '2024-06-08 02:07:59.070607+00', 'Nb0zuvJjDL8keK1lF1xX9Q', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 120, 'TwWGx47OPQs1BNtkLs9JSA', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-08 02:07:59.07107+00', '2024-06-08 03:06:06.151386+00', 'y9oA8pEThLtPyEJW2IK3eA', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 121, 'mL_eZQCxVdYq7SR-UjEJgQ', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-08 03:06:06.154686+00', '2024-06-08 04:04:06.666124+00', 'TwWGx47OPQs1BNtkLs9JSA', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 122, 'cFLCDOB1QfKd_ydDNLRmoQ', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-08 04:04:06.667264+00', '2024-06-08 22:08:31.584256+00', 'mL_eZQCxVdYq7SR-UjEJgQ', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 123, 'G5KZsQQhC6kFqd0Xht2ypg', '893c7701-d5df-4415-80bd-1ec089764400', true, '2024-06-08 22:08:31.584969+00', '2024-06-08 23:06:38.988706+00', 'cFLCDOB1QfKd_ydDNLRmoQ', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2'),
('00000000-0000-0000-0000-000000000000', 124, '4p4Q-c4t1ZH2PUvl_mcYtQ', '893c7701-d5df-4415-80bd-1ec089764400', false, '2024-06-08 23:06:38.989251+00', '2024-06-08 23:06:38.989251+00', 'G5KZsQQhC6kFqd0Xht2ypg', '8de4dae9-a9f9-44ad-bf2a-c42356feb0e2');
--
@ -144,29 +259,63 @@ INSERT INTO "auth"."refresh_tokens" ("instance_id", "id", "token", "user_id", "r
--
-- Data for Name: admins; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO "public"."admins" ("user_id", "created_at", "assigner") VALUES
('893c7701-d5df-4415-80bd-1ec089764400', '2024-06-02 21:12:58.507093+00', NULL);
--
-- Data for Name: galleries; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO "public"."galleries" ("name", "column_number", "tier", "tags", "nsfw") VALUES
('Another Test Gallery', 3, 'Free', '{Hentai}', true),
('Test Gallery', 3, 'Tier 1', '{Dojin}', true),
('More Test Gallery', 3, 'Tier 3', '{Hentai,VTuber}', true),
('Some More Testing', 3, 'Tier 2', '{Hentai,Dojin}', false),
('Even More Testing', 3, 'Free', '{VTuber}', false),
('Killa Testing Here', 3, 'Tier 1', '{VTuber,Dojin}', false),
('Popcorn Tester', 3, 'Free', '{Hentai}', true);
INSERT INTO "public"."galleries" ("name", "column_number", "tier", "nsfw", "tags", "thumbnail_file") VALUES
('Test', 3, 'Free', false, '{twatwat}', ''),
('Testsdadas', 3, 'Free', false, '{}', '');
--
-- Data for Name: interface_configurations; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO "public"."interface_configurations" ("name", "value", "type") VALUES
('primary-dark', '#100120', 'color'),
('secondary-light', '#6F5D90', 'color'),
('secondary-dark', '#2F1D50', 'color'),
('primary', '#18161d', 'color'),
('secondary', '#4F3D70', 'color'),
('primary-light', '#403260', 'color'),
('error-dark', '#5C0D0D', 'color'),
('error', '#862117', 'color'),
('success-dark', '#00A986', 'color'),
('error-light', '#C44C4C', 'color'),
('success-light', '#20E9C6', 'color'),
('success', '#00C9A6', 'color'),
('warning', '#E17558', 'color'),
('warning-light', '#E39578', 'color'),
('info-light', '#424260', 'color'),
('warning-dark', '#C15538', 'color'),
('info-dark', '#020120', 'color'),
('info', '#222140', 'color');
--
-- Data for Name: tags; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO "public"."tags" ("name") VALUES
('Hentai'),
('Dojin
'),
('VTuber');
INSERT INTO "public"."tags" ("name", "gallery_name") VALUES
('twatwat', NULL),
('', NULL);
--
-- Data for Name: tiers; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO "public"."tiers" ("name", "price", "color", "description") VALUES
('Free', 0, '#8f6eaa', 'This is a test tier.dasdasd');
--
@ -177,64 +326,11 @@ INSERT INTO "public"."user_subscriptions" ("user_id", "tier") VALUES
('893c7701-d5df-4415-80bd-1ec089764400', 'Tier 2');
--
-- Data for Name: buckets; Type: TABLE DATA; Schema: storage; Owner: supabase_storage_admin
--
INSERT INTO "storage"."buckets" ("id", "name", "owner", "created_at", "updated_at", "public", "avif_autodetection", "file_size_limit", "allowed_mime_types", "owner_id") VALUES
('galleries', 'galleries', NULL, '2024-05-27 13:06:16.360824+00', '2024-05-27 13:06:16.360824+00', false, false, NULL, NULL, NULL);
--
-- Data for Name: objects; Type: TABLE DATA; Schema: storage; Owner: supabase_storage_admin
--
INSERT INTO "storage"."objects" ("id", "bucket_id", "name", "owner", "created_at", "updated_at", "last_accessed_at", "metadata", "version", "owner_id") VALUES
('0418ff20-6b35-46a9-81f6-d220c88920c5', 'galleries', 'killa_testing_here/1.jpeg', NULL, '2024-05-27 15:26:12.014745+00', '2024-05-27 15:27:16.286533+00', '2024-05-27 15:26:12.014745+00', '{"eTag": "\"f8eaf2e06e34ad1b3e101908ab02883e\"", "size": 326461, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:27:16.278Z", "contentLength": 326461, "httpStatusCode": 200}', 'a4df5a8e-11a0-4060-8a61-65d3561c916f', NULL),
('0328f4c1-4318-4ec7-acf8-66a97544ea32', 'galleries', 'even_more_testing/1.jpeg', NULL, '2024-05-27 15:26:26.82884+00', '2024-05-27 15:27:27.502525+00', '2024-05-27 15:26:26.82884+00', '{"eTag": "\"76b9705bb529b16fc58a4bdb0b134c9b\"", "size": 552385, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:27:27.488Z", "contentLength": 552385, "httpStatusCode": 200}', 'fc9888da-be0c-4af4-b0c3-81a584fc6f54', NULL),
('25ea2051-ae55-4728-90ac-aea08467166c', 'galleries', 'test_gallery/neroshi-1-3.png', NULL, '2024-05-27 13:15:29.27921+00', '2024-05-27 14:51:41.449764+00', '2024-05-27 13:15:29.27921+00', '{"eTag": "\"2c6f2901ed88fbdd8c790a4b77d9caa8\"", "size": 156786, "mimetype": "image/png", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T14:51:41.442Z", "contentLength": 156786, "httpStatusCode": 200}', 'c9d36afc-0afe-49e3-87c9-7c1bf5b2824a', NULL),
('54527fef-4a47-48ed-b7aa-4dc10eb2a421', 'galleries', 'test_gallery/neroshi-1-2.jpeg', NULL, '2024-05-27 13:15:29.284061+00', '2024-05-27 14:51:41.458674+00', '2024-05-27 13:15:29.284061+00', '{"eTag": "\"a22ea7bfaed689b675b11428b98de42e\"", "size": 705547, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T14:51:41.442Z", "contentLength": 705547, "httpStatusCode": 200}', '3ea9ec28-b51b-45fd-a273-00d20b9b96f1', NULL),
('2e8fb8df-b9d0-49e2-9b01-7645f344869f', 'galleries', 'killa_testing_here/neroshi-1-3.png', NULL, '2024-05-27 15:26:11.996052+00', '2024-05-27 15:26:11.996052+00', '2024-05-27 15:26:11.996052+00', '{"eTag": "\"2c6f2901ed88fbdd8c790a4b77d9caa8\"", "size": 156786, "mimetype": "image/png", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:11.981Z", "contentLength": 156786, "httpStatusCode": 200}', 'a43205f1-5b04-4a87-8ce4-8d75eb17e840', NULL),
('ff5ed820-c718-441c-a169-ec63ef3afbe6', 'galleries', 'killa_testing_here/neroshi-3.jpeg', NULL, '2024-05-27 15:26:12.00853+00', '2024-05-27 15:26:12.00853+00', '2024-05-27 15:26:12.00853+00', '{"eTag": "\"7fd95d9da9f3e6c7237a94feedcfc3af\"", "size": 97841, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:11.996Z", "contentLength": 97841, "httpStatusCode": 200}', '28d3c817-2635-4214-87fa-35d65efa1481', NULL),
('058a1c46-4c20-4e3b-9ec9-56ae9abcf77a', 'galleries', 'killa_testing_here/neroshi-1-2.jpeg', NULL, '2024-05-27 15:26:12.010853+00', '2024-05-27 15:26:12.010853+00', '2024-05-27 15:26:12.010853+00', '{"eTag": "\"a22ea7bfaed689b675b11428b98de42e\"", "size": 705547, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:11.985Z", "contentLength": 705547, "httpStatusCode": 200}', '3693798c-4652-45c3-9824-13bc75fb6b6a', NULL),
('ac89d27e-a170-4c4e-8cdd-88d386be1f9b', 'galleries', 'killa_testing_here/neroshi-1.jpeg', NULL, '2024-05-27 15:26:12.01953+00', '2024-05-27 15:26:12.01953+00', '2024-05-27 15:26:12.01953+00', '{"eTag": "\"76b9705bb529b16fc58a4bdb0b134c9b\"", "size": 552385, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:12.000Z", "contentLength": 552385, "httpStatusCode": 200}', '41c5cf9a-b5e3-47e4-8273-ec2f08c46d89', NULL),
('ec56a0e1-e39e-46f3-856f-43f83c5cbc4c', 'galleries', 'even_more_testing/neroshi-1-3.png', NULL, '2024-05-27 15:26:26.810548+00', '2024-05-27 15:26:26.810548+00', '2024-05-27 15:26:26.810548+00', '{"eTag": "\"2c6f2901ed88fbdd8c790a4b77d9caa8\"", "size": 156786, "mimetype": "image/png", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:26.799Z", "contentLength": 156786, "httpStatusCode": 200}', 'e4d87895-cebf-4bf0-b390-828586868a27', NULL),
('52dc4b6a-0caf-4852-a4d0-bc7176a54972', 'galleries', 'even_more_testing/neroshi-2.jpeg', NULL, '2024-05-27 15:26:26.817193+00', '2024-05-27 15:26:26.817193+00', '2024-05-27 15:26:26.817193+00', '{"eTag": "\"f8eaf2e06e34ad1b3e101908ab02883e\"", "size": 326461, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:26.801Z", "contentLength": 326461, "httpStatusCode": 200}', 'c5363d15-0de5-4968-8bd4-9dbcccab7d93', NULL),
('f00ba7e4-8fc6-4026-9864-938ce09658b1', 'galleries', 'even_more_testing/neroshi-4-1.jpeg', NULL, '2024-05-27 15:26:26.836977+00', '2024-05-27 15:26:26.836977+00', '2024-05-27 15:26:26.836977+00', '{"eTag": "\"eac1dd9a94c71dd30f565f95d32b0c6b\"", "size": 1227804, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:26.806Z", "contentLength": 1227804, "httpStatusCode": 200}', 'c84dd01e-5615-46b4-8750-d53b79b55d7d', NULL),
('f1430361-6a4c-46e5-bb1a-c3e863ef418d', 'galleries', 'another_test_gallery/neroshi-1-3.png', NULL, '2024-05-27 15:26:37.223029+00', '2024-05-27 15:26:37.223029+00', '2024-05-27 15:26:37.223029+00', '{"eTag": "\"2c6f2901ed88fbdd8c790a4b77d9caa8\"", "size": 156786, "mimetype": "image/png", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:37.206Z", "contentLength": 156786, "httpStatusCode": 200}', '64f6e606-54a5-43a6-adf5-6abb19a14a93', NULL),
('be76aff4-3c6b-4150-89e7-d1ac2d2d5dee', 'galleries', 'killa_testing_here/neroshi-4-1.jpeg', NULL, '2024-05-27 15:26:12.032747+00', '2024-05-27 15:26:12.032747+00', '2024-05-27 15:26:12.032747+00', '{"eTag": "\"eac1dd9a94c71dd30f565f95d32b0c6b\"", "size": 1227804, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:12.001Z", "contentLength": 1227804, "httpStatusCode": 200}', 'c9dd2f8e-b541-435f-8084-cd48d21328c4', NULL),
('bb3f8f81-f4c4-4f16-a5bd-ace6ca832b5a', 'galleries', 'more_test_gallery/1.jpeg', NULL, '2024-05-27 15:26:45.962244+00', '2024-05-27 15:27:11.520157+00', '2024-05-27 15:26:45.962244+00', '{"eTag": "\"d06af35773c09ff8cc1f4a590052be28\"", "size": 456918, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:27:11.509Z", "contentLength": 456918, "httpStatusCode": 200}', '82631199-60e3-4d4a-8045-0a094decc3eb', NULL),
('ff97ab2d-31c2-48fe-bb1c-7586d1d28d9a', 'galleries', 'more_test_gallery/neroshi-1-3.png', NULL, '2024-05-27 15:26:45.935012+00', '2024-05-27 15:26:45.935012+00', '2024-05-27 15:26:45.935012+00', '{"eTag": "\"2c6f2901ed88fbdd8c790a4b77d9caa8\"", "size": 156786, "mimetype": "image/png", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:45.923Z", "contentLength": 156786, "httpStatusCode": 200}', 'c1ae3648-b56c-453a-aae4-9e7ade927f77', NULL),
('b85ae43e-e739-42d2-89b9-aeebb6274013', 'galleries', 'more_test_gallery/neroshi-1-2.jpeg', NULL, '2024-05-27 15:26:45.951778+00', '2024-05-27 15:26:45.951778+00', '2024-05-27 15:26:45.951778+00', '{"eTag": "\"a22ea7bfaed689b675b11428b98de42e\"", "size": 705547, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:45.926Z", "contentLength": 705547, "httpStatusCode": 200}', 'ab898845-f735-4f80-8ab3-9946e0c09654', NULL),
('b4c0e111-bed7-4998-9139-883f99d08011', 'galleries', 'more_test_gallery/neroshi-4-1.jpeg', NULL, '2024-05-27 15:26:45.95914+00', '2024-05-27 15:26:45.95914+00', '2024-05-27 15:26:45.95914+00', '{"eTag": "\"eac1dd9a94c71dd30f565f95d32b0c6b\"", "size": 1227804, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:45.929Z", "contentLength": 1227804, "httpStatusCode": 200}', '6009e476-2d9f-4ae1-9c84-e20c05edc098', NULL),
('be86a80f-c60c-408f-8956-50901c5decfc', 'galleries', 'even_more_testing/neroshi-3.jpeg', NULL, '2024-05-27 15:26:26.809425+00', '2024-05-27 15:26:26.809425+00', '2024-05-27 15:26:26.809425+00', '{"eTag": "\"7fd95d9da9f3e6c7237a94feedcfc3af\"", "size": 97841, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:26.799Z", "contentLength": 97841, "httpStatusCode": 200}', '31ec6434-4d98-4169-bcad-4ffbcedfadd8', NULL),
('b8ca6de4-e321-4152-98e1-61437877adaf', 'galleries', 'even_more_testing/neroshi-1-2.jpeg', NULL, '2024-05-27 15:26:26.822241+00', '2024-05-27 15:26:26.822241+00', '2024-05-27 15:26:26.822241+00', '{"eTag": "\"a22ea7bfaed689b675b11428b98de42e\"", "size": 705547, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:26.797Z", "contentLength": 705547, "httpStatusCode": 200}', '1bc18161-d98e-4006-99d4-a73dfd624c73', NULL),
('40be76ab-7733-442e-a70c-886cee49b987', 'galleries', 'another_test_gallery/1.jpeg', NULL, '2024-05-27 15:26:37.225793+00', '2024-05-27 15:27:34.666222+00', '2024-05-27 15:26:37.225793+00', '{"eTag": "\"7fd95d9da9f3e6c7237a94feedcfc3af\"", "size": 97841, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:27:34.661Z", "contentLength": 97841, "httpStatusCode": 200}', 'c2d5bdfa-6760-4dd4-a53a-382b29b6b470', NULL),
('aee6868d-46e4-4e40-9569-27b2e408af41', 'galleries', 'another_test_gallery/neroshi-4-2.jpeg', NULL, '2024-05-27 15:26:37.254185+00', '2024-05-27 15:26:37.254185+00', '2024-05-27 15:26:37.254185+00', '{"eTag": "\"d06af35773c09ff8cc1f4a590052be28\"", "size": 456918, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:37.248Z", "contentLength": 456918, "httpStatusCode": 200}', '8b5f4a89-b8f1-4e83-adb6-e30be6c570c8', NULL),
('8e77d646-62bc-4948-82d4-f481e2ada02d', 'galleries', 'popcorn_tester/neroshi-4-1.jpeg', NULL, '2024-05-27 19:59:37.966214+00', '2024-05-27 19:59:37.966214+00', '2024-05-27 19:59:37.966214+00', '{"eTag": "\"eac1dd9a94c71dd30f565f95d32b0c6b\"", "size": 1227804, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T19:59:37.946Z", "contentLength": 1227804, "httpStatusCode": 200}', 'df47d457-1f34-4eef-b37d-2eb16eae4a80', NULL),
('64e2481d-649f-4cdd-9386-eebd987eec55', 'galleries', 'popcorn_tester/neroshi-4-2.jpeg', NULL, '2024-05-27 19:59:37.969969+00', '2024-05-27 19:59:37.969969+00', '2024-05-27 19:59:37.969969+00', '{"eTag": "\"d06af35773c09ff8cc1f4a590052be28\"", "size": 456918, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T19:59:37.965Z", "contentLength": 456918, "httpStatusCode": 200}', '8dea9739-80ef-4569-8403-00d0cd2aa373', NULL),
('33ec9d63-c158-4fc5-bf0d-938537ffdbf2', 'galleries', 'even_more_testing/neroshi-4-2.jpeg', NULL, '2024-05-27 15:26:26.841264+00', '2024-05-27 15:26:26.841264+00', '2024-05-27 15:26:26.841264+00', '{"eTag": "\"d06af35773c09ff8cc1f4a590052be28\"", "size": 456918, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:26.834Z", "contentLength": 456918, "httpStatusCode": 200}', 'b99f829b-7aed-44c6-9687-aa73ac77d43d', NULL),
('af14ebc1-5768-4333-a91c-89c71635c336', 'galleries', 'popcorn_tester/neroshi-3.jpeg', NULL, '2024-05-27 19:59:37.950641+00', '2024-05-27 19:59:37.950641+00', '2024-05-27 19:59:37.950641+00', '{"eTag": "\"7fd95d9da9f3e6c7237a94feedcfc3af\"", "size": 97841, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T19:59:37.945Z", "contentLength": 97841, "httpStatusCode": 200}', '30592c80-bfca-403b-9ae8-e57bd492b87c', NULL),
('d454129e-5f63-414c-a7df-a3855b51648a', 'galleries', 'popcorn_tester/neroshi-1.jpeg', NULL, '2024-05-27 19:59:37.957116+00', '2024-05-27 19:59:37.957116+00', '2024-05-27 19:59:37.957116+00', '{"eTag": "\"76b9705bb529b16fc58a4bdb0b134c9b\"", "size": 552385, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T19:59:37.944Z", "contentLength": 552385, "httpStatusCode": 200}', 'c21dc413-6947-4ff6-8258-ff8a44c03746', NULL),
('25fdb5df-5cb1-4d6d-b882-be9003bd5c2f', 'galleries', 'more_test_gallery/neroshi-2.jpeg', NULL, '2024-05-27 15:26:45.940585+00', '2024-05-27 15:26:45.940585+00', '2024-05-27 15:26:45.940585+00', '{"eTag": "\"f8eaf2e06e34ad1b3e101908ab02883e\"", "size": 326461, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:45.927Z", "contentLength": 326461, "httpStatusCode": 200}', 'd980f193-e963-4c25-87b9-fcb88eb7fcb7', NULL),
('4c9f74e9-83ce-4058-9ad5-acb07fe409bb', 'galleries', 'more_test_gallery/neroshi-1.jpeg', NULL, '2024-05-27 15:26:45.9507+00', '2024-05-27 15:26:45.9507+00', '2024-05-27 15:26:45.9507+00', '{"eTag": "\"76b9705bb529b16fc58a4bdb0b134c9b\"", "size": 552385, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:45.929Z", "contentLength": 552385, "httpStatusCode": 200}', '0a95bd52-67af-45f7-b421-b7e1ef9b98de', NULL),
('adaf37d9-fc5c-4263-b61c-5cd564f50772', 'galleries', 'another_test_gallery/neroshi-2.jpeg', NULL, '2024-05-27 15:26:37.236201+00', '2024-05-27 15:26:37.236201+00', '2024-05-27 15:26:37.236201+00', '{"eTag": "\"f8eaf2e06e34ad1b3e101908ab02883e\"", "size": 326461, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:37.213Z", "contentLength": 326461, "httpStatusCode": 200}', '5953e3e5-a2f0-4043-b492-933487a17736', NULL),
('91e39d32-0111-4173-a43a-2ae1dd475566', 'galleries', 'popcorn_tester/neroshi-2.jpeg', NULL, '2024-05-27 19:59:37.955417+00', '2024-05-27 19:59:37.955417+00', '2024-05-27 19:59:37.955417+00', '{"eTag": "\"f8eaf2e06e34ad1b3e101908ab02883e\"", "size": 326461, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T19:59:37.946Z", "contentLength": 326461, "httpStatusCode": 200}', '6a1673e6-eb2f-4c88-81bd-e5e75c5ced52', NULL),
('168cb5fe-1deb-431a-b588-1ef0a367020d', 'galleries', 'more_test_gallery/neroshi-3.jpeg', NULL, '2024-05-27 15:26:45.9354+00', '2024-05-27 15:26:45.9354+00', '2024-05-27 15:26:45.9354+00', '{"eTag": "\"7fd95d9da9f3e6c7237a94feedcfc3af\"", "size": 97841, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:45.927Z", "contentLength": 97841, "httpStatusCode": 200}', '439d366f-ba58-4b34-bd55-f6c28902d40f', NULL),
('60294a9f-06f5-4dd1-acbc-616dba00a695', 'galleries', 'some_more_testing/neroshi-1-3.png', NULL, '2024-05-27 15:26:56.323099+00', '2024-05-27 15:26:56.323099+00', '2024-05-27 15:26:56.323099+00', '{"eTag": "\"2c6f2901ed88fbdd8c790a4b77d9caa8\"", "size": 156786, "mimetype": "image/png", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:56.312Z", "contentLength": 156786, "httpStatusCode": 200}', '135039b1-2af1-4c82-aaf3-78f9009ad1c4', NULL),
('62d04150-984f-4292-b422-f81adbbf170b', 'galleries', 'some_more_testing/neroshi-1.jpeg', NULL, '2024-05-27 15:26:56.338289+00', '2024-05-27 15:26:56.338289+00', '2024-05-27 15:26:56.338289+00', '{"eTag": "\"76b9705bb529b16fc58a4bdb0b134c9b\"", "size": 552385, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:56.317Z", "contentLength": 552385, "httpStatusCode": 200}', '7567a4f3-908b-4395-9a0a-ccecf3d4f5fe', NULL),
('b769127c-d4f3-4989-a1fc-17aa07bc50a4', 'galleries', 'some_more_testing/neroshi-4-2.jpeg', NULL, '2024-05-27 15:26:56.353941+00', '2024-05-27 15:26:56.353941+00', '2024-05-27 15:26:56.353941+00', '{"eTag": "\"d06af35773c09ff8cc1f4a590052be28\"", "size": 456918, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:56.347Z", "contentLength": 456918, "httpStatusCode": 200}', '47f7be86-2509-4172-a032-7bae7d745f29', NULL),
('02dabd39-7124-4f00-a018-23e08ae87283', 'galleries', 'another_test_gallery/neroshi-1-2.jpeg', NULL, '2024-05-27 15:26:37.241469+00', '2024-05-27 15:26:37.241469+00', '2024-05-27 15:26:37.241469+00', '{"eTag": "\"a22ea7bfaed689b675b11428b98de42e\"", "size": 705547, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:37.205Z", "contentLength": 705547, "httpStatusCode": 200}', '375de468-e8c6-42be-a40f-d3e4a1448bfb', NULL),
('c82f236c-584c-4458-be1c-ca9ff5b02e9e', 'galleries', 'popcorn_tester/neroshi-1-2.jpeg', NULL, '2024-05-27 19:59:37.956753+00', '2024-05-27 19:59:37.956753+00', '2024-05-27 19:59:37.956753+00', '{"eTag": "\"a22ea7bfaed689b675b11428b98de42e\"", "size": 705547, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T19:59:37.942Z", "contentLength": 705547, "httpStatusCode": 200}', 'd2aa1dc7-fa9f-4127-b46b-7531a204a757', NULL),
('93938f38-393b-4159-8355-e1ef678e8175', 'galleries', 'popcorn_tester/neroshi-1-3.png', NULL, '2024-05-27 19:59:37.964774+00', '2024-05-27 19:59:37.964774+00', '2024-05-27 19:59:37.964774+00', '{"eTag": "\"2c6f2901ed88fbdd8c790a4b77d9caa8\"", "size": 156786, "mimetype": "image/png", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T19:59:37.937Z", "contentLength": 156786, "httpStatusCode": 200}', 'b90067e3-e05e-4d6b-b67d-3129b4263b39', NULL),
('d7a2275f-e493-4e0d-9894-1d7a38c5249a', 'galleries', 'some_more_testing/neroshi-2.jpeg', NULL, '2024-05-27 15:26:56.330535+00', '2024-05-27 15:26:56.330535+00', '2024-05-27 15:26:56.330535+00', '{"eTag": "\"f8eaf2e06e34ad1b3e101908ab02883e\"", "size": 326461, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:56.316Z", "contentLength": 326461, "httpStatusCode": 200}', '07cb87d5-2a00-4dda-bd36-78f2e8411843', NULL),
('1b467502-3a85-4419-bde1-11283ac4f203', 'galleries', 'some_more_testing/neroshi-4-1.jpeg', NULL, '2024-05-27 15:26:56.351987+00', '2024-05-27 15:26:56.351987+00', '2024-05-27 15:26:56.351987+00', '{"eTag": "\"eac1dd9a94c71dd30f565f95d32b0c6b\"", "size": 1227804, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:56.322Z", "contentLength": 1227804, "httpStatusCode": 200}', '83885da1-827b-48a6-bcbe-5c29b2225c09', NULL),
('457cb84e-cd4e-4c37-bd67-1813e37b466a', 'galleries', 'killa_testing_here/neroshi-4-2.jpeg', NULL, '2024-05-27 15:26:12.032278+00', '2024-05-27 15:26:12.032278+00', '2024-05-27 15:26:12.032278+00', '{"eTag": "\"d06af35773c09ff8cc1f4a590052be28\"", "size": 456918, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:12.017Z", "contentLength": 456918, "httpStatusCode": 200}', '5f035b86-997e-4d08-80a2-60766ba286da', NULL),
('3ed1499b-081c-4070-856c-2113ce3477b1', 'galleries', 'some_more_testing/1.jpeg', NULL, '2024-05-27 15:26:56.325337+00', '2024-05-27 15:27:07.800292+00', '2024-05-27 15:26:56.325337+00', '{"eTag": "\"7fd95d9da9f3e6c7237a94feedcfc3af\"", "size": 97841, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:27:07.794Z", "contentLength": 97841, "httpStatusCode": 200}', '6704eff1-8d5d-4653-999f-f2d47b7efa42', NULL),
('9e140c6f-e8da-48bd-a41b-e796f59318f3', 'galleries', 'another_test_gallery/neroshi-1.jpeg', NULL, '2024-05-27 15:26:37.242454+00', '2024-05-27 15:26:37.242454+00', '2024-05-27 15:26:37.242454+00', '{"eTag": "\"76b9705bb529b16fc58a4bdb0b134c9b\"", "size": 552385, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:37.213Z", "contentLength": 552385, "httpStatusCode": 200}', '119d46fd-51b6-470f-bd4d-4568890e4764', NULL),
('1e54a73f-e44b-406c-956a-2f45a487aaae', 'galleries', 'another_test_gallery/neroshi-4-1.jpeg', NULL, '2024-05-27 15:26:37.252603+00', '2024-05-27 15:26:37.252603+00', '2024-05-27 15:26:37.252603+00', '{"eTag": "\"eac1dd9a94c71dd30f565f95d32b0c6b\"", "size": 1227804, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:37.216Z", "contentLength": 1227804, "httpStatusCode": 200}', 'f4e6e8ee-2f97-4ba5-9754-9aefa2193f64', NULL),
('f6fdeeeb-384f-412f-810b-66ea793e9eab', 'galleries', 'some_more_testing/neroshi-1-2.jpeg', NULL, '2024-05-27 15:26:56.33478+00', '2024-05-27 15:26:56.33478+00', '2024-05-27 15:26:56.33478+00', '{"eTag": "\"a22ea7bfaed689b675b11428b98de42e\"", "size": 705547, "mimetype": "image/jpeg", "cacheControl": "max-age=3600", "lastModified": "2024-05-27T15:26:56.310Z", "contentLength": 705547, "httpStatusCode": 200}', '07271b9a-b302-4f46-8701-4bfc8b157dee', NULL);
--
-- Data for Name: s3_multipart_uploads; Type: TABLE DATA; Schema: storage; Owner: supabase_storage_admin
@ -264,7 +360,7 @@ INSERT INTO "storage"."objects" ("id", "bucket_id", "name", "owner", "created_at
-- Name: refresh_tokens_id_seq; Type: SEQUENCE SET; Schema: auth; Owner: supabase_auth_admin
--
SELECT pg_catalog.setval('"auth"."refresh_tokens_id_seq"', 9, true);
SELECT pg_catalog.setval('"auth"."refresh_tokens_id_seq"', 124, true);
--
@ -274,11 +370,6 @@ SELECT pg_catalog.setval('"auth"."refresh_tokens_id_seq"', 9, true);
SELECT pg_catalog.setval('"pgsodium"."key_key_id_seq"', 1, false);
--
-- Name: hooks_id_seq; Type: SEQUENCE SET; Schema: supabase_functions; Owner: supabase_functions_admin
--
SELECT pg_catalog.setval('"supabase_functions"."hooks_id_seq"', 1, false);
--

View File

@ -3,6 +3,8 @@ module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/**/*.{js,jsx,ts,tsx}",
"./node_modules/react-tailwindcss-select/dist/index.esm.js"
],
theme: {
extend: {
@ -14,31 +16,27 @@ module.exports = {
},
aspectRatio: {}, // enable aspect-ratio plugin
textShadow: {
'pink-glow': '0 0 4px #524FFD, 0 0 4px #524FFD, 0 0 4px #524FFD, 0 0 4px #524FFD',
'purple-grey-glow': '0 0 4px #9f7aea, 0 0 15px #9f7aea, 0 0 20px #9f7aea, 0 0 25px #9f7aea',
'green-grey-glow': '0 0 4px #32CD32, 0 0 15px #32CD32, 0 0 20px #32CD32, 0 0 25px #32CD32',
// 'pink-glow': '0 0 4px #524FFD, 0 0 4px #524FFD, 0 0 4px #524FFD, 0 0 4px #524FFD',
},
colors: {
"neroshi-blue": {
50: "#EBEBFF",
100: "#D2D2FE",
200: "#A6A4FE",
300: "#7E7CFD",
400: "#524FFD",
500: "#2522FC",
600: "#0703E2",
700: "#0502AB",
800: "#03026F",
900: "#020137",
950: "#01001E"
},
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
btn: {
background: "hsl(var(--btn-background))",
"background-hover": "hsl(var(--btn-background-hover))",
},
'primary': 'var(--color-primary)',
'primary-light': 'var(--color-primary-light)',
'primary-dark': 'var(--color-primary-dark)',
'secondary': 'var(--color-secondary)',
'secondary-light': 'var(--color-secondary-light)',
'secondary-dark': 'var(--color-secondary-dark)',
'error': 'var(--color-error)',
'error-light': 'var(--color-error-light)',
'error-dark': 'var(--color-error-dark)',
'success': 'var(--color-success)',
'success-light': 'var(--color-success-light)',
'success-dark': 'var(--color-success-dark)',
'warning': 'var(--color-warning)',
'warning-light': 'var(--color-warning-light)',
'warning-dark': 'var(--color-warning-dark)',
'info': 'var(--color-info)',
'info-light': 'var(--color-info-light)',
'info-dark': 'var(--color-info-dark)',
},
},
},