diff --git a/.env.local.example b/.env.local.example new file mode 100644 index 0000000..6937031 --- /dev/null +++ b/.env.local.example @@ -0,0 +1,4 @@ +# Update these with your Supabase details from your project settings > API +# https://app.supabase.com/project/_/settings/api +NEXT_PUBLIC_SUPABASE_URL=your-project-url +NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8f322f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/README.md b/README.md new file mode 100644 index 0000000..b98ea8b --- /dev/null +++ b/README.md @@ -0,0 +1,1530 @@ +pgvector to Prod in 2 hours +

Workshop: pgvector to Prod in 2 hours

+ +

+Create a production-ready MVP for securely chatting with your documents. +

+ +## ☑️ Features + +- **Interactive Chat Interface:** Interact with your documentation, leveraging the capabilities of OpenAI’s GPT models and retrieval augmented generation (RAG). +- **Login With <3rd Party>:** Integrate one-click 3rd party login with any of our 18 auth providers and user/password. +- **Document Storage:** Securely upload, store, and retrieve user uploaded documents. +- **REST API:** Expose a flexible REST API that we’ll consume to build the interactive front-end. +- **Row-level Security:** Secure all of your user data user data with production-ready row-level security. + +## 📄 Workshop Instructions + +Thanks for joining! Let's dive in. + +![Workshop instructions](./assets/instructions.png) + +1. **Clone repo:** Clone this repo at tag `step-1`: + + ```shell + git clone -b step-1 https://github.com/supabase-community/chatgpt-your-files.git + ``` + + This will automatically clone at [step 1](#step-1---storage), our starting point. + +1. **Git checkpoints:** The workshop is broken down into steps (git tags). There's a step for every major feature we are building. + + Feel free to follow along live with the presenter. When it's time to jump to the next step, run: + + ```shell + git stash push -u # stash your working directory + git checkout step-X # jump to a checkpoint (replace X wit step #) + ``` + +1. **Step-by-step guide:** These steps are written out line-by-line. Feel free to follow along using the [steps below](#step-by-step). + +### 🚶 Need to step out? + +If you can't make the full workshop, no worries! We'll be putting out a YouTube video later that goes over the same content. + +If you'd like to get notified when the video is available, feel free to drop your name and email on [this form](https://airtable.com/appGOhbhNzJCGQoo6/shrHkzwU256fIBDIC) and we'll send you the link! + +## 🧱 Pre-req’s + +- Unix-based OS (if Windows, WSL2) +- Docker +- Node.js 18+ + +## 💿 Sample Data + +This repository includes 3 sample markdown files that we'll use to test the app: + +[`./sample-files/roman-empire-1.md`](./sample-files/roman-empire-1.md) + +[`./sample-files/roman-empire-2.md`](./sample-files/roman-empire-2.md) + +[`./sample-files/roman-empire-3.md`](./sample-files/roman-empire-3.md) + +## 🪜 Step-by-step + +Jump to a step: + +1. [Storage](#step-1---storage) +2. [Documents](#step-2---documents) +3. [Embeddings](#step-3---embeddings) +4. [Chat](#step-4---chat) +5. [Database Types](#step-5---database-types-bonus) (Bonus) +6. [You're done!](#youre-done) + +--- + +
+ +Step 0 - Setup (Optional) + +### `Step 0` - Setup + +_Use this command to jump to the `step-0` checkpoint._ + +```shell +git checkout step-0 +``` + +The beginning of step 0 is aka to: + +```shell +npx create-next-app -e with-supabase +``` + +Refer to this step if you want to learn about the additions added on top of `create-next-app` to get us up and running quicker for this workshop _(VS Code settings, UI components/styles/layouts)_. Otherwise, skip straight to [`step-1`](#step-1---storage). + +1. Install Supabase as dev dependency. + + ```bash + npm i -D supabase@1.102.0 + ``` + +1. (Optional) Setup VSCode environment. + + ```bash + mkdir -p .vscode && cat > .vscode/settings.json <<- EOF + { + "deno.enable": true, + "deno.lint": true, + "deno.unstable": false, + "deno.enablePaths": [ + "supabase" + ], + "deno.importMap": "./supabase/functions/import_map.json" + } + EOF + ``` + +1. (Optional) Setup VSCode recommended extensions. + + ```bash + cat > .vscode/extensions.json <<- EOF + { + "recommendations": [ + "denoland.vscode-deno", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "bradlc.vscode-tailwindcss", + ], + } + EOF + ``` + + Then `cmd`+`shift`+`p` → `>show recommended extensions` → install all _(or whichever you like)_ + +1. Create `import_map.json` with dependencies for our Supabase Edge Functions. We'll talk more about this in [step 2](#step-2---documents). + + ```bash + cat > supabase/functions/import_map.json <<- EOF + { + "imports": { + "@std/": "https://deno.land/std@0.168.0/", + + "@xenova/transformers": "https://cdn.jsdelivr.net/npm/@xenova/transformers@2.6.1", + "@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2.21.0", + "openai": "https://esm.sh/openai@4.10.0", + "common-tags": "https://esm.sh/common-tags@1.8.2", + "ai": "https://esm.sh/ai@2.2.13", + + "mdast-util-from-markdown": "https://esm.sh/mdast-util-from-markdown@2.0.0", + "mdast-util-to-markdown": "https://esm.sh/mdast-util-to-markdown@2.1.0", + "mdast-util-to-string": "https://esm.sh/mdast-util-to-string@4.0.0", + "unist-builder": "https://esm.sh/unist-builder@4.0.0", + "mdast": "https://esm.sh/v132/@types/mdast@4.0.0/index.d.ts", + + "https://esm.sh/v132/decode-named-character-reference@1.0.2/esnext/decode-named-character-reference.mjs": "https://esm.sh/decode-named-character-reference@1.0.2?target=deno" + } + } + EOF + ``` + +#### Scaffold Frontend + +We use [`shadcn/ui`](https://ui.shadcn.com/docs) for our UI components. + +1. Initialize `shadcn-ui`. + + ```bash + npx shadcn-ui@latest init + ``` + + ```bash + Would you like to use TypeScript (recommended)? yes + Which style would you like to use? › Default + Which color would you like to use as base color? › Slate + Where is your global CSS file? › › app/globals.css + Do you want to use CSS variables for colors? › yes + Where is your tailwind.config.js located? › tailwind.config.js + Configure the import alias for components: › @/components + Configure the import alias for utils: › @/lib/utils + Are you using React Server Components? › yes + ``` + +1. Add components. + + ```bash + npx shadcn-ui@latest add button input toast + ``` + +1. Install dependencies. + + ```bash + npm i @tanstack/react-query three-dots + ``` + +1. Wrap the app in a ``. +1. Build layouts. + +
+ +--- + +### `Step 1` - Storage + +_Use this command to jump to the `step-1` checkpoint._ + +```shell +git checkout step-1 +``` + +We'll start by handling file uploads. Supabase has a built-in object storage (backed by S3 under the hood) that integrates directly with your Postgres database. + +#### Install dependencies + +First install NPM dependencies. + +```bash +npm i +``` + +#### Start local Supabase stack + +1. Next initialize and start a local version of Supabase _(runs in Docker)_. + + ```bash + npx supabase init + npx supabase start + ``` + +1. Store Supabase URL & public anon key in `.env.local` for Next.js. + + ```bash + npx supabase status -o env \ + --override-name api.url=NEXT_PUBLIC_SUPABASE_URL \ + --override-name auth.anon_key=NEXT_PUBLIC_SUPABASE_ANON_KEY | + grep NEXT_PUBLIC > .env.local + ``` + +#### Build a SQL migration + +1. Create migration file. + + ```bash + npx supabase migration new files + ``` + + A new file will be created under `./supabase/migrations`. + +1. Within that file, create a private schema. + + ```sql + create schema private; + ``` + +1. Add bucket called 'files' via the `buckets` table in the `storage` schema. + + ```sql + insert into storage.buckets (id, name) + values ('files', 'files'); + ``` + +1. Add RLS policies to restrict access to files. + + ```sql + create policy "Authenticated users can upload files" + on storage.objects for insert to authenticated with check ( + bucket_id = 'files' and owner = auth.uid() + ); + + create policy "Users can view their own files" + on storage.objects for select to authenticated using ( + bucket_id = 'files' and owner = auth.uid() + ); + + create policy "Users can update their own files" + on storage.objects for update to authenticated with check ( + bucket_id = 'files' and owner = auth.uid() + ); + + create policy "Users can delete their own files" + on storage.objects for delete to authenticated using ( + bucket_id = 'files' and owner = auth.uid() + ); + ``` + +#### Modify frontend + +Next let's update `./app/files/page.tsx` to support file upload. + +1. Setup Supabase client at the top of the component. + + ```tsx + const supabase = createClientComponentClient(); + ``` + +1. Handle file upload in the ``'s `onChange` prop. + + ```tsx + await supabase.storage + .from('files') + .upload(`${crypto.randomUUID()}/${selectedFile.name}`, selectedFile); + ``` + +#### Improve upload RLS policy + +We can improve our previous RLS policy to require a UUID in the uploaded file path. + +1. Create `uuid_or_null()` function. + + ```sql + create or replace function private.uuid_or_null(str text) + returns uuid + language plpgsql + as $$ + begin + return str::uuid; + exception when invalid_text_representation then + return null; + end; + $$; + ``` + +1. Modify insert policy to check for UUID in the first path segment _(Postgres arrays are 1-based)_. + + ```sql + create policy "Authenticated users can upload files" + on storage.objects for insert to authenticated with check ( + bucket_id = 'files' and + owner = auth.uid() and + private.uuid_or_null(path_tokens[1]) is not null + ); + ``` + +1. Apply the migration to our local database. + + ```bash + npx supabase migration up + ``` + +--- + +### `Step 2` - Documents + +Jump to a step: + +1. [Storage](#step-1---storage) +2. [Documents](#step-2---documents) +3. [Embeddings](#step-3---embeddings) +4. [Chat](#step-4---chat) +5. [Database Types](#step-5---database-types-bonus) (Bonus) +6. [You're done!](#youre-done) + +--- + +_Use these commands to jump to the `step-2` checkpoint._ + +```shell +git stash push -u -m "my work on step-1" +git checkout step-2 +``` + +Next we'll need to process our files for retrieval augmented generation (RAG). Specifically we'll split the contents of our markdown documents by heading, which will allow us to query smaller and more meaningful sections. + +Let's create a `documents` and `document_sections` table to store our processed files. + +![Documents ER diagram](./assets/step-2-er-diagram.png) + +#### Add a new SQL migration + +1. Create migration file. + + ```bash + npx supabase migration new documents + ``` + +1. Enable `pgvector` and `pg_net` extensions. + + We'll use `pg_net` later to send HTTP requests to our edge functions. + + ```sql + create extension if not exists pg_net with schema extensions; + create extension if not exists vector with schema extensions; + ``` + +1. Create `documents` table. + + ```sql + create table documents ( + id bigint primary key generated always as identity, + name text not null, + storage_object_id uuid not null references storage.objects (id), + created_by uuid not null references auth.users (id) default auth.uid(), + created_at timestamp with time zone not null default now() + ); + ``` + +1. We'll also create a view `documents_with_storage_path` that provides easy access to the storage object path. + + ```sql + create view documents_with_storage_path + with (security_invoker=true) + as + select documents.*, storage.objects.name as storage_object_path + from documents + join storage.objects + on storage.objects.id = documents.storage_object_id; + ``` + +1. Create `document_sections` table. + + ```sql + create table document_sections ( + id bigint primary key generated always as identity, + document_id bigint not null references documents (id), + content text not null, + embedding vector (384) + ); + ``` + +1. Add HNSW index. + + Unlike IVFFlat indexes, HNSW indexes can be create immediately on an empty table. + + ```sql + create index on document_sections using hnsw (embedding vector_ip_ops); + ``` + +1. Setup RLS to control who has access to which documents. + + ```sql + alter table documents enable row level security; + alter table document_sections enable row level security; + + create policy "Users can insert documents" + on documents for insert to authenticated with check ( + auth.uid() = created_by + ); + + create policy "Users can query their own documents" + on documents for select to authenticated using ( + auth.uid() = created_by + ); + + create policy "Users can insert document sections" + on document_sections for insert to authenticated with check ( + document_id in ( + select id + from documents + where created_by = auth.uid() + ) + ); + + create policy "Users can update their own document sections" + on document_sections for update to authenticated using ( + document_id in ( + select id + from documents + where created_by = auth.uid() + ) + ) with check ( + document_id in ( + select id + from documents + where created_by = auth.uid() + ) + ); + + create policy "Users can query their own document sections" + on document_sections for select to authenticated using ( + document_id in ( + select id + from documents + where created_by = auth.uid() + ) + ); + ``` + +1. Add `supabase_url` secret to `./supabase/seed.sql`. We will use this to query our Edge Functions within our local environment. In production, set this to your Supabase project's API URL. + + ```sql + select vault.create_secret( + 'http://api.supabase.internal:8000', + 'supabase_url' + ); + ``` + +1. Create a function to retrieve the URL. + + ```sql + create function supabase_url() + returns text + language plpgsql + security definer + as $$ + declare + secret_value text; + begin + select decrypted_secret into secret_value from vault.decrypted_secrets where name = 'supabase_url'; + return secret_value; + end; + $$; + ``` + +1. Create a trigger to process new documents when they're inserted. This uses `pg_net` to send an HTTP request to our Edge Function (coming up next). + + ```sql + create function private.handle_storage_update() + returns trigger + language plpgsql + as $$ + declare + document_id bigint; + result int; + begin + insert into documents (name, storage_object_id, created_by) + values (new.path_tokens[2], new.id, new.owner) + returning id into document_id; + + select + net.http_post( + url := supabase_url() || '/functions/v1/process', + headers := jsonb_build_object( + 'Content-Type', 'application/json', + 'Authorization', current_setting('request.headers')::json->>'authorization' + ), + body := jsonb_build_object( + 'document_id', document_id + ) + ) + into result; + + return null; + end; + $$; + + create trigger on_file_upload + after insert on storage.objects + for each row + execute procedure private.handle_storage_update(); + ``` + +1. Apply the migration to our local database. + + ```bash + npx supabase migration up + ``` + +#### Edge function for `process` + +1. Create the Edge Function file. + + ```bash + npx supabase functions new process + ``` + + This will create the file `./supabase/functions/process/index.ts`. + + Make sure you have the latest version of `deno` installed + + ```bash + brew install deno + ``` + +1. First let's note how dependencies are resolved using an import map - `./supabase/functions/import_map.json`. + + Import maps aren't required in Deno, but they can simplify imports and keep dependency versions consistent. All of our dependencies come from NPM, but since we're using Deno we fetch them from a CDN like https://esm.sh or https://cdn.jsdelivr.net. + + ```json + { + "imports": { + "@std/": "https://deno.land/std@0.168.0/", + + "@xenova/transformers": "https://cdn.jsdelivr.net/npm/@xenova/transformers@2.6.1", + "@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2.21.0", + "openai": "https://esm.sh/openai@4.10.0", + "common-tags": "https://esm.sh/common-tags@1.8.2", + "ai": "https://esm.sh/ai@2.2.13", + + "mdast-util-from-markdown": "https://esm.sh/mdast-util-from-markdown@2.0.0", + "mdast-util-to-markdown": "https://esm.sh/mdast-util-to-markdown@2.1.0", + "mdast-util-to-string": "https://esm.sh/mdast-util-to-string@4.0.0", + "unist-builder": "https://esm.sh/unist-builder@4.0.0", + "mdast": "https://esm.sh/v132/@types/mdast@4.0.0/index.d.ts", + + "https://esm.sh/v132/decode-named-character-reference@1.0.2/esnext/decode-named-character-reference.mjs": "https://esm.sh/decode-named-character-reference@1.0.2?target=deno" + } + } + ``` + + _Note: URL based imports and import maps aren't a Deno invention. These are a [web standard](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) that Deno follows as closely as possible._ + +1. In `process/index.ts`, first grab the Supabase environment variables. + + ```tsx + import { createClient } from '@supabase/supabase-js'; + import { processMarkdown } from '../_lib/markdown-parser.ts'; + + // These are automatically injected + const supabaseUrl = Deno.env.get('SUPABASE_URL'); + const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY'); + + Deno.serve(async (req) => { + if (!supabaseUrl || !supabaseAnonKey) { + return new Response( + JSON.stringify({ + error: 'Missing environment variables.', + }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + }); + ``` + + _Note: These environment variables are automatically injected into the edge runtime for you. Even so, we check for their existence as a TypeScript best practice (type narrowing)._ + +1. _(Optional)_ If you are using VS Code, you may get prompted to cache your imported dependencies. You can do this by hitting `cmd`+`shift`+`p` and type `>Deno: Cache Dependencies`. + +1. Create Supabase client and configure it to inherit the original user’s permissions via the authorization header. This way we can continue to take advantage of our RLS policies. + + ```tsx + const authorization = req.headers.get('Authorization'); + + if (!authorization) { + return new Response( + JSON.stringify({ error: `No authorization header passed` }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + + const supabase = createClient(supabaseUrl, supabaseAnonKey, { + global: { + headers: { + authorization, + }, + }, + auth: { + persistSession: false, + }, + }); + ``` + +1. Grab the `document_id` from the request body and query it. + + ```tsx + const { document_id } = await req.json(); + + const { data: document } = await supabase + .from('documents_with_storage_path') + .select() + .eq('id', document_id) + .single(); + + if (!document?.storage_object_path) { + return new Response( + JSON.stringify({ error: 'Failed to find uploaded document' }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + ``` + +1. Use the Supabase client to download the file by storage path. + + ```tsx + const { data: file } = await supabase.storage + .from('files') + .download(document.storage_object_path); + + if (!file) { + return new Response( + JSON.stringify({ error: 'Failed to download storage object' }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + + const fileContents = await file.text(); + ``` + +1. Process the markdown file and store the resulting subsections into the `document_sections` table. + + _Note: `processMarkdown()` is pre-built into this repository for convenience. Feel free to read through its code to learn how it splits the markdown content._ + + ```tsx + const processedMd = processMarkdown(fileContents); + + const { error } = await supabase.from('document_sections').insert( + processedMd.sections.map(({ content }) => ({ + document_id, + content, + })) + ); + + if (error) { + console.error(error); + return new Response( + JSON.stringify({ error: 'Failed to save document sections' }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + + console.log( + `Saved ${processedMd.sections.length} sections for file '${document.name}'` + ); + ``` + +1. Return a success response. + + ```tsx + return new Response(null, { + status: 204, + headers: { 'Content-Type': 'application/json' }, + }); + ``` + +1. In a new terminal we'll serve the edge functions locally. + + ```bash + npx supabase functions serve + ``` + + _Note: Local Edge Functions are automatically served as part of `npx supabase start`, but this command allows us to also monitor their logs._ + +#### Display documents on the frontend + +Let's update `./app/files/page.tsx` to list out the uploaded documents. + +1. At the top of the component, fetch documents using the `useQuery` hook: + + ```tsx + const { data: documents } = useQuery(['files'], async () => { + const { data, error } = await supabase + .from('documents_with_storage_path') + .select(); + + if (error) { + toast({ + variant: 'destructive', + description: 'Failed to fetch documents', + }); + throw error; + } + + return data; + }); + ``` + +1. In each document's `onClick` handler, download the respective file. + + ```tsx + const { data, error } = await supabase.storage + .from('files') + .createSignedUrl(document.storage_object_path, 60); + + if (error) { + toast({ + variant: 'destructive', + description: 'Failed to download file. Please try again.', + }); + return; + } + + window.location.href = data.signedUrl; + ``` + +--- + +### `Step 3` - Embeddings + +Jump to a step: + +1. [Storage](#step-1---storage) +2. [Documents](#step-2---documents) +3. [Embeddings](#step-3---embeddings) +4. [Chat](#step-4---chat) +5. [Database Types](#step-5---database-types-bonus) (Bonus) +6. [You're done!](#youre-done) + +--- + +_Use these commands to jump to the `step-3` checkpoint._ + +```shell +git stash push -u -m "my work on step-2" +git checkout step-3 +``` + +Now let's add logic to generate embeddings automatically anytime new rows are added to the `document_sections` table. + +#### Create SQL migration + +1. Create migration file + + ```bash + npx supabase migration new embed + ``` + +1. Create `embed()` trigger function. We'll use this general purpose trigger function to asynchronously generate embeddings on arbitrary tables using a new `embed` Edge Function (coming up). + + ```sql + create function private.embed() + returns trigger + language plpgsql + as $$ + declare + content_column text = TG_ARGV[0]; + embedding_column text = TG_ARGV[1]; + batch_size int = TG_ARGV[2]; + batch_count int = ceiling((select count(*) from inserted) / batch_size::float); + result int; + begin + + for i in 0 .. (batch_count-1) loop + select + net.http_post( + url := supabase_url() || '/functions/v1/embed', + headers := jsonb_build_object( + 'Content-Type', 'application/json', + 'Authorization', current_setting('request.headers')::json->>'authorization' + ), + body := jsonb_build_object( + 'ids', (select json_agg(ds.id) from (select id from inserted limit batch_size offset i*batch_size) ds), + 'table', TG_TABLE_NAME, + 'contentColumn', content_column, + 'embeddingColumn', embedding_column + ) + ) + into result; + end loop; + + return null; + end; + $$; + ``` + +1. Add embed trigger to `document_sections` table + + ```sql + create trigger embed_document_sections + after insert on document_sections + referencing new table as inserted + for each statement + execute procedure private.embed(content, embedding, 10); + ``` + + Note we pass 3 arguments to `embed()`: + + - The first specifies which column contains the text content to embed. + - The second specifies the destination column to save the embedding into. + - The third specifies the number of records to include in each edge function call. + +1. Apply the migration to our local database. + + ```bash + npx supabase migration up + ``` + +#### Create Edge Function for `embed` + +1. Create edge function file + + ```bash + npx supabase functions new embed + ``` + +1. In `embed/index.ts`, create an embedding pipeline using Transformers.js. + + ```tsx + import { createClient } from '@supabase/supabase-js'; + import { env, pipeline } from '@xenova/transformers'; + + // Configuration for Deno runtime + env.useBrowserCache = false; + env.allowLocalModels = false; + + const generateEmbedding = await pipeline( + 'feature-extraction', + 'Supabase/gte-small' + ); + ``` + +1. Just like before, grab the Supabase variables and check for their existence _(type narrowing)_. + + ```tsx + // These are automatically injected + const supabaseUrl = Deno.env.get('SUPABASE_URL'); + const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY'); + + Deno.serve(async (req) => { + if (!supabaseUrl || !supabaseAnonKey) { + return new Response( + JSON.stringify({ + error: 'Missing environment variables.', + }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + }); + ``` + +1. Create a Supabase client and configure to inherit the user’s permissions. + + ```tsx + const authorization = req.headers.get('Authorization'); + + if (!authorization) { + return new Response( + JSON.stringify({ error: `No authorization header passed` }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + + const supabase = createClient(supabaseUrl, supabaseAnonKey, { + global: { + headers: { + authorization, + }, + }, + auth: { + persistSession: false, + }, + }); + ``` + +1. Fetch the text content from the specified table/column. + + ```tsx + const { ids, table, contentColumn, embeddingColumn } = await req.json(); + + const { data: rows, error: selectError } = await supabase + .from(table) + .select(`id, ${contentColumn}` as '*') + .in('id', ids) + .is(embeddingColumn, null); + + if (selectError) { + return new Response(JSON.stringify({ error: selectError }), { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }); + } + ``` + +1. Generate an embedding for each piece of text and update the respective rows. + + ```tsx + for (const row of rows) { + const { id, [contentColumn]: content } = row; + + if (!content) { + console.error(`No content available in column '${contentColumn}'`); + continue; + } + + const output = await generateEmbedding(content, { + pooling: 'mean', + normalize: true, + }); + + const embedding = JSON.stringify(Array.from(output.data)); + + const { error } = await supabase + .from(table) + .update({ + [embeddingColumn]: embedding, + }) + .eq('id', id); + + if (error) { + console.error( + `Failed to save embedding on '${table}' table with id ${id}` + ); + } + + console.log( + `Generated embedding ${JSON.stringify({ + table, + id, + contentColumn, + embeddingColumn, + })}` + ); + } + ``` + +1. Return a success response. + + ```tsx + return new Response(null, { + status: 204, + headers: { 'Content-Type': 'application/json' }, + }); + ``` + +--- + +### `Step 4` - Chat + +Jump to a step: + +1. [Storage](#step-1---storage) +2. [Documents](#step-2---documents) +3. [Embeddings](#step-3---embeddings) +4. [Chat](#step-4---chat) +5. [Database Types](#step-5---database-types-bonus) (Bonus) +6. [You're done!](#youre-done) + +--- + +_Use these commands to jump to the `step-4` checkpoint._ + +```shell +git stash push -u -m "my work on step-3" +git checkout step-4 +``` + +Finally, let's implement the chat functionality. For this workshop, we're going to generate our query embedding client side using a new custom hook called `usePipeline()`. + +#### Update Frontend + +1. Install dependencies + + ```bash + npm i @xenova/transformers ai + ``` + +1. Configure `next.config.js` to support Transformers.js + + ```jsx + webpack: (config) => { + config.resolve.alias = { + ...config.resolve.alias, + sharp$: false, + 'onnxruntime-node$': false, + }; + return config; + }, + ``` + +1. Import dependencies + + ```tsx + import { usePipeline } from '@/lib/hooks/use-pipeline'; + import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; + import { useChat } from 'ai/react'; + ``` + + _Note: `usePipeline()` was pre-built into this repository for convenience. It uses Web Workers to asynchronously generate embeddings in another thread. We'll be releasing this hook and more into a dedicated NPM package shortly._ + +1. Create a Supabase client in `chat/page.tsx`. + + ```tsx + const supabase = createClientComponentClient(); + ``` + +1. Create embedding pipeline. + + ```tsx + const generateEmbedding = usePipeline( + 'feature-extraction', + 'Supabase/gte-small' + ); + ``` + + _Note: it's important that the embedding model you set here matches the model used in the Edge Function, otherwise your future matching logic will be meaningless._ + +1. Manage chat messages and state with `useChat()`. + + ```tsx + const { messages, input, handleInputChange, handleSubmit, isLoading } = + useChat({ + api: `${process.env.NEXT_PUBLIC_SUPABASE_URL}/functions/v1/chat`, + }); + ``` + + _Note: `useChat()` is a convenience hook provided by Vercel's `ai` package to handle chat message state and streaming. We'll point it to an Edge Function called `chat` (coming up)._ + +1. Set the ready status to `true` when pipeline has loaded. + + ```tsx + const isReady = !!generateEmbedding; + ``` + +1. Connect `input` and `handleInputChange` to our `` props. + + ```tsx + + ``` + +1. Generate an embedding and submit messages on form submit. + + ```tsx + if (!generateEmbedding) { + throw new Error('Unable to generate embeddings'); + } + + const output = await generateEmbedding(input, { + pooling: 'mean', + normalize: true, + }); + + const embedding = JSON.stringify(Array.from(output.data)); + + const { + data: { session }, + } = await supabase.auth.getSession(); + + if (!session) { + return; + } + + handleSubmit(e, { + options: { + headers: { + authorization: `Bearer ${session.access_token}`, + }, + body: { + embedding, + }, + }, + }); + ``` + +1. Disable send button until the component is ready. + + ```tsx + + ``` + +#### SQL Migration + +1. Create migration file for a new match function + + ```bash + npx supabase migration new match + ``` + +1. Create a `match_document_sections` Postgres function. + + ```sql + create or replace function match_document_sections( + embedding vector(384), + match_threshold float + ) + returns setof document_sections + language plpgsql + as $$ + #variable_conflict use_variable + begin + return query + select * + from document_sections + where document_sections.embedding <#> embedding < -match_threshold + order by document_sections.embedding <#> embedding; + end; + $$; + ``` + + This function uses pgvector's negative inner product operator `<#>` to perform similarity search. Inner product requires less computations than other distance functions like cosine distance `<=>`, and therefore provides better query performance. + + _Note: Our embeddings are normalized, so inner product and cosine similarity are equivalent in terms of output. Note though that pgvector's `<=>` operator is cosine distance, not cosine similarity, so `inner product == 1 - cosine distance`._ + + We also filter by a `match_threshold` in order to return only the most relevant results (1 = most similar, 0 = least similar). + + _Note: `match_threshold` is negated because `<#>` is a negative inner product. See the pgvector docs for more details on why `<#>` is negative._ + +1. Apply the migration to our local database. + + ```bash + npx supabase migration up + ``` + +#### Create `chat` Edge Function + +1. First generate an API key from [OpenAI](https://platform.openai.com/account/api-keys) and save it in `supabase/functions/.env`. + + ```bash + cat > supabase/functions/.env <<- EOF + OPENAI_API_KEY= + EOF + ``` + +1. Create the edge function file. + + ```bash + npx supabase functions new chat + ``` + +1. Load the OpenAI and Supabase keys. + + ```tsx + import { createClient } from '@supabase/supabase-js'; + import { OpenAIStream, StreamingTextResponse } from 'ai'; + import { codeBlock } from 'common-tags'; + import OpenAI from 'openai'; + + const openai = new OpenAI({ + apiKey: Deno.env.get('OPENAI_API_KEY'), + }); + + // These are automatically injected + const supabaseUrl = Deno.env.get('SUPABASE_URL'); + const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY'); + ``` + +1. Since our frontend is served at a different domain origin than our Edge Function, we must handle cross origin resource sharing (CORS). + + ```tsx + export const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': + 'authorization, x-client-info, apikey, content-type', + }; + + Deno.serve(async (req) => { + // Handle CORS + if (req.method === 'OPTIONS') { + return new Response('ok', { headers: corsHeaders }); + } + }); + ``` + + Handle CORS simply by checking for an `OPTIONS` HTTP request and returning the CORS headers (`*` = allow any domain). In production, consider limiting the origins to specific domains that serve your frontend. + +1. Check for environment variables and create Supabase client. + + ```tsx + if (!supabaseUrl || !supabaseAnonKey) { + return new Response( + JSON.stringify({ + error: 'Missing environment variables.', + }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + + const authorization = req.headers.get('Authorization'); + + if (!authorization) { + return new Response( + JSON.stringify({ error: `No authorization header passed` }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + + const supabase = createClient(supabaseUrl, supabaseAnonKey, { + global: { + headers: { + authorization, + }, + }, + auth: { + persistSession: false, + }, + }); + ``` + +1. The first step of RAG is to perform similarity search using our `match_document_sections()` function. Postgres functions are executed using the `.rpc()` method. + + ```tsx + const { chatId, message, messages, embedding } = await req.json(); + + const { data: documents, error: matchError } = await supabase + .rpc('match_document_sections', { + embedding, + match_threshold: 0.8, + }) + .select('content') + .limit(5); + + if (matchError) { + console.error(matchError); + + return new Response( + JSON.stringify({ + error: 'There was an error reading your documents, please try again.', + }), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + } + ); + } + ``` + +1. The second step of RAG is to build our prompt, injecting in the relevant documents retrieved from our previous similarity search. + + ```tsx + const injectedDocs = + documents && documents.length > 0 + ? documents.map(({ content }) => content).join('\n\n') + : 'No documents found'; + + const completionMessages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = + [ + { + role: 'user', + content: codeBlock` + You're an AI assistant who answers questions about documents. + + You're a chat bot, so keep your replies succinct. + + You're only allowed to use the documents below to answer the question. + + If the question isn't related to these documents, say: + "Sorry, I couldn't find any information on that." + + If the information isn't available in the below documents, say: + "Sorry, I couldn't find any information on that." + + Do not go off topic. + + Documents: + ${injectedDocs} + `, + }, + ...messages, + ]; + ``` + + _Note: the `codeBlock` template tag is a convenience function that will strip away indentations in our multiline string. This allows us to format our code nicely while preserving the intended indentation._ + +1. Finally, create a completion stream and return it. + + ```tsx + const completionStream = await openai.chat.completions.create({ + model: 'gpt-3.5-turbo-0613', + messages: completionMessages, + max_tokens: 1024, + temperature: 0, + stream: true, + }); + + const stream = OpenAIStream(completionStream); + return new StreamingTextResponse(stream, { headers: corsHeaders }); + ``` + + `OpenAIStream` and `StreamingTextResponse` are convenience helpers from Vercel's `ai` package that translate OpenAI's response stream into a format that `useChat()` understands on the frontend. + + _Note: we must also return CORS headers here (or anywhere else we send a response)._ + +#### Try it! + +Let's try it out! Here are some questions you could try asking: + +- What kind of buildings did they live in? +- What was the most common food? +- What did people do for fun? + +--- + +### `Step 5` - Database Types (Bonus) + +Jump to a step: + +1. [Storage](#step-1---storage) +2. [Documents](#step-2---documents) +3. [Embeddings](#step-3---embeddings) +4. [Chat](#step-4---chat) +5. [Database Types](#step-5---database-types-bonus) (Bonus) +6. [You're done!](#youre-done) + +--- + +_Use these commands to jump to the `step-5` checkpoint._ + +```shell +git stash push -u -m "my work on step-4" +git checkout step-5 +``` + +You may have noticed that all of our DB data coming back from the `supabase` client has had an `any` type (such as `documents` or `document_sections`). This isn't great, since we're missing relevant type information and lose type safety _(making our app more error-prone)_. + +The Supabase CLI comes with a built-in command to generate TypeScript types based on your database's schema. + +1. Generate TypeScript types based on local DB schema. + + ```bash + supabase gen types typescript --local > supabase/functions/_lib/database.ts + ``` + +1. Add the `` generic to all Supabase clients across our project. + + 1. In React + + ```tsx + import { Database } from '@/supabase/functions/_lib/database'; + + const supabase = createClientComponentClient(); + ``` + + ```tsx + import { Database } from '@/supabase/functions/_lib/database'; + + const supabase = createServerComponentClient(); + ``` + + 1. In Edge Functions + + ```tsx + import { Database } from '../_lib/database.ts'; + + const supabase = createClient(...); + ``` + +1. Fix type errors 😃 + + 1. Looks like we found a type error in `./app/files/page.tsx`! Let's add this check to top of the document's click handler _(type narrowing)_. + + ```tsx + if (!document.storage_object_path) { + toast({ + variant: 'destructive', + description: 'Failed to download file, please try again.', + }); + return; + } + ``` + +### You're done! + +🎉 Congrats! You've built your own full stack pgvector app in 2 hours. + +If you would like to jump directly to the completed app, simply checkout the `main` branch: + +```shell +git checkout main +``` + +Jump to a previous step: + +1. [Storage](#step-1---storage) +2. [Documents](#step-2---documents) +3. [Embeddings](#step-3---embeddings) +4. [Chat](#step-4---chat) +5. [Database Types](#step-5---database-types-bonus) (Bonus) +6. [You're done!](#youre-done) + +## 🚀 Going to prod + +Up until now we've been developing the app locally. Use these instructions to deploy your app to a production Supabase project. + +1. Create a [new Supabase project](https://supabase.com/dashboard/new/_). + +1. Link the CLI with your Supabase project. + + ```bash + npx supabase link --project-ref= + ``` + + You can grab your project's reference ID in your [project’s settings](https://supabase.com/dashboard/project/_/settings/general). + +1. Push migrations to remote database. + + ```bash + npx supabase db push + ``` + +1. Set Edge Function secrets (OpenAI key). + + ```bash + npx supabase secrets set OPENAI_API_KEY= + ``` + +1. Deploy Edge Functions. + + ```bash + npx supabase functions deploy + ``` + +1. Deploy to Vercel _(or CDN of your choice - must support Next.js API routes for authentication)_. + + - Follow Vercel’s [deploy instructions](https://nextjs.org/learn/basics/deploying-nextjs-app/deploy). + - Be sure to set `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` for your Supabase project. + + You can find these in your [project’s API settings](https://supabase.com/dashboard/project/_/settings/api). + +## 📈 Next steps + +Feel free to extend this app in any way you like. Here are some ideas for next steps: + +- Record message history in the database (and generate embeddings on them for RAG memory) +- Support more file formats than just markdown +- Pull in documents from the Notion API +- Restrict chat to user-selected documents +- Perform RAG on images using CLIP embeddings + +## 💬 Feedback and issues + +Please file feedback and issues on the [on this repo's issue board](https://github.com/supabase-community/chatgpt-your-files/issues/new/choose). + +## 🔗 Supabase Vector resources + +- [Supabase AI & Vector](https://supabase.com/docs/guides/ai) +- [pgvector Columns](https://supabase.com/docs/guides/ai/vector-columns) +- [pgvector Indexes](https://supabase.com/docs/guides/ai/vector-indexes) +- [Generate Embeddings using Edge Functions](https://supabase.com/docs/guides/ai/quickstarts/generate-text-embeddings) +- [Going to Production](https://supabase.com/docs/guides/ai/going-to-prod) diff --git a/app/_examples/client-component/page.tsx b/app/_examples/client-component/page.tsx new file mode 100644 index 0000000..aab0068 --- /dev/null +++ b/app/_examples/client-component/page.tsx @@ -0,0 +1,29 @@ +'use client' + +// TODO: Duplicate or move this file outside the `_examples` folder to make it a route + +import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' +import { useEffect, useState } from 'react' + +export default function ClientComponent() { + const [todos, setTodos] = useState([]) + + // Create a Supabase client configured to use cookies + const supabase = createClientComponentClient() + + useEffect(() => { + const getTodos = async () => { + // This assumes you have a `todos` table in Supabase. Check out + // the `Create Table and seed with data` section of the README 👇 + // https://github.com/vercel/next.js/blob/canary/examples/with-supabase/README.md + const { data } = await supabase.from('todos').select() + if (data) { + setTodos(data) + } + } + + getTodos() + }, [supabase, setTodos]) + + return
{JSON.stringify(todos, null, 2)}
+} diff --git a/app/_examples/route-handler/route.ts b/app/_examples/route-handler/route.ts new file mode 100644 index 0000000..7e654a0 --- /dev/null +++ b/app/_examples/route-handler/route.ts @@ -0,0 +1,19 @@ +// TODO: Duplicate or move this file outside the `_examples` folder to make it a route + +import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' +import { cookies } from 'next/headers' +import { NextResponse } from 'next/server' + +export const dynamic = 'force-dynamic' + +export async function GET() { + // Create a Supabase client configured to use cookies + const supabase = createRouteHandlerClient({ cookies }) + + // This assumes you have a `todos` table in Supabase. Check out + // the `Create Table and seed with data` section of the README 👇 + // https://github.com/vercel/next.js/blob/canary/examples/with-supabase/README.md + const { data: todos } = await supabase.from('todos').select() + + return NextResponse.json(todos) +} diff --git a/app/_examples/server-action/page.tsx b/app/_examples/server-action/page.tsx new file mode 100644 index 0000000..de7443c --- /dev/null +++ b/app/_examples/server-action/page.tsx @@ -0,0 +1,31 @@ +// TODO: Duplicate or move this file outside the `_examples` folder to make it a route + +import { createServerActionClient } from '@supabase/auth-helpers-nextjs' +import { revalidatePath } from 'next/cache' +import { cookies } from 'next/headers' + +export const dynamic = 'force-dynamic' + +export default async function ServerAction() { + const addTodo = async (formData: FormData) => { + 'use server' + const title = formData.get('title') + + if (title) { + // Create a Supabase client configured to use cookies + const supabase = createServerActionClient({ cookies }) + + // This assumes you have a `todos` table in Supabase. Check out + // the `Create Table and seed with data` section of the README 👇 + // https://github.com/vercel/next.js/blob/canary/examples/with-supabase/README.md + await supabase.from('todos').insert({ title }) + revalidatePath('/server-action-example') + } + } + + return ( +
+ +
+ ) +} diff --git a/app/_examples/server-component/page.tsx b/app/_examples/server-component/page.tsx new file mode 100644 index 0000000..149c4de --- /dev/null +++ b/app/_examples/server-component/page.tsx @@ -0,0 +1,18 @@ +// TODO: Duplicate or move this file outside the `_examples` folder to make it a route + +import { createServerComponentClient } from '@supabase/auth-helpers-nextjs' +import { cookies } from 'next/headers' + +export const dynamic = 'force-dynamic' + +export default async function ServerComponent() { + // Create a Supabase client configured to use cookies + const supabase = createServerComponentClient({ cookies }) + + // This assumes you have a `todos` table in Supabase. Check out + // the `Create Table and seed with data` section of the README 👇 + // https://github.com/vercel/next.js/blob/canary/examples/with-supabase/README.md + const { data: todos } = await supabase.from('todos').select() + + return
{JSON.stringify(todos, null, 2)}
+} diff --git a/app/auth/callback/route.ts b/app/auth/callback/route.ts new file mode 100644 index 0000000..6730992 --- /dev/null +++ b/app/auth/callback/route.ts @@ -0,0 +1,21 @@ +import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' +import { cookies } from 'next/headers' +import { NextResponse } from 'next/server' + +export const dynamic = 'force-dynamic' + +export async function GET(request: Request) { + // The `/auth/callback` route is required for the server-side auth flow implemented + // by the Auth Helpers package. It exchanges an auth code for the user's session. + // https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-sign-in-with-code-exchange + const requestUrl = new URL(request.url) + const code = requestUrl.searchParams.get('code') + + if (code) { + const supabase = createRouteHandlerClient({ cookies }) + await supabase.auth.exchangeCodeForSession(code) + } + + // URL to redirect to after sign in process completes + return NextResponse.redirect(requestUrl.origin) +} diff --git a/app/auth/sign-in/route.ts b/app/auth/sign-in/route.ts new file mode 100644 index 0000000..accb946 --- /dev/null +++ b/app/auth/sign-in/route.ts @@ -0,0 +1,33 @@ +import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' +import { cookies } from 'next/headers' +import { NextResponse } from 'next/server' + +export const dynamic = 'force-dynamic' + +export async function POST(request: Request) { + const requestUrl = new URL(request.url) + const formData = await request.formData() + const email = String(formData.get('email')) + const password = String(formData.get('password')) + const supabase = createRouteHandlerClient({ cookies }) + + const { error } = await supabase.auth.signInWithPassword({ + email, + password, + }) + + if (error) { + return NextResponse.redirect( + `${requestUrl.origin}/login?error=Could not authenticate user`, + { + // a 301 status is required to redirect from a POST to a GET route + status: 301, + } + ) + } + + return NextResponse.redirect(requestUrl.origin, { + // a 301 status is required to redirect from a POST to a GET route + status: 301, + }) +} diff --git a/app/auth/sign-out/route.ts b/app/auth/sign-out/route.ts new file mode 100644 index 0000000..658e5c7 --- /dev/null +++ b/app/auth/sign-out/route.ts @@ -0,0 +1,17 @@ +import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' +import { cookies } from 'next/headers' +import { NextResponse } from 'next/server' + +export const dynamic = 'force-dynamic' + +export async function POST(request: Request) { + const requestUrl = new URL(request.url) + const supabase = createRouteHandlerClient({ cookies }) + + await supabase.auth.signOut() + + return NextResponse.redirect(`${requestUrl.origin}/login`, { + // a 301 status is required to redirect from a POST to a GET route + status: 301, + }) +} diff --git a/app/auth/sign-up/route.ts b/app/auth/sign-up/route.ts new file mode 100644 index 0000000..f7d2aef --- /dev/null +++ b/app/auth/sign-up/route.ts @@ -0,0 +1,39 @@ +import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' +import { cookies } from 'next/headers' +import { NextResponse } from 'next/server' + +export const dynamic = 'force-dynamic' + +export async function POST(request: Request) { + const requestUrl = new URL(request.url) + const formData = await request.formData() + const email = String(formData.get('email')) + const password = String(formData.get('password')) + const supabase = createRouteHandlerClient({ cookies }) + + const { error } = await supabase.auth.signUp({ + email, + password, + options: { + emailRedirectTo: `${requestUrl.origin}/auth/callback`, + }, + }) + + if (error) { + return NextResponse.redirect( + `${requestUrl.origin}/login?error=Could not authenticate user`, + { + // a 301 status is required to redirect from a POST to a GET route + status: 301, + } + ) + } + + return NextResponse.redirect( + `${requestUrl.origin}/login?message=Check email to continue sign in process`, + { + // a 301 status is required to redirect from a POST to a GET route + status: 301, + } + ) +} diff --git a/app/favicon.ico b/app/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/app/favicon.ico differ diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..50bd9fc --- /dev/null +++ b/app/globals.css @@ -0,0 +1,42 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 200 20% 98%; + --btn-background: 200 10% 91%; + --btn-background-hover: 200 10% 89%; + --foreground: 200 50% 3%; + } + + @media (prefers-color-scheme: dark) { + :root { + --background: 200 50% 3%; + --btn-background: 200 10% 9%; + --btn-background-hover: 200 10% 12%; + --foreground: 200 20% 96%; + } + } +} + +@layer base { + * { + @apply border-foreground/20; + } +} + +.animate-in { + animation: animateIn 0.3s ease 0.15s both; +} + +@keyframes animateIn { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..2e8ec03 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,22 @@ +import './globals.css' + +export const metadata = { + title: 'Create Next App', + description: 'Generated by create next app', +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + +
+ {children} +
+ + + ) +} diff --git a/app/login/messages.tsx b/app/login/messages.tsx new file mode 100644 index 0000000..17a2de3 --- /dev/null +++ b/app/login/messages.tsx @@ -0,0 +1,23 @@ +'use client' + +import { useSearchParams } from 'next/navigation' + +export default function Messages() { + const searchParams = useSearchParams() + const error = searchParams.get('error') + const message = searchParams.get('message') + return ( + <> + {error && ( +

+ {error} +

+ )} + {message && ( +

+ {message} +

+ )} + + ) +} diff --git a/app/login/page.tsx b/app/login/page.tsx new file mode 100644 index 0000000..0ea733b --- /dev/null +++ b/app/login/page.tsx @@ -0,0 +1,65 @@ +import Link from 'next/link' +import Messages from './messages' + +export default function Login() { + return ( +
+ + + + {' '} + Back + + +
+ + + + + + + + +
+ ) +} diff --git a/app/opengraph-image.png b/app/opengraph-image.png new file mode 100644 index 0000000..57595e6 Binary files /dev/null and b/app/opengraph-image.png differ diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..0014426 --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,188 @@ +import { createServerComponentClient } from '@supabase/auth-helpers-nextjs' +import { cookies } from 'next/headers' +import Link from 'next/link' +import LogoutButton from '../components/LogoutButton' +import SupabaseLogo from '../components/SupabaseLogo' +import NextJsLogo from '../components/NextJsLogo' +import DeployButton from '../components/DeployButton' + +export const dynamic = 'force-dynamic' + +const resources = [ + { + title: 'Cookie-based Auth and the Next.js App Router', + subtitle: + 'This free course by Jon Meyers, shows you how to configure Supabase Auth to use cookies, and steps through some common patterns.', + url: 'https://youtube.com/playlist?list=PL5S4mPUpp4OtMhpnp93EFSo42iQ40XjbF', + icon: 'M7 4V20M17 4V20M3 8H7M17 8H21M3 12H21M3 16H7M17 16H21M4 20H20C20.5523 20 21 19.5523 21 19V5C21 4.44772 20.5523 4 20 4H4C3.44772 4 3 4.44772 3 5V19C3 19.5523 3.44772 20 4 20Z', + }, + { + title: 'Supabase Next.js App Router Example', + subtitle: + 'Want to see a code example containing some common patterns with Next.js and Supabase? Check out this repo!', + url: 'https://github.com/supabase/supabase/tree/master/examples/auth/nextjs', + icon: 'M10 20L14 4M18 8L22 12L18 16M6 16L2 12L6 8', + }, + { + title: 'Supabase Auth Helpers Docs', + subtitle: + 'This template has configured Supabase Auth to use cookies for you, but the docs are a great place to learn more.', + url: 'https://supabase.com/docs/guides/auth/auth-helpers/nextjs', + icon: 'M12 6.25278V19.2528M12 6.25278C10.8321 5.47686 9.24649 5 7.5 5C5.75351 5 4.16789 5.47686 3 6.25278V19.2528C4.16789 18.4769 5.75351 18 7.5 18C9.24649 18 10.8321 18.4769 12 19.2528M12 6.25278C13.1679 5.47686 14.7535 5 16.5 5C18.2465 5 19.8321 5.47686 21 6.25278V19.2528C19.8321 18.4769 18.2465 18 16.5 18C14.7535 18 13.1679 18.4769 12 19.2528', + }, +] + +const examples = [ + { type: 'Client Components', src: 'app/_examples/client-component/page.tsx' }, + { type: 'Server Components', src: 'app/_examples/server-component/page.tsx' }, + { type: 'Server Actions', src: 'app/_examples/server-action/page.tsx' }, + { type: 'Route Handlers', src: 'app/_examples/route-handler.ts' }, +] + +export default async function Index() { + const supabase = createServerComponentClient({ cookies }) + + const { + data: { user }, + } = await supabase.auth.getUser() + + return ( +
+ + +
+
+
+ + + + + +
+

Supabase and Next.js Starter Template

+

+ The fastest way to start building apps with{' '} + Supabase and Next.js +

+
+ Get started by editing app/page.tsx +
+
+ +
+ +
+

+ Everything you need to get started +

+
+ {resources.map(({ title, subtitle, url, icon }) => ( + +

+ {title} +

+
+

{subtitle}

+
+ + + + + + + +
+
+
+ ))} +
+
+ +
+
+

Examples

+

+ Look in the _examples folder to see how to create a + Supabase client in all the different contexts. +

+
+
+ {examples.map(({ type, src }) => ( +
+
+ {type} +
+
+ {src} +
+
+ ))} +
+
+ +
+

+ Powered by{' '} + + Supabase + +

+
+
+
+ ) +} diff --git a/assets/hero.png b/assets/hero.png new file mode 100644 index 0000000..75e7048 Binary files /dev/null and b/assets/hero.png differ diff --git a/assets/instructions.png b/assets/instructions.png new file mode 100644 index 0000000..979dee6 Binary files /dev/null and b/assets/instructions.png differ diff --git a/assets/step-2-er-diagram.png b/assets/step-2-er-diagram.png new file mode 100644 index 0000000..b5e8f0c Binary files /dev/null and b/assets/step-2-er-diagram.png differ diff --git a/components/DeployButton.tsx b/components/DeployButton.tsx new file mode 100644 index 0000000..6e0b7d8 --- /dev/null +++ b/components/DeployButton.tsx @@ -0,0 +1,25 @@ +'use client' + +export default function DeployButton() { + return ( + + + + + Deploy to Vercel + + ) +} diff --git a/components/LogoutButton.tsx b/components/LogoutButton.tsx new file mode 100644 index 0000000..776d6d5 --- /dev/null +++ b/components/LogoutButton.tsx @@ -0,0 +1,9 @@ +export default function LogoutButton() { + return ( +
+ +
+ ) +} diff --git a/components/NextJsLogo.tsx b/components/NextJsLogo.tsx new file mode 100644 index 0000000..ec41163 --- /dev/null +++ b/components/NextJsLogo.tsx @@ -0,0 +1,48 @@ +import React from 'react' + +export default function NextJsLogo() { + return ( + + + + + + + + + + + ) +} diff --git a/components/SupabaseLogo.tsx b/components/SupabaseLogo.tsx new file mode 100644 index 0000000..e007646 --- /dev/null +++ b/components/SupabaseLogo.tsx @@ -0,0 +1,104 @@ +import React from 'react' + +export default function SupabaseLogo() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..2eab4b7 --- /dev/null +++ b/middleware.ts @@ -0,0 +1,17 @@ +import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs' +import { NextResponse } from 'next/server' + +import type { NextRequest } from 'next/server' + +export async function middleware(req: NextRequest) { + const res = NextResponse.next() + + // Create a Supabase client configured to use cookies + const supabase = createMiddlewareClient({ req, res }) + + // Refresh session if expired - required for Server Components + // https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-session-with-middleware + await supabase.auth.getSession() + + return res +} diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..950e2f4 --- /dev/null +++ b/next.config.js @@ -0,0 +1,8 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + serverActions: true, + }, +} + +module.exports = nextConfig diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..bed7c0d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1763 @@ +{ + "name": "chatgpt-your-files", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@supabase/auth-helpers-nextjs": "latest", + "@supabase/supabase-js": "latest", + "autoprefixer": "10.4.15", + "next": "latest", + "postcss": "8.4.29", + "react": "18.2.0", + "react-dom": "18.2.0", + "tailwindcss": "3.3.3", + "typescript": "5.1.3" + }, + "devDependencies": { + "@types/node": "20.3.1", + "@types/react": "18.2.12", + "@types/react-dom": "18.2.5", + "encoding": "^0.1.13" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next/env": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.4.tgz", + "integrity": "sha512-LGegJkMvRNw90WWphGJ3RMHMVplYcOfRWf2Be3td3sUa+1AaxmsYyANsA+znrGCBjXJNi4XAQlSoEfUxs/4kIQ==" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.4.tgz", + "integrity": "sha512-Df8SHuXgF1p+aonBMcDPEsaahNo2TCwuie7VXED4FVyECvdXfRT9unapm54NssV9tF3OQFKBFOdlje4T43VO0w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", + "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", + "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", + "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", + "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", + "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", + "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", + "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", + "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@supabase/auth-helpers-nextjs": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.8.1.tgz", + "integrity": "sha512-ZO/UGDE9oaVXwPL4gpzGu2NpPwfKOgxTUnuK6no51So8Ah9BUuUUsTj+BdZlx7jJoZEIAkHWdRIx65WuQgWAiQ==", + "dependencies": { + "@supabase/auth-helpers-shared": "0.5.0", + "set-cookie-parser": "^2.6.0" + }, + "peerDependencies": { + "@supabase/supabase-js": "^2.19.0" + } + }, + "node_modules/@supabase/auth-helpers-shared": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-shared/-/auth-helpers-shared-0.5.0.tgz", + "integrity": "sha512-kioUeYDBZ89cfqOTZFOLEFIO7kGczL0XJYZdVv/bKt5efXqhiY14NbzgGWiMvvD9o9Iluo0+YEV2tG3ZZ5W06A==", + "dependencies": { + "jose": "^4.14.4" + }, + "peerDependencies": { + "@supabase/supabase-js": "^2.19.0" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.1.5.tgz", + "integrity": "sha512-BNzC5XhCzzCaggJ8s53DP+WeHHGT/NfTsx2wUSSGKR2/ikLFQTBCDzMvGz/PxYMqRko/LwncQtKXGOYp1PkPaw==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/gotrue-js": { + "version": "2.55.0", + "resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-2.55.0.tgz", + "integrity": "sha512-wZAP66Lo68iROKo33m8seY30rCeGiR34leMEZ80j9fPm+/ar6h3y43Hb7f9F2STVMwT3Sv+aM+w0yCon5bih4g==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.14.tgz", + "integrity": "sha512-w/Tsd22e/5fAeoxqQ4P2MX6EyF+iM6rc9kmlMVFkHuG0rAltt2TLhFbDJfemnHbtvnazWaRfy5KnFU/SYT37dQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.8.4.tgz", + "integrity": "sha512-ELjpvhb04wILUiJz9zIsTSwaz9LQNlX+Ig5/LgXQ7k68qQI6NqHVn+ISRNt53DngUIyOnLHjeqqIRHBZ7zpgGA==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.8.0.tgz", + "integrity": "sha512-j1OP2nRJhqLNEoYSMkIl1+cHK/Ow9fektemazkF2CvrIrmwgfJJGaFGiWGVgwoKtwVcrdknSsYWpxs90hys1EQ==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/websocket": "^1.0.3", + "websocket": "^1.0.34" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.4.tgz", + "integrity": "sha512-yspHD19I9uQUgfTh0J94+/r/g6hnhdQmw6Y7OWqr/EbnL6uvicGV1i1UDkkmeUHqfF9Mbt2sLtuxRycYyKv2ew==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.38.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.38.0.tgz", + "integrity": "sha512-FSkIcz+/+TTBqNqhR8AdtblxEqCF72//CCkmZFIRCa3Xh/aiI0F4cBdL7AB3aIQn2DhE4aGxZ4mGiGR593096Q==", + "dependencies": { + "@supabase/functions-js": "^2.1.5", + "@supabase/gotrue-js": "^2.54.2", + "@supabase/node-fetch": "^2.6.14", + "@supabase/postgrest-js": "^1.8.4", + "@supabase/realtime-js": "^2.8.0", + "@supabase/storage-js": "^2.5.4" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/node": { + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", + "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" + }, + "node_modules/@types/phoenix": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.2.tgz", + "integrity": "sha512-I3mm7x5XIi+5NsIY3nfreY+H4PmQdyBwJ84SiUSOxSg1axwEPNmkKWYVm56y+emDpPPUL3cPzrLcgRWSd9gI7g==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.8", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", + "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.12.tgz", + "integrity": "sha512-ndmBMLCgn38v3SntMeoJaIrO6tGHYKMEBohCUmw8HoLLQdRMOIGXfeYaBTLe2lsFaSB3MOK1VXscYFnmLtTSmw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.5.tgz", + "integrity": "sha512-sRQsOS/sCLnpQhR4DSKGTtWFE3FZjpQa86KPVbhUqdYMRZ9FEFcfAytKhR/vUG2rH1oFbOOej6cuD7MFSobDRQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.4", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz", + "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==", + "dev": true + }, + "node_modules/@types/websocket": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.7.tgz", + "integrity": "sha512-62Omr8U0PO+hgjLCpPnMsmjh2/FRwIGOktZHyYAUzooEJotwkXHMp7vCacdYi8haxBNOiw9bc2HIHI+b/MPNjA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/autoprefixer": { + "version": "10.4.15", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", + "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001520", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bufferutil": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", + "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001546", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz", + "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", + "dev": true + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.543", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.543.tgz", + "integrity": "sha512-t2ZP4AcGE0iKCCQCBx/K2426crYdxD3YU6l0uK2EO3FZH0pbC4pFz/sZm2ruZsND6hQBTcDWWlo/MLpiOdif5g==" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fraction.js": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", + "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/jiti": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", + "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.2.tgz", + "integrity": "sha512-IY73F228OXRl9ar3jJagh7Vnuhj/GzBunPiZP13K0lOl7Am9SoWW3kEzq3MCllJMTtZqHTiDXQvoRd4U95aU6A==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/next/-/next-13.5.4.tgz", + "integrity": "sha512-+93un5S779gho8y9ASQhb/bTkQF17FNQOtXLKAj3lsNgltEcF0C5PMLLncDmH+8X1EnJH1kbqAERa29nRXqhjA==", + "dependencies": { + "@next/env": "13.5.4", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.31", + "styled-jsx": "5.1.1", + "watchpack": "2.4.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=16.14.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "13.5.4", + "@next/swc-darwin-x64": "13.5.4", + "@next/swc-linux-arm64-gnu": "13.5.4", + "@next/swc-linux-arm64-musl": "13.5.4", + "@next/swc-linux-x64-gnu": "13.5.4", + "@next/swc-linux-x64-musl": "13.5.4", + "@next/swc-win32-arm64-msvc": "13.5.4", + "@next/swc-win32-ia32-msvc": "13.5.4", + "@next/swc-win32-x64-msvc": "13.5.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-gyp-build": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", + "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "engines": { + "node": ">= 14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", + "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", + "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.18.2", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", + "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yaml": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", + "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..75e517c --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "@supabase/auth-helpers-nextjs": "latest", + "@supabase/supabase-js": "latest", + "autoprefixer": "10.4.15", + "next": "latest", + "postcss": "8.4.29", + "react": "18.2.0", + "react-dom": "18.2.0", + "tailwindcss": "3.3.3", + "typescript": "5.1.3" + }, + "devDependencies": { + "@types/node": "20.3.1", + "@types/react": "18.2.12", + "@types/react-dom": "18.2.5", + "encoding": "^0.1.13" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/sample-files/roman-empire-1.md b/sample-files/roman-empire-1.md new file mode 100644 index 0000000..414d683 --- /dev/null +++ b/sample-files/roman-empire-1.md @@ -0,0 +1,167 @@ +# Roman Empire + +The **Roman Empire** was the post-[Republican](/wiki/Roman_Republic 'Roman Republic') state of [ancient Rome](/wiki/Ancient_Rome 'Ancient Rome') and is generally understood to mean the period, and the territory ruled by the [Romans](/wiki/Roman_people 'Roman people') following [Octavian](/wiki/Octavian 'Octavian')\'s assumption of sole rule under the [Principate](/wiki/Principate 'Principate') in 31 BC. It included territory around the [Mediterranean](/wiki/Mediterranean_Sea 'Mediterranean Sea') in [Europe](/wiki/Europe 'Europe'), [North Africa](/wiki/North_Africa 'North Africa'), and [Western Asia](/wiki/Western_Asia 'Western Asia'), eventually extending as far north as Northern Europe, and was ruled by [emperors](/wiki/Roman_emperor 'Roman emperor'). The adoption of Christianity as the [state church](/wiki/Christianity_as_the_Roman_state_religion 'Christianity as the Roman state religion') in 380 and the [fall of the Western Roman Empire](/wiki/Fall_of_the_Western_Roman_Empire 'Fall of the Western Roman Empire') conventionally marks the end of [classical antiquity](/wiki/Classical_antiquity 'Classical antiquity') and the beginning of the [Middle Ages](/wiki/Middle_Ages 'Middle Ages'). + +Rome had expanded its rule to most of the Mediterranean and beyond, but became severely destabilized in [civil wars and political conflicts](/wiki/List_of_Roman_civil_wars_and_revolts 'List of Roman civil wars and revolts') which culminated in the [victory of Octavian](/wiki/Wars_of_Augustus 'Wars of Augustus') over [Mark Antony](/wiki/Mark_Antony 'Mark Antony') and [Cleopatra](/wiki/Cleopatra 'Cleopatra') at the [Battle of Actium](/wiki/Battle_of_Actium 'Battle of Actium') in 31 BC and the subsequent conquest of the [Ptolemaic Kingdom](/wiki/Ptolemaic_Kingdom 'Ptolemaic Kingdom') in Egypt. The [Roman Senate](/wiki/Roman_Senate 'Roman Senate') granted Octavian overarching power (_[imperium](/wiki/Imperium 'Imperium')_) and the new title of _[Augustus]( 'Augustus (title)')\_, marking his [accession as the first Roman emperor](/wiki/Constitutional_reforms_of_Augustus 'Constitutional reforms of Augustus') of a [monarchy](/wiki/Principate 'Principate') with [Rome](/wiki/Rome 'Rome') as its sole capital. The vast Roman territories were organized in [senatorial](/wiki/Senatorial_province 'Senatorial province') and [imperial](/wiki/Imperial_province 'Imperial province') provinces. + +The [first two centuries of the Empire](/wiki/History_of_the_Roman_Empire 'History of the Roman Empire') saw a period of unprecedented stability and prosperity known as the [Pax Romana](/wiki/Pax_Romana 'Pax Romana') (lit.[ ]\'Roman Peace\'). Rome reached its [greatest territorial expanse](/wiki/Borders_of_the_Roman_Empire 'Borders of the Roman Empire') under [Trajan](/wiki/Trajan 'Trajan') (AD 98--117); a period of increasing trouble and decline began under [Commodus](/wiki/Commodus 'Commodus') (180--192). In the 3rd century, the Empire underwent a [crisis](/wiki/Crisis_of_the_Third_Century 'Crisis of the Third Century') that threatened its existence, as the [Gallic](/wiki/Gallic_Empire 'Gallic Empire') and [Palmyrene](/wiki/Palmyrene_Empire 'Palmyrene Empire') Empires broke away from the Roman state, and a series of [short-lived emperors](/wiki/Barracks_emperor 'Barracks emperor') led the Empire. It was reunified under [Aurelian](/wiki/Aurelian 'Aurelian'). [Diocletian](/wiki/Diocletian 'Diocletian') set up two different imperial courts in the [Greek East and Latin West](/wiki/Greek_East_and_Latin_West 'Greek East and Latin West') in 286; [Christians rose to power](/wiki/Constantine_the_Great_and_Christianity 'Constantine the Great and Christianity') in the 4th century following the [Edict of Milan](/wiki/Edict_of_Milan 'Edict of Milan'). The imperial seat moved from Rome to [Byzantium](/wiki/Names_of_Istanbul 'Names of Istanbul') in 330, renamed [Constantinople](/wiki/Constantinople 'Constantinople') after [Constantine the Great](/wiki/Constantine_the_Great 'Constantine the Great'). The [Migration Period](/wiki/Migration_Period 'Migration Period'), involving [large invasions by Germanic peoples](/wiki/Germanic%E2%80%93Roman_contacts 'Germanic–Roman contacts') and by the [Huns](/wiki/Huns 'Huns') of [Attila](/wiki/Attila 'Attila'), led to the decline of the [Western Roman Empire](/wiki/Western_Roman_Empire 'Western Roman Empire'). With the [fall of Ravenna]( 'Battle of Ravenna (476)') to the [Germanic Herulians](/wiki/Heruli 'Heruli') and the [deposition of Romulus Augustus](/wiki/Deposition_of_Romulus_Augustus 'Deposition of Romulus Augustus') in 476 by Odoacer, the Western Roman Empire finally collapsed. The [Eastern Roman Empire](/wiki/Eastern_Roman_Empire 'Eastern Roman Empire') survived for another millennium with Constantinople as its sole capital, until the city\'s [fall](/wiki/Fall_of_Constantinople 'Fall of Constantinople') in 1453. + +Due to the Empire\'s extent and endurance, its institutions and culture had [a lasting influence](/wiki/Legacy_of_the_Roman_Empire 'Legacy of the Roman Empire') on the development of [language](/wiki/History_of_Latin 'History of Latin'), [religion](/wiki/Religion_in_ancient_Rome 'Religion in ancient Rome'), [art](/wiki/Roman_art 'Roman art'), [architecture](/wiki/Ancient_Roman_architecture 'Ancient Roman architecture'), [literature](/wiki/Latin_literature 'Latin literature'), [philosophy](/wiki/Ancient_Roman_philosophy 'Ancient Roman philosophy'), [law](/wiki/Roman_law 'Roman law'), and [forms of government](/wiki/Roman_magistrate 'Roman magistrate') in its territories. [Latin](/wiki/Latin 'Latin') evolved into the [Romance languages](/wiki/Romance_languages 'Romance languages'), while [Medieval Greek](/wiki/History_of_Greek 'History of Greek') became the language of the East. The Empire\'s [adoption of Christianity](/wiki/History_of_Christianity 'History of Christianity') led to the formation of medieval [Christendom](/wiki/Christendom 'Christendom'). Roman and [Greek art](/wiki/Ancient_Greek_art 'Ancient Greek art') had a profound impact on the [Italian Renaissance](/wiki/Italian_Renaissance 'Italian Renaissance'). Rome\'s architectural tradition served as the basis for [Romanesque](/wiki/Romanesque_architecture 'Romanesque architecture'), [Renaissance](/wiki/Renaissance_architecture 'Renaissance architecture') and [Neoclassical architecture](/wiki/Neoclassical_architecture 'Neoclassical architecture'), and influenced [Islamic architecture](/wiki/Islamic_architecture 'Islamic architecture'). The rediscovery of [classical science](/wiki/Science_in_classical_antiquity 'Science in classical antiquity') and [technology](/wiki/Ancient_Roman_technology 'Ancient Roman technology') (which formed the basis for [Islamic science](/wiki/Science_in_the_medieval_Islamic_world 'Science in the medieval Islamic world')) in medieval Europe led to the [Scientific Renaissance](/wiki/Science_in_the_Renaissance 'Science in the Renaissance') and [Scientific Revolution](/wiki/Scientific_Revolution 'Scientific Revolution'). Many modern legal systems, such as the [Napoleonic Code](/wiki/Napoleonic_Code 'Napoleonic Code'), descend from Roman law, while Rome\'s republican institutions have [influenced](/wiki/Classical_tradition 'Classical tradition') the [Italian city-state republics](/wiki/Maritime_republics 'Maritime republics') of the medieval period, the early [United States](/wiki/United_States 'United States'), and modern democratic republics. + +## History + +Main article: [History of the Roman Empire](/wiki/History_of_the_Roman_Empire 'History of the Roman Empire') + +For a chronological guide, see [Timeline of Roman history](/wiki/Timeline_of_Roman_history 'Timeline of Roman history'). + +See also: [Campaign history of the Roman military](/wiki/Campaign_history_of_the_Roman_military 'Campaign history of the Roman military') and [Roman Kingdom](/wiki/Roman_Kingdom 'Roman Kingdom') + +### Transition from Republic to Empire + +Further information: [Roman Republic](/wiki/Roman_Republic 'Roman Republic') + +Rome had begun expanding shortly after the founding of the [Roman Republic](/wiki/Roman_Republic 'Roman Republic') in the 6th century BC, though not outside the Italian peninsula until the 3rd century BC. Thus, it was an \"empire\" (a great power) long before it had an emperor. The Republic was not a nation-state in the modern sense, but a network of self-ruled towns (with varying degrees of independence from the [Senate](/wiki/Roman_Senate 'Roman Senate')) and provinces administered by military commanders. It was governed by annually elected [magistrates](/wiki/Roman_magistrate 'Roman magistrate') ([Roman consuls](/wiki/Roman_consul 'Roman consul') above all) in conjunction with the Senate. The 1st century BC was a time of political and military upheaval, which ultimately led to rule by emperors. The consuls\' military power rested in the Roman legal concept of _[imperium](/wiki/Imperium 'Imperium')_, meaning \"command\" (though typically in a military sense). Occasionally, successful consuls were given the honorary title _[imperator](/wiki/Imperator 'Imperator')_ (commander); this is the origin of the word _emperor_, since this title was always bestowed to the early emperors. + +Rome suffered a long series of internal conflicts, conspiracies, and [civil wars](/wiki/Roman_civil_wars 'Roman civil wars') from the late second century BC---[Crisis of the Roman Republic](/wiki/Crisis_of_the_Roman_Republic 'Crisis of the Roman Republic')---while greatly extending its power beyond Italy. In 44 BC, [Julius Caesar](/wiki/Julius_Caesar 'Julius Caesar') was briefly perpetual [dictator](/wiki/Roman_dictator 'Roman dictator') before being [assassinated](/wiki/Assassination_of_Julius_Caesar 'Assassination of Julius Caesar'). The faction of his assassins was driven from Rome and defeated at the [Battle of Philippi](/wiki/Battle_of_Philippi 'Battle of Philippi') in 42 BC by [Mark Antony](/wiki/Mark_Antony 'Mark Antony') and Caesar\'s adopted son [Octavian](/wiki/Augustus 'Augustus'). Antony and Octavian\'s division of the Roman world did not last and Octavian\'s forces defeated those of Mark Antony and [Cleopatra](/wiki/Cleopatra 'Cleopatra') at the [Battle of Actium](/wiki/Battle_of_Actium 'Battle of Actium') in 31 BC. In 27 BC the [Senate](/wiki/Roman_Senate 'Roman Senate') made Octavian _[princeps](/wiki/Princeps 'Princeps')_ (\"first citizen\") with [proconsular](/wiki/Proconsul 'Proconsul') _[imperium](/wiki/Imperium 'Imperium')_, thus beginning the [Principate](/wiki/Principate 'Principate') (the first epoch of Roman imperial history, usually dated from 27 BC to 284 AD), and gave him the title _[Augustus]( 'Augustus (title)')_ (\"the venerated\"). Although the republic stood in name, Augustus had all meaningful authority. Since his rule began an unprecedented period of peace and prosperity, he was so loved that he came to hold the power of a monarch _[de facto](/wiki/De_facto 'De facto')_ if not _[de jure](/wiki/De_jure 'De jure')\_. During the years of his rule, a new constitutional order emerged (in part organically and in part by design), so that, upon his death, this new constitutional order operated as before when [Tiberius](/wiki/Tiberius 'Tiberius') was accepted as the new emperor. + +### _Pax Romana_ + +Main article: [Pax Romana](/wiki/Pax_Romana 'Pax Romana') + +The 200 years that began with Augustus\'s rule is traditionally regarded as the _[Pax Romana](/wiki/Pax_Romana 'Pax Romana')_ (\"Roman Peace\"). The cohesion of the empire was furthered by a degree of social stability and economic prosperity that Rome had never before experienced. Uprisings in the provinces were infrequent and put down \"mercilessly and swiftly\". The success of Augustus in establishing principles of dynastic succession was limited by his outliving a number of talented potential heirs. The [Julio-Claudian dynasty](/wiki/Julio-Claudian_dynasty 'Julio-Claudian dynasty') lasted for four more emperors---[Tiberius](/wiki/Tiberius 'Tiberius'), [Caligula](/wiki/Caligula 'Caligula'), [Claudius](/wiki/Claudius 'Claudius'), and [Nero](/wiki/Nero 'Nero')---before it yielded in 69 AD to the strife-torn [Year of the Four Emperors](/wiki/Year_of_the_Four_Emperors 'Year of the Four Emperors'), from which [Vespasian](/wiki/Vespasian 'Vespasian') emerged as victor. Vespasian became the founder of the brief [Flavian dynasty](/wiki/Flavian_dynasty 'Flavian dynasty'), followed by the [Nerva--Antonine dynasty](/wiki/Nerva%E2%80%93Antonine_dynasty 'Nerva–Antonine dynasty') which produced the \"[Five Good Emperors](/wiki/Five_Good_Emperors 'Five Good Emperors')\": [Nerva](/wiki/Nerva 'Nerva'), [Trajan](/wiki/Trajan 'Trajan'), [Hadrian](/wiki/Hadrian 'Hadrian'), [Antoninus Pius](/wiki/Antoninus_Pius 'Antoninus Pius'), and [Marcus Aurelius](/wiki/Marcus_Aurelius 'Marcus Aurelius'). + +### Fall in the West and survival in the East + +Main articles: [Later Roman Empire](/wiki/Later_Roman_Empire 'Later Roman Empire') and [Fall of the Western Roman Empire](/wiki/Fall_of_the_Western_Roman_Empire 'Fall of the Western Roman Empire') + +See also: [Barbarian kingdoms](/wiki/Barbarian_kingdoms 'Barbarian kingdoms') and [Byzantine Empire](/wiki/Byzantine_Empire 'Byzantine Empire') + +In the view of contemporary Greek historian [Cassius Dio](/wiki/Cassius_Dio 'Cassius Dio'), the accession of [Commodus](/wiki/Commodus 'Commodus') in 180 marked the descent \"from a kingdom of gold to one of rust and iron\"---a comment which has led some historians, notably [Edward Gibbon](/wiki/Edward_Gibbon 'Edward Gibbon'), to take Commodus\' reign as the beginning of the [Empire\'s decline](/wiki/Historiography_of_the_fall_of_the_Western_Roman_Empire 'Historiography of the fall of the Western Roman Empire'). + +In 212, during the reign of [Caracalla](/wiki/Caracalla 'Caracalla'), [Roman citizenship](/wiki/Roman_citizenship 'Roman citizenship') was granted to all freeborn inhabitants of the empire. The [Severan dynasty](/wiki/Severan_dynasty 'Severan dynasty') was tumultuous---an emperor\'s reign was ended routinely by his murder or execution---and, following its collapse, the Empire was engulfed by the [Crisis of the Third Century](/wiki/Crisis_of_the_Third_Century 'Crisis of the Third Century'), a period of [invasions](/wiki/Invasion 'Invasion'), [civil strife](/wiki/Civil_strife 'Civil strife'), [economic disorder](/wiki/Economic_collapse 'Economic collapse'), and [plague](/wiki/Plague_of_Cyprian 'Plague of Cyprian'). In defining [historical epochs](/wiki/Periodization 'Periodization'), this crisis sometimes marks the transition from [Classical](/wiki/Classical_Antiquity 'Classical Antiquity') to [Late Antiquity](/wiki/Late_Antiquity 'Late Antiquity'). [Aurelian](/wiki/Aurelian 'Aurelian') stabilized the empire and [Diocletian](/wiki/Diocletian 'Diocletian') completed the work of fully restoring it in 285, but rejected the role of _princeps_ and assumed the title of _dominus_ (\"lord\"), thus starting the period known as the [Dominate](/wiki/Dominate 'Dominate'). Diocletian\'s reign brought the empire\'s most concerted effort against the perceived threat of [Christianity](/wiki/Early_Christianity 'Early Christianity'), the [\"Great Persecution\"](/wiki/Diocletianic_Persecution 'Diocletianic Persecution'). + +Diocletian divided the empire into four regions, each ruled by a separate [tetrarch](/wiki/Tetrarchy 'Tetrarchy'). Confident that he fixed the disorder plaguing Rome, he abdicated along with his co-emperor, but the Tetrarchy [collapsed shortly after](/wiki/Civil_wars_of_the_Tetrarchy 'Civil wars of the Tetrarchy'). Order was eventually restored by [Constantine the Great](/wiki/Constantine_the_Great 'Constantine the Great'), who became the first emperor to [convert to Christianity](/wiki/Constantine_the_Great_and_Christianity 'Constantine the Great and Christianity'), and who established [Constantinople](/wiki/Constantinople 'Constantinople') as the new capital of the Eastern Empire. During the decades of the [Constantinian](/wiki/Constantinian_dynasty 'Constantinian dynasty') and [Valentinian](/wiki/Valentinian_dynasty 'Valentinian dynasty') dynasties, the empire was divided along an east--west axis, with dual power centres in Constantinople and Rome. [Julian]( 'Julian (emperor)'), who under the influence of his adviser [Mardonius]( 'Mardonius (philosopher)') attempted to restore [Classical Roman](/wiki/Religion_in_ancient_Rome 'Religion in ancient Rome') and [Hellenistic religion](/wiki/Hellenistic_religion 'Hellenistic religion'), only briefly interrupted the succession of Christian emperors. [Theodosius I](/wiki/Theodosius_I 'Theodosius I'), the last emperor to rule over both East and West, died in 395 after making Christianity the [state religion](/wiki/State_church_of_the_Roman_Empire 'State church of the Roman Empire'). + +The [Western Roman Empire](/wiki/Western_Roman_Empire 'Western Roman Empire') began to [disintegrate](/wiki/Fall_of_the_Western_Roman_Empire 'Fall of the Western Roman Empire') in the early 5th century. The Romans were successful in fighting off all invaders, most famously [Attila](/wiki/Attila 'Attila'), but the empire had [assimilated so many Germanic peoples](/wiki/Migration_Period 'Migration Period') of dubious loyalty to Rome that the empire started to dismember itself. [Most chronologies](/wiki/Fall_of_the_Western_Roman_Empire 'Fall of the Western Roman Empire') place the end of the Western Roman Empire in 476, when [Romulus Augustulus](/wiki/Romulus_Augustulus 'Romulus Augustulus') was [forced to abdicate](/wiki/Deposition_of_Romulus_Augustulus 'Deposition of Romulus Augustulus') to the [Germanic](/wiki/Germanic_peoples 'Germanic peoples') warlord [Odoacer](/wiki/Odoacer 'Odoacer'). + +Odoacer ended the Western Empire by declaring [Zeno]( 'Zeno (emperor)') sole emperor and placing himself as Zeno\'s nominal subordinate. In reality, Italy was ruled by Odoacer alone. The Eastern Roman Empire, called the [Byzantine Empire](/wiki/Byzantine_Empire 'Byzantine Empire') by later historians, continued until the reign of [Constantine XI Palaiologos](/wiki/Constantine_XI_Palaiologos 'Constantine XI Palaiologos'). The last Roman emperor died in battle in 1453 against [Mehmed II](/wiki/Mehmed_II 'Mehmed II') and his [Ottoman](/wiki/Ottoman_Empire 'Ottoman Empire') forces during the [siege of Constantinople](/wiki/Fall_of_Constantinople 'Fall of Constantinople'). Mehmed II adopted the title of _[caesar](/wiki/Kayser-i_R%C3%BBm 'Kayser-i Rûm')_ in an attempt to claim a connection to the Empire. + +## Geography and demography + +Main articles: [Demography of the Roman Empire](/wiki/Demography_of_the_Roman_Empire 'Demography of the Roman Empire') and [Borders of the Roman Empire](/wiki/Borders_of_the_Roman_Empire 'Borders of the Roman Empire') + +Further information: [Classical demography](/wiki/Classical_demography 'Classical demography') + +The Roman Empire was [one of the largest](/wiki/List_of_largest_empires 'List of largest empires') in history, with contiguous territories throughout Europe, North Africa, and the Middle East. The Latin phrase _imperium sine fine_ (\"empire without end\") expressed the ideology that neither time nor space limited the Empire. In [Virgil](/wiki/Virgil 'Virgil')\'s _[Aeneid](/wiki/Aeneid 'Aeneid'),_ limitless empire is said to be granted to the Romans by [Jupiter]( 'Jupiter (mythology)'). This claim of universal dominion was renewed when the Empire came under Christian rule in the 4th century. In addition to annexing large regions, the Romans directly altered their geography, for example [cutting down entire forests](/wiki/Deforestation_during_the_Roman_period 'Deforestation during the Roman period'). + +[Roman expansion](/wiki/Campaign_history_of_the_Roman_military 'Campaign history of the Roman military') was mostly accomplished under the [Republic](/wiki/Roman_Republic 'Roman Republic'), though parts of northern Europe were conquered in the 1st century, when Roman control in Europe, Africa, and Asia was strengthened. Under [Augustus](/wiki/Augustus 'Augustus'), a \"global map of the known world\" was displayed for the first time in public at Rome, coinciding with the creation of the most comprehensive [political geography](/wiki/Political_geography 'Political geography') that survives from antiquity, the _[Geography](/wiki/Geographica 'Geographica')_ of [Strabo](/wiki/Strabo 'Strabo'). When Augustus died, the account of his achievements _([Res Gestae](/wiki/Res_Gestae_Divi_Augusti 'Res Gestae Divi Augusti'))_ prominently featured the geographical cataloguing of the Empire. Geography alongside meticulous written records were central concerns of [Roman Imperial administration](#Central_government). + +The Empire reached its largest expanse under [Trajan](/wiki/Trajan 'Trajan'), encompassing 5 million square kilometres. The traditional population estimate of [55--60 million] inhabitants accounted for between one-sixth and one-fourth of the world\'s total population and made it the most populous unified political entity in the West until the mid-19th century. Recent [demographic studies](/wiki/Classical_demography#Demography_of_the_Roman_Empire 'Classical demography') have argued for a population peak from [70 million] to more than [100 million]. Each of the three largest cities in the Empire -- Rome, [Alexandria](/wiki/Alexandria 'Alexandria'), and [Antioch](/wiki/Antioch 'Antioch') -- was almost twice the size of any European city at the beginning of the 17th century. + +As the historian [Christopher Kelly]( 'Christopher Kelly (historian)') described it: + +> Then the empire stretched from [Hadrian\'s Wall](/wiki/Hadrian%27s_Wall "Hadrian's Wall") in drizzle-soaked [northern England](/wiki/Northern_England 'Northern England') to the sun-baked banks of the [Euphrates](/wiki/Euphrates 'Euphrates') in Syria; from the great [Rhine](/wiki/Rhine 'Rhine')--[Danube](/wiki/Danube 'Danube') river system, which snaked across the fertile, flat lands of Europe from the [Low Countries](/wiki/Low_Countries 'Low Countries') to the [Black Sea](/wiki/Black_Sea 'Black Sea'), to the rich plains of the North African coast and the luxuriant gash of the [Nile Valley](/wiki/Nile_Valley 'Nile Valley') in Egypt. The empire completely circled the [Mediterranean](/wiki/Mediterranean 'Mediterranean') \... referred to by its conquerors as _[mare nostrum](/wiki/Mare_nostrum 'Mare nostrum')_---\'our sea\'. + +Trajan\'s successor [Hadrian](/wiki/Hadrian 'Hadrian') adopted a policy of maintaining rather than expanding the empire. Borders _(fines)_ were marked, and the frontiers _([limites]( 'Limes (Roman Empire)'))* patrolled. The most heavily fortified borders were the most unstable. [Hadrian\'s Wall](/wiki/Hadrian%27s_Wall "Hadrian's Wall"), which separated the Roman world from what was perceived as an ever-present [barbarian](/wiki/Barbarian 'Barbarian') threat, is the primary surviving monument of this effort. + +## Languages + +Main article: [Languages of the Roman Empire](/wiki/Languages_of_the_Roman_Empire 'Languages of the Roman Empire') + +See also: [Jireček Line](/wiki/Jire%C4%8Dek_Line 'Jireček Line') + +Latin and Greek were the main languages of the Empire, but the Empire was deliberately multilingual. [Andrew Wallace-Hadrill](/wiki/Andrew_Wallace-Hadrill 'Andrew Wallace-Hadrill') says \"The main desire of the Roman government was to make itself understood\". At the start of the Empire, knowledge of Greek was useful to pass as educated nobility and knowledge of Latin was useful for a career in the military, government, or law. Bilingual inscriptions indicate the everyday interpenetration of the two languages. + +Latin and Greek\'s mutual linguistic and cultural influence is a complex topic. Latin words incorporated into Greek were very common by the early imperial era, especially for military, administration, and trade and commerce matters. Greek grammar, literature, poetry and philosophy shaped Latin language and culture. + +There was never a legal requirement for Latin in the Empire, but it represented a certain status. High standards of Latin, _[Latinitas](/wiki/Classical_Latin 'Classical Latin')_, started with the advent of Latin literature. Due to the flexible language policy of the Empire, a natural competition of language emerged that spurred _Latinitas_, to defend Latin against the stronger cultural influence of Greek. Over time Latin usage was used to project power and a higher social class. Different emperors up until Justinian would attempt to require the use of Latin in various sections of the administration but there is no evidence that a linguistic imperialism existed during the early Empire. + +After all freeborn inhabitants were universally [enfranchised](https://en.wiktionary.org/wiki/enfranchise 'wikt:enfranchise') in [212](/wiki/Constitutio_Antoniniana 'Constitutio Antoniniana'), many Roman citizens would have lacked a knowledge of Latin. The wide use of [Koine Greek](/wiki/Koine_Greek 'Koine Greek') was what enabled the spread of Christianity and reflects its role as the [lingua franca](/wiki/Lingua_franca 'Lingua franca') of the Mediterranean during the time of the Empire. Following Diocletian\'s reforms in the 3rd century CE, there was a decline in the knowledge of Greek in the west. Spoken Latin later fragmented into the incipient [romance languages](/wiki/Romance_languages 'Romance languages') in the 7th century CE following the collapse of the Empire\'s west. + +The dominance of Latin and Greek among the literate elite obscure the continuity of other spoken languages within the Empire. Latin, referred to in its spoken form as [Vulgar Latin](/wiki/Vulgar_Latin 'Vulgar Latin'), gradually replaced [Celtic](/wiki/Celtic_languages 'Celtic languages') and [Italic languages](/wiki/Italic_languages 'Italic languages'). References to interpreters indicate the continuing use of local languages, particularly in Egypt with [Coptic](/wiki/Coptic_language 'Coptic language'), and in military settings along the Rhine and Danube. Roman [jurists](/wiki/Jurist 'Jurist') also show a concern for local languages such as [Punic](/wiki/Punic_language 'Punic language'), [Gaulish](/wiki/Gaulish_language 'Gaulish language'), and [Aramaic](/wiki/Aramaic 'Aramaic') in assuring the correct understanding of laws and oaths. In [Africa]( 'Africa (Roman province)'), Libyco-Berber and Punic were used in inscriptions into the 2nd century. In [Syria]( 'Syria (Roman province)'), [Palmyrene](/wiki/Palmyra 'Palmyra') soldiers used their [dialect of Aramaic](/wiki/Palmyrene_dialect 'Palmyrene dialect') for inscriptions, an exception to the rule that Latin was the language of the military. The last reference to Gaulish was between 560 and 575. The emergent [Gallo-Romance languages](/wiki/Gallo-Romance_languages 'Gallo-Romance languages') would then be shaped by Gaulish [Proto-Basque](/wiki/Proto-Basque_language 'Proto-Basque language') or [Aquitanian](/wiki/Aquitanian_language 'Aquitanian language') evolved with Latin loan words to modern [Basque](/wiki/Basque_language 'Basque language').The [Thracian language](/wiki/Thracian_language 'Thracian language'), as were several now-extinct languages in Anatolia are attested in Imperial-era inscriptions. + +## Society + +Further information: [Ancient Roman society](/wiki/Ancient_Roman_society 'Ancient Roman society') + +The Empire was remarkably multicultural, with \"astonishing cohesive capacity\" to create shared identity while encompassing diverse peoples. Public monuments and communal spaces open to all---such as [forums]( 'Forum (Roman)'), [amphitheatres](/wiki/List_of_Roman_amphitheatres 'List of Roman amphitheatres'), [racetracks]( 'Circus (building)') and [baths](/wiki/Thermae 'Thermae')---helped foster a sense of \"Romanness\". + +Roman society had multiple, overlapping [social hierarchies](/wiki/Social_class_in_ancient_Rome 'Social class in ancient Rome'). The civil war preceding Augustus caused upheaval, but did not effect an immediate [redistribution of wealth](/wiki/Redistribution_of_wealth 'Redistribution of wealth') and social power. From the perspective of the lower classes, a peak was merely added to the social pyramid. Personal relationships---[patronage](/wiki/Patronage_in_ancient_Rome 'Patronage in ancient Rome'), friendship _(amicitia)_, [family](/wiki/Family_in_ancient_Rome 'Family in ancient Rome'), [marriage](/wiki/Marriage_in_ancient_Rome 'Marriage in ancient Rome')---continued to influence politics. By the time of [Nero](/wiki/Nero 'Nero'), however, it was not unusual to find a former slave who was richer than a freeborn citizen, or an [equestrian](/wiki/Equestrian_order 'Equestrian order') who exercised greater power than a senator. + +The blurring of the Republic\'s more rigid hierarchies led to increased [social mobility](/wiki/Social_mobility 'Social mobility'), both upward and downward, to a greater extent than all other well-documented ancient societies. Women, freedmen, and slaves had opportunities to profit and exercise influence in ways previously less available to them. Social life, particularly for those whose personal resources were limited, was further fostered by a proliferation of [voluntary associations](/wiki/Associations_in_Ancient_Rome 'Associations in Ancient Rome') and [confraternities](/wiki/Confraternity 'Confraternity') (_[collegia](/wiki/Collegium 'Collegium')_ and _[sodalitates](/wiki/Sodales 'Sodales')_): professional and trade guilds, veterans\' groups, religious sodalities, drinking and dining clubs, performing troupes, and [burial societies](/wiki/Burial_society 'Burial society'). + +### Legal status + +Main articles: [Status in Roman legal system](/wiki/Status_in_Roman_legal_system 'Status in Roman legal system') and [Roman citizenship](/wiki/Roman_citizenship 'Roman citizenship') + +According to the [jurist Gaius]( 'Gaius (jurist)'), the essential distinction in the Roman \"[law of persons](/wiki/Legal_personality 'Legal personality')\" was that all humans were either free _(liberi)_ or slaves _(servi)_. The legal status of free persons was further defined by their citizenship. Most citizens held limited rights (such as the _[ius Latinum](/wiki/Ius_Latinum 'Ius Latinum'),_ \"Latin right\"), but were entitled to legal protections and privileges not enjoyed by non-citizens. Free people not considered citizens, but living within the Roman world, were _[peregrini]( 'Peregrinus (Roman)')_, non-Romans. In 212, the _[Constitutio Antoniniana](/wiki/Constitutio_Antoniniana 'Constitutio Antoniniana')\_ extended citizenship to all freeborn inhabitants of the empire. This legal egalitarianism required a far-reaching revision of existing laws that distinguished between citizens and non-citizens. + +#### Women in Roman law + +Main article: [Women in ancient Rome](/wiki/Women_in_ancient_Rome 'Women in ancient Rome') + +Freeborn Roman women were considered citizens, but did not vote, hold political office, or serve in the military. A mother\'s citizen status determined that of her children, as indicated by the phrase _ex duobus civibus Romanis natos_ (\"children born of two Roman citizens\"). A Roman woman kept her own [family name](/wiki/Roman_naming_conventions 'Roman naming conventions') _(nomen)_ for life. Children most often took the father\'s name, with some exceptions. Women could own property, enter contracts, and engage in business. Inscriptions throughout the Empire honour women as benefactors in funding public works, an indication they could hold considerable fortunes. + +The archaic [_manus_ marriage](/wiki/Manus_marriage 'Manus marriage') in which the woman was subject to her husband\'s authority was largely abandoned by the Imperial era, and a married woman retained ownership of any property she brought into the marriage. Technically she remained under her father\'s legal authority, even though she moved into her husband\'s home, but when her father died she became legally emancipated. This arrangement was a factor in the degree of independence Roman women enjoyed compared to many other cultures up to the modern period: although she had to answer to her father in legal matters, she was free of his direct scrutiny in daily life, and her husband had no legal power over her. Although it was a point of pride to be a \"one-man woman\" _(univira)_ who had married only once, there was little stigma attached to [divorce](/wiki/Marriage_in_ancient_Rome#Divorce 'Marriage in ancient Rome'), nor to speedy remarriage after being widowed or divorced. Girls had equal inheritance rights with boys if their father died without leaving a will. A mother\'s right to own and dispose of property, including setting the terms of her will, gave her enormous influence over her sons into adulthood. + +As part of the Augustan programme to restore traditional morality and social order, [moral legislation](/wiki/Leges_Iuliae 'Leges Iuliae') attempted to regulate conduct as a means of promoting \"[family values](/wiki/Family_values 'Family values')\". [Adultery](/wiki/Marriage_in_ancient_Rome#Adultery 'Marriage in ancient Rome') was criminalized, and defined broadly as an illicit sex act _([stuprum](/wiki/Stuprum 'Stuprum'))_ between a male citizen and a married woman, or between a married woman and any man other than her husband. That is, a [double standard](/wiki/Double_standard 'Double standard') was in place: a married woman could have sex only with her husband, but a married man did not commit adultery if he had sex with a prostitute or person of marginalized status. Childbearing was encouraged: a woman who had given birth to three children was granted symbolic honours and greater legal freedom (the _[ius trium liberorum](/wiki/Ius_trium_liberorum 'Ius trium liberorum'))_. + +#### Slaves and the law + +Main article: [Slavery in ancient Rome](/wiki/Slavery_in_ancient_Rome 'Slavery in ancient Rome') + +At the time of Augustus, as many as 35% of the people in [Roman Italy](/wiki/Roman_Italy 'Roman Italy') were slaves, making Rome one of five historical \"slave societies\" in which slaves constituted at least a fifth of the population and played a major role in the economy. Slavery was a complex institution that supported traditional Roman social structures as well as contributing economic utility. In urban settings, slaves might be professionals such as teachers, physicians, chefs, and accountants; the majority of slaves provided trained or unskilled labour. [Agriculture](/wiki/Agriculture_in_ancient_Rome 'Agriculture in ancient Rome') and industry, such as milling and mining, relied on the exploitation of slaves. Outside Italy, slaves were on average an estimated 10 to 20% of the population, sparse in [Roman Egypt](/wiki/Roman_Egypt 'Roman Egypt') but more concentrated in some Greek areas. Expanding Roman ownership of arable land and industries affected preexisting practices of slavery in the provinces. Although slavery has often been regarded as waning in the 3rd and 4th centuries, it remained an integral part of Roman society until gradually ceasing in the 6th and 7th centuries with the disintegration of the complex Imperial economy. + +Laws pertaining to slavery were \"extremely intricate\". Slaves were considered property and had no [legal personhood]( 'Person (law)'). They could be subjected to forms of corporal punishment not normally exercised on citizens, [sexual exploitation](/wiki/Sexuality_in_ancient_Rome#Master-slave_relations 'Sexuality in ancient Rome'), torture, and [summary execution](/wiki/Summary_execution 'Summary execution'). A slave could not as a matter of law be raped; a slave\'s rapist had to be prosecuted by the owner for property damage under the [Aquilian Law](/wiki/Lex_Aquilia 'Lex Aquilia'). Slaves had no right to the form of legal marriage called _[conubium](/wiki/Marriage_in_ancient_Rome 'Marriage in ancient Rome')_, but their unions were sometimes recognized. Technically, a slave could not own property, but a slave who conducted business might be given access to an individual fund _(peculium)_ that he could use, depending on the degree of trust and co-operation between owner and slave. Within a household or workplace, a hierarchy of slaves might exist, with one slave acting as the master of others. Talented slaves might accumulate a large enough _peculium_ to justify their freedom, or be [manumitted](/wiki/Manumission 'Manumission') for services rendered. Manumission had become frequent enough that in 2 BC a law _([Lex Fufia Caninia](/wiki/Lex_Fufia_Caninia 'Lex Fufia Caninia'))_ limited the number of slaves an owner was allowed to free in his will. + +Following the [Servile Wars](/wiki/Servile_Wars 'Servile Wars') of the Republic, legislation under Augustus and his successors shows a driving concern for controlling the threat of rebellions through limiting the size of work groups, and for hunting down fugitive slaves. Over time slaves gained increased legal protection, including the right to file complaints against their masters. A bill of sale might contain a clause stipulating that the slave could not be employed for prostitution, as [prostitutes in ancient Rome](/wiki/Prostitution_in_ancient_Rome 'Prostitution in ancient Rome') were often slaves. The burgeoning trade in [eunuchs](/wiki/Eunuch 'Eunuch') in the late 1st century prompted legislation that prohibited the [castration](/wiki/Sexuality_in_ancient_Rome#Castration_and_circumcision 'Sexuality in ancient Rome') of a slave against his will \"for lust or gain.\" + +Roman slavery was not based on [race]( 'Race (human categorization)'). Generally, slaves in Italy were indigenous Italians, with a minority of foreigners (including both slaves and freedmen) estimated at 5% of the total in the capital at its peak, where their number was largest. Foreign slaves had higher mortality and lower birth rates than natives, and were sometimes even subjected to mass expulsions. The average recorded age at death for the slaves of the city of Rome was seventeen and a half years (17.2 for males; 17.9 for females). + +During the period of republican expansionism when slavery had become pervasive, war captives were a main source of slaves. The range of ethnicities among slaves to some extent reflected that of the armies Rome defeated in war, and the [conquest of Greece](/wiki/Greece_in_the_Roman_era 'Greece in the Roman era') brought a number of highly skilled and educated slaves. Slaves were also traded in markets and sometimes sold by [pirates](/wiki/Cilician_pirates 'Cilician pirates'). [Infant abandonment](/wiki/Child_abandonment 'Child abandonment') and self-enslavement among the poor were other sources. _Vernae_, by contrast, were \"homegrown\" slaves born to female slaves within the household, estate or farm. Although they had no special legal status, an owner who mistreated or failed to care for his _vernae_ faced social disapproval, as they were considered part of the family household and in some cases might actually be the children of free males in the family. + +#### Freedmen + +Rome differed from [Greek city-states](/wiki/Greek_city-states 'Greek city-states') in allowing freed slaves to become citizens; any future children of a freedman were born free, with full rights of citizenship. After manumission, a slave who had belonged to a Roman citizen enjoyed active political freedom _(libertas)_, including the right to vote. His former master became his patron _([patronus](/wiki/Patronage_in_ancient_Rome 'Patronage in ancient Rome'))_: the two continued to have customary and legal obligations to each other. A freedman was not entitled to hold public office or the highest state priesthoods, but could play a [priestly role](/wiki/Augustales 'Augustales'). He could not marry a woman from a senatorial family, nor achieve legitimate senatorial rank himself, but during the early Empire, freedmen held key positions in the government bureaucracy, so much so that [Hadrian](/wiki/Hadrian 'Hadrian') limited their participation by law. The rise of successful freedmen---through political influence or wealth---is a characteristic of early Imperial society. The prosperity of a high-achieving group of freedmen is attested by [inscriptions throughout the Empire](https://commons.wikimedia.org/wiki/Category:Liberti_and_libertae_in_Ancient_Roman_inscriptions 'commons:Category:Liberti and libertae in Ancient Roman inscriptions'), and by their ownership of some of the most lavish houses at [Pompeii](/wiki/Pompeii 'Pompeii'). + +### Census rank + +See also: [Senate of the Roman Empire](/wiki/Senate_of_the_Roman_Empire 'Senate of the Roman Empire'), [Equestrian order](/wiki/Equestrian_order 'Equestrian order'), and [Decurion (administrative)]( 'Decurion (administrative)') + +The Latin word _ordo_ (plural _ordines_) is translated variously and inexactly into English as \"class, order, rank\". One purpose of the [Roman census](/wiki/Roman_census 'Roman census') was to determine the _ordo_ to which an individual belonged. The two highest _ordines_ in Rome were the senatorial and equestrian. Outside Rome, the [decurions]( 'Decurion (administrative)'), also known as _[curiales](/wiki/Curiales 'Curiales')_, were the top governing _ordo_ of an individual city. + +\"Senator\" was not itself an elected office in ancient Rome; an individual gained admission to the Senate after he had been elected to and served at least one term as an [executive magistrate](/wiki/Executive_magistrates_of_the_Roman_Empire 'Executive magistrates of the Roman Empire'). A senator also had to meet a minimum property requirement of 1 million _[sestertii](/wiki/Sestertii 'Sestertii')_. Not all men who qualified for the _ordo senatorius_ chose to take a Senate seat, which required [legal domicile]( 'Domicile (law)') at Rome. Emperors often filled vacancies in the 600-member body by appointment. A senator\'s son belonged to the _ordo senatorius_, but he had to qualify on his own merits for admission to the Senate. A senator could be removed for violating moral standards. + +In the time of Nero, senators were still primarily from [Italy]( 'Italy (Roman Empire)'), with some from the Iberian peninsula and southern France; men from the Greek-speaking provinces of the East began to be added under Vespasian. The first senator from the easternmost province, [Cappadocia]( 'Cappadocia (Roman province)'), was admitted under Marcus Aurelius. By the [Severan dynasty](/wiki/Severan_dynasty 'Severan dynasty') (193--235), Italians made up less than half the Senate. During the 3rd century, domicile at Rome became impractical, and inscriptions attest to senators who were active in politics and munificence in their homeland _(patria)_. + +Senators were the traditional governing class who rose through the _[cursus honorum](/wiki/Cursus_honorum 'Cursus honorum')_, the political career track, but equestrians often possessed greater wealth and political power. Membership in the equestrian order was based on property; in Rome\'s early days, _equites_ or knights had been distinguished by their ability to serve as mounted warriors, but cavalry service was a separate function in the Empire. A census valuation of 400,000 sesterces and three generations of free birth qualified a man as an equestrian. The census of 28 BC uncovered large numbers of men who qualified, and in 14 AD, a thousand equestrians were registered at [Cadiz](/wiki/Cadiz 'Cadiz') and [Padua](/wiki/Padua 'Padua') alone. Equestrians rose through a military career track _([tres militiae](/wiki/Tres_militiae 'Tres militiae'))_ to become highly placed [prefects](/wiki/Prefect 'Prefect') and [procurators]( 'Procurator (Roman)') within the Imperial administration. + +The rise of provincial men to the senatorial and equestrian orders is an aspect of social mobility in the early Empire. Roman aristocracy was based on competition, and unlike later [European nobility](/wiki/European_nobility 'European nobility'), a Roman family could not maintain its position merely through hereditary succession or having title to lands. Admission to the higher _ordines_ brought distinction and privileges, but also responsibilities. In antiquity, a city depended on its leading citizens to fund public works, events, and services _([munera]( 'Munera (ancient Rome)'))*. Maintaining one\'s rank required massive personal expenditures. Decurions were so vital for the functioning of cities that in the later Empire, as the ranks of the town councils became depleted, those who had risen to the Senate were encouraged to return to their hometowns, in an effort to sustain civic life. + +In the later Empire, the _[dignitas]( 'Dignitas (Roman concept)')* (\"worth, esteem\") that attended on senatorial or equestrian rank was refined further with titles such as _[vir illustris](/wiki/Vir_illustris 'Vir illustris')_ (\"illustrious man\"). The appellation _clarissimus_ (Greek _lamprotatos_) was used to designate the _[dignitas]( 'Dignitas (Roman concept)')* of certain senators and their immediate family, including women. \"Grades\" of equestrian status proliferated. + +#### Unequal justice + +As the republican principle of citizens\' equality under the law faded, the symbolic and social privileges of the upper classes led to an informal division of Roman society into those who had acquired greater honours _(honestiores)_ and humbler folk _(humiliores)_. In general, _honestiores_ were the members of the three higher \"orders,\" along with certain military officers. The granting of universal citizenship in 212 seems to have increased the competitive urge among the upper classes to have their superiority affirmed, particularly within the justice system. Sentencing depended on the judgment of the presiding official as to the relative \"worth\" _(dignitas)_ of the defendant: an _honestior_ could pay a fine for a crime for which an _humilior_ might receive a [scourging](/wiki/Scourging 'Scourging'). + +Execution, which was an infrequent legal penalty for free men under the Republic, could be quick and relatively painless for _honestiores_, while _humiliores_ might suffer the kinds of torturous death previously reserved for slaves, such as [crucifixion](/wiki/Crucifixion 'Crucifixion') and [condemnation to the beasts](/wiki/Damnatio_ad_bestias 'Damnatio ad bestias'). In the early Empire, those who converted to Christianity could lose their standing as _honestiores_, especially if they declined to fulfil religious responsibilities, and thus became subject to punishments that created the conditions of [martyrdom](/wiki/Christian_martyrs 'Christian martyrs'). + +## Government and military + +Main article: [Constitution of the Roman Empire](/wiki/Constitution_of_the_Roman_Empire 'Constitution of the Roman Empire') + +The three major elements of the Imperial state were the central government, the military, and the provincial government. The military established control of a territory through war, but after a city or people was brought under treaty, the mission turned to policing: protecting Roman citizens, agricultural fields, and religious sites. The Romans lacked sufficient manpower or resources to rule through force alone. [Cooperation with local elites]( 'Local government (ancient Roman)') was necessary to maintain order, collect information, and extract revenue. The Romans often exploited internal political divisions. + +Communities with demonstrated loyalty to Rome retained their own laws, could collect their own taxes locally, and in exceptional cases were exempt from Roman taxation. Legal privileges and relative independence incentivized compliance. Roman government was thus [limited](/wiki/Limited_government 'Limited government'), but efficient in its use of available resources. + +### Central government + +See also: [Roman emperor](/wiki/Roman_emperor 'Roman emperor') and [Senate of the Roman Empire](/wiki/Senate_of_the_Roman_Empire 'Senate of the Roman Empire') + +The [Imperial cult of ancient Rome]( 'Imperial cult (ancient Rome)') identified [emperors](/wiki/Roman_emperor 'Roman emperor') and some members of their families with [divinely sanctioned](/wiki/Divine_right_of_kings 'Divine right of kings') authority (_[auctoritas](/wiki/Auctoritas 'Auctoritas')_). The rite of [apotheosis](/wiki/Apotheosis 'Apotheosis') (also called _consecratio_) signified the deceased emperor\'s deification. The dominance of the emperor was based on the consolidation of powers from several republican offices. The emperor made himself the central religious authority as _[pontifex maximus](/wiki/Pontifex_maximus 'Pontifex maximus')_, and centralized the right to declare war, ratify treaties, and negotiate with foreign leaders. While these functions were clearly defined during the [Principate](/wiki/Principate 'Principate'), the emperor\'s powers over time became less constitutional and more monarchical, culminating in the [Dominate](/wiki/Dominate 'Dominate'). + +The emperor was the ultimate authority in policy- and decision-making, but in the early Principate, he was expected to be accessible and deal personally with official business and petitions. A bureaucracy formed around him only gradually. The Julio-Claudian emperors relied on an informal body of advisors that included not only senators and equestrians, but trusted slaves and freedmen. After Nero, the influence of the latter was regarded with suspicion, and the emperor\'s council _(consilium)_ became subject to official appointment for greater [transparency](/wiki/Open_government 'Open government'). Though the Senate took a lead in policy discussions until the end of the [Antonine dynasty](/wiki/Antonine_dynasty 'Antonine dynasty'), equestrians played an increasingly important role in the _consilium._ The women of the emperor\'s family often intervened directly in his decisions. + +Access to the emperor might be gained at the daily reception _(salutatio)_, a development of the traditional homage a client paid to his patron; public banquets hosted at the palace; and religious ceremonies. The common people who lacked this access could manifest their approval or displeasure as a group at [games](#Spectacles). By the 4th century, the Christian emperors became remote figureheads who issued general rulings, no longer responding to individual petitions. Although the Senate could do little short of assassination and open rebellion to contravene the will of the emperor, it retained its symbolic political centrality. The Senate legitimated the emperor\'s rule, and the emperor employed senators as legates _([legati](/wiki/Legatus 'Legatus'))_: generals, diplomats, and administrators. + +The practical source of an emperor\'s power and authority was the military. The [legionaries](/wiki/Legionary 'Legionary') were paid by the Imperial treasury, and swore an annual [oath of loyalty]( 'Sacramentum (oath)') to the emperor. Most emperors chose a successor, usually a close family member or [adopted](/wiki/Adoption_in_ancient_Rome 'Adoption in ancient Rome') heir. The new emperor had to seek a swift acknowledgement of his status and authority to stabilize the political landscape. No emperor could hope to survive without the allegiance of the [Praetorian Guard](/wiki/Praetorian_Guard 'Praetorian Guard') and the legions. To secure their loyalty, several emperors paid the _[donativum](/wiki/Donativum 'Donativum')_, a monetary reward. In theory, the Senate was entitled to choose the new emperor, but did so mindful of acclamation by the army or Praetorians. diff --git a/sample-files/roman-empire-2.md b/sample-files/roman-empire-2.md new file mode 100644 index 0000000..23a89ac --- /dev/null +++ b/sample-files/roman-empire-2.md @@ -0,0 +1,165 @@ +### Military + +Main articles: [Imperial Roman army](/wiki/Imperial_Roman_army 'Imperial Roman army') and [Structural history of the Roman military](/wiki/Structural_history_of_the_Roman_military 'Structural history of the Roman military') + +After the [Punic Wars](/wiki/Punic_Wars 'Punic Wars'), the Roman army comprised professional soldiers who volunteered for 20 years of active duty and five as reserves. The transition to a professional military began during the late Republic and was one of the many profound shifts away from republicanism, under which an army of [conscript citizens](/wiki/Conscripts 'Conscripts') defended the homeland against a specific threat. The Romans expanded their war machine by \"organizing the communities that they conquered in Italy into a system that generated huge reservoirs of manpower for their army.\" By Imperial times, military service was a full-time career. The pervasiveness of military garrisons throughout the Empire was a major influence in the process of [Romanization]( 'Romanization (cultural)'). + +The primary mission of the military of the early empire was to preserve the [Pax Romana](/wiki/Pax_Romana 'Pax Romana'). The three major divisions of the military were: + +- the garrison at Rome, comprising the [Praetorian Guard](/wiki/Praetorian_Guard 'Praetorian Guard'), the _[cohortes urbanae](/wiki/Cohortes_urbanae 'Cohortes urbanae')_ and the _[vigiles](/wiki/Vigiles 'Vigiles')_, who functioned as police and firefighters; +- the provincial army, comprising the [Roman legions](/wiki/Roman_legions 'Roman legions') and the auxiliaries provided by the provinces _([auxilia](/wiki/Auxilia 'Auxilia')_); +- the [navy](/wiki/Roman_navy 'Roman navy'). + +Through his military reforms, which included consolidating or disbanding units of questionable loyalty, Augustus regularized the legion. A legion was organized into ten [cohorts]( 'Cohort (military unit)'), each of which comprised six [centuries](/wiki/Centuria 'Centuria'), with a century further made up of ten squads _([contubernia](/wiki/Contubernium 'Contubernium'))_; the exact size of the Imperial legion, which was likely determined by [logistics](/wiki/Military_logistics 'Military logistics'), has been estimated to range from 4,800 to 5,280. After Germanic tribes wiped out three legions in the [Battle of the Teutoburg Forest](/wiki/Battle_of_the_Teutoburg_Forest 'Battle of the Teutoburg Forest') in 9 AD, the number of legions was increased from 25 to around 30. The army had about 300,000 soldiers in the 1st century, and under 400,000 in the 2nd, \"significantly smaller\" than the collective armed forces of the conquered territories. No more than 2% of adult males living in the Empire served in the Imperial army. Augustus also created the [Praetorian Guard](/wiki/Praetorian_Guard 'Praetorian Guard'): nine cohorts, ostensibly to maintain the public peace, which were garrisoned in Italy. Better paid than the legionaries, the Praetorians served only sixteen years. + +The _auxilia_ were recruited from among the non-citizens. Organized in smaller units of roughly cohort strength, they were paid less than the legionaries, and after 25 years of service were rewarded with [Roman citizenship](/wiki/Roman_citizenship 'Roman citizenship'), also extended to their sons. According to [Tacitus](/wiki/Tacitus 'Tacitus') there were roughly as many auxiliaries as there were legionaries---thus, around 125,000 men, implying approximately 250 auxiliary regiments. The [Roman cavalry](/wiki/Roman_cavalry 'Roman cavalry') of the earliest Empire were primarily from Celtic, Hispanic or Germanic areas. Several aspects of training and equipment derived from the Celts. + +The [Roman navy](/wiki/Roman_navy 'Roman navy') not only aided in the supply and transport of the legions but also in the protection of the [frontiers]( 'Limes (Roman Empire)') along the rivers [Rhine](/wiki/Rhine 'Rhine') and [Danube](/wiki/Danube 'Danube'). Another duty was protecting maritime trade against pirates. It patrolled the Mediterranean, parts of the [North Atlantic](/wiki/Atlantic 'Atlantic') coasts, and the [Black Sea](/wiki/Black_Sea 'Black Sea'). Nevertheless, the army was considered the senior and more prestigious branch. + +### Provincial government + +An annexed territory became a [Roman province](/wiki/Roman_province 'Roman province') in three steps: making a register of cities, taking a census, and surveying the land. Further government recordkeeping included births and deaths, real estate transactions, taxes, and juridical proceedings. In the 1st and 2nd centuries, the central government sent out around 160 officials annually to govern outside Italy. Among these officials were the [Roman governors](/wiki/Roman_governor 'Roman governor'): [magistrates elected at Rome](/wiki/Executive_magistrates_of_the_Roman_Empire 'Executive magistrates of the Roman Empire') who in the name of the [Roman people](/wiki/SPQR 'SPQR') governed [senatorial provinces](/wiki/Senatorial_province 'Senatorial province'); or governors, usually of equestrian rank, who held their _imperium_ on behalf of the emperor in [imperial provinces](/wiki/Imperial_province 'Imperial province'), most notably [Roman Egypt](/wiki/Roman_Egypt 'Roman Egypt'). A governor had to make himself accessible to the people he governed, but he could delegate various duties. His staff, however, was minimal: his official attendants _([apparitores](/wiki/Apparitor 'Apparitor'))_, including [lictors](/wiki/Lictor 'Lictor'), heralds, messengers, [scribes]( 'Scriba (ancient Rome)'), and bodyguards; [legates](/wiki/Legatus 'Legatus'), both civil and military, usually of equestrian rank; and friends who accompanied him unofficially. + +Other officials were appointed as supervisors of government finances. Separating fiscal responsibility from justice and administration was a reform of the Imperial era, to avoid provincial governors and [tax farmers]( 'Farm (revenue leasing)') exploiting local populations for personal gain. Equestrian [procurators]( 'Procurator (Roman)'), whose authority was originally \"extra-judicial and extra-constitutional,\" managed both state-owned property and the personal property of the emperor _([res privata](/wiki/Privatus 'Privatus'))_. Because Roman government officials were few, a provincial who needed help with a legal dispute or criminal case might seek out any Roman perceived to have some official capacity. + +### Law + +Main article: [Roman law](/wiki/Roman_law 'Roman law') + +Roman courts held [original jurisdiction](/wiki/Original_jurisdiction 'Original jurisdiction') over cases involving Roman citizens throughout the empire, but there were too few judicial functionaries to impose Roman law uniformly in the provinces. Most parts of the Eastern Empire already had well-established law codes and juridical procedures. Generally, it was Roman policy to respect the _mos regionis_ (\"regional tradition\" or \"law of the land\") and to regard local laws as a source of legal precedent and social stability. The compatibility of Roman and local law was thought to reflect an underlying _[ius gentium](/wiki/Ius_gentium 'Ius gentium')_, the \"law of nations\" or [international law](/wiki/International_law 'International law') regarded as common and customary. If provincial law conflicted with Roman law or custom, Roman courts heard [appeals](/wiki/Appellate_court 'Appellate court'), and the emperor held final decision-making authority. + +In the West, law had been administered on a highly localized or tribal basis, and [private property rights](/wiki/Private_property_rights 'Private property rights') may have been a novelty of the Roman era, particularly among [Celts](/wiki/Celts 'Celts'). Roman law facilitated the acquisition of wealth by a pro-Roman elite. The extension of universal citizenship to all free inhabitants of the Empire in 212 required the uniform application of Roman law, replacing local law codes that had applied to non-citizens. Diocletian\'s efforts to stabilize the Empire after the [Crisis of the Third Century](/wiki/Crisis_of_the_Third_Century 'Crisis of the Third Century') included two major compilations of law in four years, the _[Codex Gregorianus](/wiki/Codex_Gregorianus 'Codex Gregorianus')_ and the _[Codex Hermogenianus](/wiki/Codex_Hermogenianus 'Codex Hermogenianus')_, to guide provincial administrators in setting consistent legal standards. + +The pervasiveness of Roman law throughout Western Europe enormously influenced the Western legal tradition, reflected by continued use of [Latin legal terminology](/wiki/List_of_legal_Latin_terms 'List of legal Latin terms') in modern law. + +### Taxation + +Further information: [Taxation in ancient Rome](/wiki/Taxation_in_ancient_Rome 'Taxation in ancient Rome') + +Taxation under the Empire amounted to about 5% of its [gross product](/wiki/Roman_gross_domestic_product 'Roman gross domestic product'). The typical tax rate for individuals ranged from 2 to 5%. The tax code was \"bewildering\" in its complicated system of [direct](/wiki/Direct_taxation 'Direct taxation') and [indirect taxes](/wiki/Indirect_taxes 'Indirect taxes'), some paid in cash and some [in kind](/wiki/Barter 'Barter'). Taxes might be specific to a province, or kinds of properties such as [fisheries](/wiki/Fishery 'Fishery'); they might be temporary. Tax collection was justified by the need to maintain the military, and taxpayers sometimes got a refund if the army captured a surplus of booty. In-kind taxes were accepted from less-[monetized](/wiki/Monetization 'Monetization') areas, particularly those who could supply grain or goods to army camps. The primary source of direct tax revenue was individuals, who paid a [poll tax](/wiki/Tax_per_head 'Tax per head') and a tax on their land, construed as a tax on its produce or productive capacity. Tax obligations were determined by the census: each head of household provided a headcount of his household, as well as an accounting of his property. A major source of indirect-tax revenue was the _portoria_, customs and tolls on trade, including among provinces. Towards the end of his reign, Augustus instituted a 4% tax on the sale of slaves, which Nero shifted from the purchaser to the dealers, who responded by raising their prices. An owner who manumitted a slave paid a \"freedom tax\", calculated at 5% of value. An [inheritance tax](/wiki/Inheritance_tax 'Inheritance tax') of 5% was assessed when Roman citizens above a certain net worth left property to anyone outside their immediate family. Revenues from the estate tax and from an auction tax went towards the veterans\' pension fund _([aerarium militare](/wiki/Aerarium_militare 'Aerarium militare'))_. + +Low taxes helped the Roman aristocracy increase their wealth, which equalled or exceeded the revenues of the central government. An emperor sometimes replenished his treasury by confiscating the estates of the \"super-rich\", but in the later period, the [resistance](/wiki/Tax_resistance 'Tax resistance') of the wealthy to paying taxes was one of the factors contributing to the collapse of the Empire. + +## Economy + +Main article: [Roman economy](/wiki/Roman_economy 'Roman economy') + +The Empire is best thought of as a network of regional economies, based on a form of \"political capitalism\" in which the state regulated commerce to assure its own revenues. Economic growth, though not comparable to modern economies, was greater than that of most other societies prior to [industrialization](/wiki/Industrial_Revolution 'Industrial Revolution'). Territorial conquests permitted a large-scale reorganization of [land use](/wiki/Land_use 'Land use') that resulted in agricultural surplus and specialization, particularly in north Africa. Some cities were known for particular industries. The scale of urban building indicates a significant construction industry. Papyri preserve complex accounting methods that suggest elements of [economic rationalism](/wiki/Economic_rationalism 'Economic rationalism'), and the Empire was highly monetized. Although the means of communication and transport were limited in antiquity, transportation in the 1st and 2nd centuries expanded greatly, and trade routes connected regional economies. The [supply contracts for the army](/wiki/Economics_of_the_Roman_army 'Economics of the Roman army') drew on local suppliers near the base _([castrum](/wiki/Castrum 'Castrum'))_, throughout the province, and across provincial borders. [Economic historians](/wiki/Economic_history 'Economic history') vary in their calculations of the gross domestic product during the Principate. In the sample years of 14, 100, and 150 AD, estimates of per capita GDP range from 166 to 380 _[HS](/wiki/Sestertius 'Sestertius')_. The GDP per capita of [Italy]( 'Italia (Roman Empire)') is estimated as 40 to 66% higher than in the rest of the Empire, due to tax transfers from the provinces and the concentration of elite income. + +Economic dynamism resulted in social mobility. Although aristocratic values permeated traditional elite society, wealth requirements for [rank](#Census_rank) indicate a strong tendency towards [plutocracy](/wiki/Plutocracy 'Plutocracy'). Prestige could be obtained through investing one\'s wealth in grand estates or townhouses, luxury items, [public entertainments](#Spectacles), funerary monuments, and [religious dedications](/wiki/Votum 'Votum'). Guilds _([collegia](/wiki/Collegium 'Collegium'))_ and corporations _(corpora)_ provided support for individuals to succeed through networking. \"There can be little doubt that the lower classes of \... provincial towns of the Roman Empire enjoyed a high [standard of living](/wiki/Standard_of_living 'Standard of living') not equaled again in Western Europe until the 19th century\". Households in the top 1.5% of [income distribution](/wiki/Income_distribution 'Income distribution') captured about 20% of income. The \"vast majority\" produced more than half of the total income, but lived near [subsistence](/wiki/Subsistence 'Subsistence'). + +### Currency and banking + +See also: [Roman currency](/wiki/Roman_currency 'Roman currency') and [Roman finance](/wiki/Roman_finance 'Roman finance') + +The early Empire was monetized to a near-universal extent, using money as a way to express [prices](/wiki/Price 'Price') and [debts](/wiki/Debt 'Debt'). The _[sestertius](/wiki/Sestertius 'Sestertius')_ (English \"sesterces\", symbolized as _HS_) was the basic unit of reckoning value into the 4th century, though the silver _[denarius](/wiki/Denarius 'Denarius')_, worth four sesterces, was also used beginning in the [Severan dynasty](/wiki/Severan_dynasty 'Severan dynasty'). The smallest coin commonly circulated was the bronze _[as]( 'As (Roman coin)')*, one-tenth _denarius_. [Bullion](/wiki/Bullion 'Bullion') and [ingots](/wiki/Ingot 'Ingot') seem not to have counted as _pecunia_ (\"money\") and were used only on the frontiers. Romans in the first and second centuries counted coins, rather than weighing them---an indication that the coin was valued on its face. This tendency towards [fiat money](/wiki/Fiat_money 'Fiat money') led to the [debasement](/wiki/Debasement 'Debasement') of Roman coinage in the later Empire. The standardization of money throughout the Empire promoted trade and [market integration](/wiki/Market_integration 'Market integration'). The high amount of metal coinage in circulation increased the [money supply](/wiki/Money_supply 'Money supply') for trading or saving. Rome had no [central bank](/wiki/Central_bank 'Central bank'), and regulation of the banking system was minimal. Banks of classical antiquity typically kept [less in reserves](/wiki/Fractional_reserve_banking 'Fractional reserve banking') than the full total of customers\' deposits. A typical bank had fairly limited [capital](/wiki/Financial_capital 'Financial capital'), and often only one principal. [Seneca](/wiki/Seneca_the_Younger 'Seneca the Younger') assumes that anyone involved in [Roman commerce](/wiki/Roman_commerce 'Roman commerce') needs access to [credit]( 'Credit (finance)'). A professional [deposit](/wiki/Deposit_account 'Deposit account') banker received and held deposits for a fixed or indefinite term, and lent money to third parties. The senatorial elite were involved heavily in private lending, both as creditors and borrowers. The holder of a debt could use it as a means of payment by transferring it to another party, without cash changing hands. Although it has sometimes been thought that ancient Rome lacked [documentary transactions](/wiki/Negotiable_instrument 'Negotiable instrument'), the system of banks throughout the Empire permitted the exchange of large sums without physically transferring coins, in part because of the risks of moving large amounts of cash. Only one serious credit shortage is known to have occurred in the early Empire, in 33 AD; generally, available capital exceeded the amount needed by borrowers. The central government itself did not borrow money, and without [public debt](/wiki/Public_debt 'Public debt') had to fund [deficits](/wiki/Government_budget_balance 'Government budget balance') from cash reserves. + +Emperors of the [Antonine](/wiki/Antonine_dynasty 'Antonine dynasty') and [Severan](/wiki/Severan_dynasty 'Severan dynasty') dynasties debased the currency, particularly the _denarius_, under the pressures of meeting military payrolls. Sudden inflation under [Commodus](/wiki/Commodus 'Commodus') damaged the credit market. In the mid-200s, the supply of [specie](/wiki/Bullion_coin 'Bullion coin') contracted sharply. Conditions during the [Crisis of the Third Century](/wiki/Crisis_of_the_Third_Century 'Crisis of the Third Century')---such as reductions in long-distance trade, disruption of mining operations, and the physical transfer of gold coinage outside the empire by invading enemies---greatly diminished the money supply and the banking sector. Although Roman coinage had long been fiat money or [fiduciary currency](/wiki/Fiduciary_currency 'Fiduciary currency'), general economic anxieties came to a head under [Aurelian](/wiki/Aurelian 'Aurelian'), and bankers lost confidence in coins. Despite [Diocletian](/wiki/Diocletian 'Diocletian')\'s introduction of the gold _[solidus]( 'Solidus (coin)')\_ and monetary reforms, the credit market of the Empire never recovered its former robustness. + +### Mining and metallurgy + +Main articles: [Mining in ancient Rome](/wiki/Mining_in_ancient_Rome 'Mining in ancient Rome') and [Roman metallurgy](/wiki/Roman_metallurgy 'Roman metallurgy') + +The main mining regions of the Empire were the Iberian Peninsula (gold, silver, copper, tin, lead); Gaul (gold, silver, iron); Britain (mainly iron, lead, tin), the [Danubian provinces](/wiki/Danubian_provinces 'Danubian provinces') (gold, iron); [Macedonia]( 'Macedonia (Roman province)') and [Thrace](/wiki/Thracia 'Thracia') (gold, silver); and Asia Minor (gold, silver, iron, tin). Intensive large-scale mining---of alluvial deposits, and by means of [open-cast mining](/wiki/Open-cast_mining 'Open-cast mining') and [underground mining](/wiki/Underground_mining 'Underground mining')---took place from the reign of Augustus up to the early 3rd century, when the instability of the Empire disrupted production. + +[Hydraulic mining](/wiki/Hydraulic_mining 'Hydraulic mining') allowed [base](/wiki/Base_metal 'Base metal') and [precious metals](/wiki/Precious_metal 'Precious metal') to be extracted on a proto-industrial scale. The total annual iron output is estimated at 82,500 [tonnes](/wiki/Tonnes 'Tonnes'). Copper and lead production levels were unmatched until the [Industrial Revolution](/wiki/Industrial_Revolution 'Industrial Revolution'). At its peak around the mid-2nd century, the Roman silver stock is estimated at 10,000 t, five to ten times larger than the combined silver mass of [medieval Europe](/wiki/Early_Middle_Ages 'Early Middle Ages') and the [Caliphate](/wiki/Abbasid_Caliphate 'Abbasid Caliphate') around 800 AD. As an indication of the scale of Roman metal production, lead pollution in the [Greenland ice sheet](/wiki/Greenland_ice_sheet 'Greenland ice sheet') quadrupled over prehistoric levels during the Imperial era and dropped thereafter. + +### Transportation and communication + +Further information: [Cursus publicus](/wiki/Cursus_publicus 'Cursus publicus') + +The Empire completely encircled the Mediterranean, which they called \"our sea\" _([mare nostrum](/wiki/Mare_nostrum 'Mare nostrum'))_. Roman sailing vessels navigated the Mediterranean as well as major rivers. Transport by water was preferred where possible, as moving commodities by land was more difficult. Vehicles, wheels, and ships indicate the existence of a great number of skilled woodworkers. + +Land transport utilized the advanced system of [Roman roads](/wiki/Roman_roads 'Roman roads'), called \"_viae_\". These roads were primarily built for military purposes, but also served commercial ends. The in-kind taxes paid by communities included the provision of personnel, animals, or vehicles for the _[cursus publicus](/wiki/Cursus_publicus 'Cursus publicus')_, the state mail and transport service established by Augustus. Relay stations were located along the roads every seven to twelve [Roman miles](/wiki/Roman_mile 'Roman mile'), and tended to grow into villages or trading posts. A _[mansio](/wiki/Mansio 'Mansio')_ (plural _mansiones_) was a privately run service station franchised by the imperial bureaucracy for the _cursus publicus_. The distance between _mansiones_ was determined by how far a wagon could travel in a day. Carts were usually pulled by mules, travelling about 4 mph. + +### Trade and commodities + +See also: [Roman commerce](/wiki/Roman_commerce 'Roman commerce'), [Indo-Roman trade relations](/wiki/Indo-Roman_trade_relations 'Indo-Roman trade relations'), and [Sino-Roman relations](/wiki/Sino-Roman_relations 'Sino-Roman relations') + +Roman provinces traded among themselves, but trade extended outside the frontiers to regions as far away as [China](/wiki/Ancient_China 'Ancient China') and [India](/wiki/Gupta_Empire 'Gupta Empire'). Chinese trade was mostly conducted overland through middle men along the [Silk Road](/wiki/Silk_Road 'Silk Road'); Indian trade also occurred by sea from [Egyptian](/wiki/Roman_Egypt 'Roman Egypt') ports. The main [commodity](/wiki/Commodity 'Commodity') was grain. Also traded were olive oil, foodstuffs, _[garum](/wiki/Garum 'Garum')_ ([fish sauce](/wiki/Fish_sauce 'Fish sauce')), slaves, ore and manufactured metal objects, fibres and textiles, timber, [pottery](/wiki/Ancient_Roman_pottery 'Ancient Roman pottery'), [glassware](/wiki/Roman_glass 'Roman glass'), marble, [papyrus](/wiki/Papyrus 'Papyrus'), spices and _[materia medica](/wiki/Materia_medica 'Materia medica')_, ivory, pearls, and gemstones. Though most provinces could produce wine, [regional varietals](/wiki/Ancient_Rome_and_wine 'Ancient Rome and wine') were desirable and wine was a central trade good. + +### Labour and occupations + +Inscriptions record 268 different occupations in Rome and 85 in Pompeii. Professional associations or trade guilds _(collegia)_ are attested for a wide range of occupations, some quite specialized. + +Work performed by slaves falls into five general categories: domestic, with epitaphs recording at least 55 different household jobs; [imperial or public service](/wiki/Slavery_in_ancient_Rome#Servus_publicus 'Slavery in ancient Rome'); urban crafts and services; agriculture; and mining. Convicts provided much of the labour in the mines or quarries, where conditions were notoriously brutal. In practice, there was little division of labour between slave and free, and most workers were illiterate and without special skills. The greatest number of common labourers were employed in agriculture: in Italian industrial farming _([latifundia](/wiki/Latifundia 'Latifundia'))_, these may have been mostly slaves, but elsewhere slave farm labour was probably less important. + +Textile and clothing production was a major source of employment. Both textiles and finished garments were traded and products were often named for peoples or towns, like a [fashion \"label\"](/wiki/Fashion_brand 'Fashion brand'). Better ready-to-wear was exported by local businessmen (_negotiatores_ or _mercatores_). Finished garments might be retailed by their sales agents, by _vestiarii_ (clothing dealers), or peddled by itinerant merchants. The [fullers](/wiki/Fulling 'Fulling') (_[fullones](/wiki/Fullonica 'Fullonica')_) and dye workers (_coloratores_) had their own guilds. _Centonarii_ were guild workers who specialized in textile production and the recycling of old clothes into [pieced goods](/wiki/Patchwork 'Patchwork'). + +## Architecture and engineering + +Main articles: [Ancient Roman architecture](/wiki/Ancient_Roman_architecture 'Ancient Roman architecture'), [Roman engineering](/wiki/Roman_engineering 'Roman engineering'), and [Roman technology](/wiki/Roman_technology 'Roman technology') + +The chief [Roman contributions to architecture](/wiki/Ancient_Roman_architecture 'Ancient Roman architecture') were the [arch](/wiki/Arch 'Arch'), [vault]( 'Vault (architecture)') and [dome](/wiki/Dome 'Dome'). Some Roman structures still stand today, due in part to sophisticated methods of making cements and [concrete](/wiki/Roman_concrete 'Roman concrete'). [Roman temples](/wiki/Roman_temple 'Roman temple') developed [Etruscan](/wiki/Etruscan_architecture 'Etruscan architecture') and Greek forms, with some distinctive elements. [Roman roads](/wiki/Roman_roads 'Roman roads') are considered the most advanced built until the early 19th century. The system of roadways facilitated military policing, communications, and trade, and were resistant to floods and other environmental hazards. Some remained usable for over a thousand years. + +[Roman bridges](/wiki/Roman_bridges 'Roman bridges') were among the first large and lasting bridges, built from stone (and in most cases concrete) with the arch as the basic structure. The largest Roman bridge was [Trajan\'s bridge](/wiki/Trajan%27s_bridge "Trajan's bridge") over the lower Danube, constructed by [Apollodorus of Damascus](/wiki/Apollodorus_of_Damascus 'Apollodorus of Damascus'), which remained for over a millennium the longest bridge to have been built. The Romans built many [dams and reservoirs](/wiki/List_of_Roman_dams_and_reservoirs 'List of Roman dams and reservoirs') for water collection, such as the [Subiaco Dams](/wiki/Subiaco_Dams 'Subiaco Dams'), two of which fed the [Anio Novus](/wiki/Anio_Novus 'Anio Novus'), one of the largest aqueducts of Rome. + +The Romans constructed numerous [aqueducts](/wiki/Roman_aqueduct 'Roman aqueduct'). _[De aquaeductu](/wiki/De_aquaeductu 'De aquaeductu')_, a treatise by [Frontinus](/wiki/Frontinus 'Frontinus'), who served as [water commissioner](/wiki/Curator_Aquarum 'Curator Aquarum'), reflects the administrative importance placed on the water supply. Masonry channels carried water along a precise [gradient]( 'Grade (slope)'), using [gravity](/wiki/Gravity 'Gravity') alone. It was then collected in tanks and fed through pipes to public fountains, baths, [toilets](/wiki/Sanitation_in_ancient_Rome 'Sanitation in ancient Rome'), or industrial sites. The main aqueducts in Rome were the [Aqua Claudia](/wiki/Aqua_Claudia 'Aqua Claudia') and the [Aqua Marcia](/wiki/Aqua_Marcia 'Aqua Marcia'). The complex system built to supply Constantinople had its most distant supply drawn from over 120 km away along a route of more than 336 km. Roman aqueducts were built to remarkably fine [tolerance](/wiki/Engineering_tolerance 'Engineering tolerance'), and to a technological standard not equalled until modern times. The Romans also used aqueducts in their extensive mining operations across the empire. + +[Insulated glazing](/wiki/Insulated_glazing 'Insulated glazing') (or \"double glazing\") was used in the construction of [public baths](/wiki/Thermae 'Thermae'). Elite housing in cooler climates might have [hypocausts](/wiki/Hypocaust 'Hypocaust'), a form of central heating. The Romans were the first culture to assemble all essential components of the much later [steam engine](/wiki/Steam_engine 'Steam engine'): the crank and connecting rod system, [Hero](/wiki/Hero_of_Alexandria 'Hero of Alexandria')\'s [aeolipile](/wiki/Aeolipile 'Aeolipile') (generating steam power), the [cylinder](/wiki/Pneumatic_cylinder 'Pneumatic cylinder') and [piston](/wiki/Piston 'Piston') (in metal force pumps), non-return [valves](/wiki/Valves 'Valves') (in water pumps), and [gearing](/wiki/Gear_train 'Gear train') (in water mills and clocks). + +## Daily life + +Main article: [Culture of ancient Rome](/wiki/Culture_of_ancient_Rome 'Culture of ancient Rome') + +### City and country + +The city was viewed as fostering civilization by being \"properly designed, ordered, and adorned.\" Augustus undertook a vast building programme in Rome, supported public displays of art that expressed imperial ideology, and [reorganized the city](/wiki/14_regions_of_Augustan_Rome '14 regions of Augustan Rome') into neighbourhoods _([vici](/wiki/Vicus 'Vicus'))_ administered at the local level with police and firefighting services. A focus of Augustan monumental architecture was the [Campus Martius](/wiki/Campus_Martius 'Campus Martius'), an open area outside the city centre: the Altar of Augustan Peace ([_[Ara Pacis Augustae](/wiki/Ara_Pacis_Augustae 'Ara Pacis Augustae')_]) was located there, as was [an obelisk](/wiki/Obelisk_of_Montecitorio 'Obelisk of Montecitorio') imported from Egypt that formed the pointer _([gnomon](/wiki/Gnomon 'Gnomon'))_ of a [horologium](/wiki/Solarium_Augusti 'Solarium Augusti'). With its public gardens, the Campus was among the most attractive places in Rome to visit. + +City planning and urban lifestyles was influenced by the Greeks early on, and in the Eastern Empire, Roman rule shaped the development of cities that already had a strong Hellenistic character. Cities such as [Athens](/wiki/Ancient_Athens 'Ancient Athens'), [Aphrodisias](/wiki/Aphrodisias 'Aphrodisias'), [Ephesus](/wiki/Ephesus 'Ephesus') and [Gerasa](/wiki/Gerasa 'Gerasa') tailored city planning and architecture to imperial ideals, while expressing their individual identity and regional preeminence. In areas inhabited by Celtic-speaking peoples, Rome encouraged the development of urban centres with stone temples, forums, monumental fountains, and amphitheatres, often on or near the sites of preexisting walled settlements known as _[oppida](/wiki/Oppidum 'Oppidum')_. Urbanization in Roman Africa expanded on Greek and Punic coastal cities. + +The network of cities (_[coloniae]( 'Colonia (Roman)')_, _[municipia](/wiki/Municipium 'Municipium')_, _[civitates](/wiki/Civitas 'Civitas')_ or in Greek terms _[poleis](/wiki/Polis 'Polis')\_) was a primary cohesive force during the Pax Romana. Romans of the 1st and 2nd centuries were encouraged to \"inculcate the habits of peacetime\". As the classicist [Clifford Ando](/wiki/Clifford_Ando 'Clifford Ando') noted: + +> Most of the cultural [appurtenances](https://en.wiktionary.org/wiki/appurtenance 'wikt:appurtenance') popularly associated with imperial culture---[public cult](/wiki/Religion_in_ancient_Rome 'Religion in ancient Rome') and its [games](/wiki/Ludi 'Ludi') and [civic banquets](/wiki/Epulones 'Epulones'), competitions for artists, speakers, and athletes, as well as the funding of the great majority of public buildings and public display of art---were financed by private individuals, whose expenditures in this regard helped to justify their economic power and legal and provincial privileges. + +In the city of Rome, most people lived in multistory apartment buildings _([insulae]( 'Insula (building)'))_ that were often squalid firetraps. Public facilities---such as baths _([thermae](/wiki/Thermae 'Thermae'))_, toilets with running water _(latrinae)_, basins or elaborate fountains _([nymphea](/wiki/Nymphaeum 'Nymphaeum'))\_ delivering fresh water, and large-scale entertainments such as [chariot races](/wiki/Chariot_races 'Chariot races') and [gladiator combat](/wiki/Gladiator 'Gladiator')---were aimed primarily at the common people. Similar facilities were constructed in cities throughout the Empire, and some of the best-preserved Roman structures are in Spain, southern France, and northern Africa. + +The public baths served hygienic, social and cultural functions. Bathing was the focus of daily socializing. Roman baths were distinguished by a series of rooms that offered communal bathing in three temperatures, with amenities that might include an [exercise room](/wiki/Palaestra 'Palaestra'), [sauna](/wiki/Sudatorium 'Sudatorium'), [exfoliation]( 'Exfoliation (cosmetology)') spa, [ball court](/wiki/Sphaeristerium 'Sphaeristerium'), or outdoor swimming pool. Baths had [hypocaust](/wiki/Hypocaust 'Hypocaust') heating: the floors were suspended over hot-air channels. Public baths were part of urban culture [throughout the provinces](/wiki/List_of_Roman_public_baths 'List of Roman public baths'), but in the late 4th century, individual tubs began to replace communal bathing. Christians were advised to go to the baths only for hygiene. + +Rich families from Rome usually had two or more houses: a townhouse _([domus](/wiki/Domus 'Domus')_) and at least one luxury home _([villa](/wiki/Roman_villa 'Roman villa'))_ outside the city. The _domus_ was a privately owned single-family house, and might be furnished with a private bath _(balneum)_ but it was not a place to retreat from public life. Although some neighbourhoods show a higher concentration of such houses, they were not segregated enclaves. The _domus_ was meant to be visible and accessible. The atrium served as a reception hall in which the _[paterfamilias](/wiki/Paterfamilias 'Paterfamilias')_ (head of household) met with [clients](/wiki/Patronage_in_ancient_Rome 'Patronage in ancient Rome') every morning. It was a centre of family religious rites, containing a [shrine](/wiki/Lararium 'Lararium') and [images of family ancestors](/wiki/Roman_funerals_and_burial#Funerary_art 'Roman funerals and burial'). The houses were located on busy public roads, and ground-level spaces were often rented out as shops _([tabernae](/wiki/Taberna 'Taberna'))_. In addition to a kitchen garden---windowboxes might substitute in the _insulae_---townhouses typically enclosed a [peristyle](/wiki/Peristyle 'Peristyle') garden. + +The villa by contrast was an escape from the city, and in literature represents a lifestyle that balances intellectual and artistic interests _([otium](/wiki/Otium 'Otium'))_ with an appreciation of nature and agriculture. Ideally a villa commanded a view or vista, carefully framed by the architectural design. It might be located on a working estate, or in a \"resort town\" on the seacoast. + +Augustus\' programme of urban renewal, and the growth of Rome\'s population to as many as one million, was accompanied by nostalgia for rural life. Poetry idealized the lives of farmers and shepherds. Interior decorating often featured painted gardens, fountains, landscapes, vegetative ornament, and animals, rendered accurately enough to be identified by species. On a more practical level, the central government took an active interest in supporting [agriculture](/wiki/Agriculture_in_ancient_Rome 'Agriculture in ancient Rome'). Producing food was the priority of land use. Larger farms _([latifundia](/wiki/Latifundium 'Latifundium'))_ achieved an [economy of scale](/wiki/Economy_of_scale 'Economy of scale') that sustained urban life. Small farmers benefited from the development of local markets in towns and trade centres. Agricultural techniques such as [crop rotation](/wiki/Crop_rotation 'Crop rotation') and [selective breeding](/wiki/Selective_breeding 'Selective breeding') were disseminated throughout the Empire, and new crops were introduced from one province to another. + +Maintaining an affordable food supply to the city of Rome had become a major political issue in the late Republic, when the state began to provide a grain dole ([Cura Annonae](/wiki/Cura_Annonae 'Cura Annonae')) to citizens who registered for it (about 200,000--250,000 adult males in Rome). The dole cost at least 15% of state revenues, but improved living conditions among the lower classes, and subsidized the rich by allowing workers to spend more of their earnings on the wine and olive oil produced on estates. The grain dole also had symbolic value: it affirmed the emperor\'s position as universal benefactor, and the right of citizens to share in \"the fruits of conquest\". The _annona_, public facilities, and spectacular entertainments mitigated the otherwise dreary living conditions of lower-class Romans, and kept social unrest in check. The satirist [Juvenal](/wiki/Juvenal 'Juvenal'), however, saw \"[bread and circuses](/wiki/Bread_and_circuses 'Bread and circuses')\" _(panem et circenses)_ as emblematic of the loss of republican political liberty: + +> The public has long since cast off its cares: the people that once bestowed commands, consulships, legions and all else, now meddles no more and longs eagerly for just two things: bread and circuses. + +### Health and disease + +Further information: [Disease in Imperial Rome](/wiki/Disease_in_Imperial_Rome 'Disease in Imperial Rome'), [Antonine plague](/wiki/Antonine_plague 'Antonine plague'), and [Plague of Cyprian](/wiki/Plague_of_Cyprian 'Plague of Cyprian') + +[Epidemics](/wiki/Epidemics 'Epidemics') were common in the ancient world, and occasional [pandemics](/wiki/Pandemic 'Pandemic') in the Empire killed millions. The Roman population was unhealthy. About 20 percent---a large percentage by ancient standards---lived in cities, Rome being the largest. The cities were a \"demographic sink\": the death rate exceeded the birth rate and constant immigration was necessary to maintain the population. Average lifespan is estimated at the mid-twenties, and perhaps more than half of children died before reaching adulthood. Dense urban populations and [poor sanitation](/wiki/Sanitation_in_ancient_Rome 'Sanitation in ancient Rome') contributed to disease. Land and sea connections facilitated and sped the transfer of infectious diseases across the empire\'s territories. The rich were not immune; only two of emperor Marcus Aurelius\'s fourteen children are known to have reached adulthood. + +The importance of a good diet to health was recognized by medical writers such as [Galen](/wiki/Galen 'Galen') (2nd century). Views on nutrition were influenced by beliefs like [humoral theory](/wiki/Humoral_theory 'Humoral theory'). A good indicator of nutrition and disease burden is average height: the average Roman was shorter in stature than the population of pre-Roman Italian societies and medieval Europe. + +### Food and dining + +Main article: [Food and dining in the Roman Empire](/wiki/Food_and_dining_in_the_Roman_Empire 'Food and dining in the Roman Empire') + +See also: [Ancient Roman cuisine](/wiki/Ancient_Roman_cuisine 'Ancient Roman cuisine') and [Ancient Rome and wine](/wiki/Ancient_Rome_and_wine 'Ancient Rome and wine') + +Most apartments in Rome lacked kitchens, though a charcoal [brazier](/wiki/Brazier 'Brazier') could be used for rudimentary cookery. Prepared food was sold at pubs and bars, inns, and food stalls _([tabernae](/wiki/Taberna 'Taberna'), cauponae, [popinae](/wiki/Popina 'Popina'), [thermopolia](/wiki/Thermopolium 'Thermopolium'))_. [Carryout](/wiki/Carryout 'Carryout') and restaurants were for the lower classes; [fine dining](/wiki/Fine_dining 'Fine dining') appeared only at dinner parties in wealthy homes with a [chef](/wiki/Chef 'Chef') _(archimagirus)_ and kitchen staff, or banquets hosted by social clubs _([collegia]( 'Collegium (ancient Rome)'))*. + +Most Romans consumed at least 70% of their daily [calories](/wiki/Calorie 'Calorie') in the form of cereals and [legumes](/wiki/Legumes 'Legumes'). _[Puls]( 'Puls (food)')_ (pottage) was considered the food of the Romans, and could be elaborated to produce dishes similar to [polenta](/wiki/Polenta 'Polenta') or [risotto](/wiki/Risotto 'Risotto'). Urban populations and the military preferred bread. By the reign of [Aurelian](/wiki/Aurelian 'Aurelian'), the state had begun to distribute the \_annona_ as a daily ration of bread baked in state factories, and added [olive oil](/wiki/Olive_oil 'Olive oil'), wine, and pork to the dole. + +Roman literature focuses on the dining habits of the upper classes, for whom the evening meal _([cena](/wiki/Cena 'Cena'))_ had important social functions. Guests were entertained in a finely decorated dining room _([triclinium](/wiki/Triclinium 'Triclinium'))_ furnished with couches. By the late Republic, women dined, reclined, and drank wine along with men. The poet Martial describes a dinner, beginning with the _gustatio_ (\"tasting\" or \"appetizer\") salad. The main course was [kid](/wiki/Goat_meat 'Goat meat'), beans, greens, a chicken, and leftover ham, followed by a dessert of fruit and wine. Roman \"[foodies](/wiki/Foodie 'Foodie')\" indulged in [wild game](/wiki/Wild_game 'Wild game'), [fowl](/wiki/Fowl 'Fowl') such as [peacock](/wiki/Peacock 'Peacock') and [flamingo](/wiki/Flamingo 'Flamingo'), large fish ([mullet]( 'Mullet (fish)') was especially prized), and [shellfish](/wiki/Shellfish 'Shellfish'). Luxury ingredients were imported from the far reaches of empire. A book-length collection of Roman recipes is attributed to [Apicius](/wiki/Apicius 'Apicius'), a name for several figures in antiquity that became synonymous with \"[gourmet](/wiki/Gourmet 'Gourmet').\" + +Refined cuisine could be moralized as a sign of either civilized progress or decadent decline. Most often, because of the importance of landowning in Roman culture, produce---cereals, legumes, vegetables, and fruit---were considered more civilized foods than meat. The [Mediterranean staples](/wiki/Mediterranean_diet 'Mediterranean diet') of [bread](/wiki/Sacramental_bread 'Sacramental bread'), [wine](/wiki/Sacramental_wine 'Sacramental wine'), and [oil](/wiki/Chrism 'Chrism') were [sacralized](/wiki/Sanctification 'Sanctification') by Roman Christianity, while Germanic meat consumption became a mark of [paganism](/wiki/Germanic_paganism 'Germanic paganism'). Some philosophers and Christians resisted the demands of the body and the pleasures of food, and adopted [fasting](/wiki/Fasting 'Fasting') as an ideal. Food became simpler in general as urban life in the West diminished and trade routes were disrupted; the Church formally discouraged [gluttony](/wiki/Gluttony 'Gluttony'), and hunting and [pastoralism](/wiki/Pastoralism 'Pastoralism') were seen as simple and virtuous. + +### Spectacles + +See also: [Ludi](/wiki/Ludi 'Ludi'), [Chariot racing](/wiki/Chariot_racing 'Chariot racing'), and [Recitationes](/wiki/Recitationes 'Recitationes') + +When [Juvenal](/wiki/Juvenal 'Juvenal') complained that the Roman people had exchanged their political liberty for \"bread and circuses\", he was referring to the state-provided grain dole and the _circenses_, events held in the entertainment venue called a _[circus]( 'Circus (building)')_. The largest such venue in Rome was the [Circus Maximus](/wiki/Circus_Maximus 'Circus Maximus'), the setting of [horse races](/wiki/Horse_racing 'Horse racing'), [chariot races](/wiki/Chariot_races 'Chariot races'), the equestrian [Troy Game](/wiki/Lusus_Troiae 'Lusus Troiae'), staged beast hunts _([venationes](/wiki/Venatio 'Venatio'))_, athletic contests, [gladiator combat](/wiki/Gladiator 'Gladiator'), and [historical re-enactments](/wiki/Historical_re-enactment 'Historical re-enactment'). From earliest times, several [religious festivals](/wiki/Roman_festivals 'Roman festivals') had featured games _([ludi](/wiki/Ludi 'Ludi'))_, primarily horse and chariot races _(ludi circenses)\_. The races retained religious significance in connection with agriculture, [initiation](/wiki/Initiation_ritual 'Initiation ritual'), and the cycle of birth and death. + +Under Augustus, public entertainments were presented on 77 days of the year; by the reign of Marcus Aurelius, this had expanded to 135. Circus games were preceded by an elaborate parade (_[pompa circensis](/wiki/Pompa_circensis 'Pompa circensis')_) that ended at the venue. Competitive events were held also in smaller venues such as the [amphitheatre](/wiki/Roman_amphitheater 'Roman amphitheater'), which became the characteristic Roman spectacle venue, and stadium. Greek-style athletics included [footraces]( 'Stadion (running race)'), [boxing](/wiki/Ancient_Greek_boxing 'Ancient Greek boxing'), [wrestling](/wiki/Greek_wrestling 'Greek wrestling'), and the [pancratium](/wiki/Pankration 'Pankration'). Aquatic displays, such as the mock sea battle _([naumachia](/wiki/Naumachia 'Naumachia'))_ and a form of \"water ballet\", were presented in engineered pools. State-supported [theatrical events](#Performing_arts) _([ludi scaenici](/wiki/Ludi_scaenici 'Ludi scaenici'))_ took place on temple steps or in grand stone theatres, or in the smaller enclosed theatre called an _[odeon]( 'Odeon (building)')\_. + +Circuses were the largest structure regularly built in the Roman world. The Flavian Amphitheatre, better known as the [Colosseum](/wiki/Colosseum 'Colosseum'), became the regular arena for blood sports in Rome. Many [Roman amphitheatres](/wiki/List_of_Roman_amphitheatres 'List of Roman amphitheatres'), [circuses]( 'Circus (building)') and [theatres]( 'Roman theatre (structure)') built in cities outside Italy are visible as ruins today. The local ruling elite were responsible for sponsoring spectacles and arena events, which both enhanced their status and drained their resources. The physical arrangement of the amphitheatre represented the order of Roman society: the emperor in his opulent box; senators and equestrians in reserved advantageous seats; women seated at a remove from the action; slaves given the worst places, and everybody else in-between. The crowd could call for an outcome by booing or cheering, but the emperor had the final say. Spectacles could quickly become sites of social and political protest, and emperors sometimes had to deploy force to put down crowd unrest, most notoriously at the [Nika riots](/wiki/Nika_riots 'Nika riots') in 532. + +The chariot teams were known by the [colours they wore](/wiki/Chariot_racing#Factions 'Chariot racing'). Fan loyalty was fierce and at times erupted into [sports riots](/wiki/Sports_riots 'Sports riots'). Racing was perilous, but charioteers were among the most celebrated and well-compensated athletes. Circuses were designed to ensure that no team had an unfair advantage and to minimize collisions (_naufragia_), which were nonetheless frequent and satisfying to the crowd. The races retained a magical aura through their early association with [chthonic](/wiki/Chthonic 'Chthonic') rituals: circus images were considered protective or lucky, [curse tablets](/wiki/Curse_tablet 'Curse tablet') have been found buried at the site of racetracks, and charioteers were often suspected of sorcery. Chariot racing continued into the Byzantine period under imperial sponsorship, but the decline of cities in the 6th and 7th centuries led to its eventual demise. + +The Romans thought gladiator contests had originated with [funeral games]( 'Funeral games (antiquity)') and [sacrifices](/wiki/Sacrifice_in_ancient_Roman_religion 'Sacrifice in ancient Roman religion'). Some of the earliest [styles of gladiator fighting](/wiki/List_of_Roman_gladiator_types 'List of Roman gladiator types') had ethnic designations such as \"[Thracian](/wiki/Thraex 'Thraex')\" or \"Gallic\". The staged combats were considered _munera_, \"services, offerings, benefactions\", initially distinct from the festival games _(ludi)_. To mark the opening of the Colosseum, [Titus](/wiki/Titus 'Titus') presented [100 days of arena events](/wiki/Inaugural_games_of_the_Flavian_Amphitheatre 'Inaugural games of the Flavian Amphitheatre'), with 3,000 gladiators competing on a single day. Roman fascination with gladiators is indicated by how widely they are depicted on mosaics, wall paintings, lamps, and in graffiti. Gladiators were trained combatants who might be slaves, convicts, or free volunteers. Death was not a necessary or even desirable outcome in matches between these highly skilled fighters, whose training was costly and time-consuming. By contrast, _noxii_ were convicts sentenced to the arena with little or no training, often unarmed, and with no expectation of survival; physical suffering and humiliation were considered appropriate [retributive justice](/wiki/Retributive_justice 'Retributive justice'). These executions were sometimes staged or ritualized as re-enactments of [myths](/wiki/Greek_mythology 'Greek mythology'), and amphitheatres were equipped with elaborate [stage machinery](/wiki/Stagecraft 'Stagecraft') to create special effects. + +Modern scholars have found the pleasure Romans took in the \"theatre of life and death\" difficult to understand. [Pliny the Younger](/wiki/Pliny_the_Younger 'Pliny the Younger') rationalized gladiator spectacles as good for the people, \"to inspire them to face honourable wounds and despise death, by exhibiting love of glory and desire for victory\". Some Romans such as [Seneca](/wiki/Seneca_the_Younger 'Seneca the Younger') were critical of the brutal spectacles, but found virtue in the courage and dignity of the defeated fighter---an attitude that finds its fullest expression with the [Christians martyred](/wiki/Christian_martyr 'Christian martyr') in the arena. Tertullian considered deaths in the arena to be nothing more than a dressed-up form of [human sacrifice](/wiki/Human_sacrifice 'Human sacrifice'). Even [martyr literature](/wiki/Acts_of_the_martyrs 'Acts of the martyrs'), however, offers \"detailed, indeed luxuriant, descriptions of bodily suffering\", and became a popular genre at times indistinguishable from fiction. diff --git a/sample-files/roman-empire-3.md b/sample-files/roman-empire-3.md new file mode 100644 index 0000000..b9099de --- /dev/null +++ b/sample-files/roman-empire-3.md @@ -0,0 +1,160 @@ +### Recreation + +The singular _[ludus]( 'Ludus (ancient Rome)')*, \"play, game, sport, training,\" had a wide range of meanings such as \"word play,\" \"theatrical performance,\" \"board game,\" \"primary school,\" and even \"gladiator training school\" (as in _[Ludus Magnus](/wiki/Ludus_Magnus 'Ludus Magnus')_). Activities for children and young people in the Empire included [hoop rolling](/wiki/Hoop_rolling#Ancient_Rome_and_Byzantium 'Hoop rolling') and [knucklebones](/wiki/Knucklebones 'Knucklebones') (_astragali_ or \"jacks\"). Girls had [dolls](/wiki/Doll 'Doll') made of wood, [terracotta](/wiki/Terracotta 'Terracotta'), and especially [bone and ivory](/wiki/Ivory_carving 'Ivory carving'). Ball games include [trigon]( 'Trigon (game)') and [harpastum](/wiki/Harpastum 'Harpastum'). People of all ages played [board games](/wiki/Board_game 'Board game'), including _[latrunculi](/wiki/Ludus_latrunculorum 'Ludus latrunculorum')_ (\"Raiders\") and _[XII scripta](/wiki/Ludus_duodecim_scriptorum 'Ludus duodecim scriptorum')_ (\"Twelve Marks\"). A game referred to as _alea_ (dice) or _tabula_ (the board) may have been similar to [backgammon](/wiki/Backgammon 'Backgammon'). [Dicing](/wiki/Dice 'Dice') as a form of gambling was disapproved of, but was a popular pastime during the festival of the [Saturnalia](/wiki/Saturnalia 'Saturnalia'). + +After adolescence, most physical training for males was of a military nature. The [Campus Martius](/wiki/Campus_Martius 'Campus Martius') originally was an exercise field where young men learned horsemanship and warfare. Hunting was also considered an appropriate pastime. According to [Plutarch](/wiki/Plutarch 'Plutarch'), conservative Romans disapproved of Greek-style athletics that promoted a fine body for its own sake, and condemned [Nero\'s efforts to encourage Greek-style athletic games](/wiki/Quinquennial_Neronia 'Quinquennial Neronia'). Some women trained as gymnasts and dancers, and a rare few as [female gladiators](/wiki/Gladiatrix 'Gladiatrix'). The \"Bikini Girls\" mosaic shows young women engaging in routines comparable to [rhythmic gymnastics](/wiki/Rhythmic_gymnastics 'Rhythmic gymnastics'). Women were encouraged to maintain health through activities such as playing ball, swimming, walking, or reading aloud (as a breathing exercise). + +### Clothing + +Main article: [Clothing in ancient Rome](/wiki/Clothing_in_ancient_Rome 'Clothing in ancient Rome') + +Further information: [Roman hairstyles](/wiki/Roman_hairstyles 'Roman hairstyles'), [Roman jewelry](/wiki/Roman_jewelry 'Roman jewelry'), and [Cosmetics in ancient Rome](/wiki/Cosmetics_in_ancient_Rome 'Cosmetics in ancient Rome') + +In a status-conscious society like that of the Romans, clothing and personal adornment indicated the etiquette of interacting with the wearer. Wearing the correct clothing reflected a society in good order. There is little direct evidence of how Romans dressed in daily life, since portraiture may show the subject in clothing with symbolic value, and surviving textiles are rare. + +The [toga](/wiki/Toga 'Toga') was the distinctive national garment of the male citizen, but it was heavy and impractical, worn mainly for conducting political or court business and religious rites. It was a \"vast expanse\" of semi-circular white wool that could not be put on and draped correctly without assistance. The drapery became more intricate and structured over time. The _toga praetexta_, with a [purple or purplish-red](/wiki/Tyrian_purple 'Tyrian purple') stripe representing inviolability, was worn by children who had not come of age, [curule magistrates](/wiki/Executive_magistrates_of_the_Roman_Empire 'Executive magistrates of the Roman Empire'), and state priests. Only the emperor could wear an all-purple toga _(toga picta)_. + +Ordinary clothing was dark or colourful. The basic garment for all Romans, regardless of gender or wealth, was the simple sleeved [tunic](/wiki/Tunic 'Tunic'), with length differing by wearer. The tunics of poor people and labouring slaves were made from coarse wool in natural, dull shades; finer tunics were made of lightweight wool or linen. A man of the senatorial or equestrian order wore a tunic with two purple stripes _(clavi)_ woven vertically: the wider the stripe, the higher the wearer\'s status. Other garments could be layered over the tunic. Common male attire also included cloaks and in some regions [trousers](/wiki/Braccae 'Braccae'). In the 2nd century, emperors and elite men are often portrayed wearing the [pallium]( 'Pallium (Roman cloak)'), an originally Greek mantle; women are also portrayed in the pallium. [Tertullian](/wiki/Tertullian 'Tertullian') considered the pallium an appropriate garment both for Christians, in contrast to the toga, and for educated people. + +Roman clothing styles changed over time. In the [Dominate](/wiki/Dominate 'Dominate'), clothing worn by both soldiers and bureaucrats became highly decorated with geometrical patterns, stylized plant motifs, and in more elaborate examples, human or animal figures. Courtiers of the later Empire wore elaborate silk robes. The militarization of Roman society, and the waning of urban life, affected fashion: heavy military-style belts were worn by bureaucrats as well as soldiers, and the toga was abandoned, replaced by the pallium as a garment embodying social unity. + +## Arts + +Main articles: [Roman art](/wiki/Roman_art 'Roman art') and [Art collection in ancient Rome](/wiki/Art_collection_in_ancient_Rome 'Art collection in ancient Rome') + +[Greek art](/wiki/Ancient_Greek_art 'Ancient Greek art') had a profound influence on Roman art. [Public art](/wiki/Public_art 'Public art')---including [sculpture](/wiki/Roman_sculpture 'Roman sculpture'), monuments such as [victory columns](/wiki/List_of_Roman_victory_columns 'List of Roman victory columns') or [triumphal arches](/wiki/Triumphal_arch 'Triumphal arch'), and the iconography on [coins](/wiki/Roman_currency 'Roman currency')---is often analysed for historical or ideological significance. In the private sphere, artistic objects were made for [religious dedications](/wiki/Votum 'Votum'), [funerary commemoration](/wiki/Roman_funerals_and_burial 'Roman funerals and burial'), domestic use, and commerce. The wealthy advertised their appreciation of culture through artwork and [decorative arts](/wiki/Decorative_arts 'Decorative arts') in their homes. Despite the value placed on art, even famous artists were of low social status, partly as they worked with their hands. + +### Portraiture + +Main article: [Roman portraiture](/wiki/Roman_portraiture 'Roman portraiture') + +Portraiture, which survives mainly in sculpture, was the most copious form of imperial art. Portraits during the Augustan period utilize [classical proportions](/wiki/Classicism 'Classicism'), evolving later into a mixture of realism and idealism. Republican portraits were characterized by [verism](/wiki/Verism 'Verism'), but as early as the 2nd century BC, Greek [heroic nudity](/wiki/Heroic_nudity 'Heroic nudity') was adopted for conquering generals. Imperial portrait sculptures may model a mature head atop a youthful nude or semi-nude body with perfect musculature. Clothed in the toga or military regalia, the body communicates rank or role, not individual characteristics. Women of the emperor\'s family were often depicted as goddesses or divine personifications. + +Portraiture in painting is represented primarily by the [Fayum mummy portraits](/wiki/Fayum_mummy_portrait 'Fayum mummy portrait'), which evoke Egyptian and Roman traditions of commemorating the dead with realistic painting. Marble portrait sculpture were painted, but traces have rarely survived. + +### Sculpture and sarcophagi + +Main articles: [Roman sculpture](/wiki/Roman_sculpture 'Roman sculpture') and [Ancient Roman sarcophagi](/wiki/Ancient_Roman_sarcophagi 'Ancient Roman sarcophagi') + +Examples of Roman sculpture survive abundantly, though often in damaged or fragmentary condition, including freestanding statuary in marble, bronze and [terracotta](/wiki/Ancient_Roman_pottery#Terracotta_figurines 'Ancient Roman pottery'), and [reliefs](/wiki/Relief 'Relief') from public buildings and monuments. Niches in amphitheatres were originally filled with statues, as were [formal gardens](/wiki/Roman_gardens 'Roman gardens'). Temples housed cult images of deities, often by famed sculptors. + +Elaborately carved marble and limestone [sarcophagi](/wiki/Sarcophagus 'Sarcophagus') are characteristic of the 2nd to 4th centuries. Sarcophagus relief has been called the \"richest single source of Roman iconography,\" depicting [mythological scenes](/wiki/Classical_mythology 'Classical mythology') or Jewish/Christian imagery as well as the deceased\'s life. + +### Painting + +Initial Roman painting drew from [Etruscan](/wiki/Etruscan_art#Wall-painting 'Etruscan art') and [Greek](/wiki/Ancient_Greek_art#Painting 'Ancient Greek art') models and techniques. Examples of Roman paintings can be found in [palaces](/wiki/List_of_ancient_monuments_in_Rome#Palaces 'List of ancient monuments in Rome'), [catacombs](/wiki/List_of_ancient_monuments_in_Rome#Cemeteries 'List of ancient monuments in Rome') and [villas](/wiki/Roman_villa 'Roman villa'). Much of what is known of Roman painting is from the interior decoration of private homes, particularly as preserved by the [eruption of Vesuvius](/wiki/Eruption_of_Mount_Vesuvius_in_AD_79 'Eruption of Mount Vesuvius in AD 79'). In addition to decorative borders and panels with geometric or vegetative motifs, wall painting depicts scenes from mythology and theatre, landscapes and gardens, [spectacles](#Spectacles), everyday life, and [erotic art](/wiki/Erotic_art_in_Pompeii_and_Herculaneum 'Erotic art in Pompeii and Herculaneum'). + +### Mosaic + +Main article: [Roman mosaic](/wiki/Roman_mosaic 'Roman mosaic') + +[Mosaics](/wiki/Mosaic 'Mosaic') are among the most enduring of Roman [decorative arts](/wiki/Decorative_arts 'Decorative arts'), and are found on floors and other architectural features. The most common is the [tessellated mosaic](/wiki/Opus_tessellatum 'Opus tessellatum'), formed from uniform pieces _([tesserae](/wiki/Tessera 'Tessera'))_ of materials such as stone and glass. _[Opus sectile](/wiki/Opus_sectile 'Opus sectile')_ is a related technique in which flat stone, usually coloured marble, is cut precisely into shapes from which geometric or figurative patterns are formed. This more difficult technique became especially popular for luxury surfaces in the 4th century (eg the [Basilica of Junius Bassus](/wiki/Basilica_of_Junius_Bassus 'Basilica of Junius Bassus')). + +[Figurative](/wiki/Figurative_art 'Figurative art') mosaics share many themes with painting, and in some cases use almost identical [compositions]( 'Composition (visual arts)'). Geometric patterns and mythological scenes occur throughout the Empire. In North Africa, a particularly rich source of mosaics, homeowners often chose scenes of life on their estates, hunting, agriculture, and local wildlife. Plentiful and major examples of Roman mosaics come also from present-day Turkey (particularly the ([Antioch mosaics](/wiki/Antioch_mosaics 'Antioch mosaics')), Italy, southern France, Spain, and Portugal. + +### Decorative arts + +Further information: [Ancient Roman pottery](/wiki/Ancient_Roman_pottery 'Ancient Roman pottery') and [Roman glass](/wiki/Roman_glass 'Roman glass') + +[Decorative arts](/wiki/Decorative_arts 'Decorative arts') for luxury consumers included fine pottery, silver and bronze vessels and implements, and glassware. Pottery manufacturing was economically important, as were the glass and metalworking industries. Imports stimulated new regional centres of production. Southern Gaul became a leading producer of the finer red-gloss pottery _([terra sigillata](/wiki/Terra_sigillata 'Terra sigillata'))_ that was a major trade good in 1st-century Europe. [Glassblowing](/wiki/Glassblowing 'Glassblowing') was regarded by the Romans as originating in Syria in the 1st century BC, and by the 3rd century, Egypt and the [Rhineland](/wiki/Rhineland 'Rhineland') had become noted for fine glass. + +### Performing arts + +Main articles: [Theatre of ancient Rome](/wiki/Theatre_of_ancient_Rome 'Theatre of ancient Rome') and [Music of ancient Rome](/wiki/Music_of_ancient_Rome 'Music of ancient Rome') + +In Roman tradition, borrowed from the Greeks, literary theatre was performed by all-male troupes that used face masks with exaggerated facial expressions to portray emotion. Female roles were played by men in [drag]( 'Drag (clothing)') (_[travesti]( 'Travesti (theatre)')\_). Roman literary theatre tradition is particularly well represented in [Latin literature](#Literature) by the tragedies of [Seneca](/wiki/Seneca_the_Younger 'Seneca the Younger'). + +More popular than literary theatre was the genre-defying _mimus_ theatre, which featured scripted scenarios with free improvisation, risqué language and sex scenes, action sequences, and political satire, along with dance, juggling, acrobatics, tightrope walking, striptease, and [dancing bears](/wiki/Dancing_bear 'Dancing bear'). Unlike literary theatre, _mimus_ was played without masks, and encouraged stylistic realism. Female roles were performed by women. _Mimus_ was related to _[pantomimus](/wiki/Pantomime#Ancient_Rome 'Pantomime')_, an early form of [story ballet](/wiki/Story_ballet 'Story ballet') that contained no spoken dialogue but rather a sung [libretto](/wiki/Libretto 'Libretto'), often mythological, either tragic or comic. + +Although sometimes regarded as foreign, [music](/wiki/Music_of_ancient_Rome 'Music of ancient Rome') and dance existed in Rome from earliest times. Music was customary at funerals, and the _[tibia](/wiki/Aulos 'Aulos')_, a woodwind instrument, was played at sacrifices. Song _([carmen]( 'Carmen (verse)'))_ was integral to almost every social occasion. Music was thought to reflect the orderliness of the cosmos. Various woodwinds and [\"brass\" instruments](/wiki/Brass_instrument 'Brass instrument') were played, as were [stringed instruments](/wiki/Stringed_instruments 'Stringed instruments') such as the _[cithara](/wiki/Cithara 'Cithara')_, and percussion. The _[cornu]( 'Cornu (horn)')_, a long tubular metal wind instrument, was used for military signals and on parade. These instruments spread throughout the provinces and are widely depicted in Roman art. The hydraulic pipe organ _([hydraulis](/wiki/Hydraulis 'Hydraulis'))_ was \"one of the most significant technical and musical achievements of antiquity\", and accompanied gladiator games and events in the amphitheatre. Although certain dances were seen at times as non-Roman or unmanly, dancing was embedded in religious rituals of archaic Rome. Ecstatic dancing was a feature of the [mystery religions](/wiki/Mystery_religions 'Mystery religions'), particularly the cults of [Cybele](/wiki/Cybele 'Cybele') and [Isis](/wiki/Isis 'Isis'). In the secular realm, dancing girls from [Syria]( 'Syria (Roman province)') and [Cadiz](/wiki/C%C3%A1diz 'Cádiz') were extremely popular. + +Like [gladiators](/wiki/Gladiator 'Gladiator'), entertainers were legally _[infames](/wiki/Infamia 'Infamia')_, technically free but little better than slaves. \"Stars\", however, could enjoy considerable wealth and celebrity, and mingled socially and often sexually with the elite. Performers supported each other by forming guilds, and several memorials for theatre members survive. Theatre and dance were often condemned by [Christian polemicists](/wiki/Christian_polemic 'Christian polemic') in the later Empire. + +Estimates of the average [literacy rate](/wiki/Literacy_rate 'Literacy rate') range from 5 to over 30%. The Roman obsession with documents and inscriptions indicates the value placed on the written word. Laws and edicts were posted as well as read out. Illiterate Roman subjects could have a government scribe _([scriba]( 'Scriba (ancient Rome)'))* read or write their official documents for them. The military produced extensive written records. The [Babylonian Talmud](/wiki/Babylonian_Talmud 'Babylonian Talmud') declared \"if all seas were ink, all reeds were pen, all skies parchment, and all men scribes, they would be unable to set down the full scope of the Roman government\'s concerns.\" + +[Numeracy](/wiki/Numeracy 'Numeracy') was necessary for commerce. Slaves were numerate and literate in significant numbers; some were highly educated. Graffiti and low-quality inscriptions with misspellings and [solecisms](/wiki/Solecism 'Solecism') indicate casual literacy among non-elites. + +The Romans had an extensive [priestly archive](/wiki/Glossary_of_ancient_Roman_religion#libri_pontificales 'Glossary of ancient Roman religion'), and inscriptions appear throughout the Empire in connection with [votives](/wiki/Votum 'Votum') dedicated by ordinary people, as well as \"[magic spells](/wiki/Magic_in_the_Greco-Roman_world 'Magic in the Greco-Roman world')\" (eg the [Greek Magical Papyri](/wiki/Greek_Magical_Papyri 'Greek Magical Papyri')). + +Books were expensive, since each copy had to be written out on a papyrus roll _(volumen)_ by scribes. The [codex](/wiki/Codex 'Codex')---pages bound to a spine---was still a novelty in the 1st century, but by the end of the 3rd century was replacing the _volumen_. Commercial book production was established by the late Republic, and by the 1st century certain neighbourhoods of Rome and Western provincial cities were known for their bookshops. The quality of editing varied wildly, and [plagiarism](/wiki/Plagiarism 'Plagiarism') or [forgery](/wiki/Literary_forgery 'Literary forgery') were common, since there was no [copyright law](/wiki/Copyright_law 'Copyright law'). + +Collectors amassed personal libraries, and a fine library was part of the cultivated leisure _([otium](/wiki/Otium 'Otium'))_ associated with the villa lifestyle. Significant collections might attract \"in-house\" scholars, and an individual benefactor might endow a community with a library (as [Pliny the Younger](/wiki/Pliny_the_Younger 'Pliny the Younger') did in [Comum](/wiki/Comum 'Comum')). Imperial libraries were open to users on a limited basis, and represented a [literary canon](/wiki/Literary_canon 'Literary canon'). Books considered subversive might be publicly burned, and [Domitian](/wiki/Domitian 'Domitian') crucified copyists for reproducing works deemed treasonous. + +Literary texts were often shared aloud at meals or with reading groups. Public readings (_[recitationes](/wiki/Recitationes 'Recitationes')_) expanded from the 1st through the 3rd century, giving rise to \"consumer literature\" for entertainment. Illustrated books, including erotica, were popular, but are poorly represented by extant fragments. + +Literacy began to decline during the [Crisis of the Third Century](/wiki/Crisis_of_the_Third_Century 'Crisis of the Third Century'). The emperor Julian banned Christians from teaching the classical curriculum, but the [Church Fathers](/wiki/Church_Fathers 'Church Fathers') and other Christians adopted Latin and Greek literature, philosophy and science in biblical interpretation. As the Western Roman Empire declined, reading became rarer even for those within the Church hierarchy, although it continued in the [Byzantine Empire](/wiki/Byzantine_Empire 'Byzantine Empire'). + +### Education + +Main article: [Education in ancient Rome](/wiki/Education_in_ancient_Rome 'Education in ancient Rome') + +Traditional Roman education was moral and practical. Stories were meant to instil Roman values _([mores maiorum](/wiki/Mos_maiorum 'Mos maiorum'))_. Parents were expected to act as role models, and working parents passed their skills to their children, who might also enter apprenticeships. Young children were attended by a [pedagogue]( 'Paedagogus (occupation)'), usually a Greek slave or former slave, who kept the child safe, taught self-discipline and public behaviour, attended class and helped with tutoring. + +Formal education was available only to families who could pay for it; lack of state support contributed to low literacy. Primary education in reading, writing, and arithmetic might take place at home if parents hired or bought a teacher. Other children attended \"public\" schools organized by a schoolmaster _([ludimagister](/wiki/Ludi_magister 'Ludi magister'))_ paid by parents. _Vernae_ (homeborn slave children) might share in-home or public schooling. Boys and girls received primary education generally from ages 7 to 12, but classes were not segregated by grade or age. Most schools employed [corporal punishment](/wiki/Corporal_punishment 'Corporal punishment'). For the socially ambitious, education in Greek as well as Latin was necessary. Schools became more numerous during the Empire, increasing educational opportunities. + +At the age of 14, upperclass males made their [rite of passage](/wiki/Sexuality_in_ancient_Rome#Rites_of_passage 'Sexuality in ancient Rome') into adulthood, and began to learn leadership roles through mentoring from a senior family member or family friend. Higher education was provided by _[grammatici]( 'Grammarian (Greco-Roman)')_ or _[rhetores](/wiki/Rhetor 'Rhetor')_. The \_grammaticus_ or \"grammarian\" taught mainly Greek and Latin literature, with history, geography, philosophy or mathematics treated as explications of the text. With the rise of Augustus, contemporary Latin authors such as Virgil and Livy also became part of the curriculum. The _rhetor_ was a teacher of oratory or public speaking. The art of speaking _(ars dicendi)_ was highly prized, and _eloquentia_ (\"speaking ability, eloquence\") was considered the \"glue\" of civilized society. Rhetoric was not so much a body of knowledge (though it required a command of the [literary canon](/wiki/Literary_canon 'Literary canon')) as it was a mode of expression that distinguished those who held social power. The ancient model of rhetorical training---\"restraint, coolness under pressure, modesty, and good humour\"---endured into the 18th century as a Western educational ideal. + +In Latin, _illiteratus_ could mean both \"unable to read and write\" and \"lacking in cultural awareness or sophistication.\" Higher education promoted career advancement. Urban elites throughout the Empire shared a literary culture imbued with Greek educational ideals _([paideia](/wiki/Paideia 'Paideia'))_. Hellenistic cities sponsored schools of higher learning to express cultural achievement. Young Roman men often went abroad to study rhetoric and philosophy, mostly to Athens. The curriculum in the East was more likely to include music and physical training. On the Hellenistic model, Vespasian [endowed chairs](/wiki/Endowed_chair 'Endowed chair') of grammar, Latin and Greek rhetoric, and philosophy at Rome, and gave secondary teachers special exemptions from taxes and legal penalties. In the Eastern Empire, [Berytus](/wiki/Berytus 'Berytus') (present-day [Beirut](/wiki/Beirut 'Beirut')) was unusual in offering a Latin education, and became famous for its [school of Roman law](/wiki/Law_School_of_Beirut 'Law School of Beirut'). The cultural movement known as the [Second Sophistic](/wiki/Second_Sophistic 'Second Sophistic') (1st--3rd century AD) promoted the assimilation of Greek and Roman social, educational, and esthetic values. + +Literate women ranged from cultured aristocrats to girls trained to be [calligraphers](/wiki/Calligrapher 'Calligrapher') and [scribes](/wiki/Scribe 'Scribe'). The ideal woman in Augustan love poetry was educated and well-versed in the arts. Education seems to have been standard for daughters of the senatorial and equestrian orders. An educated wife was an asset for the socially ambitious household. + +### Literature + +Main article: [Latin literature](/wiki/Latin_literature 'Latin literature') + +See also: [Latin poetry](/wiki/Latin_poetry 'Latin poetry') + +[Literature under Augustus]( 'Augustan literature (ancient Rome)'), along with that of the Republic, has been viewed as the \"Golden Age\" of Latin literature, embodying [classical ideals](/wiki/Classicism 'Classicism'). The three most influential Classical Latin poets---[Virgil](/wiki/Virgil 'Virgil'), [Horace](/wiki/Horace 'Horace'), and [Ovid](/wiki/Ovid 'Ovid')---belong to this period. Virgil\'s _[Aeneid](/wiki/Aeneid 'Aeneid')_ was a national epic in the manner of the [Homeric epics](/wiki/Homeric_epics 'Homeric epics') of Greece. Horace perfected the use of [Greek lyric](/wiki/Greek_lyric 'Greek lyric') [metres]( 'Metre (poetry)') in Latin verse. Ovid\'s erotic poetry was enormously popular, but ran afoul of Augustan morality, contributing to his exile. Ovid\'s _[Metamorphoses](/wiki/Metamorphoses 'Metamorphoses')_ wove together [Greco-Roman mythology](/wiki/Greco-Roman_mythology 'Greco-Roman mythology'); his versions of [Greek myths](/wiki/Greek_mythology 'Greek mythology') became a primary source of later [classical mythology](/wiki/Classical_mythology 'Classical mythology'), and his work was hugely influential on [medieval literature](/wiki/Medieval_literature 'Medieval literature'). Latin writers were immersed in [Greek literary traditions](/wiki/Ancient_Greek_literature 'Ancient Greek literature'), and adapted its forms and content, but Romans regarded [satire](/wiki/Satire 'Satire') as a genre in which they surpassed the Greeks. The early [Principate](/wiki/Principate 'Principate') produced the satirists [Persius](/wiki/Persius 'Persius') and [Juvenal](/wiki/Juvenal 'Juvenal'). + +The mid-1st through mid-2nd century has conventionally been called the \"[Silver Age](/wiki/Silver_age 'Silver age')\" of Latin literature. The three leading writers---[Seneca](/wiki/Seneca_the_Younger 'Seneca the Younger'), [Lucan](/wiki/Lucan 'Lucan'), and [Petronius](/wiki/Petronius 'Petronius')---committed suicide after incurring [Nero](/wiki/Nero 'Nero')\'s displeasure. [Epigrammatist](/wiki/Epigram 'Epigram') and social observer [Martial](/wiki/Martial 'Martial') and the epic poet [Statius](/wiki/Statius 'Statius'), whose poetry collection _[Silvae](/wiki/Silvae 'Silvae')_ influenced [Renaissance literature](/wiki/Renaissance_literature 'Renaissance literature'), wrote during the reign of [Domitian](/wiki/Domitian 'Domitian'). Other authors of the Silver Age included [Pliny the Elder](/wiki/Pliny_the_Elder 'Pliny the Elder'), author of the encyclopedic _[Natural History]( 'Natural History (Pliny)')\_; his nephew, [Pliny the Younger](/wiki/Pliny_the_Younger 'Pliny the Younger'); and the historian [Tacitus](/wiki/Tacitus 'Tacitus'). + +The principal Latin prose author of the [Augustan age]( 'Augustan literature (ancient Rome)') is the [historian](/wiki/Roman_historiography 'Roman historiography') [Livy](/wiki/Livy 'Livy'), whose account of [Rome\'s founding](/wiki/Founding_of_Rome 'Founding of Rome') became the most familiar version in modern-era literature. Among Imperial historians who wrote in Greek are [Dionysius of Halicarnassus](/wiki/Dionysius_of_Halicarnassus 'Dionysius of Halicarnassus'), [Josephus](/wiki/Josephus 'Josephus'), and [Cassius Dio](/wiki/Cassius_Dio 'Cassius Dio'). Other major Greek authors of the Empire include the biographer [Plutarch](/wiki/Plutarch 'Plutarch'), the geographer [Strabo](/wiki/Strabo 'Strabo'), and the rhetorician and satirist [Lucian](/wiki/Lucian 'Lucian'). _[The Twelve Caesars](/wiki/The_Twelve_Caesars 'The Twelve Caesars')_ by [Suetonius](/wiki/Suetonius 'Suetonius') is a primary source for imperial biography. + +From the 2nd to the 4th centuries, Christian authors were in active dialogue with the [classical tradition](/wiki/Classical_tradition 'Classical tradition'). [Tertullian](/wiki/Tertullian 'Tertullian') was one of the earliest prose authors with a distinctly Christian voice. After the [conversion of Constantine](/wiki/Conversion_of_Constantine 'Conversion of Constantine'), Latin literature is dominated by the Christian perspective. In the late 4th century, [Jerome](/wiki/Jerome 'Jerome') produced the Latin translation of the Bible that became authoritative as the [Vulgate](/wiki/Vulgate 'Vulgate'). [Augustine](/wiki/Augustine 'Augustine') in _[The City of God against the Pagans](/wiki/The_City_of_God_against_the_Pagans 'The City of God against the Pagans')_ builds a vision of an eternal, spiritual Rome, a new _[imperium sine fine](#Geography_and_demography)_ that will outlast the collapsing Empire. + +In contrast to the unity of Classical Latin, the literary esthetic of late antiquity has a [tessellated](/wiki/Tessellation 'Tessellation') quality. A continuing interest in the religious traditions of Rome prior to Christian dominion is found into the 5th century, with the _Saturnalia_ of [Macrobius](/wiki/Macrobius 'Macrobius') and _The Marriage of Philology and Mercury_ of [Martianus Capella](/wiki/Martianus_Capella 'Martianus Capella'). Prominent Latin poets of late antiquity include [Ausonius](/wiki/Ausonius 'Ausonius'), [Prudentius](/wiki/Prudentius 'Prudentius'), [Claudian](/wiki/Claudian 'Claudian'), and [Sidonius Apollinaris](/wiki/Sidonius_Apollinaris 'Sidonius Apollinaris'). + +## Religion + +Main articles: [Religion in ancient Rome](/wiki/Religion_in_ancient_Rome 'Religion in ancient Rome') and [Roman imperial cult](/wiki/Roman_imperial_cult 'Roman imperial cult') + +See also: [History of the Jews in the Roman Empire](/wiki/History_of_the_Jews_in_the_Roman_Empire 'History of the Jews in the Roman Empire'), [Early Christianity](/wiki/Early_Christianity 'Early Christianity'), [Religious persecution in the Roman Empire](/wiki/Religious_persecution_in_the_Roman_Empire 'Religious persecution in the Roman Empire'), and [Christianization of the Roman Empire as diffusion of innovation](/wiki/Christianization_of_the_Roman_Empire_as_diffusion_of_innovation 'Christianization of the Roman Empire as diffusion of innovation') + +The Romans thought of themselves as highly religious, and attributed their success to their collective piety _([pietas](/wiki/Pietas 'Pietas'))_ and good relations with the gods _([pax deorum](/wiki/Pax_deorum 'Pax deorum'))_. The archaic religion believed to have come from the earliest [kings of Rome](/wiki/Kings_of_Rome 'Kings of Rome') was the foundation of the _[mos maiorum](/wiki/Mos_maiorum 'Mos maiorum')_, \"the way of the ancestors\", central to Roman identity. The priesthoods of the state religion were filled from the same pool of men who held public office, and the [Pontifex Maximus](/wiki/Pontifex_Maximus 'Pontifex Maximus') was the emperor. + +Roman religion was practical and contractual, based on the principle of _[do ut des](/wiki/Do_ut_des 'Do ut des')_, \"I give that you might give.\" Religion depended on knowledge and the [correct practice](/wiki/Orthopraxy 'Orthopraxy') of prayer, ritual, and sacrifice, not on faith or dogma, although Latin literature preserves learned speculation on the nature of the divine. For ordinary Romans, religion was a part of daily life. Each home had a household shrine to offer prayers and [libations](/wiki/Libation 'Libation') to the family\'s domestic deities. Neighbourhood shrines and sacred places such as springs and groves dotted the city. The [Roman calendar](/wiki/Roman_calendar 'Roman calendar') was structured around religious observances; as many as 135 days were devoted to [religious festivals](/wiki/Roman_festivals 'Roman festivals') and games (_[ludi](/wiki/Ludi 'Ludi'))_. + +In the wake of the [Republic\'s collapse](/wiki/Collapse_of_the_Roman_Republic 'Collapse of the Roman Republic'), state religion adapted to support the new regime. Augustus justified one-man rule with a vast programme of religious revivalism and reform. [Public vows](/wiki/Vota_pro_salute_rei_publicae 'Vota pro salute rei publicae') now were directed at the wellbeing of the emperor. So-called \"emperor worship\" expanded on a grand scale the traditional [veneration of the ancestral dead](/wiki/Roman_funerals_and_burial 'Roman funerals and burial') and of the _[Genius]( 'Genius (mythology)')_, the divine [tutelary](/wiki/Tutelary_deity 'Tutelary deity') of every individual. Upon death, an emperor could be made a state divinity (_[divus](/wiki/Divus 'Divus')_) by vote of the Senate. The [Roman imperial cult](/wiki/Roman_imperial_cult 'Roman imperial cult'), influenced by [Hellenistic ruler cult](/wiki/Hellenistic_ruler_cult 'Hellenistic ruler cult'), became one of the major ways Rome advertised its presence in the provinces and cultivated shared cultural identity. Cultural precedent in the Eastern provinces facilitated a rapid dissemination of Imperial cult, extending as far as [Najran](/wiki/Najran 'Najran'), in present-day [Saudi Arabia](/wiki/Saudi_Arabia 'Saudi Arabia'). Rejection of the state religion became tantamount to treason. This was the context for Rome\'s conflict with [Christianity](/wiki/Early_Christianity 'Early Christianity'), which Romans variously regarded as a form of atheism and _[superstitio](/wiki/Glossary_of_ancient_Roman_religion#superstitio 'Glossary of ancient Roman religion')\_. + +The Romans are known for the [great number of deities](/wiki/List_of_Roman_deities 'List of Roman deities') they honoured. As the Romans extended their territories, their general policy was to promote stability among diverse peoples by absorbing local deities and cults rather than eradicating them, building temples that framed local theology within Roman religion. Inscriptions throughout the Empire record the side-by-side worship of local and Roman deities, including dedications made by Romans to local gods. By the height of the Empire, numerous [syncretic or reinterpreted gods](/wiki/Interpretatio_romana 'Interpretatio romana') were cultivated, among them cults of [Cybele](/wiki/Cybele 'Cybele'), [Isis](/wiki/Isis 'Isis'), [Epona](/wiki/Epona 'Epona'), and of solar gods such as [Mithras](/wiki/Mithras 'Mithras') and [Sol Invictus](/wiki/Sol_Invictus 'Sol Invictus'), found as far north as [Roman Britain](/wiki/Roman_Britain 'Roman Britain'). Because Romans had never been obligated to cultivate one god or cult only, [religious tolerance](/wiki/Religious_tolerance 'Religious tolerance') was not an issue. + +[Mystery religions](/wiki/Mystery_religions 'Mystery religions'), which offered initiates salvation in the afterlife, were a matter of personal choice, practiced in addition to one\'s [family rites](/wiki/Sacra_gentilicia 'Sacra gentilicia') and public religion. The mysteries, however, involved exclusive oaths and secrecy, which conservative Romans viewed with suspicion as characteristic of \"[magic](/wiki/Magic_in_the_Greco-Roman_world 'Magic in the Greco-Roman world')\", conspiracy (_coniuratio_), and subversive activity. Thus, sporadic and sometimes brutal attempts were made to suppress religionists. In Gaul, the power of the [druids](/wiki/Druid 'Druid') was checked, first by forbidding Roman citizens to belong to the order, and then by banning druidism altogether. However, Celtic traditions were reinterpreted within the context of Imperial theology, and a new [Gallo-Roman religion](/wiki/Gallo-Roman_religion 'Gallo-Roman religion') coalesced; its capital at the [Sanctuary of the Three Gauls](/wiki/Sanctuary_of_the_Three_Gauls 'Sanctuary of the Three Gauls') established precedent for Western cult as a form of Roman-provincial identity. + +The monotheistic rigour of [Judaism](/wiki/Judaism 'Judaism') posed difficulties for Roman policy that led at times to compromise and granting of special exemptions. Tertullian noted that Judaism, unlike Christianity, was considered a _[religio licita](/wiki/Religio_licita 'Religio licita')_, \"legitimate religion.\" The [Jewish--Roman wars](/wiki/Jewish%E2%80%93Roman_wars 'Jewish–Roman wars') resulted from political as well as religious conflicts; the [siege of Jerusalem]( 'Siege of Jerusalem (70)') in 70 AD led to the sacking of the temple and the dispersal of Jewish political power (see [Jewish diaspora](/wiki/Jewish_diaspora 'Jewish diaspora')). + +Christianity emerged in [Roman Judaea]( 'Judaea (Roman province)') as a [Jewish religious sect](/wiki/Jewish_Christian 'Jewish Christian') in the 1st century and gradually [spread](/wiki/Spread_of_Christianity 'Spread of Christianity') out of [Jerusalem](/wiki/Jerusalem_in_Christianity 'Jerusalem in Christianity') throughout the Empire and beyond. Imperially authorized persecutions were limited and sporadic, with martyrdoms occurring most often under the authority of local officials. [Tacitus](/wiki/Tacitus 'Tacitus') reports that after the [Great Fire of Rome](/wiki/Great_Fire_of_Rome 'Great Fire of Rome') in AD 64, the emperor attempted to deflect blame from himself onto the Christians. A major persecution occurred under the emperor [Domitian](/wiki/Domitian 'Domitian') and a [persecution in 177](/wiki/Persecution_in_Lyon 'Persecution in Lyon') took place at Lugdunum, the Gallo-Roman religious capital. A letter from [Pliny the Younger](/wiki/Pliny_the_Younger 'Pliny the Younger'), governor of [Bithynia](/wiki/Bithynia 'Bithynia'), describes his persecution and executions of Christians. The [Decian persecution](/wiki/Decian_persecution 'Decian persecution') of 246--251 seriously threatened the [Christian Church](/wiki/Christian_Church 'Christian Church'), but ultimately strengthened Christian defiance. [Diocletian](/wiki/Diocletian 'Diocletian') undertook the [most severe persecution of Christians](/wiki/Diocletianic_Persecution 'Diocletianic Persecution'), from 303 to 311. + +From the 2nd century onward, the [Church Fathers](/wiki/Church_Fathers 'Church Fathers') condemned the diverse religions practiced throughout the Empire as \"pagan\". In the early 4th century, [Constantine I](/wiki/Constantine_I 'Constantine I') became the first emperor to [convert to Christianity](/wiki/Convert_to_Christianity 'Convert to Christianity'). He supported the Church financially and made laws that favored it, but the new religion was already successful, having moved from less than 50,000 to over a million adherents between 150 and 250. Constantine and his successors banned public sacrifice while tolerating other traditional practices. Constantine never engaged in a [purge](/wiki/Purge 'Purge'), there were no \"pagan martyrs\" during his reign, and people who had not converted to Christianity remained in important positions at court. [Julian](/wiki/Julian_the_Apostate 'Julian the Apostate') attempted to revive traditional public sacrifice and [Hellenistic religion](/wiki/Hellenistic_religion 'Hellenistic religion'), but met Christian resistance and lack of popular support. + +Christians of the 4th century believed the conversion of Constantine showed that Christianity had triumphed over paganism (in Heaven) and little further action besides such rhetoric was necessary. Thus, their focus was [heresy](/wiki/Heresy_in_Christianity 'Heresy in Christianity'). According to [Peter Brown]( 'Peter Brown (historian)'), \"In most areas, polytheists were not molested, and apart from a few ugly incidents of local violence, Jewish communities also enjoyed a century of stable, even privileged, existence\". There were anti-pagan laws, but they were not generally enforced; through the 6th century, centers of paganism existed in Athens, Gaza, Alexandria, and elsewhere. + +According to recent Jewish scholarship, toleration of the Jews was maintained under Christian emperors. This did not extend to [heretics](/wiki/Christian_heresy 'Christian heresy'): Theodosius I made multiple laws and acted against alternate forms of Christianity, and heretics were persecuted and killed by both the government and the church throughout Late Antiquity. Non-Christians were not persecuted until the 6th century. Rome\'s original religious hierarchy and ritual influenced Christian forms, and many pre-Christian practices survived in Christian festivals and local traditions. + +## Legacy + +Main article: [Legacy of the Roman Empire](/wiki/Legacy_of_the_Roman_Empire 'Legacy of the Roman Empire') + +Several states claimed to be the Roman Empire\'s successor. The [Holy Roman Empire](/wiki/Holy_Roman_Empire 'Holy Roman Empire') was established in 800 when [Pope Leo III](/wiki/Pope_Leo_III 'Pope Leo III') crowned [Charlemagne](/wiki/Charlemagne 'Charlemagne') as [Roman emperor](/wiki/Roman_emperor 'Roman emperor'). The [Russian Tsardom](/wiki/Tsardom_of_Russia 'Tsardom of Russia'), as inheritor of the Byzantine Empire\'s [Orthodox Christian](/wiki/Eastern_Orthodox_Church 'Eastern Orthodox Church') tradition, counted itself the [Third Rome](/wiki/Third_Rome 'Third Rome') (Constantinople having been the second), in accordance with the concept of [translatio imperii](/wiki/Translatio_imperii 'Translatio imperii'). The last Eastern Roman titular, [Andreas Palailogos](/wiki/Andreas_Palaiologos 'Andreas Palaiologos'), sold the title of Emperor of Constantinople to [Charles VIII of France](/wiki/Charles_VIII_of_France 'Charles VIII of France'); upon Charles\' death, Palaiologos reclaimed the title and on his death granted it to [Ferdinand and Isabella](/wiki/Ferdinand_and_Isabella 'Ferdinand and Isabella') and their successors, who never used it. When the [Ottomans](/wiki/Ottoman_Empire 'Ottoman Empire'), who based their state on the Byzantine model, took Constantinople in 1453, [Mehmed II](/wiki/Mehmed_II 'Mehmed II') established his capital there and claimed to sit on the throne of the Roman Empire. He even launched an [invasion of Otranto](/wiki/Ottoman_invasion_of_Otranto 'Ottoman invasion of Otranto') with the purpose of re-uniting the Empire, which was aborted by his death. In the medieval West, \"Roman\" came to mean the church and the Catholic Pope. The Greek form [Romaioi](/wiki/Romaioi 'Romaioi') remained attached to the Greek-speaking Christian population of the Byzantine Empire and is still used by [Greeks](/wiki/Greeks 'Greeks'). + +The Roman Empire\'s control of the Italian peninsula influenced [Italian nationalism](/wiki/Italian_nationalism 'Italian nationalism') and the [unification of Italy](/wiki/Unification_of_Italy 'Unification of Italy') (_[Risorgimento](/wiki/Risorgimento 'Risorgimento')_) in 1861. Roman imperialism was claimed by fascist ideology, particularly by the [Italian Empire](/wiki/Italian_Empire 'Italian Empire') and [Nazi Germany](/wiki/Nazi_Germany 'Nazi Germany'). + +In the United States, the [founders](/wiki/Founding_Fathers_of_the_United_States 'Founding Fathers of the United States') were educated in the [classical tradition](/wiki/Classical_tradition 'Classical tradition'), and used classical models for [landmarks in Washington, D.C.](/wiki/List_of_National_Historic_Landmarks_in_Washington,_D.C. 'List of National Historic Landmarks in Washington, D.C.'). The founders saw [Athenian democracy](/wiki/Athenian_democracy 'Athenian democracy') and [Roman republicanism](/wiki/Roman_republic 'Roman republic') as models for the [mixed constitution](/wiki/Mixed_constitution 'Mixed constitution'), but regarded the emperor as a figure of tyranny. + +## See also + +- [Outline of ancient Rome](/wiki/Outline_of_ancient_Rome 'Outline of ancient Rome') +- [List of political systems in France](/wiki/List_of_political_systems_in_France 'List of political systems in France') +- [List of Roman dynasties](/wiki/List_of_Roman_dynasties 'List of Roman dynasties') +- [Daqin](/wiki/Daqin 'Daqin') (\"Great [Qin](/wiki/Qin_dynasty 'Qin dynasty')\"), the ancient Chinese name for the Roman Empire; see also [Sino-Roman relations](/wiki/Sino-Roman_relations 'Sino-Roman relations') +- [Imperial Italy]( 'Imperial Italy (fascist)') +- [Byzantine Empire under the Justinian dynasty](/wiki/Byzantine_Empire_under_the_Justinian_dynasty 'Byzantine Empire under the Justinian dynasty') diff --git a/supabase/migrations/20230618024722_init.sql b/supabase/migrations/20230618024722_init.sql new file mode 100644 index 0000000..5b08ad9 --- /dev/null +++ b/supabase/migrations/20230618024722_init.sql @@ -0,0 +1,18 @@ +create table if not exists todos ( + id uuid default gen_random_uuid() primary key, + created_at timestamp with time zone default timezone('utc'::text, now()) not null, + title text, + is_complete boolean default false, + user_id uuid references auth.users default auth.uid() +); + +-- Set up Row Level Security (RLS) +-- See https://supabase.com/docs/guides/auth/row-level-security for more details. +alter table todos + enable row level security; + +create policy "Authenticated users can select todos" on todos + for select to authenticated using (true); + +create policy "Authenticated users can insert their own todos" on todos + for insert to authenticated with check (auth.uid() = user_id); diff --git a/supabase/seed.sql b/supabase/seed.sql new file mode 100644 index 0000000..89f27cf --- /dev/null +++ b/supabase/seed.sql @@ -0,0 +1,5 @@ +insert into todos(title) +values + ('Create Supabase project'), + ('Create Next.js app from Supabase Starter template'), + ('Keep building cool stuff!'); diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..bcbebff --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,17 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ['./app/**/*.{js,ts,jsx,tsx,mdx}'], + theme: { + extend: { + colors: { + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', + btn: { + background: 'hsl(var(--btn-background))', + 'background-hover': 'hsl(var(--btn-background-hover))', + }, + }, + }, + }, + plugins: [], +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e06a445 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +}