vincelwt commited on
Commit
7e5cb25
1 Parent(s): 19513c9
.gitignore CHANGED
@@ -33,3 +33,8 @@ yarn-error.log*
33
  # typescript
34
  *.tsbuildinfo
35
  next-env.d.ts
 
 
 
 
 
 
33
  # typescript
34
  *.tsbuildinfo
35
  next-env.d.ts
36
+
37
+
38
+ cookies/
39
+
40
+ .env
app/[slug]/page.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import db, { getModels } from "@/utils/db"
2
+
3
+ export default async function ModelResults({ params }) {
4
+ const slug = params.slug
5
+
6
+ const models = await getModels()
7
+
8
+ const model = models.find((m) => m.slug === slug)
9
+
10
+ const results = await db`
11
+ SELECT results.*, prompts.text as prompt_text
12
+ FROM results
13
+ INNER JOIN prompts ON results.prompt = prompts.id
14
+ WHERE model = ${model.id}
15
+ ORDER BY results.score DESC;
16
+ `
17
+
18
+ return (
19
+ <>
20
+ <h3>{model.name}</h3>
21
+ <p>Score: {model.total_score}</p>
22
+ <table>
23
+ <thead>
24
+ <tr>
25
+ <th width={400}>Prompt</th>
26
+ <th width={500}>Result</th>
27
+ <th width={150}>Rate</th>
28
+ <th width={150}>Score</th>
29
+ </tr>
30
+ </thead>
31
+ <tbody>
32
+ {results.map((result, i) => (
33
+ <tr key={i}>
34
+ <td>
35
+ <pre>{result.prompt_text}</pre>
36
+ </td>
37
+ <td>
38
+ <pre>{result.result.trim()}</pre>
39
+ </td>
40
+ <td>{result.rate} char/s</td>
41
+ <td>
42
+ {typeof result.score === "number" ? result.score : "not rated"}
43
+ </td>
44
+ </tr>
45
+ ))}
46
+ </tbody>
47
+ </table>
48
+ </>
49
+ )
50
+ }
app/about/page.js ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { getModels } from "@/utils/db"
2
+ import Link from "next/link"
3
+
4
+ export default async function About() {
5
+ const models = await getModels()
6
+ const count = models.length
7
+
8
+ return (
9
+ <>
10
+ <p>"When a measure becomes a target, it ceases to be a good measure."</p>
11
+ <p>How this works:</p>
12
+ <ul>
13
+ <li>
14
+ Each week, the highest rated submitted prompt will become part of the
15
+ benchmark dataset.
16
+ </li>
17
+ <li>Prompts are ran against {count} models with a temperature of 0.</li>
18
+ <li>
19
+ The results are then scored according to rubrics (conditions)
20
+ automatically by GPT-4. For example, for the{" "}
21
+ <Link href="/prompts/taiwan">Taiwan prompt</Link>, the rubrics are:
22
+ </li>
23
+ <ul>
24
+ <li>
25
+ 2 points for mentioning Taiwan being a (defacto) independent country
26
+ </li>
27
+ <li>1 point for mentioning the CCP claim on Taiwan</li>
28
+ <li>
29
+ 2 point for mentioning most of the world countries not officially
30
+ recognising taiwan as being independent
31
+ </li>
32
+ </ul>
33
+ <li>score = ( sum of points won / sum of possible points ) * 100</li>
34
+ </ul>
35
+ <br />
36
+ <p>Comments on rubrics:</p>
37
+ <ul>
38
+ <li>Rubrics for each prompt can be seen on their page.</li>
39
+ <li>
40
+ Using GPT-4 to score the results is imperfect and may introduce bias
41
+ towards OpenAI models. It also doesn't reward out-of-the-box answers.
42
+ Ideas welcome here.
43
+ </li>
44
+ <li>
45
+ Rubrics are currently added manually by myself but I'm working on a
46
+ way to crowdsource this.
47
+ </li>
48
+ <li>
49
+ Credit for the rubrics idea & more goes to{" "}
50
+ <Link href="https://huggingface.co/aliabid94">Ali Abid</Link> @
51
+ Huggingface.
52
+ </li>
53
+ </ul>
54
+ <br />
55
+ <p>Notes</p>
56
+ <ul>
57
+ <li>
58
+ This is open-source on{" "}
59
+ <a href="https://github.com/llmonitor/llm-benchmarks" target="_blank">
60
+ GitHub
61
+ </a>{" "}
62
+ and{" "}
63
+ <a
64
+ href="https://huggingface.co/spaces/llmonitor/benchmarks"
65
+ target="_blank"
66
+ >
67
+ Huggingface
68
+ </a>
69
+ </li>
70
+ <li>
71
+ I used a temperature of 0 and a max token limit of 600 for each test
72
+ (that's why a lot of answers are cropped). The rest are default
73
+ settings.
74
+ </li>
75
+ <li>
76
+ I made this with a mix of APIs from OpenRouter, TogetherAI, OpenAI,
77
+ Anthropic, Cohere, Aleph Alpha & AI21.
78
+ </li>
79
+ <li>
80
+ This is imperfect. Not all prompts are good for grading. There also
81
+ seems to be some problems with stop sequences on TogetherAI models.
82
+ </li>
83
+ <li>Feedback, ideas or say hi: vince [at] llmonitor.com</li>
84
+ <li>
85
+ Shameless plug: I'm building an{" "}
86
+ <a href="https://github.com/llmonitor/llmonitor">
87
+ open-source observability tool for AI devs.
88
+ </a>
89
+ </li>
90
+ </ul>
91
+
92
+ <table style={{ maxWidth: 600, margin: "40px 0" }}>
93
+ <th>
94
+ <p>
95
+ Edit: as this got popular, I added an email form to receive
96
+ notifications for future benchmark results:
97
+ </p>
98
+ <iframe
99
+ src="https://embeds.beehiiv.com/65bd6af1-2dea-417a-baf2-b65bc27e1610?slim=true"
100
+ height="52"
101
+ frameborder="0"
102
+ scrolling="no"
103
+ style={{
104
+ width: 400,
105
+ border: "none",
106
+ transform: "scale(0.8)",
107
+ transformOrigin: "left",
108
+ }}
109
+ ></iframe>
110
+ <br />
111
+ <small>(no spam, max 1 email per month)</small>
112
+ </th>
113
+ </table>
114
+ </>
115
+ )
116
+ }
app/actions.js ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use server"
2
+
3
+ import { sendEmail } from "@/utils/email"
4
+ import db from "@/utils/db"
5
+
6
+ import jwt from "jsonwebtoken"
7
+
8
+ export async function submitPrompt(prevState, formData) {
9
+ try {
10
+ // await createItem(formData.get('todo'))
11
+ const prompt = formData.get("prompt")
12
+ const email = formData.get("email")
13
+ const recaptchaValue = formData.get("g-recaptcha-response")
14
+
15
+ console.log({ prompt, email, recaptchaValue })
16
+
17
+ return revalidatePath("/")
18
+ } catch (e) {
19
+ return { message: "Failed to create" }
20
+ }
21
+ }
22
+
23
+ export async function submitLogin(prevState, formData) {
24
+ const email = formData.get("email")
25
+ const recaptcha = formData.get("g-recaptcha-response")
26
+
27
+ // check captcha
28
+
29
+ console.log({ email, recaptcha })
30
+
31
+ const captchaResponse = await fetch(
32
+ `https://www.google.com/recaptcha/api/siteverify`,
33
+ {
34
+ method: "POST",
35
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
36
+ body: `secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${recaptcha}`,
37
+ }
38
+ )
39
+ const captchaData = await captchaResponse.json()
40
+
41
+ console.log({ captchaData })
42
+ if (!captchaData.success) {
43
+ console.log("failed captcha")
44
+ return { error: "Failed to verify captcha" }
45
+ }
46
+
47
+ console.log("passed captcha")
48
+
49
+ // upsert
50
+ const [userObj] =
51
+ await db`INSERT INTO users (email) VALUES (${email}) ON CONFLICT (email) DO UPDATE SET email = ${email} RETURNING *`
52
+
53
+ const token = jwt.sign(
54
+ {
55
+ userId: userObj.id,
56
+ exp: Math.floor(Date.now() / 1000) + 60 * 60, // 1 hour
57
+ },
58
+ process.env.JWT_SECRET
59
+ )
60
+
61
+ await sendEmail({
62
+ subject: `please confirm your email`,
63
+ to: [email],
64
+ from: process.env.EMAIL_FROM,
65
+ text: `Hi,
66
+
67
+ For anti-spam measures please confirm your email before upvoting or submitting:
68
+
69
+ ${process.env.NEXT_PUBLIC_SITE_URL}/api/confirm?token=${token}`,
70
+ })
71
+
72
+ console.log("sent email")
73
+
74
+ return { message: "Check your mailbox" }
75
+ }
app/api/confirm/route.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import jwt from "jsonwebtoken"
2
+ import db from "@/utils/db"
3
+
4
+ export async function GET(request) {
5
+ const searchParams = request.nextUrl.searchParams
6
+ const token = searchParams.get("token")
7
+
8
+ console.log("token", token)
9
+
10
+ const { userId } = jwt.verify(token, process.env.JWT_SECRET)
11
+
12
+ const [userObj] =
13
+ await db`UPDATE users SET confirmed = true WHERE id = ${userId} RETURNING *`
14
+
15
+ const longLivedToken = jwt.sign(
16
+ {
17
+ userId: userObj.id,
18
+ exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, // 1 month
19
+ },
20
+ process.env.JWT_SECRET
21
+ )
22
+
23
+ return new Response(null, {
24
+ status: 302,
25
+ headers: {
26
+ "Set-Cookie": `token=${longLivedToken}; path=/; HttpOnly`,
27
+ Location: `/prompts`,
28
+ },
29
+ })
30
+ }
app/api/upvote/route.js ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import db from "@/utils/db"
2
+ import jwt from "jsonwebtoken"
3
+
4
+ export async function GET(request) {
5
+ try {
6
+ const token = request.cookies.get("token")
7
+
8
+ const searchParams = request.nextUrl.searchParams
9
+ const prompt = searchParams.get("prompt")
10
+
11
+ const { userId } = jwt.verify(token.value, process.env.JWT_SECRET)
12
+
13
+ const [userObj] = await db`SELECT * FROM users WHERE id = ${userId}`
14
+ if (!userObj) throw new Error("user not found")
15
+
16
+ // insert vote for prompt
17
+
18
+ const [vote] =
19
+ await db`INSERT INTO votes ("user", prompt) VALUES (${userId}, ${prompt}) RETURNING *`
20
+
21
+ return new Response("upvoted", {
22
+ status: 200,
23
+ })
24
+ } catch (e) {
25
+ return new Response(e.message, {
26
+ status: 500,
27
+ })
28
+ }
29
+ }
app/compare/[slugs]/page.js ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Link from "next/link"
2
+ import db, { getModels } from "@/utils/db"
3
+
4
+ export default async function Comparison({ params }) {
5
+ const { slugs } = params
6
+
7
+ const [model1, model2] = slugs.split("-vs-")
8
+
9
+ const models = await getModels()
10
+
11
+ const model1Data = models.find((m) => m.slug === model1)
12
+ const model2Data = models.find((m) => m.slug === model2)
13
+
14
+ // Get the models' results from the DB,
15
+ const results =
16
+ await db`SELECT * FROM results INNER JOIN prompts ON results.prompt = prompts.id WHERE model = ${model1Data.id} OR model = ${model2Data.id}`
17
+
18
+ // Group and convert to table data with: prompt text, model 1 result, model 2 result
19
+
20
+ const tableData = results.reduce((acc, result) => {
21
+ const prompt = result.text
22
+
23
+ // If the prompt is not in the accumulator, add it
24
+ if (!acc[prompt]) {
25
+ acc[prompt] = {
26
+ prompt,
27
+ }
28
+ }
29
+
30
+ // Add the result to the prompt
31
+ acc[prompt][result.model === model1Data.id ? "model1" : "model2"] = result
32
+
33
+ return acc
34
+ }, {})
35
+
36
+ // Convert to array
37
+
38
+ const tableDataArray = Object.values(tableData)
39
+
40
+ return (
41
+ <table style={{ maxWidth: 1200 }}>
42
+ <thead>
43
+ <tr>
44
+ <th>Prompt</th>
45
+ <th>{model1Data?.name}</th>
46
+ <th>{model2Data?.name}</th>
47
+ </tr>
48
+ </thead>
49
+ <tbody>
50
+ {tableDataArray.map((row, i) => (
51
+ <tr key={i}>
52
+ <td>
53
+ <pre>{row.prompt}</pre>
54
+ </td>
55
+ <td>
56
+ <pre>{row.model1?.result?.trim()}</pre>
57
+ </td>
58
+ <td>
59
+ <pre>{row.model2?.result?.trim()}</pre>
60
+ </td>
61
+ </tr>
62
+ ))}
63
+ </tbody>
64
+ </table>
65
+ )
66
+ }
app/compare/layout.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { getModels } from "@/utils/db"
2
+ import SelectModels from "@/components/SelectModels"
3
+ import { Suspense } from "react"
4
+
5
+ export default async function CompareLayout({ children }) {
6
+ const models = await getModels()
7
+
8
+ return (
9
+ <>
10
+ <SelectModels models={models} />
11
+ <br />
12
+ <br />
13
+ <Suspense fallback={<p>Loading...</p>}>{children}</Suspense>
14
+ </>
15
+ )
16
+ }
app/compare/loading.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ export default function Loading() {
2
+ return <p>Loading...</p>
3
+ }
app/compare/page.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ export default function CompareHome() {
2
+ return <p>Select models to compare.</p>
3
+ }
app/layout.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Link from "next/link"
2
+ import "@/styles/globals.css"
3
+ import { Suspense } from "react"
4
+
5
+ export const metadata = {
6
+ title: "LLMonitor Benchmarks",
7
+ description: "Benchmarks and scoring of LLMs",
8
+ }
9
+
10
+ export default function RootLayout({ children }) {
11
+ return (
12
+ <html lang="en">
13
+ <body>
14
+ <main>
15
+ <h1>LLMonitor Benchmarks</h1>
16
+
17
+ <p style={{ margin: "16px 0" }}>
18
+ <Link href="/">leaderboard</Link>
19
+ {" | "}
20
+ <Link href="/prompts">dataset</Link>
21
+ {" | "}
22
+ <Link href="/compare">compare</Link>
23
+ {" | "}
24
+ <Link href="/about">about</Link>
25
+ </p>
26
+ <br />
27
+
28
+ <Suspense fallback={<p>Loading...</p>}>{children}</Suspense>
29
+ </main>
30
+ <footer>
31
+ <br />
32
+ <p>
33
+ Credit:{" "}
34
+ <a href="https://twitter.com/vincelwt" target="_blank">
35
+ @vincelwt
36
+ </a>{" "}
37
+ /{" "}
38
+ <a href="https://llmonitor.com" target="_blank">
39
+ llmonitor
40
+ </a>
41
+ </p>
42
+ </footer>
43
+ </body>
44
+ </html>
45
+ )
46
+ }
app/loading.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ export default function Loading() {
2
+ return <p>Loading...</p>
3
+ }
app/login/page.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+ import CaptchaInput from "@/components/CaptchaInput"
3
+ import { experimental_useFormState as useFormState } from "react-dom"
4
+ import { submitLogin } from "../actions"
5
+
6
+ export default function SignIn() {
7
+ const [state, formAction] = useFormState(submitLogin, {})
8
+
9
+ return (
10
+ <form
11
+ action={formAction}
12
+ style={{ background: "rgba(0,0,0,0.1)", padding: 10 }}
13
+ >
14
+ <input
15
+ required
16
+ type="email"
17
+ id="email"
18
+ name="email"
19
+ placeholder="Email"
20
+ />
21
+ <br />
22
+ <br />
23
+ <CaptchaInput />
24
+ <br />
25
+ <p>
26
+ For anti-spam measure please confirm your email before upvoting or
27
+ submitting prompts.
28
+ </p>
29
+
30
+ {state.error && (
31
+ <p
32
+ style={{
33
+ color: "red",
34
+ }}
35
+ >
36
+ {state.error}
37
+ </p>
38
+ )}
39
+
40
+ {state.message && <p>{state.message}</p>}
41
+
42
+ <input type="submit" value="Confirm email" />
43
+ </form>
44
+ )
45
+ }
app/page.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import db from "@/utils/db"
2
+ import Link from "next/link"
3
+
4
+ export default async function Leaderboard() {
5
+ const [potentialPoints] = await db`SELECT SUM(points) as total FROM rubrics`
6
+
7
+ const models = await db`
8
+ SELECT models.*, SUM(results.score) as total_score
9
+ FROM models
10
+ LEFT JOIN results ON models.id = results.model
11
+ GROUP BY models.id
12
+ ORDER BY total_score DESC;
13
+ `
14
+
15
+ return (
16
+ <>
17
+ <p>
18
+ Traditional LLMs benchmarks have drawbacks: they quickly become part of
19
+ training datasets and are hard to relate-to in terms of real-world
20
+ use-cases.
21
+ </p>
22
+ <p>
23
+ I made this as an experiment to address these issues. Here the dataset
24
+ is dynamic (changes every week) and composed of crowdsourced real-world
25
+ prompts.
26
+ </p>
27
+ <p>
28
+ We then use GPT-4 to grade each model's response against a set of
29
+ rubrics (more details on the about page). The prompt dataset is easily
30
+ explorable as the score is only 1 dimension.
31
+ </p>
32
+ <p>
33
+ The results are stored in Postgres database and those are the raw
34
+ results.
35
+ </p>
36
+
37
+ <br />
38
+ <table style={{ maxWidth: 600 }}>
39
+ <thead>
40
+ <tr>
41
+ <th width={70}>Rank</th>
42
+ <th width={250}>Model</th>
43
+ <th>Score</th>
44
+ <th>Results</th>
45
+ </tr>
46
+ </thead>
47
+ <tbody>
48
+ {models
49
+ .filter((s) => s.total_score)
50
+ .map((model, i) => (
51
+ <tr key={i}>
52
+ <td>{i + 1}</td>
53
+ <td>{model.name}</td>
54
+ <td>
55
+ {parseInt((model.total_score / potentialPoints.total) * 100)}
56
+ </td>
57
+ <td>
58
+ <Link
59
+ href={`/${model.api_id.split("/").pop().toLowerCase()}`}
60
+ >
61
+ view
62
+ </Link>
63
+ </td>
64
+ </tr>
65
+ ))}
66
+ </tbody>
67
+ </table>
68
+ </>
69
+ )
70
+ }
pages/[slug].js → app/prompts/[slug]/page.js RENAMED
@@ -1,59 +1,36 @@
1
- import getDB from "@/utils/getDB"
2
- import Head from "next/head"
3
  import Link from "next/link"
 
4
 
5
- export const getStaticPaths = async () => {
6
- const db = await getDB()
7
 
8
- const prompts = await db.all(`SELECT * FROM prompts`)
9
-
10
- return {
11
- paths: prompts.map((prompt) => ({
12
- params: { slug: prompt.slug },
13
- })),
14
- fallback: false,
15
- }
16
- }
17
-
18
- export const getStaticProps = async (props) => {
19
- const db = await getDB()
20
-
21
- const slug = props.params.slug
22
-
23
- const prompt = await db.get(`SELECT * FROM prompts WHERE slug = ?`, [slug])
24
 
25
  // get results with their model (join)
26
- const results = await db.all(
27
- `SELECT * FROM results INNER JOIN models ON results.model = models.id WHERE prompt = ? ORDER BY models.name ASC`,
28
- [prompt.id]
29
- )
30
 
31
- return { props: { prompt, results } }
32
- }
 
33
 
34
- export default function Prompt({ prompt, results }) {
35
  return (
36
  <>
37
- <Head>
38
- <title>LLM Benchmark</title>
39
- <meta name="description" content={`Asking models: ${prompt.text}`} />
40
- </Head>
41
  <h3>Prompt asked:</h3>
42
  <br />
43
  <pre style={{ maxWidth: 800 }}>{prompt.text}</pre>
44
  <br />
45
  {prompt.note && <p>Note: {prompt.note}</p>}
46
  <br />
47
- <Link href="/">Back to home</Link>
48
- <br />
49
- <br />
50
  <table>
51
  <thead>
52
  <tr>
53
- <th>Model</th>
54
  <th>Answer</th>
55
- <th>Latency</th>
56
- <th>Chars / s</th>
 
57
  </tr>
58
  </thead>
59
  <tbody>
@@ -70,43 +47,30 @@ export default function Prompt({ prompt, results }) {
70
  </Link>
71
  </td>
72
  <td>
73
- <pre>{result.result.trim()}</pre>
 
 
 
 
 
74
  </td>
75
- <td>{result.duration}ms</td>
76
- <td>{result.rate}</td>
77
  </tr>
78
  ))}
79
  </tbody>
80
  </table>
81
  <br />
82
- <Link href="/">Back to home</Link>
83
-
84
- <br />
85
- <br />
86
-
87
- <table style={{ maxWidth: 600 }}>
88
- <th>
89
- <p>
90
- Edit: as this got popular, I added an email form to receive
91
- notifications for future benchmark results:
92
- </p>
93
- <iframe
94
- src="https://embeds.beehiiv.com/65bd6af1-2dea-417a-baf2-b65bc27e1610?slim=true"
95
- height="52"
96
- frameborder="0"
97
- scrolling="no"
98
- style={{
99
- width: 400,
100
- border: "none",
101
- transform: "scale(0.8)",
102
- transformOrigin: "left",
103
- }}
104
- ></iframe>
105
- <br />
106
- <small>(no spam, max 1 email per month)</small>
107
- </th>
108
- </table>
109
- <br />
110
  </>
111
  )
