├── public
└── favicon.ico
├── postcss.config.cjs
├── prettier.config.cjs
├── src
├── components
│ ├── analytics.tsx
│ ├── tagsBox.tsx
│ └── layout.tsx
├── styles
│ └── globals.css
├── utils
│ ├── store.ts
│ └── trpc.ts
├── types
│ ├── next-auth.d.ts
│ └── problem-data.ts
├── pages
│ ├── api
│ │ ├── examples.ts
│ │ ├── pa-import-mock.ts
│ │ ├── trpc
│ │ │ └── [trpc].ts
│ │ ├── restricted.ts
│ │ └── auth
│ │ │ └── [...nextauth].ts
│ └── _app.tsx
├── server
│ ├── trpc
│ │ ├── router
│ │ │ ├── auth.ts
│ │ │ ├── example.ts
│ │ │ ├── _app.ts
│ │ │ └── attempt.ts
│ │ ├── trpc.ts
│ │ └── context.ts
│ ├── db
│ │ └── client.ts
│ └── common
│ │ └── get-server-auth-session.ts
├── data
│ ├── problems
│ │ ├── order.txt
│ │ ├── Asia Pacific Informatics Olympiad
│ │ │ ├── 2020.json
│ │ │ ├── 2021.json
│ │ │ ├── 2022.json
│ │ │ ├── 2011.json
│ │ │ ├── 2012.json
│ │ │ ├── 2013.json
│ │ │ ├── 2007.json
│ │ │ ├── 2009.json
│ │ │ ├── 2010.json
│ │ │ ├── 2008.json
│ │ │ ├── 2014.json
│ │ │ ├── 2015.json
│ │ │ ├── 2016.json
│ │ │ ├── 2017.json
│ │ │ ├── 2019.json
│ │ │ └── 2018.json
│ │ ├── Japanese Olympiad in Informatics: Open Contest
│ │ │ ├── 2019.json
│ │ │ ├── 2016.json
│ │ │ ├── 2017.json
│ │ │ ├── 2013.json
│ │ │ ├── 2020.json
│ │ │ ├── 2021.json
│ │ │ ├── 2022.json
│ │ │ ├── 2015.json
│ │ │ ├── 2018.json
│ │ │ └── 2014.json
│ │ ├── Balkan Olympiad in Informatics
│ │ │ ├── 2009.json
│ │ │ ├── 2015.json
│ │ │ ├── 2017.json
│ │ │ ├── 2012.json
│ │ │ ├── 2018.json
│ │ │ ├── 2016.json
│ │ │ └── 2011.json
│ │ ├── National Olympiad in Informatics (Singapore)
│ │ │ ├── 2013.json
│ │ │ ├── 2012.json
│ │ │ ├── 2014.json
│ │ │ ├── 2015.json
│ │ │ ├── 2016.json
│ │ │ ├── 2017.json
│ │ │ └── 2011.json
│ │ ├── Croatian Olympiad in Informatics
│ │ │ ├── 2018.json
│ │ │ ├── 2021.json
│ │ │ ├── 2022.json
│ │ │ ├── 2020.json
│ │ │ ├── 2017.json
│ │ │ ├── 2019.json
│ │ │ └── 2016.json
│ │ ├── InfO(1) Cup
│ │ │ ├── 2019.json
│ │ │ ├── 2018.json
│ │ │ ├── 2020.json
│ │ │ └── 2017.json
│ │ ├── Japanese Olympiad in Informatics: Final Round
│ │ │ ├── 2017.json
│ │ │ ├── 2021.json
│ │ │ ├── 2020.json
│ │ │ ├── 2022.json
│ │ │ ├── 2018.json
│ │ │ ├── 2019.json
│ │ │ ├── 2014.json
│ │ │ ├── 2016.json
│ │ │ ├── 2015.json
│ │ │ └── 2013.json
│ │ ├── Central-European Olympiad in Informatics
│ │ │ ├── 2009.json
│ │ │ ├── 2016.json
│ │ │ ├── 2012.json
│ │ │ ├── 2014.json
│ │ │ ├── 2010.json
│ │ │ ├── 2013.json
│ │ │ ├── 2007.json
│ │ │ ├── 2011.json
│ │ │ ├── 2017.json
│ │ │ ├── 2018.json
│ │ │ ├── 2015.json
│ │ │ ├── 2019.json
│ │ │ ├── 2021.json
│ │ │ ├── 2022.json
│ │ │ ├── 2020.json
│ │ │ ├── 2005.json
│ │ │ ├── 2006.json
│ │ │ └── 2008.json
│ │ ├── Baltic Olympiad in Informatics
│ │ │ ├── 2020.json
│ │ │ ├── 2021.json
│ │ │ ├── 2022.json
│ │ │ ├── 2006.json
│ │ │ ├── 2012.json
│ │ │ ├── 2016.json
│ │ │ ├── 2017.json
│ │ │ ├── 2010.json
│ │ │ ├── 2008.json
│ │ │ ├── 2019.json
│ │ │ ├── 2005.json
│ │ │ ├── 2007.json
│ │ │ ├── 2009.json
│ │ │ ├── 2018.json
│ │ │ ├── 2015.json
│ │ │ ├── 2013.json
│ │ │ └── 2014.json
│ │ ├── International Olympiad in Informatics
│ │ │ ├── 2021.json
│ │ │ ├── 2022.json
│ │ │ ├── 2020.json
│ │ │ ├── 2013.json
│ │ │ ├── 2014.json
│ │ │ ├── 2011.json
│ │ │ ├── 2015.json
│ │ │ ├── 2007.json
│ │ │ ├── 2005.json
│ │ │ ├── 2008.json
│ │ │ ├── 2012.json
│ │ │ ├── 2003.json
│ │ │ ├── 2004.json
│ │ │ ├── 2006.json
│ │ │ ├── 2019.json
│ │ │ └── 2017.json
│ │ └── International Zhautykov Olympiad in Informatics
│ │ │ ├── 2014.json
│ │ │ ├── 2017.json
│ │ │ ├── 2018.json
│ │ │ ├── 2019.json
│ │ │ ├── 2015.json
│ │ │ ├── 2020.json
│ │ │ ├── 2016.json
│ │ │ ├── 2021.json
│ │ │ ├── 2022.json
│ │ │ ├── 2012.json
│ │ │ ├── 2013.json
│ │ │ └── 2011.json
│ ├── update_tags.py
│ ├── filter_tags.json
│ └── combine.py
└── env
│ ├── server.mjs
│ ├── client.mjs
│ └── schema.mjs
├── tailwind.config.cjs
├── next.config.mjs
├── tsconfig.json
├── .gitignore
├── LICENSE
└── package.json
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/labs-asterisk/oichecklist/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/prettier.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import("prettier").Config} */
2 | module.exports = {
3 | plugins: [require.resolve("prettier-plugin-tailwindcss")],
4 | };
5 |
--------------------------------------------------------------------------------
/src/components/analytics.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Analytics } from "@vercel/analytics/react";
3 |
4 | export function AnalyticsWrapper() {
5 | return ;
6 | }
7 |
--------------------------------------------------------------------------------
/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ["./src/**/*.{js,ts,jsx,tsx}"],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | };
9 |
--------------------------------------------------------------------------------
/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | html,
6 | body,
7 | #__next {
8 | height: 100%;
9 | overflow-y: hidden;
10 | overflow-x: hidden;
11 | }
12 |
13 | li[role="option"] {
14 | color: black !important;
15 | }
16 |
--------------------------------------------------------------------------------
/src/utils/store.ts:
--------------------------------------------------------------------------------
1 | import { atom } from "jotai";
2 | import problems from "../data/problem_data.json";
3 | import filterTags from "../data/filter_tags.json";
4 |
5 | export const problemsAtom = atom(problems);
6 | export const filterTopicsAtom = atom(
7 | Object.entries(filterTags.topicWise).map(([tag, occ], j) => tag)
8 | );
9 |
10 |
--------------------------------------------------------------------------------
/src/types/next-auth.d.ts:
--------------------------------------------------------------------------------
1 | import { type DefaultSession } from "next-auth";
2 |
3 | declare module "next-auth" {
4 | /**
5 | * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
6 | */
7 | interface Session {
8 | user?: {
9 | id: string;
10 | } & DefaultSession["user"];
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/pages/api/examples.ts:
--------------------------------------------------------------------------------
1 | import { type NextApiRequest, type NextApiResponse } from "next";
2 |
3 | import { prisma } from "../../server/db/client";
4 |
5 | const examples = async (req: NextApiRequest, res: NextApiResponse) => {
6 | const examples = await prisma.example.findMany();
7 | res.status(200).json(examples);
8 | };
9 |
10 | export default examples;
11 |
--------------------------------------------------------------------------------
/src/server/trpc/router/auth.ts:
--------------------------------------------------------------------------------
1 | import { router, publicProcedure, protectedProcedure } from "../trpc";
2 |
3 | export const authRouter = router({
4 | getSession: publicProcedure.query(({ ctx }) => {
5 | return ctx.session;
6 | }),
7 | getSecretMessage: protectedProcedure.query(() => {
8 | return "you can now see this secret message!";
9 | }),
10 | });
11 |
--------------------------------------------------------------------------------
/next.config.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | /**
3 | * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
4 | * This is especially useful for Docker builds.
5 | */
6 | !process.env.SKIP_ENV_VALIDATION && (await import("./src/env/server.mjs"));
7 |
8 | /** @type {import("next").NextConfig} */
9 | const config = {
10 | reactStrictMode: true,
11 | swcMinify: true,
12 | i18n: {
13 | locales: ["en"],
14 | defaultLocale: "en",
15 | },
16 | };
17 | export default config;
18 |
--------------------------------------------------------------------------------
/src/server/db/client.ts:
--------------------------------------------------------------------------------
1 | import { PrismaClient } from "@prisma/client";
2 |
3 | import { env } from "../../env/server.mjs";
4 |
5 | declare global {
6 | // eslint-disable-next-line no-var
7 | var prisma: PrismaClient | undefined;
8 | }
9 |
10 | export const prisma =
11 | global.prisma ||
12 | new PrismaClient({
13 | log:
14 | env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
15 | });
16 |
17 | if (env.NODE_ENV !== "production") {
18 | global.prisma = prisma;
19 | }
20 |
--------------------------------------------------------------------------------
/src/server/trpc/router/example.ts:
--------------------------------------------------------------------------------
1 | import { z } from "zod";
2 |
3 | import { router, publicProcedure } from "../trpc";
4 |
5 | export const exampleRouter = router({
6 | hello: publicProcedure
7 | .input(z.object({ text: z.string().nullish() }).nullish())
8 | .query(({ input }) => {
9 | return {
10 | greeting: `Hello ${input?.text ?? "world"}`,
11 | };
12 | }),
13 | getAll: publicProcedure.query(({ ctx }) => {
14 | return ctx.prisma.example.findMany();
15 | }),
16 | });
17 |
--------------------------------------------------------------------------------
/src/server/trpc/router/_app.ts:
--------------------------------------------------------------------------------
1 | import { router } from "../trpc";
2 | // import { authRouter } from "./auth";
3 | // import { exampleRouter } from "./example";
4 |
5 | import { attemptRouter } from "./attempt";
6 | import { viewRouter } from "./view";
7 | import { importRouter } from "./import";
8 |
9 | export const appRouter = router({
10 | // example: exampleRouter,
11 | // auth: authRouter,
12 | attempt: attemptRouter,
13 | view: viewRouter,
14 | import: importRouter
15 | });
16 |
17 | // export type definition of API
18 | export type AppRouter = typeof appRouter;
19 |
--------------------------------------------------------------------------------
/src/pages/api/pa-import-mock.ts:
--------------------------------------------------------------------------------
1 | import { type NextApiRequest, type NextApiResponse } from "next";
2 |
3 | import { getPythonAnywhereProblems } from "../../server/common/pa-import";
4 |
5 | const paImportMock = async (req: NextApiRequest, res: NextApiResponse) => {
6 | const url =
7 | "oichecklist.pythonanywhere.com/view/4c47fbe2fda9f464a8e57b895b0dc36574000586";
8 |
9 | const paProblems = await getPythonAnywhereProblems(url);
10 |
11 | console.log("got paProblems: ", paProblems);
12 |
13 | res.status(200).json(paProblems);
14 | };
15 |
16 | export default paImportMock;
17 |
--------------------------------------------------------------------------------
/src/pages/api/trpc/[trpc].ts:
--------------------------------------------------------------------------------
1 | import { createNextApiHandler } from "@trpc/server/adapters/next";
2 |
3 | import { env } from "../../../env/server.mjs";
4 | import { createContext } from "../../../server/trpc/context";
5 | import { appRouter } from "../../../server/trpc/router/_app";
6 |
7 | // export API handler
8 | export default createNextApiHandler({
9 | router: appRouter,
10 | createContext,
11 | onError:
12 | env.NODE_ENV === "development"
13 | ? ({ path, error }) => {
14 | console.error(`❌ tRPC failed on ${path}: ${error}`);
15 | }
16 | : undefined,
17 | });
18 |
--------------------------------------------------------------------------------
/src/data/problems/order.txt:
--------------------------------------------------------------------------------
1 | International Olympiad in Informatics
2 | Asia Pacific Informatics Olympiad
3 | USA Computing Olympiad
4 | Central-European Olympiad in Informatics
5 | Baltic Olympiad in Informatics
6 | National Olympiad in Informatics (Singapore)
7 | International Zhautykov Olympiad in Informatics
8 | Japanese Olympiad in Informatics: Final Round
9 | Japanese Olympiad in Informatics: Open Contest
10 | Japanese Olympiad in Informatics: Spring Camp
11 | Croatian Olympiad in Informatics
12 | Balkan Olympiad in Informatics
13 | InfO(1) Cup
14 | Polish Olympiad in Informatics
15 | Croatian Open Competition in Informatics
--------------------------------------------------------------------------------
/src/data/update_tags.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | f = open("problem_data.json")
4 | data = json.load(f)
5 |
6 | tags = {}
7 |
8 | for section in data["sections"]:
9 | for year in section["years"]:
10 | for problem in year["problems"]:
11 | for tag in problem["tags"]:
12 | if tag in tags:
13 | tags[tag] += 1
14 | else:
15 | tags[tag] = 1
16 |
17 | to_write = {}
18 | to_write["topicWise"] = tags
19 |
20 | json_object = json.dumps(to_write, indent=2)
21 | with open("filter_tags.json", "w") as outfile:
22 | outfile.write(json_object)
23 |
--------------------------------------------------------------------------------
/src/types/problem-data.ts:
--------------------------------------------------------------------------------
1 | export interface Checklist {
2 | sections: Section[];
3 | }
4 |
5 | export interface Section {
6 | sectionName: string;
7 | years: Year[];
8 | }
9 |
10 | export interface Year {
11 | year: string;
12 | problems: Problem[];
13 | }
14 |
15 | export interface Problem {
16 | slug: string;
17 | name: string;
18 | editorial: string;
19 | link: string;
20 | solves: number;
21 | tags: string[];
22 | }
23 |
24 | export enum AttemptingState {
25 | Untouched = "Untouched", // white
26 | Attempting = "Attempting", // yellow
27 | Unimplemented = "Unimplemented", // blue
28 | Solved = "Solved", // green
29 | }
30 |
--------------------------------------------------------------------------------
/src/server/common/get-server-auth-session.ts:
--------------------------------------------------------------------------------
1 | import { type GetServerSidePropsContext } from "next";
2 | import { unstable_getServerSession } from "next-auth";
3 |
4 | import { authOptions } from "../../pages/api/auth/[...nextauth]";
5 |
6 | /**
7 | * Wrapper for unstable_getServerSession https://next-auth.js.org/configuration/nextjs
8 | * See example usage in trpc createContext or the restricted API route
9 | */
10 | export const getServerAuthSession = async (ctx: {
11 | req: GetServerSidePropsContext["req"];
12 | res: GetServerSidePropsContext["res"];
13 | }) => {
14 | return await unstable_getServerSession(ctx.req, ctx.res, authOptions);
15 | };
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "noUncheckedIndexedAccess": true
18 | },
19 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.cjs", "**/*.mjs"],
20 | "exclude": ["node_modules"]
21 | }
22 |
--------------------------------------------------------------------------------
/src/pages/api/restricted.ts:
--------------------------------------------------------------------------------
1 | import { type NextApiRequest, type NextApiResponse } from "next";
2 |
3 | import { getServerAuthSession } from "../../server/common/get-server-auth-session";
4 |
5 | const restricted = async (req: NextApiRequest, res: NextApiResponse) => {
6 | const session = await getServerAuthSession({ req, res });
7 |
8 | if (session) {
9 | res.send({
10 | content:
11 | "This is protected content. You can access this content because you are signed in.",
12 | });
13 | } else {
14 | res.send({
15 | error:
16 | "You must be signed in to view the protected content on this page.",
17 | });
18 | }
19 | };
20 |
21 | export default restricted;
22 |
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2020.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2020,
3 | "problems": [
4 | {
5 | "slug": "APIO_20_01_walls",
6 | "name": "Walls",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/APIO20_paint",
9 | "solves": 76,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_20_02_cities",
14 | "name": "Cities",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/APIO20_swap",
17 | "solves": 73,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_20_03_fun",
22 | "name": "Fun",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/APIO20_fun",
25 | "solves": 19,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2021.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2021,
3 | "problems": [
4 | {
5 | "slug": "APIO_21_01_hexagon",
6 | "name": "Hexagon",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/APIO21_hexagon",
9 | "solves": 0,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_21_02_jumps",
14 | "name": "Jumps",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/APIO21_jumps",
17 | "solves": 50,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_21_03_roads",
22 | "name": "Roads",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/APIO21_roads",
25 | "solves": 35,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # database
12 | /prisma/db.sqlite
13 | /prisma/db.sqlite-journal
14 |
15 | # next.js
16 | /.next/
17 | /out/
18 | next-env.d.ts
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | .pnpm-debug.log*
32 |
33 | # local env files
34 | # do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
35 | .env
36 | .env*.local
37 |
38 | # vercel
39 | .vercel
40 |
41 | # typescript
42 | *.tsbuildinfo
43 |
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2022.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2022,
3 | "problems": [
4 | {
5 | "slug": "APIO_22_01_mars",
6 | "name": "Mars",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/APIO22_mars",
9 | "solves": 13,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_22_02_game",
14 | "name": "Game",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/APIO22_game",
17 | "solves": 3,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_22_03_permutation",
22 | "name": "Permutation",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/APIO22_perm",
25 | "solves": 71,
26 | "tags": []
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2019.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2019,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_19_01_Jumps",
6 | "name": "Jumps",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI19_jumps",
9 | "solves": 7,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_19_02_Remittance",
14 | "name": "Remittance",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI19_remittance",
17 | "solves": 86,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_19_03_Virus",
22 | "name": "Virus",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI19_virus",
25 | "solves": 2,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2016.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2016,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_16_01_Joiris",
6 | "name": "Joiris",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI16_joiris",
9 | "solves": 4,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_16_02_RNA",
14 | "name": "RNA",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI16_selling_rna",
17 | "solves": 55,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_16_03_Skyscraper",
22 | "name": "Skyscraper",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI16_skyscraper",
25 | "solves": 9,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2017.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2017,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_17_01_Park",
6 | "name": "Park",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI17_amusement_park",
9 | "solves": 34,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_17_02_Bulldozer",
14 | "name": "Bulldozer",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI17_bulldozer",
17 | "solves": 14,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_17_03_Golf",
22 | "name": "Golf",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI17_golf",
25 | "solves": 2,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2013.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2013,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_13_01_Disparity",
6 | "name": "Disparity",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI13_disparity",
9 | "solves": 0,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_13_02_Sync",
14 | "name": "Sync",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI13_synchronization",
17 | "solves": 1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_13_03_Watching",
22 | "name": "Watching",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI13_watching",
25 | "solves": 46,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2020.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2020,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_20_01_Furniture",
6 | "name": "Furniture",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI20_furniture",
9 | "solves": 76,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_20_02_Monochrome",
14 | "name": "Monochrome",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI20_monochrome",
17 | "solves": 47,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_20_03_Power",
22 | "name": "Power",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI20_power",
25 | "solves": 110,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2021.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2021,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_21_01_Crossing",
6 | "name": "Crossing",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI21_crossing",
9 | "solves": 88,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_21_02_Financial",
14 | "name": "Financial",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI21_financial",
17 | "solves": 82,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_21_03_Monster",
22 | "name": "Monster",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI21_monster",
25 | "solves": 13,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2022.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2022,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_22_01_Seesaw",
6 | "name": "Seesaw",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI22_seesaw",
9 | "solves": 33,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_22_02_Giraffes",
14 | "name": "Giraffes",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI22_giraffes",
17 | "solves": 5,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_22_03_SchoolRoad",
22 | "name": "SchoolRoad",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI22_schoolroad",
25 | "solves": 16,
26 | "tags": []
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2015.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2015,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_15_01_Tiles",
6 | "name": "Tiles",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI15_colored_tiles",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_15_02_Election",
14 | "name": "Election",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI15_election_campaign",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_15_03_Sterilizing",
22 | "name": "Sterilizing",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI15_sterilizing",
25 | "solves": -1,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/filter_tags.json:
--------------------------------------------------------------------------------
1 | {
2 | "topicWise": {
3 | "Greedy": 4,
4 | "Implementation": 7,
5 | "Fenwick Tree": 2,
6 | "Data Structures": 5,
7 | "Stack": 1,
8 | "Segment Tree": 7,
9 | "Ad-hoc": 7,
10 | "Constructive": 3,
11 | "Graph": 9,
12 | "Disjoint Set Union": 2,
13 | "Simulation": 1,
14 | "Dijkstra": 2,
15 | "Binary Search": 4,
16 | "Dynamic Programming": 6,
17 | "Observations": 1,
18 | "Game Theory": 1,
19 | "Topological Sort": 1,
20 | "Divide and Conquer": 4,
21 | "Interactive": 5,
22 | "Strongly Connected Components": 2,
23 | "Two Pointers": 1,
24 | "Minimum Spanning Tree": 1,
25 | "Math": 4,
26 | "Bitwise": 1,
27 | "SQRT Decomposition": 1,
28 | "Sorting": 1,
29 | "Geometry": 1,
30 | "Sweep Line": 1,
31 | "Centroid": 1,
32 | "Persistence": 1
33 | }
34 | }
--------------------------------------------------------------------------------
/src/data/problems/Balkan Olympiad in Informatics/2009.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2009,
3 | "problems": [
4 | {
5 | "slug": "Balkan_09_01_NewBeginning",
6 | "name": "New beginning",
7 | "editorial": "",
8 | "link": "https://www.acmicpc.net/problem/7080",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "Balkan_09_02_Reading",
14 | "name": "Reading",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/Balkan/Balkan-09-Reading.txt",
16 | "link": "https://www.acmicpc.net/problem/7081",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "Balkan_09_03_Strip",
22 | "name": "Strip",
23 | "editorial": "",
24 | "link": "https://www.acmicpc.net/problem/7082",
25 | "solves": -1,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import { type AppType } from "next/app";
2 | import { type Session } from "next-auth";
3 | import { SessionProvider } from "next-auth/react";
4 |
5 | import { ChakraProvider, extendTheme } from "@chakra-ui/react";
6 |
7 | import { trpc } from "../utils/trpc";
8 |
9 | import "../styles/globals.css";
10 | import { MultiSelectTheme } from "chakra-multiselect";
11 |
12 | const theme = extendTheme({
13 | components: {
14 | MultiSelect: MultiSelectTheme,
15 | },
16 | });
17 |
18 | const MyApp: AppType<{ session: Session | null }> = ({
19 | Component,
20 | pageProps: { session, ...pageProps },
21 | }) => {
22 | return (
23 |
24 |
25 |
26 |
27 |
28 | );
29 | };
30 |
31 | export default trpc.withTRPC(MyApp);
32 |
--------------------------------------------------------------------------------
/src/data/combine.py:
--------------------------------------------------------------------------------
1 | import json, os
2 |
3 | data = {}
4 | data["sections"] = []
5 |
6 | tmpData = {}
7 | for section in os.listdir("problems"):
8 | if section == "order.txt":
9 | continue
10 | section_object = {}
11 | section_object["sectionName"] = section
12 | section_object["years"] = []
13 | for year in os.listdir("problems/" + section + "/"):
14 | f = open("problems/" + section + "/" + year)
15 | year_data = json.load(f)
16 | section_object["years"].append(year_data)
17 | section_object["years"].sort(key=lambda x: -x["year"])
18 | tmpData[section] = section_object
19 |
20 |
21 | with open("problems/order.txt") as f:
22 | contents = f.readlines()
23 | for section in contents:
24 | data["sections"].append(tmpData[section.strip()])
25 |
26 | json_object = json.dumps(data, indent=2)
27 | with open("problem_data.json", "w") as outfile:
28 | outfile.write(json_object)
29 |
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2011.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2011,
3 | "problems": [
4 | {
5 | "slug": "APIO_11_01_Color",
6 | "name": "Color",
7 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-11-Color.txt",
8 | "link": "https://dmoj.ca/problem/apio11p1",
9 | "solves": 1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_11_02_Path",
14 | "name": "Path",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-11-Path.txt",
16 | "link": "https://dmoj.ca/problem/apio11p2",
17 | "solves": 8,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_11_03_guessword",
22 | "name": "Guessword",
23 | "editorial": "",
24 | "link": "https://dmoj.ca/problem/apio11p3",
25 | "solves": 0,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2012.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2012,
3 | "problems": [
4 | {
5 | "slug": "APIO_12_01_Dispatching",
6 | "name": "Dispatching",
7 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-12-Dispatching.txt",
8 | "link": "https://dmoj.ca/problem/apio12p1",
9 | "solves": 22,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_12_02_Guard",
14 | "name": "Guard",
15 | "editorial": "",
16 | "link": "https://dmoj.ca/problem/apio12p2",
17 | "solves": 12,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_12_03_Kunai",
22 | "name": "Kunai",
23 | "editorial": "https://github.com/tmwilliamlin168/CompetitiveProgramming/blob/master/APIO/12-Kunai.cpp",
24 | "link": "https://dmoj.ca/problem/apio12p3",
25 | "solves": 0,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/env/server.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | /**
3 | * This file is included in `/next.config.mjs` which ensures the app isn't built with invalid env vars.
4 | * It has to be a `.mjs`-file to be imported there.
5 | */
6 | import { serverSchema } from "./schema.mjs";
7 | import { env as clientEnv, formatErrors } from "./client.mjs";
8 |
9 | const _serverEnv = serverSchema.safeParse(process.env);
10 |
11 | if (!_serverEnv.success) {
12 | console.error(
13 | "❌ Invalid environment variables:\n",
14 | ...formatErrors(_serverEnv.error.format()),
15 | );
16 | throw new Error("Invalid environment variables");
17 | }
18 |
19 | for (let key of Object.keys(_serverEnv.data)) {
20 | if (key.startsWith("NEXT_PUBLIC_")) {
21 | console.warn("❌ You are exposing a server-side env-variable:", key);
22 |
23 | throw new Error("You are exposing a server-side env-variable");
24 | }
25 | }
26 |
27 | export const env = { ..._serverEnv.data, ...clientEnv };
28 |
--------------------------------------------------------------------------------
/src/data/problems/National Olympiad in Informatics (Singapore)/2013.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2013,
3 | "problems": [
4 | {
5 | "slug": "NOI_13_01_gw",
6 | "name": "Global Warming",
7 | "editorial": "https://github.com/sjhuang26/competitive-programming/blob/master/noi/NOI%252013-gw.cpp",
8 | "link": "https://oj.uz/problem/view/NOI13_gw",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "NOI_13_02_diesel",
14 | "name": "Diesel",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/NOI/official",
16 | "link": "https://dunjudge.me/analysis/problems/281/",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "NOI_13_03_ferries",
22 | "name": "Ferries",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/NOI13_ferries",
25 | "solves": -1,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2013.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2013,
3 | "problems": [
4 | {
5 | "slug": "APIO_13_01_Robots",
6 | "name": "Robots",
7 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-13-Robots.txt",
8 | "link": "https://oj.uz/problem/view/APIO13_robots",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_13_02_Toll",
14 | "name": "Toll",
15 | "editorial": "https://github.com/tmwilliamlin168/CompetitiveProgramming/blob/master/APIO/13-Toll.cpp",
16 | "link": "https://oj.uz/problem/view/APIO13_toll",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_13_03_tasksauthor",
22 | "name": "Tasksauthor",
23 | "editorial": "",
24 | "link": "https://dunjudge.me/analysis/problems/437/",
25 | "solves": -1,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Croatian Olympiad in Informatics/2018.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2018,
3 | "problems": [
4 | {
5 | "slug": "COI_18_01_paprike",
6 | "name": "Paprike",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/COI18_paprike",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "COI_18_02_pick",
14 | "name": "Pick",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/COI18_pick",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "COI_18_03_svjetlost",
22 | "name": "Svjetlost",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/COI18_svjetlost",
25 | "solves": -1,
26 | "tags": []
27 | },
28 | {
29 | "slug": "COI_18_04_zagonetka",
30 | "name": "Zagonetka",
31 | "editorial": "",
32 | "link": "https://oj.uz/problem/view/COI18_zagonetka",
33 | "solves": -1,
34 | "tags": []
35 | }
36 | ]
37 | }
--------------------------------------------------------------------------------
/src/data/problems/InfO(1) Cup/2019.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2019,
3 | "problems": [
4 | {
5 | "slug": "InfOCup_19_01_CONSUL",
6 | "name": "CONSUL",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/info1cup19_consul",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "InfOCup_19_02_Costinland",
14 | "name": "Costinland",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/info1cup19_costinland",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "InfOCup_19_03_Cat",
22 | "name": "Cat",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/info1cup19_cat",
25 | "solves": -1,
26 | "tags": []
27 | },
28 | {
29 | "slug": "InfOCup_19_04_Mouse",
30 | "name": "Mouse",
31 | "editorial": "",
32 | "link": "https://oj.uz/problem/view/info1cup19_mouse",
33 | "solves": -1,
34 | "tags": []
35 | }
36 | ]
37 | }
--------------------------------------------------------------------------------
/src/pages/api/auth/[...nextauth].ts:
--------------------------------------------------------------------------------
1 | import NextAuth, { type NextAuthOptions } from "next-auth";
2 | import GithubProvider from "next-auth/providers/github";
3 | // Prisma adapter for NextAuth, optional and can be removed
4 | import { PrismaAdapter } from "@next-auth/prisma-adapter";
5 |
6 | import { env } from "../../../env/server.mjs";
7 | import { prisma } from "../../../server/db/client";
8 |
9 | export const authOptions: NextAuthOptions = {
10 | // Include user.id on session
11 | callbacks: {
12 | session({ session, user }) {
13 | if (session.user) {
14 | session.user.id = user.id;
15 | }
16 | return session;
17 | },
18 | },
19 | // Configure one or more authentication providers
20 | adapter: PrismaAdapter(prisma),
21 | providers: [
22 | GithubProvider({
23 | clientId: env.GITHUB_CLIENT_ID,
24 | clientSecret: env.GITHUB_CLIENT_SECRET
25 | })
26 | // ...add more providers here
27 | ],
28 | };
29 |
30 | export default NextAuth(authOptions);
31 |
--------------------------------------------------------------------------------
/src/server/trpc/trpc.ts:
--------------------------------------------------------------------------------
1 | import { initTRPC, TRPCError } from "@trpc/server";
2 | import superjson from "superjson";
3 |
4 | import { type Context } from "./context";
5 |
6 | const t = initTRPC.context().create({
7 | transformer: superjson,
8 | errorFormatter({ shape }) {
9 | return shape;
10 | },
11 | });
12 |
13 | export const router = t.router;
14 |
15 | /**
16 | * Unprotected procedure
17 | **/
18 | export const publicProcedure = t.procedure;
19 |
20 | /**
21 | * Reusable middleware to ensure
22 | * users are logged in
23 | */
24 | const isAuthed = t.middleware(({ ctx, next }) => {
25 | if (!ctx.session || !ctx.session.user) {
26 | throw new TRPCError({ code: "UNAUTHORIZED" });
27 | }
28 | return next({
29 | ctx: {
30 | // infers the `session` as non-nullable
31 | session: { ...ctx.session, user: ctx.session.user },
32 | },
33 | });
34 | });
35 |
36 | /**
37 | * Protected procedure
38 | **/
39 | export const protectedProcedure = t.procedure.use(isAuthed);
40 |
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2007.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2007,
3 | "problems": [
4 | {
5 | "slug": "APIO_07_01_MOBILE2",
6 | "name": "Mobile2",
7 | "editorial": "https://github.com/cacophonix/SPOJ/blob/master/MOBILE2.cpp",
8 | "link": "https://tlx.toki.id/problems/apio-2007/A",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_07_02_Backup",
14 | "name": "Backup",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-07-Backup.txt",
16 | "link": "https://tlx.toki.id/problems/apio-2007/B",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_07_03_Zoo",
22 | "name": "Zoo",
23 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-07-Zoo.txt",
24 | "link": "https://tlx.toki.id/problems/apio-2007/C",
25 | "solves": -1,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2009.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2009,
3 | "problems": [
4 | {
5 | "slug": "APIO_09_01_Oil",
6 | "name": "Oil",
7 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-09-Oil.txt",
8 | "link": "https://dmoj.ca/problem/apio09p1",
9 | "solves": 15,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_09_02_Convention",
14 | "name": "Convention",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-09-Convention.txt",
16 | "link": "https://dmoj.ca/problem/apio09p2",
17 | "solves": 5,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_09_03_ATM",
22 | "name": "Atm",
23 | "editorial": "https://github.com/goar5670/CompetitiveProgramming/blob/master/APIO%252009-ATM.cpp",
24 | "link": "https://dmoj.ca/problem/apio09p3",
25 | "solves": 20,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Croatian Olympiad in Informatics/2021.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2021,
3 | "problems": [
4 | {
5 | "slug": "COI_21_01_autobahn",
6 | "name": "Autobahn",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/COI21_autobahn",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "COI_21_02_cigle",
14 | "name": "Cigle",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/COI21_cigle",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "COI_21_03_izvanzemaljci",
22 | "name": "Izvanzemaljci",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/COI21_izvanzemaljci",
25 | "solves": -1,
26 | "tags": []
27 | },
28 | {
29 | "slug": "COI_21_04_malnarisc",
30 | "name": "MalnaRISC",
31 | "editorial": "",
32 | "link": "https://oj.uz/problem/view/COI21_malnarisc",
33 | "solves": -1,
34 | "tags": []
35 | }
36 | ]
37 | }
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2010.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2010,
3 | "problems": [
4 | {
5 | "slug": "APIO_10_01_Commando",
6 | "name": "Commando",
7 | "editorial": "https://github.com/timpostuvan/CompetitiveProgramming/blob/master/Olympiad/APIO/Commando2010.cpp",
8 | "link": "https://dmoj.ca/problem/apio10p1",
9 | "solves": 9,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_10_02_Patrol",
14 | "name": "Patrol",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-10-Patrol.txt",
16 | "link": "https://dmoj.ca/problem/apio10p2",
17 | "solves": 13,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_10_03_Signaling",
22 | "name": "Signaling",
23 | "editorial": "https://github.com/shanto86/Training/blob/master/Dmoj/APIO%252010-Signaling.cpp",
24 | "link": "https://dmoj.ca/problem/apio10p3",
25 | "solves": 1,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/Japanese Olympiad in Informatics: Open Contest/2018.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2018,
3 | "problems": [
4 | {
5 | "slug": "JOIOC_18_01_Bubble2",
6 | "name": "Bubble 2",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/JOI18_bubblesort2",
9 | "solves": 18,
10 | "tags": []
11 | },
12 | {
13 | "slug": "JOIOC_18_02_Catdog",
14 | "name": "Catdog",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/JOI18_catdog",
17 | "solves": 4,
18 | "tags": []
19 | },
20 | {
21 | "slug": "JOIOC_18_03_Collapse",
22 | "name": "Collapse",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/JOI18_collapse",
25 | "solves": 5,
26 | "tags": []
27 | },
28 | {
29 | "slug": "JOIOC_18_04_Xylophone",
30 | "name": "Xylophone",
31 | "editorial": "",
32 | "link": "https://oj.uz/problem/view/JOI18_xylophone",
33 | "solves": 84,
34 | "tags": []
35 | }
36 | ]
37 | }
--------------------------------------------------------------------------------
/src/data/problems/InfO(1) Cup/2018.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2018,
3 | "problems": [
4 | {
5 | "slug": "InfOCup_18_01_Maxcomp",
6 | "name": "Maxcomp",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/info1cup18_maxcomp",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "InfOCup_18_02_DEL13",
14 | "name": "DEL13",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/info1cup18_del13",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "InfOCup_18_03_HiddenSequence",
22 | "name": "Hidden Sequence",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/info1cup18_hidden",
25 | "solves": -1,
26 | "tags": []
27 | },
28 | {
29 | "slug": "InfOCup_18_04_BalancedTree",
30 | "name": "Balanced Tree",
31 | "editorial": "",
32 | "link": "https://oj.uz/problem/view/info1cup18_balancedtree",
33 | "solves": -1,
34 | "tags": []
35 | }
36 | ]
37 | }
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2008.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2008,
3 | "problems": [
4 | {
5 | "slug": "APIO_08_01_Beads",
6 | "name": "Beads",
7 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-08-Beads.txt",
8 | "link": "https://tlx.toki.id/problems/apio-2008/A",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_08_02_Roads",
14 | "name": "Roads",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-08-Roads.txt",
16 | "link": "https://tlx.toki.id/problems/apio-2008/B",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_08_03_DNA",
22 | "name": "Dna",
23 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-08-DNA.txt",
24 | "link": "https://tlx.toki.id/problems/apio-2008/C",
25 | "solves": -1,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/data/problems/InfO(1) Cup/2020.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2020,
3 | "problems": [
4 | {
5 | "slug": "InfOCup_20_01_TableTennis",
6 | "name": "Table Tennis",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/info1cup20_tabletennis",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "InfOCup_20_02_Trampoline",
14 | "name": "Trampoline",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/info1cup20_trampoline",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "InfOCup_20_03_Football",
22 | "name": "Football",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/info1cup20_football",
25 | "solves": -1,
26 | "tags": []
27 | },
28 | {
29 | "slug": "InfOCup_20_04_Cheerleaders",
30 | "name": "Cheerleaders",
31 | "editorial": "",
32 | "link": "https://oj.uz/problem/view/info1cup20_cheerleaders",
33 | "solves": -1,
34 | "tags": []
35 | }
36 | ]
37 | }
--------------------------------------------------------------------------------
/src/data/problems/Croatian Olympiad in Informatics/2022.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2022,
3 | "problems": [
4 | {
5 | "slug": "COI_22_01_mađioničar",
6 | "name": "Mađioničar",
7 | "editorial": "",
8 | "link": "https://evaluator.hsin.hr/tasks/SS202241madionicar/",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "COI_22_02_mensza",
14 | "name": "Mensza",
15 | "editorial": "",
16 | "link": "https://evaluator.hsin.hr/tasks/SS202242mensza/",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "COI_22_03_povjerenstvo",
22 | "name": "Povjerenstvo",
23 | "editorial": "",
24 | "link": "https://evaluator.hsin.hr/tasks/SS202243povjerenstvo/",
25 | "solves": -1,
26 | "tags": []
27 | },
28 | {
29 | "slug": "COI_22_04_vinjete",
30 | "name": "Vinjete",
31 | "editorial": "",
32 | "link": "https://evaluator.hsin.hr/tasks/SS202244vinjete/",
33 | "solves": -1,
34 | "tags": []
35 | }
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/src/data/problems/InfO(1) Cup/2017.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2017,
3 | "problems": [
4 | {
5 | "slug": "InfOCup_17_01_EasterEggs",
6 | "name": "Easter Eggs",
7 | "editorial": "",
8 | "link": "https://oj.uz/problem/view/info1cup17_eastereggs",
9 | "solves": -1,
10 | "tags": []
11 | },
12 | {
13 | "slug": "InfOCup_17_02_XORSum",
14 | "name": "XOR Sum",
15 | "editorial": "",
16 | "link": "https://oj.uz/problem/view/info1cup17_xorsum",
17 | "solves": -1,
18 | "tags": []
19 | },
20 | {
21 | "slug": "InfOCup_17_03_BinarySubsequences",
22 | "name": "Binary Subsequences",
23 | "editorial": "",
24 | "link": "https://oj.uz/problem/view/info1cup17_binary",
25 | "solves": -1,
26 | "tags": []
27 | },
28 | {
29 | "slug": "InfOCup_17_04_PermutationRecovery",
30 | "name": "Permutation Recovery",
31 | "editorial": "",
32 | "link": "https://oj.uz/problem/view/info1cup17_permutation",
33 | "solves": -1,
34 | "tags": []
35 | }
36 | ]
37 | }
--------------------------------------------------------------------------------
/src/data/problems/Asia Pacific Informatics Olympiad/2014.json:
--------------------------------------------------------------------------------
1 | {
2 | "year": 2014,
3 | "problems": [
4 | {
5 | "slug": "APIO_14_01_Palindrome",
6 | "name": "Palindrome",
7 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-14-Palindrome.txt",
8 | "link": "https://oj.uz/problem/view/APIO14_palindrome",
9 | "solves": 10,
10 | "tags": []
11 | },
12 | {
13 | "slug": "APIO_14_02_Sequence",
14 | "name": "Sequence",
15 | "editorial": "https://github.com/mostafa-saad/MyCompetitiveProgramming/blob/master/Olympiad/APIO/APIO-14-Sequence.txt",
16 | "link": "https://oj.uz/problem/view/APIO14_sequence",
17 | "solves": 33,
18 | "tags": []
19 | },
20 | {
21 | "slug": "APIO_14_03_Beads",
22 | "name": "Beads",
23 | "editorial": "https://github.com/tmwilliamlin168/CompetitiveProgramming/blob/master/APIO/14-Beads.cpp",
24 | "link": "https://oj.uz/problem/view/APIO14_beads",
25 | "solves": 25,
26 | "tags": []
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/src/env/client.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { clientEnv, clientSchema } from "./schema.mjs";
3 |
4 | const _clientEnv = clientSchema.safeParse(clientEnv);
5 |
6 | export const formatErrors = (
7 | /** @type {import('zod').ZodFormattedError