OnyxMunk commited on
Commit
bdd5dc5
·
1 Parent(s): b11e831

feat: Add OpenMoji browser and Fibonacci converter

Browse files

This commit introduces two new features:

1. **OpenMoji Browser**:
- Adds a new tab to browse, search, and copy emojis from the OpenMoji library.
- The `openmoji` npm package has been added as a dependency.

2. **Fibonacci Algorithm Comparator**:
- Adds a new tab to compare the performance of naive recursive and O(1)-space iterative solutions for calculating Fibonacci numbers.
- Provides C++ code examples and an analysis of the generated assembly code to illustrate the efficiency difference.

.idx/integrations.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "firebase_hosting": {},
3
+ "google_maps_platform": {}
4
+ }
.idx/mcp.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "mcpServers": {}
3
+ }
.vscode/extensions.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3
+ // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4
+
5
+ // List of extensions which should be recommended for users of this workspace.
6
+ "recommendations": [
7
+
8
+ ],
9
+ // List of extensions recommended by Code OSS that should not be recommended for users of this workspace.
10
+ "unwantedRecommendations": [
11
+
12
+ ]
13
+ }
app/globals.css ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ :root {
7
+ --background: 0 0% 100%;
8
+ --foreground: 0 0% 3.9%;
9
+ --card: 0 0% 100%;
10
+ --card-foreground: 0 0% 3.9%;
11
+ --popover: 0 0% 100%;
12
+ --popover-foreground: 0 0% 3.9%;
13
+ --primary: 0 0% 9%;
14
+ --primary-foreground: 0 0% 98%;
15
+ --secondary: 0 0% 96.1%;
16
+ --secondary-foreground: 0 0% 9%;
17
+ --muted: 0 0% 96.1%;
18
+ --muted-foreground: 0 0% 45.1%;
19
+ --accent: 0 0% 96.1%;
20
+ --accent-foreground: 0 0% 9%;
21
+ --destructive: 0 84.2% 60.2%;
22
+ --destructive-foreground: 0 0% 98%;
23
+ --border: 0 0% 89.8%;
24
+ --input: 0 0% 89.8%;
25
+ --ring: 0 0% 3.9%;
26
+ --chart-1: 12 76% 61%;
27
+ --chart-2: 173 58% 39%;
28
+ --chart-3: 197 37% 24%;
29
+ --chart-4: 43 74% 66%;
30
+ --chart-5: 27 87% 67%;
31
+ --radius: 0.5rem
32
+ }
33
+ .dark {
34
+ --background: 0 0% 3.9%;
35
+ --foreground: 0 0% 98%;
36
+ --card: 0 0% 3.9%;
37
+ --card-foreground: 0 0% 98%;
38
+ --popover: 0 0% 3.9%;
39
+ --popover-foreground: 0 0% 98%;
40
+ --primary: 0 0% 98%;
41
+ --primary-foreground: 0 0% 9%;
42
+ --secondary: 0 0% 14.9%;
43
+ --secondary-foreground: 0 0% 98%;
44
+ --muted: 0 0% 14.9%;
45
+ --muted-foreground: 0 0% 63.9%;
46
+ --accent: 0 0% 14.9%;
47
+ --accent-foreground: 0 0% 98%;
48
+ --destructive: 0 62.8% 30.6%;
49
+ --destructive-foreground: 0 0% 98%;
50
+ --border: 0 0% 14.9%;
51
+ --input: 0 0% 14.9%;
52
+ --ring: 0 0% 83.1%;
53
+ --chart-1: 220 70% 50%;
54
+ --chart-2: 160 60% 45%;
55
+ --chart-3: 30 80% 55%;
56
+ --chart-4: 280 65% 60%;
57
+ --chart-5: 340 75% 55%
58
+ }
59
+ }
60
+
61
+ @layer base {
62
+ * {
63
+ @apply border-border;
64
+ }
65
+ body {
66
+ @apply bg-background text-foreground;
67
+ }
68
+ }
app/page.js CHANGED
@@ -1,11 +1,13 @@
1
  import React from "react";
2
  import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
3
- import { Sparkles, Zap, Smile, Settings, Type, Signal } from "lucide-react";
4
  import LeetConverter from "@/components/LeetConverter";
5
  import EmojiConverter from "@/components/EmojiConverter";
6
  import CustomMapper from "@/components/CustomMapper";
7
  import AsciiConverter from "@/components/AsciiConverter";
8
  import MorseConverter from "@/components/MorseConverter";
 
 
9
 
10
  export default function Home() {
11
  return (
@@ -33,7 +35,7 @@ export default function Home() {
33
  <div className="bg-white/80 backdrop-blur-xl rounded-3xl shadow-2xl border border-white/20 overflow-hidden">
34
  <Tabs defaultValue="leet" className="w-full">
35
  <div className="border-b border-slate-200 bg-white/50 px-6 pt-6">
36
- <TabsList className="grid w-full grid-cols-5 bg-slate-100/80">
37
  <TabsTrigger value="leet" className="flex items-center gap-2">
38
  <Zap className="w-4 h-4" />
39
  <span className="hidden sm:inline">L33T Speak</span>
@@ -44,6 +46,16 @@ export default function Home() {
44
  <span className="hidden sm:inline">Emoji Speak</span>
45
  <span className="sm:hidden">Emoji</span>
46
  </TabsTrigger>
 
 
 
 
 
 
 
 
 
 
47
  <TabsTrigger value="ascii" className="flex items-center gap-2">
48
  <Type className="w-4 h-4" />
49
  <span className="hidden sm:inline">ASCII Art</span>
@@ -70,6 +82,14 @@ export default function Home() {
70
  <TabsContent value="emoji" className="mt-0">
71
  <EmojiConverter />
72
  </TabsContent>
 
 
 
 
 
 
 
 
73
 
74
  <TabsContent value="ascii" className="mt-0">
75
  <AsciiConverter />
 
1
  import React from "react";
2
  import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
3
+ import { Sparkles, Zap, Smile, Settings, Type, Signal, Search, FunctionSquare } from "lucide-react";
4
  import LeetConverter from "@/components/LeetConverter";
5
  import EmojiConverter from "@/components/EmojiConverter";
6
  import CustomMapper from "@/components/CustomMapper";
7
  import AsciiConverter from "@/components/AsciiConverter";
8
  import MorseConverter from "@/components/MorseConverter";
9
+ import OpenMojiBrowser from "@/components/OpenMojiBrowser";
10
+ import FibonacciConverter from "@/components/FibonacciConverter";
11
 
12
  export default function Home() {
13
  return (
 
35
  <div className="bg-white/80 backdrop-blur-xl rounded-3xl shadow-2xl border border-white/20 overflow-hidden">
36
  <Tabs defaultValue="leet" className="w-full">
37
  <div className="border-b border-slate-200 bg-white/50 px-6 pt-6">
38
+ <TabsList className="grid w-full grid-cols-7 bg-slate-100/80">
39
  <TabsTrigger value="leet" className="flex items-center gap-2">
40
  <Zap className="w-4 h-4" />
41
  <span className="hidden sm:inline">L33T Speak</span>
 
46
  <span className="hidden sm:inline">Emoji Speak</span>
47
  <span className="sm:hidden">Emoji</span>
48
  </TabsTrigger>
49
+ <TabsTrigger value="openmoji" className="flex items-center gap-2">
50
+ <Search className="w-4 h-4" />
51
+ <span className="hidden sm:inline">OpenMoji</span>
52
+ <span className="sm:hidden">Moji</span>
53
+ </TabsTrigger>
54
+ <TabsTrigger value="fibonacci" className="flex items-center gap-2">
55
+ <FunctionSquare className="w-4 h-4" />
56
+ <span className="hidden sm:inline">Fibonacci</span>
57
+ <span className="sm:hidden">Fib</span>
58
+ </TabsTrigger>
59
  <TabsTrigger value="ascii" className="flex items-center gap-2">
60
  <Type className="w-4 h-4" />
61
  <span className="hidden sm:inline">ASCII Art</span>
 
82
  <TabsContent value="emoji" className="mt-0">
83
  <EmojiConverter />
84
  </TabsContent>
85
+
86
+ <TabsContent value="openmoji" className="mt-0">
87
+ <OpenMojiBrowser />
88
+ </TabsContent>
89
+
90
+ <TabsContent value="fibonacci" className="mt-0">
91
+ <FibonacciConverter />
92
+ </TabsContent>
93
 
94
  <TabsContent value="ascii" className="mt-0">
95
  <AsciiConverter />
components.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": true,
5
+ "tsx": false,
6
+ "tailwind": {
7
+ "config": "tailwind.config.js",
8
+ "css": "app/globals.css",
9
+ "baseColor": "neutral",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "iconLibrary": "lucide",
14
+ "aliases": {
15
+ "components": "@/components",
16
+ "utils": "@/lib/utils",
17
+ "ui": "@/components/ui",
18
+ "lib": "@/lib",
19
+ "hooks": "@/hooks"
20
+ },
21
+ "registries": {}
22
+ }
components/AsciiConverter.js CHANGED
@@ -1,3 +1,4 @@
 
1
  import React, { useState } from "react";
2
  import { Button } from "@/components/ui/button";
3
  import { Textarea } from "@/components/ui/textarea";
 
1
+ 'use client';
2
  import React, { useState } from "react";
3
  import { Button } from "@/components/ui/button";
4
  import { Textarea } from "@/components/ui/textarea";
components/CustomMapper.js CHANGED
@@ -1,3 +1,4 @@
 
1
  import React, { useState } from "react";
2
  import { Button } from "@/components/ui/button";
3
  import { Input } from "@/components/ui/input";
 
1
+ 'use client';
2
  import React, { useState } from "react";
3
  import { Button } from "@/components/ui/button";
4
  import { Input } from "@/components/ui/input";
components/EmojiConverter.js CHANGED
@@ -1,3 +1,4 @@
 
1
  import React, { useState } from "react";
2
  import { Button } from "@/components/ui/button";
3
  import { Textarea } from "@/components/ui/textarea";
 
1
+ 'use client';
2
  import React, { useState } from "react";
3
  import { Button } from "@/components/ui/button";
4
  import { Textarea } from "@/components/ui/textarea";
components/FibonacciConverter.js ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { Input } from "@/components/ui/input";
3
+ import { Button } from "@/components/ui/button";
4
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
5
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
6
+
7
+ const FibonacciConverter = () => {
8
+ const [n, setN] = useState(10);
9
+ const [algorithm, setAlgorithm] = useState('iterative');
10
+ const [result, setResult] = useState(null);
11
+ const [executionTime, setExecutionTime] = useState(null);
12
+
13
+ const fibRecursive = (num) => {
14
+ if (num <= 1) return num;
15
+ return fibRecursive(num - 1) + fibRecursive(num - 2);
16
+ };
17
+
18
+ const fibIterative = (num) => {
19
+ if (num <= 1) return num;
20
+ let a = 0, b = 1;
21
+ for (let i = 2; i <= num; i++) {
22
+ const temp = a + b;
23
+ a = b;
24
+ b = temp;
25
+ }
26
+ return b;
27
+ };
28
+
29
+ const calculateFib = () => {
30
+ const startTime = performance.now();
31
+ const res = algorithm === 'recursive' ? fibRecursive(n) : fibIterative(n);
32
+ const endTime = performance.now();
33
+ setResult(res);
34
+ setExecutionTime(endTime - startTime);
35
+ };
36
+
37
+ const recursiveCode = `// Naive Recursive (Exponential Time, O(2^n))
38
+ long long fib_recursive(int n) {
39
+ if (n <= 1) {
40
+ return n;
41
+ }
42
+ return fib_recursive(n - 1) + fib_recursive(n - 2);
43
+ }`;
44
+
45
+ const iterativeCode = `// Iterative (Linear Time, O(n), O(1) Space)
46
+ long long fib_iterative(int n) {
47
+ if (n <= 1) {
48
+ return n;
49
+ }
50
+ long long a = 0, b = 1;
51
+ for (int i = 2; i <= n; ++i) {
52
+ long long temp = a + b;
53
+ a = b;
54
+ b = temp;
55
+ }
56
+ return b;
57
+ }`;
58
+
59
+ return (
60
+ <div className="space-y-6">
61
+ <Card>
62
+ <CardHeader>
63
+ <CardTitle>Fibonacci Calculator</CardTitle>
64
+ <CardDescription>Select an algorithm and a number to see the result and execution time.</CardDescription>
65
+ </CardHeader>
66
+ <CardContent className="space-y-4">
67
+ <div className="flex items-center space-x-4">
68
+ <Input type="number" value={n} onChange={(e) => setN(parseInt(e.target.value))} placeholder="Enter n" className="w-24" />
69
+ <Select value={algorithm} onValueChange={setAlgorithm}>
70
+ <SelectTrigger className="w-[180px]">
71
+ <SelectValue placeholder="Select Algorithm" />
72
+ </SelectTrigger>
73
+ <SelectContent>
74
+ <SelectItem value="iterative">Iterative</SelectItem>
75
+ <SelectItem value="recursive">Recursive</SelectItem>
76
+ </SelectContent>
77
+ </Select>
78
+ <Button onClick={calculateFib}>Calculate</Button>
79
+ </div>
80
+ {result !== null && (
81
+ <div>
82
+ <p>Result: {result}</p>
83
+ <p>Execution Time: {executionTime?.toFixed(4)} ms</p>
84
+ </div>
85
+ )}
86
+ </CardContent>
87
+ </Card>
88
+
89
+ <Card>
90
+ <CardHeader>
91
+ <CardTitle>Assembly-Level Proof</CardTitle>
92
+ <CardDescription>A comparison of the generated x86-64 assembly from a standard C++ compiler (like GCC or Clang on Godbolt).</CardDescription>
93
+ </CardHeader>
94
+ <CardContent className="grid md:grid-cols-2 gap-6">
95
+ <div>
96
+ <h3 className="font-semibold mb-2">Naive Recursive C++</h3>
97
+ <pre className="bg-slate-100 p-4 rounded-md text-sm whitespace-pre-wrap"><code>{recursiveCode}</code></pre>
98
+ <div className="mt-4 text-sm">
99
+ <p className="font-semibold">Assembly Analysis:</p>
100
+ <ul className="list-disc list-inside space-y-1 mt-1">
101
+ <li>Generates two recursive `call fib_recursive` instructions inside the function body.</li>
102
+ <li>Each call pushes a return address onto the stack, leading to a stack depth proportional to `n`.</li>
103
+ <li>For large `n`, this will inevitably lead to a `stack overflow` and is highly inefficient due to recomputing the same values many times.</li>
104
+ </ul>
105
+ </div>
106
+ </div>
107
+ <div>
108
+ <h3 className="font-semibold mb-2">O(1)-Space Iterative C++</h3>
109
+ <pre className="bg-slate-100 p-4 rounded-md text-sm whitespace-pre-wrap"><code>{iterativeCode}</code></pre>
110
+ <div className="mt-4 text-sm">
111
+ <p className="font-semibold">Assembly Analysis:</p>
112
+ <ul className="list-disc list-inside space-y-1 mt-1">
113
+ <li>The core logic is a simple loop (`.L3` in a typical assembly output).</li>
114
+ <li>It uses registers for variables `a` and `b`, performing additions and moves.</li>
115
+ <li>Contains `jmp` (jump) instructions to loop, but no recursive `call` instructions.</li>
116
+ <li>Stack usage is constant (O(1)), making it efficient and safe for very large `n`.</li>
117
+ </ul>
118
+ </div>
119
+ </div>
120
+ </CardContent>
121
+ </Card>
122
+ </div>
123
+ );
124
+ };
125
+
126
+ export default FibonacciConverter;
components/LeetConverter.js CHANGED
@@ -1,3 +1,4 @@
 
1
  import React, { useState } from "react";
2
  import { Button } from "@/components/ui/button";
3
  import { Textarea } from "@/components/ui/textarea";
 
1
+ 'use client';
2
  import React, { useState } from "react";
3
  import { Button } from "@/components/ui/button";
4
  import { Textarea } from "@/components/ui/textarea";
components/OpenMojiBrowser.js ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from 'react';
2
+ import { Input } from "@/components/ui/input";
3
+ import { ScrollArea } from "@/components/ui/scroll-area";
4
+ import { Button } from '@/components/ui/button';
5
+ import { Copy } from 'lucide-react';
6
+
7
+ const OpenMojiBrowser = () => {
8
+ const [emojis, setEmojis] = useState([]);
9
+ const [searchTerm, setSearchTerm] = useState('');
10
+ const [selectedEmoji, setSelectedEmoji] = useState(null);
11
+
12
+ useEffect(() => {
13
+ fetch('https://unpkg.com/openmoji@latest/data/openmoji.json')
14
+ .then(response => response.json())
15
+ .then(data => setEmojis(data));
16
+ }, []);
17
+
18
+ const filteredEmojis = emojis.filter(emoji =>
19
+ emoji.annotation.toLowerCase().includes(searchTerm.toLowerCase())
20
+ );
21
+
22
+ const handleCopyToClipboard = (emoji) => {
23
+ navigator.clipboard.writeText(emoji.emoji);
24
+ setSelectedEmoji(emoji.hexcode);
25
+ setTimeout(() => setSelectedEmoji(null), 2000);
26
+ };
27
+
28
+ return (
29
+ <div className="h-[600px] flex flex-col gap-4">
30
+ <Input
31
+ type="text"
32
+ placeholder="Search for an emoji..."
33
+ value={searchTerm}
34
+ onChange={(e) => setSearchTerm(e.target.value)}
35
+ className="w-full"
36
+ />
37
+ <ScrollArea className="flex-grow border rounded-md p-4 bg-white">
38
+ <div className="grid grid-cols-8 gap-4">
39
+ {filteredEmojis.map(emoji => (
40
+ <div
41
+ key={emoji.hexcode}
42
+ className="relative group flex items-center justify-center p-2 rounded-lg hover:bg-slate-100 cursor-pointer transition-colors"
43
+ onClick={() => handleCopyToClipboard(emoji)}
44
+ >
45
+ <img
46
+ src={`https://unpkg.com/openmoji@latest/color/svg/${emoji.hexcode}.svg`}
47
+ alt={emoji.annotation}
48
+ className="w-10 h-10"
49
+ />
50
+ <div className="absolute bottom-full mb-2 w-max bg-slate-800 text-white text-xs rounded py-1 px-2 opacity-0 group-hover:opacity-100 transition-opacity">
51
+ {emoji.annotation}
52
+ <div className="absolute top-full left-1/2 -translate-x-1/2 w-0 h-0 border-x-4 border-x-transparent border-t-4 border-t-slate-800"></div>
53
+ </div>
54
+ {selectedEmoji === emoji.hexcode && (
55
+ <div className="absolute inset-0 bg-green-500/20 rounded-lg flex items-center justify-center">
56
+ <Copy className="w-6 h-6 text-green-700" />
57
+ </div>
58
+ )}
59
+ </div>
60
+ ))}
61
+ </div>
62
+ </ScrollArea>
63
+ </div>
64
+ );
65
+ };
66
+
67
+ export default OpenMojiBrowser;
components/ui/tabs.jsx ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as TabsPrimitive from "@radix-ui/react-tabs"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ const Tabs = TabsPrimitive.Root
9
+
10
+ const TabsList = React.forwardRef(({ className, ...props }, ref) => (
11
+ <TabsPrimitive.List
12
+ ref={ref}
13
+ className={cn(
14
+ "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
15
+ className
16
+ )}
17
+ {...props} />
18
+ ))
19
+ TabsList.displayName = TabsPrimitive.List.displayName
20
+
21
+ const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
22
+ <TabsPrimitive.Trigger
23
+ ref={ref}
24
+ className={cn(
25
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
26
+ className
27
+ )}
28
+ {...props} />
29
+ ))
30
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
31
+
32
+ const TabsContent = React.forwardRef(({ className, ...props }, ref) => (
33
+ <TabsPrimitive.Content
34
+ ref={ref}
35
+ className={cn(
36
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
37
+ className
38
+ )}
39
+ {...props} />
40
+ ))
41
+ TabsContent.displayName = TabsPrimitive.Content.displayName
42
+
43
+ export { Tabs, TabsList, TabsTrigger, TabsContent }
firebase.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // Import the functions you need from the SDKs you need
3
+ import { initializeApp } from "firebase/app";
4
+ import { getAnalytics } from "firebase/analytics";
5
+ // TODO: Add SDKs for Firebase products that you want to use
6
+ // https://firebase.google.com/docs/web/setup#available-libraries
7
+
8
+ // Your web app's Firebase configuration
9
+ // For Firebase JS SDK v7.20.0 and later, measurementId is optional
10
+ const firebaseConfig = {
11
+ apiKey: "your-api-key",
12
+ authDomain: "your-auth-domain",
13
+ projectId: "your-project-id",
14
+ storageBucket: "your-storage-bucket",
15
+ messagingSenderId: "your-messaging-sender-id",
16
+ appId: "your-app-id",
17
+ measurementId: "your-measurement-id"
18
+ };
19
+
20
+ // Initialize Firebase
21
+ const app = initializeApp(firebaseConfig);
22
+ const analytics = getAnalytics(app);
jsconfig.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "paths": {
4
+ "@/*": ["./*"]
5
+ }
6
+ }
7
+ }
lib/utils.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
next.config.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {};
3
+
4
+ module.exports = nextConfig;
package-lock.json CHANGED
The diff for this file is too large to render. See raw diff
 
package.json CHANGED
@@ -3,35 +3,38 @@
3
  "version": "0.1.0",
4
  "private": true,
5
  "scripts": {
6
- "dev": "next dev",
7
- "build": "next build",
8
- "start": "next start",
9
- "lint": "next lint"
10
  },
11
  "dependencies": {
12
- "@radix-ui/react-label": "^2.0.2",
13
- "@radix-ui/react-select": "^2.0.0",
14
- "@radix-ui/react-slider": "^1.1.2",
15
- "@radix-ui/react-slot": "^1.0.2",
16
- "@radix-ui/react-switch": "^1.0.3",
17
- "class-variance-authority": "^0.7.0",
18
- "clsx": "^2.1.0",
19
- "lucide-react": "^0.356.0",
20
- "next": "14.1.3",
21
- "next-themes": "^0.2.1",
22
- "react": "^18",
23
- "react-dom": "^18",
24
- "sonner": "^1.4.3",
25
- "tailwind-merge": "^2.2.1",
26
- "tailwindcss-animate": "^1.0.7"
 
 
 
27
  },
28
  "devDependencies": {
29
- "@types/node": "^20",
30
- "@types/react": "^18",
31
- "@types/react-dom": "^18",
32
- "autoprefixer": "^10.0.1",
33
- "postcss": "^8",
34
- "tailwindcss": "^3.3.0",
35
- "typescript": "^5"
36
  }
37
- }
 
3
  "version": "0.1.0",
4
  "private": true,
5
  "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
  },
11
  "dependencies": {
12
+ "@radix-ui/react-label": "^2.0.2",
13
+ "@radix-ui/react-select": "^2.0.0",
14
+ "@radix-ui/react-slider": "^1.1.2",
15
+ "@radix-ui/react-slot": "^1.0.2",
16
+ "@radix-ui/react-switch": "^1.0.3",
17
+ "@radix-ui/react-tabs": "^1.1.13",
18
+ "class-variance-authority": "^0.7.1",
19
+ "clsx": "^2.1.1",
20
+ "firebase": "^12.6.0",
21
+ "lucide-react": "^0.356.0",
22
+ "next": "^14.2.33",
23
+ "next-themes": "^0.2.1",
24
+ "openmoji": "^16.0.0",
25
+ "react": "^18",
26
+ "react-dom": "^18",
27
+ "sonner": "^1.4.3",
28
+ "tailwind-merge": "^2.6.0",
29
+ "tailwindcss-animate": "^1.0.7"
30
  },
31
  "devDependencies": {
32
+ "@types/node": "^20",
33
+ "@types/react": "^18",
34
+ "@types/react-dom": "^18",
35
+ "autoprefixer": "^10.4.22",
36
+ "postcss": "^8.5.6",
37
+ "tailwindcss": "^3.4.18",
38
+ "typescript": "^5"
39
  }
40
+ }
postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
tailwind.config.js ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ darkMode: ['class'],
4
+ content: [
5
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
6
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
7
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
8
+ ],
9
+ theme: {
10
+ extend: {
11
+ borderRadius: {
12
+ lg: 'var(--radius)',
13
+ md: 'calc(var(--radius) - 2px)',
14
+ sm: 'calc(var(--radius) - 4px)'
15
+ },
16
+ colors: {
17
+ background: 'hsl(var(--background))',
18
+ foreground: 'hsl(var(--foreground))',
19
+ card: {
20
+ DEFAULT: 'hsl(var(--card))',
21
+ foreground: 'hsl(var(--card-foreground))'
22
+ },
23
+ popover: {
24
+ DEFAULT: 'hsl(var(--popover))',
25
+ foreground: 'hsl(var(--popover-foreground))'
26
+ },
27
+ primary: {
28
+ DEFAULT: 'hsl(var(--primary))',
29
+ foreground: 'hsl(var(--primary-foreground))'
30
+ },
31
+ secondary: {
32
+ DEFAULT: 'hsl(var(--secondary))',
33
+ foreground: 'hsl(var(--secondary-foreground))'
34
+ },
35
+ muted: {
36
+ DEFAULT: 'hsl(var(--muted))',
37
+ foreground: 'hsl(var(--muted-foreground))'
38
+ },
39
+ accent: {
40
+ DEFAULT: 'hsl(var(--accent))',
41
+ foreground: 'hsl(var(--accent-foreground))'
42
+ },
43
+ destructive: {
44
+ DEFAULT: 'hsl(var(--destructive))',
45
+ foreground: 'hsl(var(--destructive-foreground))'
46
+ },
47
+ border: 'hsl(var(--border))',
48
+ input: 'hsl(var(--input))',
49
+ ring: 'hsl(var(--ring))',
50
+ chart: {
51
+ '1': 'hsl(var(--chart-1))',
52
+ '2': 'hsl(var(--chart-2))',
53
+ '3': 'hsl(var(--chart-3))',
54
+ '4': 'hsl(var(--chart-4))',
55
+ '5': 'hsl(var(--chart-5))'
56
+ }
57
+ }
58
+ }
59
+ },
60
+ plugins: [require("tailwindcss-animate")],
61
+ }