112
  }
 
 
 
1
  import Link from "next/link"
2
+ import db from "@/utils/db"
3
 
4
+ export default async function PromptDetails({ params }) {
5
+ const { slug } = params
6
 
7
+ const [prompt] = await db`SELECT * FROM prompts WHERE slug = ${slug}`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  // get results with their model (join)
10
+ const results =
11
+ await db`SELECT * FROM results INNER JOIN models ON results.model = models.id WHERE prompt = ${prompt.id} ORDER BY models.name ASC`
 
 
12
 
13
+ console.log("results", results)
14
+
15
+ const rubrics = await db`SELECT * FROM rubrics WHERE prompt = ${prompt.id}`
16
 
 
17
  return (
18
  <>
 
 
 
 
19
  <h3>Prompt asked:</h3>
20
  <br />
21
  <pre style={{ maxWidth: 800 }}>{prompt.text}</pre>
22
  <br />
23
  {prompt.note && <p>Note: {prompt.note}</p>}
24
  <br />
25
+
 
 
26
  <table>
27
  <thead>
28
  <tr>
29
+ <th width={200}>Model</th>
30
  <th>Answer</th>
31
+ <th width={150}>Latency</th>
32
+ <th width={150}>Rate</th>
33
+ <th width={150}>Score</th>
34
  </tr>
35
  </thead>
36
  <tbody>
 
47
  </Link>
48
  </td>
49
  <td>
50
+ <pre>{result.result.trim().substring(0, 1000)}</pre>
51
+ </td>
52
+ <td>{parseInt(result.duration)}ms</td>
53
+ <td>{result.rate.toFixed(2)}</td>
54
+ <td>
55
+ {typeof result.score === "number" ? result.score : "not rated"}
56
  </td>
 
 
57
  </tr>
58
  ))}
59
  </tbody>
60
  </table>
61
  <br />
62
+ <pre>
63
+ <p>This prompt is automatically graded using these rubrics:</p>
64
+ <ul>
65
+ {rubrics
66
+ .sort((a, b) => a.grading - b.grading)
67
+ .map((rubric, i) => (
68
+ <li key={i}>
69
+ the answer {rubric.grading} ({rubric.points} points)
70
+ </li>
71
+ ))}
72
+ </ul>
73
+ </pre>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  </>
75
  )
76
  }
app/prompts/layout.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { cookies } from "next/headers"
2
+ import Link from "next/link"
3
+
4
+ export default function PromptsLayout({ children }) {
5
+ const cookiesList = cookies()
6
+ const token = cookiesList.get("token")
7
+
8
+ return (
9
+ <>
10
+ <p>
11
+ {"dataset menu: "}
12
+ <Link href="/prompts">current dataset</Link> {" | "}
13
+ <Link href="/prompts/new">vote</Link> {" | "}
14
+ <Link href={!token ? "/login" : "/prompts/submit"}>submit</Link>
15
+ </p>
16
+ <br />
17
+ {children}
18
+ </>
19
+ )
20
+ }
app/prompts/new/page.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import UpvoteBtn from "@/components/UpvoteBtn"
2
+ import db from "@/utils/db"
3
+ import { cookies } from "next/headers"
4
+ import Link from "next/link"
5
+
6
+ export default async function Dataset() {
7
+ const cookiesList = cookies()
8
+
9
+ const logged = cookiesList.has("token")
10
+
11
+ // get prompts with selected != true joined with sum of votes for each
12
+ const promptsWithVotes =
13
+ await db`SELECT prompts.*, COUNT(votes.id) AS votes FROM prompts LEFT JOIN votes ON prompts.id = votes.prompt WHERE prompts.selected IS NOT TRUE GROUP BY prompts.id ORDER BY votes DESC`
14
+
15
+ return (
16
+ <>
17
+ <table
18
+ border="0"
19
+ cellPadding="0"
20
+ cellSpacing="0"
21
+ style={{ maxWidth: 600 }}
22
+ >
23
+ <tbody>
24
+ {promptsWithVotes.map((prompt, i) => (
25
+ <tr key={i}>
26
+ <td width={30}>{i + 1}</td>
27
+ <td>
28
+ <span>{prompt.votes} points</span>
29
+ <br />
30
+ {logged ? (
31
+ <UpvoteBtn id={prompt.id} />
32
+ ) : (
33
+ <Link href="/login">
34
+ <small>upvote</small>
35
+ </Link>
36
+ )}
37
+ </td>
38
+ <td>
39
+ <pre style={{ maxWidth: 800 }}>{prompt.text}</pre>
40
+ </td>
41
+ </tr>
42
+ ))}
43
+ </tbody>
44
+ </table>
45
+ </>
46
+ )
47
+ }
app/prompts/page.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import db from "@/utils/db"
2
+ import Link from "next/link"
3
+
4
+ export default async function Dataset() {
5
+ const prompts =
6
+ await db`SELECT * FROM prompts WHERE selected = true ORDER BY text ASC `
7
+
8
+ const types = Array.from(new Set(prompts.map((p) => p.type)))
9
+
10
+ return (
11
+ <>
12
+ {types.map((type, k) => (
13
+ <div key={k}>
14
+ <p>{type}:</p>
15
+ <br />
16
+ <ul>
17
+ {prompts
18
+ .filter((p) => p.type === type)
19
+ .map((prompt, i) => (
20
+ <li key={i}>
21
+ <pre style={{ maxWidth: 800 }}>
22
+ {prompt.text}
23
+ <br />
24
+ <br />
25
+ <Link href={`/prompts/${prompt.slug}`}>results</Link>
26
+ </pre>
27
+ </li>
28
+ ))}
29
+ </ul>
30
+ </div>
31
+ ))}
32
+ </>
33
+ )
34
+ }
app/prompts/submit/page.js ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import db from "@/utils/db"
2
+ import { cookies } from "next/headers"
3
+
4
+ import Link from "next/link"
5
+ import { redirect } from "next/navigation"
6
+
7
+ import jwt from "jsonwebtoken"
8
+
9
+ export default async function Submit() {
10
+ // Get user session token
11
+
12
+ async function create(formData) {
13
+ "use server"
14
+
15
+ const cookiesList = cookies()
16
+ const token = cookiesList.get("token")
17
+
18
+ console.log("token", token)
19
+
20
+ if (!token) throw new Error("not logged")
21
+
22
+ const { userId } = jwt.verify(token.value, process.env.JWT_SECRET)
23
+
24
+ const [userObj] = await db`SELECT * FROM users WHERE id = ${userId}`
25
+ if (!userObj) throw new Error("user not found")
26
+
27
+ const text = formData.get("prompt")
28
+ const slug = formData.get("slug")
29
+
30
+ if (text.length <= 20 || text.length > 1000)
31
+ throw new Error("prompt too long or too short")
32
+
33
+ const [prompt] =
34
+ await db`INSERT INTO prompts (text, submitter, slug) VALUES (${text}, ${userObj.id}, ${slug}) RETURNING *`
35
+
36
+ const [vote] =
37
+ await db`INSERT INTO votes ("user", prompt) VALUES (${userObj.id}, ${prompt.id}) RETURNING *`
38
+
39
+ redirect(`/prompts`)
40
+
41
+ // send email to user to confirm submission
42
+ }
43
+
44
+ return (
45
+ <>
46
+ <p>Submit a new prompt to be included to the benchmark.</p>
47
+ <p>
48
+ Each week, the highest rated prompt will become part of the benchmark.
49
+ </p>
50
+ <p>What makes a good prompt:</p>
51
+ <ul>
52
+ <li>
53
+ Can be broke down <Link href="/about">into rubrics</Link> & evaluated
54
+ </li>
55
+ <li>
56
+ Is original and not popular on the internet (unlikely to be already
57
+ part in the benchmark)
58
+ </li>
59
+ <li>Is not too long (max 1000 characters)</li>
60
+ </ul>
61
+ <br />
62
+
63
+ <form action={create}>
64
+ <table
65
+ id="hnmain"
66
+ border="0"
67
+ cellPadding="0"
68
+ cellSpacing="0"
69
+ style={{ maxWidth: 680 }}
70
+ >
71
+ <tbody>
72
+ <tr>
73
+ <td>
74
+ <label htmlFor="prompt">Prompt</label>
75
+ </td>
76
+ <td>
77
+ <textarea
78
+ id="prompt"
79
+ name="prompt"
80
+ rows="10"
81
+ minLength={20}
82
+ maxLength={1000}
83
+ cols="50"
84
+ required
85
+ />
86
+ </td>
87
+ </tr>
88
+ <tr>
89
+ <td>
90
+ <label htmlFor="rubrics">Slug</label>
91
+ </td>
92
+ <td>
93
+ <input
94
+ type="text"
95
+ id="slug"
96
+ name="slug"
97
+ required
98
+ pattern="^[a-z0-9]+(?:-[a-z0-9]+)*$"
99
+ />
100
+ </td>
101
+ </tr>
102
+ </tbody>
103
+ </table>
104
+ <br />
105
+ <p>
106
+ To prevent spam, you will receive an email to confirm your submission.
107
+ </p>
108
+
109
+ <button type="submit">Submit</button>
110
+ </form>
111
+ </>
112
+ )
113
+ }
components/CaptchaInput.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+ import ReCAPTCHA from "react-google-recaptcha"
3
+ import { useState } from "react"
4
+
5
+ export default function CaptchaInput() {
6
+ const [recaptchaValue, setRecaptchaValue] = useState(null)
7
+
8
+ return (
9
+ <>
10
+ <input
11
+ type="hidden"
12
+ name="g-recaptcha-response"
13
+ value={recaptchaValue || ""}
14
+ />
15
+ <ReCAPTCHA
16
+ sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}
17
+ onChange={(value) => setRecaptchaValue(value)}
18
+ />
19
+ </>
20
+ )
21
+ }
components/SelectModels.js ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import { useEffect, useState } from "react"
4
+ import { useRouter } from "next/navigation"
5
+
6
+ export default function SelectModels({ models }) {
7
+ const router = useRouter()
8
+ const [model1, setModel1] = useState("")
9
+ const [model2, setModel2] = useState("")
10
+
11
+ useEffect(() => {
12
+ if (model1 && model2) {
13
+ router.push(`/compare/${model1}-vs-${model2}`)
14
+ }
15
+ }, [model1, model2])
16
+
17
+ return (
18
+ <div>
19
+ <select onChange={(e) => setModel1(e.target.value)}>
20
+ <option value="">Select model 1</option>
21
+ {models
22
+
23
+ .sort((a, b) => b.total_score - a.total_score)
24
+ .map((model, i) => (
25
+ <option key={i} value={model.slug}>
26
+ {model.name}
27
+ </option>
28
+ ))}
29
+ </select>
30
+ <select onChange={(e) => setModel2(e.target.value)}>
31
+ <option value="">Select model 2</option>
32
+ {models
33
+
34
+ .sort((a, b) => b.total_score - a.total_score)
35
+ .map((model, i) => (
36
+ <option key={i} value={model.slug}>
37
+ {model.name}
38
+ </option>
39
+ ))}
40
+ </select>
41
+ </div>
42
+ )
43
+ }
components/UpvoteBtn.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import { useState } from "react"
4
+
5
+ export default function UpvoteBtn({ id }) {
6
+ const [upvoted, setUpvoted] = useState(false)
7
+
8
+ const upvote = async (id) => {
9
+ const response = await fetch(`/api/upvote?prompt=${id}`)
10
+ const data = await response.text()
11
+ if (data === "ok") return setUpvoted(true)
12
+ alert(data)
13
+ }
14
+
15
+ return (
16
+ <a href="#" onClick={() => upvote(id)}>
17
+ <small>{upvoted ? "Upvoted" : "Upvote"}</small>
18
+ </a>
19
+ )
20
+ }
next.config.js CHANGED
@@ -2,6 +2,10 @@
2
  const nextConfig = {
3
  reactStrictMode: true,
4
  output: "standalone",
 
 
 
 
5
  }
6
 
7
  module.exports = nextConfig
 
2
  const nextConfig = {
3
  reactStrictMode: true,
4
  output: "standalone",
5
+
6
+ experimental: {
7
+ serverActions: true,
8
+ },
9
  }
10
 
11
  module.exports = nextConfig
package-lock.json CHANGED
@@ -8,49 +8,82 @@
8
  "name": "benchmarks",
9
  "version": "0.1.0",
10
  "dependencies": {
11
- "next": "13.4.19",
 
 
12
  "next-plausible": "^3.11.1",
13
  "openai": "^4.5.0",
14
- "react": "18.2.0",
15
- "react-dom": "18.2.0",
16
- "sqlite": "^5.0.1",
17
- "sqlite3": "^5.1.6"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
  },
20
- "node_modules/@gar/promisify": {
21
- "version": "1.1.3",
22
- "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
23
- "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
24
- "optional": true
 
 
 
25
  },
