M96820 commited on
Commit
fdc200a
·
unverified ·
1 Parent(s): 5db3b83

feat: add ai-comic-factory

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. ai-comic-factory/.eslintrc.json +3 -0
  2. ai-comic-factory/.gitignore +37 -0
  3. ai-comic-factory/.nvmrc +1 -0
  4. ai-comic-factory/CONTRIBUTORS.md +10 -0
  5. ai-comic-factory/Dockerfile +65 -0
  6. ai-comic-factory/LICENCE.md +170 -0
  7. ai-comic-factory/README.md +192 -0
  8. ai-comic-factory/components.json +16 -0
  9. ai-comic-factory/next.config.js +12 -0
  10. ai-comic-factory/package-lock.json +0 -0
  11. ai-comic-factory/package.json +86 -0
  12. ai-comic-factory/postcss.config.js +6 -0
  13. ai-comic-factory/public/bubble.jpg +0 -0
  14. ai-comic-factory/public/favicon.ico +0 -0
  15. ai-comic-factory/public/favicon/favicon-114-precomposed.png +0 -0
  16. ai-comic-factory/public/favicon/favicon-120-precomposed.png +0 -0
  17. ai-comic-factory/public/favicon/favicon-144-precomposed.png +0 -0
  18. ai-comic-factory/public/favicon/favicon-152-precomposed.png +0 -0
  19. ai-comic-factory/public/favicon/favicon-180-precomposed.png +0 -0
  20. ai-comic-factory/public/favicon/favicon-192.png +0 -0
  21. ai-comic-factory/public/favicon/favicon-32.png +0 -0
  22. ai-comic-factory/public/favicon/favicon-36.png +0 -0
  23. ai-comic-factory/public/favicon/favicon-48.png +0 -0
  24. ai-comic-factory/public/favicon/favicon-57.png +0 -0
  25. ai-comic-factory/public/favicon/favicon-60.png +0 -0
  26. ai-comic-factory/public/favicon/favicon-72-precomposed.png +0 -0
  27. ai-comic-factory/public/favicon/favicon-72.png +0 -0
  28. ai-comic-factory/public/favicon/favicon-76.png +0 -0
  29. ai-comic-factory/public/favicon/favicon-96.png +0 -0
  30. ai-comic-factory/public/favicon/favicon.ico +0 -0
  31. ai-comic-factory/public/favicon/index.html +133 -0
  32. ai-comic-factory/public/favicon/manifest.json +41 -0
  33. ai-comic-factory/public/icon.png +0 -0
  34. ai-comic-factory/public/layouts/layout0.jpg +0 -0
  35. ai-comic-factory/public/layouts/layout0_hd.jpg +0 -0
  36. ai-comic-factory/public/layouts/layout1.jpg +0 -0
  37. ai-comic-factory/public/layouts/layout1_hd.jpg +0 -0
  38. ai-comic-factory/public/layouts/layout2.jpg +0 -0
  39. ai-comic-factory/public/layouts/layout2_hd.jpg +0 -0
  40. ai-comic-factory/public/layouts/layout3 hd.jpg +0 -0
  41. ai-comic-factory/public/layouts/layout3.jpg +0 -0
  42. ai-comic-factory/public/layouts/layout4 hd.jpg +0 -0
  43. ai-comic-factory/public/layouts/layout4.jpg +0 -0
  44. ai-comic-factory/public/mask.png +0 -0
  45. ai-comic-factory/public/next.svg +1 -0
  46. ai-comic-factory/public/quick-and-dirty-emoji.png +0 -0
  47. ai-comic-factory/public/sign-in-with-huggingface-xl.svg +43 -0
  48. ai-comic-factory/public/vercel.svg +1 -0
  49. ai-comic-factory/src/app/engine/caption.ts +54 -0
  50. ai-comic-factory/src/app/engine/censorship.ts +184 -0
