| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | import { useDark, useToggle } from "@vueuse/core"; | 
					
						
							| 
									
										
										
										
											2022-02-23 15:04:45 -09:00
										 |  |  | 
 | 
					
						
							|  |  |  | export const useToggleDarkMode = () => { | 
					
						
							|  |  |  |   const isDark = useDark(); | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |   const toggleDark = useToggle(isDark); | 
					
						
							| 
									
										
										
										
											2022-02-23 15:04:45 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |   return () => toggleDark(); | 
					
						
							| 
									
										
										
										
											2022-02-23 15:04:45 -09:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-07 15:12:25 -08:00
										 |  |  | export const useAsyncKey = function () { | 
					
						
							| 
									
										
										
										
											2025-09-27 19:17:08 -05:00
										 |  |  |   return `${Date.now()}-${Math.random().toString(36).slice(2)}`; | 
					
						
							| 
									
										
										
										
											2021-08-07 15:12:25 -08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-22 15:32:13 -09:00
										 |  |  | export const titleCase = function (str: string) { | 
					
						
							|  |  |  |   return str | 
					
						
							|  |  |  |     .split(" ") | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     .map(word => word.charAt(0).toUpperCase() + word.slice(1)) | 
					
						
							| 
									
										
										
										
											2022-02-22 15:32:13 -09:00
										 |  |  |     .join(" "); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  | export function uuid4() { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |   return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => | 
					
						
							|  |  |  |     (parseInt(c) ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (parseInt(c) / 4)))).toString(16), | 
					
						
							| 
									
										
										
										
											2021-11-06 11:28:47 -08:00
										 |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-06 14:32:55 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // https://stackoverflow.com/questions/28876300/deep-copying-array-of-nested-objects-in-javascript
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | export function deepCopy<T>(obj: T): T { | 
					
						
							| 
									
										
										
										
											2021-11-06 14:32:55 -08:00
										 |  |  |   let rv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (typeof obj) { | 
					
						
							|  |  |  |     case "object": | 
					
						
							|  |  |  |       if (obj === null) { | 
					
						
							|  |  |  |         // null => null
 | 
					
						
							|  |  |  |         rv = null; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |         switch (Object.prototype.toString.call(obj)) { | 
					
						
							| 
									
										
										
										
											2021-11-06 14:32:55 -08:00
										 |  |  |           case "[object Array]": | 
					
						
							|  |  |  |             // It's an array, create a new array with
 | 
					
						
							|  |  |  |             // deep copies of the entries
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |             rv = (obj as unknown as Array<unknown>).map(deepCopy); | 
					
						
							| 
									
										
										
										
											2021-11-06 14:32:55 -08:00
										 |  |  |             break; | 
					
						
							|  |  |  |           case "[object Date]": | 
					
						
							|  |  |  |             // Clone the date
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |             rv = new Date(obj as unknown as Date); | 
					
						
							| 
									
										
										
										
											2021-11-06 14:32:55 -08:00
										 |  |  |             break; | 
					
						
							|  |  |  |           case "[object RegExp]": | 
					
						
							|  |  |  |             // Clone the RegExp
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |             rv = new RegExp(obj as unknown as RegExp); | 
					
						
							| 
									
										
										
										
											2021-11-06 14:32:55 -08:00
										 |  |  |             break; | 
					
						
							|  |  |  |           // ...probably a few others
 | 
					
						
							|  |  |  |           default: | 
					
						
							|  |  |  |             // Some other kind of object, deep-copy its
 | 
					
						
							|  |  |  |             // properties into a new object
 | 
					
						
							|  |  |  |             rv = Object.keys(obj).reduce(function (prev, key) { | 
					
						
							|  |  |  |               prev[key] = deepCopy(obj[key]); | 
					
						
							|  |  |  |               return prev; | 
					
						
							|  |  |  |             }, {}); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       // It's a primitive, copy via assignment
 | 
					
						
							|  |  |  |       rv = obj; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |   return rv as T; | 
					
						
							| 
									
										
										
										
											2021-11-06 14:32:55 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-17 10:30:10 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function downloadAsJson(data: any, filename: string) { | 
					
						
							|  |  |  |   const content = JSON.stringify(data); | 
					
						
							|  |  |  |   const blob = new Blob([content], { type: "application/json" }); | 
					
						
							|  |  |  |   const url = URL.createObjectURL(blob); | 
					
						
							|  |  |  |   const a = document.createElement("a"); | 
					
						
							|  |  |  |   a.download = filename; | 
					
						
							|  |  |  |   a.href = url; | 
					
						
							|  |  |  |   a.click(); | 
					
						
							|  |  |  |   URL.revokeObjectURL(url); | 
					
						
							|  |  |  | } |