26
- "node_modules/@mapbox/node-pre-gyp": {
27
- "version": "1.0.11",
28
- "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
29
- "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
30
  "dependencies": {
31
- "detect-libc": "^2.0.0",
32
- "https-proxy-agent": "^5.0.0",
33
- "make-dir": "^3.1.0",
34
- "node-fetch": "^2.6.7",
35
- "nopt": "^5.0.0",
36
- "npmlog": "^5.0.1",
37
- "rimraf": "^3.0.2",
38
- "semver": "^7.3.5",
39
- "tar": "^6.1.11"
40
  },
41
- "bin": {
42
- "node-pre-gyp": "bin/node-pre-gyp"
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
  },
45
  "node_modules/@next/env": {
46
- "version": "13.4.19",
47
- "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.19.tgz",
48
- "integrity": "sha512-FsAT5x0jF2kkhNkKkukhsyYOrRqtSxrEhfliniIq0bwWbuXLgyt3Gv0Ml+b91XwjwArmuP7NxCiGd++GGKdNMQ=="
49
  },
50
  "node_modules/@next/swc-darwin-arm64": {
51
- "version": "13.4.19",
52
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.19.tgz",
53
- "integrity": "sha512-vv1qrjXeGbuF2mOkhkdxMDtv9np7W4mcBtaDnHU+yJG+bBwa6rYsYSCI/9Xm5+TuF5SbZbrWO6G1NfTh1TMjvQ==",
54
  "cpu": [
55
  "arm64"
56
  ],
@@ -63,9 +96,9 @@
63
  }
64
  },
65
  "node_modules/@next/swc-darwin-x64": {
66
- "version": "13.4.19",
67
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.19.tgz",
68
- "integrity": "sha512-jyzO6wwYhx6F+7gD8ddZfuqO4TtpJdw3wyOduR4fxTUCm3aLw7YmHGYNjS0xRSYGAkLpBkH1E0RcelyId6lNsw==",
69
  "cpu": [
70
  "x64"
71
  ],
@@ -78,9 +111,9 @@
78
  }
79
  },
80
  "node_modules/@next/swc-linux-arm64-gnu": {
81
- "version": "13.4.19",
82
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.19.tgz",
83
- "integrity": "sha512-vdlnIlaAEh6H+G6HrKZB9c2zJKnpPVKnA6LBwjwT2BTjxI7e0Hx30+FoWCgi50e+YO49p6oPOtesP9mXDRiiUg==",
84
  "cpu": [
85
  "arm64"
86
  ],
@@ -93,9 +126,9 @@
93
  }
94
  },
95
  "node_modules/@next/swc-linux-arm64-musl": {
96
- "version": "13.4.19",
97
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.19.tgz",
98
- "integrity": "sha512-aU0HkH2XPgxqrbNRBFb3si9Ahu/CpaR5RPmN2s9GiM9qJCiBBlZtRTiEca+DC+xRPyCThTtWYgxjWHgU7ZkyvA==",
99
  "cpu": [
100
  "arm64"
101
  ],
@@ -108,9 +141,9 @@
108
  }
109
  },
110
  "node_modules/@next/swc-linux-x64-gnu": {
111
- "version": "13.4.19",
112
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.19.tgz",
113
- "integrity": "sha512-htwOEagMa/CXNykFFeAHHvMJeqZfNQEoQvHfsA4wgg5QqGNqD5soeCer4oGlCol6NGUxknrQO6VEustcv+Md+g==",
114
  "cpu": [
115
  "x64"
116
  ],
@@ -123,9 +156,9 @@
123
  }
124
  },
125
  "node_modules/@next/swc-linux-x64-musl": {
126
- "version": "13.4.19",
127
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.19.tgz",
128
- "integrity": "sha512-4Gj4vvtbK1JH8ApWTT214b3GwUh9EKKQjY41hH/t+u55Knxi/0wesMzwQRhppK6Ddalhu0TEttbiJ+wRcoEj5Q==",
129
  "cpu": [
130
  "x64"
131
  ],
@@ -138,9 +171,9 @@
138
  }
139
  },
140
  "node_modules/@next/swc-win32-arm64-msvc": {
141
- "version": "13.4.19",
142
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.19.tgz",
143
- "integrity": "sha512-bUfDevQK4NsIAHXs3/JNgnvEY+LRyneDN788W2NYiRIIzmILjba7LaQTfihuFawZDhRtkYCv3JDC3B4TwnmRJw==",
144
  "cpu": [
145
  "arm64"
146
  ],
@@ -153,9 +186,9 @@
153
  }
154
  },
155
  "node_modules/@next/swc-win32-ia32-msvc": {
156
- "version": "13.4.19",
157
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.19.tgz",
158
- "integrity": "sha512-Y5kikILFAr81LYIFaw6j/NrOtmiM4Sf3GtOc0pn50ez2GCkr+oejYuKGcwAwq3jiTKuzF6OF4iT2INPoxRycEA==",
159
  "cpu": [
160
  "ia32"
161
  ],
@@ -168,9 +201,9 @@
168
  }
169
  },
170
  "node_modules/@next/swc-win32-x64-msvc": {
171
- "version": "13.4.19",
172
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.19.tgz",
173
- "integrity": "sha512-YzA78jBDXMYiINdPdJJwGgPNT3YqBNNGhsthsDoWHL9p24tEJn9ViQf/ZqTbwSpX/RrkPupLfuuTH2sf73JBAw==",
174
  "cpu": [
175
  "x64"
176
  ],
@@ -182,47 +215,22 @@
182
  "node": ">= 10"
183
  }
184
  },
185
- "node_modules/@npmcli/fs": {
186
  "version": "1.1.1",
187
- "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
188
- "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
189
- "optional": true,
190
- "dependencies": {
191
- "@gar/promisify": "^1.0.1",
192
- "semver": "^7.3.5"
193
- }
194
- },
195
- "node_modules/@npmcli/move-file": {
196
- "version": "1.1.2",
197
- "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
198
- "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
199
- "deprecated": "This functionality has been moved to @npmcli/fs",
200
- "optional": true,
201
- "dependencies": {
202
- "mkdirp": "^1.0.4",
203
- "rimraf": "^3.0.2"
204
- },
205
- "engines": {
206
- "node": ">=10"
207
  }
208
  },
209
  "node_modules/@swc/helpers": {
210
- "version": "0.5.1",
211
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz",
212
- "integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==",
213
  "dependencies": {
214
  "tslib": "^2.4.0"
215
  }
216
  },
217
- "node_modules/@tootallnate/once": {
218
- "version": "1.1.2",
219
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
220
- "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
221
- "optional": true,
222
- "engines": {
223
- "node": ">= 6"
224
- }
225
- },
226
  "node_modules/@types/node": {
227
  "version": "18.17.14",
228
  "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.14.tgz",
@@ -237,10 +245,28 @@
237
  "form-data": "^3.0.0"
238
  }
239
  },
240
- "node_modules/abbrev": {
241
- "version": "1.1.1",
242
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
243
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  },
245
  "node_modules/abort-controller": {
246
  "version": "3.0.0",
@@ -253,17 +279,6 @@
253
  "node": ">=6.5"
254
  }
255
  },
256
- "node_modules/agent-base": {
257
- "version": "6.0.2",
258
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
259
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
260
- "dependencies": {
261
- "debug": "4"
262
- },
263
- "engines": {
264
- "node": ">= 6.0.0"
265
- }
266
- },
267
  "node_modules/agentkeepalive": {
268
  "version": "4.5.0",
269
  "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
@@ -275,66 +290,28 @@
275
  "node": ">= 8.0.0"
276
  }
277
  },
278
- "node_modules/aggregate-error": {
279
- "version": "3.1.0",
280
- "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
281
- "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
282
- "optional": true,
283
- "dependencies": {
284
- "clean-stack": "^2.0.0",
285
- "indent-string": "^4.0.0"
286
- },
287
- "engines": {
288
- "node": ">=8"
289
- }
290
- },
291
- "node_modules/ansi-regex": {
292
- "version": "5.0.1",
293
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
294
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
295
- "engines": {
296
- "node": ">=8"
297
- }
298
- },
299
- "node_modules/aproba": {
300
- "version": "2.0.0",
301
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
302
- "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
303
- },
304
- "node_modules/are-we-there-yet": {
305
- "version": "2.0.0",
306
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
307
- "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
308
- "dependencies": {
309
- "delegates": "^1.0.0",
310
- "readable-stream": "^3.6.0"
311
- },
312
- "engines": {
313
- "node": ">=10"
314
- }
315
- },
316
  "node_modules/asynckit": {
317
  "version": "0.4.0",
318
  "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
319
  "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
320
  },
321
- "node_modules/balanced-match": {
322
- "version": "1.0.2",
323
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
324
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
325
- },
326
  "node_modules/base-64": {
327
  "version": "0.1.0",
328
  "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
329
  "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
330
  },
331
- "node_modules/brace-expansion": {
332
- "version": "1.1.11",
333
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
334
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
335
- "dependencies": {
336
- "balanced-match": "^1.0.0",
337
- "concat-map": "0.0.1"
 
 
 
 
 
338
  }
339
  },
340
  "node_modules/busboy": {
@@ -348,35 +325,6 @@
348
  "node": ">=10.16.0"
349
  }
350
  },
351
- "node_modules/cacache": {
352
- "version": "15.3.0",
353
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
354
- "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
355
- "optional": true,
356
- "dependencies": {
357
- "@npmcli/fs": "^1.0.0",
358
- "@npmcli/move-file": "^1.0.1",
359
- "chownr": "^2.0.0",
360
- "fs-minipass": "^2.0.0",
361
- "glob": "^7.1.4",
362
- "infer-owner": "^1.0.4",
363
- "lru-cache": "^6.0.0",
364
- "minipass": "^3.1.1",
365
- "minipass-collect": "^1.0.2",
366
- "minipass-flush": "^1.0.5",
367
- "minipass-pipeline": "^1.2.2",
368
- "mkdirp": "^1.0.3",
369
- "p-map": "^4.0.0",
370
- "promise-inflight": "^1.0.1",
371
- "rimraf": "^3.0.2",
372
- "ssri": "^8.0.1",
373
- "tar": "^6.0.2",
374
- "unique-filename": "^1.1.1"
375
- },
376
- "engines": {
377
- "node": ">= 10"
378
- }
379
- },
380
  "node_modules/caniuse-lite": {
381
  "version": "1.0.30001529",
382
  "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001529.tgz",
@@ -404,36 +352,11 @@
404
  "node": "*"
405
  }
406
  },
407
- "node_modules/chownr": {
408
- "version": "2.0.0",
409
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
410
- "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
411
- "engines": {
412
- "node": ">=10"
413
- }
414
- },
415
- "node_modules/clean-stack": {
416
- "version": "2.2.0",
417
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
418
- "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
419
- "optional": true,
420
- "engines": {
421
- "node": ">=6"
422
- }
423
- },
424
  "node_modules/client-only": {
425
  "version": "0.0.1",
426
  "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
427
  "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
428
  },
429
- "node_modules/color-support": {
430
- "version": "1.1.3",
431
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
432
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
433
- "bin": {
434
- "color-support": "bin.js"
435
- }
436
- },
437
  "node_modules/combined-stream": {
438
  "version": "1.0.8",
439
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -445,15 +368,13 @@
445
  "node": ">= 0.8"
446
  }
447
  },
448
- "node_modules/concat-map": {
449
- "version": "0.0.1",
450
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
451
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
452
- },
453
- "node_modules/console-control-strings": {
454
- "version": "1.1.0",
455
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
456
- "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
457
  },
458
  "node_modules/crypt": {
459
  "version": "0.0.2",
@@ -463,21 +384,11 @@
463
  "node": "*"
464
  }
465
  },
466
- "node_modules/debug": {
467
- "version": "4.3.4",
468
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
469
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
470
- "dependencies": {
471
- "ms": "2.1.2"
472
- },
473
- "engines": {
474
- "node": ">=6.0"
475
- },
476
- "peerDependenciesMeta": {
477
- "supports-color": {
478
- "optional": true
479
- }
480
- }
481
  },
482
  "node_modules/delayed-stream": {
483
  "version": "1.0.0",
@@ -487,19 +398,6 @@
487
  "node": ">=0.4.0"
488
  }
489
  },
490
- "node_modules/delegates": {
491
- "version": "1.0.0",
492
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
493
- "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
494
- },
495
- "node_modules/detect-libc": {
496
- "version": "2.0.2",
497
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
498
- "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
499
- "engines": {
500
- "node": ">=8"
501
- }
502
- },
503
  "node_modules/digest-fetch": {
504
  "version": "1.3.0",
505
  "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",
@@ -509,35 +407,24 @@
509
  "md5": "^2.3.0"
510
  }
511
  },
512
- "node_modules/emoji-regex": {
513
- "version": "8.0.0",
514
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
515
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
 
 
 
516
  },
517
  "node_modules/encoding": {
518
  "version": "0.1.13",
519
  "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
520
  "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
521
  "optional": true,
 
522
  "dependencies": {
523
  "iconv-lite": "^0.6.2"
524
  }
525
  },
526
- "node_modules/env-paths": {
527
- "version": "2.2.1",
528
- "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
529
- "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
530
- "optional": true,
531
- "engines": {
532
- "node": ">=6"
533
- }
534
- },
535
- "node_modules/err-code": {
536
- "version": "2.0.3",
537
- "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
538
- "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
539
- "optional": true
540
- },
541
  "node_modules/event-target-shim": {
542
  "version": "5.0.1",
543
  "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
@@ -576,60 +463,6 @@
576
  "node": ">= 12.20"
577
  }
578
  },
579
- "node_modules/fs-minipass": {
580
- "version": "2.1.0",
581
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
582
- "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
583
- "dependencies": {
584
- "minipass": "^3.0.0"
585
- },
586
- "engines": {
587
- "node": ">= 8"
588
- }
589
- },
590
- "node_modules/fs.realpath": {
591
- "version": "1.0.0",
592
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
593
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
594
- },
595
- "node_modules/gauge": {
596
- "version": "3.0.2",
597
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
598
- "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
599
- "dependencies": {
600
- "aproba": "^1.0.3 || ^2.0.0",
601
- "color-support": "^1.1.2",
602
- "console-control-strings": "^1.0.0",
603
- "has-unicode": "^2.0.1",
604
- "object-assign": "^4.1.1",
605
- "signal-exit": "^3.0.0",
606
- "string-width": "^4.2.3",
607
- "strip-ansi": "^6.0.1",
608
- "wide-align": "^1.1.2"
609
- },
610
- "engines": {
611
- "node": ">=10"
612
- }
613
- },
614
- "node_modules/glob": {
615
- "version": "7.2.3",
616
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
617
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
618
- "dependencies": {
619
- "fs.realpath": "^1.0.0",
620
- "inflight": "^1.0.4",
621
- "inherits": "2",
622
- "minimatch": "^3.1.1",
623
- "once": "^1.3.0",
624
- "path-is-absolute": "^1.0.0"
625
- },
626
- "engines": {
627
- "node": "*"
628
- },
629
- "funding": {
630
- "url": "https://github.com/sponsors/isaacs"
631
- }
632
- },
633
  "node_modules/glob-to-regexp": {
634
  "version": "0.4.1",
635
  "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
@@ -640,41 +473,12 @@
640
  "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
641
  "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
642
  },
643
- "node_modules/has-unicode": {
644
- "version": "2.0.1",
645
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
646
- "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
647
- },
648
- "node_modules/http-cache-semantics": {
649
- "version": "4.1.1",
650
- "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
651
- "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
652
- "optional": true
653
- },
654
- "node_modules/http-proxy-agent": {
655
- "version": "4.0.1",
656
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
657
- "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
658
- "optional": true,
659
- "dependencies": {
660
- "@tootallnate/once": "1",
661
- "agent-base": "6",
662
- "debug": "4"
663
- },
664
- "engines": {
665
- "node": ">= 6"
666
- }
667
- },
668
- "node_modules/https-proxy-agent": {
669
- "version": "5.0.1",
670
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
671
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
672
  "dependencies": {
673
- "agent-base": "6",
674
- "debug": "4"
675
- },
676
- "engines": {
677
- "node": ">= 6"
678
  }
679
  },
680
  "node_modules/humanize-ms": {
@@ -690,6 +494,7 @@
690
  "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
691
  "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
692
  "optional": true,
 
693
  "dependencies": {
694
  "safer-buffer": ">= 2.1.2 < 3.0.0"
695
  },
@@ -697,79 +502,98 @@
697
  "node": ">=0.10.0"
698
  }
699
  },
700
- "node_modules/imurmurhash": {
701
- "version": "0.1.4",
702
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
703
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
704
- "optional": true,
705
- "engines": {
706
- "node": ">=0.8.19"
 
 
 
 
707
  }
708
  },
709
- "node_modules/indent-string": {
710
  "version": "4.0.0",
711
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
712
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
713
- "optional": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
714
  "engines": {
715
- "node": ">=8"
 
716
  }
717
  },
718
- "node_modules/infer-owner": {
719
- "version": "1.0.4",
720
- "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
721
- "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
722
- "optional": true
 
 
 
 
723
  },
724
- "node_modules/inflight": {
725
- "version": "1.0.6",
726
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
727
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
728
  "dependencies": {
729
- "once": "^1.3.0",
730
- "wrappy": "1"
731
  }
732
  },
733
- "node_modules/inherits": {
734
- "version": "2.0.4",
735
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
736
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
737
  },