ai-comic-factory/.eslintrc.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "extends": "next/core-web-vitals"
3
+ }
ai-comic-factory/.gitignore ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.js
7
+
8
+ # testing
9
+ /coverage
10
+
11
+ # next.js
12
+ /.next/
13
+ /out/
14
+
15
+ # production
16
+ /build
17
+
18
+ # misc
19
+ .DS_Store
20
+ *.pem
21
+
22
+ # debug
23
+ npm-debug.log*
24
+ yarn-debug.log*
25
+ yarn-error.log*
26
+
27
+ # local env files
28
+ .env*.local
29
+
30
+ # vercel
31
+ .vercel
32
+
33
+ # typescript
34
+ *.tsbuildinfo
35
+ next-env.d.ts
36
+
37
+ pnpm-lock.yaml
ai-comic-factory/.nvmrc ADDED
@@ -0,0 +1 @@
 
 
1
+ v20.17.0
ai-comic-factory/CONTRIBUTORS.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ This project was developed by Julian Bilcke (@jbilcke-hf), as part of his work at Hugging Face.
2
+
3
+ ------------------------------------------
4
+
5
+ A huge thanks to external developers for their contributions!
6
+
7
+ 艾逗笔 (@idoubi):
8
+ - [feature] Added support for OpenAI: https://github.com/jbilcke-hf/ai-comic-factory/pull/6
9
+ - [bug] predict import error (use dynamic imports for the LLM provider): https://github.com/jbilcke-hf/ai-comic-factory/pull/9
10
+
ai-comic-factory/Dockerfile ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20-alpine AS base
2
+
3
+ # Install dependencies only when needed
4
+ FROM base AS deps
5
+ # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
6
+ RUN apk add --no-cache libc6-compat
7
+ WORKDIR /app
8
+
9
+ # Install dependencies based on the preferred package manager
10
+ COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
11
+ RUN \
12
+ if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
13
+ elif [ -f package-lock.json ]; then npm ci; \
14
+ elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
15
+ else echo "Lockfile not found." && exit 1; \
16
+ fi
17
+
18
+ # Uncomment the following lines if you want to use a secret at buildtime,
19
+ # for example to access your private npm packages
20
+ # RUN --mount=type=secret,id=HF_EXAMPLE_SECRET,mode=0444,required=true \
21
+ # $(cat /run/secrets/HF_EXAMPLE_SECRET)
22
+
23
+ # Rebuild the source code only when needed
24
+ FROM base AS builder
25
+ WORKDIR /app
26
+ COPY --from=deps /app/node_modules ./node_modules
27
+ COPY . .
28
+
29
+ # Next.js collects completely anonymous telemetry data about general usage.
30
+ # Learn more here: https://nextjs.org/telemetry
31
+ # Uncomment the following line in case you want to disable telemetry during the build.
32
+ # ENV NEXT_TELEMETRY_DISABLED 1
33
+
34
+ # RUN yarn build
35
+
36
+ # If you use yarn, comment out this line and use the line above
37
+ RUN npm run build
38
+
39
+ # Production image, copy all the files and run next
40
+ FROM base AS runner
41
+ WORKDIR /app
42
+
43
+ ENV NODE_ENV production
44
+ # Uncomment the following line in case you want to disable telemetry during runtime.
45
+ # ENV NEXT_TELEMETRY_DISABLED 1
46
+
47
+ RUN addgroup --system --gid 1001 nodejs
48
+ RUN adduser --system --uid 1001 nextjs
49
+
50
+ COPY --from=builder /app/public ./public
51
+
52
+ # Automatically leverage output traces to reduce image size
53
+ # https://nextjs.org/docs/advanced-features/output-file-tracing
54
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
55
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
56
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/cache ./.next/cache
57
+ # COPY --from=builder --chown=nextjs:nodejs /app/.next/cache/fetch-cache ./.next/cache/fetch-cache
58
+
59
+ USER nextjs
60
+
61
+ EXPOSE 3000
62
+
63
+ ENV PORT 3000
64
+
65
+ CMD ["node", "server.js"]
ai-comic-factory/LICENCE.md ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ ==============
3
+
4
+ _Version 2.0, January 2004_
5
+ _&lt;<http://www.apache.org/licenses/>&gt;_
6
+
7
+ ### Terms and Conditions for use, reproduction, and distribution
8
+
9
+ #### 1. Definitions
10
+
11
+ “License” shall mean the terms and conditions for use, reproduction, and
12
+ distribution as defined by Sections 1 through 9 of this document.
13
+
14
+ “Licensor” shall mean the copyright owner or entity authorized by the copyright
15
+ owner that is granting the License.
16
+
17
+ “Legal Entity” shall mean the union of the acting entity and all other entities
18
+ that control, are controlled by, or are under common control with that entity.
19
+ For the purposes of this definition, “control” means **(i)** the power, direct or
20
+ indirect, to cause the direction or management of such entity, whether by
21
+ contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or **(iii)** beneficial ownership of such entity.
23
+
24
+ “You” (or “Your”) shall mean an individual or Legal Entity exercising
25
+ permissions granted by this License.
26
+
27
+ “Source” form shall mean the preferred form for making modifications, including
28
+ but not limited to software source code, documentation source, and configuration
29
+ files.
30
+
31
+ “Object” form shall mean any form resulting from mechanical transformation or
32
+ translation of a Source form, including but not limited to compiled object code,
33
+ generated documentation, and conversions to other media types.
34
+
35
+ “Work” shall mean the work of authorship, whether in Source or Object form, made
36
+ available under the License, as indicated by a copyright notice that is included
37
+ in or attached to the work (an example is provided in the Appendix below).
38
+
39
+ “Derivative Works” shall mean any work, whether in Source or Object form, that
40
+ is based on (or derived from) the Work and for which the editorial revisions,
41
+ annotations, elaborations, or other modifications represent, as a whole, an
42
+ original work of authorship. For the purposes of this License, Derivative Works
43
+ shall not include works that remain separable from, or merely link (or bind by
44
+ name) to the interfaces of, the Work and Derivative Works thereof.
45
+
46
+ “Contribution” shall mean any work of authorship, including the original version
47
+ of the Work and any modifications or additions to that Work or Derivative Works
48
+ thereof, that is intentionally submitted to Licensor for inclusion in the Work
49
+ by the copyright owner or by an individual or Legal Entity authorized to submit
50
+ on behalf of the copyright owner. For the purposes of this definition,
51
+ “submitted” means any form of electronic, verbal, or written communication sent
52
+ to the Licensor or its representatives, including but not limited to
53
+ communication on electronic mailing lists, source code control systems, and
54
+ issue tracking systems that are managed by, or on behalf of, the Licensor for
55
+ the purpose of discussing and improving the Work, but excluding communication
56
+ that is conspicuously marked or otherwise designated in writing by the copyright
57
+ owner as “Not a Contribution.”
58
+
59
+ “Contributor” shall mean Licensor and any individual or Legal Entity on behalf
60
+ of whom a Contribution has been received by Licensor and subsequently
61
+ incorporated within the Work.
62
+
63
+ #### 2. Grant of Copyright License
64
+
65
+ Subject to the terms and conditions of this License, each Contributor hereby
66
+ grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
67
+ irrevocable copyright license to reproduce, prepare Derivative Works of,
68
+ publicly display, publicly perform, sublicense, and distribute the Work and such
69
+ Derivative Works in Source or Object form.
70
+
71
+ #### 3. Grant of Patent License
72
+
73
+ Subject to the terms and conditions of this License, each Contributor hereby
74
+ grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
75
+ irrevocable (except as stated in this section) patent license to make, have
76
+ made, use, offer to sell, sell, import, and otherwise transfer the Work, where
77
+ such license applies only to those patent claims licensable by such Contributor
78
+ that are necessarily infringed by their Contribution(s) alone or by combination
79
+ of their Contribution(s) with the Work to which such Contribution(s) was
80
+ submitted. If You institute patent litigation against any entity (including a
81
+ cross-claim or counterclaim in a lawsuit) alleging that the Work or a
82
+ Contribution incorporated within the Work constitutes direct or contributory
83
+ patent infringement, then any patent licenses granted to You under this License
84
+ for that Work shall terminate as of the date such litigation is filed.
85
+
86
+ #### 4. Redistribution
87
+
88
+ You may reproduce and distribute copies of the Work or Derivative Works thereof
89
+ in any medium, with or without modifications, and in Source or Object form,
90
+ provided that You meet the following conditions:
91
+
92
+ * **(a)** You must give any other recipients of the Work or Derivative Works a copy of
93
+ this License; and
94
+ * **(b)** You must cause any modified files to carry prominent notices stating that You
95
+ changed the files; and
96
+ * **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
97
+ all copyright, patent, trademark, and attribution notices from the Source form
98
+ of the Work, excluding those notices that do not pertain to any part of the
99
+ Derivative Works; and
100
+ * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
101
+ Derivative Works that You distribute must include a readable copy of the
102
+ attribution notices contained within such NOTICE file, excluding those notices
103
+ that do not pertain to any part of the Derivative Works, in at least one of the
104
+ following places: within a NOTICE text file distributed as part of the
105
+ Derivative Works; within the Source form or documentation, if provided along
106
+ with the Derivative Works; or, within a display generated by the Derivative
107
+ Works, if and wherever such third-party notices normally appear. The contents of
108
+ the NOTICE file are for informational purposes only and do not modify the
109
+ License. You may add Your own attribution notices within Derivative Works that
110
+ You distribute, alongside or as an addendum to the NOTICE text from the Work,
111
+ provided that such additional attribution notices cannot be construed as
112
+ modifying the License.
113
+
114
+ You may add Your own copyright statement to Your modifications and may provide
115
+ additional or different license terms and conditions for use, reproduction, or
116
+ distribution of Your modifications, or for any such Derivative Works as a whole,
117
+ provided Your use, reproduction, and distribution of the Work otherwise complies
118
+ with the conditions stated in this License.
119
+
120
+ #### 5. Submission of Contributions
121
+
122
+ Unless You explicitly state otherwise, any Contribution intentionally submitted
123
+ for inclusion in the Work by You to the Licensor shall be under the terms and
124
+ conditions of this License, without any additional terms or conditions.
125
+ Notwithstanding the above, nothing herein shall supersede or modify the terms of
126
+ any separate license agreement you may have executed with Licensor regarding
127
+ such Contributions.
128
+
129
+ #### 6. Trademarks
130
+
131
+ This License does not grant permission to use the trade names, trademarks,
132
+ service marks, or product names of the Licensor, except as required for
133
+ reasonable and customary use in describing the origin of the Work and
134
+ reproducing the content of the NOTICE file.
135
+
136
+ #### 7. Disclaimer of Warranty
137
+
138
+ Unless required by applicable law or agreed to in writing, Licensor provides the
139
+ Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
140
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
141
+ including, without limitation, any warranties or conditions of TITLE,
142
+ NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
143
+ solely responsible for determining the appropriateness of using or
144
+ redistributing the Work and assume any risks associated with Your exercise of
145
+ permissions under this License.
146
+
147
+ #### 8. Limitation of Liability
148
+
149
+ In no event and under no legal theory, whether in tort (including negligence),
150
+ contract, or otherwise, unless required by applicable law (such as deliberate
151
+ and grossly negligent acts) or agreed to in writing, shall any Contributor be
152
+ liable to You for damages, including any direct, indirect, special, incidental,
153
+ or consequential damages of any character arising as a result of this License or
154
+ out of the use or inability to use the Work (including but not limited to
155
+ damages for loss of goodwill, work stoppage, computer failure or malfunction, or
156
+ any and all other commercial damages or losses), even if such Contributor has
157
+ been advised of the possibility of such damages.
158
+
159
+ #### 9. Accepting Warranty or Additional Liability
160
+
161
+ While redistributing the Work or Derivative Works thereof, You may choose to
162
+ offer, and charge a fee for, acceptance of support, warranty, indemnity, or
163
+ other liability obligations and/or rights consistent with this License. However,
164
+ in accepting such obligations, You may act only on Your own behalf and on Your
165
+ sole responsibility, not on behalf of any other Contributor, and only if You
166
+ agree to indemnify, defend, and hold each Contributor harmless for any liability
167
+ incurred by, or claims asserted against, such Contributor by reason of your
168
+ accepting any such warranty or additional liability.
169
+
170
+ _END OF TERMS AND CONDITIONS_
ai-comic-factory/README.md ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: AI Comic Factory
3
+ emoji: 👩‍🎨
4
+ colorFrom: red
5
+ colorTo: yellow
6
+ sdk: docker
7
+ pinned: true
8
+ app_port: 3000
9
+ disable_embedding: false
10
+ short_description: Create your own AI comic with a single prompt
11
+ hf_oauth: true
12
+ hf_oauth_expiration_minutes: 43200
13
+ hf_oauth_scopes: [inference-api]
14
+ ---
15
+
16
+ # AI Comic Factory
17
+
18
+ Last release: AI Comic Factory 1.2
19
+
20
+ The AI Comic Factory will soon have an official website: [aicomicfactory.app](https://aicomicfactory.app)
21
+
22
+ For more information about my other projects please check [linktr.ee/FLNGR](https://linktr.ee/FLNGR).
23
+
24
+ ## Running the project at home
25
+
26
+ First, I would like to highlight that everything is open-source (see [here](https://huggingface.co/spaces/jbilcke-hf/ai-comic-factory/tree/main), [here](https://huggingface.co/spaces/jbilcke-hf/VideoChain-API/tree/main), [here](https://huggingface.co/spaces/hysts/SD-XL/tree/main), [here](https://github.com/huggingface/text-generation-inference)).
27
+
28
+ However the project isn't a monolithic Space that can be duplicated and ran immediately:
29
+ it requires various components to run for the frontend, backend, LLM, SDXL etc.
30
+
31
+ If you try to duplicate the project, open the `.env` you will see it requires some variables.
32
+
33
+ Provider config:
34
+ - `LLM_ENGINE`: can be one of `INFERENCE_API`, `INFERENCE_ENDPOINT`, `OPENAI`, `GROQ`, `ANTHROPIC`
35
+ - `RENDERING_ENGINE`: can be one of: "INFERENCE_API", "INFERENCE_ENDPOINT", "REPLICATE", "VIDEOCHAIN", "OPENAI" for now, unless you code your custom solution
36
+
37
+ Auth config:
38
+ - `AUTH_HF_API_TOKEN`: if you decide to use Hugging Face for the LLM engine (inference api model or a custom inference endpoint)
39
+ - `AUTH_OPENAI_API_KEY`: to use OpenAI for the LLM engine
40
+ - `AUTH_GROQ_API_KEY`: to use Groq for the LLM engine
41
+ - `AUTH_ANTHROPIC_API_KEY`: to use Anthropic (Claude) for the LLM engine
42
+ - `AUTH_VIDEOCHAIN_API_TOKEN`: secret token to access the VideoChain API server
43
+ - `AUTH_REPLICATE_API_TOKEN`: in case you want to use Replicate.com
44
+
45
+ Rendering config:
46
+ - `RENDERING_HF_INFERENCE_ENDPOINT_URL`: necessary if you decide to use a custom inference endpoint
47
+ - `RENDERING_REPLICATE_API_MODEL_VERSION`: url to the VideoChain API server
48
+ - `RENDERING_HF_INFERENCE_ENDPOINT_URL`: optional, default to nothing
49
+ - `RENDERING_HF_INFERENCE_API_BASE_MODEL`: optional, defaults to "stabilityai/stable-diffusion-xl-base-1.0"
50
+ - `RENDERING_HF_INFERENCE_API_REFINER_MODEL`: optional, defaults to "stabilityai/stable-diffusion-xl-refiner-1.0"
51
+ - `RENDERING_REPLICATE_API_MODEL`: optional, defaults to "stabilityai/sdxl"
52
+ - `RENDERING_REPLICATE_API_MODEL_VERSION`: optional, in case you want to change the version
53
+
54
+ Language model config (depending on the LLM engine you decide to use):
55
+ - `LLM_HF_INFERENCE_ENDPOINT_URL`: "<use your own>"
56
+ - `LLM_HF_INFERENCE_API_MODEL`: "HuggingFaceH4/zephyr-7b-beta"
57
+ - `LLM_OPENAI_API_BASE_URL`: "https://api.openai.com/v1"
58
+ - `LLM_OPENAI_API_MODEL`: "gpt-4-turbo"
59
+ - `LLM_GROQ_API_MODEL`: "mixtral-8x7b-32768"
60
+ - `LLM_ANTHROPIC_API_MODEL`: "claude-3-opus-20240229"
61
+
62
+ In addition, there are some community sharing variables that you can just ignore.
63
+ Those variables are not required to run the AI Comic Factory on your own website or computer
64
+ (they are meant to create a connection with the Hugging Face community,
65
+ and thus only make sense for official Hugging Face apps):
66
+ - `NEXT_PUBLIC_ENABLE_COMMUNITY_SHARING`: you don't need this
67
+ - `COMMUNITY_API_URL`: you don't need this
68
+ - `COMMUNITY_API_TOKEN`: you don't need this
69
+ - `COMMUNITY_API_ID`: you don't need this
70
+
71
+ Please read the `.env` default config file for more informations.
72
+ To customise a variable locally, you should create a `.env.local`
73
+ (do not commit this file as it will contain your secrets).
74
+
75
+ -> If you intend to run it with local, cloud-hosted and/or proprietary models **you are going to need to code 👨‍💻**.
76
+
77
+ ## The LLM API (Large Language Model)
78
+
79
+ Currently the AI Comic Factory uses [zephyr-7b-beta](https://huggingface.co/HuggingFaceH4/zephyr-7b-beta) through an [Inference Endpoint](https://huggingface.co/docs/inference-endpoints/index).
80
+
81
+ You have multiple options:
82
+
83
+ ### Option 1: Use an Inference API model
84
+
85
+ This is a new option added recently, where you can use one of the models from the Hugging Face Hub. By default we suggest to use [zephyr-7b-beta](https://huggingface.co/HuggingFaceH4/zephyr-7b-beta) as it will provide better results than the 7b model.
86
+
87
+ To activate it, create a `.env.local` configuration file:
88
+
89
+ ```bash
90
+ LLM_ENGINE="INFERENCE_API"
91
+
92
+ HF_API_TOKEN="Your Hugging Face token"
93
+
94
+ # "HuggingFaceH4/zephyr-7b-beta" is used by default, but you can change this
95
+ # note: You should use a model able to generate JSON responses,
96
+ # so it is storngly suggested to use at least the 34b model
97
+ HF_INFERENCE_API_MODEL="HuggingFaceH4/zephyr-7b-beta"
98
+ ```
99
+
100
+ ### Option 2: Use an Inference Endpoint URL
101
+
102
+ If you would like to run the AI Comic Factory on a private LLM running on the Hugging Face Inference Endpoint service, create a `.env.local` configuration file:
103
+
104
+ ```bash
105
+ LLM_ENGINE="INFERENCE_ENDPOINT"
106
+
107
+ HF_API_TOKEN="Your Hugging Face token"
108
+
109
+ HF_INFERENCE_ENDPOINT_URL="path to your inference endpoint url"
110
+ ```
111
+
112
+ To run this kind of LLM locally, you can use [TGI](https://github.com/huggingface/text-generation-inference) (Please read [this post](https://github.com/huggingface/text-generation-inference/issues/726) for more information about the licensing).
113
+
114
+ ### Option 3: Use an OpenAI API Key
115
+
116
+ This is a new option added recently, where you can use OpenAI API with an OpenAI API Key.
117
+
118
+ To activate it, create a `.env.local` configuration file:
119
+
120
+ ```bash
121
+ LLM_ENGINE="OPENAI"
122
+
123
+ # default openai api base url is: https://api.openai.com/v1
124
+ LLM_OPENAI_API_BASE_URL="A custom OpenAI API Base URL if you have some special privileges"
125
+
126
+ LLM_OPENAI_API_MODEL="gpt-4-turbo"
127
+
128
+ AUTH_OPENAI_API_KEY="Yourown OpenAI API Key"
129
+ ```
130
+ ### Option 4: (new, experimental) use Groq
131
+
132
+ ```bash
133
+ LLM_ENGINE="GROQ"
134
+
135
+ LLM_GROQ_API_MODEL="mixtral-8x7b-32768"
136
+
137
+ AUTH_GROQ_API_KEY="Your own GROQ API Key"
138
+ ```
139
+ ### Option 5: (new, experimental) use Anthropic (Claude)
140
+
141
+ ```bash
142
+ LLM_ENGINE="ANTHROPIC"
143
+
144
+ LLM_ANTHROPIC_API_MODEL="claude-3-opus-20240229"
145
+
146
+ AUTH_ANTHROPIC_API_KEY="Your own ANTHROPIC API Key"
147
+ ```
148
+
149
+ ### Option 6: Fork and modify the code to use a different LLM system
150
+
151
+ Another option could be to disable the LLM completely and replace it with another LLM protocol and/or provider (eg. Claude, Replicate), or a human-generated story instead (by returning mock or static data).
152
+
153
+ ### Notes
154
+
155
+ It is possible that I modify the AI Comic Factory to make it easier in the future (eg. add support for Claude or Replicate)
156
+
157
+ ## The Rendering API
158
+
159
+ This API is used to generate the panel images. This is an API I created for my various projects at Hugging Face.
160
+
161
+ I haven't written documentation for it yet, but basically it is "just a wrapper ™" around other existing APIs:
162
+
163
+ - The [hysts/SD-XL](https://huggingface.co/spaces/hysts/SD-XL?duplicate=true) Space by [@hysts](https://huggingface.co/hysts)
164
+ - And other APIs for making videos, adding audio etc.. but you won't need them for the AI Comic Factory
165
+
166
+ ### Option 1: Deploy VideoChain yourself
167
+
168
+ You will have to [clone](https://huggingface.co/spaces/jbilcke-hf/VideoChain-API?duplicate=true) the [source-code](https://huggingface.co/spaces/jbilcke-hf/VideoChain-API/tree/main)
169
+
170
+ Unfortunately, I haven't had the time to write the documentation for VideoChain yet.
171
+ (When I do I will update this document to point to the VideoChain's README)
172
+
173
+
174
+ ### Option 2: Use Replicate
175
+
176
+ To use Replicate, create a `.env.local` configuration file:
177
+
178
+ ```bash
179
+ RENDERING_ENGINE="REPLICATE"
180
+
181
+ RENDERING_REPLICATE_API_MODEL="stabilityai/sdxl"
182
+
183
+ RENDERING_REPLICATE_API_MODEL_VERSION="da77bc59ee60423279fd632efb4795ab731d9e3ca9705ef3341091fb989b7eaf"
184
+
185
+ AUTH_REPLICATE_API_TOKEN="Your Replicate token"
186
+ ```
187
+
188
+ ### Option 3: Use another SDXL API
189
+
190
+ If you fork the project you will be able to modify the code to use the Stable Diffusion technology of your choice (local, open-source, proprietary, your custom HF Space etc).
191
+
192
+ It would even be something else, such as Dall-E.
ai-comic-factory/components.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "default",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.js",
8
+ "css": "app/globals.css",
9
+ "baseColor": "stone",
10
+ "cssVariables": false
11
+ },
12
+ "aliases": {
13
+ "components": "@/components",
14
+ "utils": "@/lib/utils"
15
+ }
16
+ }
ai-comic-factory/next.config.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ output: 'standalone',
4
+
5
+ experimental: {
6
+ serverActions: {
7
+ bodySizeLimit: '8mb',
8
+ },
9
+ }
10
+ }
11
+
12
+ module.exports = nextConfig
ai-comic-factory/package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
ai-comic-factory/package.json ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@jbilcke/comic-factory",
3
+ "version": "1.2.3",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "@aitube/clap": "0.2.4",
13
+ "@anthropic-ai/sdk": "^0.25.0",
14
+ "@huggingface/hub": "^0.15.1",
15
+ "@huggingface/inference": "^2.0.0",
16
+ "@mediapipe/tasks-vision": "0.10.15",
17
+ "@radix-ui/react-accordion": "^1.1.2",
18
+ "@radix-ui/react-avatar": "^1.0.3",
19
+ "@radix-ui/react-checkbox": "^1.0.4",
20
+ "@radix-ui/react-collapsible": "^1.0.3",
21
+ "@radix-ui/react-dialog": "^1.0.4",
22
+ "@radix-ui/react-dropdown-menu": "^2.0.5",
23
+ "@radix-ui/react-icons": "^1.3.0",
24
+ "@radix-ui/react-label": "^2.0.2",
25
+ "@radix-ui/react-menubar": "^1.0.3",
26
+ "@radix-ui/react-popover": "^1.0.6",
27
+ "@radix-ui/react-select": "^1.2.2",
28
+ "@radix-ui/react-separator": "^1.0.3",
29
+ "@radix-ui/react-slider": "^1.1.2",
30
+ "@radix-ui/react-slot": "^1.0.2",
31
+ "@radix-ui/react-switch": "^1.0.3",
32
+ "@radix-ui/react-toast": "^1.1.4",
33
+ "@radix-ui/react-tooltip": "^1.0.6",
34
+ "@types/node": "20.4.2",
35
+ "@types/react": "18.3.0",
36
+ "@types/react-dom": "18.3.0",
37
+ "@types/uuid": "^9.0.2",
38
+ "autoprefixer": "10.4.18",
39
+ "class-variance-authority": "^0.6.1",
40
+ "clsx": "^2.1.0",
41
+ "cmdk": "^0.2.0",
42
+ "cookies-next": "^2.1.2",
43
+ "date-fns": "^2.30.0",
44
+ "encoding": "^0.1.13",
45
+ "eslint": "8.45.0",
46
+ "eslint-config-next": "13.4.10",
47
+ "groq-sdk": "^0.3.1",
48
+ "html2canvas": "^1.4.1",
49
+ "i": "^0.3.7",
50
+ "konva": "^9.2.2",
51
+ "lucide-react": "^0.260.0",
52
+ "next": "14.2.7",
53
+ "npm": "^10.7.0",
54
+ "openai": "^4.29.2",
55
+ "pick": "^0.0.1",
56
+ "postcss": "8.4.37",
57
+ "query-string": "^9.0.0",
58
+ "react": "18.3.1",
59
+ "react-circular-progressbar": "^2.1.0",
60
+ "react-contenteditable": "^3.3.7",
61
+ "react-dom": "18.3.1",
62
+ "react-draggable": "^4.4.6",
63
+ "react-hook-consent": "^3.5.3",
64
+ "react-icons": "^4.11.0",
65
+ "react-konva": "^18.2.10",
66
+ "react-virtualized-auto-sizer": "^1.0.20",
67
+ "replicate": "^0.32.0",
68
+ "sbd": "^1.0.19",
69
+ "sharp": "^0.33.4",
70
+ "tailwind-merge": "^2.2.2",
71
+ "tailwindcss": "3.4.1",
72
+ "tailwindcss-animate": "^1.0.6",
73
+ "ts-node": "^10.9.1",
74
+ "typescript": "^5.4.5",
75
+ "use-file-picker": "^2.1.2",
76
+ "usehooks-ts": "2.9.1",
77
+ "uuid": "^9.0.0",
78
+ "yaml": "^2.4.5",
79
+ "zustand": "^4.5.1"
80
+ },
81
+ "devDependencies": {
82
+ "@types/qs": "^6.9.7",
83
+ "@types/react-virtualized": "^9.21.22",
84
+ "@types/sbd": "^1.0.3"
85
+ }
86
+ }
ai-comic-factory/postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
ai-comic-factory/public/bubble.jpg ADDED
ai-comic-factory/public/favicon.ico ADDED
ai-comic-factory/public/favicon/favicon-114-precomposed.png ADDED
ai-comic-factory/public/favicon/favicon-120-precomposed.png ADDED
ai-comic-factory/public/favicon/favicon-144-precomposed.png ADDED
ai-comic-factory/public/favicon/favicon-152-precomposed.png ADDED
ai-comic-factory/public/favicon/favicon-180-precomposed.png ADDED
ai-comic-factory/public/favicon/favicon-192.png ADDED
ai-comic-factory/public/favicon/favicon-32.png ADDED
ai-comic-factory/public/favicon/favicon-36.png ADDED
ai-comic-factory/public/favicon/favicon-48.png ADDED
ai-comic-factory/public/favicon/favicon-57.png ADDED
ai-comic-factory/public/favicon/favicon-60.png ADDED
ai-comic-factory/public/favicon/favicon-72-precomposed.png ADDED
ai-comic-factory/public/favicon/favicon-72.png ADDED
ai-comic-factory/public/favicon/favicon-76.png ADDED
ai-comic-factory/public/favicon/favicon-96.png ADDED
ai-comic-factory/public/favicon/favicon.ico ADDED
ai-comic-factory/public/favicon/index.html ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <title>
4
+ Favicons
5
+ </title>
6
+ <meta charset="utf-8" />
7
+
8
+ <!-- For old IEs -->
9
+ <link rel="shortcut icon" href="favicon.ico" />
10
+
11
+ <!-- For new browsers multisize ico -->
12
+ <link rel="icon" type="image/x-icon" sizes="16x16 32x32" href="favicon.ico">
13
+
14
+ <!-- Chrome for Android -->
15
+ <link rel="icon" sizes="192x192" href="favicon-192.png">
16
+
17
+ <!-- For iPhone 6+ downscaled for other devices -->
18
+ <link rel="apple-touch-icon" sizes="180x180" href="favicon-180-precomposed.png">
19
+
20
+ <!-- For IE10 Metro -->
21
+ <meta name="msapplication-TileColor" content="#FFFFFF">
22
+ <meta name="msapplication-TileImage" content="favicon-114-precomposed.png">
23
+
24
+ <style>
25
+
26
+ body {
27
+ background-color: #f5f5f5;
28
+ border: 0px;
29
+ margin: 0px;
30
+ padding: 0px;
31
+ font-family: Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;
32
+ color: black;
33
+ }
34
+
35
+ pre {
36
+ margin: 0px;
37
+ color: black;
38
+ padding: 0px 5%;
39
+ }
40
+
41
+ code {
42
+
43
+ }
44
+
45
+ .container {
46
+ background-color: white;
47
+ max-width: 800px;
48
+ width: 100%;
49
+ margin: 0 auto;
50
+ padding: 1% 0;
51
+ height: 100%;
52
+ }
53
+
54
+ .comment {
55
+ color: gray;
56
+ padding: 0px;
57
+ margin: 0px;
58
+ }
59
+
60
+ hr {
61
+ width: 80%;
62
+ padding: 0 5%;
63
+ border-color: #f5f5f5;
64
+ background-color: #D1D1D1;
65
+ }
66
+
67
+ p {
68
+ padding: 1% 5%;
69
+ }
70
+
71
+ </style>
72
+
73
+ </head>
74
+ <body class="">
75
+
76
+ <div class="container">
77
+ <p>
78
+ To use the favicons insert into your head section some of these tags accordly to your needs.
79
+ </p>
80
+ <hr>
81
+ <pre>
82
+ <code>
83
+ <span class="comment">&lt;!-- For old IEs --&gt;</span>
84
+ &lt;link rel=&quot;shortcut icon&quot; href=&quot;favicon.ico&quot; /&gt;
85
+
86
+ <span class="comment">&lt;!-- For new browsers - multisize ico --&gt;</span>
87
+ &lt;link rel=&quot;icon&quot; type=&quot;image/x-icon&quot; sizes=&quot;16x16 32x32&quot; href=&quot;favicon.ico&quot;&gt;
88
+
89
+ <span class="comment">&lt;!-- For iPad with high-resolution Retina display running iOS &ge; 7: --&gt;</span>
90
+ &lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;152x152&quot; href=&quot;favicon-152-precomposed.png&quot;&gt;
91
+
92
+ <span class="comment">&lt;!-- For iPad with high-resolution Retina display running iOS &le; 6: --&gt;</span>
93
+ &lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;144x144&quot; href=&quot;favicon-144-precomposed.png&quot;&gt;
94
+
95
+ <span class="comment">&lt;!-- For iPhone with high-resolution Retina display running iOS &ge; 7: --&gt;</span>
96
+ &lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;120x120&quot; href=&quot;favicon-120-precomposed.png&quot;&gt;
97
+
98
+ <span class="comment">&lt;!-- For iPhone with high-resolution Retina display running iOS &le; 6: --&gt;</span>
99
+ &lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;114x114&quot; href=&quot;favicon-114-precomposed.png&quot;&gt;
100
+
101
+ <span class="comment">&lt;!-- For iPhone 6+ --&gt;</span>
102
+ &lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;180x180&quot; href=&quot;favicon-180-precomposed.png&quot;&gt;
103
+
104
+ <span class="comment">&lt;!-- For first- and second-generation iPad: --&gt;</span>
105
+ &lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;72x72&quot; href=&quot;favicon-72-precomposed.png&quot;&gt;
106
+
107
+ <span class="comment">&lt;!-- For non-Retina iPhone, iPod Touch, and Android 2.1+ devices: --&gt;</span>
108
+ &lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;57x57&quot; href=&quot;favicon-57.png&quot;&gt;
109
+
110
+ <span class="comment">&lt;!-- For Old Chrome --&gt;</span>
111
+ &lt;link rel=&quot;icon&quot; sizes=&quot;32x32&quot; href=&quot;favicon-32.png&quot; &gt;
112
+
113
+ <span class="comment">&lt;!-- For IE10 Metro --&gt;</span>
114
+ &lt;meta name=&quot;msapplication-TileColor&quot; content=&quot;#FFFFFF&quot;&gt;
115
+ &lt;meta name=&quot;msapplication-TileImage&quot; content=&quot;favicon-144.png&quot;&gt;
116
+ &lt;meta name=&quot;theme-color&quot; content=&quot;#ffffff&quot;&gt;
117
+
118
+ <span class="comment">&lt;!-- Chrome for Android --&gt;</span>
119
+ &lt;link rel=&quot;manifest&quot; href=&quot;manifest.json&quot;&gt;
120
+ &lt;link rel=&quot;icon&quot; sizes=&quot;192x192&quot; href=&quot;favicon-192.png&quot;&gt;
121
+
122
+ </code>
123
+ </pre>
124
+
125
+ <hr>
126
+
127
+ <p>
128
+ For more informations about favicons consult <a href="https://github.com/audreyr/favicon-cheat-sheet">The Favicon Cheat Sheet</a> by Audrey Roy.
129
+ </p>
130
+
131
+ </div>
132
+
133
+ </body>
ai-comic-factory/public/favicon/manifest.json ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "pollo",
3
+ "icons": [
4
+ {
5
+ "src": "\/favicon-36.png",
6
+ "sizes": "36x36",
7
+ "type": "image\/png",
8
+ "density": 0.75
9
+ },
10
+ {
11
+ "src": "\/favicon-48.png",
12
+ "sizes": "48x48",
13
+ "type": "image\/png",
14
+ "density": 1
15
+ },
16
+ {
17
+ "src": "\/favicon-72.png",
18
+ "sizes": "72x72",
19
+ "type": "image\/png",
20
+ "density": 1.5
21
+ },
22
+ {
23
+ "src": "\/favicon-96.png",
24
+ "sizes": "96x96",
25
+ "type": "image\/png",
26
+ "density": 2
27
+ },
28
+ {
29
+ "src": "\/favicon-144.png",
30
+ "sizes": "144x144",
31
+ "type": "image\/png",
32
+ "density": 3
33
+ },
34
+ {
35
+ "src": "\/favicon-192.png",
36
+ "sizes": "192x192",
37
+ "type": "image\/png",
38
+ "density": 4
39
+ }
40
+ ]
41
+ }
ai-comic-factory/public/icon.png ADDED
ai-comic-factory/public/layouts/layout0.jpg ADDED
ai-comic-factory/public/layouts/layout0_hd.jpg ADDED
ai-comic-factory/public/layouts/layout1.jpg ADDED
ai-comic-factory/public/layouts/layout1_hd.jpg ADDED
ai-comic-factory/public/layouts/layout2.jpg ADDED
ai-comic-factory/public/layouts/layout2_hd.jpg ADDED
ai-comic-factory/public/layouts/layout3 hd.jpg ADDED
ai-comic-factory/public/layouts/layout3.jpg ADDED
ai-comic-factory/public/layouts/layout4 hd.jpg ADDED
ai-comic-factory/public/layouts/layout4.jpg ADDED
ai-comic-factory/public/mask.png ADDED
ai-comic-factory/public/next.svg ADDED
ai-comic-factory/public/quick-and-dirty-emoji.png ADDED
ai-comic-factory/public/sign-in-with-huggingface-xl.svg ADDED
ai-comic-factory/public/vercel.svg ADDED
ai-comic-factory/src/app/engine/caption.ts ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use server"
2
+
3
+ import { ImageAnalysisRequest, ImageAnalysisResponse } from "@/types"
4
+
5
+ const apiUrl = `${process.env.RENDERING_VIDEOCHAIN_API_URL || ""}`
6
+
7
+ export async function see({
8
+ prompt,
9
+ imageBase64
10
+ }: {
11
+ prompt: string
12
+ imageBase64: string
13
+ }): Promise<string> {
14
+ if (!prompt) {
15
+ console.error(`cannot call the API without an image, aborting..`)
16
+ throw new Error(`cannot call the API without an image, aborting..`)
17
+ }
18
+
19
+ try {
20
+ const request = {
21
+ prompt,
22
+ image: imageBase64
23
+
24
+ } as ImageAnalysisRequest
25
+
26
+ console.log(`calling ${apiUrl}/analyze called with: `, {
27
+ prompt: request.prompt,
28
+ image: request.image.slice(0, 20)
29
+ })
30
+
31
+ const res = await fetch(`${apiUrl}/analyze`, {
32
+ method: "POST",
33
+ headers: {
34
+ Accept: "application/json",
35
+ "Content-Type": "application/json",
36
+ // Authorization: `Bearer ${videochainApi}`,
37
+ },
38
+ body: JSON.stringify(request),
39
+ cache: 'no-store',
40
+ // we can also use this (see https://vercel.com/blog/vercel-cache-api-nextjs-cache)
41
+ // next: { revalidate: 1 }
42
+ })
43
+
44
+ if (res.status !== 200) {
45
+ throw new Error('Failed to fetch data')
46
+ }
47
+
48
+ const response = (await res.json()) as ImageAnalysisResponse
49
+ return response.result
50
+ } catch (err) {
51
+ console.error(err)
52
+ return ""
53
+ }
54
+ }
ai-comic-factory/src/app/engine/censorship.ts ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // I don't want to be banned by Replicate because bad actors are asking
3
+ // for some naked anime stuff or whatever
4
+ // I also want to avoid a PR scandal due to some bad user generated content
5
+
6
+ import { computeSecretFingerprint } from "@/lib/computeSecretFingerprint"
7
+
8
+ // those keywords have been generated by looking at the logs of the panorama and the AI Comic Factory
9
+ // those are real requests some users tried to attempt.. :|
10
+
11
+ const chickens = [
12
+ "fcb4dacbd99b21368c50f29c1d47071c87cf2225ab9192282c785460391cd365",
13
+ "68840b60ac27eacaa7afe17e898d3c4a2dc71acff8c74d6782c1bcaafd14963d",
14
+ "67f745224fd6e1a7a3a244514d5807fcc994cbb62ca4ec8fa44cd14244a515ae",
15
+ "681fea565117808c6dbe002520d2cfeeb3e5c67e68630afb4a453449a9da587b",
16
+ "2f3d913b3db9e15a930aac43eb2d6fe8817db8e4bcf37794bf0227b06b718d1b",
17
+ "922a700b807e4994df82eba2b48a6ac131fe8d8d1035d06b3592d622fb232161",
18
+ "cb69ee6774eafcc720adb1f689d28acbb9f47998cbea0299ec66a58dedf91c37"
19
+ ]
20
+
21
+ const ducks = [
22
+ "1c52cb20c0cbc76349fa63232b982bd394cf0850ebc17240dcf33c19fb15a26d",
23
+ "e1d4de9b8d464d7da07c276b63a42c1c9922224f0a6cab6b0826427ce4a7461a",
24
+ "0be3174bfb1a48a65875c2f035b1ae14fbc8f232f55785018de0cfe2132fa952",
25
+ "0f174769641b2e5d2c79b5a83e8ef91e004f6f3e62531cd70cfdff02159268cb",
26
+ "e9fb8ae8ff720acd91025229478a21e43e8e976e30119a76c293201adf572736",
27
+ "f65a0dc0e07b5d084ff24c69dcdb953f7b57101d2ebb716d4dfb5963076ef807",
28
+ "2bf38af1646489c2c086f811d082054cd29e23fa7bb5c525396bec01b3ab688e"
29
+ ]
30
+
31
+ const cats = [
32
+ "fcffc3e997d952007d1b902a9cf40b750ba4a410ac65bfd95475996bf51359e4",
33
+ "3172a5fa159754d703489dfba5af520b8ace107cdf170f4c4cb38a6797aa163f",
34
+ "500012dbff4498a9c4513369d6b9b373fab9330ffd2cb1e622294043cc21b610",
35
+ "84e3a8d34ee7d0c8e7a2926dd1acad46a0b66b9d27725b3a7e5053550f490301"
36
+ ]
37
+
38
+ const roasted = [
39
+ "a2bfbce0046c9a52a0eabf98f73e0f8e09959970431fc892ebdb4e1c97031b50",
40
+ "6eca1adf06851f99e9cdfbb496c27d46ff81106903d11f3346a146e96082b016",
41
+ "49a124c9ed6fbbad4105b3657dc25de369bcafb9d6787f610c08f584cd607d0f",
42
+ "c3afb59420c812cbc7c8f57ad3e8d79407f10106a99f829aa65316c99d0b29c4",
43
+ "2b808858836a5c205080f5b93201ef92e098cff931d8de6d9f20dc722997d077",
44
+ "07bef89d1a7d63c9c5ed64ba0f73d6cff689811847c2e20c8b3fbfb060e1d64e",
45
+ "baeb994922d5473f534aa54322d83effe74c6c4dac807e6b523a677d7acdc17b",
46
+ "ea4735a879edd5cc94ca7db26edd5a970df69a41f0009d3444486647e44175af",
47
+ "f2412249030454cd13ac6f7965871d924c16daacda0123de81892adb19ce49ac",
48
+ "9958c56e12bab8549cf752bcd8bec4ac36cf79c404b1faf5611f057bb71bc0e1",
49
+ "76cdade0b3d4caf0888f60318a5cbca00f830a3b0bf37735fc64fdaeb67c34d3",
50
+ "1bf53c97869e1ea89bda19da64a9173d48fe4ec823e949e2c898f8abb3fbf457",
51
+ "1bf53c97869e1ea89bda19da64a9173d48fe4ec823e949e2c898f8abb3fbf457",
52
+ "3d7f973fab8f4a19c0a3e59efe970ed7bd55a1cb795752d9cbe3c19e8a7d81ec"
53
+ ]
54
+
55
+ const banned = [
56
+ "8a05d4869d9d6ce388c6cd2db13ca12b88097b90f9be027d5ffaaa467c7a6e5e",
57
+ "0c475212a608138244c5fc150b1563e5ef79c516234fd78dcd5993f726c359a0",
58
+ "df17388805f99f2ff3e5ae97a0f55e5c927eb47f17ca65822bf8c88f02bac3dd",
59
+ "86c3355d1bd581cdf7306729d8dd0ee9b7a317b9cfd6d7a6f5fad9c0dafe2167",
60
+ "23a2484cd420c9ffbfcc2c0075a9b330664450ced1fc64ab6a65e278086b8c6e",
61
+ "fb4cabe709b62eea1b4cc0030c76f5e4a43ee677ce19124e8e7bafa86c78ab66",
62
+ "d99c26daee85f7dc81c46c061a5874cff7179ed72d884d2316d664d36ffe7ab5",
63
+ "b93c38af5aa221d76c60ee3eb762efee0cdb0daf29ceb235b7dda6d46c06490d",
64
+ "8cf6c8765dc757319461dd9a785e77c201b8e5a604d36b817cd987c6a5e62500",
65
+ "f4a1cb290745717f86c3cee30fc324c0d80a9945fcbc7bbeb010579f58792f1e",
66
+ "7c87c47c42fc983119551342be9ddd5b32e530c0504ccdbbaa1e12b1d9f1bbcb",
67
+ "d04fad4f21d030da7a1301afbf480ef6246eb7bbf0f26e31865b2e015a25f747",
68
+ "d685ff22fb9da01ee949db212770729603989850864ef7a7085e1f086cfa7deb",
69
+ "533b90588d9ccf7967da54691f575e9fd4926c6e0b5fd94a47b932bcea270bee",
70
+ "9c2d61f28f5bb7f3f1dc9122be64cda8a428b46ce68b70120da4c41dba96ba4c",
71
+ "5d4b1a3eebe64dfa631d0e3b084bd96ee9364c3669269f838ca17a4900276264",
72
+ "d56f56413b9679fc0820a2c0237224ded8554c61fab8959c174123c8b68ba029",
73
+ "323a9ab60739726070d615ff3a05d7ff6bb6e3c4dd9ff16ce24f253ecd7b8851",
74
+ "975c6739de7d4999db15972f707f5f4e95649275f1c0c48e895b8c537e8638ec",
75
+ "67ee26eb9e1c1c7124797321b02bca90a19c18171782917cd4a487b722484dce",
76
+ "6df5aa7b72a4e6e3fb726489ff1437daa5752047507f4da912680b1d6647c7d6",
77
+ "b0864805364359e8c5810c233b1bf2c74dedce9055ae5f7680ba05b4e39db8e2",
78
+ "a8f841472ecffdd6266151148320c8e36847a24ead9d3338e0313b075c16649d",
79
+ "f9b127cd90e85b0ff68dd220361671663f0154b2b827f1f7ea797b020ca0018c",
80
+ "d5c20e9a1ecf01c82da24c514d867498b3e5f522adc1523ce29404a6563641d5",
81
+ "241022b49d7c0aba24a61eea1137a804f36e4bcb47af42950275baac9b4e7aac",
82
+ "fc99a70e17b6c86ef1b537654b0f50353567a7b59912c3ba955f3fca4d1ea696",
83
+ "255306e968009003d295cb2a7256f27bfcdb5d1743bf4d9f2aa4b8adf1a7734d",
84
+ "048c7b709763dd9c43794d241c369f0abcb079d546ddcbbba9968a1ed1da7ed7",
85
+ "520cbfeef3e4c405d79478eedccb97a4d476be585626dd2b1c53292797491bc7",
86
+ "f9f28a7ae7e8b1719b350a04dc087a4b8e33478d109ceeef6ba892b32d1105c9",
87
+ "d177f1bfe603647ef4c1c0e6f1a7172081fb9bbc2ea859705949f2c5aa5d4f22",
88
+ "302feef2c09247fbd23789581f7f5e2219f88ae0a937880954938573c2a52a84",
89
+ "99edd6f57b864873835f16f19c805dd94bed9da8967b84e3a62782f106d9ebcc",
90
+ "e75e5f01dcd8351c9553e89558085bd68e6feb295dee5d8da0c9b43ee303ce36",
91
+ "135e52a026aea9d2e12de358a85e05cf21121a18269269b7c62678c3bc846f5b",
92
+ "28e5b2d3eb5f1ef4cc7b570878b03acf303a6ca4ca95893591e0fb943b0beab0",
93
+ "a26b26340f8d0363633490556d20bcc250726d10e1431eb8c22d6b1ff3f2b14a",
94
+ "27e4ddde96ec6a1dbe1cf12d79448b3e72f144944c15b299629542d1b65fbabf",
95
+ "efd9c0a391ee93251046a58326d1b21b33fe21d71a3fb1855b9048ade53df77c",
96
+ "6d505fcce416c26a606878aab4d249a034ba2a9846cb1f883e0f9e3fb76ba6da",
97
+ "3a37b8a1b72f9bca51233536d50f9c8d33a787434684787871e0049c82347cda",
98
+ "16f9b451184a7c3148344c7d0315f5312ca20553d2271912ecaad91810d977e6",
99
+ "7406537eb74d1885bd05e191228de313b13702a64d90ae1736c6377b25ab579a",
100
+ "7e4d1395ae18980015cab16c85ffa20b4cb90a2db594126e893d0f7ac6eecaa8",
101
+ "ba813ee6c25698f0f68a07121d38bb47c9aa404c1ab0a6e767595cb75e1747b8",
102
+ "6586c93f3ece83e01ecc1eb84a7711e7975826a388d478a009468ea0ed9dc03e",
103
+ "8960174c74d86e03ae88fb6774580170e49952f2286d960be08c556bbd0dda95",
104
+ "4d611454369aa1a4e2b7eed1734fac5d480f08fb86b87a162967e416370f2a8e",
105
+ "59d48440f85eabf565fe8d3bc6b973ba64c70df3b36b0511e0e67ceca91762b3",
106
+ "cd926926e2af74e43d1a6a420a7e1933b78662320477a3c018b2711d8765e339",
107
+ "80e90057df6a59823f51aafac36ed5bc4e5ac26d675d9c1467501590c82f12d4",
108
+ "a9cf28b869b70e258adde5639a048f866ec86f8f3f3d53bfc960b86aa6da9239",
109
+ "cc2adbf8ac0cddeefa304d7b20f14a7e047a4b2299cc5e8f898f5c59660bd964",
110
+ "92a150a46146e9d3f84899cf15e12514af684e7ee18d7add782ddd4f4a15ef18",
111
+ "d9b2e84ef6dc0ce449357d52c9095f69b173a1b848ea2921199d33b0ec10024a",
112
+ "a9329a7e4d367a0135c1ca86c6ce5ecabcc26529235229d71b6bf991f7689e21",
113
+ "8f160c6fd8ccc3fb2a371a4b52748f0bd030766627c4322e2911fe82f6b10497",
114
+ "620e96eae4f3e88cbe0770292b33724c5df3866d83f39df6380441f7271c80e2",
115
+ "cafa3481fa3c45ed1e55cd0129c12b477eeab5aa3d6da20cae6d6292f19b0e6d",
116
+ "be07994e9a83aa3689e79b6e96123676ccc4fa29f523c28c750c6d60505531ee",
117
+ "f6498069768cd3aa79b2b0c91879694f05a259c8ee4a6bb343f0435f74eb1b53",
118
+ "c9b6b26cb3a694eb78fcac0a14ad18d46d50907186a9add41022d31d191b2b65"
119
+ ]
120
+
121
+ const young = [
122
+ "ffdf66787b4a33b78b18c18822e334cfe2c8406caf442851deef451bd43140a1",
123
+ "858f22219afc4b32a7ba9a27a213d7f495e77c3cceed8147eae5282bf3e23d39",
124
+ "8c3c46df84ace3d58d4ce0fbc513017986b33c6002ae369d9f7dd1f892a898cb",
125
+ "66caa22b9483fdf026ce67de61067d81535a7c9b3169cbc5c2a455ac8dcc7bec",
126
+ "76893047b1eff9fadc7be07b13adb5aaed9c73bcdeea46ee07098605e2c7ff76",
127
+ "526cb848754e2baaa17376a5693d90ba3f69f71fd2a866f22876ac8a075849a7",
128
+ "f59c38e31d0f64dc1bfcdf34451723bc1a65570e209e5496c8d1d7f6d3d649db",
129
+ "e013a67e275c62c1402ccbbb11ad14afb8b8a82318a44c07d67599ed5ac874de",
130
+ "3bef34219fb07f867ecbff4d6748f598d6cc0761e17dd0d431ee1f4ec3281374",
131
+ "8211bf5f613fac06cd5d074d34c16dfacc9367c8afaa6ad3aff99d145e5221be"
132
+ ]
133
+
134
+ const getFingerprint = (word: string) => {
135
+ return computeSecretFingerprint(
136
+ word.toLocaleLowerCase().replaceAll(/[^a-zA-Z0-9]/gi, "")
137
+ )
138
+ }
139
+
140
+ const encode = (list: string[]) => {
141
+ console.log(JSON.stringify(
142
+ list.sort((a, b) => (b.length - a.length))
143
+ .map(item => getFingerprint(item)), null, 2))
144
+ }
145
+
146
+ // encode([ "badword" ])
147
+
148
+ export const filterOutBadWords = (sentence: string) => {
149
+ if (process.env.ENABLE_CENSORSHIP !== "true") { return sentence }
150
+
151
+ let requireCensorship = false
152
+
153
+ const words = sentence.replaceAll(/[^a-zA-Z0-9]/gi, " ").replaceAll(/\s+/gi, " ").trim().split(" ")
154
+
155
+ const sanitized = words.map(word => {
156
+ const fingerprint = getFingerprint(word)
157
+
158
+ let result: string = word
159
+ // some users want to play it smart and bypass our system so let's play too
160
+ if (chickens.includes(fingerprint)) {
161
+ result = "large chicken"
162
+ } else if (ducks.includes(fingerprint)) {
163
+ result = "big duck"
164
+ } else if (cats.includes(fingerprint)) {
165
+ result = "cat"
166
+ } else if (roasted.includes(fingerprint)) {
167
+ result = "roasted chicken"
168
+ } else if (young.includes(fingerprint)) {
169
+ result = "adult"
170
+ } else if (banned.includes(fingerprint)) {
171
+ result = "_BANNED_"
172
+ }
173
+
174
+ if (result !== word) {
175
+ requireCensorship = true
176
+ }
177
+ return result
178
+ }).filter(item => item !== "_BANNED_").join(" ")
179
+
180
+ // if the user didn't try to use a bad word, we leave it untouched
181
+ // he words array has been degraded by the replace operation, but it removes commas etc which isn't great
182
+ // so if the request was genuine and SFW, it's best to return the original prompt
183
+ return requireCensorship ? sanitized : sentence
184
+ }