├── .gitmodules ├── README.md ├── assets ├── btns │ ├── code.png │ ├── copy.png │ ├── history_btn.png │ ├── iterate_btn.png │ ├── randomize_btn.png │ ├── share_btn.png │ └── upload_btn.png ├── data │ ├── qa_dataset.txt │ ├── random_prompts.txt │ ├── visualizations.txt │ └── wip_qa_dataset.txt ├── favicon │ └── baby_llama_logo.png ├── fonts │ ├── Sunny Spells.otf │ └── Sunny Spells.ttf ├── footer │ ├── html_css_js.png │ ├── langchain.png │ ├── llama_cpp.png │ ├── meta_llama_2.png │ └── python.png └── logos │ ├── baby-llama-logo.png │ ├── baby-llama-logo2.png │ └── baby-llama-logo3.png ├── baby_code.py ├── completion.js ├── index.html ├── index.js ├── memory ├── __pycache__ │ └── chat_session.cpython-311.pyc └── chat_session.py ├── requirements.txt ├── scripts ├── conver_to_dolly.py ├── process_ipynb_tutorials.py ├── process_matplotlib_examples.py ├── proxy.py └── update_deps.py ├── styles.css └── tests └── file_regex_matcher.py /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "llama.cpp"] 2 | path = llama.cpp 3 | url = https://github.com/ggerganov/llama.cpp.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # baby-code 2 | A simple and 100% Local, Open-Source Code 🐍 Interpreter for 🦙 LLMs 3 | 4 | ## Baby Llama is: 5 | - [x] powered by [Llama.cpp](https://github.com/ggerganov/llama.cpp) 6 | - [x] extremly SIMPLE & 100% LOCAL 7 | - [x] CROSS-PLATFORM. 8 | 9 | https://github.com/itsPreto/baby-code/assets/45348368/a5319303-aa97-4c01-9e91-7d3f03514139 10 | 11 | Leveraging [open source gguf models](https://huggingface.co/models?search=gguf) and powered by llama.cpp this project is a humble foundation for enabling LLMs to act as Code Interpreters. 12 | 13 | ## 🏗️ Architecture (in a nutshell) 14 | 15 | - 🖥️ **_Backend_**: Python Flask (CORS for serving both the API and the HTML). 16 | - 🌐 **_Frontend_**: HTML/JS/CSS (I'm not a frontend dev but gave it my best shot-- prolly tons of issues). 17 | - ⚙️ **_Engine_**: Llama.cpp: An inference library for `ggml/gguf` models). 18 | - 🧠 **_Model_**: [GGUF](https://github.com/ggerganov/llama.cpp#description) format (replacing the retired `ggml` format). 19 | 20 | ## 🦙 Features 21 | - 🎊 Confetti:3 22 | - 💬 Contextual Conversations: Models are augmented with the ongoing context of the conversation-- allowing them to remember and refer back to previous parts of it. 23 | - 🔄 Dynamic Code Interaction: Copy, Diff, Edit, Save and Run the generated Python scripts right from the chat. 24 | - 🐞 Auto-Debugging & 🏃 Auto-Run: Allow the model to automatically debug and execute any attempts at fixing issue on the fly (_it will die trying_). 25 | - 📊 Inference & Performance Metrics: Stay informed about how fast the model is processing your requests and tally the successful vs failed script executions. 26 | - ❓ Random Prompts: Not sure what to ask? Click the "Rand" button to randomly pick from a pre-defined prompt list! 27 | 28 | ## 🚀 Getting Started ⚠️ IMPORTANT ⚠️ 29 | 30 | - This project is dependent on its submodule `llama.cpp` and relies on its successful build. 31 | - First, clone the repo: 32 | 33 | ```bash 34 | git clone --recurse-submodules https://github.com/itsPreto/baby-code 35 | ``` 36 | 37 | - Navigate to the llama.cpp submodule: 38 | 39 | ```bash 40 | cd baby-code/llama.cpp 41 | ``` 42 | 43 | - Install the required libraries: 44 | 45 | ```bash 46 | pip install -r requirements.txt 47 | ``` 48 | 49 | - Then repeat the same for the root project: 50 | ```bash 51 | cd baby-code && pip install -r requirements.txt 52 | ``` 53 | 54 | ## 🏗️ Build llama.cpp 55 | 56 | In order to build llama.cpp you have three different options. 57 | 58 | - Using `make`: 59 | - On Linux or MacOS: 60 | 61 | ```bash 62 | make 63 | ``` 64 | 65 | - On Windows: 66 | 67 | 1. Download the latest fortran version of [w64devkit](https://github.com/skeeto/w64devkit/releases). 68 | 2. Extract `w64devkit` on your pc. 69 | 3. Run `w64devkit.exe`. 70 | 4. Use the `cd` command to reach the `llama.cpp` folder. 71 | 5. From here you can run: 72 | ```bash 73 | make 74 | ``` 75 | 76 | - Using `CMake`: 77 | 78 | ```bash 79 | mkdir build 80 | cd build 81 | cmake .. 82 | cmake --build . --config Release 83 | ``` 84 | 85 | ### Build Alternatives [Metal](https://github.com/ggerganov/llama.cpp#metal-build), [Intel Mlk](https://github.com/ggerganov/llama.cpp#intel-mkl), [MPI](https://github.com/ggerganov/llama.cpp#mpi-build), [BLIS](https://github.com/ggerganov/llama.cpp/blob/master/docs/BLIS.md) [cuBLAS](https://github.com/ggerganov/llama.cpp#cublas), [clBLAST](https://github.com/ggerganov/llama.cpp#clblast), [OpenBLAS](https://github.com/ggerganov/llama.cpp#openblas), and [hipBLAS](https://github.com/ggerganov/llama.cpp#openblas). 86 | 87 | ## 💾 Model Download 88 | 89 | - [TheBloke/WizardCoder-Python-13B-V1.0-GGUF](https://huggingface.co/TheBloke/WizardCoder-Python-13B-V1.0-GGUF) is a friendly, [gpu] budget model. 90 | - You may also download any other models supported by llama.cpp, of any parameter size of your choosing. 91 | - Keep in mind that the paramters might need to be tuned for your specific case: 92 | 93 | ## 🧠 Model Config 94 | Load up your chosen model `gguf` for local inference using CPU or GPU by simply placing it in the `llama.cpp/models` folder and edit the `baby_code.py` init config below: 95 | 96 | ```python 97 | if __name__ == '__main__': 98 | # Run the external command 99 | server_process = subprocess.Popen( 100 | ["./llama.cpp/server", "-m", "./llama.cpp/models/wizardcoder-python-13b-v1.0.Q5_K_M.gguf", "-c", "1024", 101 | "-ngl", "1", "--path", "."]) 102 | # Pause for 5 seconds 103 | time.sleep(5) 104 | app.run(args.host, port=args.port) 105 | ``` 106 | 107 | You may also want to customize & configure the flask server at the top of the file, like so: 108 | 109 | ```python 110 | parser = argparse.ArgumentParser(description="An example of using server.cpp with a similar API to OAI. It must be used together with server.cpp.") 111 | parser.add_argument("--stop", type=str, help="the end of response in chat completions(default: '')", default="") 112 | parser.add_argument("--llama-api", type=str, help="Set the address of server.cpp in llama.cpp(default: http://127.0.0.1:8080)", default='http://127.0.0.1:8080') 113 | parser.add_argument("--api-key", type=str, help="Set the api key to allow only few user(default: NULL)", default="") 114 | parser.add_argument("--host", type=str, help="Set the ip address to listen.(default: 127.0.0.1)", default='127.0.0.1') 115 | parser.add_argument("--port", type=int, help="Set the port to listen.(default: 8081)", default=8081) 116 | ``` 117 | 118 | ## 🏃‍♀️ Run it 119 | - From the project `root` simply run: 120 | ```bash 121 | python3 baby_code.py 122 | ``` 123 | 124 | The `server.cpp` will be served to `http://127.0.0.1:8080/` by default, while the the Flask (`baby_code.py`) currently listens on port 8081. 125 | 126 | ## 🤝 Contributing 127 | > Contributions to this project are welcome. Please create a fork of the repository, make your changes, and submit a pull 128 | request. 129 | > I'll be creating a few issues for feature tracking soon!! 130 | > 131 | > ALSO~ If anyone would like to start a Discord channel and help me manage it that would be awesome 132 | > 133 | > _(I'm not on it that much)_. 134 | 135 | ## License 136 | This project is licensed under the MIT License. 137 | -------------------------------------------------------------------------------- /assets/btns/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/btns/code.png -------------------------------------------------------------------------------- /assets/btns/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/btns/copy.png -------------------------------------------------------------------------------- /assets/btns/history_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/btns/history_btn.png -------------------------------------------------------------------------------- /assets/btns/iterate_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/btns/iterate_btn.png -------------------------------------------------------------------------------- /assets/btns/randomize_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/btns/randomize_btn.png -------------------------------------------------------------------------------- /assets/btns/share_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/btns/share_btn.png -------------------------------------------------------------------------------- /assets/btns/upload_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/btns/upload_btn.png -------------------------------------------------------------------------------- /assets/data/random_prompts.txt: -------------------------------------------------------------------------------- 1 | Create synthetic data and visualize the relationship between two sets of data on a 2D plane. 2 | Generate synthetic data to show how different categories compare in terms of their counts. 3 | Use synthetic data to highlight the trend between two variables and indicate the strength of their correlation. 4 | Produce synthetic data to compare the distribution of multiple categories in a single visualization. 5 | With synthetic data, display a scatter plot with markers of varying sizes to indicate importance or quantity. 6 | Construct synthetic data to visualize the correlation matrix of a dataset to understand inter-variable relationships. 7 | Create synthetic data to show a pairwise relationship of variables in a multi-dimensional dataset. 8 | Using synthetic data, contrast positive and negative values in a diverging manner. 9 | Develop synthetic data to stack data series on top of each other to indicate volume or counts over time. 10 | With synthetic data, display a categorical breakdown of a metric using vertical bars. 11 | Generate synthetic time series data and highlight significant events using annotations. 12 | Create synthetic time series data and decompose it to show its trend, seasonal, and random components. 13 | Visualize multiple synthetic time series data on the same plot for comparison. 14 | Use dual axes to compare two synthetic metrics with different scales over time. 15 | Show the variation in synthetic data using error bands or confidence intervals. 16 | Visualize daily activities or events over the course of a year using a calendar heatmap with synthetic data. 17 | Group synthetic data by seasons or cycles to highlight periodic trends. 18 | Use a hierarchical tree to represent the structure of nested synthetic data. 19 | Cluster synthetic data points based on similarity and display them in distinct colors or groups. 20 | Utilize parallel lines to visualize multi-dimensional synthetic data. 21 | Show the distribution of a single synthetic variable using a histogram. 22 | Highlight the central tendency and spread of synthetic data using a box plot. 23 | Combine categorical plots to show individual synthetic data points and their overall distribution. 24 | Visualize synthetic data distributions for different categories side by side. 25 | Break down synthetic data into its constituent categories using a pie or donut chart. 26 | Use a treemap to show hierarchical synthetic data with nested rectangles. 27 | Show synthetic data progression over a continuous interval using an area chart. 28 | Visualize synthetic categorical data distributions using violin plots. 29 | Represent a synthetic dataset's density distribution using a density or KDE plot. 30 | Show the difference between two time points for various synthetic categories using a slope chart. 31 | Visualize the start and end points of synthetic categories using a dumbbell plot. 32 | Highlight the density of events over a continuous synthetic variable using strip or swarm plots. 33 | Display synthetic multi-dimensional dataset using Andrews curves. 34 | Capture the distribution and outliers of synthetic data using a combination of box and dot plots. 35 | Visualize the proportion of synthetic categories using a waffle chart. 36 | Show the distribution of synthetic data for various groups using grouped or stacked bar charts. 37 | Represent synthetic data frequency using a lollipop chart. 38 | Highlight the peaks and troughs of synthetic data using a dot plot. 39 | Visualize correlations in synthetic time-lagged data using an ACF or PACF plot. 40 | Display hierarchical clustering of synthetic data using a dendrogram. 41 | Show the change in a synthetic metric over categories using a bar chart. 42 | Visualize the flow or sequence of synthetic data using a Sankey diagram. 43 | Highlight the distribution of a synthetic metric across categories using a radial or spider chart. 44 | Capture the composition of synthetic data over time using stacked area or stream graphs. 45 | Visualize the concentration of synthetic data points in a scatter plot using hexbin plots. 46 | Highlight similarities or differences in synthetic datasets using mirrored histograms or back-to-back bar charts. 47 | Represent a comparison of two related synthetic metrics for various categories using a bullet chart. 48 | Visualize cyclic synthetic data using radial or circular plots. 49 | Represent a synthetic dataset's distribution across quantiles using a Q-Q plot. 50 | Visualize the impact or effect of one variable on another using a scatter plot matrix with synthetic data. -------------------------------------------------------------------------------- /assets/data/visualizations.txt: -------------------------------------------------------------------------------- 1 | # Scatter Plot 2 | import matplotlib.pyplot as plt 3 | x = [1,2,3,4,5] 4 | y = [2,4,6,8,10] 5 | plt.scatter(x,y) 6 | plt.xlabel('x') 7 | plt.ylabel('y') 8 | plt.show() 9 | 10 | # Bubble Plot 11 | import matplotlib.pyplot as plt 12 | x = [1,2,3,4,5] 13 | y = [2,4,6,8,10] 14 | sizes = [10,20,30,40,50] 15 | colors = ['red','green','blue','orange','yellow'] 16 | plt.scatter(x, y, s=sizes, c=colors) 17 | plt.xlabel('x') 18 | plt.ylabel('y') 19 | plt.show() 20 | 21 | # Scatter Plot with Regression 22 | import matplotlib.pyplot as plt 23 | import numpy as np 24 | x = np.random.rand(30) 25 | y = x*3 + np.random.rand(30) 26 | plt.scatter(x,y) 27 | plt.plot(x, x*3, c='r') 28 | plt.xlabel('x') 29 | plt.ylabel('y') 30 | plt.show() 31 | 32 | # Strip Plot 33 | import seaborn as sns 34 | x = ['A','B','C'] 35 | data = [1,2,3,4,5,6] 36 | sns.stripplot(x=x, y=data) 37 | plt.xlabel('groups') 38 | plt.ylabel('data') 39 | plt.show() 40 | 41 | # Counts Plot 42 | import matplotlib.pyplot as plt 43 | import pandas as pd 44 | df = pd.DataFrame({'x': [1,1,2,2,3], 'y': [1,2,2,3,3]}) 45 | counts = df.groupby(['x','y']).size().reset_index(name='counts') 46 | plt.scatter(counts.x, counts.y, s=counts.counts*2) 47 | plt.show() 48 | 49 | # Marginal Histogram 50 | import seaborn as sns 51 | x = [1,2,3,4,5] 52 | y = [5,3,6,4,2] 53 | sns.jointplot(x, y, kind="hist") 54 | plt.show() 55 | 56 | # Marginal Boxplot 57 | import seaborn as sns 58 | x = [1,2,3,4,5] 59 | y = [5,3,6,4,2] 60 | sns.jointplot(x, y, kind="box") 61 | plt.show() 62 | 63 | # Correlogram 64 | import seaborn as sns 65 | import numpy as np 66 | data = np.random.rand(5,5) 67 | sns.heatmap(data, annot=True) 68 | plt.show() 69 | 70 | # Pairwise Plot 71 | import seaborn as sns 72 | iris = sns.load_dataset('iris') 73 | sns.pairplot(iris) 74 | plt.show() 75 | 76 | # Diverging Bars 77 | import matplotlib.pyplot as plt 78 | x = [3,1,2] 79 | y = range(len(x)) 80 | plt.barh(y, x) 81 | plt.ylim(-1, len(x)) 82 | plt.show() 83 | 84 | # Diverging Texts 85 | import matplotlib.pyplot as plt 86 | x = [3,1,2] 87 | y = range(len(x)) 88 | for i, v in enumerate(x): 89 | plt.text(v + .02, i, str(v), color='blue') 90 | plt.barh(y, x) 91 | plt.ylim(-1, len(x)) 92 | plt.show() 93 | 94 | # Diverging Dot Plot 95 | import matplotlib.pyplot as plt 96 | import numpy as np 97 | x = np.random.normal(0, 1, 100) 98 | plt.scatter(x, np.zeros_like(x), c=[( 'r' if xx < 0 else 'g') for xx in x], s=100) 99 | plt.xlim(-4,4) 100 | plt.show() 101 | 102 | # Diverging Lollipop Chart 103 | import matplotlib.pyplot as plt 104 | x = [-1.2, 3.5, 2.3, -3.5] 105 | y = range(len(x)) 106 | plt.hlines(y, 0, x, linewidth=2) 107 | plt.scatter(x, y, s=100, c='red') 108 | plt.ylim(-1, len(x)) 109 | plt.show() 110 | 111 | # Area Chart 112 | import matplotlib.pyplot as plt 113 | x = [1,2,3,4,5] 114 | y = [1,2,3,2,1] 115 | plt.plot(x, y) 116 | plt.fill_between(x, y) 117 | plt.show() 118 | 119 | # Ordered Bar Chart 120 | import matplotlib.pyplot as plt 121 | x = [3,1,2] 122 | y = range(len(x)) 123 | plt.barh(y, x) 124 | for i, v in enumerate(x): 125 | plt.text(v + .02, i, str(v), color='blue') 126 | plt.show() 127 | 128 | # Lollipop Chart 129 | import matplotlib.pyplot as plt 130 | x = [1,3,2] 131 | y = range(len(x)) 132 | plt.stem(x, y) 133 | plt.show() 134 | 135 | # Dot Plot 136 | import matplotlib.pyplot as plt 137 | x = [2,5,4,8] 138 | plt.plot(x, 'o') 139 | plt.margins(0.2) 140 | plt.yticks(range(len(x)), x) 141 | plt.show() 142 | 143 | # Slope Chart 144 | import matplotlib.pyplot as plt 145 | before = [10,20,30] 146 | after = [15,18,27] 147 | plt.plot(before, range(len(before))) 148 | plt.plot(after, range(len(after))) 149 | plt.show() 150 | 151 | # Dumbbell Plot 152 | import matplotlib.pyplot as plt 153 | start = [1,2,3] 154 | end = [3,2,4] 155 | y = range(len(start)) 156 | plt.plot(start, y, 'o') 157 | plt.plot(end, y, 'o') 158 | plt.plot(start, y, '-o') 159 | plt.plot(end, y, '-o') 160 | plt.show() 161 | 162 | # Histogram 163 | import matplotlib.pyplot as plt 164 | data = [1,1,1,2,2,3,4,4,4,4,5,6] 165 | plt.hist(data) 166 | plt.show() 167 | 168 | # Histogram for Categorical 169 | import matplotlib.pyplot as plt 170 | data = [1,1,1,2,2,3,4,4,4,4,5,6] 171 | groups = ['A','B','A','B','A','B','A','B','A','B','A','B'] 172 | plt.hist(data, ec='k', color=['red','blue']) 173 | plt.show() 174 | 175 | # Density Plot 176 | import matplotlib.pyplot as plt 177 | import numpy as np 178 | data = np.random.randn(1000) 179 | plt.density(data) 180 | plt.show() 181 | 182 | # Density Plot Grid 183 | import seaborn as sns 184 | tips = sns.load_dataset('tips') 185 | g = sns.FacetGrid(tips, col="sex", margin_titles=True) 186 | g.map(sns.kdeplot, "total_bill") 187 | plt.show() 188 | 189 | # Joyplot 190 | import joypy 191 | import pandas as pd 192 | data = pd.DataFrame(data=np.random.randn(100,5), columns=['a','b','c','d','e']) 193 | joypy.joyplot(data) 194 | plt.show() 195 | 196 | # Distributed Dot Plot 197 | import matplotlib.pyplot as plt 198 | import numpy as np 199 | x1 = np.random.normal(0, 1, 100) 200 | x2 = np.random.normal(2, 1, 100) 201 | plt.scatter(x1, np.zeros_like(x1), c='blue', s=10) 202 | plt.scatter(x2, np.zeros_like(x2), c='red', s=10) 203 | plt.show() 204 | 205 | # Box Plot 206 | import matplotlib.pyplot as plt 207 | data = [1,1,3,4,4,4,5,6] 208 | plt.boxplot(data) 209 | plt.show() 210 | 211 | # Dot + Box Plot 212 | import seaborn as sns 213 | tips = sns.load_dataset('tips') 214 | ax = sns.boxplot(x=tips['sex'], y=tips['total_bill']) 215 | sns.stripplot(x=tips['sex'], y=tips['total_bill'], jitter=True, ax=ax) 216 | plt.show() 217 | 218 | # Violin plot 219 | import seaborn as sns 220 | tips = sns.load_dataset('tips') 221 | ax = sns.violinplot(x="sex", y="total_bill", data=tips) 222 | plt.show() 223 | 224 | # Population Pyramid 225 | import matplotlib.pyplot as plt 226 | age = [2,3,4,2,1] 227 | men = [2,3,4,2,1] 228 | women = [1,2,1,2,3] 229 | plt.barh(age, men, color='blue') 230 | plt.barh(age, -women, color='red') 231 | plt.show() 232 | 233 | # Categorical Plots 234 | import seaborn as sns 235 | titanic = sns.load_dataset('titanic') 236 | sns.catplot(x="sex", y="survived", hue="class", kind="bar", data=titanic) 237 | plt.show() 238 | 239 | # Waffle Chart 240 | import matplotlib.pyplot as plt 241 | from pywaffle import Waffle 242 | data = {'A':12,'B':30,'C':8,'D':10} 243 | fig = plt.figure() 244 | Waffle(data, rows=5, values=data.values(), labels=data.keys(), legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1)}).savefig(fig) 245 | fig.tight_layout() 246 | fig.show() 247 | 248 | # Pie Chart 249 | import matplotlib.pyplot as plt 250 | data = [10,20,30,40] 251 | plt.pie(data) 252 | plt.show() 253 | 254 | # Treemap 255 | import squarify 256 | data = [10, 20, 30, 40] 257 | squarify.plot(sizes=data, label=data.keys(), color=data.keys()) 258 | plt.axis('off') 259 | plt.show() 260 | 261 | # Bar Chart 262 | import matplotlib.pyplot as plt 263 | x = [1,2,3,4] 264 | y = [10,20,25,30] 265 | plt.bar(x,y) 266 | plt.show() 267 | 268 | # Time Series Plot 269 | import matplotlib.pyplot as plt 270 | import pandas as pd 271 | data = pd.Series(range(1,10)) 272 | data.plot() 273 | plt.show() 274 | 275 | # Time Series with Annotations 276 | import matplotlib.pyplot as plt 277 | time = [1,2,3,4,5] 278 | data = [10,12,8,14,5] 279 | plt.plot(time, data) 280 | plt.scatter(3, 8, s=100, c='red') 281 | plt.annotate('Low', xy=(3,8), xytext=(3.5, 5), arrowprops=dict(facecolor='black')) 282 | plt.show() 283 | 284 | # ACF PACF 285 | from statsmodels.graphics.tsaplots import plot_acf, plot_pacf 286 | data = [1,2,3,4,5,6,7,8,9] 287 | plot_acf(data) 288 | plot_pacf(data) 289 | plt.show() 290 | 291 | # Cross Correlation 292 | from statsmodels.graphics.tsaplots import plot_acf 293 | x = [1,2,3,4,5,6] 294 | y = [10,20,30,40,50,60] 295 | plot_acf(x,y) 296 | plt.show() 297 | 298 | # Time Series Decomposition 299 | from statsmodels.tsa.seasonal import seasonal_decompose 300 | data = [1,2,3,4,5,6,7,8,9,10,11,12] 301 | result = seasonal_decompose(data) 302 | result.plot() 303 | plt.show() 304 | 305 | # Multiple Time Series 306 | import matplotlib.pyplot as plt 307 | import pandas as pd 308 | df = pd.DataFrame(data=np.random.randn(50,3),columns=['a','b','c']) 309 | df.plot() 310 | plt.show() 311 | 312 | # Dual Axis Time Series 313 | import matplotlib.pyplot as plt 314 | import pandas as pd 315 | time = pd.date_range('2020-01-01', periods=10, freq='M') 316 | data1 = pd.Series(range(10)) 317 | data2 = pd.Series(range(50,60)) 318 | fig, ax1 = plt.subplots() 319 | ax1.plot(time, data1) 320 | ax2 = ax1.twinx() 321 | ax2.plot(time, data2, c='r') 322 | plt.show() 323 | 324 | # Time Series Error Bands 325 | import matplotlib.pyplot as plt 326 | import pandas as pd 327 | df = pd.DataFrame(data=np.random.randn(30,4), columns=list('ABCD')) 328 | df.rolling(window=3).mean().plot(style='-o', yerr=df.rolling(window=3).std()) 329 | plt.show() 330 | 331 | # Stacked Area Chart 332 | import matplotlib.pyplot as plt 333 | time = [1,2,3,4] 334 | data1 = [1,2,3,4] 335 | data2 = [4,3,2,1] 336 | plt.stackplot(time, data1, data2) 337 | plt.show() 338 | 339 | # UnStacked Area Chart 340 | import matplotlib.pyplot as plt 341 | time = [1,2,3,4] 342 | data1 = [1,2,3,4] 343 | data2 = [4,3,2,1] 344 | plt.plot(time, data1, label='Data 1') 345 | plt.plot(time, data2, label='Data 2') 346 | plt.stackplot(time, data1, data2, colors=['#AAAAAA','#CCCCCC']) 347 | plt.legend() 348 | plt.show() 349 | 350 | # Calendar Heatmap 351 | import calmap 352 | import pandas as pd 353 | df = pd.DataFrame(data=np.random.randn(365,4), columns=list('ABCD')) 354 | calmap.calendarplot(df['A']) 355 | plt.show() 356 | 357 | # Seasonal Plot 358 | import matplotlib.pyplot as plt 359 | import pandas as pd 360 | df = pd.DataFrame({'Year':[2000,2001],'Data':[10,30]}) 361 | df = df.set_index(['Year']) 362 | df.unstack().plot(kind='line') 363 | plt.show() 364 | 365 | # Dendrogram 366 | from scipy.cluster.hierarchy import dendrogram, linkage 367 | import matplotlib.pyplot as plt 368 | X = [[i] for i in range(10)] 369 | dendrogram(linkage(X, 'ward')) 370 | plt.show() 371 | 372 | # Cluster Plot 373 | from sklearn.datasets import make_blobs 374 | import matplotlib.pyplot as plt 375 | X, y = make_blobs(n_samples=150, n_features=2, centers=3) 376 | plt.scatter(X[:,0], X[:,1], c=y, s=50, cmap='Accent') 377 | plt.show() 378 | 379 | # Andrews Curves 380 | from pandas.plotting import andrews_curves 381 | data = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/mtcars.csv') 382 | andrews_curves(data, 'cyl') 383 | plt.show() 384 | 385 | # Parallel Coordinates 386 | from pandas.plotting import parallel_coordinates 387 | data = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/mtcars.csv') 388 | plt.figure(figsize=(12,9), dpi= 80) 389 | parallel_coordinates(data, 'cyl', colormap='Dark2') 390 | plt.show() -------------------------------------------------------------------------------- /assets/favicon/baby_llama_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/favicon/baby_llama_logo.png -------------------------------------------------------------------------------- /assets/fonts/Sunny Spells.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/fonts/Sunny Spells.otf -------------------------------------------------------------------------------- /assets/fonts/Sunny Spells.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/fonts/Sunny Spells.ttf -------------------------------------------------------------------------------- /assets/footer/html_css_js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/footer/html_css_js.png -------------------------------------------------------------------------------- /assets/footer/langchain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/footer/langchain.png -------------------------------------------------------------------------------- /assets/footer/llama_cpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/footer/llama_cpp.png -------------------------------------------------------------------------------- /assets/footer/meta_llama_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/footer/meta_llama_2.png -------------------------------------------------------------------------------- /assets/footer/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/footer/python.png -------------------------------------------------------------------------------- /assets/logos/baby-llama-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/logos/baby-llama-logo.png -------------------------------------------------------------------------------- /assets/logos/baby-llama-logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/logos/baby-llama-logo2.png -------------------------------------------------------------------------------- /assets/logos/baby-llama-logo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/assets/logos/baby-llama-logo3.png -------------------------------------------------------------------------------- /baby_code.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import json 4 | import subprocess 5 | import time 6 | import argparse 7 | import csv 8 | import webbrowser 9 | import magic 10 | from flask import Flask, request, jsonify 11 | from flask_cors import CORS 12 | from PIL import Image 13 | import pandas as pd 14 | import zipfile 15 | import tarfile 16 | from pydub.utils import mediainfo 17 | from moviepy.editor import VideoFileClip 18 | # PyPDF2 and python-docx will be used for document extraction 19 | import PyPDF2 20 | from docx import Document 21 | 22 | # Assuming the ChatSession class is in a file named chat_session.py 23 | from memory.chat_session import ChatSession 24 | 25 | app = Flask(__name__) 26 | CORS(app) 27 | 28 | TEXT_EXTENSIONS = ['.txt', '.md', '.csv', '.tsv', '.log', '.json', '.xml','.yml', '.yaml', '.ini', '.conf'] 29 | CODE_EXTENSIONS = ['.py', '.js', '.html', '.css', '.c', '.cpp', '.java', '.sh','.bat'] 30 | DATA_EXTENSIONS = ['.csv', '.json', '.xls', '.xlsx', '.xml', '.sql', '.db', '.h5', '.pkl'] 31 | IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.ico','.svg'] 32 | DOCUMENT_EXTENSIONS = ['.pdf', '.doc', '.docx', '.ppt', '.pptx', '.odt', '.ods','.rtf'] 33 | AUDIO_EXTENSIONS = ['.mp3', '.wav', '.ogg', '.flac', '.m4a', '.aac'] 34 | VIDEO_EXTENSIONS = ['.mp4', '.avi', '.mkv', '.flv', '.mov', '.wmv', '.webm'] 35 | ARCHIVE_EXTENSIONS = ['.zip', '.tar', '.gz', '.rar', '.7z', '.bz2'] 36 | OTHER_EXTENSIONS = ['.iso', '.img'] 37 | 38 | parser = argparse.ArgumentParser( description="An example of using server.cpp with a similar API to OAI. It must be used together with server.cpp.") 39 | 40 | parser.add_argument("--stop", type=str, help="the end of response in chat completions(default: '')", default="") 41 | parser.add_argument("--llama-api", type=str, help="Set the address of server.cpp in llama.cpp(default: http://127.0.0.1:8080)", default='http://127.0.0.1:8080') 42 | parser.add_argument("--api-key", type=str, help="Set the api key to allow only few user(default: NULL)", default="") 43 | parser.add_argument("--host", type=str, help="Set the ip address to listen.(default: 127.0.0.1)", default='127.0.0.1') 44 | parser.add_argument("--model_path", type=str, help="Set the port to listen.(default: 8081)", default="./llama.cpp/models/CodeLlama-7b-Python/codellama-7b-python.Q5_K_M.gguf") 45 | parser.add_argument("--port", type=int, help="Set the port to listen.(default: 8081)", default=8081) 46 | 47 | args = parser.parse_args() 48 | 49 | 50 | @app.route('/run_python_code', methods=['POST']) 51 | def run_python_code(): 52 | """ 53 | Run Python code and return the stdout and stderr. 54 | 55 | Parameters: 56 | None 57 | 58 | Returns: 59 | dict: A dictionary containing the stdout and stderr. 60 | 61 | Raises: 62 | None 63 | """ 64 | code = request.json['code'] 65 | stdout, stderr = execute(code) 66 | 67 | # Check if there's a "ModuleNotFoundError" 68 | if "ModuleNotFoundError" in stderr: 69 | module_name = stderr.split("'")[ 70 | 1] # Extract the module name from the error message 71 | response = install_dependency(module_name) 72 | 73 | # If the module was installed successfully, re-run the code 74 | if response['status'] == 'success': 75 | stdout, stderr = execute(code) 76 | 77 | return {"stdout": stdout, "stderr": stderr} 78 | 79 | 80 | @app.route('/install_module', methods=['POST']) 81 | def install_module(): 82 | """ 83 | Installs the specified Python module. 84 | 85 | Parameters: 86 | - module_name (str): The name of the Python module to install. 87 | 88 | Returns: 89 | - Status message indicating the result of the installation. 90 | """ 91 | module_name = request.json['module_name'] 92 | response = install_dependency(module_name) 93 | return response 94 | 95 | 96 | def install_dependency(module_name): 97 | """ 98 | Installs the specified Python module using pip. 99 | 100 | Parameters: 101 | - module_name (str): The name of the Python module to install. 102 | 103 | Returns: 104 | - Status message indicating the result of the installation. 105 | """ 106 | process = subprocess.Popen(["pip", "install", module_name], 107 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) 108 | stdout, stderr = process.communicate() 109 | if process.returncode == 0: 110 | return {"status": "success", 111 | "message": f"Module {module_name} installed successfully."} 112 | else: 113 | return {"status": "error", "message": stderr.decode()} 114 | 115 | 116 | def execute(code): 117 | process = subprocess.Popen(["python3", "-c", code], 118 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) 119 | stdout, stderr = process.communicate() 120 | return stdout.decode(), stderr.decode() 121 | 122 | 123 | @app.route('/read_file_sample', methods=['POST']) 124 | def read_file_sample(): 125 | """ 126 | Reads a sample from the provided file path and returns the content. 127 | 128 | Parameters: 129 | - filepath (str): The path to the file. 130 | 131 | Returns: 132 | - If the reading is successful, a sample of the file content. 133 | - If there's an error, an error message. 134 | """ 135 | filepath = request.json['filepath'] 136 | 137 | if not os.path.exists(filepath): 138 | return {"error": "File not found."}, 404 139 | 140 | print(f"Received request for {filepath}") 141 | 142 | extension = "." + filepath.split('.').pop().lower() 143 | 144 | # Print detected extension 145 | print("Detected extension:", extension) 146 | 147 | # Detect MIME type 148 | mime_detector = magic.Magic(mime=True) 149 | mime_type = mime_detector.from_file(filepath) 150 | 151 | # Print detected MIME type 152 | print("Detected MIME type:", mime_type) 153 | 154 | MAX_CHARACTERS = 500 # Or any other number you find suitable 155 | 156 | mime_to_extension = { 157 | # Text Files 158 | "text/plain": [".txt", ".md", ".log", ".ini", ".conf", ".sh", ".bat", 159 | ".c", ".cpp", ".java", ".py", ".js", ".css", ".html"], 160 | "text/csv": [".csv"], 161 | "text/tab-separated-values": [".tsv"], 162 | "application/json": [".json"], 163 | "application/xml": [".xml"], 164 | "application/x-yaml": [".yml", ".yaml"], 165 | 166 | # Image Files 167 | "image/jpeg": [".jpg", ".jpeg"], 168 | "image/png": [".png"], 169 | "image/gif": [".gif"], 170 | "image/bmp": [".bmp"], 171 | "image/tiff": [".tiff"], 172 | "image/x-icon": [".ico"], 173 | "image/svg+xml": [".svg"], 174 | 175 | # Data Files 176 | "application/vnd.ms-excel": [".xls"], 177 | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [ 178 | ".xlsx"], 179 | "application/sql": [".sql"], 180 | "application/x-sqlite3": [".db"], 181 | "application/x-hdf": [".h5"], 182 | "application/octet-stream": [".pkl"], 183 | # General binary, might need more specific handling 184 | 185 | # Document Files 186 | "application/pdf": [".pdf"], 187 | "application/msword": [".doc"], 188 | "application/vnd.openxmlformats-officedocument.wordprocessingml.document": [ 189 | ".docx"], 190 | "application/vnd.ms-powerpoint": [".ppt"], 191 | "application/vnd.openxmlformats-officedocument.presentationml.presentation": [ 192 | ".pptx"], 193 | "application/vnd.oasis.opendocument.text": [".odt"], 194 | "application/vnd.oasis.opendocument.spreadsheet": [".ods"], 195 | "application/rtf": [".rtf"], 196 | 197 | # Audio Files 198 | "audio/mpeg": [".mp3"], 199 | "audio/wav": [".wav"], 200 | "audio/ogg": [".ogg"], 201 | "audio/flac": [".flac"], 202 | "audio/mp4": [".m4a", ".aac"], 203 | 204 | # Video Files 205 | "video/mp4": [".mp4"], 206 | "video/x-msvideo": [".avi"], 207 | "video/x-matroska": [".mkv"], 208 | "video/x-flv": [".flv"], 209 | "video/quicktime": [".mov"], 210 | "video/x-ms-wmv": [".wmv"], 211 | "video/webm": [".webm"], 212 | 213 | # Archive Files 214 | "application/zip": [".zip"], 215 | "application/x-tar": [".tar"], 216 | "application/gzip": [".gz"], 217 | "application/x-rar-compressed": [".rar"], 218 | "application/x-7z-compressed": [".7z"], 219 | "application/x-bzip2": [".bz2"], 220 | 221 | # Other 222 | "application/x-iso9660-image": [".iso"], 223 | "application/x-apple-diskimage": [".img"], 224 | } 225 | 226 | # Validate MIME type against the extension 227 | print(f"Validating MIME type {mime_type} against extension {extension}...") 228 | # Validate MIME type against the extension 229 | if mime_type in mime_to_extension and extension not in mime_to_extension[ 230 | mime_type]: 231 | print( 232 | f"MIME type validation failed for {mime_type} and extension {extension}.") 233 | return { 234 | "error": f"File extension {extension} does not match detected MIME type {mime_type}."}, 400 235 | print( 236 | f"MIME type validation passed for {mime_type} and extension {extension}.") 237 | 238 | try: 239 | # Handle text-based and code files 240 | print("TEXT_EXTENSIONS:", TEXT_EXTENSIONS) 241 | print("CODE_EXTENSIONS:", CODE_EXTENSIONS) 242 | print("Condition Check:", 243 | extension in TEXT_EXTENSIONS or extension in CODE_EXTENSIONS) 244 | 245 | if extension in TEXT_EXTENSIONS or extension in CODE_EXTENSIONS: 246 | print("Handling text-based or code files.") 247 | with open(filepath, 'r') as f: 248 | if extension == "json": 249 | print("Reading JSON file.") 250 | data = json.load(f) 251 | sample_data = json.dumps(data[:5], indent=4)[ 252 | :MAX_CHARACTERS] 253 | elif extension == "csv": 254 | print("Reading CSV file.") 255 | reader = csv.reader(f) 256 | header = next(reader, None) # Get the header 257 | rows = [header] 258 | chars_read = len(",".join(header)) 259 | for row in reader: 260 | if chars_read + len(",".join(row)) > MAX_CHARACTERS: 261 | break 262 | chars_read += len(",".join(row)) 263 | rows.append(row) 264 | sample_data = "\n".join([",".join(row) for row in 265 | rows]) # Convert rows to CSV format 266 | else: 267 | print("Reading general text file.") 268 | content = f.read() 269 | sample_data = content[:MAX_CHARACTERS] 270 | 271 | # Handle document files 272 | elif extension in DOCUMENT_EXTENSIONS: 273 | print("Handling document files.") 274 | if extension == "pdf": 275 | print("Reading PDF file.") 276 | with open(filepath, 'rb') as f: 277 | reader = PyPDF2.PdfFileReader(f) 278 | page = reader.getPage(0) 279 | sample_data = page.extractText()[:MAX_CHARACTERS] 280 | elif extension == "docx": 281 | print("Reading DOCX file.") 282 | doc = Document(filepath) 283 | paragraphs = [p.text for p in doc.paragraphs] 284 | sample_data = "\n".join(paragraphs)[:MAX_CHARACTERS] 285 | else: 286 | sample_data = "Document type not supported for direct reading." 287 | 288 | # Handle audio files 289 | elif extension in AUDIO_EXTENSIONS: 290 | print("Handling audio files.") 291 | info = mediainfo(filepath) 292 | sample_data = f"Audio file detected. Duration: {info['duration']}s, Channels: {info['channels']}" 293 | 294 | # Handle video files 295 | elif extension in VIDEO_EXTENSIONS: 296 | print("Handling video files.") 297 | clip = VideoFileClip(filepath) 298 | sample_data = f"Video file detected. Duration: {clip.duration}s, Resolution: {clip.size[0]}x{clip.size[1]}" 299 | clip.reader.close() 300 | del clip 301 | 302 | # Handle archive files 303 | elif extension in ARCHIVE_EXTENSIONS: 304 | print("Handling archive files.") 305 | if extension in ['.zip']: 306 | print("Reading ZIP file.") 307 | with zipfile.ZipFile(filepath, 'r') as z: 308 | sample_data = f"Archive contains: {', '.join(z.namelist())}" 309 | elif extension in ['.tar', '.gz', '.bz2']: 310 | print("Reading TAR or compressed TAR file.") 311 | with tarfile.open(filepath, 'r') as t: 312 | sample_data = f"Archive contains: {', '.join(t.getnames())}" 313 | else: 314 | sample_data = "Archive type not supported for direct reading." 315 | 316 | # Handle other types 317 | elif extension in OTHER_EXTENSIONS: 318 | print("Handling special file types.") 319 | sample_data = "Special file detected. No direct reading available." 320 | 321 | else: 322 | return {"error": "Unsupported file type."}, 400 323 | 324 | print(f"Sample data extraction successful: {sample_data}") 325 | return {"sample_data": sample_data} 326 | except Exception as e: 327 | print(f"Error encountered: {str(e)}") 328 | return {"error": str(e)}, 500 329 | 330 | 331 | CHAT_HISTORY_ENABLED = True 332 | CURRENT_SESSION = None 333 | CHAT_SESSIONS = [] 334 | 335 | CHAT_SESSIONS_PATH = "chat_sessions.json" 336 | 337 | 338 | def save_chat_sessions(): 339 | with open(CHAT_SESSIONS_PATH, 'w') as f: 340 | sessions_data = [session.to_dict() for session in CHAT_SESSIONS] 341 | json.dump(sessions_data, f) 342 | 343 | 344 | @app.route('/toggle_chat_history', methods=['POST']) 345 | def toggle_chat_history(): 346 | global CHAT_HISTORY_ENABLED 347 | CHAT_HISTORY_ENABLED = not CHAT_HISTORY_ENABLED 348 | return {"status": "success", "enabled": CHAT_HISTORY_ENABLED} 349 | 350 | 351 | @app.route('/add_message', methods=['POST']) 352 | def add_message(): 353 | global CURRENT_SESSION 354 | if not CHAT_HISTORY_ENABLED: 355 | return {"status": "error", 356 | "message": "Chat history saving is disabled."} 357 | 358 | sender = request.json['sender'] 359 | content = request.json['content'] 360 | timestamp = request.json['timestamp'] 361 | 362 | if not CURRENT_SESSION: 363 | CURRENT_SESSION = ChatSession(session_id=str(time.time()), 364 | timestamp=timestamp) 365 | CURRENT_SESSION.add_message(sender, content, timestamp) 366 | 367 | return {"status": "success"} 368 | 369 | 370 | @app.route('/end_session', methods=['POST']) 371 | def end_session(): 372 | global CURRENT_SESSION 373 | if CURRENT_SESSION: 374 | CHAT_SESSIONS.append(CURRENT_SESSION) 375 | save_chat_sessions() 376 | CURRENT_SESSION = None 377 | return {"status": "success"} 378 | 379 | 380 | @app.route('/load_chat_session', methods=['POST']) 381 | def load_chat_session(): 382 | session_id = request.json['session_id'] 383 | for session in CHAT_SESSIONS: 384 | if session.session_id == session_id: 385 | return {"status": "success", "session": session.to_dict()} 386 | return {"status": "error", "message": "Session not found."} 387 | 388 | 389 | if __name__ == '__main__': 390 | # Run the server.cpp as a subprocess 391 | server_process = subprocess.Popen(["./llama.cpp/server", "-m", args.model_path, "-c", "4096", "-ngl", "1", "--path", "."]) 392 | webbrowser.open(args.llama_api) 393 | # Pause for 5 seconds 394 | time.sleep(5) 395 | app.run(args.host, port=args.port) 396 | -------------------------------------------------------------------------------- /completion.js: -------------------------------------------------------------------------------- 1 | const paramDefaults = { 2 | stream: true, 3 | n_predict: 500, 4 | temperature: 0.2, 5 | stop: [""] 6 | }; 7 | 8 | let generation_settings = null; 9 | 10 | 11 | // Completes the prompt as a generator. Recommended for most use cases. 12 | // 13 | // Example: 14 | // 15 | // import { llama } from '/completion.js' 16 | // 17 | // const request = llama("Tell me a joke", {n_predict: 800}) 18 | // for await (const chunk of request) { 19 | // document.write(chunk.data.content) 20 | // } 21 | // 22 | export async function* llama(prompt, params = {}, config = {}) { 23 | let controller = config.controller; 24 | 25 | if (!controller) { 26 | controller = new AbortController(); 27 | } 28 | 29 | const completionParams = { ...paramDefaults, ...params, prompt }; 30 | 31 | const response = await fetch("/completion", { 32 | method: 'POST', 33 | body: JSON.stringify(completionParams), 34 | headers: { 35 | 'Connection': 'keep-alive', 36 | 'Content-Type': 'application/json', 37 | 'Accept': 'text/event-stream' 38 | }, 39 | signal: controller.signal, 40 | }); 41 | 42 | const reader = response.body.getReader(); 43 | const decoder = new TextDecoder(); 44 | 45 | let content = ""; 46 | let leftover = ""; // Buffer for partially read lines 47 | 48 | try { 49 | let cont = true; 50 | 51 | while (cont) { 52 | const result = await reader.read(); 53 | if (result.done) { 54 | break; 55 | } 56 | 57 | // Add any leftover data to the current chunk of data 58 | const text = leftover + decoder.decode(result.value); 59 | 60 | // Check if the last character is a line break 61 | const endsWithLineBreak = text.endsWith('\n'); 62 | 63 | // Split the text into lines 64 | let lines = text.split('\n'); 65 | 66 | // If the text doesn't end with a line break, then the last line is incomplete 67 | // Store it in leftover to be added to the next chunk of data 68 | if (!endsWithLineBreak) { 69 | leftover = lines.pop(); 70 | } else { 71 | leftover = ""; // Reset leftover if we have a line break at the end 72 | } 73 | 74 | // Parse all sse events and add them to result 75 | const regex = /^(\S+):\s(.*)$/gm; 76 | for (const line of lines) { 77 | const match = regex.exec(line); 78 | if (match) { 79 | result[match[1]] = match[2] 80 | // since we know this is llama.cpp, let's just decode the json in data 81 | if (result.data) { 82 | result.data = JSON.parse(result.data); 83 | content += result.data.content; 84 | 85 | // yield 86 | yield result; 87 | 88 | // if we got a stop token from server, we will break here 89 | if (result.data.stop) { 90 | if (result.data.generation_settings) { 91 | generation_settings = result.data.generation_settings; 92 | } 93 | cont = false; 94 | break; 95 | } 96 | } 97 | } 98 | } 99 | } 100 | } catch (e) { 101 | if (e.name !== 'AbortError') { 102 | console.error("llama error: ", e); 103 | } 104 | throw e; 105 | } 106 | finally { 107 | controller.abort(); 108 | } 109 | 110 | return content; 111 | } 112 | 113 | // Call llama, return an event target that you can subcribe to 114 | // 115 | // Example: 116 | // 117 | // import { llamaEventTarget } from '/completion.js' 118 | // 119 | // const conn = llamaEventTarget(prompt) 120 | // conn.addEventListener("message", (chunk) => { 121 | // document.write(chunk.detail.content) 122 | // }) 123 | // 124 | export const llamaEventTarget = (prompt, params = {}, config = {}) => { 125 | const eventTarget = new EventTarget(); 126 | (async () => { 127 | let content = ""; 128 | for await (const chunk of llama(prompt, params, config)) { 129 | if (chunk.data) { 130 | content += chunk.data.content; 131 | eventTarget.dispatchEvent(new CustomEvent("message", { detail: chunk.data })); 132 | } 133 | if (chunk.data.generation_settings) { 134 | eventTarget.dispatchEvent(new CustomEvent("generation_settings", { detail: chunk.data.generation_settings })); 135 | } 136 | if (chunk.data.timings) { 137 | eventTarget.dispatchEvent(new CustomEvent("timings", { detail: chunk.data.timings })); 138 | } 139 | } 140 | eventTarget.dispatchEvent(new CustomEvent("done", { detail: { content } })); 141 | })(); 142 | return eventTarget; 143 | } 144 | 145 | // Call llama, return a promise that resolves to the completed text. This does not support streaming 146 | // 147 | // Example: 148 | // 149 | // llamaPromise(prompt).then((content) => { 150 | // document.write(content) 151 | // }) 152 | // 153 | // or 154 | // 155 | // const content = await llamaPromise(prompt) 156 | // document.write(content) 157 | // 158 | export const llamaPromise = (prompt, params = {}, config = {}) => { 159 | return new Promise(async (resolve, reject) => { 160 | let content = ""; 161 | try { 162 | for await (const chunk of llama(prompt, params, config)) { 163 | content += chunk.data.content; 164 | } 165 | resolve(content); 166 | } catch (error) { 167 | reject(error); 168 | } 169 | }); 170 | }; 171 | 172 | /** 173 | * (deprecated) 174 | */ 175 | export const llamaComplete = async (params, controller, callback) => { 176 | for await (const chunk of llama(params.prompt, params, { controller })) { 177 | callback(chunk); 178 | } 179 | } 180 | 181 | // Get the model info from the server. This is useful for getting the context window and so on. 182 | export const llamaModelInfo = async () => { 183 | if (!generation_settings) { 184 | generation_settings = await fetch("/model.json").then(r => r.json()); 185 | } 186 | return generation_settings; 187 | } 188 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Baby 🦙 Code 🐍 Interpreter 9 | 10 | 11 | 12 | 13 | 808 | 809 | 810 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | function t(){throw new Error("Cycle detected")}function n(){if(o>1){o--;return}let t,n=!1;while(void 0!==_){let i=_;_=void 0;r++;while(void 0!==i){const _=i.o;i.o=void 0;i.f&=-3;if(!(8&i.f)&&c(i))try{i.c()}catch(e){if(!n){t=e;n=!0}}i=_}}r=0;o--;if(n)throw t}function e(t){if(o>0)return t();o++;try{return t()}finally{n()}}let i,_,o=0,r=0,u=0;function l(t){if(void 0===i)return;let n=t.n;if(void 0===n||n.t!==i){n={i:0,S:t,p:i.s,n:void 0,t:i,e:void 0,x:void 0,r:n};if(void 0!==i.s)i.s.n=n;i.s=n;t.n=n;if(32&i.f)t.S(n);return n}else if(-1===n.i){n.i=0;if(void 0!==n.n){n.n.p=n.p;if(void 0!==n.p)n.p.n=n.n;n.p=i.s;n.n=void 0;i.s.n=n;i.s=n}return n}}function f(t){this.v=t;this.i=0;this.n=void 0;this.t=void 0}f.prototype.h=function(){return!0};f.prototype.S=function(t){if(this.t!==t&&void 0===t.e){t.x=this.t;if(void 0!==this.t)this.t.e=t;this.t=t}};f.prototype.U=function(t){if(void 0!==this.t){const n=t.e,e=t.x;if(void 0!==n){n.x=e;t.e=void 0}if(void 0!==e){e.e=n;t.x=void 0}if(t===this.t)this.t=e}};f.prototype.subscribe=function(t){const n=this;return b((function(){const e=n.value,i=32&this.f;this.f&=-33;try{t(e)}finally{this.f|=i}}))};f.prototype.valueOf=function(){return this.value};f.prototype.toString=function(){return this.value+""};f.prototype.toJSON=function(){return this.value};f.prototype.peek=function(){return this.v};Object.defineProperty(f.prototype,"value",{get(){const t=l(this);if(void 0!==t)t.i=this.i;return this.v},set(e){if(i instanceof p)!function(){throw new Error("Computed cannot have side-effects")}();if(e!==this.v){if(r>100)t();this.v=e;this.i++;u++;o++;try{for(let t=this.t;void 0!==t;t=t.x)t.t.N()}finally{n()}}}});function s(t){return new f(t)}function c(t){for(let n=t.s;void 0!==n;n=n.n)if(n.S.i!==n.i||!n.S.h()||n.S.i!==n.i)return!0;return!1}function h(t){for(let n=t.s;void 0!==n;n=n.n){const e=n.S.n;if(void 0!==e)n.r=e;n.S.n=n;n.i=-1;if(void 0===n.n){t.s=n;break}}}function a(t){let n,e=t.s;while(void 0!==e){const t=e.p;if(-1===e.i){e.S.U(e);if(void 0!==t)t.n=e.n;if(void 0!==e.n)e.n.p=t}else n=e;e.S.n=e.r;if(void 0!==e.r)e.r=void 0;e=t}t.s=n}function p(t){f.call(this,void 0);this.x=t;this.s=void 0;this.g=u-1;this.f=4}(p.prototype=new f).h=function(){this.f&=-3;if(1&this.f)return!1;if(32==(36&this.f))return!0;this.f&=-5;if(this.g===u)return!0;this.g=u;this.f|=1;if(this.i>0&&!c(this)){this.f&=-2;return!0}const t=i;try{h(this);i=this;const t=this.x();if(16&this.f||this.v!==t||0===this.i){this.v=t;this.f&=-17;this.i++}}catch(t){this.v=t;this.f|=16;this.i++}i=t;a(this);this.f&=-2;return!0};p.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(let t=this.s;void 0!==t;t=t.n)t.S.S(t)}f.prototype.S.call(this,t)};p.prototype.U=function(t){if(void 0!==this.t){f.prototype.U.call(this,t);if(void 0===this.t){this.f&=-33;for(let t=this.s;void 0!==t;t=t.n)t.S.U(t)}}};p.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(let t=this.t;void 0!==t;t=t.x)t.t.N()}};p.prototype.peek=function(){if(!this.h())t();if(16&this.f)throw this.v;return this.v};Object.defineProperty(p.prototype,"value",{get(){if(1&this.f)t();const n=l(this);this.h();if(void 0!==n)n.i=this.i;if(16&this.f)throw this.v;return this.v}});function d(t){return new p(t)}function v(t){const e=t.u;t.u=void 0;if("function"==typeof e){o++;const _=i;i=void 0;try{e()}catch(n){t.f&=-2;t.f|=8;y(t);throw n}finally{i=_;n()}}}function y(t){for(let n=t.s;void 0!==n;n=n.n)n.S.U(n);t.x=void 0;t.s=void 0;v(t)}function m(t){if(i!==this)throw new Error("Out-of-order effect");a(this);i=t;this.f&=-2;if(8&this.f)y(this);n()}function g(t){this.x=t;this.u=void 0;this.s=void 0;this.o=void 0;this.f=32}g.prototype.c=function(){const t=this.S();try{if(8&this.f)return;if(void 0===this.x)return;const n=this.x();if("function"==typeof n)this.u=n}finally{t()}};g.prototype.S=function(){if(1&this.f)t();this.f|=1;this.f&=-9;v(this);h(this);o++;const n=i;i=this;return m.bind(this,n)};g.prototype.N=function(){if(!(2&this.f)){this.f|=2;this.o=_;_=this}};g.prototype.d=function(){this.f|=8;if(!(1&this.f))y(this)};function b(t){const n=new g(t);try{n.c()}catch(t){n.d();throw t}return n.d.bind(n)}var k,S,x,w,C,E,U,H,N,P={},D=[],$=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,T=Array.isArray;function V(t,n){for(var e in n)t[e]=n[e];return t}function A(t){var n=t.parentNode;n&&n.removeChild(t)}function F(t,n,e){var i,_,o,r={};for(o in n)"key"==o?i=n[o]:"ref"==o?_=n[o]:r[o]=n[o];if(arguments.length>2&&(r.children=arguments.length>3?k.call(arguments,2):e),"function"==typeof t&&null!=t.defaultProps)for(o in t.defaultProps)void 0===r[o]&&(r[o]=t.defaultProps[o]);return M(t,r,i,_,null)}function M(t,n,e,i,_){var o={type:t,props:n,key:e,ref:i,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==_?++x:_};return null==_&&null!=S.vnode&&S.vnode(o),o}function W(){return{current:null}}function O(t){return t.children}function L(t,n){this.props=t,this.context=n}function R(t,n){if(null==n)return t.__?R(t.__,t.__.__k.indexOf(t)+1):null;for(var e;nn&&C.sort(H));q.__r=0}function B(t,n,e,i,_,o,r,u,l,f){var s,c,h,a,p,d,v,y=i&&i.__k||D,m=y.length;for(e.__k=[],s=0;s0?M(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):a)){if(a.__=e,a.__b=e.__b+1,null===(h=y[s])||h&&a.key==h.key&&a.type===h.type)y[s]=void 0;else for(c=0;c=0;n--)if((e=t.__k[n])&&(i=K(e)))return i;return null}function Q(t,n,e,i,_){var o;for(o in e)"children"===o||"key"===o||o in n||Y(t,o,null,e[o],i);for(o in n)_&&"function"!=typeof n[o]||"children"===o||"key"===o||"value"===o||"checked"===o||e[o]===n[o]||Y(t,o,n[o],e[o],i)}function X(t,n,e){"-"===n[0]?t.setProperty(n,null==e?"":e):t[n]=null==e?"":"number"!=typeof e||$.test(n)?e:e+"px"}function Y(t,n,e,i,_){var o;t:if("style"===n)if("string"==typeof e)t.style.cssText=e;else{if("string"==typeof i&&(t.style.cssText=i=""),i)for(n in i)e&&n in e||X(t.style,n,"");if(e)for(n in e)i&&e[n]===i[n]||X(t.style,n,e[n])}else if("o"===n[0]&&"n"===n[1])o=n!==(n=n.replace(/Capture$/,"")),n=n.toLowerCase()in t?n.toLowerCase().slice(2):n.slice(2),t.l||(t.l={}),t.l[n+o]=e,e?i||t.addEventListener(n,o?tt:Z,o):t.removeEventListener(n,o?tt:Z,o);else if("dangerouslySetInnerHTML"!==n){if(_)n=n.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==n&&"height"!==n&&"href"!==n&&"list"!==n&&"form"!==n&&"tabIndex"!==n&&"download"!==n&&"rowSpan"!==n&&"colSpan"!==n&&n in t)try{t[n]=null==e?"":e;break t}catch(t){}"function"==typeof e||(null==e||!1===e&&"-"!==n[4]?t.removeAttribute(n):t.setAttribute(n,e))}}function Z(t){return this.l[t.type+!1](S.event?S.event(t):t)}function tt(t){return this.l[t.type+!0](S.event?S.event(t):t)}function nt(t,n,e,i,_,o,r,u,l){var f,s,c,h,a,p,d,v,y,m,g,b,k,x,w,C=n.type;if(void 0!==n.constructor)return null;null!=e.__h&&(l=e.__h,u=n.__e=e.__e,n.__h=null,o=[u]),(f=S.__b)&&f(n);try{t:if("function"==typeof C){if(v=n.props,y=(f=C.contextType)&&i[f.__c],m=f?y?y.props.value:f.__:i,e.__c?d=(s=n.__c=e.__c).__=s.__E:("prototype"in C&&C.prototype.render?n.__c=s=new C(v,m):(n.__c=s=new L(v,m),s.constructor=C,s.render=rt),y&&y.sub(s),s.props=v,s.state||(s.state={}),s.context=m,s.__n=i,c=s.__d=!0,s.__h=[],s._sb=[]),null==s.__s&&(s.__s=s.state),null!=C.getDerivedStateFromProps&&(s.__s==s.state&&(s.__s=V({},s.__s)),V(s.__s,C.getDerivedStateFromProps(v,s.__s))),h=s.props,a=s.state,s.__v=n,c)null==C.getDerivedStateFromProps&&null!=s.componentWillMount&&s.componentWillMount(),null!=s.componentDidMount&&s.__h.push(s.componentDidMount);else{if(null==C.getDerivedStateFromProps&&v!==h&&null!=s.componentWillReceiveProps&&s.componentWillReceiveProps(v,m),!s.__e&&null!=s.shouldComponentUpdate&&!1===s.shouldComponentUpdate(v,s.__s,m)||n.__v===e.__v){for(n.__v!==e.__v&&(s.props=v,s.state=s.__s,s.__d=!1),s.__e=!1,n.__e=e.__e,n.__k=e.__k,n.__k.forEach((function(t){t&&(t.__=n)})),g=0;g2&&(u.children=arguments.length>3?k.call(arguments,2):e),M(t.type,u,i||t.key,_||t.ref,null)}function st(t,n){var e={__c:n="__cC"+N++,__:t,Consumer:function(t,n){return t.children(n)},Provider:function(t){var e,i;return this.getChildContext||(e=[],(i={})[n]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(t){this.props.value!==t.value&&e.some((function(t){t.__e=!0,j(t)}))},this.sub=function(t){e.push(t);var n=t.componentWillUnmount;t.componentWillUnmount=function(){e.splice(e.indexOf(t),1),n&&n.call(t)}}),t.children}};return e.Provider.__=e.Consumer.contextType=e}k=D.slice,S={__e:function(t,n,e,i){for(var _,o,r;n=n.__;)if((_=n.__c)&&!_.__)try{if((o=_.constructor)&&null!=o.getDerivedStateFromError&&(_.setState(o.getDerivedStateFromError(t)),r=_.__d),null!=_.componentDidCatch&&(_.componentDidCatch(t,i||{}),r=_.__d),r)return _.__E=_}catch(n){t=n}throw t}},x=0,w=function(t){return null!=t&&void 0===t.constructor},L.prototype.setState=function(t,n){var e;e=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=V({},this.state),"function"==typeof t&&(t=t(V({},e),this.props)),t&&V(e,t),null!=t&&this.__v&&(n&&this._sb.push(n),j(this))},L.prototype.forceUpdate=function(t){this.__v&&(this.__e=!0,t&&this.__h.push(t),j(this))},L.prototype.render=O,C=[],U="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,H=function(t,n){return t.__v.__b-n.__v.__b},q.__r=0,N=0;var ct,ht,at,pt,dt=0,vt=[],yt=[],mt=S.__b,gt=S.__r,bt=S.diffed,kt=S.__c,St=S.unmount;function xt(t,n){S.__h&&S.__h(ht,t,dt||n),dt=0;var e=ht.__H||(ht.__H={__:[],__h:[]});return t>=e.__.length&&e.__.push({__V:yt}),e.__[t]}function wt(t){return dt=1,Ct(It,t)}function Ct(t,n,e){var i=xt(ct++,2);if(i.t=t,!i.__c&&(i.__=[e?e(n):It(void 0,n),function(t){var n=i.__N?i.__N[0]:i.__[0],e=i.t(n,t);n!==e&&(i.__N=[e,i.__[1]],i.__c.setState({}))}],i.__c=ht,!ht.u)){var _=function(t,n,e){if(!i.__c.__H)return!0;var _=i.__c.__H.__.filter((function(t){return t.__c}));if(_.every((function(t){return!t.__N})))return!o||o.call(this,t,n,e);var r=!1;return _.forEach((function(t){if(t.__N){var n=t.__[0];t.__=t.__N,t.__N=void 0,n!==t.__[0]&&(r=!0)}})),!(!r&&i.__c.props===t)&&(!o||o.call(this,t,n,e))};ht.u=!0;var o=ht.shouldComponentUpdate,r=ht.componentWillUpdate;ht.componentWillUpdate=function(t,n,e){if(this.__e){var i=o;o=void 0,_(t,n,e),o=i}r&&r.call(this,t,n,e)},ht.shouldComponentUpdate=_}return i.__N||i.__}function Et(t,n){var e=xt(ct++,3);!S.__s&&Rt(e.__H,n)&&(e.__=t,e.i=n,ht.__H.__h.push(e))}function Ut(t,n){var e=xt(ct++,4);!S.__s&&Rt(e.__H,n)&&(e.__=t,e.i=n,ht.__h.push(e))}function Ht(t){return dt=5,Pt((function(){return{current:t}}),[])}function Nt(t,n,e){dt=6,Ut((function(){return"function"==typeof t?(t(n()),function(){return t(null)}):t?(t.current=n(),function(){return t.current=null}):void 0}),null==e?e:e.concat(t))}function Pt(t,n){var e=xt(ct++,7);return Rt(e.__H,n)?(e.__V=t(),e.i=n,e.__h=t,e.__V):e.__}function Dt(t,n){return dt=8,Pt((function(){return t}),n)}function $t(t){var n=ht.context[t.__c],e=xt(ct++,9);return e.c=t,n?(null==e.__&&(e.__=!0,n.sub(ht)),n.props.value):t.__}function Tt(t,n){S.useDebugValue&&S.useDebugValue(n?n(t):t)}function Vt(t){var n=xt(ct++,10),e=wt();return n.__=t,ht.componentDidCatch||(ht.componentDidCatch=function(t,i){n.__&&n.__(t,i),e[1](t)}),[e[0],function(){e[1](void 0)}]}function At(){var t=xt(ct++,11);if(!t.__){for(var n=ht.__v;null!==n&&!n.__m&&null!==n.__;)n=n.__;var e=n.__m||(n.__m=[0,0]);t.__="P"+e[0]+"-"+e[1]++}return t.__}function Ft(){for(var t;t=vt.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(Ot),t.__H.__h.forEach(Lt),t.__H.__h=[]}catch(u){t.__H.__h=[],S.__e(u,t.__v)}}S.__b=function(t){ht=null,mt&&mt(t)},S.__r=function(t){gt&>(t),ct=0;var n=(ht=t.__c).__H;n&&(at===ht?(n.__h=[],ht.__h=[],n.__.forEach((function(t){t.__N&&(t.__=t.__N),t.__V=yt,t.__N=t.i=void 0}))):(n.__h.forEach(Ot),n.__h.forEach(Lt),n.__h=[],ct=0)),at=ht},S.diffed=function(t){bt&&bt(t);var n=t.__c;n&&n.__H&&(n.__H.__h.length&&(1!==vt.push(n)&&pt===S.requestAnimationFrame||((pt=S.requestAnimationFrame)||Wt)(Ft)),n.__H.__.forEach((function(t){t.i&&(t.__H=t.i),t.__V!==yt&&(t.__=t.__V),t.i=void 0,t.__V=yt}))),at=ht=null},S.__c=function(t,n){n.some((function(t){try{t.__h.forEach(Ot),t.__h=t.__h.filter((function(t){return!t.__||Lt(t)}))}catch(s){n.some((function(t){t.__h&&(t.__h=[])})),n=[],S.__e(s,t.__v)}})),kt&&kt(t,n)},S.unmount=function(t){St&&St(t);var n,e=t.__c;e&&e.__H&&(e.__H.__.forEach((function(t){try{Ot(t)}catch(t){n=t}})),e.__H=void 0,n&&S.__e(n,e.__v))};var Mt="function"==typeof requestAnimationFrame;function Wt(t){var n,e=function(){clearTimeout(i),Mt&&cancelAnimationFrame(n),setTimeout(t)},i=setTimeout(e,100);Mt&&(n=requestAnimationFrame(e))}function Ot(t){var n=ht,e=t.__c;"function"==typeof e&&(t.__c=void 0,e()),ht=n}function Lt(t){var n=ht;t.__c=t.__(),ht=n}function Rt(t,n){return!t||t.length!==n.length||n.some((function(n,e){return n!==t[e]}))}function It(t,n){return"function"==typeof n?n(t):n}function jt(t,n){S[t]=n.bind(null,S[t]||(()=>{}))}let qt,Bt;function Gt(t){if(Bt)Bt();Bt=t&&t.S()}function zt({data:t}){const n=Kt(t);n.value=t;const e=Pt(()=>{let t=this.__v;while(t=t.__)if(t.__c){t.__c.__$f|=4;break}this.__$u.c=()=>{this.base.data=e.peek()};return d(()=>{let t=n.value.value;return 0===t?0:!0===t?"":t||""})},[]);return e.value}zt.displayName="_st";Object.defineProperties(f.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:zt},props:{configurable:!0,get(){return{data:this}}},__b:{configurable:!0,value:1}});jt("__b",(t,n)=>{if("string"==typeof n.type){let t,e=n.props;for(let i in e){if("children"===i)continue;let _=e[i];if(_ instanceof f){if(!t)n.__np=t={};t[i]=_;e[i]=_.peek()}}}t(n)});jt("__r",(t,n)=>{Gt();let e,i=n.__c;if(i){i.__$f&=-2;e=i.__$u;if(void 0===e)i.__$u=e=function(t){let n;b((function(){n=this}));n.c=()=>{i.__$f|=1;i.setState({})};return n}()}qt=i;Gt(e);t(n)});jt("__e",(t,n,e,i)=>{Gt();qt=void 0;t(n,e,i)});jt("diffed",(t,n)=>{Gt();qt=void 0;let e;if("string"==typeof n.type&&(e=n.__e)){let t=n.__np,i=n.props;if(t){let n=e.U;if(n)for(let e in n){let i=n[e];if(void 0!==i&&!(e in t)){i.d();n[e]=void 0}}else{n={};e.U=n}for(let _ in t){let o=n[_],r=t[_];if(void 0===o){o=Jt(e,_,r,i);n[_]=o}else o.o(r,i)}}}t(n)});function Jt(t,n,e,i){const _=n in t&&void 0===t.ownerSVGElement,o=s(e);return{o:(t,n)=>{o.value=t;i=n},d:b(()=>{const e=o.value.value;if(i[n]!==e){i[n]=e;if(_)t[n]=e;else if(e)t.setAttribute(n,e);else t.removeAttribute(n)}})}}jt("unmount",(t,n)=>{if("string"==typeof n.type){let t=n.__e;if(t){const n=t.U;if(n){t.U=void 0;for(let t in n){let e=n[t];if(e)e.d()}}}}else{let t=n.__c;if(t){const n=t.__$u;if(n){t.__$u=void 0;n.d()}}}t(n)});jt("__h",(t,n,e,i)=>{if(i<3)n.__$f|=2;t(n,e,i)});L.prototype.shouldComponentUpdate=function(t,n){const e=this.__$u;if(!(e&&void 0!==e.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(let i in n)return!0;for(let i in t)if("__source"!==i&&t[i]!==this.props[i])return!0;for(let i in this.props)if(!(i in t))return!0;return!1};function Kt(t){return Pt(()=>s(t),[])}function Qt(t){const n=Ht(t);n.current=t;qt.__$f|=4;return Pt(()=>d(()=>n.current()),[])}function Xt(t){const n=Ht(t);n.current=t;Et(()=>b(()=>n.current()),[])}var Yt=function(t,n,e,i){var _;n[0]=0;for(var o=1;o=5&&((_||!t&&5===i)&&(r.push(i,0,_,e),i=6),t&&(r.push(i,t,0,e),i=6)),_=""},l=0;l"===n?(i=1,_=""):_=n+_[0]:o?n===o?o="":_+=n:'"'===n||"'"===n?o=n:">"===n?(u(),i=1):i&&("="===n?(i=5,e=_,_=""):"/"===n&&(i<5||">"===t[l][f+1])?(u(),3===i&&(r=r[0]),i=r,(r=r[0]).push(2,0,i),i=0):" "===n||"\t"===n||"\n"===n||"\r"===n?(u(),i=2):_+=n),3===i&&"!--"===_&&(i=4,r=r[0])}return u(),r}(t)),n),arguments,[])).length>1?n:n[0]}var nn=tn.bind(F);export{L as Component,O as Fragment,f as Signal,e as batch,ft as cloneElement,d as computed,st as createContext,F as createElement,W as createRef,b as effect,F as h,nn as html,lt as hydrate,w as isValidElement,S as options,ut as render,s as signal,z as toChildArray,Dt as useCallback,Qt as useComputed,$t as useContext,Tt as useDebugValue,Et as useEffect,Vt as useErrorBoundary,At as useId,Nt as useImperativeHandle,Ut as useLayoutEffect,Pt as useMemo,Ct as useReducer,Ht as useRef,Kt as useSignal,Xt as useSignalEffect,wt as useState}; 2 | -------------------------------------------------------------------------------- /memory/__pycache__/chat_session.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itsPreto/baby-code/1783c7ff40adb909bb7b82ab6ad2ea4edb400ca0/memory/__pycache__/chat_session.cpython-311.pyc -------------------------------------------------------------------------------- /memory/chat_session.py: -------------------------------------------------------------------------------- 1 | class ChatSession: 2 | def __init__(self, session_id, timestamp): 3 | self.session_id = session_id 4 | self.timestamp = timestamp 5 | self.messages = [] 6 | 7 | def add_message(self, sender, content, timestamp): 8 | self.messages.append({ 9 | "sender": sender, 10 | "content": content, 11 | "timestamp": timestamp 12 | }) 13 | 14 | def to_dict(self): 15 | return { 16 | "session_id": self.session_id, 17 | "timestamp": self.timestamp, 18 | "messages": self.messages 19 | } 20 | 21 | @classmethod 22 | def from_dict(cls, data): 23 | session = cls(data["session_id"], data["timestamp"]) 24 | session.messages = data["messages"] 25 | return session 26 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==2.3.2 2 | flask-cors==4.0.0 3 | pandas==2.0.3 4 | zipfile36==0.1.3 5 | pydub==0.25.1 6 | numpy==1.24 7 | moviepy==1.0.3 8 | PyPDF2==3.0.1 9 | python-docx==0.8.11 10 | python-magic==0.4.27 11 | sentencepiece==0.1.99 12 | argparse~=1.4.0 13 | black~=22.8.0 14 | requests~=2.31.0 15 | matplotlib~=3.3.4 16 | Pillow>=9.2.0 17 | gguf>=0.1.0 18 | -------------------------------------------------------------------------------- /scripts/conver_to_dolly.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | with open('paste.txt', 'r') as f: 4 | content = f.read() 5 | 6 | parts = re.split(r'(---\n)', content) 7 | 8 | output = "" 9 | for i in range(0, len(parts), 2): 10 | question = parts[i].strip() 11 | answer = parts[i+1].strip() 12 | 13 | output += f""" 14 | Prompt: 15 | ### Instruction: 16 | Use the Task below and the Input given to write the Response, which is a programming code that can solve the Task. 17 | 18 | ### Task: 19 | Optimize a code snippet written in Python. {question} 20 | 21 | ### Input: 22 | {answer} 23 | 24 | ### Response: 25 | """ 26 | 27 | with open('output.txt', 'w') as f: 28 | f.write(output) -------------------------------------------------------------------------------- /scripts/process_ipynb_tutorials.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | 4 | base_url = "https://raw.githubusercontent.com/holtzy/The-Python-Graph-Gallery/master/src/notebooks/" 5 | 6 | files = [ 7 | "1-basic-barplot.ipynb", 8 | "10-barplot-with-number-of-observation.ipynb", 9 | "100-calling-a-color-with-seaborn.ipynb", 10 | "101-make-a-color-palette-with-seaborn.ipynb", 11 | "104-seaborn-themes.ipynb", 12 | "106-seaborn-style-on-matplotlib-plot.ipynb", 13 | "11-grouped-barplot.ipynb", 14 | "110-basic-correlation-matrix-with-seaborn.ipynb", 15 | "111-custom-correlogram.ipynb", 16 | "12-stacked-barplot-with-matplotlib.ipynb", 17 | "120-line-chart-with-matplotlib.ipynb", 18 | "121-line-chart-customization.ipynb", 19 | "122-multiple-lines-chart.ipynb", 20 | "123-highlight-a-line-in-line-plot.ipynb", 21 | "124-spaghetti-plot.ipynb", 22 | "125-small-multiples-for-line-chart.ipynb", 23 | "13-percent-stacked-barplot.ipynb", 24 | "130-basic-matplotlib-scatterplot.ipynb", 25 | "131-custom-a-matplotlib-scatterplot.ipynb", 26 | "132-basic-connected-scatterplot.ipynb", 27 | "134-how-to-avoid-overplotting-with-python.ipynb", 28 | "140-basic-pieplot-with-panda.ipynb", 29 | "150-parallel-plot-with-pandas.ipynb", 30 | "160-basic-donut-plot.ipynb", 31 | "161-custom-matplotlib-donut-plot.ipynb", 32 | "162-change-background-of-donut-plot.ipynb", 33 | "163-donut-plot-with-subgroups.ipynb", 34 | "170-basic-venn-diagram-with-2-groups.ipynb", 35 | "171-basic-venn-diagram-with-3-groups.ipynb", 36 | "172-custom-venn-diagram.ipynb", 37 | "173-elaborated-venn-diagram.ipynb", 38 | "174-change-background-colour-of-venn-diagram.ipynb", 39 | "180-basic-lollipop-plot.ipynb", 40 | "181-custom-lollipop-plot.ipynb", 41 | "182-vertical-lollipop-plot.ipynb", 42 | "183-highlight-a-group-in-lollipop.ipynb", 43 | "184-lollipop-plot-with-2-groups.ipynb", 44 | "185-lollipop-plot-with-conditional-color.ipynb", 45 | "190-custom-matplotlib-title.ipynb", 46 | "191-custom-axis-on-matplotlib-chart.ipynb", 47 | "192-about-matplotlib-margins.ipynb", 48 | "193-annotate-matplotlib-chart.ipynb", 49 | "194-split-the-graphic-window-with-subplot.ipynb", 50 | "196-select-one-color-with-matplotlib.ipynb", 51 | "197-available-color-palettes-with-matplotlib.ipynb", 52 | "199-matplotlib-style-sheets.ipynb", 53 | "2-horizontal-barplot.ipynb", 54 | "20-basic-histogram-seaborn.ipynb", 55 | "200-basic-treemap-with-python.ipynb", 56 | "201-control-the-color-of-treemap.ipynb", 57 | "202-treemap-with-colors-mapped-on-values.ipynb", 58 | "21-control-rug-and-density-on-seaborn-histogram.ipynb", 59 | "220-sankey-diagram-with-matplotlib.ipynb", 60 | "23-90degree-rotated-histogram.ipynb", 61 | "231-chord-diagram-with-bokeh.ipynb", 62 | "24-histogram-with-a-boxplot-on-top-seaborn.ipynb", 63 | "240-basic-area-chart.ipynb", 64 | "241-improve-area-chart.ipynb", 65 | "242-area-chart-and-faceting.ipynb", 66 | "243-area-chart-with-white-grid.ipynb", 67 | "25-histogram-with-several-variables-seaborn.ipynb", 68 | "250-basic-stacked-area-chart.ipynb", 69 | "251-stacked-area-chart-with-seaborn-style.ipynb", 70 | "252-baseline-options-for-stacked-area-chart.ipynb", 71 | "253-control-the-color-in-stacked-area-chart.ipynb", 72 | "254-pandas-stacked-area-chart.ipynb", 73 | "255-percentage-stacked-area-chart.ipynb", 74 | "260-basic-wordcloud.ipynb", 75 | "261-custom-python-wordcloud.ipynb", 76 | "262-worcloud-with-specific-shape.ipynb", 77 | "270-basic-bubble-plot.ipynb", 78 | "271-custom-your-bubble-plot.ipynb", 79 | "272-map-a-color-to-bubble-plot.ipynb", 80 | "281-basic-map-with-basemap.ipynb", 81 | "282-custom-appearance-of-basemap.ipynb", 82 | "283-set-bounding-box-in-basemap.ipynb", 83 | "284-different-types-of-map-projection.ipynb", 84 | "285-use-a-background-layer.ipynb", 85 | "286-boundaries-provided-in-basemap.ipynb", 86 | "288-map-background-with-folium.ipynb", 87 | "292-choropleth-map-with-folium.ipynb", 88 | "3-control-color-of-barplots.ipynb", 89 | "30-basic-boxplot-with-seaborn.ipynb", 90 | "300-draw-a-connection-line.ipynb", 91 | "31-horizontal-boxplot-with-seaborn.ipynb", 92 | "310-basic-map-with-markers.ipynb", 93 | "312-add-markers-on-folium-map.ipynb", 94 | "313-bubble-map-with-folium.ipynb", 95 | "315-a-world-map-of-surf-tweets.ipynb", 96 | "32-custom-boxplot-appearance-seaborn.ipynb", 97 | "320-basic-network-from-pandas-data-frame.ipynb", 98 | "321-custom-networkx-graph-appearance.ipynb", 99 | "322-network-layout-possibilities.ipynb", 100 | "323-directed-or-undirected-network.ipynb", 101 | "324-map-a-color-to-network-nodes.ipynb", 102 | "325-map-colour-to-the-edges-of-a-network.ipynb", 103 | "326-background-colour-of-network-chart.ipynb", 104 | "327-network-from-correlation-matrix.ipynb", 105 | "33-control-colors-of-boxplot-seaborn.ipynb", 106 | "34-grouped-boxplot.ipynb", 107 | "340-scatterplot-animation.ipynb", 108 | "341-python-gapminder-animation.ipynb", 109 | "342-animation-on-3d-plot.ipynb", 110 | "35-control-order-of-boxplot.ipynb", 111 | "36-add-jitter-over-boxplot-seaborn.ipynb", 112 | "370-3d-scatterplot.ipynb", 113 | "371-surface-plot.ipynb", 114 | "372-3d-pca-result.ipynb", 115 | "38-show-number-of-observation-on-boxplot.ipynb", 116 | "39-hidden-data-under-boxplot.ipynb", 117 | "390-basic-radar-chart.ipynb", 118 | "391-radar-chart-with-several-individuals.ipynb", 119 | "392-use-faceting-for-radar-chart.ipynb", 120 | "4-add-title-and-axis-label.ipynb", 121 | "40-basic-scatterplot-seaborn.ipynb", 122 | "400-basic-dendrogram.ipynb", 123 | "401-customised-dendrogram.ipynb", 124 | "402-color-dendrogram-labels.ipynb", 125 | "404-dendrogram-with-heat-map.ipynb", 126 | "405-dendrogram-with-heatmap-and-coloured-leaves.ipynb", 127 | "406-chord-diagram_mne.ipynb", 128 | "41-control-marker-features.ipynb", 129 | "42-custom-linear-regression-fit-seaborn.ipynb", 130 | "43-use-categorical-variable-to-color-scatterplot-seaborn.ipynb", 131 | "44-control-axis-limits-of-plot-seaborn.ipynb", 132 | "45-control-color-of-each-marker-seaborn.ipynb", 133 | "46-add-text-annotation-on-scatterplot.ipynb", 134 | "5-control-width-and-space-in-barplots.ipynb", 135 | "50-basic-violinplot-and-input-formats.ipynb", 136 | "500-network-chart-with-edge-bundling.ipynb", 137 | "502-violinplot-and-swarmplot.ipynb", 138 | "503-waffle-chart-introduction.ipynb", 139 | "504-histogram-with-colored-tails.ipynb", 140 | "505-Introduction-to-swarm-plot-in-seaborn.ipynb", 141 | "506-histogram-with-small-mutliples.ipynb", 142 | "51-horizontal-violinplot.ipynb", 143 | "52-custom-seaborn-violinplot.ipynb", 144 | "53-control-color-of-seaborn-violinplot.ipynb", 145 | "54-grouped-violinplot.ipynb", 146 | "55-control-order-of-groups-in-violinplot-seaborn.ipynb", 147 | "58-show-number-of-observation-on-violinplot.ipynb", 148 | "6-change-bars-texture.ipynb", 149 | "7-custom-barplot-layout.ipynb", 150 | "70-basic-density-plot-with-seaborn.ipynb", 151 | "71-density-plot-with-shade-seaborn.ipynb", 152 | "72-horizontal-density-plot.ipynb", 153 | "73-control-bandwidth-of-seaborn-density-plot.ipynb", 154 | "74-density-plot-of-several-variables.ipynb", 155 | "8-add-confidence-interval-on-barplot.ipynb", 156 | "80-contour-plot-with-seaborn.ipynb", 157 | "82-marginal-plot-with-seaborn.ipynb", 158 | "83-basic-2d-histograms-with-matplotlib.ipynb", 159 | "84-hexbin-plot-with-matplotlib.ipynb", 160 | "85-density-plot-with-matplotlib.ipynb", 161 | "86-avoid-overlapping-in-scatterplot-with-2d-density.ipynb", 162 | "90-heatmaps-with-various-input-format.ipynb", 163 | "91-customize-seaborn-heatmap.ipynb", 164 | "92-control-color-in-seaborn-heatmaps.ipynb", 165 | "94-use-normalization-on-seaborn-heatmap.ipynb", 166 | "_template.ipynb", 167 | "area-fill-between-two-lines-in-matplotlib.ipynb", 168 | "basic-barplot-with-seaborn.ipynb", 169 | "basic-histogram-in-matplotlib.ipynb", 170 | "basic-sankey-diagram-with-pysankey.ipynb", 171 | "basic-time-series-with-matplotlib.ipynb", 172 | "bubble-plot-with-seaborn.ipynb", 173 | "chord-diagram-python-chord.ipynb", 174 | "choropleth-map-geopandas-python.ipynb", 175 | "choropleth-map-plotly-python.ipynb", 176 | "circular-barplot-basic.ipynb", 177 | "circular-barplot-with-groups.ipynb", 178 | "circular-packing-1-level-hierarchy.ipynb", 179 | "circular-packing-several-levels-of-hierarchy.ipynb", 180 | "connected-scatterplot-for-evolution.ipynb", 181 | "custom-fonts-in-matplotlib.ipynb", 182 | "custom-legend-with-matplotlib.ipynb", 183 | "density-chart-matplotlib.ipynb", 184 | "density-chart-multiple-groups-seaborn.ipynb", 185 | "density-mirror.ipynb", 186 | "error-bars-on-barplot.ipynb", 187 | "grouped-barplot.ipynb", 188 | "heatmap-for-timeseries-matplotlib.ipynb", 189 | "hexbin-map-from-geojson-python.ipynb", 190 | "how-to-remove-axis-in-matplotlib.ipynb", 191 | "how-to-use-rectangles-in-matplotlib-legends.ipynb", 192 | "line-chart-dual-y-axis-with-matplotlib.ipynb", 193 | "manhattan-plot-with-matplotlib.ipynb", 194 | "map-read-geojson-with-python-geopandas.ipynb", 195 | "pie-plot-matplotlib-basic.ipynb", 196 | "ridgeline-graph-plotly.ipynb", 197 | "ridgeline-graph-seaborn.ipynb", 198 | "sankey-diagram-with-python-and-plotly.ipynb", 199 | "scatterplot-and-log-scale-in-matplotlib.ipynb", 200 | "scatterplot-with-regression-fit-in-matplotlib.ipynb", 201 | "seaborn-title-customization.ipynb", 202 | "stacked-and-percent-stacked-barplot.ipynb", 203 | "streamchart-basic-matplotlib.ipynb", 204 | "web-circular-barplot-with-matplotlib.ipynb", 205 | "web-circular-lollipop-plot-with-matplotlib.ipynb", 206 | "web-ggbetweenstats-with-matplotlib.ipynb", 207 | "web-heatmap-and-radial-barchart-plastics.ipynb", 208 | "web-highlighted-lineplot-with-faceting.ipynb", 209 | "web-horizontal-barplot-with-labels-the-economist.ipynb", 210 | "web-lemurs-parallel-chart.ipynb", 211 | "web-line-chart-with-labels-at-line-end.ipynb", 212 | "web-lineplots-and-area-chart-the-economist.ipynb", 213 | "web-lollipop-plot-with-python-mario-kart-64-world-records.ipynb", 214 | "web-lollipop-plot-with-python-the-office.ipynb", 215 | "web-multiple-lines-and-panels.ipynb", 216 | "web-radar-chart-with-matplotlib.ipynb", 217 | "web-scatterplot-astronaut.ipynb", 218 | "web-scatterplot-text-annotation-and-regression-matplotlib.ipynb", 219 | "web-stacked-line-chart-with-labels.ipynb", 220 | "web-streamchart-with-matplotlib.ipynb", 221 | "web-text-repel-with-matplotlib.ipynb", 222 | "web-time-series-and-facetting-with-matplotlib.ipynb" 223 | ] 224 | 225 | 226 | def get_raw_content(file_name): 227 | url = base_url + file_name 228 | response = requests.get(url) 229 | if response.status_code == 200: 230 | return response.text 231 | else: 232 | print(f"Failed to fetch {url}") 233 | return None 234 | 235 | def extract_qa_pairs(notebook_content): 236 | try: 237 | notebook = json.loads(notebook_content) 238 | cells = notebook['cells'] 239 | 240 | qa_pairs = [] 241 | for i in range(len(cells) - 1): 242 | if cells[i]['cell_type'] == 'markdown' and cells[i+1]['cell_type'] == 'code': 243 | question = ''.join(cells[i]['source']) 244 | answer = ''.join(cells[i+1]['source']) 245 | qa_pairs.append((question, answer)) 246 | 247 | return qa_pairs 248 | except Exception as e: 249 | print(f"Error parsing notebook: {e}") 250 | return [] 251 | 252 | 253 | all_qa_pairs = [] 254 | 255 | for file in files: 256 | content = get_raw_content(file) 257 | if content: 258 | qa_pairs = extract_qa_pairs(content) 259 | all_qa_pairs.extend(qa_pairs) 260 | 261 | # Save to a .txt file 262 | with open('qa_dataset.txt', 'w', encoding='utf-8') as f: 263 | for question, answer in all_qa_pairs: 264 | f.write("Question: " + question + "\n") 265 | f.write("Answer: " + answer + "\n") 266 | f.write("---\n") -------------------------------------------------------------------------------- /scripts/process_matplotlib_examples.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | def collect_python_files_content(root_folder): 4 | qa_pairs = [] 5 | 6 | # Recursively walk through directories 7 | for dirpath, dirnames, filenames in os.walk(root_folder): 8 | print(f"Processing {dirpath}...") 9 | for filename in filenames: 10 | if filename.endswith(".py"): 11 | print(f"Processing {filename}...") 12 | question = filename[:-3] # Remove .py extension 13 | file_path = os.path.join(dirpath, filename) 14 | with open(file_path, 'r', encoding='utf-8') as file: 15 | print(f"Reading {file_path}") 16 | try: 17 | answer = file.read() 18 | qa_pairs.append((question, answer)) 19 | except Exception as e: 20 | print(f"Error reading {file_path}: {e}") 21 | return qa_pairs 22 | 23 | def save_to_txt(qa_pairs, output_filename): 24 | with open(output_filename, 'w', encoding='utf-8') as f: 25 | for question, answer in qa_pairs: 26 | f.write("Question: " + question + "\n") 27 | f.write("Answer: " + answer + "\n") 28 | f.write("---\n") 29 | 30 | if __name__ == "__main__": 31 | root_folders = ["datasets/tutorials_python", "datasets/plot_types_python", "datasets/gallery_python"] 32 | all_qa_pairs = [] 33 | 34 | for root_folder in root_folders: 35 | print(f"Processing {root_folder}...") 36 | all_qa_pairs.extend(collect_python_files_content(root_folder)) 37 | 38 | save_to_txt(all_qa_pairs, "wip_qa_dataset.txt") 39 | print("Dataset saved to wip_qa_dataset.txt") 40 | -------------------------------------------------------------------------------- /scripts/proxy.py: -------------------------------------------------------------------------------- 1 | from mitmproxy import http 2 | import re 3 | 4 | 5 | def response(flow: http.HTTPFlow) -> None: 6 | if flow.request.pretty_url == "http://127.0.0.1:8080": # the url of the AI model server 7 | # this is a response from the AI model server 8 | data = flow.response.text # get the response data 9 | # check if the response contains Python code and store it if it does 10 | codeBlockRegex = r'```python\n([\s\S]*?)```' 11 | matches = re.findall(codeBlockRegex, data) 12 | if matches: 13 | for match in matches: 14 | print(f"Found Python code in response: {match}") # replace this with your actual code storage function 15 | -------------------------------------------------------------------------------- /scripts/update_deps.py: -------------------------------------------------------------------------------- 1 | import re 2 | import requests 3 | 4 | 5 | def get_latest_version(package_name: str) -> str: 6 | """ 7 | Retrieves the latest version of a package from PyPI. 8 | 9 | Args: 10 | package_name (str): The name of the package to retrieve the latest version for. 11 | 12 | Returns: 13 | str: The latest version of the specified package. 14 | 15 | Raises: 16 | Exception: If there is an error retrieving the package information from PyPI. 17 | """ 18 | pypi_api_url = f"https://pypi.org/pypi/{package_name}/json" 19 | response = requests.get(pypi_api_url) 20 | 21 | if response.status_code == 200: 22 | latest_version = response.json()["info"]["version"] 23 | return latest_version 24 | else: 25 | raise Exception(f"Error retrieving {package_name} information. Status code: {response.status_code}") 26 | 27 | 28 | def update_requirements_txt(file_path: str) -> None: 29 | """ 30 | Updates the requirements.txt file with the latest versions of packages. 31 | 32 | Args: 33 | file_path (str): The path to the requirements.txt file. 34 | 35 | Returns: 36 | None: This function does not return anything. 37 | """ 38 | with open(file_path, "r") as file: 39 | requirements = file.readlines() 40 | 41 | updated_requirements = [] 42 | 43 | for line in requirements: 44 | match = re.match(r"^([a-zA-Z0-9-_.]+)==(.+)$", line.strip()) 45 | if match: 46 | package_name, current_version = match.groups() 47 | latest_version = get_latest_version(package_name) 48 | 49 | if current_version != latest_version: 50 | print(f"Updating {package_name} from {current_version} to {latest_version}") 51 | updated_requirements.append(f"{package_name}=={latest_version}\n") 52 | else: 53 | print(f"{package_name} is up to date ({current_version})") 54 | updated_requirements.append(line) 55 | else: 56 | print(f"Skipping unrecognized line: {line.strip()}") 57 | updated_requirements.append(line) 58 | 59 | with open(file_path, "w") as file: 60 | file.writelines(updated_requirements) 61 | print("Requirements file updated.") 62 | 63 | 64 | requirements_file_path = "/Users/marconeves/Desktop/desktop/projects/baby-llama.pycpp/baby-code/requirements.txt" 65 | update_requirements_txt(requirements_file_path) -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | body {color: white;position: relative;display: flex;height: 100vh;max-width: 66vw;min-height: 100vh;line-height: 1.2;margin: 0 auto;padding: 0 5.5em;overflow-y: hidden;overflow-x: hidden;background: linear-gradient(to right, #4bca3a9e, #f9f9f996, #7341eaa6);font-family: Arial, sans-serif;flex-direction: column;align-items: center;justify-content: space-between;} 2 | 3 | .toggles { 4 | margin-top: 16px; 5 | display: contents; 6 | } 7 | 8 | #chat { 9 | display: flex; 10 | margin: 10px; 11 | flex-direction: column; 12 | align-items: flex-end; 13 | } 14 | 15 | ::-webkit-scrollbar { 16 | width: 0; /* Remove scrollbar space */ 17 | background: transparent; /* Optional: just make scrollbar invisible */ 18 | } 19 | /* Optional: show position indicator in red */ 20 | ::-webkit-scrollbar-thumb { 21 | background: #ff000000; 22 | } 23 | 24 | #container { 25 | /* color: #ffffff; */ 26 | overflow: auto; 27 | box-shadow: 0px 13px 15px 8px rgba(0, 0, 0, 0.2); 28 | margin-top: 20px; 29 | min-height: 90vh; 30 | transition: all ease-in 0.3s; 31 | min-width: 33vh; 32 | overflow-x: hidden; 33 | display: flex; 34 | background: #bcbbbad9; 35 | flex-direction: column; 36 | justify-content: center; 37 | align-items: center; 38 | position: relative; 39 | max-width: 90vw; 40 | margin-bottom: 20px; 41 | animation: slideFromTop 1s cubic-bezier(0, 0, 0, 1.63); 42 | max-height: 44vh; 43 | border-radius: 43px; 44 | } 45 | 46 | main {display: flex;gap: 1em;flex-grow: 2;margin-top: 8px;overflow-y: auto;overflow-x: hidden;min-width: 60vw;background: #ffffff61;transition: all 0.5s ease-in-out;box-shadow: 0px 2px 11px 3px rgb(0 0 0 / 19%);border-radius: 8px;margin-bottom: 4px;animation: flyInFromRight 1.2s cubic-bezier(0.4, 0, 1, 1);padding: 10px;justify-content: center;} 47 | 48 | 49 | 50 | @font-face { 51 | font-family: 'Sunny Spells'; 52 | src: url('./assets/fonts/Sunny\ Spells.otf') format('opentype'), 53 | url('./assets/fonts/Sunny\ Spells.ttf') format('truetype'); 54 | } 55 | 56 | a {color: #54349f;} 57 | 58 | p { 59 | /* overflow-wrap: break-word; */ 60 | word-wrap: break-word; 61 | hyphens: auto; 62 | color: #e6d2b8; 63 | /* background: black; */ 64 | /* width: 90%; */ 65 | /* justify-content: center; */ 66 | /* padding: 15px; */ 67 | /* border-radius: 24px; */ 68 | margin-top: 0.5em; 69 | margin-bottom: 0.5em; 70 | } 71 | 72 | p.strong { 73 | color: aliceblue; 74 | } 75 | 76 | 77 | #write form { 78 | margin: 1em 0 0 0; 79 | display: flex; 80 | width: 100%; 81 | flex-direction: column; 82 | gap: 0.5em; 83 | text-align: center; 84 | align-items: stretch; 85 | } 86 | 87 | .right { 88 | display: flex; 89 | flex-direction: row; 90 | gap: 0.5em; 91 | margin-bottom: 30px; 92 | justify-content: center; 93 | animation: fade-in 3s ease; 94 | } 95 | 96 | fieldset { 97 | border: none; 98 | padding: 0; 99 | margin: 0; 100 | } 101 | 102 | fieldset.two {display: grid;justify-content: center;border: 1px solid #fff;margin-top: 7px;padding: 12px;width: fit-content;text-shadow: 1px 0px 1px black;box-shadow: inset 0px 5px 7px 0px rgb(141 141 141 / 60%);background: linear-gradient(to left, #4185369e, #5e439e87);border-radius: 21px;border-color: #0a0a0a00;grid-template: 103 | "a a";gap: 1em;justify-items: center;} 104 | 105 | fieldset.two { 106 | transition: transform 0.3s ease, box-shadow 0.3s ease; /* smooth transition for the hover effect */ 107 | } 108 | 109 | fieldset.two:hover { 110 | box-shadow: inset 0 4px 8px rgb(0 0 0 / 77%); /* inset shadow */ 111 | transform: scale(0.98); /* slightly scale down */ 112 | } 113 | 114 | fieldset.three { 115 | display: grid; 116 | grid-template: "a a a"; 117 | gap: 1em; 118 | } 119 | 120 | .greenHighlight { 121 | color: green; 122 | font-size: 12; 123 | text-shadow: 1px 0px 1px black; 124 | } 125 | 126 | .yellowHighlight { 127 | color: yellow; 128 | } 129 | 130 | .redHighlight { 131 | color: red; 132 | background: black; 133 | letter-spacing: 2px; 134 | word-spacing: 5px; 135 | padding: 2px; 136 | border-radius: 3px; 137 | } 138 | 139 | details { 140 | border: 1px solid #fff; 141 | /* background: #919191; */ 142 | border-radius: 16px; 143 | /* padding: 0.5em 0.5em 0; */ 144 | margin-top: 0.5em; 145 | } 146 | 147 | summary { 148 | font-weight: bold; 149 | margin: 0.02em -0.5em 0; 150 | padding: 0.5em; 151 | cursor: pointer; 152 | } 153 | 154 | textarea { 155 | padding: 10px; 156 | height: 10vh; 157 | width: 100%; 158 | flex-grow: 1; 159 | border-radius: 8px; 160 | transition: all 0.8s ease-in-out; 161 | /* box-shadow: 1px -4px 20px 4px rgba(0, 0, 0, 0.2); */ 162 | color: black; 163 | background: #000000a8; 164 | /* border-radius: 12px; */ 165 | } 166 | 167 | textarea#inputarea { 168 | width: 50vw; 169 | } 170 | 171 | textarea#inputarea:hover { 172 | transform: scale(0.98) translateY(-4px); 173 | } 174 | 175 | textarea:hover { 176 | transform: scale(0.98) translateY(4px); 177 | } 178 | 179 | 180 | pre code { 181 | display: block; 182 | color: #000; 183 | } 184 | 185 | pre { 186 | position: relative; 187 | } 188 | 189 | #codeblock { 190 | width: fit-content; 191 | height: fit-content; 192 | margin-top: 18px; 193 | margin-right: 20px; 194 | margin-bottom: -43px; 195 | margin-left: 23px; 196 | } 197 | 198 | .editButton, .codeblock-checkbox ,.diffbutton, .saveButton, .copyButton, .runButton { 199 | display: flex; 200 | align-items: center; 201 | justify-content: space-around; 202 | height: 23px; 203 | border-radius: 20px; 204 | border: none; 205 | cursor: pointer; 206 | position: absolute; 207 | top: 4px; 208 | padding: 4px; 209 | } 210 | 211 | .editButton, .diffbutton, .saveButton, .copyButton, .runButton { 212 | top: 6px; 213 | width: 24px; 214 | } 215 | 216 | .codeblock-checkbox { 217 | left: 30px; 218 | margin:inherit 4px; 219 | width: 15px; 220 | } 221 | 222 | .diffButton {right: 136px;} 223 | 224 | .copyButton {right: 65px;} 225 | 226 | .saveButton {right: 100px;} 227 | 228 | .runButton { 229 | right: 30px; 230 | transition: all 0.2s ease-in-out; 231 | } 232 | 233 | .runButton:hover { 234 | color: green; 235 | width: 30px; 236 | transform: translateX(8px); 237 | } 238 | 239 | 240 | .editButton { 241 | right: 170px; 242 | } 243 | 244 | code { 245 | font-family: monospace; 246 | color: #0fa78f; 247 | } 248 | 249 | label { 250 | color: #21201f; 251 | font-style: italic; 252 | font-size: 16px; 253 | } 254 | 255 | fieldset label { 256 | margin: 0.5em 0; 257 | display: block; 258 | } 259 | 260 | header, footer { 261 | text-align: center; 262 | } 263 | 264 | footer { 265 | font-size: 60%; 266 | padding-top: 5px; 267 | padding-right: 60px; 268 | padding-bottom: 5px; 269 | padding-left: 60px; 270 | border-top-left-radius: 40px; 271 | border-top-right-radius: 40px; 272 | background: linear-gradient(to left, #005c4f47, #b93e0054); 273 | color: #888; 274 | } 275 | 276 | code[class*=language-], 277 | pre[class*=language-] { 278 | color: #f8f8f2; /* Bright text color */ 279 | white-space: pre-line; 280 | word-spacing: normal; 281 | word-break: normal; 282 | border-radius: 40px; 283 | margin: 14px; 284 | background: #282a36; /* Dark Background */ 285 | word-wrap: normal; 286 | justify-content: center; 287 | -moz-tab-size: 4; 288 | -o-tab-size: 4; 289 | tab-size: 2; 290 | -webkit-hyphens: none; 291 | -moz-hyphens: none; 292 | -ms-hyphens: none; 293 | hyphens: none; 294 | } 295 | 296 | code[class*=language-] ::-moz-selection, 297 | code[class*=language-]::-moz-selection, 298 | pre[class*=language-] ::-moz-selection, 299 | pre[class*=language-]::-moz-selection { 300 | text-shadow: none; 301 | background: #44475a /* Moderate dark color for selection */ 302 | } 303 | 304 | code[class*=language-] ::selection, 305 | code[class*=language-]::selection, 306 | pre[class*=language-] ::selection, 307 | pre[class*=language-]::selection { 308 | text-shadow: none; 309 | background: #44475a; /* Moderate dark color for selection */ 310 | } 311 | 312 | @media print { 313 | code[class*=language-], 314 | pre[class*=language-] { 315 | text-shadow: none; 316 | } 317 | } 318 | 319 | pre[class*=language-] { 320 | /* padding-left: 5em; */ 321 | margin-bottom: -3.5em; 322 | margin-left: -5px; 323 | } 324 | 325 | :not(pre)>code[class*=language-], 326 | pre[class*=language-] { 327 | background: #00000000; /* Black background */ 328 | } 329 | 330 | :not(pre)>code[class*=language-] { 331 | padding: .1em; 332 | border-radius: .3em; 333 | white-space: normal; 334 | } 335 | 336 | .token.cdata, 337 | .token.comment, 338 | .token.doctype, 339 | .token.prolog { 340 | color: #8be9fd; /* Cyan color */ 341 | font-style: italic; 342 | } 343 | 344 | #logo { 345 | display: inline-block; 346 | font-size: 24px; 347 | transition: transform 0.5s; 348 | } 349 | 350 | .spinning { 351 | animation: spin 1s linear infinite; 352 | } 353 | 354 | @keyframes spin { 355 | 0% { transform: rotate(0deg); } 356 | 100% { transform: rotate(-360deg); } 357 | } 358 | 359 | .token.punctuation { 360 | color: #f8f8f2; /* Bright text color */ 361 | font-weight: bold; 362 | } 363 | 364 | .token.namespace { 365 | opacity: .7 366 | } 367 | 368 | .token.boolean, 369 | .token.constant, 370 | .token.deleted, 371 | .token.number, 372 | .token.property, 373 | .token.symbol, 374 | .token.tag { 375 | font-weight: bold; 376 | color: #ff5555; /* Bright red color */ 377 | font-style: italic; 378 | } 379 | 380 | .token.attr-name, 381 | .token.builtin, 382 | .token.char, 383 | .token.inserted, 384 | .token.selector, 385 | .token.string { 386 | color: #50fa7b; /* Green color */ 387 | } 388 | 389 | .language-css .token.string, 390 | .style .token.string, 391 | .token.entity, 392 | .token.operator, 393 | .token.url { 394 | color: #f1fa8c; /* Yellow color */ 395 | /* Black background */ 396 | } 397 | 398 | .token.atrule, 399 | .token.attr-value, 400 | .token.keyword { 401 | color: #bd93f9; /* Purple color */ 402 | } 403 | 404 | .token.class-name, 405 | .token.function { 406 | color: #f8f8f2; /* Bright text color */ 407 | } 408 | 409 | .token.important, 410 | .token.regex, 411 | .token.variable { 412 | color: #ffb86c; /* Orange color */ 413 | } 414 | 415 | .token.bold, 416 | .token.important { 417 | font-weight: 700; 418 | } 419 | 420 | .token.italic { 421 | font-style: italic; 422 | } 423 | 424 | .token.entity { 425 | cursor: help; 426 | } 427 | 428 | 429 | button { 430 | border: none; 431 | background-color: #ffffff; 432 | /* Removes background color */ 433 | border: none; 434 | /* Removes border */ 435 | color: black; 436 | width: 55px; 437 | height: 25px; 438 | cursor: pointer; 439 | border-radius: 5px; 440 | } 441 | 442 | button:hover { 443 | } 444 | 445 | /* Crash in from the top with bounce */ 446 | @keyframes crashInFromTop { 447 | 0% { 448 | transform: translateY(-100vh); 449 | animation-timing-function: ease-in; 450 | } 451 | 452 | 38% { 453 | transform: translateY(0); 454 | animation-timing-function: ease-out; 455 | } 456 | 457 | 55% { 458 | transform: translateY(-65vh); 459 | animation-timing-function: ease-in; 460 | } 461 | 462 | 72% { 463 | transform: translateY(0); 464 | animation-timing-function: ease-out; 465 | } 466 | 467 | 81% { 468 | transform: translateY(-28vh); 469 | animation-timing-function: ease-in; 470 | } 471 | 472 | 90% { 473 | transform: translateY(0); 474 | animation-timing-function: ease-out; 475 | } 476 | 477 | 95% { 478 | transform: translateY(-8vh); 479 | animation-timing-function: ease-in; 480 | } 481 | 482 | 100% { 483 | transform: translateY(0); 484 | animation-timing-function: ease-out; 485 | } 486 | } 487 | 488 | @keyframes slideFromTop { 489 | 0% { 490 | transform: translateY(-100vh); 491 | } 492 | 493 | 100% { 494 | transform: translateY(0); 495 | } 496 | } 497 | 498 | /* Fly in from the left */ 499 | @keyframes flyInFromLeft { 500 | 0% { 501 | transform: translateX(-100vw); 502 | } 503 | 504 | 100% { 505 | transform: translateX(0); 506 | } 507 | } 508 | 509 | /* Fly in from the right */ 510 | @keyframes flyInFromRight { 511 | 0% { 512 | transform: translateX(100vw); 513 | } 514 | 515 | 100% { 516 | transform: translateX(0); 517 | } 518 | } 519 | 520 | /* Fly in from the bottom */ 521 | @keyframes flyInFromBottom { 522 | 0% { 523 | transform: translateY(100vh); 524 | } 525 | 526 | 100% { 527 | transform: translateY(0); 528 | } 529 | } 530 | 531 | @keyframes flyOutToBottom { 532 | 0% { 533 | transform: translateY(0); 534 | } 535 | 536 | 100% { 537 | transform: translateY(100vh); 538 | } 539 | } 540 | 541 | #main_output_container { 542 | margin-top: 15px; 543 | flex-direction: row-reverse; 544 | } 545 | 546 | @keyframes slide { 547 | 0% { 548 | transform: translateX(0); 549 | } 550 | 551 | 100% { 552 | transform: translateX(-50%); 553 | } 554 | 555 | /* For two slide-tracks */ 556 | } 557 | 558 | @keyframes bounce { 559 | 560 | 0%, 561 | 20%, 562 | 50%, 563 | 80%, 564 | 100% { 565 | transform: translateY(0); 566 | } 567 | 568 | 40% { 569 | transform: translateY(-10px); 570 | } 571 | 572 | 60% { 573 | transform: translateY(-5px); 574 | } 575 | } 576 | 577 | 578 | 579 | @keyframes TitleGradientAnimation { 580 | 0% { 581 | background-position: 100% 0px; 582 | } 583 | 584 | 25% { 585 | background-position: 25% 25%; 586 | } 587 | 588 | 50% { 589 | background-position: 0px 50%; 590 | } 591 | 592 | 75% { 593 | background-position: 75% 25%; 594 | } 595 | 596 | 100% { 597 | background-position: 100% 0px; 598 | } 599 | } 600 | 601 | @keyframes fade-in { 602 | 0% { 603 | opacity: 0; 604 | } 605 | 606 | 100% { 607 | opacity: 1; 608 | } 609 | } 610 | 611 | @keyframes fade-out { 612 | 0% { 613 | opacity: 1; 614 | } 615 | 100% { 616 | opacity: 0; 617 | } 618 | } 619 | 620 | .rotate-icon { 621 | display: inline-block; /* This ensures that the transform property works as expected */ 622 | transform-origin: center; 623 | transition: all 0.3s ease; /* This will ensure a smooth transition in both directions */ 624 | } 625 | 626 | #randButton { 627 | margin-right: -10px; 628 | } 629 | 630 | #sendButton:hover .rotate-icon { 631 | color: #69c95c; 632 | transform: rotate(-30deg) translate3d(6px, -2px, 3px); 633 | } 634 | 635 | #sendButton:hover { 636 | background-color: transparent; /* Background becomes transparent on hover */ 637 | } 638 | 639 | #sendButton { 640 | background-color: #00d600a1; /* Initial background color */ 641 | transition: all 0.3s ease-in-out; /* Transition for smooth animation */ 642 | } 643 | 644 | /* Hover effect for the send button */ 645 | #sendButton:hover, #sendButton:hover .rotate-icon { 646 | background-color: transparent; /* Background becomes transparent on hover */ 647 | } 648 | 649 | .container pre { 650 | display: flex; 651 | flex-wrap: nowrap; 652 | justify-content: space-evenly; 653 | align-items: flex-start; 654 | flex-direction: row-reverse; 655 | } 656 | 657 | .container::before { 658 | color: #ffffff8e; /* Placeholder text color */ 659 | text-align: center; 660 | opacity: 0.0; 661 | display: var(--empty, flex); 662 | justify-content: center; 663 | align-items: center; 664 | overflow-y: auto; 665 | position: absolute; 666 | width: 100%; 667 | height: 100%; 668 | } 669 | 670 | code.language-python { 671 | background-color: #87c25e52; 672 | max-width: 60vmax; 673 | white-space: pre-wrap; 674 | margin-bottom: -70px; 675 | text-align: start; 676 | transition: all ease-in 0.2s; 677 | padding-right: 20px; 678 | padding-bottom: 20px; 679 | padding-left: 20px; 680 | border-radius: 44px; 681 | } 682 | 683 | .container:not(:empty)::before { 684 | --empty: none; 685 | } 686 | 687 | .bottom-bar { 688 | display: flex; 689 | justify-content: space-between; 690 | border-top-left-radius: 16px; 691 | border-top-right-radius: 16px; 692 | align-items: center; 693 | width: 100vw; 694 | height: 60px; /* Adjust as needed */ 695 | background-color: #124f598c; /* Adjust color as needed */ 696 | } 697 | 698 | .carousel-container { 699 | flex: 0.7; 700 | display: flex; 701 | overflow-x: auto; 702 | gap: 10px; /* Space between chat cards */ 703 | } 704 | 705 | .chat-card { 706 | min-width: 100px; /* Adjust as needed */ 707 | cursor: grabbing; 708 | height: 40px; /* Adjust as needed */ 709 | background-color: #e0e0e0; /* Adjust color as needed */ 710 | border-radius: 5px; 711 | display: flex; 712 | align-items: center; 713 | justify-content: center; 714 | } 715 | 716 | .buttons-container { 717 | flex: inherit; 718 | display: flex; 719 | margin-right: 16px; 720 | gap: 10px; /* Space between buttons */ 721 | margin-bottom: 20px; 722 | } 723 | 724 | 725 | 726 | 727 | p.user { 728 | background: #0088ff; 729 | text-align: start; 730 | margin-left:14px; 731 | overflow-wrap: anywhere; 732 | margin-top: 20px; 733 | margin-bottom: 20px; 734 | margin-right:14px; 735 | width: fit-content; 736 | display: inline-block; 737 | animation: flyInFromRight 0.7s cubic-bezier(0.4, 0, 0.2, 1); 738 | transition: all ease-in 0.2s; 739 | padding: 16px; 740 | border-radius: 32px; 741 | } 742 | 743 | p.char { 744 | background: black; 745 | border-radius: 32px; 746 | margin-right: 48px; 747 | max-width: 900px; 748 | /* text-align: start; */ 749 | padding: 16px; 750 | margin-left: 10px; 751 | transition: all ease-in 0.3s; 752 | } 753 | 754 | 755 | p.user:hover { 756 | transform: translateX(-6px); 757 | } 758 | 759 | .language-python.error { 760 | background-color: #d65c5c6e; /* Change this to the color you want for failed execution */ 761 | transition: all ease-in 0.2s; 762 | } 763 | 764 | .language-python:hover { 765 | transform: translateY(2px); 766 | } 767 | 768 | .language-python { 769 | transition: all 0.8s ease-in-out; 770 | } 771 | 772 | @keyframes rotateIn { 773 | from { 774 | transform: rotate(0deg); 775 | } 776 | to { 777 | transform: rotate(360deg); 778 | } 779 | } 780 | 781 | @keyframes rotateOut { 782 | from { 783 | transform: rotate(360deg); 784 | } 785 | to { 786 | transform: rotate(0deg); 787 | } 788 | } 789 | 790 | /* Apply the animation on hover */ 791 | #resetButton:hover .fas.fa-redo { 792 | animation: rotateIn 0.5s forwards; 793 | } 794 | 795 | /* Reset the animation when not hovered */ 796 | #resetButton .fas.fa-redo { 797 | animation: rotateOut 0.5s forwards; 798 | } 799 | 800 | fieldset div label { 801 | display: block; /* Make the label block-level so it takes up the full width */ 802 | border-bottom: 1px solid #100f0f; 803 | margin-bottom: 10px; 804 | padding-bottom: 5px; 805 | } 806 | 807 | #randomizeButton { 808 | transition: all 0.3s ease; /* This will ensure a smooth transition in both directions */ 809 | background-color: #9b00d661; /* Initial background color */ 810 | } 811 | 812 | #randomizeButton:hover { 813 | background-color: #9b00d600; /* Initial background color */ 814 | } 815 | 816 | #randomizeButton i { 817 | transition: all 0.3s ease; /* This will ensure a smooth transition in both directions */ 818 | } 819 | 820 | /* Randomize Button Icon Hover Animation */ 821 | #randomizeButton:hover i, #randomizeButton i:hover { 822 | color: #af79c1; 823 | background-color: #9b00d600; 824 | animation: rotisserieSpin 1.4s cubic-bezier(0.32, 0, 0.67, 1) infinite; 825 | } 826 | 827 | @keyframes rotisserieSpin { 828 | 0% { transform: scale(1.2) rotateX(0deg); } 829 | 50% { transform: scale(0.7) rotateX(180deg); } 830 | 100% { transform: scale(1.2) rotateX(360deg); } 831 | } 832 | @keyframes shrinkAndToss { 833 | 0% { 834 | transform: scale(1); 835 | opacity: 1; 836 | } 837 | 30% { 838 | transform: scale(0.9); 839 | opacity: 0.8; 840 | } 841 | 100% { 842 | transform: scale(1); 843 | opacity: 1; 844 | } 845 | } 846 | 847 | .shrink-and-toss { 848 | animation: shrinkAndToss 1s forwards; 849 | } 850 | 851 | /* Initial styles for the stop button and its icon */ 852 | #stopButton { 853 | cursor: pointer; 854 | background-color: #ff0000a1; /* Initial background color */ 855 | transition: background-color 0.3s ease-in-out; /* Transition for smooth animation */ 856 | } 857 | 858 | #stopButton i { 859 | color: white; /* Initial icon color */ 860 | transition: all 0.3s ease-in-out; /* Transition for smooth animation */ 861 | } 862 | 863 | /* Hover styles for the stop button and its icon */ 864 | #stopButton:hover { 865 | background-color: transparent; /* Background becomes transparent on hover */ 866 | } 867 | 868 | #stopButton:hover i { 869 | transform: scale(1.2) translateY(-4px); 870 | color: red; /* Icon color changes to red on hover */ 871 | } 872 | 873 | #diff-overlay { 874 | display: none; 875 | position: absolute; 876 | width: 100%; 877 | height: 100%; 878 | background-color: rgb(0 0 0 / 0%); 879 | z-index: 9999; 880 | overflow: auto; 881 | padding: 20px; 882 | /* opacity: 0; */ 883 | /* visibility: hidden; */ 884 | transition: opacity 0.3s ease-out; 885 | } 886 | 887 | #diff-result { 888 | text-wrap: balance; 889 | } 890 | 891 | #diff-content { 892 | background-color: #1c2f29; 893 | margin: 15% auto; 894 | padding: 20px; 895 | width: fit-content; 896 | max-width: 70vw; 897 | border-radius: 16px; 898 | opacity: 0; 899 | visibility: hidden; 900 | transition: opacity 0.3s ease, visibility 0.3s ease; 901 | box-shadow: 0 4px 8px 0 darkslategrey; 902 | position: relative; 903 | } 904 | 905 | #diff-content.visible { 906 | opacity: 1; 907 | visibility: visible; 908 | } 909 | 910 | 911 | #diff-close { 912 | width: 50px; 913 | height: 50px; 914 | cursor: pointer; 915 | position: absolute; 916 | top: 0; 917 | right: -20px; 918 | cursor: pointer; 919 | font-size: 25px; 920 | color: red; 921 | } 922 | 923 | 924 | #diff-result .addition { 925 | color: #00c500; 926 | /* Light green background */ 927 | } 928 | 929 | #diff-result .deletion { 930 | color: #cc0000; 931 | /* Light red background */ 932 | } 933 | 934 | .flyInFromBottom { 935 | animation: flyInFromBottom 0.5s forwards; 936 | } 937 | 938 | .flyOutToBottom { 939 | animation: flyOutToBottom 0.5s forwards; 940 | } 941 | 942 | #score-container-left, #score-container-right { 943 | position: fixed; 944 | top: 10px; 945 | width: 120px; 946 | color: rgb(0, 0, 0); 947 | background: #ffffff9c; 948 | letter-spacing: 2px; 949 | text-align: center; 950 | font-size:18px; 951 | text-shadow: rgb(53 44 44 / 19%) -3px 4px 2px; 952 | font-family: "Sunny Spells", fallbackFont, sans-serif; 953 | padding: 5px 10px; 954 | border-radius: 5px; 955 | font-weight: bold; 956 | } 957 | 958 | #score-container-left { 959 | animation: 1.9s cubic-bezier(0.4, 0, 1, 1) 0s 1 normal none running flyInFromLeft; 960 | left: 10px; 961 | } 962 | 963 | #score-container-right { 964 | animation: 2.1s cubic-bezier(0.4, 0, 1, 1) 0s 1 normal none running flyInFromRight; 965 | right: 10px; 966 | } 967 | 968 | 969 | @keyframes dotScroll { 970 | 0% { 971 | background-position-y: 140px 972 | } 973 | 974 | to { 975 | background-position-y: 0 976 | } 977 | } 978 | 979 | *,:before,:after { 980 | box-sizing: border-box; 981 | border-width: 0; 982 | border-style: solid; 983 | border-color: #161e29 984 | } 985 | 986 | :before,:after { 987 | --tw-content: "" 988 | } 989 | 990 | html { 991 | line-height: 1.5; 992 | -webkit-text-size-adjust: 100%; 993 | -moz-tab-size: 4; 994 | -o-tab-size: 4; 995 | tab-size: 4; 996 | font-family: Google Sans Text,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"; 997 | font-feature-settings: normal; 998 | font-variation-settings: normal 999 | } 1000 | 1001 | hr { 1002 | height: 0; 1003 | color: inherit; 1004 | border-top-width: 1px 1005 | } 1006 | 1007 | abbr:where([title]) { 1008 | -webkit-text-decoration: underline dotted; 1009 | text-decoration: underline dotted 1010 | } 1011 | 1012 | h1,h2,h3,h4,h5,h6 { 1013 | font-weight: inherit; 1014 | } 1015 | 1016 | a { 1017 | text-decoration: inherit 1018 | } 1019 | 1020 | b,strong { 1021 | font-weight: bolder 1022 | } 1023 | 1024 | code,kbd,samp,pre { 1025 | font-size: 1em; 1026 | } 1027 | 1028 | small { 1029 | font-size: 80% 1030 | } 1031 | 1032 | sub,sup { 1033 | font-size: 75%; 1034 | line-height: 0; 1035 | position: relative; 1036 | vertical-align: baseline 1037 | } 1038 | 1039 | sub { 1040 | bottom: -.25em 1041 | } 1042 | 1043 | sup { 1044 | top: -.5em 1045 | } 1046 | 1047 | 1048 | 1049 | table { 1050 | text-indent: 0; 1051 | border-color: inherit; 1052 | border-collapse: collapse 1053 | } 1054 | 1055 | button,input,optgroup,select,textarea { 1056 | font-family: inherit; 1057 | font-feature-settings: inherit; 1058 | font-variation-settings: inherit; 1059 | font-size: 100%; 1060 | font-weight: inherit; 1061 | line-height: inherit; 1062 | color: inherit; 1063 | margin-right: 0px; 1064 | margin-left: 0px; 1065 | padding: 6px; 1066 | } 1067 | 1068 | button,select { 1069 | text-transform: none 1070 | } 1071 | 1072 | button,[type=button],[type=reset],[type=submit] { 1073 | -webkit-appearance: button; 1074 | background-color: transparent; 1075 | background-image: none 1076 | } 1077 | 1078 | :-moz-focusring { 1079 | outline: auto 1080 | } 1081 | 1082 | :-moz-ui-invalid { 1083 | box-shadow: none 1084 | } 1085 | 1086 | progress { 1087 | vertical-align: baseline 1088 | } 1089 | 1090 | ::-webkit-inner-spin-button,::-webkit-outer-spin-button { 1091 | height: auto 1092 | } 1093 | 1094 | [type=search] { 1095 | -webkit-appearance: textfield; 1096 | outline-offset: -2px 1097 | } 1098 | 1099 | ::-webkit-search-decoration { 1100 | -webkit-appearance: none 1101 | } 1102 | 1103 | ::-webkit-file-upload-button { 1104 | -webkit-appearance: button; 1105 | font: inherit 1106 | } 1107 | 1108 | summary { 1109 | display: list-item 1110 | } 1111 | 1112 | blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre { 1113 | margin: 2px; 1114 | } 1115 | 1116 | fieldset { 1117 | margin: 0; 1118 | padding: 0 1119 | } 1120 | 1121 | legend { 1122 | padding: 0 1123 | } 1124 | 1125 | ol,ul,menu { 1126 | list-style: none; 1127 | margin: 0; 1128 | padding: 0 1129 | } 1130 | 1131 | dialog { 1132 | padding: 0 1133 | } 1134 | 1135 | input::-moz-placeholder,textarea::-moz-placeholder { 1136 | opacity: 1; 1137 | color: #808c9c 1138 | } 1139 | 1140 | input::placeholder,textarea::placeholder { 1141 | opacity: 1; 1142 | color: #808c9c 1143 | } 1144 | 1145 | button,[role=button] { 1146 | cursor: pointer 1147 | } 1148 | 1149 | :disabled { 1150 | cursor: default 1151 | } 1152 | 1153 | img,svg,video,canvas,audio,iframe,embed,object { 1154 | display: block; 1155 | vertical-align: middle 1156 | } 1157 | 1158 | img,video { 1159 | max-width: 100%; 1160 | height: auto 1161 | } 1162 | 1163 | [hidden] { 1164 | display: none 1165 | } 1166 | 1167 | :root { 1168 | color-scheme: dark; 1169 | } 1170 | 1171 | html { 1172 | position: relative; 1173 | scroll-padding: 2rem; 1174 | scroll-behavior: smooth; 1175 | --tw-bg-opacity: 1; 1176 | 1177 | --tw-text-opacity: 1; 1178 | color: rgb(128 140 156 / var(--tw-text-opacity)); 1179 | -webkit-font-smoothing: antialiased; 1180 | -moz-osx-font-smoothing: grayscale 1181 | } 1182 | 1183 | @media screen and (prefers-reduced-motion) { 1184 | html { 1185 | scroll-behavior: auto 1186 | } 1187 | } 1188 | 1189 | @media (prefers-contrast: more) { 1190 | html { 1191 | --tw-text-opacity: 1; 1192 | color: rgb(191 199 210 / var(--tw-text-opacity)) 1193 | } 1194 | } 1195 | 1196 | ::-moz-selection { 1197 | background-color: #a87ffb80; 1198 | --tw-text-opacity: 1; 1199 | color: rgb(191 199 210 / var(--tw-text-opacity)) 1200 | } 1201 | 1202 | ::selection { 1203 | background-color: #a87ffb80; 1204 | --tw-text-opacity: 1; 1205 | } 1206 | 1207 | @media (prefers-contrast: more) { 1208 | ::-moz-selection { 1209 | --tw-text-opacity: 1; 1210 | color: rgb(255 255 255 / var(--tw-text-opacity)) 1211 | } 1212 | 1213 | ::selection { 1214 | --tw-text-opacity: 1; 1215 | color: rgb(255 255 255 / var(--tw-text-opacity)) 1216 | } 1217 | } 1218 | 1219 | 1220 | @media (prefers-contrast: more) { 1221 | #terminal main:after { 1222 | --tw-border-opacity: 1; 1223 | border-color: rgb(128 140 156 / var(--tw-border-opacity)); 1224 | --tw-bg-opacity: 1; 1225 | background-color: rgb(16 21 29 / var(--tw-bg-opacity)) 1226 | } 1227 | } 1228 | 1229 | @media (min-width: 768px) { 1230 | #terminal main:after { 1231 | border-top-left-radius:.5rem; 1232 | border-top-right-radius: .5rem 1233 | } 1234 | 1235 | #terminal main:after:before { 1236 | content: ""; 1237 | background: linear-gradient(133.61deg,#a87ffb 17.33%,#25a6e9 100.47%); 1238 | opacity: .5; 1239 | pointer-events: none; 1240 | position: absolute; 1241 | left: 5rem; 1242 | right: 5rem; 1243 | top: .5rem; 1244 | bottom: 0; 1245 | z-index: -10; 1246 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 1247 | --tw-blur: blur(64px); 1248 | filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); 1249 | transition: opacity .5s ease 1250 | } 1251 | 1252 | #terminal main:after:after { 1253 | content: ""; 1254 | background: linear-gradient(to right,#2E3C51 0%,#2E3C51 34%,#2E3C51 49%,#fff 57%,#fff 64%,#A87FFB 66%,#25A6E9 100%); 1255 | background-size: 300% 100%; 1256 | background-position: 0% 50%; 1257 | background-repeat: no-repeat; 1258 | transition: background-position .8s ease; 1259 | inset: -1px; 1260 | border-top-left-radius: 9px; 1261 | border-top-right-radius: 9px; 1262 | pointer-events: none; 1263 | position: absolute; 1264 | z-index: -10; 1265 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 1266 | } 1267 | 1268 | @media screen and (prefers-reduced-motion: no-preference) { 1269 | #terminal.is-nudging main:after:after,#terminal:hover main:after:after { 1270 | animation: .7s pulseshimmer 1s cubic-bezier(.8,0,.2,1) infinite alternate; 1271 | animation-fill-mode: backwards 1272 | } 1273 | 1274 | @keyframes pulseshimmer { 1275 | } 1276 | 1277 | #terminal.is-nudging main:after { 1278 | transform: translateY(0); 1279 | animation: .7s pulsepeek .4s ease-in-out infinite alternate 1280 | } 1281 | 1282 | @keyframes pulsepeek { 1283 | } 1284 | 1285 | #terminal.is-nudging main:after:before { 1286 | opacity: .8 1287 | } 1288 | 1289 | #terminal.is-nudging main:after:after { 1290 | background-position: 100% 50% 1291 | } 1292 | 1293 | #terminal:hover main:after { 1294 | transform: none; 1295 | animation: none 1296 | } 1297 | 1298 | #terminal:hover main:after:before { 1299 | opacity: 1 1300 | } 1301 | 1302 | #terminal:hover main:after:after { 1303 | background-position: 100% 50% 1304 | } 1305 | } 1306 | } 1307 | 1308 | .terminal-open #terminal main:after { 1309 | animation: none 1310 | } 1311 | 1312 | .terminal-open #terminal main:after:before { 1313 | opacity: 0 1314 | } 1315 | 1316 | .terminal-open #terminal main:after:after { 1317 | animation: none; 1318 | opacity: 1; 1319 | background: none; 1320 | --tw-bg-opacity: 1; 1321 | background-color: rgb(46 60 81 / var(--tw-bg-opacity)) 1322 | } 1323 | 1324 | main:after { 1325 | position: absolute; 1326 | inset: 0; 1327 | z-index: -10 1328 | } 1329 | 1330 | .terminal-open main:after { 1331 | animation-play-state: paused 1332 | } 1333 | 1334 | @media (prefers-reduced-motion) { 1335 | main:after { 1336 | animation: none 1337 | } 1338 | } 1339 | 1340 | @media (min-width: 768px) { 1341 | main:after { 1342 | background-size:calc(8.3333333333% - 1px) 140px 1343 | } 1344 | } 1345 | 1346 | .form-control-wrapper { 1347 | position: relative; 1348 | font-family: JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace; 1349 | font-size: .875rem; 1350 | line-height: 1.25rem; 1351 | --tw-text-opacity: 1; 1352 | color: rgb(139 152 169 / var(--tw-text-opacity)) 1353 | } 1354 | 1355 | @media (max-width: 767px) { 1356 | .form-control-wrapper { 1357 | font-size:16px 1358 | } 1359 | } 1360 | 1361 | .form-control-wrapper:after { 1362 | pointer-events: none; 1363 | position: absolute; 1364 | right: 0; 1365 | display: block; 1366 | content: ""; 1367 | width: 16px; 1368 | height: 16px; 1369 | opacity: 0; 1370 | transform: translate(-4px); 1371 | transition: transform .3s ease,opacity .3s ease; 1372 | background-image: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="16" height="16" viewBox="0 0 16 16"%3E%3Cpath fill="%23F76769" fill-rule="evenodd" d="M7.56 1h.88l6.54 12.26l-.44.74H1.44L1 13.26L7.56 1zM8 2.28L2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z" clip-rule="evenodd"%2F%3E%3C%2Fsvg%3E') 1373 | } 1374 | 1375 | .form-control-wrapper.form-control-error:after { 1376 | opacity: 1; 1377 | transform: translate(0) 1378 | } 1379 | 1380 | .form-control { 1381 | width: 100%; 1382 | background-color: transparent; 1383 | padding-right: 1.5rem; 1384 | --tw-text-opacity: 1; 1385 | color: rgb(191 199 210 / var(--tw-text-opacity)); 1386 | caret-color: #a87ffb; 1387 | outline: 2px solid transparent; 1388 | outline-offset: 2px 1389 | } 1390 | 1391 | .form-control::-moz-placeholder { 1392 | --tw-text-opacity: 1; 1393 | color: rgb(71 83 101 / var(--tw-text-opacity)) 1394 | } 1395 | 1396 | .form-control::placeholder { 1397 | --tw-text-opacity: 1; 1398 | color: rgb(71 83 101 / var(--tw-text-opacity)) 1399 | } 1400 | 1401 | .form-control:-webkit-autofill { 1402 | -webkit-text-fill-color: #ffffff!important; 1403 | -webkit-box-shadow: 0 0 0px 100px rgb(22,30,41) inset 1404 | } 1405 | 1406 | .form-control:autofill,.form-control:-webkit-autofill,.form-control:auto-fill { 1407 | -webkit-text-fill-color: #ffffff!important; 1408 | -webkit-box-shadow: 0 0 0px 100px rgb(22,30,41) inset 1409 | } 1410 | 1411 | .form-control:-webkit-autofill::-webkit-contacts-auto-fill-button { 1412 | --tw-bg-opacity: 1; 1413 | background-color: rgb(128 140 156 / var(--tw-bg-opacity)) 1414 | } 1415 | 1416 | .form-control:autofill::-webkit-contacts-auto-fill-button,.form-control:-webkit-autofill::-webkit-contacts-auto-fill-button,.form-control:auto-fill::-webkit-contacts-auto-fill-button { 1417 | --tw-bg-opacity: 1; 1418 | background-color: rgb(128 140 156 / var(--tw-bg-opacity)) 1419 | } 1420 | 1421 | .form-control:-webkit-autofill::-webkit-contacts-auto-fill-button:hover { 1422 | --tw-bg-opacity: 1; 1423 | background-color: rgb(168 127 251 / var(--tw-bg-opacity)) 1424 | } 1425 | 1426 | .form-control:autofill::-webkit-contacts-auto-fill-button:hover,.form-control:-webkit-autofill::-webkit-contacts-auto-fill-button:hover,.form-control:auto-fill::-webkit-contacts-auto-fill-button:hover { 1427 | --tw-bg-opacity: 1; 1428 | background-color: rgb(168 127 251 / var(--tw-bg-opacity)) 1429 | } 1430 | 1431 | .form-control:not(input:-webkit-autofill)::-webkit-contacts-auto-fill-button { 1432 | --tw-bg-opacity: 1; 1433 | background-color: rgb(128 140 156 / var(--tw-bg-opacity)) 1434 | } 1435 | 1436 | .form-control:not(input:-webkit-autofill)::-webkit-contacts-auto-fill-button:hover { 1437 | --tw-bg-opacity: 1; 1438 | background-color: rgb(168 127 251 / var(--tw-bg-opacity)) 1439 | } 1440 | 1441 | .form-control-error .form-control { 1442 | --tw-text-opacity: 1; 1443 | color: rgb(247 103 105 / var(--tw-text-opacity)) 1444 | } 1445 | 1446 | .select-group { 1447 | position: relative 1448 | } 1449 | 1450 | .select-group select { 1451 | -webkit-appearance: none; 1452 | -moz-appearance: none; 1453 | appearance: none; 1454 | overflow: hidden; 1455 | text-overflow: ellipsis; 1456 | white-space: nowrap; 1457 | border-radius: 0; 1458 | background-color: transparent; 1459 | padding-top: .75rem; 1460 | padding-bottom: .75rem; 1461 | padding-bottom: 1px; 1462 | padding-right: 1.5rem; 1463 | caret-color: #a87ffb; 1464 | outline: 2px solid transparent; 1465 | outline-offset: 2px 1466 | } 1467 | 1468 | .select-group:after { 1469 | content: ""; 1470 | pointer-events: none; 1471 | position: absolute; 1472 | right: 0; 1473 | bottom: 5px; 1474 | height: .75rem; 1475 | width: .75rem; 1476 | background-size: contain; 1477 | background-position: center; 1478 | background-repeat: no-repeat; 1479 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 11 6'%3E%3Cpath fill='%23BFC7D2' d='M5 5.08.68.707l-.64.64 4.693 4.64h.587l4.693-4.64-.64-.64L5 5.08Z'/%3E%3C/svg%3E") 1480 | } 1481 | 1482 | .select-group:focus-within:after { 1483 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 11 6'%3E%3Cpath fill='%23A87FFB' d='M5 5.08.68.707l-.64.64 4.693 4.64h.587l4.693-4.64-.64-.64L5 5.08Z'/%3E%3C/svg%3E") 1484 | } 1485 | 1486 | .select-group:focus-within select { 1487 | --tw-text-opacity: 1; 1488 | color: rgb(168 127 251 / var(--tw-text-opacity)) 1489 | } 1490 | 1491 | input.form-control[type=checkbox]:focus { 1492 | outline-color: #a87ffb; 1493 | outline-offset: 1px; 1494 | outline-width: 1px; 1495 | border-radius: 4px 1496 | } 1497 | 1498 | .title { 1499 | font-family: Google Sans Display,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"; 1500 | font-weight: 500; 1501 | letter-spacing: -.025em; 1502 | --tw-text-opacity: 1; 1503 | color: rgb(191 199 210 / var(--tw-text-opacity)) 1504 | } 1505 | 1506 | @media (prefers-contrast: more) { 1507 | .title { 1508 | --tw-text-opacity: 1; 1509 | color: rgb(255 255 255 / var(--tw-text-opacity)) 1510 | } 1511 | } 1512 | 1513 | .link,.rich-text a { 1514 | --tw-text-opacity: 1; 1515 | color: rgb(255 255 255 / var(--tw-text-opacity)); 1516 | text-decoration-line: underline; 1517 | text-decoration-color: #2e3c51; 1518 | text-underline-offset: 2px; 1519 | transition-property: color,background-color,border-color,text-decoration-color,fill,stroke; 1520 | transition-timing-function: cubic-bezier(.4,0,.2,1); 1521 | transition-duration: .15s 1522 | } 1523 | 1524 | .link:hover,.rich-text a:hover { 1525 | --tw-text-opacity: 1; 1526 | color: rgb(168 127 251 / var(--tw-text-opacity)); 1527 | text-decoration-color: #a87ffb 1528 | } 1529 | 1530 | .button { 1531 | position: relative; 1532 | display: inline-block; 1533 | overflow: hidden; 1534 | border-radius: 9999px; 1535 | padding: .625rem 1.5rem; 1536 | text-align: center; 1537 | font-family: Google Sans Display,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"; 1538 | font-size: .875rem; 1539 | line-height: 1.25rem; 1540 | font-weight: 700; 1541 | letter-spacing: -.025em; 1542 | transition-property: color,border-color,transform,opacity,background-color; 1543 | transition-duration: .3s; 1544 | transition-timing-function: ease 1545 | } 1546 | 1547 | @media (min-width: 768px) { 1548 | .button { 1549 | width:auto; 1550 | padding: .875rem 1.5rem 1551 | } 1552 | } 1553 | 1554 | .button:before { 1555 | content: ""; 1556 | pointer-events: none; 1557 | position: absolute; 1558 | inset: 0; 1559 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 1560 | opacity: 0; 1561 | transition: opacity .3s ease,transform .3s ease 1562 | } 1563 | 1564 | .button.has-arrow:after { 1565 | content: "~>"; 1566 | margin-left: .375rem; 1567 | display: inline-block; 1568 | font-family: JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace; 1569 | font-weight: 500; 1570 | letter-spacing: 0em; 1571 | transition: transform .3s ease 1572 | } 1573 | 1574 | .button-outline { 1575 | border-width: 1px; 1576 | --tw-border-opacity: 1; 1577 | border-color: rgb(46 60 81 / var(--tw-border-opacity)); 1578 | --tw-bg-opacity: 1; 1579 | background-color: rgb(16 21 29 / var(--tw-bg-opacity)); 1580 | --tw-text-opacity: 1; 1581 | color: rgb(191 199 210 / var(--tw-text-opacity)) 1582 | } 1583 | 1584 | .button-outline:before { 1585 | --tw-bg-opacity: 1; 1586 | background-color: rgb(168 127 251 / var(--tw-bg-opacity)) 1587 | } 1588 | 1589 | .button-outline:hover,.button-outline:focus { 1590 | --tw-border-opacity: 1; 1591 | border-color: rgb(168 127 251 / var(--tw-border-opacity)) 1592 | } 1593 | 1594 | .button-outline:hover:before,.button-outline:focus:before { 1595 | opacity: .1 1596 | } 1597 | 1598 | .button-outline:active:before { 1599 | opacity: .2 1600 | } 1601 | 1602 | @media (prefers-contrast: more) { 1603 | .button-outline { 1604 | --tw-border-opacity: 1; 1605 | border-color: rgb(255 255 255 / var(--tw-border-opacity)); 1606 | --tw-text-opacity: 1; 1607 | color: rgb(255 255 255 / var(--tw-text-opacity)) 1608 | } 1609 | } 1610 | 1611 | .button-primary { 1612 | border-width: 1px; 1613 | --tw-border-opacity: 1; 1614 | border-color: rgb(168 127 251 / var(--tw-border-opacity)); 1615 | --tw-bg-opacity: 1; 1616 | background-color: rgb(168 127 251 / var(--tw-bg-opacity)); 1617 | --tw-text-opacity: 1; 1618 | color: rgb(16 21 29 / var(--tw-text-opacity)) 1619 | } 1620 | 1621 | .button-primary:hover,.button-primary:focus { 1622 | --tw-bg-opacity: 1; 1623 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)) 1624 | } 1625 | 1626 | .button-primary:active:before { 1627 | opacity: 1 1628 | } 1629 | 1630 | .button-link { 1631 | margin-left: -1.5rem; 1632 | margin-right: -1.5rem; 1633 | padding-left: 1.5rem; 1634 | padding-right: 1.5rem 1635 | } 1636 | 1637 | .button-link:before { 1638 | --tw-bg-opacity: 1; 1639 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)) 1640 | } 1641 | 1642 | .button-link:hover,.button-link:focus { 1643 | --tw-border-opacity: 1; 1644 | border-color: rgb(168 127 251 / var(--tw-border-opacity)); 1645 | --tw-text-opacity: 1; 1646 | color: rgb(191 199 210 / var(--tw-text-opacity)) 1647 | } 1648 | 1649 | .button-link:hover:before,.button-link:focus:before { 1650 | opacity: .05 1651 | } 1652 | 1653 | .button-link:active:before { 1654 | opacity: .1 1655 | } 1656 | 1657 | .squiggly-arrow { 1658 | display: inline-block 1659 | } 1660 | 1661 | .squiggly-arrow:after { 1662 | content: "~>"; 1663 | font-family: JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace 1664 | } 1665 | 1666 | .obscure-stars { 1667 | border-radius: .75rem; 1668 | --tw-bg-opacity: 1; 1669 | background-color: rgb(16 21 29 / var(--tw-bg-opacity)); 1670 | --tw-shadow: 0 0 20px 20px #10151D; 1671 | --tw-shadow-colored: 0 0 20px 20px var(--tw-shadow-color); 1672 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow) 1673 | } 1674 | 1675 | .shine { 1676 | background-image: radial-gradient(200px 100px at 50% 0%,#131f33 20%,rgba(19,30,49,0) 100%) 1677 | } 1678 | 1679 | @media (min-width: 768px) { 1680 | .shine { 1681 | background-image:radial-gradient(500px 200px at 50% 0%,#131f33 20%,rgba(19,30,49,0) 100%) 1682 | } 1683 | } 1684 | 1685 | *,:before,:after { 1686 | --tw-border-spacing-x: 0; 1687 | --tw-border-spacing-y: 0; 1688 | --tw-translate-x: 0; 1689 | --tw-translate-y: 0; 1690 | --tw-rotate: 0; 1691 | --tw-skew-x: 0; 1692 | --tw-skew-y: 0; 1693 | --tw-scale-x: 1; 1694 | --tw-scale-y: 1; 1695 | --tw-pan-x: ; 1696 | --tw-pan-y: ; 1697 | --tw-pinch-zoom: ; 1698 | --tw-scroll-snap-strictness: proximity; 1699 | --tw-gradient-from-position: ; 1700 | --tw-gradient-via-position: ; 1701 | --tw-gradient-to-position: ; 1702 | --tw-ordinal: ; 1703 | --tw-slashed-zero: ; 1704 | --tw-numeric-figure: ; 1705 | --tw-numeric-spacing: ; 1706 | --tw-numeric-fraction: ; 1707 | --tw-ring-inset: ; 1708 | --tw-ring-offset-width: 0px; 1709 | --tw-ring-offset-color: #fff; 1710 | --tw-ring-color: rgb(70 153 191 / 50%); 1711 | --tw-ring-offset-shadow: 0 0 #0000; 1712 | --tw-ring-shadow: 0 0 #0000; 1713 | --tw-shadow: 0 0 #0000; 1714 | /* --tw-shadow-colored: 0 0 #ff2828b5; */ 1715 | --tw-blur: ; 1716 | --tw-brightness: ; 1717 | --tw-contrast: ; 1718 | --tw-grayscale: ; 1719 | --tw-hue-rotate: ; 1720 | --tw-invert: ; 1721 | --tw-saturate: ; 1722 | --tw-sepia: ; 1723 | --tw-drop-shadow: ; 1724 | --tw-backdrop-blur: ; 1725 | --tw-backdrop-brightness: ; 1726 | --tw-backdrop-contrast: ; 1727 | --tw-backdrop-grayscale: ; 1728 | --tw-backdrop-hue-rotate: ; 1729 | --tw-backdrop-invert: ; 1730 | --tw-backdrop-opacity: ; 1731 | --tw-backdrop-saturate: ; 1732 | --tw-backdrop-sepia: 1733 | } 1734 | 1735 | ::backdrop { 1736 | --tw-border-spacing-x: 0; 1737 | --tw-border-spacing-y: 0; 1738 | --tw-translate-x: 0; 1739 | --tw-translate-y: 0; 1740 | --tw-rotate: 0; 1741 | --tw-skew-x: 0; 1742 | --tw-skew-y: 0; 1743 | --tw-scale-x: 1; 1744 | --tw-scale-y: 1; 1745 | --tw-pan-x: ; 1746 | --tw-pan-y: ; 1747 | --tw-pinch-zoom: ; 1748 | --tw-scroll-snap-strictness: proximity; 1749 | --tw-gradient-from-position: ; 1750 | --tw-gradient-via-position: ; 1751 | --tw-gradient-to-position: ; 1752 | --tw-ordinal: ; 1753 | --tw-slashed-zero: ; 1754 | --tw-numeric-figure: ; 1755 | --tw-numeric-spacing: ; 1756 | --tw-numeric-fraction: ; 1757 | --tw-ring-inset: ; 1758 | --tw-ring-offset-width: 0px; 1759 | --tw-ring-offset-color: #fff; 1760 | --tw-ring-color: rgb(0 138 201 / .5); 1761 | --tw-ring-offset-shadow: 0 0 #0000; 1762 | --tw-ring-shadow: 0 0 #0000; 1763 | --tw-shadow: 0 0 #0000; 1764 | --tw-shadow-colored: 0 0 #0000; 1765 | --tw-blur: ; 1766 | --tw-brightness: ; 1767 | --tw-contrast: ; 1768 | --tw-grayscale: ; 1769 | --tw-hue-rotate: ; 1770 | --tw-invert: ; 1771 | --tw-saturate: ; 1772 | --tw-sepia: ; 1773 | --tw-drop-shadow: ; 1774 | --tw-backdrop-blur: ; 1775 | --tw-backdrop-brightness: ; 1776 | --tw-backdrop-contrast: ; 1777 | --tw-backdrop-grayscale: ; 1778 | --tw-backdrop-hue-rotate: ; 1779 | --tw-backdrop-invert: ; 1780 | --tw-backdrop-opacity: ; 1781 | --tw-backdrop-saturate: ; 1782 | --tw-backdrop-sepia: 1783 | } 1784 | 1785 | .container { 1786 | width: 100%; 1787 | margin-right: auto; 1788 | margin-left: auto 1789 | } 1790 | 1791 | @media (min-width: 360px) { 1792 | .container { 1793 | max-width:360px 1794 | } 1795 | } 1796 | 1797 | @media (min-width: 400px) { 1798 | .container { 1799 | max-width:400px 1800 | } 1801 | } 1802 | 1803 | @media (min-width: 640px) { 1804 | .container { 1805 | max-width:640px 1806 | } 1807 | } 1808 | 1809 | @media (min-width: 768px) { 1810 | .container { 1811 | max-width:768px 1812 | } 1813 | } 1814 | 1815 | @media (min-width: 1024px) { 1816 | .container { 1817 | max-width:1024px 1818 | } 1819 | } 1820 | 1821 | @media (min-width: 1280px) { 1822 | .container { 1823 | max-width:1280px 1824 | } 1825 | } 1826 | 1827 | @media (min-width: 1536px) { 1828 | .container { 1829 | max-width:1536px 1830 | } 1831 | } 1832 | 1833 | #sidebar { 1834 | display: flex; 1835 | justify-content: space-between; 1836 | padding-left: 1rem; 1837 | padding-right: 1rem 1838 | } 1839 | 1840 | @media (max-width: 767px) { 1841 | #sidebar { 1842 | position:absolute; 1843 | left: 0; 1844 | right: 0; 1845 | top: 0 1846 | } 1847 | } 1848 | 1849 | @media (min-width: 768px) { 1850 | #sidebar { 1851 | position:sticky; 1852 | top: 0; 1853 | height: 100vh; 1854 | width: 70px; 1855 | flex-direction: column; 1856 | align-items: stretch; 1857 | border-right-width: 1px; 1858 | --tw-border-opacity: 1; 1859 | border-color: rgb(46 60 81 / var(--tw-border-opacity)); 1860 | --tw-bg-opacity: 1; 1861 | background-color: rgb(22 30 41 / var(--tw-bg-opacity)); 1862 | padding-top: 1rem; 1863 | padding-bottom: 1rem 1864 | } 1865 | } 1866 | 1867 | .dynamic-dropdown-icon { 1868 | display: inline-block; 1869 | width: 1rem 1870 | } 1871 | 1872 | .dynamic-dropdown-icon:before,.dynamic-dropdown-icon:after { 1873 | position: absolute; 1874 | right: 1.5rem; 1875 | --tw-bg-opacity: 1; 1876 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)); 1877 | content: ""; 1878 | top: 50%; 1879 | width: 12px; 1880 | height: 1.2px; 1881 | transform-origin: center; 1882 | transition: transform .3s ease .3s 1883 | } 1884 | 1885 | @media (prefers-reduced-motion) { 1886 | .dynamic-dropdown-icon:before,.dynamic-dropdown-icon:after { 1887 | transition: none 1888 | } 1889 | } 1890 | 1891 | .dynamic-dropdown-icon:before { 1892 | transform: rotate(45deg) scaleX(.5) translate(-3px,1px) 1893 | } 1894 | 1895 | .dynamic-dropdown-icon:after { 1896 | transform: rotate(-45deg) scaleX(.5) translate(3px,1px) 1897 | } 1898 | 1899 | .terminal-open .dynamic-dropdown-icon:before { 1900 | transform: rotate(45deg) scaleX(1) translate(0) 1901 | } 1902 | 1903 | .terminal-open .dynamic-dropdown-icon:after { 1904 | transform: rotate(-45deg) scaleX(1) translate(0) 1905 | } 1906 | 1907 | #terminal { 1908 | pointer-events: none; 1909 | position: fixed; 1910 | left: 0; 1911 | right: 0; 1912 | bottom: 0; 1913 | z-index: 50; 1914 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 1915 | } 1916 | 1917 | @media (min-width: 768px) { 1918 | #terminal { 1919 | left:5rem 1920 | } 1921 | } 1922 | 1923 | #terminal { 1924 | transform: translateY(100%) 1925 | } 1926 | 1927 | @media screen and (prefers-reduced-motion: no-preference) { 1928 | #terminal { 1929 | transition: transform .3s ease 1930 | } 1931 | } 1932 | 1933 | #terminal .container { 1934 | pointer-events: auto; 1935 | position: relative; 1936 | max-width: 640px; 1937 | --tw-bg-opacity: 1; 1938 | background-color: rgb(22 30 41 / var(--tw-bg-opacity)) 1939 | } 1940 | 1941 | @media (prefers-contrast: more) { 1942 | #terminal .container { 1943 | --tw-border-opacity: 1; 1944 | border-color: rgb(128 140 156 / var(--tw-border-opacity)); 1945 | --tw-bg-opacity: 1; 1946 | background-color: rgb(16 21 29 / var(--tw-bg-opacity)) 1947 | } 1948 | } 1949 | 1950 | #terminal .bg { 1951 | z-index: -1; 1952 | position: absolute; 1953 | inset: 0; 1954 | --tw-bg-opacity: 1; 1955 | background-color: rgb(22 30 41 / var(--tw-bg-opacity)) 1956 | } 1957 | 1958 | @media (prefers-contrast: more) { 1959 | #terminal .bg { 1960 | --tw-bg-opacity: 1; 1961 | background-color: rgb(16 21 29 / var(--tw-bg-opacity)) 1962 | } 1963 | } 1964 | 1965 | @media (min-width: 768px) { 1966 | #terminal .container,#terminal .bg { 1967 | border-top-left-radius:.5rem; 1968 | border-top-right-radius: .5rem 1969 | } 1970 | } 1971 | 1972 | @media (max-width: 767px) { 1973 | .terminal-open #terminal:before { 1974 | content:""; 1975 | background: linear-gradient(133.61deg,#a87ffb 17.33%,#25a6e9 100.47%); 1976 | opacity: .5; 1977 | pointer-events: none; 1978 | position: absolute; 1979 | left: 5rem; 1980 | right: 5rem; 1981 | top: .5rem; 1982 | bottom: 0; 1983 | z-index: -10; 1984 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 1985 | --tw-blur: blur(64px); 1986 | filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); 1987 | transition: opacity .5s ease 1988 | } 1989 | 1990 | .terminal-open #terminal:after { 1991 | content: ""; 1992 | background: linear-gradient(to right,#A87FFB 0%,#25A6E9 100%); 1993 | background-repeat: no-repeat; 1994 | inset: -1px; 1995 | pointer-events: none; 1996 | position: absolute; 1997 | z-index: -10; 1998 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 1999 | } 2000 | } 2001 | 2002 | @media (min-width: 768px) { 2003 | #terminal { 2004 | transform:translateY(calc(100% - 52px)) 2005 | } 2006 | 2007 | #terminal .container:before { 2008 | content: ""; 2009 | background: linear-gradient(133.61deg,#a87ffb 17.33%,#25a6e9 100.47%); 2010 | opacity: .5; 2011 | pointer-events: none; 2012 | position: absolute; 2013 | left: 5rem; 2014 | right: 5rem; 2015 | top: .5rem; 2016 | bottom: 0; 2017 | z-index: -10; 2018 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 2019 | --tw-blur: blur(64px); 2020 | filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); 2021 | transition: opacity .5s ease 2022 | } 2023 | 2024 | #terminal .container:after { 2025 | content: ""; 2026 | background: linear-gradient(to right,#2E3C51 0%,#2E3C51 34%,#2E3C51 49%,#fff 57%,#fff 64%,#A87FFB 66%,#25A6E9 100%); 2027 | background-size: 300% 100%; 2028 | background-position: 0% 50%; 2029 | background-repeat: no-repeat; 2030 | transition: background-position .8s ease; 2031 | inset: -1px; 2032 | border-top-left-radius: 9px; 2033 | border-top-right-radius: 9px; 2034 | pointer-events: none; 2035 | position: absolute; 2036 | z-index: -10; 2037 | transform: translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 2038 | } 2039 | 2040 | @media screen and (prefers-reduced-motion: no-preference) { 2041 | #terminal.is-nudging .container:after,#terminal:hover .container:after { 2042 | animation: .7s pulseshimmer 1s cubic-bezier(.8,0,.2,1) infinite alternate; 2043 | animation-fill-mode: backwards 2044 | } 2045 | 2046 | @keyframes pulseshimmer { 2047 | 0% { 2048 | opacity: 1 2049 | } 2050 | 2051 | to { 2052 | opacity: .4 2053 | } 2054 | } 2055 | 2056 | #terminal.is-nudging .container { 2057 | transform: translateY(0); 2058 | animation: .7s pulsepeek .4s ease-in-out infinite alternate 2059 | } 2060 | 2061 | @keyframes pulsepeek { 2062 | 0% { 2063 | transform: translateY(0) 2064 | } 2065 | 2066 | to { 2067 | transform: translateY(-4px) 2068 | } 2069 | } 2070 | 2071 | #terminal.is-nudging .container:before { 2072 | opacity: .8 2073 | } 2074 | 2075 | #terminal.is-nudging .container:after { 2076 | background-position: 100% 50% 2077 | } 2078 | 2079 | #terminal:hover { 2080 | transform: translateY(calc(100% - 60px)) 2081 | } 2082 | 2083 | #terminal:hover .container { 2084 | transform: none; 2085 | animation: none 2086 | } 2087 | 2088 | #terminal:hover .container:before { 2089 | opacity: 1 2090 | } 2091 | 2092 | #terminal:hover .container:after { 2093 | background-position: 100% 50% 2094 | } 2095 | } 2096 | } 2097 | 2098 | .terminal-open #terminal { 2099 | animation: none; 2100 | transform: translateY(0) 2101 | } 2102 | 2103 | .terminal-open #terminal .container { 2104 | animation: none 2105 | } 2106 | 2107 | .terminal-open #terminal .container:before { 2108 | opacity: 0 2109 | } 2110 | 2111 | .terminal-open #terminal .container:after { 2112 | animation: none; 2113 | opacity: 1; 2114 | background: none; 2115 | --tw-bg-opacity: 1; 2116 | background-color: rgb(46 60 81 / var(--tw-bg-opacity)) 2117 | } 2118 | 2119 | #terminal-overlay { 2120 | pointer-events: none; 2121 | position: fixed; 2122 | inset: 0; 2123 | z-index: 40; 2124 | --tw-bg-opacity: 1; 2125 | background-color: rgb(20 26 35 / var(--tw-bg-opacity)); 2126 | opacity: 0; 2127 | transition: opacity .3s ease 2128 | } 2129 | 2130 | .terminal-open #terminal-overlay { 2131 | pointer-events: auto; 2132 | opacity: .5 2133 | } 2134 | 2135 | .grecaptcha-badge { 2136 | display: none!important 2137 | } 2138 | 2139 | .sr-only { 2140 | position: absolute; 2141 | width: 1px; 2142 | height: 1px; 2143 | padding: 0; 2144 | margin: -1px; 2145 | overflow: hidden; 2146 | clip: rect(0,0,0,0); 2147 | white-space: nowrap; 2148 | border-width: 0 2149 | } 2150 | 2151 | .pointer-events-none { 2152 | pointer-events: none 2153 | } 2154 | 2155 | .fixed { 2156 | position: fixed 2157 | } 2158 | 2159 | .absolute { 2160 | position: absolute 2161 | } 2162 | 2163 | .relative { 2164 | position: relative 2165 | } 2166 | 2167 | .inset-0 { 2168 | inset: 0 2169 | } 2170 | 2171 | .top-1 { 2172 | top: .25rem 2173 | } 2174 | 2175 | .-z-10 { 2176 | z-index: -10 2177 | } 2178 | 2179 | .z-10 { 2180 | z-index: 10 2181 | } 2182 | 2183 | .z-20 { 2184 | z-index: 20 2185 | } 2186 | 2187 | .mx-auto { 2188 | margin-left: auto; 2189 | margin-right: auto 2190 | } 2191 | 2192 | .my-16 { 2193 | margin-top: 4rem; 2194 | margin-bottom: 4rem 2195 | } 2196 | 2197 | .my-4 { 2198 | margin-top: 1rem; 2199 | margin-bottom: 1rem 2200 | } 2201 | 2202 | .-mb-1 { 2203 | margin-bottom: -.25rem 2204 | } 2205 | 2206 | .-ml-3 { 2207 | margin-left: -.75rem 2208 | } 2209 | 2210 | .mb-10 { 2211 | margin-bottom: 2.5rem 2212 | } 2213 | 2214 | .mb-12 { 2215 | margin-bottom: 3rem 2216 | } 2217 | 2218 | .mb-2 { 2219 | margin-bottom: .5rem 2220 | } 2221 | 2222 | .mb-5 { 2223 | margin-bottom: 1.25rem 2224 | } 2225 | 2226 | .mb-6 { 2227 | margin-bottom: 1.5rem 2228 | } 2229 | 2230 | .mb-8 { 2231 | margin-bottom: 2rem 2232 | } 2233 | 2234 | .ml-12 { 2235 | margin-left: 3rem 2236 | } 2237 | 2238 | .ml-4 { 2239 | margin-left: 1rem 2240 | } 2241 | 2242 | .ml-8 { 2243 | margin-left: 2rem 2244 | } 2245 | 2246 | .mt-24 { 2247 | margin-top: 6rem 2248 | } 2249 | 2250 | .mt-5 { 2251 | margin-top: 1.25rem 2252 | } 2253 | 2254 | .box-border { 2255 | box-sizing: border-box 2256 | } 2257 | 2258 | .block { 2259 | display: block 2260 | } 2261 | 2262 | .inline-block { 2263 | display: inline-block 2264 | } 2265 | 2266 | .flex { 2267 | display: flex 2268 | } 2269 | 2270 | .grid { 2271 | display: grid 2272 | } 2273 | 2274 | .hidden { 2275 | display: none 2276 | } 2277 | 2278 | .aspect-\[4\/3\] { 2279 | aspect-ratio: 4/3 2280 | } 2281 | 2282 | .aspect-square { 2283 | aspect-ratio: 1 / 1 2284 | } 2285 | 2286 | .h-10 { 2287 | height: 2.5rem 2288 | } 2289 | 2290 | .h-14 { 2291 | height: 3.5rem 2292 | } 2293 | 2294 | .h-16 { 2295 | height: 4rem 2296 | } 2297 | 2298 | .h-3 { 2299 | height: .75rem 2300 | } 2301 | 2302 | .h-4 { 2303 | height: 1rem 2304 | } 2305 | 2306 | .h-5 { 2307 | height: 1.25rem 2308 | } 2309 | 2310 | .h-9 { 2311 | height: 2.25rem 2312 | } 2313 | 2314 | .h-full { 2315 | height: 100% 2316 | } 2317 | 2318 | .h-screen { 2319 | height: 100vh 2320 | } 2321 | 2322 | .max-h-\[1280px\] { 2323 | max-height: 1280px 2324 | } 2325 | 2326 | .min-h-\[480px\] { 2327 | min-height: 480px 2328 | } 2329 | 2330 | .w-10 { 2331 | width: 2.5rem 2332 | } 2333 | 2334 | .w-14 { 2335 | width: 3.5rem 2336 | } 2337 | 2338 | .w-16 { 2339 | width: 4rem 2340 | } 2341 | 2342 | .w-20 { 2343 | width: 5rem 2344 | } 2345 | 2346 | .w-3 { 2347 | width: .75rem 2348 | } 2349 | 2350 | .w-4 { 2351 | width: 1rem 2352 | } 2353 | 2354 | .w-5 { 2355 | width: 1.25rem 2356 | } 2357 | 2358 | .w-9 { 2359 | width: 2.25rem 2360 | } 2361 | 2362 | .w-full { 2363 | width: 100% 2364 | } 2365 | 2366 | .min-w-0 { 2367 | min-width: 0px 2368 | } 2369 | 2370 | .max-w-\[160px\] { 2371 | max-width: 160px 2372 | } 2373 | 2374 | .max-w-\[420px\] { 2375 | max-width: 420px 2376 | } 2377 | 2378 | .max-w-\[520px\] { 2379 | max-width: 520px 2380 | } 2381 | 2382 | .max-w-screen-md { 2383 | max-width: 768px 2384 | } 2385 | 2386 | .flex-1 { 2387 | flex: 1 1 0% 2388 | } 2389 | 2390 | .flex-shrink-0 { 2391 | flex-shrink: 0 2392 | } 2393 | 2394 | .-translate-x-1 { 2395 | --tw-translate-x: -.25rem; 2396 | transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 2397 | } 2398 | 2399 | .translate-x-0 { 2400 | --tw-translate-x: 0px; 2401 | transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 2402 | } 2403 | 2404 | .rotate-180 { 2405 | --tw-rotate: 180deg; 2406 | transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 2407 | } 2408 | 2409 | .rotate-90 { 2410 | --tw-rotate: 90deg; 2411 | transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 2412 | } 2413 | 2414 | .transform { 2415 | transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 2416 | } 2417 | 2418 | .select-none { 2419 | -webkit-user-select: none; 2420 | -moz-user-select: none; 2421 | user-select: none 2422 | } 2423 | 2424 | .resize { 2425 | resize: both 2426 | } 2427 | 2428 | .list-disc { 2429 | list-style-type: disc 2430 | } 2431 | 2432 | .flex-col { 2433 | flex-direction: column 2434 | } 2435 | 2436 | .flex-col-reverse { 2437 | flex-direction: column-reverse 2438 | } 2439 | 2440 | .flex-wrap { 2441 | flex-wrap: wrap 2442 | } 2443 | 2444 | .items-start { 2445 | align-items: flex-start 2446 | } 2447 | 2448 | .items-end { 2449 | align-items: flex-end 2450 | } 2451 | 2452 | .items-center { 2453 | align-items: center 2454 | } 2455 | 2456 | .items-baseline { 2457 | align-items: baseline 2458 | } 2459 | 2460 | .items-stretch { 2461 | align-items: stretch 2462 | } 2463 | 2464 | .justify-end { 2465 | justify-content: flex-end 2466 | } 2467 | 2468 | .justify-center { 2469 | justify-content: center 2470 | } 2471 | 2472 | .justify-between { 2473 | justify-content: space-between 2474 | } 2475 | 2476 | .justify-stretch { 2477 | justify-content: stretch 2478 | } 2479 | 2480 | .gap-1 { 2481 | gap: .25rem 2482 | } 2483 | 2484 | .gap-2 { 2485 | gap: .5rem 2486 | } 2487 | 2488 | .gap-3 { 2489 | gap: .75rem 2490 | } 2491 | 2492 | .gap-6 { 2493 | gap: 1.5rem 2494 | } 2495 | 2496 | .gap-x-6 { 2497 | -moz-column-gap: 1.5rem; 2498 | column-gap: 1.5rem 2499 | } 2500 | 2501 | .gap-x-8 { 2502 | -moz-column-gap: 2rem; 2503 | column-gap: 2rem 2504 | } 2505 | 2506 | .gap-y-4 { 2507 | row-gap: 1rem 2508 | } 2509 | 2510 | .space-y-4>:not([hidden])~:not([hidden]) { 2511 | --tw-space-y-reverse: 0; 2512 | margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); 2513 | margin-bottom: calc(1rem * var(--tw-space-y-reverse)) 2514 | } 2515 | 2516 | .self-stretch { 2517 | align-self: stretch 2518 | } 2519 | 2520 | .rounded-full { 2521 | border-radius: 9999px 2522 | } 2523 | 2524 | .rounded-lg { 2525 | border-radius: .5rem 2526 | } 2527 | 2528 | .rounded-md { 2529 | border-radius: .375rem 2530 | } 2531 | 2532 | .border { 2533 | border-width: 1px 2534 | } 2535 | 2536 | .border-t { 2537 | border-top-width: 1px 2538 | } 2539 | 2540 | .border-gray-300 { 2541 | --tw-border-opacity: 1; 2542 | border-color: rgb(46 60 81 / var(--tw-border-opacity)) 2543 | } 2544 | 2545 | .bg-blue { 2546 | --tw-bg-opacity: 1; 2547 | background-color: rgb(37 166 233 / var(--tw-bg-opacity)) 2548 | } 2549 | 2550 | .bg-gray-100 { 2551 | --tw-bg-opacity: 1; 2552 | background-color: rgb(16 21 29 / var(--tw-bg-opacity)) 2553 | } 2554 | 2555 | .bg-gray-200 { 2556 | --tw-bg-opacity: 1; 2557 | background-color: rgb(22 30 41 / var(--tw-bg-opacity)) 2558 | } 2559 | 2560 | .bg-gray-300 { 2561 | --tw-bg-opacity: 1; 2562 | background-color: rgb(46 60 81 / var(--tw-bg-opacity)) 2563 | } 2564 | 2565 | .bg-purple { 2566 | --tw-bg-opacity: 1; 2567 | background-color: rgb(168 127 251 / var(--tw-bg-opacity)) 2568 | } 2569 | 2570 | .bg-white { 2571 | --tw-bg-opacity: 1; 2572 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)) 2573 | } 2574 | 2575 | .bg-yellow { 2576 | --tw-bg-opacity: 1; 2577 | background-color: rgb(255 194 110 / var(--tw-bg-opacity)) 2578 | } 2579 | 2580 | .fill-blue-400 { 2581 | fill: #25a6e9 2582 | } 2583 | 2584 | .fill-current { 2585 | fill: currentColor 2586 | } 2587 | 2588 | .fill-green-400 { 2589 | fill: #17b877 2590 | } 2591 | 2592 | .fill-purple-500 { 2593 | fill: #8964e8 2594 | } 2595 | 2596 | .fill-yellow-400 { 2597 | fill: #ffa23e 2598 | } 2599 | 2600 | .object-contain { 2601 | -o-object-fit: contain; 2602 | object-fit: contain 2603 | } 2604 | 2605 | .object-center { 2606 | -o-object-position: center; 2607 | object-position: center 2608 | } 2609 | 2610 | .p-3 { 2611 | padding: .75rem 2612 | } 2613 | 2614 | .p-4 { 2615 | padding: 1rem 2616 | } 2617 | 2618 | .p-6 { 2619 | padding: 1.5rem 2620 | } 2621 | 2622 | .p-8 { 2623 | padding: 2rem 2624 | } 2625 | 2626 | .px-3 { 2627 | padding-left: .75rem; 2628 | padding-right: .75rem 2629 | } 2630 | 2631 | .px-6 { 2632 | padding-left: 1.5rem; 2633 | padding-right: 1.5rem 2634 | } 2635 | 2636 | .py-1 { 2637 | padding-top: .25rem; 2638 | padding-bottom: .25rem 2639 | } 2640 | 2641 | .py-12 { 2642 | padding-top: 3rem; 2643 | padding-bottom: 3rem 2644 | } 2645 | 2646 | .py-2 { 2647 | padding-top: .5rem; 2648 | padding-bottom: .5rem 2649 | } 2650 | 2651 | .py-4 { 2652 | padding-top: 1rem; 2653 | padding-bottom: 1rem 2654 | } 2655 | 2656 | .py-5 { 2657 | padding-top: 1.25rem; 2658 | padding-bottom: 1.25rem 2659 | } 2660 | 2661 | .pb-14 { 2662 | padding-bottom: 3.5rem 2663 | } 2664 | 2665 | .pb-24 { 2666 | padding-bottom: 6rem 2667 | } 2668 | 2669 | .pt-16 { 2670 | padding-top: 4rem 2671 | } 2672 | 2673 | .pt-3 { 2674 | padding-top: .75rem 2675 | } 2676 | 2677 | .pt-8 { 2678 | padding-top: 2rem 2679 | } 2680 | 2681 | .text-left { 2682 | text-align: left 2683 | } 2684 | 2685 | .font-display { 2686 | font-family: Google Sans Display,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji" 2687 | } 2688 | 2689 | .font-mono { 2690 | font-family: Google Sans Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace 2691 | } 2692 | 2693 | .font-mono-fancy { 2694 | font-family: JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace 2695 | } 2696 | 2697 | .font-sans { 2698 | font-family: Google Sans Text,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji" 2699 | } 2700 | 2701 | .text-2xl { 2702 | font-size: 1.5rem; 2703 | line-height: 2rem 2704 | } 2705 | 2706 | .text-3xl { 2707 | font-size: 1.875rem; 2708 | line-height: 2.25rem 2709 | } 2710 | 2711 | .text-4xl { 2712 | font-size: 2.25rem; 2713 | line-height: 2.5rem 2714 | } 2715 | 2716 | .text-\[12px\]\/\[18px\] { 2717 | font-size: 12px; 2718 | line-height: 18px 2719 | } 2720 | 2721 | .text-\[13px\] { 2722 | font-size: 13px 2723 | } 2724 | 2725 | .text-\[24px\]\/\[29px\] { 2726 | font-size: 24px; 2727 | line-height: 29px 2728 | } 2729 | 2730 | .text-\[36px\]\/\[43px\] { 2731 | font-size: 36px; 2732 | line-height: 43px 2733 | } 2734 | 2735 | .text-lg { 2736 | font-size: 1.125rem; 2737 | line-height: 1.75rem 2738 | } 2739 | 2740 | .text-sm { 2741 | font-size: .875rem; 2742 | line-height: 1.25rem 2743 | } 2744 | 2745 | .text-xs { 2746 | font-size: .75rem; 2747 | line-height: 1rem 2748 | } 2749 | 2750 | .font-medium { 2751 | font-weight: 500 2752 | } 2753 | 2754 | .text-\[\#25A6E9\] { 2755 | --tw-text-opacity: 1; 2756 | color: rgb(37 166 233 / var(--tw-text-opacity)) 2757 | } 2758 | 2759 | .text-gray-300 { 2760 | --tw-text-opacity: 1; 2761 | color: rgb(46 60 81 / var(--tw-text-opacity)) 2762 | } 2763 | 2764 | .text-gray-350 { 2765 | --tw-text-opacity: 1; 2766 | color: rgb(51 62 79 / var(--tw-text-opacity)) 2767 | } 2768 | 2769 | .text-gray-400 { 2770 | --tw-text-opacity: 1; 2771 | color: rgb(128 140 156 / var(--tw-text-opacity)) 2772 | } 2773 | 2774 | .text-gray-425 { 2775 | --tw-text-opacity: 1; 2776 | color: rgb(139 152 169 / var(--tw-text-opacity)) 2777 | } 2778 | 2779 | .text-gray-450 { 2780 | --tw-text-opacity: 1; 2781 | color: rgb(164 175 189 / var(--tw-text-opacity)) 2782 | } 2783 | 2784 | .text-gray-500 { 2785 | --tw-text-opacity: 1; 2786 | color: rgb(191 199 210 / var(--tw-text-opacity)) 2787 | } 2788 | 2789 | .text-green { 2790 | --tw-text-opacity: 1; 2791 | color: rgb(23 184 119 / var(--tw-text-opacity)) 2792 | } 2793 | 2794 | .text-purple { 2795 | --tw-text-opacity: 1; 2796 | color: rgb(168 127 251 / var(--tw-text-opacity)) 2797 | } 2798 | 2799 | .text-red-500 { 2800 | --tw-text-opacity: 1; 2801 | color: rgb(239 68 68 / var(--tw-text-opacity)) 2802 | } 2803 | 2804 | .text-white { 2805 | --tw-text-opacity: 1; 2806 | color: rgb(255 255 255 / var(--tw-text-opacity)) 2807 | } 2808 | 2809 | .accent-purple-500 { 2810 | accent-color: #8964E8 2811 | } 2812 | 2813 | .opacity-0 { 2814 | opacity: 0 2815 | } 2816 | 2817 | .opacity-100 { 2818 | opacity: 1 2819 | } 2820 | 2821 | .opacity-40 { 2822 | opacity: .4 2823 | } 2824 | 2825 | .filter { 2826 | filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) 2827 | } 2828 | 2829 | .transition { 2830 | transition-property: color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter; 2831 | transition-property: color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter; 2832 | transition-property: color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter; 2833 | transition-timing-function: cubic-bezier(.4,0,.2,1); 2834 | transition-duration: .15s 2835 | } 2836 | 2837 | .transition-colors { 2838 | transition-property: color,background-color,border-color,text-decoration-color,fill,stroke; 2839 | transition-timing-function: cubic-bezier(.4,0,.2,1); 2840 | transition-duration: .15s 2841 | } 2842 | 2843 | .duration-500 { 2844 | transition-duration: .5s 2845 | } 2846 | 2847 | @media (min-width: 400px) { 2848 | .xs\:has-arrow.button:after { 2849 | content:"~>"; 2850 | margin-left: .375rem; 2851 | display: inline-block; 2852 | font-family: JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace; 2853 | font-weight: 500; 2854 | letter-spacing: 0em; 2855 | transition: transform .3s ease 2856 | } 2857 | } 2858 | 2859 | .hover\:text-gray-500:hover { 2860 | --tw-text-opacity: 1; 2861 | color: rgb(191 199 210 / var(--tw-text-opacity)) 2862 | } 2863 | 2864 | .group:hover .group-hover\:text-gray-400 { 2865 | --tw-text-opacity: 1; 2866 | color: rgb(128 140 156 / var(--tw-text-opacity)) 2867 | } 2868 | 2869 | @media (min-width: 360px) { 2870 | .xxs\:flex { 2871 | display:flex 2872 | } 2873 | 2874 | .xxs\:flex-row { 2875 | flex-direction: row 2876 | } 2877 | 2878 | .xxs\:justify-center { 2879 | justify-content: center 2880 | } 2881 | } 2882 | 2883 | @media (min-width: 400px) { 2884 | .xs\:w-auto { 2885 | width:auto 2886 | } 2887 | } 2888 | 2889 | @media (max-width: 767px) { 2890 | .max-md\:my-24 { 2891 | margin-top:6rem; 2892 | margin-bottom: 6rem 2893 | } 2894 | 2895 | .max-md\:mb-16 { 2896 | margin-bottom: 4rem 2897 | } 2898 | 2899 | .max-md\:hidden { 2900 | display: none 2901 | } 2902 | 2903 | .max-md\:space-y-1>:not([hidden])~:not([hidden]) { 2904 | --tw-space-y-reverse: 0; 2905 | margin-top: calc(.25rem * calc(1 - var(--tw-space-y-reverse))); 2906 | margin-bottom: calc(.25rem * var(--tw-space-y-reverse)) 2907 | } 2908 | 2909 | .max-md\:text-\[\#56657d\] { 2910 | --tw-text-opacity: 1; 2911 | color: rgb(86 101 125 / var(--tw-text-opacity)) 2912 | } 2913 | } 2914 | 2915 | @media (max-width: 1023px) { 2916 | .max-lg\:border-t-0 { 2917 | border-top-width:0px 2918 | } 2919 | } 2920 | 2921 | @media (min-width: 640px) { 2922 | .sm\:items-center { 2923 | align-items:center 2924 | } 2925 | } 2926 | 2927 | @media (min-width: 768px) { 2928 | .md\:relative { 2929 | position:relative 2930 | } 2931 | 2932 | .md\:-right-6 { 2933 | right: -1.5rem 2934 | } 2935 | 2936 | .md\:my-32 { 2937 | margin-top: 8rem; 2938 | margin-bottom: 8rem 2939 | } 2940 | 2941 | .md\:mb-10 { 2942 | margin-bottom: 2.5rem 2943 | } 2944 | 2945 | .md\:mb-16 { 2946 | margin-bottom: 4rem 2947 | } 2948 | 2949 | .md\:mt-0 { 2950 | margin-top: 0 2951 | } 2952 | 2953 | .md\:inline-block { 2954 | display: inline-block 2955 | } 2956 | 2957 | .md\:flex { 2958 | display: flex 2959 | } 2960 | 2961 | .md\:hidden { 2962 | display: none 2963 | } 2964 | 2965 | .md\:h-48 { 2966 | height: 12rem 2967 | } 2968 | 2969 | .md\:min-h-\[600px\] { 2970 | min-height: 600px 2971 | } 2972 | 2973 | .md\:w-20 { 2974 | width: 5rem 2975 | } 2976 | 2977 | .md\:w-8 { 2978 | width: 2rem 2979 | } 2980 | 2981 | .md\:max-w-\[850px\] { 2982 | max-width: 850px 2983 | } 2984 | 2985 | .md\:flex-1 { 2986 | flex: 1 1 0% 2987 | } 2988 | 2989 | .md\:flex-col { 2990 | flex-direction: column 2991 | } 2992 | 2993 | .md\:justify-end { 2994 | justify-content: flex-end 2995 | } 2996 | 2997 | .md\:p-12 { 2998 | padding: 3rem 2999 | } 3000 | 3001 | .md\:p-16 { 3002 | padding: 4rem 3003 | } 3004 | 3005 | .md\:px-12 { 3006 | padding-left: 3rem; 3007 | padding-right: 3rem 3008 | } 3009 | 3010 | .md\:py-24 { 3011 | padding-top: 6rem; 3012 | padding-bottom: 6rem 3013 | } 3014 | 3015 | .md\:pb-60 { 3016 | padding-bottom: 15rem 3017 | } 3018 | 3019 | .md\:pt-2 { 3020 | padding-top: .5rem 3021 | } 3022 | 3023 | .md\:text-center { 3024 | text-align: center 3025 | } 3026 | 3027 | .md\:text-2xl { 3028 | font-size: 1.5rem; 3029 | line-height: 2rem 3030 | } 3031 | 3032 | .md\:text-4xl { 3033 | font-size: 2.25rem; 3034 | line-height: 2.5rem 3035 | } 3036 | 3037 | .md\:text-\[32px\]\/\[38px\] { 3038 | font-size: 32px; 3039 | line-height: 38px 3040 | } 3041 | 3042 | .md\:text-\[52px\]\/\[62px\] { 3043 | font-size: 52px; 3044 | line-height: 62px 3045 | } 3046 | 3047 | .md\:text-base { 3048 | font-size: 1rem; 3049 | line-height: 1.5rem 3050 | } 3051 | } 3052 | 3053 | @media (min-width: 1024px) { 3054 | .lg\:h-\[650px\] { 3055 | height:650px 3056 | } 3057 | 3058 | .lg\:w-1\/3 { 3059 | width: 33.333333% 3060 | } 3061 | 3062 | .lg\:w-2\/3 { 3063 | width: 66.666667% 3064 | } 3065 | 3066 | .lg\:flex-row { 3067 | flex-direction: row 3068 | } 3069 | 3070 | .lg\:flex-row-reverse { 3071 | flex-direction: row-reverse 3072 | } 3073 | 3074 | .lg\:items-start { 3075 | align-items: flex-start 3076 | } 3077 | 3078 | .lg\:border-l-0 { 3079 | border-left-width: 0px 3080 | } 3081 | 3082 | .lg\:border-r-0 { 3083 | border-right-width: 0px 3084 | } 3085 | } 3086 | 3087 | @media (min-width: 1280px) { 3088 | .xl\:mb-4 { 3089 | margin-bottom:1rem 3090 | } 3091 | } 3092 | 3093 | 3094 | input { 3095 | margin-right:4px; 3096 | } -------------------------------------------------------------------------------- /tests/file_regex_matcher.py: -------------------------------------------------------------------------------- 1 | import re 2 | import unittest 3 | 4 | def detect_file_request(text): 5 | # Regular expression pattern to detect file paths 6 | pattern = r'(/[\w\-\.\/]+(?:\.\w+))' 7 | match = re.search(pattern, text) 8 | 9 | print(match.group(1)) 10 | return match.group(1) if match else None 11 | 12 | class TestDetectFileRequest(unittest.TestCase): 13 | 14 | def test_text_files(self): 15 | self.assertEqual(detect_file_request("Can you read /path/to/file.txt?"), "/path/to/file.txt") 16 | self.assertEqual(detect_file_request("What's in /documents/note.md?"), "/documents/note.md") 17 | self.assertEqual(detect_file_request("Summarize the contents of this file: /Users/marconeves/Downloads/shakespeare.txt"), "/Users/marconeves/Downloads/shakespeare.txt") 18 | 19 | def test_code_files(self): 20 | self.assertEqual(detect_file_request("What's the output if I run /projects/python/script.py?"), "/projects/python/script.py") 21 | self.assertEqual(detect_file_request("Debug /webpage/assets/script.js"), "/webpage/assets/script.js") 22 | self.assertEqual(detect_file_request("Check for errors in /code/main.c"), "/code/main.c") 23 | 24 | def test_data_files(self): 25 | self.assertEqual(detect_file_request("What's the data in /sheets/financials.xlsx?"), "/sheets/financials.xlsx") 26 | self.assertEqual(detect_file_request("Can you analyze /database/sample.sql?"), "/database/sample.sql") 27 | self.assertEqual(detect_file_request("Tell me the stats from /data/report.h5"), "/data/report.h5") 28 | 29 | def test_image_files(self): 30 | self.assertEqual(detect_file_request("How does /images/sample.jpg look?"), "/images/sample.jpg") 31 | self.assertEqual(detect_file_request("Is /profile/picture.png a good photo?"), "/profile/picture.png") 32 | self.assertEqual(detect_file_request("Display the image at /photos/vacation.tiff"), "/photos/vacation.tiff") 33 | 34 | def test_document_files(self): 35 | self.assertEqual(detect_file_request("What's the content of /reports/annual.pdf?"), "/reports/annual.pdf") 36 | self.assertEqual(detect_file_request("Show me the slides in /conference/presentation.ppt"), "/conference/presentation.ppt") 37 | self.assertEqual(detect_file_request("Read the first page of /documents/contract.docx"), "/documents/contract.docx") 38 | 39 | def test_audio_files(self): 40 | self.assertEqual(detect_file_request("Can I listen to /music/album/song.flac?"), "/music/album/song.flac") 41 | self.assertEqual(detect_file_request("Play the track from /audio/recordings/interview.m4a"), "/audio/recordings/interview.m4a") 42 | self.assertEqual(detect_file_request("What's the duration of /podcasts/episode1.mp3?"), "/podcasts/episode1.mp3") 43 | 44 | def test_video_files(self): 45 | self.assertEqual(detect_file_request("I'd like to watch /movies/adventure.mp4"), "/movies/adventure.mp4") 46 | self.assertEqual(detect_file_request("Preview the clip at /videos/sample.avi"), "/videos/sample.avi") 47 | self.assertEqual(detect_file_request("What's the resolution of /recordings/conference.webm?"), "/recordings/conference.webm") 48 | 49 | def test_archive_files(self): 50 | self.assertEqual(detect_file_request("What's inside /backup/data.rar?"), "/backup/data.rar") 51 | self.assertEqual(detect_file_request("List the contents of /archives/project.zip"), "/archives/project.zip") 52 | self.assertEqual(detect_file_request("Extract /compressed/files.tar.gz for me"), "/compressed/files.tar.gz") 53 | 54 | def test_other_files(self): 55 | self.assertEqual(detect_file_request("Can you mount /os/windows.iso?"), "/os/windows.iso") 56 | self.assertEqual(detect_file_request("What's the size of /backup/full.img?"), "/backup/full.img") 57 | 58 | if __name__ == "__main__": 59 | unittest.main() --------------------------------------------------------------------------------