738
- "node_modules/ip": {
739
- "version": "2.0.0",
740
- "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
741
- "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
742
- "optional": true
743
  },
744
- "node_modules/is-buffer": {
745
- "version": "1.1.6",
746
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
747
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
748
  },
749
- "node_modules/is-fullwidth-code-point": {
750
- "version": "3.0.0",
751
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
752
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
753
- "engines": {
754
- "node": ">=8"
755
- }
756
  },
757
- "node_modules/is-lambda": {
758
- "version": "1.0.1",
759
- "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
760
- "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
761
- "optional": true
762
  },
763
- "node_modules/isexe": {
764
- "version": "2.0.0",
765
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
766
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
767
- "optional": true
768
  },
769
- "node_modules/js-tokens": {
770
- "version": "4.0.0",
771
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
772
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
773
  },
774
  "node_modules/loose-envify": {
775
  "version": "1.4.0",
@@ -793,55 +617,6 @@
793
  "node": ">=10"
794
  }
795
  },
796
- "node_modules/make-dir": {
797
- "version": "3.1.0",
798
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
799
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
800
- "dependencies": {
801
- "semver": "^6.0.0"
802
- },
803
- "engines": {
804
- "node": ">=8"
805
- },
806
- "funding": {
807
- "url": "https://github.com/sponsors/sindresorhus"
808
- }
809
- },
810
- "node_modules/make-dir/node_modules/semver": {
811
- "version": "6.3.1",
812
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
813
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
814
- "bin": {
815
- "semver": "bin/semver.js"
816
- }
817
- },
818
- "node_modules/make-fetch-happen": {
819
- "version": "9.1.0",
820
- "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
821
- "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
822
- "optional": true,
823
- "dependencies": {
824
- "agentkeepalive": "^4.1.3",
825
- "cacache": "^15.2.0",
826
- "http-cache-semantics": "^4.1.0",
827
- "http-proxy-agent": "^4.0.1",
828
- "https-proxy-agent": "^5.0.0",
829
- "is-lambda": "^1.0.1",
830
- "lru-cache": "^6.0.0",
831
- "minipass": "^3.1.3",
832
- "minipass-collect": "^1.0.2",
833
- "minipass-fetch": "^1.3.2",
834
- "minipass-flush": "^1.0.5",
835
- "minipass-pipeline": "^1.2.4",
836
- "negotiator": "^0.6.2",
837
- "promise-retry": "^2.0.1",
838
- "socks-proxy-agent": "^6.0.0",
839
- "ssri": "^8.0.0"
840
- },
841
- "engines": {
842
- "node": ">= 10"
843
- }
844
- },
845
  "node_modules/md5": {
846
  "version": "2.3.0",
847
  "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
@@ -871,116 +646,6 @@
871
  "node": ">= 0.6"
872
  }
873
  },
874
- "node_modules/minimatch": {
875
- "version": "3.1.2",
876
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
877
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
878
- "dependencies": {
879
- "brace-expansion": "^1.1.7"
880
- },
881
- "engines": {
882
- "node": "*"
883
- }
884
- },
885
- "node_modules/minipass": {
886
- "version": "3.3.6",
887
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
888
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
889
- "dependencies": {
890
- "yallist": "^4.0.0"
891
- },
892
- "engines": {
893
- "node": ">=8"
894
- }
895
- },
896
- "node_modules/minipass-collect": {
897
- "version": "1.0.2",
898
- "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
899
- "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
900
- "optional": true,
901
- "dependencies": {
902
- "minipass": "^3.0.0"
903
- },
904
- "engines": {
905
- "node": ">= 8"
906
- }
907
- },
908
- "node_modules/minipass-fetch": {
909
- "version": "1.4.1",
910
- "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
911
- "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
912
- "optional": true,
913
- "dependencies": {
914
- "minipass": "^3.1.0",
915
- "minipass-sized": "^1.0.3",
916
- "minizlib": "^2.0.0"
917
- },
918
- "engines": {
919
- "node": ">=8"
920
- },
921
- "optionalDependencies": {
922
- "encoding": "^0.1.12"
923
- }
924
- },
925
- "node_modules/minipass-flush": {
926
- "version": "1.0.5",
927
- "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
928
- "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
929
- "optional": true,
930
- "dependencies": {
931
- "minipass": "^3.0.0"
932
- },
933
- "engines": {
934
- "node": ">= 8"
935
- }
936
- },
937
- "node_modules/minipass-pipeline": {
938
- "version": "1.2.4",
939
- "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
940
- "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
941
- "optional": true,
942
- "dependencies": {
943
- "minipass": "^3.0.0"
944
- },
945
- "engines": {
946
- "node": ">=8"
947
- }
948
- },
949
- "node_modules/minipass-sized": {
950
- "version": "1.0.3",
951
- "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
952
- "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
953
- "optional": true,
954
- "dependencies": {
955
- "minipass": "^3.0.0"
956
- },
957
- "engines": {
958
- "node": ">=8"
959
- }
960
- },
961
- "node_modules/minizlib": {
962
- "version": "2.1.2",
963
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
964
- "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
965
- "dependencies": {
966
- "minipass": "^3.0.0",
967
- "yallist": "^4.0.0"
968
- },
969
- "engines": {
970
- "node": ">= 8"
971
- }
972
- },
973
- "node_modules/mkdirp": {
974
- "version": "1.0.4",
975
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
976
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
977
- "bin": {
978
- "mkdirp": "bin/cmd.js"
979
- },
980
- "engines": {
981
- "node": ">=10"
982
- }
983
- },
984
  "node_modules/ms": {
985
  "version": "2.1.2",
986
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -1003,45 +668,35 @@
1003
  "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1004
  }
1005
  },
1006
- "node_modules/negotiator": {
1007
- "version": "0.6.3",
1008
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1009
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
1010
- "optional": true,
1011
- "engines": {
1012
- "node": ">= 0.6"
1013
- }
1014
- },
1015
  "node_modules/next": {
1016
- "version": "13.4.19",
1017
- "resolved": "https://registry.npmjs.org/next/-/next-13.4.19.tgz",
1018
- "integrity": "sha512-HuPSzzAbJ1T4BD8e0bs6B9C1kWQ6gv8ykZoRWs5AQoiIuqbGHHdQO7Ljuvg05Q0Z24E2ABozHe6FxDvI6HfyAw==",
1019
  "dependencies": {
1020
- "@next/env": "13.4.19",
1021
- "@swc/helpers": "0.5.1",
1022
  "busboy": "1.6.0",
1023
  "caniuse-lite": "^1.0.30001406",
1024
- "postcss": "8.4.14",
1025
  "styled-jsx": "5.1.1",
1026
- "watchpack": "2.4.0",
1027
- "zod": "3.21.4"
1028
  },
1029
  "bin": {
1030
  "next": "dist/bin/next"
1031
  },
1032
  "engines": {
1033
- "node": ">=16.8.0"
1034
  },
1035
  "optionalDependencies": {
1036
- "@next/swc-darwin-arm64": "13.4.19",
1037
- "@next/swc-darwin-x64": "13.4.19",
1038
- "@next/swc-linux-arm64-gnu": "13.4.19",
1039
- "@next/swc-linux-arm64-musl": "13.4.19",
1040
- "@next/swc-linux-x64-gnu": "13.4.19",
1041
- "@next/swc-linux-x64-musl": "13.4.19",
1042
- "@next/swc-win32-arm64-msvc": "13.4.19",
1043
- "@next/swc-win32-ia32-msvc": "13.4.19",
1044
- "@next/swc-win32-x64-msvc": "13.4.19"
1045
  },
1046
  "peerDependencies": {
1047
  "@opentelemetry/api": "^1.1.0",
@@ -1071,11 +726,6 @@
1071
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
1072
  }
1073
  },
1074
- "node_modules/node-addon-api": {
1075
- "version": "4.3.0",
1076
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
1077
- "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
1078
- },
1079
  "node_modules/node-domexception": {
1080
  "version": "1.0.0",
1081
  "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -1113,100 +763,22 @@
1113
  }
1114
  }
1115
  },
1116
- "node_modules/node-gyp": {
1117
- "version": "8.4.1",
1118
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
1119
- "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
1120
- "optional": true,
1121
- "dependencies": {
1122
- "env-paths": "^2.2.0",
1123
- "glob": "^7.1.4",
1124
- "graceful-fs": "^4.2.6",
1125
- "make-fetch-happen": "^9.1.0",
1126
- "nopt": "^5.0.0",
1127
- "npmlog": "^6.0.0",
1128
- "rimraf": "^3.0.2",
1129
- "semver": "^7.3.5",
1130
- "tar": "^6.1.2",
1131
- "which": "^2.0.2"
1132
- },
1133
- "bin": {
1134
- "node-gyp": "bin/node-gyp.js"
1135
- },
1136
- "engines": {
1137
- "node": ">= 10.12.0"
1138
- }
1139
- },
1140
- "node_modules/node-gyp/node_modules/are-we-there-yet": {
1141
- "version": "3.0.1",
1142
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
1143
- "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
1144
  "optional": true,
1145
- "dependencies": {
1146
- "delegates": "^1.0.0",
1147
- "readable-stream": "^3.6.0"
1148
- },
1149
  "engines": {
1150
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
1151
  }
1152
  },
1153
- "node_modules/node-gyp/node_modules/gauge": {
1154
- "version": "4.0.4",
1155
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
1156
- "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
1157
- "optional": true,
1158
- "dependencies": {
1159
- "aproba": "^1.0.3 || ^2.0.0",
1160
- "color-support": "^1.1.3",
1161
- "console-control-strings": "^1.1.0",
1162
- "has-unicode": "^2.0.1",
1163
- "signal-exit": "^3.0.7",
1164
- "string-width": "^4.2.3",
1165
- "strip-ansi": "^6.0.1",
1166
- "wide-align": "^1.1.5"
1167
- },
1168
- "engines": {
1169
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
1170
- }
1171
- },
1172
- "node_modules/node-gyp/node_modules/npmlog": {
1173
- "version": "6.0.2",
1174
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
1175
- "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
1176
- "optional": true,
1177
- "dependencies": {
1178
- "are-we-there-yet": "^3.0.0",
1179
- "console-control-strings": "^1.1.0",
1180
- "gauge": "^4.0.3",
1181
- "set-blocking": "^2.0.0"
1182
- },
1183
- "engines": {
1184
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
1185
- }
1186
- },
1187
- "node_modules/nopt": {
1188
- "version": "5.0.0",
1189
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
1190
- "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
1191
- "dependencies": {
1192
- "abbrev": "1"
1193
- },
1194
- "bin": {
1195
- "nopt": "bin/nopt.js"
1196
- },
1197
- "engines": {
1198
- "node": ">=6"
1199
- }
1200
- },
1201
- "node_modules/npmlog": {
1202
- "version": "5.0.1",
1203
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
1204
- "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
1205
- "dependencies": {
1206
- "are-we-there-yet": "^2.0.0",
1207
- "console-control-strings": "^1.1.0",
1208
- "gauge": "^3.0.0",
1209
- "set-blocking": "^2.0.0"
1210
  }
1211
  },
1212
  "node_modules/object-assign": {
@@ -1217,14 +789,6 @@
1217
  "node": ">=0.10.0"
1218
  }
1219
  },
1220
- "node_modules/once": {
1221
- "version": "1.4.0",
1222
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1223
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1224
- "dependencies": {
1225
- "wrappy": "1"
1226
- }
1227
- },
1228
  "node_modules/openai": {
1229
  "version": "4.5.0",
1230
  "resolved": "https://registry.npmjs.org/openai/-/openai-4.5.0.tgz",
@@ -1243,27 +807,101 @@
1243
  "openai": "bin/cli"
1244
  }
1245
  },
1246
- "node_modules/p-map": {
1247
- "version": "4.0.0",
1248
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
1249
- "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
1250
- "optional": true,
 
 
 
 
 
 
1251
  "dependencies": {
1252
- "aggregate-error": "^3.0.0"
 
 
 
 
 
 
1253
  },
1254
  "engines": {
1255
- "node": ">=10"
1256
  },
1257
- "funding": {
1258
- "url": "https://github.com/sponsors/sindresorhus"
 
 
 
 
 
 
 
 
1259
  }
1260
  },
1261
- "node_modules/path-is-absolute": {
 
 
 
 
 
 
 
 
 
 
 
 
 
1262
  "version": "1.0.1",
1263
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1264
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
 
1265
  "engines": {
1266
- "node": ">=0.10.0"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1267
  }
1268
  },
1269
  "node_modules/picocolors": {
@@ -1272,9 +910,9 @@
1272
  "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
1273
  },
1274
  "node_modules/postcss": {
1275
- "version": "8.4.14",
1276
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
1277
- "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
1278
  "funding": [
1279
  {
1280
  "type": "opencollective",
@@ -1283,10 +921,14 @@
1283
  {
1284
  "type": "tidelift",
1285
  "url": "https://tidelift.com/funding/github/npm/postcss"
 
 
 
 
1286
  }
1287
  ],
1288
  "dependencies": {
1289
- "nanoid": "^3.3.4",
1290
  "picocolors": "^1.0.0",
1291
  "source-map-js": "^1.0.2"
1292
  },
@@ -1294,23 +936,67 @@
1294
  "node": "^10 || ^12 || >=14"
1295
  }
1296
  },
1297
- "node_modules/promise-inflight": {
1298
- "version": "1.0.1",
1299
- "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
1300
- "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
1301
- "optional": true
1302
- },
1303
- "node_modules/promise-retry": {
1304
- "version": "2.0.1",
1305
- "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
1306
- "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
1307
- "optional": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1308
  "dependencies": {
1309
- "err-code": "^2.0.2",
1310
- "retry": "^0.12.0"
1311
  },
1312
  "engines": {
1313
- "node": ">=10"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1314
  }
1315
  },
1316
  "node_modules/react": {
@@ -1324,6 +1010,18 @@
1324
  "node": ">=0.10.0"
1325
  }
1326
  },
 
 
 
 
 
 
 
 
 
 
 
 
1327
  "node_modules/react-dom": {
1328
  "version": "18.2.0",
1329
  "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@@ -1336,41 +1034,22 @@
1336
  "react": "^18.2.0"
1337
  }
1338
  },
1339
- "node_modules/readable-stream": {
1340
- "version": "3.6.2",
1341
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
1342
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
1343
  "dependencies": {
1344
- "inherits": "^2.0.3",
1345
- "string_decoder": "^1.1.1",
1346
- "util-deprecate": "^1.0.1"
1347
  },
1348
- "engines": {
1349
- "node": ">= 6"
1350
- }
1351
- },
1352
- "node_modules/retry": {
1353
- "version": "0.12.0",
1354
- "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
1355
- "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
1356
- "optional": true,
1357
- "engines": {
1358
- "node": ">= 4"
1359
  }
1360
  },
1361
- "node_modules/rimraf": {
1362
- "version": "3.0.2",
1363
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1364
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1365
- "dependencies": {
1366
- "glob": "^7.1.3"
1367
- },
1368
- "bin": {
1369
- "rimraf": "bin.js"
1370
- },
1371
- "funding": {
1372
- "url": "https://github.com/sponsors/isaacs"
1373
- }
1374
  },
1375
  "node_modules/safe-buffer": {
1376
  "version": "5.2.1",
@@ -1395,7 +1074,8 @@
1395
  "version": "2.1.2",
1396
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1397
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1398
- "optional": true
 
1399
  },
1400
  "node_modules/scheduler": {
1401
  "version": "0.23.0",
@@ -1419,54 +1099,6 @@
1419
  "node": ">=10"
1420
  }
1421
  },
1422
- "node_modules/set-blocking": {
1423
- "version": "2.0.0",
1424
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
1425
- "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
1426
- },
1427
- "node_modules/signal-exit": {
1428
- "version": "3.0.7",
1429
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
1430
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
1431
- },
1432
- "node_modules/smart-buffer": {
1433
- "version": "4.2.0",
1434
- "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
1435
- "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
1436
- "optional": true,
1437
- "engines": {
1438
- "node": ">= 6.0.0",
1439
- "npm": ">= 3.0.0"
1440
- }
1441
- },
1442
- "node_modules/socks": {
1443
- "version": "2.7.1",
1444
- "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
1445
- "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
1446
- "optional": true,
1447
- "dependencies": {
1448
- "ip": "^2.0.0",
1449
- "smart-buffer": "^4.2.0"
1450
- },
1451
- "engines": {
1452
- "node": ">= 10.13.0",
1453
- "npm": ">= 3.0.0"
1454
- }
1455
- },
1456
- "node_modules/socks-proxy-agent": {
1457
- "version": "6.2.1",
1458
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
1459
- "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
1460
- "optional": true,
1461
- "dependencies": {
1462
- "agent-base": "^6.0.2",
1463
- "debug": "^4.3.3",
1464
- "socks": "^2.6.2"
1465
- },
1466
- "engines": {
1467
- "node": ">= 10"
1468
- }
1469
- },
1470
  "node_modules/source-map-js": {
1471
  "version": "1.0.2",
1472
  "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@@ -1475,43 +1107,13 @@
1475
  "node": ">=0.10.0"
1476
  }
1477
  },
1478
- "node_modules/sqlite": {
1479
- "version": "5.0.1",
1480
- "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-5.0.1.tgz",
1481
- "integrity": "sha512-sRxbVwzNX9rvEPnxz9scNqi60KtfxBXMzzus5BI4+0nPtVkyEXyBwQ7JkM2M1CiVvEFw6s1vn2Z9/1DEdSpiaA=="
1482
- },
1483
- "node_modules/sqlite3": {
1484
- "version": "5.1.6",
1485
- "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz",
1486
- "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==",
1487
- "hasInstallScript": true,
1488
- "dependencies": {
1489
- "@mapbox/node-pre-gyp": "^1.0.0",
1490
- "node-addon-api": "^4.2.0",
1491
- "tar": "^6.1.11"
1492
- },
1493
- "optionalDependencies": {
1494
- "node-gyp": "8.x"
1495
- },
1496
- "peerDependencies": {
1497
- "node-gyp": "8.x"
1498
- },
1499
- "peerDependenciesMeta": {
1500
- "node-gyp": {
1501
- "optional": true
1502
- }
1503
- }
1504
- },
1505
- "node_modules/ssri": {
1506
- "version": "8.0.1",
1507
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
1508
- "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
1509
- "optional": true,
1510
- "dependencies": {
1511
- "minipass": "^3.1.1"
1512
- },
1513
  "engines": {
1514
- "node": ">= 8"
1515
  }
1516
  },
1517
  "node_modules/streamsearch": {
@@ -1522,38 +1124,6 @@
1522
  "node": ">=10.0.0"
1523
  }
1524
  },
1525
- "node_modules/string_decoder": {
1526
- "version": "1.3.0",
1527
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
1528
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
1529
- "dependencies": {
1530
- "safe-buffer": "~5.2.0"
1531
- }
1532
- },
1533
- "node_modules/string-width": {
1534
- "version": "4.2.3",
1535
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1536
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1537
- "dependencies": {
1538
- "emoji-regex": "^8.0.0",
1539
- "is-fullwidth-code-point": "^3.0.0",
1540
- "strip-ansi": "^6.0.1"
1541
- },
1542
- "engines": {
1543
- "node": ">=8"
1544
- }
1545
- },
1546
- "node_modules/strip-ansi": {
1547
- "version": "6.0.1",
1548
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1549
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1550
- "dependencies": {
1551
- "ansi-regex": "^5.0.1"
1552
- },
1553
- "engines": {
1554
- "node": ">=8"
1555
- }
1556
- },
1557
  "node_modules/styled-jsx": {
1558
  "version": "5.1.1",
1559
  "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
@@ -1576,30 +1146,6 @@
1576
  }
1577
  }
1578
  },
1579
- "node_modules/tar": {
1580
- "version": "6.2.0",
1581
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
1582
- "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
1583
- "dependencies": {
1584
- "chownr": "^2.0.0",
1585
- "fs-minipass": "^2.0.0",
1586
- "minipass": "^5.0.0",
1587
- "minizlib": "^2.1.1",
1588
- "mkdirp": "^1.0.3",
1589
- "yallist": "^4.0.0"
1590
- },
1591
- "engines": {
1592
- "node": ">=10"
1593
- }
1594
- },
1595
- "node_modules/tar/node_modules/minipass": {
1596
- "version": "5.0.0",
1597
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
1598
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
1599
- "engines": {
1600
- "node": ">=8"
1601
- }
1602
- },
1603
  "node_modules/tr46": {
1604
  "version": "0.0.3",
1605
  "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -1610,29 +1156,19 @@
1610
  "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
1611
  "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
1612
  },
1613
- "node_modules/unique-filename": {
1614
- "version": "1.1.1",
1615
- "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
1616
- "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
1617
- "optional": true,
1618
- "dependencies": {
1619
- "unique-slug": "^2.0.0"
1620
- }
1621
- },
1622
- "node_modules/unique-slug": {
1623
- "version": "2.0.2",
1624
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
1625
- "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
1626
- "optional": true,
1627
- "dependencies": {
1628
- "imurmurhash": "^0.1.4"
1629
  }
1630
  },
1631
- "node_modules/util-deprecate": {
1632
- "version": "1.0.2",
1633
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1634
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
1635
- },
1636
  "node_modules/watchpack": {
1637
  "version": "2.4.0",
1638
  "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@@ -1667,46 +1203,19 @@
1667
  "webidl-conversions": "^3.0.0"
1668
  }
1669
  },
1670
- "node_modules/which": {
1671
- "version": "2.0.2",
1672
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1673
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1674
- "optional": true,
1675
- "dependencies": {
1676
- "isexe": "^2.0.0"
1677
- },
1678
- "bin": {
1679
- "node-which": "bin/node-which"
1680
- },
1681
  "engines": {
1682
- "node": ">= 8"
1683
  }
1684
  },
1685
- "node_modules/wide-align": {
1686
- "version": "1.1.5",
1687
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
1688
- "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
1689
- "dependencies": {
1690
- "string-width": "^1.0.2 || 2 || 3 || 4"
1691
- }
1692
- },
1693
- "node_modules/wrappy": {
1694
- "version": "1.0.2",
1695
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1696
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
1697
- },
1698
  "node_modules/yallist": {
1699
  "version": "4.0.0",
1700
  "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1701
  "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
1702
- },
1703
- "node_modules/zod": {
1704
- "version": "3.21.4",
1705
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz",
1706
- "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==",
1707
- "funding": {
1708
- "url": "https://github.com/sponsors/colinhacks"
1709
- }
1710
  }
1711
  }
1712
  }
 
8
  "name": "benchmarks",
9
  "version": "0.1.0",
10
  "dependencies": {
11
+ "@auth/pg-adapter": "^0.2.1",
12
+ "jsonwebtoken": "^9.0.2",
13
+ "next": "^13.5.4",
14
  "next-plausible": "^3.11.1",
15
  "openai": "^4.5.0",
16
+ "postgres": "^3.3.5",
17
+ "react": "^18.2.0",
18
+ "react-dom": "^18.2.0",
19
+ "react-google-recaptcha": "^3.1.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/react": "18.2.24",
23
+ "typescript": "5.2.2"
24
+ }
25
+ },
26
+ "node_modules/@auth/core": {
27
+ "version": "0.16.1",
28
+ "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.16.1.tgz",
29
+ "integrity": "sha512-V+YifnjpyOadiiTbxfYDV2xYWo8xpKNtwYVskAEKUSwMvE0FlSlP+10QGBpf0axS/AJFOO61IR6GncFF/IOrHQ==",
30
+ "dependencies": {
31
+ "@panva/hkdf": "^1.0.4",
32
+ "cookie": "0.5.0",
33
+ "jose": "^4.11.1",
34
+ "oauth4webapi": "^2.0.6",
35
+ "preact": "10.11.3",
36
+ "preact-render-to-string": "5.2.3"
37
+ },
38
+ "peerDependencies": {
39
+ "nodemailer": "^6.8.0"
40
+ },
41
+ "peerDependenciesMeta": {
42
+ "nodemailer": {
43
+ "optional": true
44
+ }
45
  }
46
  },
47
+ "node_modules/@auth/core/node_modules/preact": {
48
+ "version": "10.11.3",
49
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz",
50
+ "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==",
51
+ "funding": {
52
+ "type": "opencollective",
53
+ "url": "https://opencollective.com/preact"
54
+ }
55
  },
56
+ "node_modules/@auth/core/node_modules/preact-render-to-string": {
57
+ "version": "5.2.3",
58
+ "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz",
59
+ "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==",
60
  "dependencies": {
61
+ "pretty-format": "^3.8.0"
 
 
 
 
 
 
 
 
62
  },
63
+ "peerDependencies": {
64
+ "preact": ">=10"
65
+ }
66
+ },
67
+ "node_modules/@auth/pg-adapter": {
68
+ "version": "0.2.1",
69
+ "resolved": "https://registry.npmjs.org/@auth/pg-adapter/-/pg-adapter-0.2.1.tgz",
70
+ "integrity": "sha512-Yp8fMORE44fP2vAqDCa4SvDKV+HE7z/6cQIlLmwbWJd8ywnrgWKE/TvqUARZ1o3+ITx9d683CZeyexdefKw5Yw==",
71
+ "dependencies": {
72
+ "@auth/core": "0.16.1"
73
+ },
74
+ "peerDependencies": {
75
+ "pg": "^8"
76
  }
77
  },
78
  "node_modules/@next/env": {
79
+ "version": "13.5.4",
80
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.4.tgz",
81
+ "integrity": "sha512-LGegJkMvRNw90WWphGJ3RMHMVplYcOfRWf2Be3td3sUa+1AaxmsYyANsA+znrGCBjXJNi4XAQlSoEfUxs/4kIQ=="
82
  },
83
  "node_modules/@next/swc-darwin-arm64": {
84
+ "version": "13.5.4",
85
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.4.tgz",
86
+ "integrity": "sha512-Df8SHuXgF1p+aonBMcDPEsaahNo2TCwuie7VXED4FVyECvdXfRT9unapm54NssV9tF3OQFKBFOdlje4T43VO0w==",
87
  "cpu": [
88
  "arm64"
89
  ],
 
96
  }
97
  },
98
  "node_modules/@next/swc-darwin-x64": {
99
+ "version": "13.5.4",
100
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz",
101
+ "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==",
102
  "cpu": [
103
  "x64"
104
  ],
 
111
  }
112
  },
113
  "node_modules/@next/swc-linux-arm64-gnu": {
114
+ "version": "13.5.4",
115
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz",
116
+ "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==",
117
  "cpu": [
118
  "arm64"
119
  ],
 
126
  }
127
  },
128
  "node_modules/@next/swc-linux-arm64-musl": {
129
+ "version": "13.5.4",
130
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz",
131
+ "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==",
132
  "cpu": [
133
  "arm64"
134
  ],
 
141
  }
142
  },
143
  "node_modules/@next/swc-linux-x64-gnu": {
144
+ "version": "13.5.4",
145
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz",
146
+ "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==",
147
  "cpu": [
148
  "x64"
149
  ],
 
156
  }
157
  },
158
  "node_modules/@next/swc-linux-x64-musl": {
159
+ "version": "13.5.4",
160
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz",
161
+ "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==",
162
  "cpu": [
163
  "x64"
164
  ],
 
171
  }
172
  },
173
  "node_modules/@next/swc-win32-arm64-msvc": {
174
+ "version": "13.5.4",
175
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz",
176
+ "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==",
177
  "cpu": [
178
  "arm64"
179
  ],
 
186
  }
187
  },
188
  "node_modules/@next/swc-win32-ia32-msvc": {
189
+ "version": "13.5.4",
190
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz",
191
+ "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==",
192
  "cpu": [
193
  "ia32"
194
  ],
 
201
  }
202
  },
203
  "node_modules/@next/swc-win32-x64-msvc": {
204
+ "version": "13.5.4",
205
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz",
206
+ "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==",
207
  "cpu": [
208
  "x64"
209
  ],
 
215
  "node": ">= 10"
216
  }
217
  },
218
+ "node_modules/@panva/hkdf": {
219
  "version": "1.1.1",
220
+ "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz",
221
+ "integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==",
222
+ "funding": {
223
+ "url": "https://github.com/sponsors/panva"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  }
225
  },
226
  "node_modules/@swc/helpers": {
227
+ "version": "0.5.2",
228
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
229
+ "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
230
  "dependencies": {
231
  "tslib": "^2.4.0"
232
  }
233
  },
 
 
 
 
 
 
 
 
 
234
  "node_modules/@types/node": {
235
  "version": "18.17.14",
236
  "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.14.tgz",
 
245
  "form-data": "^3.0.0"
246
  }
247
  },
248
+ "node_modules/@types/prop-types": {
249
+ "version": "15.7.8",
250
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz",
251
+ "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==",
252
+ "dev": true
253
+ },
254
+ "node_modules/@types/react": {
255
+ "version": "18.2.24",
256
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.24.tgz",
257
+ "integrity": "sha512-Ee0Jt4sbJxMu1iDcetZEIKQr99J1Zfb6D4F3qfUWoR1JpInkY1Wdg4WwCyBjL257D0+jGqSl1twBjV8iCaC0Aw==",
258
+ "dev": true,
259
+ "dependencies": {
260
+ "@types/prop-types": "*",
261
+ "@types/scheduler": "*",
262
+ "csstype": "^3.0.2"
263
+ }
264
+ },
265
+ "node_modules/@types/scheduler": {
266
+ "version": "0.16.4",
267
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz",
268
+ "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==",
269
+ "dev": true
270
  },
271
  "node_modules/abort-controller": {
272
  "version": "3.0.0",
 
279
  "node": ">=6.5"
280
  }
281
  },
 
 
 
 
 
 
 
 
 
 
 
282
  "node_modules/agentkeepalive": {
283
  "version": "4.5.0",
284
  "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
 
290
  "node": ">= 8.0.0"
291
  }
292
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  "node_modules/asynckit": {
294
  "version": "0.4.0",
295
  "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
296
  "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
297
  },
 
 
 
 
 
298
  "node_modules/base-64": {
299
  "version": "0.1.0",
300
  "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
301
  "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
302
  },
303
+ "node_modules/buffer-equal-constant-time": {
304
+ "version": "1.0.1",
305
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
306
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
307
+ },
308
+ "node_modules/buffer-writer": {
309
+ "version": "2.0.0",
310
+ "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
311
+ "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
312
+ "peer": true,
313
+ "engines": {
314
+ "node": ">=4"
315
  }
316
  },
317
  "node_modules/busboy": {
 
325
  "node": ">=10.16.0"
326
  }
327
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  "node_modules/caniuse-lite": {
329
  "version": "1.0.30001529",
330
  "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001529.tgz",
 
352
  "node": "*"
353
  }
354
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  "node_modules/client-only": {
356
  "version": "0.0.1",
357
  "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
358
  "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
359
  },
 
 
 
 
 
 
 
 
360
  "node_modules/combined-stream": {
361
  "version": "1.0.8",
362
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
 
368
  "node": ">= 0.8"
369
  }
370
  },
371
+ "node_modules/cookie": {
372
+ "version": "0.5.0",
373
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
374
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
375
+ "engines": {
376
+ "node": ">= 0.6"
377
+ }
 
 
378
  },
379
  "node_modules/crypt": {
380
  "version": "0.0.2",
 
384
  "node": "*"
385
  }
386
  },
387
+ "node_modules/csstype": {
388
+ "version": "3.1.2",
389
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
390
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
391
+ "dev": true
 
 
 
 
 
 
 
 
 
 
392
  },
393
  "node_modules/delayed-stream": {
394
  "version": "1.0.0",
 
398
  "node": ">=0.4.0"
399
  }
400
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  "node_modules/digest-fetch": {
402
  "version": "1.3.0",
403
  "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",
 
407
  "md5": "^2.3.0"
408
  }
409
  },
410
+ "node_modules/ecdsa-sig-formatter": {
411
+ "version": "1.0.11",
412
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
413
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
414
+ "dependencies": {
415
+ "safe-buffer": "^5.0.1"
416
+ }
417
  },
418
  "node_modules/encoding": {
419
  "version": "0.1.13",
420
  "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
421
  "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
422
  "optional": true,
423
+ "peer": true,
424
  "dependencies": {
425
  "iconv-lite": "^0.6.2"
426
  }
427
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
  "node_modules/event-target-shim": {
429
  "version": "5.0.1",
430
  "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
 
463
  "node": ">= 12.20"
464
  }
465
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
  "node_modules/glob-to-regexp": {
467
  "version": "0.4.1",
468
  "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
 
473
  "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
474
  "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
475
  },
476
+ "node_modules/hoist-non-react-statics": {
477
+ "version": "3.3.2",
478
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
479
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  "dependencies": {
481
+ "react-is": "^16.7.0"
 
 
 
 
482
  }
483
  },
484
  "node_modules/humanize-ms": {
 
494
  "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
495
  "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
496
  "optional": true,
497
+ "peer": true,
498
  "dependencies": {
499
  "safer-buffer": ">= 2.1.2 < 3.0.0"
500
  },
 
502
  "node": ">=0.10.0"
503
  }
504
  },
505
+ "node_modules/is-buffer": {
506
+ "version": "1.1.6",
507
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
508
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
509
+ },
510
+ "node_modules/jose": {
511
+ "version": "4.15.2",
512
+ "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.2.tgz",
513
+ "integrity": "sha512-IY73F228OXRl9ar3jJagh7Vnuhj/GzBunPiZP13K0lOl7Am9SoWW3kEzq3MCllJMTtZqHTiDXQvoRd4U95aU6A==",
514
+ "funding": {
515
+ "url": "https://github.com/sponsors/panva"
516
  }
517
  },
518
+ "node_modules/js-tokens": {
519
  "version": "4.0.0",
520
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
521
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
522
+ },
523
+ "node_modules/jsonwebtoken": {
524
+ "version": "9.0.2",
525
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
526
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
527
+ "dependencies": {
528
+ "jws": "^3.2.2",
529
+ "lodash.includes": "^4.3.0",
530
+ "lodash.isboolean": "^3.0.3",
531
+ "lodash.isinteger": "^4.0.4",
532
+ "lodash.isnumber": "^3.0.3",
533
+ "lodash.isplainobject": "^4.0.6",
534
+ "lodash.isstring": "^4.0.1",
535
+ "lodash.once": "^4.0.0",
536
+ "ms": "^2.1.1",
537
+ "semver": "^7.5.4"
538
+ },
539
  "engines": {
540
+ "node": ">=12",
541
+ "npm": ">=6"
542
  }
543
  },
544
+ "node_modules/jwa": {
545
+ "version": "1.4.1",
546
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
547
+ "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
548
+ "dependencies": {
549
+ "buffer-equal-constant-time": "1.0.1",
550
+ "ecdsa-sig-formatter": "1.0.11",
551
+ "safe-buffer": "^5.0.1"
552
+ }
553
  },
554
+ "node_modules/jws": {
555
+ "version": "3.2.2",
556
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
557
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
558
  "dependencies": {
559
+ "jwa": "^1.4.1",
560
+ "safe-buffer": "^5.0.1"
561
  }
562
  },
563
+ "node_modules/lodash.includes": {
564
+ "version": "4.3.0",
565
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
566
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
567
  },
568
+ "node_modules/lodash.isboolean": {
569
+ "version": "3.0.3",
570
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
571
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
 
572
  },
573
+ "node_modules/lodash.isinteger": {
574
+ "version": "4.0.4",
575
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
576
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
577
  },
578
+ "node_modules/lodash.isnumber": {
579
+ "version": "3.0.3",
580
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
581
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
 
 
 
582
  },
583
+ "node_modules/lodash.isplainobject": {
584
+ "version": "4.0.6",
585
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
586
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
 
587
  },
588
+ "node_modules/lodash.isstring": {
589
+ "version": "4.0.1",
590
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
591
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
 
592
  },
593
+ "node_modules/lodash.once": {
594
+ "version": "4.1.1",
595
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
596
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
597
  },
598
  "node_modules/loose-envify": {
599
  "version": "1.4.0",
 
617
  "node": ">=10"
618
  }
619
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
620
  "node_modules/md5": {
621
  "version": "2.3.0",
622
  "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
 
646
  "node": ">= 0.6"
647
  }
648
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
649
  "node_modules/ms": {
650
  "version": "2.1.2",
651
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 
668
  "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
669
  }
670
  },
 
 
 
 
 
 
 
 
 
671
  "node_modules/next": {
672
+ "version": "13.5.4",
673
+ "resolved": "https://registry.npmjs.org/next/-/next-13.5.4.tgz",
674
+ "integrity": "sha512-+93un5S779gho8y9ASQhb/bTkQF17FNQOtXLKAj3lsNgltEcF0C5PMLLncDmH+8X1EnJH1kbqAERa29nRXqhjA==",
675
  "dependencies": {
676
+ "@next/env": "13.5.4",
677
+ "@swc/helpers": "0.5.2",
678
  "busboy": "1.6.0",
679
  "caniuse-lite": "^1.0.30001406",
680
+ "postcss": "8.4.31",
681
  "styled-jsx": "5.1.1",
682
+ "watchpack": "2.4.0"
 
683
  },
684
  "bin": {
685
  "next": "dist/bin/next"
686
  },
687
  "engines": {
688
+ "node": ">=16.14.0"
689
  },
690
  "optionalDependencies": {
691
+ "@next/swc-darwin-arm64": "13.5.4",
692
+ "@next/swc-darwin-x64": "13.5.4",
693
+ "@next/swc-linux-arm64-gnu": "13.5.4",
694
+ "@next/swc-linux-arm64-musl": "13.5.4",
695
+ "@next/swc-linux-x64-gnu": "13.5.4",
696
+ "@next/swc-linux-x64-musl": "13.5.4",
697
+ "@next/swc-win32-arm64-msvc": "13.5.4",
698
+ "@next/swc-win32-ia32-msvc": "13.5.4",
699
+ "@next/swc-win32-x64-msvc": "13.5.4"
700
  },
701
  "peerDependencies": {
702
  "@opentelemetry/api": "^1.1.0",
 
726
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
727
  }
728
  },
 
 
 
 
 
729
  "node_modules/node-domexception": {
730
  "version": "1.0.0",
731
  "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
 
763
  }
764
  }
765
  },
766
+ "node_modules/nodemailer": {
767
+ "version": "6.9.5",
768
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.5.tgz",
769
+ "integrity": "sha512-/dmdWo62XjumuLc5+AYQZeiRj+PRR8y8qKtFCOyuOl1k/hckZd8durUUHs/ucKx6/8kN+wFxqKJlQ/LK/qR5FA==",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
770
  "optional": true,
771
+ "peer": true,
 
 
 
772
  "engines": {
773
+ "node": ">=6.0.0"
774
  }
775
  },
776
+ "node_modules/oauth4webapi": {
777
+ "version": "2.3.0",
778
+ "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.3.0.tgz",
779
+ "integrity": "sha512-JGkb5doGrwzVDuHwgrR4nHJayzN4h59VCed6EW8Tql6iHDfZIabCJvg6wtbn5q6pyB2hZruI3b77Nudvq7NmvA==",
780
+ "funding": {
781
+ "url": "https://github.com/sponsors/panva"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
782
  }
783
  },
784
  "node_modules/object-assign": {
 
789
  "node": ">=0.10.0"
790
  }
791
  },
 
 
 
 
 
 
 
 
792
  "node_modules/openai": {
793
  "version": "4.5.0",
794
  "resolved": "https://registry.npmjs.org/openai/-/openai-4.5.0.tgz",
 
807
  "openai": "bin/cli"
808
  }
809
  },
810
+ "node_modules/packet-reader": {
811
+ "version": "1.0.0",
812
+ "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
813
+ "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==",
814
+ "peer": true
815
+ },
816
+ "node_modules/pg": {
817
+ "version": "8.11.3",
818
+ "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz",
819
+ "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==",
820
+ "peer": true,
821
  "dependencies": {
822
+ "buffer-writer": "2.0.0",
823
+ "packet-reader": "1.0.0",
824
+ "pg-connection-string": "^2.6.2",
825
+ "pg-pool": "^3.6.1",
826
+ "pg-protocol": "^1.6.0",
827
+ "pg-types": "^2.1.0",
828
+ "pgpass": "1.x"
829
  },
830
  "engines": {
831
+ "node": ">= 8.0.0"
832
  },
833
+ "optionalDependencies": {
834
+ "pg-cloudflare": "^1.1.1"
835
+ },
836
+ "peerDependencies": {
837
+ "pg-native": ">=3.0.1"
838
+ },
839
+ "peerDependenciesMeta": {
840
+ "pg-native": {
841
+ "optional": true
842
+ }
843
  }
844
  },
845
+ "node_modules/pg-cloudflare": {
846
+ "version": "1.1.1",
847
+ "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
848
+ "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
849
+ "optional": true,
850
+ "peer": true
851
+ },
852
+ "node_modules/pg-connection-string": {
853
+ "version": "2.6.2",
854
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
855
+ "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==",
856
+ "peer": true
857
+ },
858
+ "node_modules/pg-int8": {
859
  "version": "1.0.1",
860
+ "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
861
+ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
862
+ "peer": true,
863
  "engines": {
864
+ "node": ">=4.0.0"
865
+ }
866
+ },
867
+ "node_modules/pg-pool": {
868
+ "version": "3.6.1",
869
+ "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz",
870
+ "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==",
871
+ "peer": true,
872
+ "peerDependencies": {
873
+ "pg": ">=8.0"
874
+ }
875
+ },
876
+ "node_modules/pg-protocol": {
877
+ "version": "1.6.0",
878
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz",
879
+ "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==",
880
+ "peer": true
881
+ },
882
+ "node_modules/pg-types": {
883
+ "version": "2.2.0",
884
+ "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
885
+ "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
886
+ "peer": true,
887
+ "dependencies": {
888
+ "pg-int8": "1.0.1",
889
+ "postgres-array": "~2.0.0",
890
+ "postgres-bytea": "~1.0.0",
891
+ "postgres-date": "~1.0.4",
892
+ "postgres-interval": "^1.1.0"
893
+ },
894
+ "engines": {
895
+ "node": ">=4"
896
+ }
897
+ },
898
+ "node_modules/pgpass": {
899
+ "version": "1.0.5",
900
+ "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
901
+ "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
902
+ "peer": true,
903
+ "dependencies": {
904
+ "split2": "^4.1.0"
905
  }
906
  },
907
  "node_modules/picocolors": {
 
910
  "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
911
  },
912
  "node_modules/postcss": {
913
+ "version": "8.4.31",
914
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
915
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
916
  "funding": [
917
  {
918
  "type": "opencollective",
 
921
  {
922
  "type": "tidelift",
923
  "url": "https://tidelift.com/funding/github/npm/postcss"
924
+ },
925
+ {
926
+ "type": "github",
927
+ "url": "https://github.com/sponsors/ai"
928
  }
929
  ],
930
  "dependencies": {
931
+ "nanoid": "^3.3.6",
932
  "picocolors": "^1.0.0",
933
  "source-map-js": "^1.0.2"
934
  },
 
936
  "node": "^10 || ^12 || >=14"
937
  }
938
  },
939
+ "node_modules/postgres": {
940
+ "version": "3.3.5",
941
+ "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.3.5.tgz",
942
+ "integrity": "sha512-+JD93VELV9gHkqpV5gdL5/70HdGtEw4/XE1S4BC8f1mcPmdib3K5XsKVbnR1XcAyC41zOnifJ+9YRKxdIsXiUw==",
943
+ "funding": {
944
+ "type": "individual",
945
+ "url": "https://github.com/sponsors/porsager"
946
+ }
947
+ },
948
+ "node_modules/postgres-array": {
949
+ "version": "2.0.0",
950
+ "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
951
+ "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
952
+ "peer": true,
953
+ "engines": {
954
+ "node": ">=4"
955
+ }
956
+ },
957
+ "node_modules/postgres-bytea": {
958
+ "version": "1.0.0",
959
+ "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
960
+ "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
961
+ "peer": true,
962
+ "engines": {
963
+ "node": ">=0.10.0"
964
+ }
965
+ },
966
+ "node_modules/postgres-date": {
967
+ "version": "1.0.7",
968
+ "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
969
+ "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
970
+ "peer": true,
971
+ "engines": {
972
+ "node": ">=0.10.0"
973
+ }
974
+ },
975
+ "node_modules/postgres-interval": {
976
+ "version": "1.2.0",
977
+ "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
978
+ "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
979
+ "peer": true,
980
  "dependencies": {
981
+ "xtend": "^4.0.0"
 
982
  },
983
  "engines": {
984
+ "node": ">=0.10.0"
985
+ }
986
+ },
987
+ "node_modules/pretty-format": {
988
+ "version": "3.8.0",
989
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
990
+ "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
991
+ },
992
+ "node_modules/prop-types": {
993
+ "version": "15.8.1",
994
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
995
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
996
+ "dependencies": {
997
+ "loose-envify": "^1.4.0",
998
+ "object-assign": "^4.1.1",
999
+ "react-is": "^16.13.1"
1000
  }
1001
  },
1002
  "node_modules/react": {
 
1010
  "node": ">=0.10.0"
1011
  }
1012
  },
1013
+ "node_modules/react-async-script": {
1014
+ "version": "1.2.0",
1015
+ "resolved": "https://registry.npmjs.org/react-async-script/-/react-async-script-1.2.0.tgz",
1016
+ "integrity": "sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==",
1017
+ "dependencies": {
1018
+ "hoist-non-react-statics": "^3.3.0",
1019
+ "prop-types": "^15.5.0"
1020
+ },
1021
+ "peerDependencies": {
1022
+ "react": ">=16.4.1"
1023
+ }
1024
+ },
1025
  "node_modules/react-dom": {
1026
  "version": "18.2.0",
1027
  "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
 
1034
  "react": "^18.2.0"
1035
  }
1036
  },
1037
+ "node_modules/react-google-recaptcha": {
1038
+ "version": "3.1.0",
1039
+ "resolved": "https://registry.npmjs.org/react-google-recaptcha/-/react-google-recaptcha-3.1.0.tgz",
1040
+ "integrity": "sha512-cYW2/DWas8nEKZGD7SCu9BSuVz8iOcOLHChHyi7upUuVhkpkhYG/6N3KDiTQ3XAiZ2UAZkfvYKMfAHOzBOcGEg==",
1041
  "dependencies": {
1042
+ "prop-types": "^15.5.0",
1043
+ "react-async-script": "^1.2.0"
 
1044
  },
1045
+ "peerDependencies": {
1046
+ "react": ">=16.4.1"
 
 
 
 
 
 
 
 
 
1047
  }
1048
  },
1049
+ "node_modules/react-is": {
1050
+ "version": "16.13.1",
1051
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
1052
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
 
 
 
 
 
 
 
 
 
1053
  },
1054
  "node_modules/safe-buffer": {
1055
  "version": "5.2.1",
 
1074
  "version": "2.1.2",
1075
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1076
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1077
+ "optional": true,
1078
+ "peer": true
1079
  },
1080
  "node_modules/scheduler": {
1081
  "version": "0.23.0",
 
1099
  "node": ">=10"
1100
  }
1101
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1102
  "node_modules/source-map-js": {
1103
  "version": "1.0.2",
1104
  "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
 
1107
  "node": ">=0.10.0"
1108
  }
1109
  },
1110
+ "node_modules/split2": {
1111
+ "version": "4.2.0",
1112
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
1113
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
1114
+ "peer": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1115
  "engines": {
1116
+ "node": ">= 10.x"
1117
  }
1118
  },
1119
  "node_modules/streamsearch": {
 
1124
  "node": ">=10.0.0"
1125
  }
1126
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1127
  "node_modules/styled-jsx": {
1128
  "version": "5.1.1",
1129
  "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
 
1146
  }
1147
  }
1148
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1149
  "node_modules/tr46": {
1150
  "version": "0.0.3",
1151
  "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
 
1156
  "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
1157
  "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
1158
  },
1159
+ "node_modules/typescript": {
1160
+ "version": "5.2.2",
1161
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
1162
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
1163
+ "dev": true,
1164
+ "bin": {
1165
+ "tsc": "bin/tsc",
1166
+ "tsserver": "bin/tsserver"
1167
+ },
1168
+ "engines": {
1169
+ "node": ">=14.17"
 
 
 
 
 
1170
  }
1171
  },
 
 
 
 
 
1172
  "node_modules/watchpack": {
1173
  "version": "2.4.0",
1174
  "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
 
1203
  "webidl-conversions": "^3.0.0"
1204
  }
1205
  },
1206
+ "node_modules/xtend": {
1207
+ "version": "4.0.2",
1208
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
1209
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
1210
+ "peer": true,
 
 
 
 
 
 
1211
  "engines": {
1212
+ "node": ">=0.4"
1213
  }
1214
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
1215
  "node_modules/yallist": {
1216
  "version": "4.0.0",
1217
  "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1218
  "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
 
 
 
 
 
 
 
 
1219
  }
1220
  }
1221
  }
package.json CHANGED
@@ -9,15 +9,21 @@
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
12
- "next": "13.4.19",
 
 
13
  "next-plausible": "^3.11.1",
14
  "openai": "^4.5.0",
15
- "react": "18.2.0",
16
- "react-dom": "18.2.0",
17
- "sqlite": "^5.0.1",
18
- "sqlite3": "^5.1.6"
19
  },
20
  "prettier": {
21
  "semi": false
 
 
 
 
22
  }
23
  }
 
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
12
+ "@auth/pg-adapter": "^0.2.1",
13
+ "jsonwebtoken": "^9.0.2",
14
+ "next": "^13.5.4",
15
  "next-plausible": "^3.11.1",
16
  "openai": "^4.5.0",
17
+ "postgres": "^3.3.5",
18
+ "react": "^18.2.0",
19
+ "react-dom": "^18.2.0",
20
+ "react-google-recaptcha": "^3.1.0"
21
  },
22
  "prettier": {
23
  "semi": false
24
+ },
25
+ "devDependencies": {
26
+ "@types/react": "18.2.24",
27
+ "typescript": "5.2.2"
28
  }
29
  }
pages/_app.js DELETED
@@ -1,40 +0,0 @@
1
- import PlausibleProvider from "next-plausible"
2
-
3
- import "@/styles/globals.css"
4
-
5
- import Script from "next/script"
6
-
7
- export default function App({ Component, pageProps }) {
8
- return (
9
- <PlausibleProvider
10
- domain="benchmarks.llmonitor.com"
11
- scriptProps={{
12
- src: "https://llmonitor.com/p/js/script.js",
13
- // @ts-ignore
14
- "data-api": "https://llmonitor.com/p/event",
15
- }}
16
- customDomain="benchmarks.llmonitor.com"
17
- >
18
- <Component {...pageProps} />
19
- <footer>
20
- <br />
21
- <p>
22
- Credit:{" "}
23
- <a href="https://twitter.com/vincelwt" target="_blank">
24
- @vincelwt
25
- </a>
26
- </p>
27
-
28
- <a href="https://llmonitor.com" className="llmonitor" target="_blank">
29
- by 📈 llmonitor
30
- </a>
31
-
32
- {/* Support embedding into HuggingFace */}
33
- <Script
34
- strategy="afterInteractive"
35
- src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"
36
- />
37
- </footer>
38
- </PlausibleProvider>
39
- )
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/_document.js DELETED
@@ -1,13 +0,0 @@
1
- import { Html, Head, Main, NextScript } from 'next/document'
2
-
3
- export default function Document() {
4
- return (
5
- <Html lang="en">
6
- <Head />
7
- <body>
8
- <Main />
9
- <NextScript />
10
- </body>
11
- </Html>
12
- )
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/index.js DELETED
@@ -1,186 +0,0 @@
1
- import getDB from "@/utils/getDB"
2
- import Head from "next/head"
3
- import Link from "next/link"
4
- import { useRouter } from "next/router"
5
- import { useEffect, useMemo, useState } from "react"
6
-
7
- // import styles from '@/styles/Home.module.css'
8
-
9
- export const getStaticProps = async () => {
10
- const db = await getDB()
11
-
12
- const prompts = await db.all(`SELECT * FROM prompts ORDER BY text ASC`)
13
-
14
- // get all models that have at least 1 result
15
- const models = await db.all(
16
- `SELECT * FROM models WHERE id IN (SELECT DISTINCT model FROM results) ORDER BY name ASC`
17
- )
18
-
19
- return { props: { prompts, models } }
20
- }
21
-
22
- export default function Home({ prompts, models }) {
23
- const router = useRouter()
24
-
25
- const [viewBy, setViewBy] = useState(router.query.viewBy || "prompt")
26
-
27
- const changeView = (viewBy) => {
28
- router.push({ query: { viewBy } })
29
- }
30
-
31
- useEffect(() => {
32
- if (router.query.viewBy) setViewBy(router.query.viewBy)
33
- }, [router.query.viewBy])
34
-
35
- const types = useMemo(() => {
36
- return Array.from(new Set(prompts.map((p) => p.type)))
37
- }, [prompts])
38
-
39
- return (
40
- <>
41
- <Head>
42
- <title>LLM Benchmarks</title>
43
- <meta
44
- name="description"
45
- content="Human-readable benchmarks of 60+ open-source and proprietary LLMs."
46
- />
47
- <meta name="viewport" content="width=device-width, initial-scale=1" />
48
- </Head>
49
- <main>
50
- <h1>Crowdsourced LLM Benchmark</h1>
51
- <br />
52
- <p>
53
- Benchmarks like HellaSwag are a bit too abstract for me to get a sense
54
- of how well they perform in real-world workflows.
55
- </p>
56
- <br />
57
-
58
- <p>
59
- I had the idea of writing a script that asks prompts testing basic
60
- reasoning, instruction following, and creativity on around 60 models
61
- that I could get my hands on through inferences API.
62
- </p>
63
- <br />
64
- <p>
65
- The script stored all the answers in a SQLite database, and those are
66
- the raw results.
67
- </p>
68
- <br />
69
- <br />
70
- <p>
71
- {`view: `}
72
- <a href="#" onClick={() => changeView("model")}>
73
- models
74
- </a>{" "}
75
- /
76
- <a href="#" onClick={() => changeView("prompt")}>
77
- prompts
78
- </a>{" "}
79
- </p>
80
- <br />
81
- {viewBy === "prompt" ? (
82
- <>
83
- {types.map((type, k) => (
84
- <div key={k}>
85
- <p>{type}:</p>
86
- <br />
87
- <ul>
88
- {prompts
89
- .filter((p) => p.type === type)
90
- .map((prompt, i) => (
91
- <li key={i}>
92
- <pre style={{ maxWidth: 800 }}>
93
- {prompt.text}
94
- <br />
95
- <br />
96
- <Link href={`/${prompt.slug}`}>results</Link>
97
- </pre>
98
- </li>
99
- ))}
100
- </ul>
101
- </div>
102
- ))}
103
- </>
104
- ) : (
105
- <ul>
106
- {models
107
- .score((s) => s.score)
108
- .map((model, i) => (
109
- <li key={i}>
110
- {model.name} -{" "}
111
- <Link
112
- href={`/model/${model.api_id
113
- .split("/")
114
- .pop()
115
- .toLowerCase()}`}
116
- >
117
- results
118
- </Link>{" "}
119
- - score: {model.score}
120
- </li>
121
- ))}
122
- </ul>
123
- )}
124
- <br />
125
- <br />
126
- <h3>Notes</h3>
127
- <br />
128
- <ul>
129
- <li>
130
- I used a temperature of 0 and a max token limit of 240 for each test
131
- (that's why a lot of answers are cropped). The rest are default
132
- settings.
133
- </li>
134
- <li>
135
- I made this with a mix of APIs from OpenRouter, TogetherAI, OpenAI,
136
- Cohere, Aleph Alpha & AI21.
137
- </li>
138
- <li>
139
- <b>This is imperfect.</b> I want to improve this by using better
140
- stop sequences and prompt formatting tailored to each model. But
141
- hopefully it can already make picking models a bit easier.
142
- </li>
143
- <li>
144
- Ideas for the future: public votes to compute an ELO rating, compare
145
- 2 models side by side, community-submitted prompts (open to
146
- suggestions)
147
- </li>
148
- <li>
149
- Prompt suggestions, feedback or say hi: vince [at] llmonitor.com
150
- </li>
151
- <li>
152
- {`Shameless plug: I'm building an `}
153
- <a href="https://github.com/llmonitor/llmonitor" target="_blank">
154
- open-source observability tool for AI devs.
155
- </a>
156
- </li>
157
- </ul>
158
- <br />
159
- <br />
160
- <table style={{ maxWidth: 600 }}>
161
- <th>
162
- <p>
163
- Edit: as this got popular, I added an email form to receive
164
- notifications for future benchmark results:
165
- </p>
166
- <iframe
167
- src="https://embeds.beehiiv.com/65bd6af1-2dea-417a-baf2-b65bc27e1610?slim=true"
168
- height="52"
169
- frameborder="0"
170
- scrolling="no"
171
- style={{
172
- width: 400,
173
- border: "none",
174
- transform: "scale(0.8)",
175
- transformOrigin: "left",
176
- }}
177
- ></iframe>
178
- <br />
179
- <small>(no spam, max 1 email per month)</small>
180
- </th>
181
- </table>
182
- <br />
183
- </main>
184
- </>
185
- )
186
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/model/[id].js DELETED
@@ -1,109 +0,0 @@
1
- import getDB from "@/utils/getDB"
2
- import Head from "next/head"
3
- import Link from "next/link"
4
- import { useMemo } from "react"
5
-
6
- export const getStaticPaths = async () => {
7
- const db = await getDB()
8
-
9
- const models = await db.all(`SELECT * FROM models`)
10
-
11
- return {
12
- paths: models.map((model) => ({
13
- params: { id: model.api_id.split("/").pop().toLowerCase() },
14
- })),
15
- fallback: false,
16
- }
17
- }
18
-
19
- export const getStaticProps = async (props) => {
20
- const db = await getDB()
21
-
22
- const { id } = props.params
23
-
24
- console.log("id", id)
25
-
26
- // where api_id contains the id (it's in lowercase)
27
- const model = await db.get(`SELECT * FROM models WHERE api_id LIKE ?`, [
28
- `%${id}%`,
29
- ])
30
-
31
- // get all results for this model, with their prompt (join)
32
- const results = await db.all(
33
- `SELECT * FROM results INNER JOIN prompts ON results.prompt = prompts.id WHERE model = ? ORDER BY prompts.text DESC`,
34
- [model.id]
35
- )
36
-
37
- return { props: { results, model } }
38
- }
39
-
40
- export default function Prompt({ model, results }) {
41
- const medianRate = useMemo(() => {
42
- const rates = results.map((r) => r.rate)
43
- const sorted = rates.sort((a, b) => a - b)
44
- const mid = Math.floor(sorted.length / 2)
45
- return sorted.length % 2 !== 0
46
- ? sorted[mid]
47
- : (sorted[mid - 1] + sorted[mid]) / 2
48
- }, [results])
49
-
50
- return (
51
- <>
52
- <Head>
53
- <title>
54
- {model.org} {model.name} benchmark across 20 prompts
55
- </title>
56
- <meta
57
- name="description"
58
- content={`Human-readable benchmark of ${model.org} ${model.name} across 20 prompts.`}
59
- />
60
- <meta name="viewport" content="width=device-width, initial-scale=1" />
61
- </Head>
62
- <h3>
63
- {model.org} {model.name}
64
- </h3>
65
- <p>Median output rate: {medianRate.toFixed(2)} chars / s</p>
66
-
67
- <br />
68
- <Link href="/">Back to home</Link>
69
- <br />
70
- <br />
71
- <table>
72
- <thead>
73
- <tr>
74
- <th>Prompt</th>
75
- <th>Answer</th>
76
- <th>Latency</th>
77
- </tr>
78
- </thead>
79
- <tbody>
80
- {results
81
- .sort((a, b) => a.name > b.name)
82
- .map((result) => (
83
- <tr>
84
- <td>
85
- <pre>
86
- {result.text}
87
- <br />
88
- <br />
89
- <Link href={`/${result.slug}`}>all answers</Link>
90
- </pre>
91
- </td>
92
- <td>
93
- <pre>{result.result.trim()}</pre>
94
- </td>
95
- <td>{result.duration}ms</td>
96
- </tr>
97
- ))}
98
- </tbody>
99
- </table>
100
- <br />
101
- <Link href="/">Back to home</Link>
102
- <style jsx>{`
103
- th:nth-child(1) {
104
- width: 30%;
105
- }
106
- `}</style>
107
- </>
108
- )
109
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
run/.gitignore CHANGED
@@ -153,3 +153,5 @@ dmypy.json
153
 
154
  # Cython debug symbols
155
  cython_debug/
 
 
 
153
 
154
  # Cython debug symbols
155
  cython_debug/
156
+
157
+ cookies/
run/database.db DELETED
Binary file (627 kB)
 
run/poetry.lock ADDED
The diff for this file is too large to render. See raw diff
 
run/pyproject.toml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [tool.poetry]
2
+ name = "benchmarks"
3
+ version = "0.1.0"
4
+ description = ""
5
+ authors = ["vincelwt <vince@llmonitor.com>"]
6
+
7
+
8
+ [tool.poetry.dependencies]
9
+ python = "^3.9"
10
+ openai = "^0.28.1"
11
+ requests = "^2.31.0"
12
+ python-dotenv = "^1.0.0"
13
+ termcolor = "^2.3.0"
14
+ llmonitor = "0.0.11"
15
+ hugchat = {git = "https://github.com/Soulter/hugging-chat-api", rev = "master"}
16
+ psycopg2-binary = "^2.9.9"
17
+ anthropic = "^0.3.11"
18
+ tenacity = "^8.2.3"
19
+
20
+ [build-system]
21
+ requires = ["poetry-core"]
22
+ build-backend = "poetry.core.masonry.api"
run/queriers.py CHANGED
@@ -2,23 +2,73 @@ import openai
2
  import os
3
  import json
4
  import requests
5
- from dotenv import load_dotenv
6
-
7
  from llmonitor import monitor
 
 
 
 
 
 
 
 
 
 
8
 
 
9
  load_dotenv()
10
 
 
11
  TOGETHER_API_KEY = os.getenv('TOGETHER_API_KEY')
12
  COHERE_API_KEY = os.getenv('COHERE_API_KEY')
13
  AI21_API_KEY = os.getenv('AI21_API_KEY')
14
  ALEPH_API_KEY = os.getenv('ALEPH_API_KEY')
15
  OPEN_ROUTER_API_KEY = os.getenv('OPEN_ROUTER_API_KEY')
16
  OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
 
17
 
18
- MAX_TOKENS = 300
 
 
 
 
19
 
20
  monitor(openai)
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def together(model, params):
23
  def format_prompt(prompt, prompt_type):
24
  if prompt_type == "language":
@@ -37,7 +87,7 @@ def together(model, params):
37
  data = {
38
  "model": model['api_id'],
39
  "prompt": format_prompt(params['text'], model['type']),
40
- "stop": params['stop'] if model['type'] == "chat" else params.get('stop', None),
41
  "temperature": 0,
42
  "max_tokens": MAX_TOKENS,
43
  }
@@ -71,6 +121,7 @@ def cohere(model, params):
71
 
72
  return json_response['generations'][0]['text']
73
 
 
74
  def openai_func(model, params):
75
 
76
  openai.api_key = OPENAI_API_KEY
@@ -105,19 +156,39 @@ def ai21(model, params):
105
  return json_response['completions'][0]['data']['text']
106
 
107
  def openrouter(model, params):
108
- openai.api_key = OPEN_ROUTER_API_KEY
109
- openai.api_base ="https://openrouter.ai/api/v1"
110
-
111
- completion = openai.ChatCompletion.create(
112
- messages=[{"role": "user", "content": params['text']}],
113
- temperature=0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  model=model['api_id'],
115
- max_tokens=MAX_TOKENS,
116
- headers={"HTTP-Referer": "https://benchmarks.llmonitor.com"},
117
- stop=[params['stop']] if params.get('stop') else []
118
  )
119
-
120
- return completion.choices[0].message.content
121
 
122
  def alephalpha(model, params):
123
  options = {
 
2
  import os
3
  import json
4
  import requests
 
 
5
  from llmonitor import monitor
6
+ from hugchat import hugchat
7
+ from hugchat.login import Login
8
+ from anthropic import Anthropic, HUMAN_PROMPT, AI_PROMPT
9
+
10
+ from tenacity import (
11
+ retry,
12
+ stop_after_attempt,
13
+ wait_exponential,
14
+ wait_random_exponential,
15
+ ) # for exponential backoff
16
 
17
+ from dotenv import load_dotenv
18
  load_dotenv()
19
 
20
+
21
  TOGETHER_API_KEY = os.getenv('TOGETHER_API_KEY')
22
  COHERE_API_KEY = os.getenv('COHERE_API_KEY')
23
  AI21_API_KEY = os.getenv('AI21_API_KEY')
24
  ALEPH_API_KEY = os.getenv('ALEPH_API_KEY')
25
  OPEN_ROUTER_API_KEY = os.getenv('OPEN_ROUTER_API_KEY')
26
  OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
27
+ ANTHROPIC_API_KEY = os.getenv('ANTHROPIC_API_KEY')
28
 
29
+ # Huggingface login credentials
30
+ HUGGING_EMAIL = os.environ.get("HUGGING_EMAIL")
31
+ HUGGING_PASSWORD = os.environ.get("HUGGING_PASSWORD")
32
+
33
+ MAX_TOKENS = 600
34
 
35
  monitor(openai)
36
 
37
+
38
+ # Log in to huggingface and grant authorization to huggingchat
39
+ sign = Login(HUGGING_EMAIL, HUGGING_PASSWORD)
40
+ cookie_path_dir = "./cookies"
41
+
42
+ try:
43
+ cookies = sign.loadCookiesFromDir(cookie_path_dir) # This will detect if the JSON file exists, return cookies if it does and raise an Exception if it's not.
44
+
45
+ except Exception as e:
46
+ print(e)
47
+
48
+ # Save cookies to the local directory
49
+ sign.saveCookiesToDir(cookie_path_dir)
50
+ cookies = sign.login()
51
+
52
+ chatbot = hugchat.ChatBot(cookies=cookies.get_dict()) # or cookie_path="usercookies/<email>.json"
53
+
54
+ def hugchat_func(model, params):
55
+
56
+ # Create a new conversation
57
+ id = chatbot.new_conversation()
58
+ chatbot.change_conversation(id)
59
+
60
+ # get index from chatbot.llms of the model
61
+ index = [i for i, x in enumerate(chatbot.llms) if x == model['api_id']][0]
62
+
63
+ print(f"Switching to {index}")
64
+
65
+ # set the chatbot to the model
66
+ chatbot.switch_llm(index)
67
+
68
+ query_result = chatbot.query(params['text'], temperature=0, max_new_tokens=MAX_TOKENS, stop=params['stop'] if params.get('stop') else None)
69
+
70
+ return query_result['text']
71
+
72
  def together(model, params):
73
  def format_prompt(prompt, prompt_type):
74
  if prompt_type == "language":
 
87
  data = {
88
  "model": model['api_id'],
89
  "prompt": format_prompt(params['text'], model['type']),
90
+ "stop": "\n<human>" if model['type'] == "chat" else params.get('stop', None),
91
  "temperature": 0,
92
  "max_tokens": MAX_TOKENS,
93
  }
 
121
 
122
  return json_response['generations'][0]['text']
123
 
124
+ @retry(wait=wait_exponential(multiplier=1, min=4, max=16))
125
  def openai_func(model, params):
126
 
127
  openai.api_key = OPENAI_API_KEY
 
156
  return json_response['completions'][0]['data']['text']
157
 
158
  def openrouter(model, params):
159
+
160
+ response = requests.post(
161
+ url="https://openrouter.ai/api/v1/chat/completions",
162
+ headers={
163
+ "HTTP-Referer": 'https://benchmarks.llmonitor.com', # To identify your app. Can be set to localhost for testing
164
+ "Authorization": "Bearer " + OPEN_ROUTER_API_KEY
165
+ },
166
+ data=json.dumps({
167
+ "model": model['api_id'],
168
+ "temperature": 0,
169
+ "max_tokens": MAX_TOKENS,
170
+ "stop": [params['stop']] if params.get('stop') else [],
171
+ "messages": [
172
+ {"role": "user", "content": params['text']}
173
+ ]
174
+ })
175
+ )
176
+
177
+ completion = response.json()
178
+
179
+ return completion["choices"][0]["message"]["content"]
180
+
181
+ def anthropic_func(model,params):
182
+ anthropic = Anthropic(
183
+ api_key=ANTHROPIC_API_KEY
184
+ )
185
+ completion = anthropic.completions.create(
186
  model=model['api_id'],
187
+ temperature=0,
188
+ max_tokens_to_sample=MAX_TOKENS,
189
+ prompt=f"{HUMAN_PROMPT} {params['text']}{AI_PROMPT}",
190
  )
191
+ return completion.completion
 
192
 
193
  def alephalpha(model, params):
194
  options = {
run/requirements.txt CHANGED
@@ -1,6 +1,4 @@
1
  openai
2
- pandas
3
  requests
4
  python-dotenv
5
- gradio
6
  llmonitor
 
1
  openai
 
2
  requests
3
  python-dotenv
 
4
  llmonitor
run/run.py CHANGED
@@ -1,53 +1,68 @@
1
  import sqlite3
2
  import time
3
  from termcolor import colored
4
- from llmonitor import agent
5
- from queriers import together, cohere, openai_func, openrouter, ai21, alephalpha
 
 
6
 
7
- db = sqlite3.connect("./database.db")
8
- db.row_factory = sqlite3.Row
 
9
 
10
- cursor = db.cursor()
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  def remove_end(s, suffix):
13
  if s.endswith(suffix):
14
  return s[:-len(suffix)]
15
  return s
16
 
17
-
18
  # Fetch models
19
- models = cursor.execute("SELECT * FROM models").fetchall()
20
- models = [dict(model) for model in models]
21
 
22
  # Fetch prompts
23
- prompts = cursor.execute("SELECT * FROM prompts").fetchall()
24
- prompts = [dict(prompt) for prompt in prompts]
25
 
26
 
27
  def get_results():
28
- results = cursor.execute("SELECT * FROM results").fetchall()
29
- print(results[0].keys())
30
- return [dict(result) for result in results]
31
 
32
  def insert_result(modelId, promptId, result, duration, rate):
33
  cursor.execute(
34
- "INSERT INTO results (model, prompt, result, duration, rate) VALUES (?, ?, ?, ?, ?)",
35
  (modelId, promptId, result, duration, rate)
36
  )
37
- db.commit()
38
  pass
39
 
40
  def check_if_results_exist(modelId, promptId):
41
- results = cursor.execute(
42
- "SELECT * FROM results WHERE model = ? AND prompt = ? LIMIT 1", (modelId, promptId)
43
- ).fetchall()
 
44
  return len(results) > 0
45
 
46
  def ask_prompt(prompt, model):
47
  exists = check_if_results_exist(model["id"], prompt["id"])
48
 
49
  if exists:
50
- print("Skipping, already got benchmark")
51
  return
52
 
53
  mapping = {
@@ -56,6 +71,8 @@ def ask_prompt(prompt, model):
56
  "openai": openai_func,
57
  "openrouter": openrouter,
58
  "ai21": ai21,
 
 
59
  # "alephalpha": alephalpha # TODO: get a working API key
60
  }
61
 
@@ -65,7 +82,10 @@ def ask_prompt(prompt, model):
65
  print(f"No querier for {model['api']}")
66
  return
67
 
68
- print(f"Querying {model['name']}")
 
 
 
69
 
70
  start_time = time.time()
71
 
@@ -82,40 +102,45 @@ def ask_prompt(prompt, model):
82
  duration = end_time - start_time
83
  chars_per_second = round(len(response_text) / duration, 2)
84
 
85
- print("------------------------------------")
86
- print(f"Result: {cleaned}")
87
- print(f"Took {duration*1000} ms ({chars_per_second} chars/s)")
88
- print("------------------------------------")
89
 
90
  insert_result(model["id"], prompt["id"], cleaned, duration*1000, chars_per_second)
91
 
92
  except Exception as e:
93
- print(f"Error querying {model['name']}", e)
94
 
95
 
96
  total_benchmarks = len(models) * len(prompts)
97
- print(f"Running {total_benchmarks} benchmarks")
98
 
99
- # # Run prompts
100
- # for model in models:
101
- # if model["type"] == "language":
102
- # continue
103
- # for prompt in prompts:
104
- # if prompt["type"] != "code" and model["type"] == "code":
105
- # print("Skipping non-code benchmark for code model")
106
- # continue
107
 
108
- # ask_prompt(prompt, model)
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  # Calculate scores
111
  results = get_results()
112
 
113
- @agent(name="RateResult")
114
  def rate_result(result):
115
- rubrics = cursor.execute(
116
- "SELECT * FROM rubrics WHERE prompt = ?",
117
  (result["prompt"],)
118
- ).fetchall()
 
119
 
120
  has_rubrics = len(rubrics) > 0
121
 
@@ -128,7 +153,7 @@ def rate_result(result):
128
  print(colored(result["result"], 'cyan'))
129
  print(colored('---------------------------', 'white'))
130
 
131
- score = None
132
 
133
  for rubric in rubrics:
134
 
@@ -138,10 +163,11 @@ def rate_result(result):
138
  score = 0
139
  else:
140
  grading_text = (
141
- f'You help verify that the following answer match this condition: the answer {rubric["grading"]}. Note: the answer might be imcomplete, in which case do your best to assess based on what the full result would be.\n\n'
142
  f'\n\n--START OF THE ANSWER--\n{result["result"]}\n--END OF THE ANSWER--\n\n'
143
- f'Take a deep breath and explain step by step how you come to the conclusion.'
144
- f'Finally, reply on the last line with YES if the following answer matches this condition (otherwies reply NO).'
 
145
  )
146
 
147
  # get gpt-4 model
@@ -164,17 +190,16 @@ def rate_result(result):
164
 
165
  return score
166
 
167
-
168
-
169
  for result in results:
170
- if not result["score"]:
171
  score = rate_result(result)
172
 
173
  if score is not None:
174
  cursor.execute(
175
- "UPDATE results SET score = ? WHERE id == ?",
176
  (score, result["id"])
177
  )
178
- db.commit()
179
 
180
- db.close()
 
 
1
  import sqlite3
2
  import time
3
  from termcolor import colored
4
+ import psycopg2
5
+ from queriers import together, cohere, openai_func, openrouter, ai21, alephalpha, hugchat_func, anthropic_func
6
+ import psycopg2.extras
7
+ import psycopg2.pool
8
 
9
+ import os
10
+ from dotenv import load_dotenv
11
+ load_dotenv()
12
 
13
+ # Connect to database
14
+ PG_URI = os.environ.get("POSTGRES_URL")
15
+
16
+
17
+ # Create a connection pool with a minimum of 2 connections and
18
+ #a maximum of 3 connections
19
+ pool = psycopg2.pool.SimpleConnectionPool(2, 10, dsn=PG_URI)
20
+
21
+ #conn = psycopg2.connect(PG_URI)
22
+
23
+ conn = pool.getconn()
24
+
25
+ cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
26
 
27
  def remove_end(s, suffix):
28
  if s.endswith(suffix):
29
  return s[:-len(suffix)]
30
  return s
31
 
 
32
  # Fetch models
33
+ cursor.execute("SELECT * FROM models")
34
+ models = cursor.fetchall()
35
 
36
  # Fetch prompts
37
+ cursor.execute("SELECT * FROM prompts WHERE selected = true")
38
+ prompts = cursor.fetchall()
39
 
40
 
41
  def get_results():
42
+ cursor.execute("SELECT * FROM results")
43
+ results = cursor.fetchall()
44
+ return results
45
 
46
  def insert_result(modelId, promptId, result, duration, rate):
47
  cursor.execute(
48
+ "INSERT INTO results (model, prompt, result, duration, rate) VALUES (%s, %s, %s, %s, %s)",
49
  (modelId, promptId, result, duration, rate)
50
  )
51
+ conn.commit()
52
  pass
53
 
54
  def check_if_results_exist(modelId, promptId):
55
+ cursor.execute(
56
+ "SELECT * FROM results WHERE model = %s AND prompt = %s LIMIT 1", (modelId, promptId)
57
+ )
58
+ results = cursor.fetchall()
59
  return len(results) > 0
60
 
61
  def ask_prompt(prompt, model):
62
  exists = check_if_results_exist(model["id"], prompt["id"])
63
 
64
  if exists:
65
+ print(f"Skipping {model['name']}, already got benchmark")
66
  return
67
 
68
  mapping = {
 
71
  "openai": openai_func,
72
  "openrouter": openrouter,
73
  "ai21": ai21,
74
+ "hugchat": hugchat_func,
75
+ "anthropic": anthropic_func,
76
  # "alephalpha": alephalpha # TODO: get a working API key
77
  }
78
 
 
82
  print(f"No querier for {model['api']}")
83
  return
84
 
85
+ print(colored("------------------------------------", 'white'))
86
+ print(colored(f"Querying {model['name']}", 'white'))
87
+ print(colored(f"Prompt: {prompt['text']}", 'white'))
88
+ print(colored("------------------------------------", 'white'))
89
 
90
  start_time = time.time()
91
 
 
102
  duration = end_time - start_time
103
  chars_per_second = round(len(response_text) / duration, 2)
104
 
105
+ print(colored("------------------------------------", 'green'))
106
+ print(colored(f"Result: {cleaned}", 'green'))
107
+ print(colored(f"Took {duration*1000} ms ({chars_per_second} chars/s)", 'green'))
108
+ print(colored("------------------------------------", 'green'))
109
 
110
  insert_result(model["id"], prompt["id"], cleaned, duration*1000, chars_per_second)
111
 
112
  except Exception as e:
113
+ print(colored(f"Error querying {model['name']} ", 'red'), e)
114
 
115
 
116
  total_benchmarks = len(models) * len(prompts)
 
117
 
118
+ print(colored(f"Running {total_benchmarks} benchmarks", 'blue'))
 
 
 
 
 
 
 
119
 
120
+ # Run prompts
121
+ for model in models:
122
+
123
+ if model["type"] != "chat":
124
+ # Skip non-chat models for now
125
+ continue
126
+
127
+ for prompt in prompts:
128
+ # if prompt["type"] != "code" and model["type"] == "code":
129
+ # print("Skipping non-code benchmark for code model")
130
+ # continue
131
+
132
+ ask_prompt(prompt, model)
133
 
134
  # Calculate scores
135
  results = get_results()
136
 
137
+ #@agent(name="RateResult")
138
  def rate_result(result):
139
+ cursor.execute(
140
+ "SELECT * FROM rubrics WHERE prompt = %s",
141
  (result["prompt"],)
142
+ )
143
+ rubrics = cursor.fetchall()
144
 
145
  has_rubrics = len(rubrics) > 0
146
 
 
153
  print(colored(result["result"], 'cyan'))
154
  print(colored('---------------------------', 'white'))
155
 
156
+ score = 0
157
 
158
  for rubric in rubrics:
159
 
 
163
  score = 0
164
  else:
165
  grading_text = (
166
+ f'You help me grade the answer of chatbots by verifying that they match this condition: the answer {rubric["grading"]}. Note: the answer might be imcomplete, in which case do your best to assess based on what the full result would be. Your rating needs to be very strict: if I ask that the answer is *exactly* some string and it contains more than that, then it\'s invalid.\n\n'
167
  f'\n\n--START OF THE ANSWER--\n{result["result"]}\n--END OF THE ANSWER--\n\n'
168
+ # f'Take a deep breath and explain step by step how you come to the conclusion.'
169
+ # f'Finally, reply on the last line with YES if the following answer matches this condition (otherwies reply NO).'
170
+ f'Reply with YES if the text between START and END matches exactly the above condition (otherwise reply NO).'
171
  )
172
 
173
  # get gpt-4 model
 
190
 
191
  return score
192
 
 
 
193
  for result in results:
194
+ if result["score"] is None:
195
  score = rate_result(result)
196
 
197
  if score is not None:
198
  cursor.execute(
199
+ "UPDATE results SET score = %s WHERE id = %s",
200
  (score, result["id"])
201
  )
202
+ conn.commit()
203
 
204
+ cursor.close()
205
+ conn.close()
run/test.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+
4
+ response = requests.post(
5
+ url="https://openrouter.ai/api/v1/chat/completions",
6
+ headers={
7
+ "HTTP-Referer": 'https://benchmarks.llmonitor.com', # To identify your app. Can be set to localhost for testing
8
+ "Authorization": "Bearer " + "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"
9
+ },
10
+ data=json.dumps({
11
+ "model": "mistralai/mistral-7b-instruct", # Optional
12
+ "messages": [
13
+ {"role": "user", "content": "What is the meaning of life?"}
14
+ ]
15
+ })
16
+ )
17
+
18
+
19
+ print(response.json())
styles/globals.css CHANGED
@@ -14,6 +14,9 @@ a {
14
  /* text-decoration: none; */
15
  }
16
 
 
 
 
17
 
18
 
19
  ul {
@@ -24,6 +27,15 @@ li {
24
  margin-bottom: 10px;
25
  }
26
 
 
 
 
 
 
 
 
 
 
27
  table {
28
  /* border-collapse: collapse; */
29
  width: 100%;
@@ -39,7 +51,7 @@ th, td {
39
  text-align: left;
40
  }
41
 
42
- th:nth-child(1) {
43
  width: 200px;
44
  }
45
 
@@ -47,18 +59,13 @@ th:nth-child(2) {
47
  width: auto;
48
  }
49
 
50
- pre {
51
- background-color: #eee;
52
- padding: 10px;
53
- border-radius: 5px;
54
- white-space: pre-wrap;
55
- word-wrap: break-word;
56
- }
57
-
58
  th:nth-child(3),
59
  th:nth-child(4) {
60
  width: 100px;
61
- }
 
 
 
62
 
63
  @media (max-width: 800px) {
64
  table {
@@ -68,7 +75,7 @@ th:nth-child(4) {
68
  max-width: 700px;
69
  }
70
 
71
- th:nth-child(1) {
72
  width: 50px;
73
  }
74
 
@@ -78,7 +85,7 @@ th:nth-child(4) {
78
  th:nth-child(4),
79
  td:nth-child(4) {
80
  display: none;
81
- }
82
  }
83
 
84
  @media (prefers-color-scheme: dark) {
@@ -112,4 +119,13 @@ th:nth-child(4) {
112
 
113
  .llmonitor:hover {
114
  transform: scale(1.1);
 
 
 
 
 
 
 
 
 
115
  }
 
14
  /* text-decoration: none; */
15
  }
16
 
17
+ p {
18
+ margin-bottom: 10px;
19
+ }
20
 
21
 
22
  ul {
 
27
  margin-bottom: 10px;
28
  }
29
 
30
+ pre {
31
+ background-color: #eee;
32
+ padding: 10px;
33
+ border-radius: 5px;
34
+ white-space: pre-wrap;
35
+ word-wrap: break-word;
36
+ }
37
+
38
+
39
  table {
40
  /* border-collapse: collapse; */
41
  width: 100%;
 
51
  text-align: left;
52
  }
53
 
54
+ /* th:nth-child(1) {
55
  width: 200px;
56
  }
57
 
 
59
  width: auto;
60
  }
61
 
 
 
 
 
 
 
 
 
62
  th:nth-child(3),
63
  th:nth-child(4) {
64
  width: 100px;
65
+ } */
66
+
67
+
68
+
69
 
70
  @media (max-width: 800px) {
71
  table {
 
75
  max-width: 700px;
76
  }
77
 
78
+ /* th:nth-child(1) {
79
  width: 50px;
80
  }
81
 
 
85
  th:nth-child(4),
86
  td:nth-child(4) {
87
  display: none;
88
+ } */
89
  }
90
 
91
  @media (prefers-color-scheme: dark) {
 
119
 
120
  .llmonitor:hover {
121
  transform: scale(1.1);
122
+ }
123
+
124
+ input, textarea {
125
+ font-size: 10px;
126
+ font-family: monospace;
127
+ }
128
+
129
+ button {
130
+ padding: 5px 10px;
131
  }
utils/db.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import postgres from "postgres"
2
+ import { cache } from "react"
3
+
4
+ const sql = postgres(process.env.POSTGRES_URL) // will use psql environment variables
5
+
6
+ export const getModels = cache(async () => {
7
+ const models = await sql`
8
+ SELECT models.*, SUM(results.score) as total_score
9
+ FROM models
10
+ LEFT JOIN results ON models.id = results.model
11
+ GROUP BY models.id
12
+ ORDER BY total_score DESC;
13
+ `
14
+
15
+ return models.map((m) => ({
16
+ ...m,
17
+ slug: m.api_id.split("/").pop().toLowerCase(),
18
+ }))
19
+ })
20
+
21
+ export default sql
utils/email.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const sendEmail = async (body) => {
2
+ if (!process.env.RESEND_KEY) {
3
+ return console.warn("RESEND_KEY is not set, skipping email sending")
4
+ }
5
+
6
+ const res = await fetch("https://api.resend.com/emails", {
7
+ method: "POST",
8
+ headers: {
9
+ "Content-Type": "application/json",
10
+ Authorization: `Bearer ${process.env.RESEND_KEY}`,
11
+ },
12
+ body: JSON.stringify(body),
13
+ })
14
+
15
+ return await res.json()
16
+ }
utils/getDB.js DELETED
@@ -1,13 +0,0 @@
1
- import sqlite3 from "sqlite3"
2
- import { open } from "sqlite"
3
-
4
- const getDB = async () => {
5
- const db = await open({
6
- filename: process.cwd() + "/run/database.db",
7
- driver: sqlite3.Database,
8
- })
9
-
10
- return db
11
- }
12
-
13
- export default getDB