Compare commits
150 Commits
v0.101.0
...
feat/extra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
254145f0e5 | ||
|
|
c28f11336e | ||
|
|
2e30683b7b | ||
|
|
0af7b8b145 | ||
|
|
5d39b84886 | ||
|
|
537c4051cc | ||
|
|
d0a22bc517 | ||
|
|
19a75acf3f | ||
|
|
3f0abce874 | ||
|
|
36dd29f919 | ||
|
|
d7838f0b67 | ||
|
|
3353d4f436 | ||
|
|
7740154bdc | ||
|
|
a14eed81f6 | ||
|
|
54f51b365a | ||
|
|
c0e0a712ad | ||
|
|
3ab5bbae4d | ||
|
|
cafeb3920a | ||
|
|
fb465b442c | ||
|
|
d3a559a700 | ||
|
|
7768003735 | ||
|
|
f02b3b48e8 | ||
|
|
ba273bb9f4 | ||
|
|
490c539d63 | ||
|
|
ebd60519dd | ||
|
|
56304a4d71 | ||
|
|
32f0f98522 | ||
|
|
b18dd22341 | ||
|
|
8eebae0955 | ||
|
|
ed229e0578 | ||
|
|
dbfaad6c06 | ||
|
|
6e5176b088 | ||
|
|
becf4d7426 | ||
|
|
082040c6e1 | ||
|
|
1ae11ce3a5 | ||
|
|
cf968b3590 | ||
|
|
a3db1ab156 | ||
|
|
7440110a44 | ||
|
|
3638e6b12c | ||
|
|
621ed5b9de | ||
|
|
1e3135dea0 | ||
|
|
8f21c0b34a | ||
|
|
b3feb38369 | ||
|
|
2bf862d5b9 | ||
|
|
cbb7b4ffea | ||
|
|
b2f496048f | ||
|
|
e084bc4c07 | ||
|
|
d9b0660def | ||
|
|
b997452733 | ||
|
|
e699566e62 | ||
|
|
2bd83e6285 | ||
|
|
46e5090445 | ||
|
|
035a311e4d | ||
|
|
850528750c | ||
|
|
645720a725 | ||
|
|
a6c74449aa | ||
|
|
7f05d9cdff | ||
|
|
02d42dc5ff | ||
|
|
e730378b27 | ||
|
|
c14d95f561 | ||
|
|
13b700e0e5 | ||
|
|
f849c4b315 | ||
|
|
c2c19e8ecd | ||
|
|
12875ec308 | ||
|
|
5d12d57a22 | ||
|
|
5cc2296768 | ||
|
|
7c1175995f | ||
|
|
d834cd78a7 | ||
|
|
79d2010bfa | ||
|
|
3f86c809ce | ||
|
|
1570ea77d8 | ||
|
|
99bdd2e433 | ||
|
|
7646061215 | ||
|
|
505a985755 | ||
|
|
e895ea406a | ||
|
|
8b8a78e949 | ||
|
|
1c940ff8a2 | ||
|
|
841cb32835 | ||
|
|
61e96f91d0 | ||
|
|
9f6c07f5cc | ||
|
|
1efb21c627 | ||
|
|
d5b04864c8 | ||
|
|
da28f4505a | ||
|
|
5174deac07 | ||
|
|
e2a628fa2f | ||
|
|
290f488c78 | ||
|
|
b00cb52da5 | ||
|
|
c7bb5ff119 | ||
|
|
faa069b8a1 | ||
|
|
e57f1e6f23 | ||
|
|
73975ab521 | ||
|
|
761a67f238 | ||
|
|
736c69816d | ||
|
|
270339da11 | ||
|
|
aa93bc5492 | ||
|
|
0c9c36ea7e | ||
|
|
af67967502 | ||
|
|
78bec0c782 | ||
|
|
0c77563672 | ||
|
|
241a9e2e7f | ||
|
|
59b691d670 | ||
|
|
a6c515aea0 | ||
|
|
850710926e | ||
|
|
904da14895 | ||
|
|
4c5bc3a3d3 | ||
|
|
ecec661b72 | ||
|
|
fb629f7693 | ||
|
|
13fff33aa4 | ||
|
|
8053221b12 | ||
|
|
ba699f9842 | ||
|
|
eb5ebb53cb | ||
|
|
c26357be40 | ||
|
|
db4af96040 | ||
|
|
5cb3983fe0 | ||
|
|
92292de0ff | ||
|
|
a26923cc6d | ||
|
|
2c4ac4ba30 | ||
|
|
254511bfbf | ||
|
|
e2f6f8a4e4 | ||
|
|
e346963e76 | ||
|
|
5f1bdf7264 | ||
|
|
93a3b29677 | ||
|
|
b157cd909c | ||
|
|
2f24703690 | ||
|
|
27efa8844e | ||
|
|
98de4b6dc3 | ||
|
|
d121de5152 | ||
|
|
5ad7323d03 | ||
|
|
183020a4e3 | ||
|
|
a56a5fe1f5 | ||
|
|
af4fc11a4e | ||
|
|
a63b8b2031 | ||
|
|
7b02d87558 | ||
|
|
16737b93dd | ||
|
|
c23fe7cf13 | ||
|
|
6d80323a76 | ||
|
|
8b630c6e2e | ||
|
|
047a8d9644 | ||
|
|
f14ae01fab | ||
|
|
785470b0ae | ||
|
|
73918c042b | ||
|
|
8d6eb6fa53 | ||
|
|
f97fbf8325 | ||
|
|
e7d6e646be | ||
|
|
839444af47 | ||
|
|
24a58da4b6 | ||
|
|
aa37196169 | ||
|
|
f821d7fcd6 | ||
|
|
b417831507 | ||
|
|
a4dbefd7ef |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@triliumnext/client",
|
||||
"version": "0.101.0",
|
||||
"version": "0.101.1",
|
||||
"description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0-only",
|
||||
@@ -61,6 +61,7 @@
|
||||
"panzoom": "9.4.3",
|
||||
"preact": "10.28.1",
|
||||
"react-i18next": "16.5.0",
|
||||
"react-window": "2.2.3",
|
||||
"reveal.js": "5.2.1",
|
||||
"svg-pan-zoom": "3.6.2",
|
||||
"tabulator-tables": "6.3.1",
|
||||
|
||||
@@ -535,6 +535,7 @@ export type FilteredCommandNames<T extends CommandData> = keyof Pick<CommandMapp
|
||||
|
||||
export class AppContext extends Component {
|
||||
isMainWindow: boolean;
|
||||
windowId: string;
|
||||
components: Component[];
|
||||
beforeUnloadListeners: (WeakRef<BeforeUploadListener> | (() => boolean))[];
|
||||
tabManager!: TabManager;
|
||||
@@ -543,10 +544,11 @@ export class AppContext extends Component {
|
||||
|
||||
lastSearchString?: string;
|
||||
|
||||
constructor(isMainWindow: boolean) {
|
||||
constructor(isMainWindow: boolean, windowId: string) {
|
||||
super();
|
||||
|
||||
this.isMainWindow = isMainWindow;
|
||||
this.windowId = windowId;
|
||||
// non-widget/layout components needed for the application
|
||||
this.components = [];
|
||||
this.beforeUnloadListeners = [];
|
||||
@@ -676,8 +678,7 @@ export class AppContext extends Component {
|
||||
this.beforeUnloadListeners = this.beforeUnloadListeners.filter(l => l !== listener);
|
||||
}
|
||||
}
|
||||
|
||||
const appContext = new AppContext(window.glob.isMainWindow);
|
||||
const appContext = new AppContext(window.glob.isMainWindow, window.glob.windowId);
|
||||
|
||||
// we should save all outstanding changes before the page/app is closed
|
||||
$(window).on("beforeunload", () => {
|
||||
|
||||
@@ -142,14 +142,15 @@ export default class Entrypoints extends Component {
|
||||
}
|
||||
|
||||
async openInWindowCommand({ notePath, hoistedNoteId, viewScope }: NoteCommandData) {
|
||||
const extraWindowId = utils.randomString(4);
|
||||
const extraWindowHash = linkService.calculateHash({ notePath, hoistedNoteId, viewScope });
|
||||
|
||||
if (utils.isElectron()) {
|
||||
const { ipcRenderer } = utils.dynamicRequire("electron");
|
||||
|
||||
ipcRenderer.send("create-extra-window", { extraWindowHash });
|
||||
ipcRenderer.send("create-extra-window", { extraWindowId, extraWindowHash });
|
||||
} else {
|
||||
const url = `${window.location.protocol}//${window.location.host}${window.location.pathname}?extraWindow=1${extraWindowHash}`;
|
||||
const url = `${window.location.protocol}//${window.location.host}${window.location.pathname}?extraWindow=${extraWindowId}${extraWindowHash}`;
|
||||
|
||||
window.open(url, "", "width=1000,height=800");
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import linkService from "../services/link.js";
|
||||
import type { EventData } from "./app_context.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
|
||||
const MAX_SAVED_WINDOWS = 10;
|
||||
|
||||
interface TabState {
|
||||
contexts: NoteContext[];
|
||||
position: number;
|
||||
@@ -41,9 +43,6 @@ export default class TabManager extends Component {
|
||||
this.recentlyClosedTabs = [];
|
||||
|
||||
this.tabsUpdate = new SpacedUpdate(async () => {
|
||||
if (!appContext.isMainWindow) {
|
||||
return;
|
||||
}
|
||||
if (options.is("databaseReadonly")) {
|
||||
return;
|
||||
}
|
||||
@@ -52,9 +51,21 @@ export default class TabManager extends Component {
|
||||
.map((nc) => nc.getPojoState())
|
||||
.filter((t) => !!t);
|
||||
|
||||
await server.put("options", {
|
||||
openNoteContexts: JSON.stringify(openNoteContexts)
|
||||
});
|
||||
// Update the current window’s openNoteContexts in options
|
||||
const savedWindows = options.getJson("openNoteContexts");
|
||||
const win = savedWindows.find(w => w.windowId === appContext.windowId);
|
||||
if (win) {
|
||||
win.contexts = openNoteContexts;
|
||||
} else {
|
||||
savedWindows.push({
|
||||
windowId: appContext.windowId,
|
||||
createdAt: Date.now(),
|
||||
closedAt: null,
|
||||
contexts: openNoteContexts
|
||||
});
|
||||
}
|
||||
|
||||
await options.save("openNoteContexts", JSON.stringify(savedWindows));
|
||||
});
|
||||
|
||||
appContext.addBeforeUnloadListener(this);
|
||||
@@ -69,8 +80,13 @@ export default class TabManager extends Component {
|
||||
}
|
||||
|
||||
async loadTabs() {
|
||||
// Get the current window’s openNoteContexts
|
||||
const savedWindows = options.getJson("openNoteContexts");
|
||||
const currentWin = savedWindows.find(w => w.windowId === appContext.windowId);
|
||||
const openNoteContexts = currentWin ? currentWin.contexts : undefined;
|
||||
|
||||
try {
|
||||
const noteContextsToOpen = (appContext.isMainWindow && options.getJson("openNoteContexts")) || [];
|
||||
const noteContextsToOpen = openNoteContexts || [];
|
||||
|
||||
// preload all notes at once
|
||||
await froca.getNotes([...noteContextsToOpen.flatMap((tab: NoteContextState) =>
|
||||
@@ -119,6 +135,32 @@ export default class TabManager extends Component {
|
||||
}
|
||||
});
|
||||
|
||||
// Save window contents
|
||||
if (currentWin) {
|
||||
currentWin.createdAt = Date.now();
|
||||
currentWin.closedAt = null;
|
||||
currentWin.contexts = filteredNoteContexts;
|
||||
} else {
|
||||
// Filter out the oldest entry (excluding the main window)
|
||||
if (savedWindows?.length >= MAX_SAVED_WINDOWS) {
|
||||
const candidates = savedWindows.filter(w => w.windowId !== "main");
|
||||
if (candidates.length > 0) {
|
||||
const oldest = candidates.reduce((a, b) =>
|
||||
a.createdAt < b.createdAt ? a : b
|
||||
);
|
||||
savedWindows.splice(savedWindows.indexOf(oldest), 1);
|
||||
}
|
||||
}
|
||||
savedWindows.push({
|
||||
windowId: appContext.windowId,
|
||||
createdAt: Date.now(),
|
||||
closedAt: null,
|
||||
contexts: filteredNoteContexts
|
||||
});
|
||||
}
|
||||
|
||||
await options.save("openNoteContexts", JSON.stringify(savedWindows));
|
||||
|
||||
// if there's a notePath in the URL, make sure it's open and active
|
||||
// (useful, for e.g., opening clipped notes from clipper or opening link in an extra window)
|
||||
if (parsedFromUrl.notePath) {
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import appContext from "./components/app_context.js";
|
||||
import utils from "./services/utils.js";
|
||||
import noteTooltipService from "./services/note_tooltip.js";
|
||||
import bundleService from "./services/bundle.js";
|
||||
import toastService from "./services/toast.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
import electronContextMenu from "./menus/electron_context_menu.js";
|
||||
import glob from "./services/glob.js";
|
||||
import { t } from "./services/i18n.js";
|
||||
import options from "./services/options.js";
|
||||
import "autocomplete.js/index_jquery.js";
|
||||
|
||||
import type ElectronRemote from "@electron/remote";
|
||||
import type Electron from "electron";
|
||||
import "boxicons/css/boxicons.min.css";
|
||||
import "autocomplete.js/index_jquery.js";
|
||||
|
||||
import appContext from "./components/app_context.js";
|
||||
import electronContextMenu from "./menus/electron_context_menu.js";
|
||||
import bundleService from "./services/bundle.js";
|
||||
import glob from "./services/glob.js";
|
||||
import { t } from "./services/i18n.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
import noteTooltipService from "./services/note_tooltip.js";
|
||||
import options from "./services/options.js";
|
||||
import toastService from "./services/toast.js";
|
||||
import utils from "./services/utils.js";
|
||||
|
||||
await appContext.earlyInit();
|
||||
|
||||
|
||||
@@ -582,6 +582,10 @@ export default class FNote {
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return `tn-icon ${this.#getIconInternal()}`;
|
||||
}
|
||||
|
||||
#getIconInternal() {
|
||||
const iconClassLabels = this.getLabels("iconClass");
|
||||
const workspaceIconClass = this.getWorkspaceIconClass();
|
||||
|
||||
|
||||
BIN
apps/client/src/fonts/boxicons.woff2
Normal file
@@ -92,7 +92,7 @@ export default class DesktopLayout {
|
||||
.optChild(launcherPaneIsHorizontal, <LeftPaneToggle isHorizontalLayout={true} />)
|
||||
.child(<TabHistoryNavigationButtons />)
|
||||
.child(new TabRowWidget().class("full-width"))
|
||||
.optChild(launcherPaneIsHorizontal && isNewLayout, <RightPaneToggle />)
|
||||
.optChild(isNewLayout, <RightPaneToggle />)
|
||||
.optChild(customTitleBarButtons, <TitleBarButtons />)
|
||||
.css("height", "40px")
|
||||
.css("background-color", "var(--launcher-pane-background-color)")
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import appContext from "./components/app_context.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
import glob from "./services/glob.js";
|
||||
import "boxicons/css/boxicons.min.css";
|
||||
import "autocomplete.js/index_jquery.js";
|
||||
|
||||
import appContext from "./components/app_context.js";
|
||||
import glob from "./services/glob.js";
|
||||
import noteAutocompleteService from "./services/note_autocomplete.js";
|
||||
|
||||
glob.setupGlobs();
|
||||
|
||||
await appContext.earlyInit();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { signal } from "@preact/signals";
|
||||
import appContext from "../components/app_context.js";
|
||||
import froca from "./froca.js";
|
||||
import { t } from "./i18n.js";
|
||||
import utils from "./utils.js";
|
||||
import utils, { randomString } from "./utils.js";
|
||||
|
||||
export interface ToastOptions {
|
||||
id?: string;
|
||||
@@ -86,7 +86,7 @@ export async function showErrorForScriptNote(noteId: string, message: string) {
|
||||
export const toasts = signal<ToastOptionsWithRequiredId[]>([]);
|
||||
|
||||
function addToast(opts: ToastOptions) {
|
||||
const id = opts.id ?? crypto.randomUUID();
|
||||
const id = opts.id ?? randomString();
|
||||
const toast = { ...opts, id };
|
||||
toasts.value = [ ...toasts.value, toast ];
|
||||
return id;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { dayjs } from "@triliumnext/commons";
|
||||
import type { ViewMode, ViewScope } from "./link.js";
|
||||
import FNote from "../entities/fnote";
|
||||
import { snapdom } from "@zumer/snapdom";
|
||||
|
||||
import FNote from "../entities/fnote";
|
||||
import type { ViewMode, ViewScope } from "./link.js";
|
||||
|
||||
const SVG_MIME = "image/svg+xml";
|
||||
|
||||
export const isShare = !window.glob;
|
||||
@@ -113,9 +114,8 @@ function formatDateISO(date: Date) {
|
||||
export function formatDateTime(date: Date, userSuppliedFormat?: string): string {
|
||||
if (userSuppliedFormat?.trim()) {
|
||||
return dayjs(date).format(userSuppliedFormat);
|
||||
} else {
|
||||
return `${formatDate(date)} ${formatTime(date)}`;
|
||||
}
|
||||
return `${formatDate(date)} ${formatTime(date)}`;
|
||||
}
|
||||
|
||||
function localNowDateTime() {
|
||||
@@ -191,9 +191,9 @@ export function formatSize(size: number | null | undefined) {
|
||||
|
||||
if (size < 1024) {
|
||||
return `${size} KiB`;
|
||||
} else {
|
||||
return `${Math.round(size / 102.4) / 10} MiB`;
|
||||
}
|
||||
return `${Math.round(size / 102.4) / 10} MiB`;
|
||||
|
||||
}
|
||||
|
||||
function toObject<T, R>(array: T[], fn: (arg0: T) => [key: string, value: R]) {
|
||||
@@ -208,7 +208,7 @@ function toObject<T, R>(array: T[], fn: (arg0: T) => [key: string, value: R]) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
export function randomString(len: number) {
|
||||
export function randomString(len: number = 16) {
|
||||
let text = "";
|
||||
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
@@ -297,18 +297,18 @@ function formatHtml(html: string) {
|
||||
let indent = "\n";
|
||||
const tab = "\t";
|
||||
let i = 0;
|
||||
let pre: { indent: string; tag: string }[] = [];
|
||||
const pre: { indent: string; tag: string }[] = [];
|
||||
|
||||
html = html
|
||||
.replace(new RegExp("<pre>([\\s\\S]+?)?</pre>"), function (x) {
|
||||
.replace(new RegExp("<pre>([\\s\\S]+?)?</pre>"), (x) => {
|
||||
pre.push({ indent: "", tag: x });
|
||||
return "<--TEMPPRE" + i++ + "/-->";
|
||||
return `<--TEMPPRE${i++}/-->`;
|
||||
})
|
||||
.replace(new RegExp("<[^<>]+>[^<]?", "g"), function (x) {
|
||||
.replace(new RegExp("<[^<>]+>[^<]?", "g"), (x) => {
|
||||
let ret;
|
||||
const tagRegEx = /<\/?([^\s/>]+)/.exec(x);
|
||||
let tag = tagRegEx ? tagRegEx[1] : "";
|
||||
let p = new RegExp("<--TEMPPRE(\\d+)/-->").exec(x);
|
||||
const tag = tagRegEx ? tagRegEx[1] : "";
|
||||
const p = new RegExp("<--TEMPPRE(\\d+)/-->").exec(x);
|
||||
|
||||
if (p) {
|
||||
const pInd = parseInt(p[1]);
|
||||
@@ -318,24 +318,22 @@ function formatHtml(html: string) {
|
||||
if (["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "menuitem", "meta", "param", "source", "track", "wbr"].indexOf(tag) >= 0) {
|
||||
// self closing tag
|
||||
ret = indent + x;
|
||||
} else if (x.indexOf("</") < 0) {
|
||||
//open tag
|
||||
if (x.charAt(x.length - 1) !== ">") ret = indent + x.substr(0, x.length - 1) + indent + tab + x.substr(x.length - 1, x.length);
|
||||
else ret = indent + x;
|
||||
!p && (indent += tab);
|
||||
} else {
|
||||
if (x.indexOf("</") < 0) {
|
||||
//open tag
|
||||
if (x.charAt(x.length - 1) !== ">") ret = indent + x.substr(0, x.length - 1) + indent + tab + x.substr(x.length - 1, x.length);
|
||||
else ret = indent + x;
|
||||
!p && (indent += tab);
|
||||
} else {
|
||||
//close tag
|
||||
indent = indent.substr(0, indent.length - 1);
|
||||
if (x.charAt(x.length - 1) !== ">") ret = indent + x.substr(0, x.length - 1) + indent + x.substr(x.length - 1, x.length);
|
||||
else ret = indent + x;
|
||||
}
|
||||
//close tag
|
||||
indent = indent.substr(0, indent.length - 1);
|
||||
if (x.charAt(x.length - 1) !== ">") ret = indent + x.substr(0, x.length - 1) + indent + x.substr(x.length - 1, x.length);
|
||||
else ret = indent + x;
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
|
||||
for (i = pre.length; i--;) {
|
||||
html = html.replace("<--TEMPPRE" + i + "/-->", pre[i].tag.replace("<pre>", "<pre>\n").replace("</pre>", pre[i].indent + "</pre>"));
|
||||
html = html.replace(`<--TEMPPRE${i}/-->`, pre[i].tag.replace("<pre>", "<pre>\n").replace("</pre>", `${pre[i].indent}</pre>`));
|
||||
}
|
||||
|
||||
return html.charAt(0) === "\n" ? html.substr(1, html.length - 1) : html;
|
||||
@@ -364,11 +362,11 @@ type dynamicRequireMappings = {
|
||||
export function dynamicRequire<T extends keyof dynamicRequireMappings>(moduleName: T): Awaited<dynamicRequireMappings[T]>{
|
||||
if (typeof __non_webpack_require__ !== "undefined") {
|
||||
return __non_webpack_require__(moduleName);
|
||||
} else {
|
||||
// explicitly pass as string and not as expression to suppress webpack warning
|
||||
// 'Critical dependency: the request of a dependency is an expression'
|
||||
return require(`${moduleName}`);
|
||||
}
|
||||
// explicitly pass as string and not as expression to suppress webpack warning
|
||||
// 'Critical dependency: the request of a dependency is an expression'
|
||||
return require(`${moduleName}`);
|
||||
|
||||
}
|
||||
|
||||
function timeLimit<T>(promise: Promise<T>, limitMs: number, errorMessage?: string) {
|
||||
@@ -509,8 +507,8 @@ export function escapeRegExp(str: string) {
|
||||
function areObjectsEqual(...args: unknown[]) {
|
||||
let i;
|
||||
let l;
|
||||
let leftChain: Object[];
|
||||
let rightChain: Object[];
|
||||
let leftChain: object[];
|
||||
let rightChain: object[];
|
||||
|
||||
function compare2Objects(x: unknown, y: unknown) {
|
||||
let p;
|
||||
@@ -695,9 +693,9 @@ async function downloadAsSvg(nameWithoutExtension: string, svgSource: string | S
|
||||
|
||||
try {
|
||||
const result = await snapdom(element, {
|
||||
backgroundColor: "transparent",
|
||||
scale: 2
|
||||
});
|
||||
backgroundColor: "transparent",
|
||||
scale: 2
|
||||
});
|
||||
triggerDownload(`${nameWithoutExtension}.svg`, result.url);
|
||||
} finally {
|
||||
cleanup();
|
||||
@@ -733,9 +731,9 @@ async function downloadAsPng(nameWithoutExtension: string, svgSource: string | S
|
||||
|
||||
try {
|
||||
const result = await snapdom(element, {
|
||||
backgroundColor: "transparent",
|
||||
scale: 2
|
||||
});
|
||||
backgroundColor: "transparent",
|
||||
scale: 2
|
||||
});
|
||||
const pngImg = await result.toPng();
|
||||
await triggerDownload(`${nameWithoutExtension}.png`, pngImg.src);
|
||||
} finally {
|
||||
@@ -763,11 +761,11 @@ export function getSizeFromSvg(svgContent: string) {
|
||||
return {
|
||||
width: parseFloat(width),
|
||||
height: parseFloat(height)
|
||||
}
|
||||
} else {
|
||||
console.warn("SVG export error", svgDocument.documentElement);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
console.warn("SVG export error", svgDocument.documentElement);
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -896,9 +894,9 @@ export function mapToKeyValueArray<K extends string | number | symbol, V>(map: R
|
||||
export function getErrorMessage(e: unknown) {
|
||||
if (e && typeof e === "object" && "message" in e && typeof e.message === "string") {
|
||||
return e.message;
|
||||
} else {
|
||||
return "Unknown error";
|
||||
}
|
||||
return "Unknown error";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
498
apps/client/src/stylesheets/boxicons-compat.css
Normal file
@@ -0,0 +1,498 @@
|
||||
.bx-ul
|
||||
{
|
||||
margin-left: 2em;
|
||||
padding-left: 0;
|
||||
|
||||
list-style: none;
|
||||
}
|
||||
.bx-ul > li
|
||||
{
|
||||
position: relative;
|
||||
}
|
||||
.bx-ul .bx
|
||||
{
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
position: absolute;
|
||||
left: -2em;
|
||||
|
||||
width: 2em;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
@-webkit-keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: rotate3d(0, 0, 1, -10deg);
|
||||
transform: rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
.bx-spin
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.bx-spin-hover:hover
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
.bx-tada
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
.bx-tada-hover:hover
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
|
||||
.bx-flashing
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
.bx-flashing-hover:hover
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
|
||||
.bx-burst
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-burst-hover:hover
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-xs
|
||||
{
|
||||
font-size: 1rem!important;
|
||||
}
|
||||
.bx-sm
|
||||
{
|
||||
font-size: 1.55rem!important;
|
||||
}
|
||||
.bx-md
|
||||
{
|
||||
font-size: 2.25rem!important;
|
||||
}
|
||||
.bx-lg
|
||||
{
|
||||
font-size: 3.0rem!important;
|
||||
}
|
||||
.bx-fw
|
||||
{
|
||||
font-size: 1.2857142857em;
|
||||
line-height: .8em;
|
||||
|
||||
width: 1.2857142857em;
|
||||
height: .8em;
|
||||
margin-top: -.2em!important;
|
||||
|
||||
vertical-align: middle;
|
||||
}
|
||||
.bx-pull-left
|
||||
{
|
||||
float: left;
|
||||
|
||||
margin-right: .3em!important;
|
||||
}
|
||||
.bx-pull-right
|
||||
{
|
||||
float: right;
|
||||
|
||||
margin-left: .3em!important;
|
||||
}
|
||||
.bx-rotate-90
|
||||
{
|
||||
transform: rotate(90deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)';
|
||||
}
|
||||
.bx-rotate-180
|
||||
{
|
||||
transform: rotate(180deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
|
||||
}
|
||||
.bx-rotate-270
|
||||
{
|
||||
transform: rotate(270deg);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';
|
||||
}
|
||||
.bx-flip-horizontal
|
||||
{
|
||||
transform: scaleX(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)';
|
||||
}
|
||||
.bx-flip-vertical
|
||||
{
|
||||
transform: scaleY(-1);
|
||||
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
|
||||
}
|
||||
.bx-border
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: .25em;
|
||||
}
|
||||
.bx-border-circle
|
||||
{
|
||||
padding: .25em;
|
||||
|
||||
border: .07em solid rgba(0,0,0,.1);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/** Custom icon **/
|
||||
.bx-empty {
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
@import "./boxicons-compat.css";
|
||||
|
||||
@font-face {
|
||||
font-family: Montserrat;
|
||||
src: url(../fonts/Montserrat-Light.ttf);
|
||||
@@ -436,7 +438,6 @@ body.desktop .tabulator-popup-container,
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dropdown-menu a:hover:not(.disabled),
|
||||
.dropdown-item:hover:not(.disabled, .dropdown-container-item),
|
||||
.tabulator-menu-item:hover,
|
||||
:root .excalidraw .context-menu .context-menu-item:hover {
|
||||
@@ -1129,11 +1130,6 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
|
||||
border-color: var(--main-border-color) !important;
|
||||
}
|
||||
|
||||
.bx-empty {
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 0.5rem 1rem 0.5rem 1rem !important; /* make modal header padding slightly smaller */
|
||||
}
|
||||
@@ -1800,7 +1796,7 @@ button.close:hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.reference-link .bx {
|
||||
.reference-link .tn-icon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
margin-inline-end: 3px;
|
||||
@@ -1952,6 +1948,10 @@ body.electron.platform-darwin:not(.native-titlebar) .tab-row-container {
|
||||
padding-inline-start: 1em;
|
||||
}
|
||||
|
||||
.tab-row-widget {
|
||||
contain: inline-size;
|
||||
}
|
||||
|
||||
#tab-row-left-spacer {
|
||||
width: env(titlebar-area-x);
|
||||
-webkit-app-region: drag;
|
||||
@@ -1961,7 +1961,7 @@ body.electron.platform-darwin:not(.native-titlebar):not(.full-screen) #tab-row-l
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.tab-row-container {
|
||||
body.electron:not(.platform-darwin) .tab-row-container {
|
||||
padding-inline-end: calc(100vw - env(titlebar-area-width, 100vw));
|
||||
}
|
||||
|
||||
@@ -2415,7 +2415,7 @@ footer.webview-footer button {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.right-pane-tab .tab-title .bx {
|
||||
.right-pane-tab .tab-title .tn-icon {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
@@ -2543,18 +2543,11 @@ footer.webview-footer button {
|
||||
inset-inline-end: 10px;
|
||||
}
|
||||
|
||||
.content-floating-buttons button.bx {
|
||||
.content-floating-buttons button.tn-icon {
|
||||
font-size: 130%;
|
||||
padding: 1px 10px 1px 10px;
|
||||
}
|
||||
|
||||
/* Customized icons */
|
||||
|
||||
.bx-tn-toc::before {
|
||||
content: "\ec24";
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* CK Editor */
|
||||
|
||||
/* Insert text snippet: limit the width of the listed items to avoid overly long names */
|
||||
|
||||
@@ -349,5 +349,5 @@ body .todo-list input[type="checkbox"]:not(:checked):before {
|
||||
|
||||
.note-split.with-hue *::selection,
|
||||
.quick-edit-dialog-wrapper.with-hue *::selection {
|
||||
background: hsl(var(--custom-color-hue), 49.2%, 35%);
|
||||
--selection-background-color: hsl(var(--custom-color-hue), 49.2%, 35%);
|
||||
}
|
||||
@@ -320,5 +320,5 @@
|
||||
|
||||
.note-split.with-hue *::selection,
|
||||
.quick-edit-dialog-wrapper.with-hue *::selection {
|
||||
background: hsl(var(--custom-color-hue), 60%, 90%);
|
||||
--selection-background-color: hsl(var(--custom-color-hue), 60%, 90%);
|
||||
}
|
||||
@@ -134,7 +134,7 @@ body.backdrop-effects-disabled {
|
||||
white-space-collapse: discard;
|
||||
}
|
||||
|
||||
.dropdown-menu.tn-dropdown-menu .bx {
|
||||
.dropdown-menu.tn-dropdown-menu .dropdown-item .tn-icon {
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ html body .dropdown-item[disabled] {
|
||||
}
|
||||
|
||||
/* Menu item icon */
|
||||
.dropdown-item .bx {
|
||||
.dropdown-item .tn-icon {
|
||||
translate: 0 var(--menu-item-icon-vert-offset);
|
||||
color: var(--menu-item-icon-color) !important;
|
||||
font-size: 1.1em;
|
||||
@@ -496,7 +496,7 @@ li.dropdown-item a.dropdown-item-button {
|
||||
border: unset;
|
||||
}
|
||||
|
||||
li.dropdown-item a.dropdown-item-button.bx {
|
||||
li.dropdown-item a.dropdown-item-button.tn-icon {
|
||||
color: var(--menu-text-color) !important;
|
||||
}
|
||||
|
||||
@@ -557,13 +557,13 @@ li.dropdown-item a.dropdown-item-button:focus-visible {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#toast-container .toast:not(.no-title) .bx {
|
||||
#toast-container .toast:not(.no-title) .tn-icon {
|
||||
margin-inline-end: 0.5em;
|
||||
font-size: 1.1em;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
#toast-container .toast.no-title .bx {
|
||||
#toast-container .toast.no-title .tn-icon {
|
||||
margin-inline-end: 0;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
@@ -754,7 +754,7 @@ li.dropdown-item a.dropdown-item-button:focus-visible {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.note-list-wrapper .note-book-card .bx {
|
||||
.note-list-wrapper .note-book-card .tn-icon {
|
||||
color: var(--left-pane-icon-color) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,6 +423,6 @@ div.tn-tool-dialog {
|
||||
font-size: unset;
|
||||
}
|
||||
|
||||
.note-type-chooser-dialog div.note-type-dropdown .dropdown-item span.bx {
|
||||
.note-type-chooser-dialog div.note-type-dropdown .dropdown-item span.tn-icon {
|
||||
margin-inline-end: .25em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ button.ck.ck-button:is(.ck-button-action, .ck-button-save, .ck-button-cancel, .c
|
||||
}
|
||||
|
||||
/* Button's icon */
|
||||
button.btn.btn-primary span.bx,
|
||||
button.btn.btn-secondary span.bx,
|
||||
button.btn.btn-sm span.bx,
|
||||
button.btn.btn-success span.bx {
|
||||
button.btn.btn-primary span.tn-icon,
|
||||
button.btn.btn-secondary span.tn-icon,
|
||||
button.btn.btn-sm span.tn-icon,
|
||||
button.btn.btn-success span.tn-icon {
|
||||
color: var(--cmd-button-icon-color);
|
||||
padding-inline-end: 0.35em;
|
||||
font-size: 1.2em;
|
||||
|
||||
@@ -634,6 +634,10 @@ html .note-detail-editable-text :not(figure, .include-note, hr):first-child {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.ck-content strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ck-content hr {
|
||||
margin: 5px 0;
|
||||
height: 1px;
|
||||
|
||||
@@ -151,6 +151,11 @@
|
||||
--options-title-font-size: .75rem;
|
||||
--options-title-offset: 13px;
|
||||
}
|
||||
|
||||
.note-split.options {
|
||||
--preferred-max-content-width: var(--options-card-max-width);
|
||||
}
|
||||
|
||||
/* Create a gap at the top of the option pages */
|
||||
.note-detail-content-widget-content.options>*:first-child {
|
||||
margin-top: var(--options-first-item-top-margin, 1em);
|
||||
@@ -185,10 +190,6 @@ body.experimental-feature-new-layout .note-detail-content-widget-content.options
|
||||
padding: var(--options-card-padding);
|
||||
}
|
||||
|
||||
body.prefers-centered-content .options-section:not(.tn-no-card) {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
body.desktop .options-section:not(.tn-no-card) {
|
||||
min-width: var(--options-card-min-width);
|
||||
max-width: var(--options-card-max-width);
|
||||
|
||||
@@ -497,7 +497,7 @@ div.bookmark-folder-widget .note-link:hover a {
|
||||
}
|
||||
|
||||
/* The item's icon */
|
||||
div.bookmark-folder-widget .note-link .bx {
|
||||
div.bookmark-folder-widget .note-link .tn-icon {
|
||||
color: var(--menu-item-icon-color);
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
@@ -229,11 +229,11 @@ span.fancytree-node.archived {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.fancytree-node:hover .bx.tree-item-button {
|
||||
.fancytree-node:hover .tn-icon.tree-item-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bx.tree-item-button {
|
||||
.tn-icon.tree-item-button {
|
||||
display: none;
|
||||
font-size: 120%;
|
||||
cursor: pointer;
|
||||
@@ -243,7 +243,7 @@ span.fancytree-node.archived {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.unhoist-button.bx.tree-item-button {
|
||||
.unhoist-button.tn-icon.tree-item-button {
|
||||
margin-inline-start: 0; /* unhoist button is on the left and doesn't need more margin */
|
||||
display: block; /* keep always visible */
|
||||
}
|
||||
|
||||
@@ -11,11 +11,25 @@
|
||||
},
|
||||
"toast": {
|
||||
"critical-error": {
|
||||
"title": "خطأ فادح"
|
||||
"title": "خطأ فادح",
|
||||
"message": "حدث خطأ حرج يمنع تشغيل تطبيق العميل:\n\n{{message}}\n\nيُرجّح أن يكون سبب هذا الخطأ هو تعطل أحد البرامج النصية بشكل غير متوقع. حاول تشغيل التطبيق في الوضع الآمن لحل المشكلة."
|
||||
},
|
||||
"widget-error": {
|
||||
"title": "فشل في البدء بعنصر الواجهة"
|
||||
}
|
||||
"title": "فشل في البدء بعنصر الواجهة",
|
||||
"message-custom": "تعذر تهيئة عنصر واجهة المستخدم المخصص من الملاحظة ذات المعرّف \"{{id}}\" والعنوان \"{{title}}\" بسبب:\n\n{{message}}",
|
||||
"message-unknown": "تعذر تهيئة عنصر واجهة المستخدم غير المعروف بسبب:\n\n{{message}}"
|
||||
},
|
||||
"bundle-error": {
|
||||
"title": "فشل تحميل البرنامج النصي المخصص",
|
||||
"message": "تعذر تنفيذ البرنامج النصي بسبب:\n\n{{message}}"
|
||||
},
|
||||
"widget-list-error": {
|
||||
"title": "فشل في الحصول على قائمة الأدوات من الخادم"
|
||||
},
|
||||
"widget-render-error": {
|
||||
"title": "فشل عرض عنصر واجهة مستخدم React مخصص"
|
||||
},
|
||||
"widget-missing-parent": "لا تحتوي الأداة المخصصة على خاصية إلزامية '{{property}}'.\n\nإذا كان من المفترض تشغيل هذا البرنامج النصي بدون عنصر واجهة مستخدم، فاستخدم '#run=frontendStartup' بدلاً من ذلك."
|
||||
},
|
||||
"add_link": {
|
||||
"add_link": "أضافة رابط",
|
||||
@@ -209,7 +223,6 @@
|
||||
"backlink_other": ""
|
||||
},
|
||||
"note_icon": {
|
||||
"category": "الفئة:",
|
||||
"search": "بحث:",
|
||||
"change_note_icon": "تغيير ايقونة الملاحظة",
|
||||
"reset-default": "اعادة تعيين الى الايقونة الافتراضية"
|
||||
|
||||
@@ -146,7 +146,6 @@
|
||||
"relation": "relació"
|
||||
},
|
||||
"note_icon": {
|
||||
"category": "Categoria:",
|
||||
"search": "Cerca:"
|
||||
},
|
||||
"basic_properties": {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"widget-render-error": {
|
||||
"title": "渲染自定义 React 小部件失败"
|
||||
},
|
||||
"widget-missing-parent": "自定义小部件未定义强制性的 \"{{property}}\" 属性。",
|
||||
"widget-missing-parent": "自定义小部件未定义强制性的 \"{{property}}\" 属性。\n\n如果此脚本需要在没有 UI 元素的情况下运行,请改用“#run=frontendStartup”。",
|
||||
"open-script-note": "打开脚本笔记",
|
||||
"scripting-error": "自定义脚本错误:{{title}}"
|
||||
},
|
||||
@@ -764,7 +764,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "更改笔记图标",
|
||||
"category": "类别:",
|
||||
"search": "搜索:",
|
||||
"reset-default": "重置为默认图标"
|
||||
},
|
||||
@@ -1597,7 +1596,11 @@
|
||||
"note_detail": {
|
||||
"could_not_find_typewidget": "找不到类型为 '{{type}}' 的 typeWidget",
|
||||
"printing": "正在打印…",
|
||||
"printing_pdf": "正在导出为PDF…"
|
||||
"printing_pdf": "正在导出为PDF…",
|
||||
"print_report_title": "打印报告",
|
||||
"print_report_collection_content_other": "集合中的 {{count}} 篇笔记无法打印,因为它们不受支持或受到保护。",
|
||||
"print_report_collection_details_button": "查看详情",
|
||||
"print_report_collection_details_ignored_notes": "忽略的笔记"
|
||||
},
|
||||
"note_title": {
|
||||
"placeholder": "请输入笔记标题...",
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
},
|
||||
"bundle-error": {
|
||||
"title": "Benutzerdefiniertes Skript konnte nicht geladen werden",
|
||||
"message": "Skript aus der Notiz \"{{title}}\" mit der ID \"{{id}}\", konnte nicht ausgeführt werden wegen:\n\n{{message}}"
|
||||
"message": "Skript konnte nicht ausgeführt werden wegen:\n\n{{message}}"
|
||||
},
|
||||
"widget-list-error": {
|
||||
"title": "Abruf der Liste von Widgets vom Server ist fehlgeschlagen"
|
||||
}
|
||||
},
|
||||
"add_link": {
|
||||
@@ -746,7 +749,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Notiz-Icon ändern",
|
||||
"category": "Kategorie:",
|
||||
"search": "Suche:",
|
||||
"reset-default": "Standard wiederherstellen"
|
||||
},
|
||||
|
||||
@@ -765,9 +765,16 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Change note icon",
|
||||
"category": "Category:",
|
||||
"search": "Search:",
|
||||
"reset-default": "Reset to default icon"
|
||||
"search_placeholder_one": "Search {{number}} icons across {{count}} packs",
|
||||
"search_placeholder_other": "Search {{number}} icons across {{count}} packs",
|
||||
"search_placeholder_filtered": "Search {{number}} icons in {{name}}",
|
||||
"reset-default": "Reset to default icon",
|
||||
"filter": "Filter",
|
||||
"filter-none": "All icons",
|
||||
"filter-default": "Default icons",
|
||||
"icon_tooltip": "{{name}}\nIcon pack: {{iconPack}}",
|
||||
"no_results": "No icons found."
|
||||
},
|
||||
"basic_properties": {
|
||||
"note_type": "Note type",
|
||||
@@ -1613,7 +1620,7 @@
|
||||
"will_be_deleted_in": "This attachment will be automatically deleted in {{time}}",
|
||||
"will_be_deleted_soon": "This attachment will be automatically deleted soon",
|
||||
"deletion_reason": ", because the attachment is not linked in the note's content. To prevent deletion, add the attachment link back into the content or convert the attachment into note.",
|
||||
"role_and_size": "Role: {{role}}, Size: {{size}}",
|
||||
"role_and_size": "Role: {{role}}, size: {{size}}, MIME: {{- mimeType}}",
|
||||
"link_copied": "Attachment link copied to clipboard.",
|
||||
"unrecognized_role": "Unrecognized attachment role '{{role}}'."
|
||||
},
|
||||
|
||||
@@ -749,7 +749,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Cambiar icono de nota",
|
||||
"category": "Categoría:",
|
||||
"search": "Búsqueda:",
|
||||
"reset-default": "Restablecer a icono por defecto"
|
||||
},
|
||||
|
||||
@@ -756,7 +756,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Changer l'icône de note",
|
||||
"category": "Catégorie :",
|
||||
"search": "Recherche :",
|
||||
"reset-default": "Réinitialiser l'icône par défaut"
|
||||
},
|
||||
|
||||
@@ -1333,7 +1333,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Cambia icona nota",
|
||||
"category": "Categoria:",
|
||||
"search": "Ricerca:",
|
||||
"reset-default": "Ripristina l'icona predefinita"
|
||||
},
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"widget-render-error": {
|
||||
"title": "カスタム React ウィジェットのレンダリングに失敗しました"
|
||||
},
|
||||
"widget-missing-parent": "カスタムウィジェットに必須の '{{property}}' プロパティが定義されていません。",
|
||||
"widget-missing-parent": "カスタムウィジェットに必須の '{{property}}' プロパティが定義されていません。\n\nこのスクリプトを UI 要素なしで実行する場合は、代わりに '#run=frontendStartup' を使用してください。",
|
||||
"open-script-note": "スクリプトノートを開く",
|
||||
"scripting-error": "カスタムスクリプトエラー: {{title}}"
|
||||
},
|
||||
@@ -152,7 +152,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "ノートアイコンの変更",
|
||||
"category": "カテゴリー:",
|
||||
"search": "検索:",
|
||||
"reset-default": "アイコンをデフォルトに戻す"
|
||||
},
|
||||
@@ -161,7 +160,7 @@
|
||||
"editable": "編集可能",
|
||||
"basic_properties": "基本プロパティ",
|
||||
"language": "言語",
|
||||
"configure_code_notes": "コードノートを設定しています..."
|
||||
"configure_code_notes": "コードノートを設定..."
|
||||
},
|
||||
"i18n": {
|
||||
"title": "ローカライゼーション",
|
||||
@@ -1930,7 +1929,11 @@
|
||||
"note_detail": {
|
||||
"could_not_find_typewidget": "タイプ {{type}} の typeWidget が見つかりませんでした",
|
||||
"printing": "印刷中です...",
|
||||
"printing_pdf": "PDF へのエクスポート中です..."
|
||||
"printing_pdf": "PDF へのエクスポート中です...",
|
||||
"print_report_title": "レポートを印刷",
|
||||
"print_report_collection_content_other": "コレクション内の {{count}} 件のノートは、サポートされていないか保護されているため、印刷できませんでした。",
|
||||
"print_report_collection_details_button": "詳細を見る",
|
||||
"print_report_collection_details_ignored_notes": "無視されたノート"
|
||||
},
|
||||
"watched_file_update_status": {
|
||||
"ignore_this_change": "この変更を無視する",
|
||||
|
||||
@@ -1286,7 +1286,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Zmień ikonę notatki",
|
||||
"category": "Kategoria:",
|
||||
"search": "Szukaj:",
|
||||
"reset-default": "Przywróć domyślną ikonę"
|
||||
},
|
||||
|
||||
@@ -724,7 +724,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Alterar ícone da nota",
|
||||
"category": "Categoria:",
|
||||
"search": "Pesquisa:",
|
||||
"reset-default": "Redefinir para o ícone padrão"
|
||||
},
|
||||
|
||||
@@ -1008,7 +1008,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Alterar ícone da nota",
|
||||
"category": "Categoria:",
|
||||
"search": "Busca:",
|
||||
"reset-default": "Redefinir para o ícone padrão"
|
||||
},
|
||||
|
||||
@@ -1483,7 +1483,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Schimbă iconița notiței",
|
||||
"category": "Categorie:",
|
||||
"reset-default": "Resetează la iconița implicită",
|
||||
"search": "Căutare:"
|
||||
},
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"widget-render-error": {
|
||||
"title": "Не удалось отобразить пользовательский React виджет"
|
||||
},
|
||||
"widget-missing-parent": "В пользовательском виджете не определено обязательное свойство '{{property}}'.",
|
||||
"widget-missing-parent": "В пользовательском виджете не определено обязательное свойство '{{property}}'.\n\nЕсли этот скрипт предназначен для запуска без элемента пользовательского интерфейса, используйте '#run=frontendStartup'.",
|
||||
"open-script-note": "Открыть заметку со скриптом",
|
||||
"scripting-error": "Ошибка пользовательского скрипта: {{title}}"
|
||||
},
|
||||
@@ -1010,7 +1010,6 @@
|
||||
"backlink_many": "{{count}} обратных ссылок"
|
||||
},
|
||||
"note_icon": {
|
||||
"category": "Категория:",
|
||||
"search": "Поиск:",
|
||||
"change_note_icon": "Изменить иконку заметки",
|
||||
"reset-default": "Сбросить к значку по умолчанию"
|
||||
@@ -2112,7 +2111,13 @@
|
||||
"note_detail": {
|
||||
"could_not_find_typewidget": "Не удалось найти typeWidget для типа '{{type}}'",
|
||||
"printing_pdf": "Выполняется экспорт PDF...",
|
||||
"printing": "Выполняется печать..."
|
||||
"printing": "Выполняется печать...",
|
||||
"print_report_title": "Отчет по печати",
|
||||
"print_report_collection_content_one": "{{count}} заметка в коллекции не удалось распечатать, поскольку она не поддерживается или защищена.",
|
||||
"print_report_collection_content_few": "{{count}} заметки в коллекции не удалось распечатать, поскольку они не поддерживаются или защищены.",
|
||||
"print_report_collection_content_many": "{{count}} заметок в коллекции не удалось распечатать, поскольку они не поддерживаются или защищены.",
|
||||
"print_report_collection_details_button": "Подробнее",
|
||||
"print_report_collection_details_ignored_notes": "Пропущенные заметки"
|
||||
},
|
||||
"book": {
|
||||
"no_children_help": "В этой коллекции нет дочерних заметок, поэтому отображать нечего. Подробности см. в <a href=\"https://triliumnext.github.io/Docs/Wiki/book-note.html\">wiki</a>.",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"bundle-error": {
|
||||
"title": "載入自訂腳本失敗",
|
||||
"message": "來自 ID 為 \"{{id}}\"、標題為 \"{{title}}\" 的筆記的腳本因以下原因無法執行:\n\n{{message}}"
|
||||
"message": "腳本因以下原因無法執行:\n\n{{message}}"
|
||||
},
|
||||
"widget-list-error": {
|
||||
"title": "無法從伺服器取得元件清單"
|
||||
@@ -761,7 +761,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "更改筆記圖標",
|
||||
"category": "類別:",
|
||||
"search": "搜尋:",
|
||||
"reset-default": "重置為預設圖標"
|
||||
},
|
||||
|
||||
@@ -849,7 +849,6 @@
|
||||
},
|
||||
"note_icon": {
|
||||
"change_note_icon": "Змінити значок нотатки",
|
||||
"category": "Категорія:",
|
||||
"search": "Пошук:",
|
||||
"reset-default": "Скинути значок до стандартного значення"
|
||||
},
|
||||
|
||||
2
apps/client/src/types-assets.d.ts
vendored
@@ -17,5 +17,3 @@ declare module "*?raw" {
|
||||
var content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
declare module "boxicons/css/boxicons.min.css" { }
|
||||
|
||||
4
apps/client/src/types.d.ts
vendored
@@ -1,3 +1,5 @@
|
||||
import { IconRegistry } from "@triliumnext/commons";
|
||||
|
||||
import appContext, { AppContext } from "./components/app_context";
|
||||
import type FNote from "./entities/fnote";
|
||||
import type { PrintReport } from "./print";
|
||||
@@ -34,6 +36,7 @@ interface CustomGlobals {
|
||||
isProtectedSessionAvailable: boolean;
|
||||
isDev: boolean;
|
||||
isMainWindow: boolean;
|
||||
windowId: string;
|
||||
maxEntityChangeIdAtLoad: number;
|
||||
maxEntityChangeSyncIdAtLoad: number;
|
||||
assetPath: string;
|
||||
@@ -46,6 +49,7 @@ interface CustomGlobals {
|
||||
linter: typeof lint;
|
||||
hasNativeTitleBar: boolean;
|
||||
isRtl: boolean;
|
||||
iconRegistry: IconRegistry;
|
||||
}
|
||||
|
||||
type RequireMethod = (moduleName: string) => any;
|
||||
|
||||
@@ -142,7 +142,7 @@ function ShowTocWidgetButton({ note, noteContext, isDefaultViewMode }: FloatingB
|
||||
|
||||
return isEnabled && <FloatingButton
|
||||
text={t("show_toc_widget_button.show_toc")}
|
||||
icon="bx bx-tn-toc"
|
||||
icon="bx bx-spreadsheet bx-rotate-180"
|
||||
onClick={() => {
|
||||
if (noteContext?.viewScope && noteContext.noteId) {
|
||||
noteContext.viewScope.tocTemporarilyHidden = false;
|
||||
|
||||
@@ -13,6 +13,7 @@ import debounce from "../services/debounce";
|
||||
import { t } from "../services/i18n";
|
||||
import { DefinitionObject, extractAttributeDefinitionTypeAndName, LabelType } from "../services/promoted_attribute_definition_parser";
|
||||
import server from "../services/server";
|
||||
import { randomString } from "../services/utils";
|
||||
import ws from "../services/ws";
|
||||
import { useNoteContext, useNoteLabel, useTriliumEvent, useUniqueName } from "./react/hooks";
|
||||
import NoteAutocomplete from "./react/NoteAutocomplete";
|
||||
@@ -116,7 +117,7 @@ export function usePromotedAttributeData(note: FNote | null | undefined, compone
|
||||
valueAttr.attributeId = "";
|
||||
}
|
||||
|
||||
const uniqueId = crypto.randomUUID();
|
||||
const uniqueId = randomString();
|
||||
cells.push({ definitionAttr, definition, valueAttr, valueName, uniqueId });
|
||||
}
|
||||
}
|
||||
@@ -319,7 +320,7 @@ function MultiplicityCell({ cell, cells, setCells, setCellToFocus, note, compone
|
||||
const index = cells.indexOf(cell);
|
||||
const newCell: Cell = {
|
||||
...cell,
|
||||
uniqueId: crypto.randomUUID(),
|
||||
uniqueId: randomString(),
|
||||
valueAttr: {
|
||||
attributeId: "",
|
||||
type: cell.valueAttr.type,
|
||||
|
||||
@@ -4,6 +4,7 @@ import Component, { TypedComponent } from "../components/component.js";
|
||||
import froca from "../services/froca.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import toastService, { showErrorForScriptNote } from "../services/toast.js";
|
||||
import { randomString } from "../services/utils.js";
|
||||
import { renderReactWidget } from "./react/react_utils.jsx";
|
||||
|
||||
export class TypedBasicWidget<T extends TypedComponent<any>> extends TypedComponent<T> {
|
||||
@@ -180,7 +181,7 @@ export class TypedBasicWidget<T extends TypedComponent<any>> extends TypedCompon
|
||||
});
|
||||
} else {
|
||||
toastService.showPersistent({
|
||||
id: `custom-widget-failure-unknown-${crypto.randomUUID()}`,
|
||||
id: `custom-widget-failure-unknown-${randomString()}`,
|
||||
title: t("toast.widget-error.title"),
|
||||
icon: "bx bx-error-circle",
|
||||
message: t("toast.widget-error.message-unknown", {
|
||||
|
||||
@@ -108,14 +108,6 @@ button.global-menu-button {
|
||||
margin-inline-end: 5px;
|
||||
}
|
||||
|
||||
.global-menu .dropdown-item .bx {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
font-size: 120%;
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
|
||||
.global-menu-button-wrapper:hover .global-menu-button-update-available-button {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ body.prefers-centered-content .note-list-widget:not(.full-height) {
|
||||
}
|
||||
|
||||
.note-list-widget .note-list {
|
||||
padding: 10px;
|
||||
padding-block: 10px;
|
||||
}
|
||||
|
||||
.note-list-widget.full-height,
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.geo-map-container .leaflet-div-icon .bx {
|
||||
.geo-map-container .leaflet-div-icon .tn-icon {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
inset-inline-start: 2px;
|
||||
|
||||
@@ -74,11 +74,11 @@ describe("Presentation model", () => {
|
||||
});
|
||||
|
||||
it("rewrites links to other slides", () => {
|
||||
expect(data.slides[1].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide1"><span><span class="bx bx-folder"></span>First slide</span></a>.</p></div>`);
|
||||
expect(data.slides[1].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide2"><span><span class="bx bx-note"></span>First-sub</span></a>.</p></div>`);
|
||||
expect(data.slides[1].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide1"><span><span class="tn-icon bx bx-folder"></span>First slide</span></a>.</p></div>`);
|
||||
expect(data.slides[1].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-slide2"><span><span class="tn-icon bx bx-note"></span>First-sub</span></a>.</p></div>`);
|
||||
});
|
||||
|
||||
it("rewrites links even if they are not part of the slideshow", () => {
|
||||
expect(data.slides[0].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-other"><span><span class="bx bx-note"></span>Other note</span></a>.</p></div>`);
|
||||
expect(data.slides[0].verticalSlides![0].content.__html).toStrictEqual(`<div class="ck-content"><p>Go to <a class="reference-link" href="#/slide-other"><span><span class="tn-icon bx bx-note"></span>Other note</span></a>.</p></div>`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
overflow: auto;
|
||||
scroll-behavior: smooth;
|
||||
position: relative;
|
||||
|
||||
> .inline-title,
|
||||
> .note-detail > .note-detail-editable-text,
|
||||
> .note-list-widget:not(.full-height) {
|
||||
padding-inline: 24px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.note-split.type-code:not(.mime-text-x-sqlite) {
|
||||
|
||||
@@ -30,7 +30,7 @@ export function CustomNoteLauncher({ launcherNote, getTargetNoteId, getHoistedNo
|
||||
const activate = !!evt.shiftKey;
|
||||
await appContext.tabManager.openInNewTab(targetNoteId, hoistedNoteIdWithDefault, activate);
|
||||
} else {
|
||||
await appContext.tabManager.openInSameTab(targetNoteId);
|
||||
await appContext.tabManager.openInSameTab(targetNoteId, hoistedNoteIdWithDefault);
|
||||
}
|
||||
}, [ launcherNote, getTargetNoteId, getHoistedNoteId ]);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
margin-inline: 6px;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
.icon-action {
|
||||
font-size: .9rem !important;
|
||||
|
||||
.bxs-chevron-right {
|
||||
&.breadcrumb-separator {
|
||||
transform: translateY(8%);
|
||||
|
||||
&::before {
|
||||
|
||||
@@ -191,7 +191,7 @@ function BreadcrumbSeparator(props: BreadcrumbSeparatorProps) {
|
||||
<Dropdown
|
||||
text={<Icon icon="bx bxs-chevron-right" />}
|
||||
noSelectButtonStyle
|
||||
buttonClassName="icon-action"
|
||||
buttonClassName="icon-action breadcrumb-separator"
|
||||
hideToggleArrow
|
||||
dropdownContainerClassName="tn-dropdown-menu-scrollable breadcrumb-child-list"
|
||||
dropdownOptions={{ popperConfig: { strategy: "fixed", placement: "top" } }}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
max-width: var(--max-content-width);
|
||||
container-type: inline-size;
|
||||
padding-top: 20px;
|
||||
padding-inline-start: 24px;
|
||||
|
||||
& > .inline-title-row {
|
||||
--icon-size: 35px;
|
||||
|
||||
@@ -4,12 +4,21 @@ body.experimental-feature-new-layout {
|
||||
}
|
||||
|
||||
.title-actions {
|
||||
--title-actions-padding-start: 12px;
|
||||
--title-actions-padding-end: 8px;
|
||||
|
||||
display: flex;
|
||||
max-width: var(--max-content-width);
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
padding-inline: var(--title-actions-padding-start) var(--title-actions-padding-end);
|
||||
|
||||
body.prefers-centered-content .note-split:not(.full-content-width) & {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
&:not(:empty) {
|
||||
padding: 0.75em 15px;
|
||||
padding-block: 0.75em;
|
||||
}
|
||||
|
||||
.edited-notes {
|
||||
@@ -40,5 +49,11 @@ body.experimental-feature-new-layout {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .collapsible,
|
||||
> .note-type-switcher {
|
||||
padding-inline-start: calc(24px - var(--title-actions-padding-start));
|
||||
padding-inline-end: calc(24px - var(--title-actions-padding-end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
background-color: var(--left-pane-background-color);
|
||||
padding-inline: 0.25em;
|
||||
font-size: 0.85em;
|
||||
|
||||
|
||||
> .breadcrumb {
|
||||
flex-grow: 1;
|
||||
--icon-button-size: 23px;
|
||||
@@ -104,7 +104,7 @@
|
||||
/* Note path card */
|
||||
li {
|
||||
--border-radius: 6px;
|
||||
|
||||
|
||||
position: relative;
|
||||
background: var(--card-background-color);
|
||||
padding: 8px 20px 8px 25px;
|
||||
@@ -120,7 +120,7 @@
|
||||
& + li {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
|
||||
/* Current path arrow */
|
||||
&.path-current::before {
|
||||
position: absolute;
|
||||
@@ -180,7 +180,7 @@
|
||||
&:last-child {
|
||||
border-radius: 0 0 var(--border-radius) var(--border-radius);
|
||||
}
|
||||
|
||||
|
||||
/* Card header */
|
||||
& > span:first-child {
|
||||
display: block;
|
||||
@@ -202,7 +202,7 @@
|
||||
}
|
||||
|
||||
/* Note icon */
|
||||
> .bx {
|
||||
> .tn-icon {
|
||||
color: var(--menu-item-icon-color);
|
||||
}
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ function AttributesButton({ note, attributesShown, setAttributesShown }: Attribu
|
||||
|
||||
// React to note changes.
|
||||
useEffect(() => {
|
||||
setCount(note.attributes.length);
|
||||
setCount(note.getAttributes().filter(a => !a.isAutoLink).length);
|
||||
}, [ note ]);
|
||||
|
||||
// React to changes in count.
|
||||
|
||||
@@ -32,17 +32,14 @@ div.note-icon-widget {
|
||||
}
|
||||
|
||||
.note-icon-widget .filter-row {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-inline-end: 20px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.note-icon-widget .filter-row span {
|
||||
display: block;
|
||||
padding-inline-start: 15px;
|
||||
padding-inline-end: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -75,6 +72,14 @@ div.note-icon-widget {
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.note-icon-widget {
|
||||
.no-results {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: var(--muted-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
body.experimental-feature-new-layout {
|
||||
.note-icon-widget button.note-icon {
|
||||
--input-focus-outline-color: var(--note-icon-hover-background-color);
|
||||
@@ -111,4 +116,4 @@ body.experimental-feature-new-layout {
|
||||
transition: background 200ms ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,36 @@
|
||||
import Dropdown from "./react/Dropdown";
|
||||
import "./note_icon.css";
|
||||
|
||||
import { IconRegistry } from "@triliumnext/commons";
|
||||
import { Dropdown as BootstrapDropdown } from "bootstrap";
|
||||
import clsx from "clsx";
|
||||
import { t } from "i18next";
|
||||
import { useNoteContext, useNoteLabel } from "./react/hooks";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import server from "../services/server";
|
||||
import type { Category, Icon } from "./icon_list";
|
||||
import FormTextBox from "./react/FormTextBox";
|
||||
import FormSelect from "./react/FormSelect";
|
||||
import { CSSProperties, RefObject } from "preact";
|
||||
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||
import { CellComponentProps, Grid } from "react-window";
|
||||
|
||||
import FNote from "../entities/fnote";
|
||||
import attributes from "../services/attributes";
|
||||
import Button from "./react/Button";
|
||||
import server from "../services/server";
|
||||
import ActionButton from "./react/ActionButton";
|
||||
import Dropdown from "./react/Dropdown";
|
||||
import { FormDropdownDivider, FormListItem } from "./react/FormList";
|
||||
import FormTextBox from "./react/FormTextBox";
|
||||
import { useNoteContext, useNoteLabel, useStaticTooltip } from "./react/hooks";
|
||||
|
||||
interface IconToCountCache {
|
||||
iconClassToCountMap: Record<string, number>;
|
||||
}
|
||||
|
||||
interface IconData {
|
||||
iconToCount: Record<string, number>;
|
||||
categories: Category[];
|
||||
icons: Icon[];
|
||||
}
|
||||
|
||||
let fullIconData: {
|
||||
categories: Category[];
|
||||
icons: Icon[];
|
||||
};
|
||||
let iconToCountCache!: Promise<IconToCountCache> | null;
|
||||
|
||||
type IconWithName = (IconRegistry["sources"][number]["icons"][number] & { iconPack: string });
|
||||
|
||||
export default function NoteIcon() {
|
||||
const { note, viewScope } = useNoteContext();
|
||||
const [ icon, setIcon ] = useState<string | null | undefined>();
|
||||
const [ iconClass ] = useNoteLabel(note, "iconClass");
|
||||
const [ workspaceIconClass ] = useNoteLabel(note, "workspaceIconClass");
|
||||
const dropdownRef = useRef<BootstrapDropdown>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setIcon(note?.getIcon());
|
||||
@@ -41,130 +40,219 @@ export default function NoteIcon() {
|
||||
<Dropdown
|
||||
className="note-icon-widget"
|
||||
title={t("note_icon.change_note_icon")}
|
||||
dropdownContainerStyle={{ width: "610px" }}
|
||||
dropdownRef={dropdownRef}
|
||||
dropdownContainerStyle={{ width: "620px" }}
|
||||
dropdownOptions={{ autoClose: "outside" }}
|
||||
buttonClassName={`note-icon tn-focusable-button ${icon ?? "bx bx-empty"}`}
|
||||
hideToggleArrow
|
||||
disabled={viewScope?.viewMode !== "default"}
|
||||
>
|
||||
{ note && <NoteIconList note={note} /> }
|
||||
{ note && <NoteIconList note={note} dropdownRef={dropdownRef} /> }
|
||||
</Dropdown>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function NoteIconList({ note }: { note: FNote }) {
|
||||
function NoteIconList({ note, dropdownRef }: {
|
||||
note: FNote,
|
||||
dropdownRef: RefObject<BootstrapDropdown>;
|
||||
}) {
|
||||
const searchBoxRef = useRef<HTMLInputElement>(null);
|
||||
const iconListRef = useRef<HTMLDivElement>(null);
|
||||
const [ search, setSearch ] = useState<string>();
|
||||
const [ categoryId, setCategoryId ] = useState<string>("0");
|
||||
const [ iconData, setIconData ] = useState<IconData>();
|
||||
const [ filterByPrefix, setFilterByPrefix ] = useState<string | null>(null);
|
||||
useStaticTooltip(iconListRef, {
|
||||
selector: "span",
|
||||
customClass: "pre-wrap-text",
|
||||
animation: false,
|
||||
title() { return this.getAttribute("title") || ""; },
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
async function loadIcons() {
|
||||
if (!fullIconData) {
|
||||
fullIconData = (await import("./icon_list.js")).default;
|
||||
}
|
||||
|
||||
// Filter by text and/or category.
|
||||
let icons: Icon[] = fullIconData.icons;
|
||||
const processedSearch = search?.trim()?.toLowerCase();
|
||||
if (processedSearch || categoryId) {
|
||||
icons = icons.filter((icon) => {
|
||||
if (categoryId !== "0" && String(icon.category_id) !== categoryId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (processedSearch) {
|
||||
if (!icon.name.includes(processedSearch) &&
|
||||
!icon.term?.find((t) => t.includes(processedSearch))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Sort by count.
|
||||
const iconToCount = await getIconToCountMap();
|
||||
if (iconToCount) {
|
||||
icons.sort((a, b) => {
|
||||
const countA = iconToCount[a.className ?? ""] || 0;
|
||||
const countB = iconToCount[b.className ?? ""] || 0;
|
||||
|
||||
return countB - countA;
|
||||
});
|
||||
}
|
||||
|
||||
setIconData({
|
||||
iconToCount,
|
||||
icons,
|
||||
categories: fullIconData.categories
|
||||
})
|
||||
}
|
||||
|
||||
loadIcons();
|
||||
}, [ search, categoryId ]);
|
||||
const allIcons = useAllIcons();
|
||||
const filteredIcons = useFilteredIcons(allIcons, search, filterByPrefix);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="filter-row">
|
||||
<span>{t("note_icon.category")}</span>
|
||||
<FormSelect
|
||||
name="icon-category"
|
||||
values={fullIconData?.categories ?? []}
|
||||
currentValue={categoryId} onChange={setCategoryId}
|
||||
keyProperty="id" titleProperty="name"
|
||||
/>
|
||||
|
||||
<span>{t("note_icon.search")}</span>
|
||||
<FormTextBox
|
||||
inputRef={searchBoxRef}
|
||||
type="text"
|
||||
name="icon-search"
|
||||
placeholder={ filterByPrefix
|
||||
? t("note_icon.search_placeholder_filtered", {
|
||||
number: filteredIcons.length ?? 0,
|
||||
name: glob.iconRegistry.sources.find(s => s.prefix === filterByPrefix)?.name ?? ""
|
||||
})
|
||||
: t("note_icon.search_placeholder", { number: filteredIcons.length ?? 0, count: glob.iconRegistry.sources.length })}
|
||||
currentValue={search} onChange={setSearch}
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="icon-list"
|
||||
onClick={(e) => {
|
||||
const clickedTarget = e.target as HTMLElement;
|
||||
|
||||
if (!clickedTarget.classList.contains("bx")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const iconClass = Array.from(clickedTarget.classList.values()).join(" ");
|
||||
if (note) {
|
||||
const attributeToSet = note.hasOwnedLabel("workspace") ? "workspaceIconClass" : "iconClass";
|
||||
attributes.setLabel(note.noteId, attributeToSet, iconClass);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{getIconLabels(note).length > 0 && (
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<Button
|
||||
<ActionButton
|
||||
icon="bx bx-reset"
|
||||
text={t("note_icon.reset-default")}
|
||||
onClick={() => {
|
||||
if (!note) {
|
||||
return;
|
||||
}
|
||||
if (!note) return;
|
||||
for (const label of getIconLabels(note)) {
|
||||
attributes.removeAttributeById(note.noteId, label.attributeId);
|
||||
}
|
||||
dropdownRef?.current?.hide();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(iconData?.icons ?? []).map(({className, name}) => (
|
||||
<span class={`bx ${className}`} title={name} />
|
||||
))}
|
||||
{glob.iconRegistry.sources.length > 0 && <Dropdown
|
||||
buttonClassName="bx bx-filter-alt"
|
||||
hideToggleArrow
|
||||
noSelectButtonStyle
|
||||
noDropdownListStyle
|
||||
iconAction
|
||||
title={t("note_icon.filter")}
|
||||
>
|
||||
<IconFilterContent filterByPrefix={filterByPrefix} setFilterByPrefix={setFilterByPrefix} />
|
||||
</Dropdown>}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="icon-list"
|
||||
ref={iconListRef}
|
||||
onClick={(e) => {
|
||||
// Make sure we are not clicking on something else than a button.
|
||||
const clickedTarget = e.target as HTMLElement;
|
||||
if (!clickedTarget.classList.contains("tn-icon")) return;
|
||||
|
||||
const iconClass = Array.from(clickedTarget.classList.values()).filter(c => c !== "tn-icon").join(" ");
|
||||
if (note) {
|
||||
const attributeToSet = note.hasOwnedLabel("workspace") ? "workspaceIconClass" : "iconClass";
|
||||
attributes.setLabel(note.noteId, attributeToSet, iconClass);
|
||||
}
|
||||
dropdownRef?.current?.hide();
|
||||
}}
|
||||
>
|
||||
{filteredIcons.length ? (
|
||||
<Grid
|
||||
columnCount={12}
|
||||
columnWidth={48}
|
||||
rowCount={Math.ceil(filteredIcons.length / 12)}
|
||||
rowHeight={48}
|
||||
cellComponent={IconItemCell}
|
||||
cellProps={{
|
||||
filteredIcons
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div class="no-results">{t("note_icon.no_results")}</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function IconItemCell({ rowIndex, columnIndex, style, filteredIcons }: CellComponentProps<{
|
||||
filteredIcons: IconWithName[];
|
||||
}>): React.JSX.Element {
|
||||
const iconIndex = rowIndex * 12 + columnIndex;
|
||||
const iconData = filteredIcons[iconIndex] as IconWithName | undefined;
|
||||
if (!iconData) return <></>;
|
||||
|
||||
const { id, terms, iconPack } = iconData;
|
||||
return (
|
||||
<span
|
||||
key={id}
|
||||
class={clsx(id, "tn-icon")}
|
||||
title={t("note_icon.icon_tooltip", { name: terms?.[0] ?? id, iconPack })}
|
||||
style={style as CSSProperties}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function IconFilterContent({ filterByPrefix, setFilterByPrefix }: {
|
||||
filterByPrefix: string | null;
|
||||
setFilterByPrefix: (value: string | null) => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<FormListItem
|
||||
checked={filterByPrefix === null}
|
||||
onClick={() => setFilterByPrefix(null)}
|
||||
>{t("note_icon.filter-none")}</FormListItem>
|
||||
<FormListItem
|
||||
checked={filterByPrefix === "bx"}
|
||||
onClick={() => setFilterByPrefix("bx")}
|
||||
>{t("note_icon.filter-default")}</FormListItem>
|
||||
<FormDropdownDivider />
|
||||
|
||||
{glob.iconRegistry.sources.map(({ prefix, name, icon }) => (
|
||||
prefix !== "bx" && <FormListItem
|
||||
key={prefix}
|
||||
onClick={() => setFilterByPrefix(prefix)}
|
||||
icon={icon}
|
||||
checked={filterByPrefix === prefix}
|
||||
>{name}</FormListItem>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function useAllIcons() {
|
||||
const [ allIcons, setAllIcons ] = useState<IconWithName[]>();
|
||||
|
||||
useEffect(() => {
|
||||
getIconToCountMap().then((iconsToCount) => {
|
||||
const allIcons = [
|
||||
...glob.iconRegistry.sources.flatMap(s => s.icons.map((i) => ({
|
||||
...i,
|
||||
iconPack: s.name,
|
||||
})))
|
||||
];
|
||||
|
||||
// Sort by count.
|
||||
if (iconsToCount) {
|
||||
allIcons.sort((a, b) => {
|
||||
const countA = iconsToCount[a.id ?? ""] || 0;
|
||||
const countB = iconsToCount[b.id ?? ""] || 0;
|
||||
|
||||
return countB - countA;
|
||||
});
|
||||
}
|
||||
|
||||
setAllIcons(allIcons);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return allIcons;
|
||||
}
|
||||
|
||||
function useFilteredIcons(allIcons: IconWithName[] | undefined, search: string | undefined, filterByPrefix: string | null) {
|
||||
// Filter by text and/or icon pack.
|
||||
const filteredIcons = useMemo(() => {
|
||||
let icons: IconWithName[] = allIcons ?? [];
|
||||
const processedSearch = search?.trim()?.toLowerCase();
|
||||
if (processedSearch || filterByPrefix !== null) {
|
||||
icons = icons.filter((icon) => {
|
||||
if (filterByPrefix) {
|
||||
if (!icon.id?.startsWith(`${filterByPrefix} `)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (processedSearch) {
|
||||
if (!icon.terms?.some((t) => t.includes(processedSearch))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return icons;
|
||||
}, [ allIcons, search, filterByPrefix ]);
|
||||
return filteredIcons;
|
||||
}
|
||||
|
||||
async function getIconToCountMap() {
|
||||
if (!iconToCountCache) {
|
||||
iconToCountCache = server.get<IconToCountCache>("other/icon-usage");
|
||||
@@ -180,5 +268,5 @@ function getIconLabels(note: FNote) {
|
||||
}
|
||||
return note.getOwnedLabels()
|
||||
.filter((label) => ["workspaceIconClass", "iconClass"]
|
||||
.includes(label.name));
|
||||
.includes(label.name));
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ div.note-title-widget {
|
||||
|
||||
&::selection {
|
||||
color: var(--main-text-color);
|
||||
background: var(--selection-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +92,7 @@ body.experimental-feature-new-layout {
|
||||
height: var(--size);
|
||||
padding: 0;
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
opacity: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -1,38 +1,39 @@
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import utils from "../services/utils.js";
|
||||
import contextMenu from "../menus/context_menu.js";
|
||||
import froca from "../services/froca.js";
|
||||
import branchService from "../services/branches.js";
|
||||
import ws from "../services/ws.js";
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import server from "../services/server.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import appContext, { type CommandListenerData, type EventData } from "../components/app_context.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import clipboard from "../services/clipboard.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import linkService from "../services/link.js";
|
||||
import options from "../services/options.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import type FBranch from "../entities/fbranch.js";
|
||||
import type LoadResults from "../services/load_results.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type { NoteType } from "../entities/fnote.js";
|
||||
import type { AttributeRow, BranchRow } from "../services/load_results.js";
|
||||
import type { SetNoteOpts } from "../components/note_context.js";
|
||||
import type { TouchBarItem } from "../components/touch_bar.js";
|
||||
import type { TreeCommandNames } from "../menus/tree_context_menu.js";
|
||||
import "jquery.fancytree";
|
||||
import "jquery.fancytree/dist/modules/jquery.fancytree.dnd5.js";
|
||||
import "jquery.fancytree/dist/modules/jquery.fancytree.clones.js";
|
||||
import "jquery.fancytree/dist/modules/jquery.fancytree.filter.js";
|
||||
import "../stylesheets/tree.css";
|
||||
|
||||
import appContext, { type CommandListenerData, type EventData } from "../components/app_context.js";
|
||||
import type { SetNoteOpts } from "../components/note_context.js";
|
||||
import type { TouchBarItem } from "../components/touch_bar.js";
|
||||
import type FBranch from "../entities/fbranch.js";
|
||||
import type FNote from "../entities/fnote.js";
|
||||
import type { NoteType } from "../entities/fnote.js";
|
||||
import contextMenu from "../menus/context_menu.js";
|
||||
import type { TreeCommandNames } from "../menus/tree_context_menu.js";
|
||||
import branchService from "../services/branches.js";
|
||||
import clipboard from "../services/clipboard.js";
|
||||
import dialogService from "../services/dialog.js";
|
||||
import froca from "../services/froca.js";
|
||||
import hoistedNoteService from "../services/hoisted_note.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import linkService from "../services/link.js";
|
||||
import type LoadResults from "../services/load_results.js";
|
||||
import type { AttributeRow, BranchRow } from "../services/load_results.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import options from "../services/options.js";
|
||||
import protectedSessionService from "../services/protected_session.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import server from "../services/server.js";
|
||||
import shortcutService from "../services/shortcuts.js";
|
||||
import toastService from "../services/toast.js";
|
||||
import treeService from "../services/tree.js";
|
||||
import utils from "../services/utils.js";
|
||||
import ws from "../services/ws.js";
|
||||
import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="tree-wrapper">
|
||||
<style>
|
||||
@@ -242,7 +243,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
e.preventDefault();
|
||||
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath, {
|
||||
activate: e.shiftKey ? true : false
|
||||
activate: !!e.shiftKey
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -402,7 +403,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
} else if (ctrlKey) {
|
||||
const notePath = treeService.getNotePath(node);
|
||||
appContext.tabManager.openTabWithNoteWithHoisting(notePath, {
|
||||
activate: event.shiftKey ? true : false
|
||||
activate: !!event.shiftKey
|
||||
});
|
||||
} else if (event.altKey) {
|
||||
node.setSelected(!node.isSelected());
|
||||
@@ -499,9 +500,9 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
return ["before", "after"];
|
||||
} else if (["_lbAvailableLaunchers", "_lbVisibleLaunchers"].includes(node.data.noteId)) {
|
||||
return ["over"];
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
},
|
||||
dragDrop: async (node, data) => {
|
||||
if (
|
||||
@@ -597,7 +598,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
clones: {
|
||||
highlightActiveClones: true
|
||||
},
|
||||
enhanceTitle: async function (
|
||||
async enhanceTitle (
|
||||
event: Event,
|
||||
data: {
|
||||
node: Fancytree.FancytreeNode;
|
||||
@@ -627,7 +628,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
const isHoistedNote = activeNoteContext && activeNoteContext.hoistedNoteId === note.noteId && note.noteId !== "root";
|
||||
|
||||
if (note.hasLabel("workspace") && !isHoistedNote) {
|
||||
const $enterWorkspaceButton = $(`<span class="tree-item-button enter-workspace-button bx bx-door-open" title="${t("note_tree.hoist-this-note-workspace")}"></span>`).on(
|
||||
const $enterWorkspaceButton = $(`<span class="tree-item-button tn-icon enter-workspace-button bx bx-door-open" title="${t("note_tree.hoist-this-note-workspace")}"></span>`).on(
|
||||
"click",
|
||||
cancelClickPropagation
|
||||
);
|
||||
@@ -636,7 +637,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
if (note.type === "search") {
|
||||
const $refreshSearchButton = $(`<span class="tree-item-button refresh-search-button bx bx-refresh" title="${t("note_tree.refresh-saved-search-results")}"></span>`).on(
|
||||
const $refreshSearchButton = $(`<span class="tree-item-button tn-icon refresh-search-button bx bx-refresh" title="${t("note_tree.refresh-saved-search-results")}"></span>`).on(
|
||||
"click",
|
||||
cancelClickPropagation
|
||||
);
|
||||
@@ -650,7 +651,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
&& !note.isLaunchBarConfig()
|
||||
&& !note.noteId.startsWith("_help")
|
||||
) {
|
||||
const $createChildNoteButton = $(`<span class="tree-item-button add-note-button bx bx-plus" title="${t("note_tree.create-child-note")}"></span>`).on(
|
||||
const $createChildNoteButton = $(`<span class="tree-item-button tn-icon add-note-button bx bx-plus" title="${t("note_tree.create-child-note")}"></span>`).on(
|
||||
"click",
|
||||
cancelClickPropagation
|
||||
);
|
||||
@@ -659,7 +660,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
if (isHoistedNote) {
|
||||
const $unhoistButton = $(`<span class="tree-item-button unhoist-button bx bx-door-open" title="${t("note_tree.unhoist")}"></span>`).on("click", cancelClickPropagation);
|
||||
const $unhoistButton = $(`<span class="tree-item-button tn-icon unhoist-button bx bx-door-open" title="${t("note_tree.unhoist")}"></span>`).on("click", cancelClickPropagation);
|
||||
|
||||
$span.append($unhoistButton);
|
||||
}
|
||||
@@ -1281,7 +1282,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
|
||||
// activeNode is supposed to be moved when we find out activeNode is deleted but not all branches are deleted. save it for fixing activeNodePath after all nodes loaded.
|
||||
let movedActiveNode: Fancytree.FancytreeNode | null = null;
|
||||
let parentsOfAddedNodes: Fancytree.FancytreeNode[] = [];
|
||||
const parentsOfAddedNodes: Fancytree.FancytreeNode[] = [];
|
||||
|
||||
for (const branchRow of branchRows) {
|
||||
if (branchRow.noteId) {
|
||||
@@ -1452,10 +1453,10 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
if (branchId && branchId.startsWith("virt")) {
|
||||
// in case of virtual branches there's nothing to update
|
||||
return;
|
||||
} else {
|
||||
logError(`Cannot find branch=${branchId}`);
|
||||
return;
|
||||
}
|
||||
logError(`Cannot find branch=${branchId}`);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
branch.isExpanded = isExpanded;
|
||||
@@ -1594,7 +1595,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
// Trigger the event with the selected branch IDs
|
||||
appContext.triggerEvent("editBranchPrefix", {
|
||||
selectedOrActiveBranchIds: branchIds,
|
||||
node: node
|
||||
node
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1779,12 +1780,12 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
#moveLaunchers(selectedOrActiveBranchIds: string[], desktopParent: string, mobileParent: string) {
|
||||
const desktopLaunchersToMove = selectedOrActiveBranchIds.filter((branchId) => !branchId.startsWith("_lbMobile"));
|
||||
if (desktopLaunchersToMove) {
|
||||
branchService.moveToParentNote(desktopLaunchersToMove, "_lbRoot_" + desktopParent);
|
||||
branchService.moveToParentNote(desktopLaunchersToMove, `_lbRoot_${ desktopParent}`);
|
||||
}
|
||||
|
||||
const mobileLaunchersToMove = selectedOrActiveBranchIds.filter((branchId) => branchId.startsWith("_lbMobile"));
|
||||
if (mobileLaunchersToMove) {
|
||||
branchService.moveToParentNote(mobileLaunchersToMove, "_lbMobileRoot_" + mobileParent);
|
||||
branchService.moveToParentNote(mobileLaunchersToMove, `_lbMobileRoot_${ mobileParent}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1829,7 +1830,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget {
|
||||
selectedOrActiveBranchIds: this.getSelectedOrActiveBranchIds(node),
|
||||
selectedOrActiveNoteIds: this.getSelectedOrActiveNoteIds(node)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const items: TouchBarItem[] = [
|
||||
new TouchBar.TouchBarButton({
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
font-size: 1.2em;
|
||||
margin-inline-end: 4px;
|
||||
opacity: .6;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
span.bx {
|
||||
span.tn-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ interface IconProps extends Pick<HTMLAttributes<HTMLSpanElement>, "className" |
|
||||
export default function Icon({ icon, className, ...restProps }: IconProps) {
|
||||
return (
|
||||
<span
|
||||
class={clsx(icon ?? "bx bx-empty", className)}
|
||||
class={clsx(icon ?? "bx bx-empty", className, "tn-icon")}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1177,7 +1177,7 @@ export function useContentElement(noteContext: NoteContext | null | undefined) {
|
||||
const requestId = ++requestIdRef.current;
|
||||
noteContext?.getContentElement().then(contentElement => {
|
||||
// Prevent stale async.
|
||||
if (requestId !== requestIdRef.current) return;
|
||||
if (!contentElement || requestId !== requestIdRef.current) return;
|
||||
setContentElement(contentElement?.[0] ?? null);
|
||||
forceUpdate(v => v + 1);
|
||||
});
|
||||
|
||||
@@ -135,7 +135,7 @@ function RibbonTab({ icon, title, active, onClick, toggleCommand }: { icon: stri
|
||||
>
|
||||
<span
|
||||
ref={iconRef}
|
||||
className={`ribbon-tab-title-icon ${icon}`}
|
||||
className={`ribbon-tab-title-icon tn-icon ${icon}`}
|
||||
/>
|
||||
|
||||
{ active && <span class="ribbon-tab-title-label">{title}</span> }
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.ribbon-tab-title .bx {
|
||||
.ribbon-tab-title .tn-icon {
|
||||
font-size: 150%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createPortal } from "preact/compat";
|
||||
import { useCallback, useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { t } from "../../services/i18n";
|
||||
import { randomString } from "../../services/utils";
|
||||
import { useActiveNoteContext, useContentElement, useIsNoteReadOnly, useNoteProperty, useTextEditor, useTriliumOptionJson } from "../react/hooks";
|
||||
import Modal from "../react/Modal";
|
||||
import { HighlightsListOptions } from "../type_widgets/options/text_notes";
|
||||
@@ -201,7 +202,7 @@ function extractHighlightsFromTextEditor(editor: CKTextEditor) {
|
||||
|
||||
if (Object.values(attrs).some(Boolean)) {
|
||||
result.push({
|
||||
id: crypto.randomUUID(),
|
||||
id: randomString(),
|
||||
text: item.data,
|
||||
attrs,
|
||||
textNode: item.textNode,
|
||||
@@ -269,7 +270,7 @@ function extractHighlightsFromStaticHtml(el: HTMLElement | null) {
|
||||
|
||||
if (Object.values(attrs).some(Boolean)) {
|
||||
highlights.push({
|
||||
id: crypto.randomUUID(),
|
||||
id: randomString(),
|
||||
text: node.textContent,
|
||||
element: el,
|
||||
attrs
|
||||
|
||||
@@ -28,7 +28,7 @@ body.experimental-feature-new-layout #right-pane {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&.collapsed .card-header > .bx {
|
||||
&.collapsed .card-header > .tn-icon {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ body.experimental-feature-new-layout #right-pane {
|
||||
padding: 0.75em;
|
||||
color: var(--muted-text-color);
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { t } from "../../services/i18n";
|
||||
import options from "../../services/options";
|
||||
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer";
|
||||
import Button from "../react/Button";
|
||||
import { useActiveNoteContext, useLegacyWidget, useNoteProperty, useTriliumOptionBool, useTriliumOptionJson } from "../react/hooks";
|
||||
import { useActiveNoteContext, useLegacyWidget, useNoteProperty, useTriliumEvent, useTriliumOptionBool, useTriliumOptionJson } from "../react/hooks";
|
||||
import Icon from "../react/Icon";
|
||||
import LegacyRightPanelWidget from "../right_panel_widget";
|
||||
import HighlightsList from "./HighlightsList";
|
||||
@@ -30,6 +30,9 @@ export default function RightPanelContainer({ widgetsByParent }: { widgetsByPare
|
||||
const [ rightPaneVisible, setRightPaneVisible ] = useTriliumOptionBool("rightPaneVisible");
|
||||
const items = useItems(rightPaneVisible, widgetsByParent);
|
||||
useSplit(rightPaneVisible);
|
||||
useTriliumEvent("toggleRightPane", () => {
|
||||
setRightPaneVisible(!rightPaneVisible);
|
||||
});
|
||||
|
||||
return (
|
||||
<div id="right-pane">
|
||||
|
||||
@@ -5,6 +5,7 @@ import clsx from "clsx";
|
||||
import { useCallback, useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { t } from "../../services/i18n";
|
||||
import { randomString } from "../../services/utils";
|
||||
import { useActiveNoteContext, useContentElement, useIsNoteReadOnly, useNoteProperty, useTextEditor } from "../react/hooks";
|
||||
import Icon from "../react/Icon";
|
||||
import RightPanelWidget from "./RightPanelWidget";
|
||||
@@ -172,7 +173,7 @@ function extractTocFromTextEditor(editor: CKTextEditor) {
|
||||
// Assign a unique ID
|
||||
let tocId = item.getAttribute(TOC_ID) as string | undefined;
|
||||
if (!tocId) {
|
||||
tocId = crypto.randomUUID();
|
||||
tocId = randomString();
|
||||
writer.setAttribute(TOC_ID, tocId, item);
|
||||
}
|
||||
|
||||
@@ -210,7 +211,7 @@ function extractTocFromStaticHtml(el: HTMLElement | null) {
|
||||
const headings: DomHeading[] = [];
|
||||
for (const headingEl of el.querySelectorAll<HTMLHeadingElement>("h1,h2,h3,h4,h5,h6")) {
|
||||
headings.push({
|
||||
id: crypto.randomUUID(),
|
||||
id: randomString(),
|
||||
level: parseInt(headingEl.tagName.substring(1), 10),
|
||||
text: headingEl.textContent,
|
||||
element: headingEl
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.attachment-actions .dropdown-item .bx {
|
||||
.attachment-actions .dropdown-item .tn-icon {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
font-size: 120%;
|
||||
|
||||
@@ -195,7 +195,11 @@ function AttachmentInfo({ attachment, isFullDetail }: { attachment: FAttachment,
|
||||
) : (attachment.title)}
|
||||
</h4>
|
||||
<div className="attachment-details">
|
||||
{t("attachment_detail_2.role_and_size", { role: attachment.role, size: utils.formatSize(attachment.contentLength) })}
|
||||
{t("attachment_detail_2.role_and_size", {
|
||||
role: attachment.role,
|
||||
size: utils.formatSize(attachment.contentLength),
|
||||
mimeType: attachment.mime
|
||||
})}
|
||||
</div>
|
||||
<div style="flex: 1 1;" />
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
margin: 4px 0;
|
||||
font-size: 12px;
|
||||
opacity: 0.5;
|
||||
@@ -78,7 +78,7 @@
|
||||
.ribbon {
|
||||
padding: 0 5px;
|
||||
|
||||
.bx {
|
||||
.tn-icon {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.note-detail-editable-text {
|
||||
font-family: var(--detail-font-family);
|
||||
padding-inline-start: 14px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -49,4 +48,8 @@ body.heading-style-underline .note-detail-editable-text h6 { border-bottom: 1px
|
||||
box-shadow: none !important;
|
||||
min-height: 50px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.note-detail-editable-text .ck.ck-editor__editable_inline {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -35,5 +35,5 @@ describe("CK config", () => {
|
||||
expect(config.translations, locale.id).toHaveLength(2);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 10_000);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@triliumnext/desktop",
|
||||
"version": "0.101.0",
|
||||
"version": "0.101.1",
|
||||
"description": "Build your personal knowledge base with Trilium Notes",
|
||||
"private": true,
|
||||
"main": "src/main.ts",
|
||||
|
||||
|
After Width: | Height: | Size: 545 B |
|
After Width: | Height: | Size: 727 B |
|
After Width: | Height: | Size: 828 B |
|
After Width: | Height: | Size: 931 B |
BIN
apps/desktop/src/assets/images/tray/closed-windowsTemplate.png
Normal file
|
After Width: | Height: | Size: 292 B |
|
After Width: | Height: | Size: 355 B |
|
After Width: | Height: | Size: 434 B |
|
After Width: | Height: | Size: 492 B |
@@ -6,6 +6,8 @@ import sqlInit from "@triliumnext/server/src/services/sql_init.js";
|
||||
import windowService from "@triliumnext/server/src/services/window.js";
|
||||
import tray from "@triliumnext/server/src/services/tray.js";
|
||||
import options from "@triliumnext/server/src/services/options.js";
|
||||
import { randomString } from "@triliumnext/server/src/services/utils.js";
|
||||
|
||||
import electronDebug from "electron-debug";
|
||||
import electronDl from "electron-dl";
|
||||
import { PRODUCT_NAME } from "./app-info";
|
||||
@@ -72,7 +74,8 @@ async function main() {
|
||||
app.on("second-instance", (event, commandLine) => {
|
||||
const lastFocusedWindow = windowService.getLastFocusedWindow();
|
||||
if (commandLine.includes("--new-window")) {
|
||||
windowService.createExtraWindow("");
|
||||
const extraWindowId = randomString(4);
|
||||
windowService.createExtraWindow(extraWindowId, "");
|
||||
} else if (lastFocusedWindow) {
|
||||
if (lastFocusedWindow.isMinimized()) {
|
||||
lastFocusedWindow.restore();
|
||||
|
||||
1
apps/icon-pack-builder/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.zip
|
||||
112
apps/icon-pack-builder/boxicons-free/LICENSE.txt
Normal file
@@ -0,0 +1,112 @@
|
||||
Boxicons Free License
|
||||
|
||||
Free Icons offered by Boxicons is open source. You can use them for your personal and commercial projects.
|
||||
Icons
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Icons are free under — CC 4.0 License
|
||||
|
||||
You are free to:
|
||||
|
||||
- Share — copy and redistribute the material in any medium or format for any purpose, even commercially.
|
||||
- Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
- The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
- Attribution — You must give appropriate credit , provide a link to the license, and indicate if changes were made . You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
||||
- No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation .
|
||||
|
||||
No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# Fonts
|
||||
|
||||
Fonts are free under - SIL OFL 1.1 License:
|
||||
|
||||
PREAMBLE
|
||||
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
DEFINITIONS
|
||||
|
||||
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
“Modified Version” refers to any derivative made by adding to, deleting, or substituting – in part or in whole – any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
PERMISSION & CONDITIONS
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1 - Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2 - Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3 - No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4 - The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5 - The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Code is free under - MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Attribution
|
||||
|
||||
Attribution is required according to MIT,SIL OFL 1.1 and CC 4.0 License.
|
||||
They are already included in the Free icons , you are not required to take any actions
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
# Brand Icons License
|
||||
|
||||
The brand icons offered in Boxicons are trademarks of their respective brands. Their usage here is solely intended to represent the respective brands and does not imply any affiliation or endorsement.
|
||||
|
||||
|
||||
Copyright 2025 Boxicons.
|
||||
|
||||
515
apps/icon-pack-builder/boxicons-free/fonts/animations.css
Normal file
@@ -0,0 +1,515 @@
|
||||
@-webkit-keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: rotate3d(0, 0, 1, -10deg);
|
||||
transform: rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes beat {
|
||||
to {
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes bounce
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale(1.1,1);
|
||||
transform: scale(1.1,1);
|
||||
}
|
||||
|
||||
25%
|
||||
{
|
||||
-webkit-transform: scale(0.9,1) translateY(-.25em);
|
||||
transform: scale(0.9,1) translateY(-.25em);
|
||||
}
|
||||
|
||||
50%
|
||||
{
|
||||
-webkit-transform: scale(1.1,0.9);
|
||||
transform: scale(1.1,0.9);
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
87.5%
|
||||
{
|
||||
-webkit-transform: scale(1, 1) translateY(-.1em);
|
||||
transform: scale(1, 1) translateY(-.1em);
|
||||
}
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes breathe {
|
||||
from{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50%{
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
opacity: 0.4;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes wiggle {
|
||||
from{
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
30%{
|
||||
-webkit-transform: translateX(0.075em);
|
||||
transform: translateX(0.075em);
|
||||
}
|
||||
60%{
|
||||
-webkit-transform: translateX(-0.075em);
|
||||
transform: translateX(-0.075em);
|
||||
}
|
||||
75%{
|
||||
-webkit-transform: translateX(0.025em);
|
||||
transform: translateX(0.025em);
|
||||
}
|
||||
90%{
|
||||
-webkit-transform: translateX(-0.025em);
|
||||
transform: translateX(-0.025em);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bx-wiggle{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-wiggle-hover:hover{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-breathe{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
|
||||
}
|
||||
.bx-breathe-hover:hover
|
||||
{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
}
|
||||
.bx-bounce{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
.bx-bounce-hover:hover
|
||||
{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
|
||||
.bx-beat
|
||||
{
|
||||
-webkit-animation: beat .5s infinite alternate;
|
||||
animation: beat .5s infinite alternate;
|
||||
animation-timing-function: cubic-bezier(.19,.96,.65,1);
|
||||
transform-origin: center;
|
||||
}
|
||||
.bx-spin
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.bx-spin-hover:hover
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bx-tada
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
.bx-tada-hover:hover
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
|
||||
.bx-flashing
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
.bx-flashing-hover:hover
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
|
||||
.bx-burst
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-burst-hover:hover
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
1
apps/icon-pack-builder/boxicons-free/fonts/animations.min.css
vendored
Normal file
11124
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.css
Normal file
25720
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.html
Normal file
3702
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.json
Normal file
1
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.min.css
vendored
Normal file
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.ttf
Normal file
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.woff
Normal file
BIN
apps/icon-pack-builder/boxicons-free/fonts/basic/boxicons.woff2
Normal file
515
apps/icon-pack-builder/boxicons-free/fonts/brands/animations.css
Normal file
@@ -0,0 +1,515 @@
|
||||
@-webkit-keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@keyframes spin
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
100%
|
||||
{
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes burst
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes flashing
|
||||
{
|
||||
0%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
45%
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
90%
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-left
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(-20px);
|
||||
transform: translateX(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-right
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateX(20px);
|
||||
transform: translateX(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-up
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(-20px);
|
||||
transform: translateY(-20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes fade-down
|
||||
{
|
||||
0%
|
||||
{
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: translateY(20px);
|
||||
transform: translateY(20px);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes tada
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
10%,
|
||||
20%
|
||||
{
|
||||
-webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
30%,
|
||||
50%,
|
||||
70%,
|
||||
90%
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg);
|
||||
}
|
||||
|
||||
40%,
|
||||
60%,
|
||||
80%
|
||||
{
|
||||
-webkit-transform: rotate3d(0, 0, 1, -10deg);
|
||||
transform: rotate3d(0, 0, 1, -10deg);
|
||||
}
|
||||
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale3d(1, 1, 1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes beat {
|
||||
to {
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes bounce
|
||||
{
|
||||
from
|
||||
{
|
||||
-webkit-transform: scale(1.1,1);
|
||||
transform: scale(1.1,1);
|
||||
}
|
||||
|
||||
25%
|
||||
{
|
||||
-webkit-transform: scale(0.9,1) translateY(-.25em);
|
||||
transform: scale(0.9,1) translateY(-.25em);
|
||||
}
|
||||
|
||||
50%
|
||||
{
|
||||
-webkit-transform: scale(1.1,0.9);
|
||||
transform: scale(1.1,0.9);
|
||||
}
|
||||
75%
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
87.5%
|
||||
{
|
||||
-webkit-transform: scale(1, 1) translateY(-.1em);
|
||||
transform: scale(1, 1) translateY(-.1em);
|
||||
}
|
||||
to
|
||||
{
|
||||
-webkit-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes breathe {
|
||||
from{
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50%{
|
||||
-webkit-transform: scale(1.4);
|
||||
transform: scale(1.4);
|
||||
opacity: 0.4;
|
||||
}
|
||||
to {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
}
|
||||
@keyframes wiggle {
|
||||
from{
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
30%{
|
||||
-webkit-transform: translateX(0.075em);
|
||||
transform: translateX(0.075em);
|
||||
}
|
||||
60%{
|
||||
-webkit-transform: translateX(-0.075em);
|
||||
transform: translateX(-0.075em);
|
||||
}
|
||||
75%{
|
||||
-webkit-transform: translateX(0.025em);
|
||||
transform: translateX(0.025em);
|
||||
}
|
||||
90%{
|
||||
-webkit-transform: translateX(-0.025em);
|
||||
transform: translateX(-0.025em);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: translateX(0);
|
||||
transform:translateX(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bx-wiggle{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-wiggle-hover:hover{
|
||||
-webkit-animation: wiggle 1s infinite;
|
||||
animation: wiggle 1s infinite;
|
||||
animation-timing-function:cubic-bezier(.23,.57,.79,.58);
|
||||
}
|
||||
.bx-breathe{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
|
||||
}
|
||||
.bx-breathe-hover:hover
|
||||
{
|
||||
-webkit-animation: breathe 3s infinite;
|
||||
animation: breathe 3s infinite ease-in-out;
|
||||
}
|
||||
.bx-bounce{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
.bx-bounce-hover:hover
|
||||
{
|
||||
-webkit-animation: bounce 1s infinite;
|
||||
animation: bounce 1s infinite;
|
||||
animation-timing-function: cubic-bezier(.98,.97,.64,1.62);
|
||||
}
|
||||
|
||||
.bx-beat
|
||||
{
|
||||
-webkit-animation: beat .5s infinite alternate;
|
||||
animation: beat .5s infinite alternate;
|
||||
animation-timing-function: cubic-bezier(.19,.96,.65,1);
|
||||
transform-origin: center;
|
||||
}
|
||||
.bx-spin
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
.bx-spin-hover:hover
|
||||
{
|
||||
-webkit-animation: spin 2s linear infinite;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bx-tada
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
.bx-tada-hover:hover
|
||||
{
|
||||
-webkit-animation: tada 1.5s ease infinite;
|
||||
animation: tada 1.5s ease infinite;
|
||||
}
|
||||
|
||||
.bx-flashing
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
.bx-flashing-hover:hover
|
||||
{
|
||||
-webkit-animation: flashing 1.5s infinite linear;
|
||||
animation: flashing 1.5s infinite linear;
|
||||
}
|
||||
|
||||
.bx-burst
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-burst-hover:hover
|
||||
{
|
||||
-webkit-animation: burst 1.5s infinite linear;
|
||||
animation: burst 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-up-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-up 1.5s infinite linear;
|
||||
animation: fade-up 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-down-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-down 1.5s infinite linear;
|
||||
animation: fade-down 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-left-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-left 1.5s infinite linear;
|
||||
animation: fade-left 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
.bx-fade-right-hover:hover
|
||||
{
|
||||
-webkit-animation: fade-right 1.5s infinite linear;
|
||||
animation: fade-right 1.5s infinite linear;
|
||||
}
|
||||
@@ -0,0 +1,906 @@
|
||||
@font-face {
|
||||
font-family: "boxicons-brands";
|
||||
src: url("./boxicons-brands.ttf?945bfe89057cc7627be1ecdc648441aa") format("truetype"),
|
||||
url("./boxicons-brands.woff?945bfe89057cc7627be1ecdc648441aa") format("woff"),
|
||||
url("./boxicons-brands.woff2?945bfe89057cc7627be1ecdc648441aa") format("woff2");
|
||||
}
|
||||
|
||||
|
||||
.bxl {
|
||||
font-family: boxicons-brands !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
display:inline-block;
|
||||
speak:none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.bxl.variable-selector-00:before {
|
||||
content: "\fb1e";
|
||||
}
|
||||
.bxl.bx-500px:before {
|
||||
content: "\f101";
|
||||
}
|
||||
.bxl.bx-99designs:before {
|
||||
content: "\f102";
|
||||
}
|
||||
.bxl.bx-adobe:before {
|
||||
content: "\f103";
|
||||
}
|
||||
.bxl.bx-airbnb:before {
|
||||
content: "\f104";
|
||||
}
|
||||
.bxl.bx-algolia:before {
|
||||
content: "\f105";
|
||||
}
|
||||
.bxl.bx-amazon:before {
|
||||
content: "\f106";
|
||||
}
|
||||
.bxl.bx-amex:before {
|
||||
content: "\f107";
|
||||
}
|
||||
.bxl.bx-android:before {
|
||||
content: "\f108";
|
||||
}
|
||||
.bxl.bx-angular:before {
|
||||
content: "\f109";
|
||||
}
|
||||
.bxl.bx-anthropic:before {
|
||||
content: "\f10a";
|
||||
}
|
||||
.bxl.bx-apple-music:before {
|
||||
content: "\f10b";
|
||||
}
|
||||
.bxl.bx-apple:before {
|
||||
content: "\f10c";
|
||||
}
|
||||
.bxl.bx-arc-browser:before {
|
||||
content: "\f10d";
|
||||
}
|
||||
.bxl.bx-artstation:before {
|
||||
content: "\f10e";
|
||||
}
|
||||
.bxl.bx-asana:before {
|
||||
content: "\f10f";
|
||||
}
|
||||
.bxl.bx-atlassian:before {
|
||||
content: "\f110";
|
||||
}
|
||||
.bxl.bx-atom-editor:before {
|
||||
content: "\f111";
|
||||
}
|
||||
.bxl.bx-audible:before {
|
||||
content: "\f112";
|
||||
}
|
||||
.bxl.bx-auth0:before {
|
||||
content: "\f113";
|
||||
}
|
||||
.bxl.bx-autodesk:before {
|
||||
content: "\f114";
|
||||
}
|
||||
.bxl.bx-aws:before {
|
||||
content: "\f115";
|
||||
}
|
||||
.bxl.bx-baidu:before {
|
||||
content: "\f116";
|
||||
}
|
||||
.bxl.bx-bash:before {
|
||||
content: "\f117";
|
||||
}
|
||||
.bxl.bx-behance:before {
|
||||
content: "\f118";
|
||||
}
|
||||
.bxl.bx-better-auth:before {
|
||||
content: "\f119";
|
||||
}
|
||||
.bxl.bx-bing:before {
|
||||
content: "\f11a";
|
||||
}
|
||||
.bxl.bx-bitcoin-logo:before {
|
||||
content: "\f11b";
|
||||
}
|
||||
.bxl.bx-blender:before {
|
||||
content: "\f11c";
|
||||
}
|
||||
.bxl.bx-blogger:before {
|
||||
content: "\f11d";
|
||||
}
|
||||
.bxl.bx-bluesky:before {
|
||||
content: "\f11e";
|
||||
}
|
||||
.bxl.bx-bolt-b:before {
|
||||
content: "\f11f";
|
||||
}
|
||||
.bxl.bx-bootstrap:before {
|
||||
content: "\f120";
|
||||
}
|
||||
.bxl.bx-boxicons:before {
|
||||
content: "\f121";
|
||||
}
|
||||
.bxl.bx-brave-browser:before {
|
||||
content: "\f122";
|
||||
}
|
||||
.bxl.bx-bun:before {
|
||||
content: "\f123";
|
||||
}
|
||||
.bxl.bx-buy-me-a-coffee:before {
|
||||
content: "\f124";
|
||||
}
|
||||
.bxl.bx-c-plus-plus:before {
|
||||
content: "\f125";
|
||||
}
|
||||
.bxl.bx-c-sharp:before {
|
||||
content: "\f126";
|
||||
}
|
||||
.bxl.bx-c:before {
|
||||
content: "\f127";
|
||||
}
|
||||
.bxl.bx-canva:before {
|
||||
content: "\f128";
|
||||
}
|
||||
.bxl.bx-chess-com:before {
|
||||
content: "\f129";
|
||||
}
|
||||
.bxl.bx-chrome:before {
|
||||
content: "\f12a";
|
||||
}
|
||||
.bxl.bx-claude-ai:before {
|
||||
content: "\f12b";
|
||||
}
|
||||
.bxl.bx-clerk:before {
|
||||
content: "\f12c";
|
||||
}
|
||||
.bxl.bx-cloudflare:before {
|
||||
content: "\f12d";
|
||||
}
|
||||
.bxl.bx-codepen:before {
|
||||
content: "\f12e";
|
||||
}
|
||||
.bxl.bx-convex:before {
|
||||
content: "\f12f";
|
||||
}
|
||||
.bxl.bx-creative-commons:before {
|
||||
content: "\f130";
|
||||
}
|
||||
.bxl.bx-crunchyroll:before {
|
||||
content: "\f131";
|
||||
}
|
||||
.bxl.bx-css3:before {
|
||||
content: "\f132";
|
||||
}
|
||||
.bxl.bx-cursor-ai:before {
|
||||
content: "\f133";
|
||||
}
|
||||
.bxl.bx-dailymotion:before {
|
||||
content: "\f134";
|
||||
}
|
||||
.bxl.bx-deepmind:before {
|
||||
content: "\f135";
|
||||
}
|
||||
.bxl.bx-deepseek:before {
|
||||
content: "\f136";
|
||||
}
|
||||
.bxl.bx-deezer:before {
|
||||
content: "\f137";
|
||||
}
|
||||
.bxl.bx-deno:before {
|
||||
content: "\f138";
|
||||
}
|
||||
.bxl.bx-dev-to:before {
|
||||
content: "\f139";
|
||||
}
|
||||
.bxl.bx-deviantart:before {
|
||||
content: "\f13a";
|
||||
}
|
||||
.bxl.bx-devpost:before {
|
||||
content: "\f13b";
|
||||
}
|
||||
.bxl.bx-digg:before {
|
||||
content: "\f13c";
|
||||
}
|
||||
.bxl.bx-digitalocean:before {
|
||||
content: "\f13d";
|
||||
}
|
||||
.bxl.bx-discord-alt:before {
|
||||
content: "\f13e";
|
||||
}
|
||||
.bxl.bx-discord:before {
|
||||
content: "\f13f";
|
||||
}
|
||||
.bxl.bx-discourse:before {
|
||||
content: "\f140";
|
||||
}
|
||||
.bxl.bx-discover:before {
|
||||
content: "\f141";
|
||||
}
|
||||
.bxl.bx-django:before {
|
||||
content: "\f142";
|
||||
}
|
||||
.bxl.bx-docker:before {
|
||||
content: "\f143";
|
||||
}
|
||||
.bxl.bx-dot-env:before {
|
||||
content: "\f144";
|
||||
}
|
||||
.bxl.bx-dribbble:before {
|
||||
content: "\f145";
|
||||
}
|
||||
.bxl.bx-drizzle-orm:before {
|
||||
content: "\f146";
|
||||
}
|
||||
.bxl.bx-dropbox:before {
|
||||
content: "\f147";
|
||||
}
|
||||
.bxl.bx-ebay:before {
|
||||
content: "\f148";
|
||||
}
|
||||
.bxl.bx-edge:before {
|
||||
content: "\f149";
|
||||
}
|
||||
.bxl.bx-ember-js:before {
|
||||
content: "\f14a";
|
||||
}
|
||||
.bxl.bx-etsy:before {
|
||||
content: "\f14b";
|
||||
}
|
||||
.bxl.bx-expo:before {
|
||||
content: "\f14c";
|
||||
}
|
||||
.bxl.bx-express-js:before {
|
||||
content: "\f14d";
|
||||
}
|
||||
.bxl.bx-facebook-circle:before {
|
||||
content: "\f14e";
|
||||
}
|
||||
.bxl.bx-facebook-square:before {
|
||||
content: "\f14f";
|
||||
}
|
||||
.bxl.bx-facebook:before {
|
||||
content: "\f150";
|
||||
}
|
||||
.bxl.bx-fastapi:before {
|
||||
content: "\f151";
|
||||
}
|
||||
.bxl.bx-fastify:before {
|
||||
content: "\f152";
|
||||
}
|
||||
.bxl.bx-figma-alt:before {
|
||||
content: "\f153";
|
||||
}
|
||||
.bxl.bx-figma:before {
|
||||
content: "\f154";
|
||||
}
|
||||
.bxl.bx-firebase:before {
|
||||
content: "\f155";
|
||||
}
|
||||
.bxl.bx-firefox:before {
|
||||
content: "\f156";
|
||||
}
|
||||
.bxl.bx-fiverr:before {
|
||||
content: "\f157";
|
||||
}
|
||||
.bxl.bx-flask-old:before {
|
||||
content: "\f158";
|
||||
}
|
||||
.bxl.bx-flask:before {
|
||||
content: "\f159";
|
||||
}
|
||||
.bxl.bx-flickr-square:before {
|
||||
content: "\f15a";
|
||||
}
|
||||
.bxl.bx-flickr:before {
|
||||
content: "\f15b";
|
||||
}
|
||||
.bxl.bx-flutter:before {
|
||||
content: "\f15c";
|
||||
}
|
||||
.bxl.bx-foursquare:before {
|
||||
content: "\f15d";
|
||||
}
|
||||
.bxl.bx-framer:before {
|
||||
content: "\f15e";
|
||||
}
|
||||
.bxl.bx-gatsby-js:before {
|
||||
content: "\f15f";
|
||||
}
|
||||
.bxl.bx-gemini:before {
|
||||
content: "\f160";
|
||||
}
|
||||
.bxl.bx-git:before {
|
||||
content: "\f161";
|
||||
}
|
||||
.bxl.bx-github-copilot:before {
|
||||
content: "\f162";
|
||||
}
|
||||
.bxl.bx-github:before {
|
||||
content: "\f163";
|
||||
}
|
||||
.bxl.bx-gitlab:before {
|
||||
content: "\f164";
|
||||
}
|
||||
.bxl.bx-gmail:before {
|
||||
content: "\f165";
|
||||
}
|
||||
.bxl.bx-go-lang:before {
|
||||
content: "\f166";
|
||||
}
|
||||
.bxl.bx-google-antigravity:before {
|
||||
content: "\f167";
|
||||
}
|
||||
.bxl.bx-google-cloud:before {
|
||||
content: "\f168";
|
||||
}
|
||||
.bxl.bx-google-pay:before {
|
||||
content: "\f169";
|
||||
}
|
||||
.bxl.bx-google:before {
|
||||
content: "\f16a";
|
||||
}
|
||||
.bxl.bx-graphql:before {
|
||||
content: "\f16b";
|
||||
}
|
||||
.bxl.bx-grok:before {
|
||||
content: "\f16c";
|
||||
}
|
||||
.bxl.bx-groq-ai:before {
|
||||
content: "\f16d";
|
||||
}
|
||||
.bxl.bx-gsap:before {
|
||||
content: "\f16e";
|
||||
}
|
||||
.bxl.bx-gumroad:before {
|
||||
content: "\f16f";
|
||||
}
|
||||
.bxl.bx-hashnode:before {
|
||||
content: "\f170";
|
||||
}
|
||||
.bxl.bx-hcaptcha:before {
|
||||
content: "\f171";
|
||||
}
|
||||
.bxl.bx-heroku:before {
|
||||
content: "\f172";
|
||||
}
|
||||
.bxl.bx-hono-js:before {
|
||||
content: "\f173";
|
||||
}
|
||||
.bxl.bx-html5:before {
|
||||
content: "\f174";
|
||||
}
|
||||
.bxl.bx-hugo:before {
|
||||
content: "\f175";
|
||||
}
|
||||
.bxl.bx-ibm:before {
|
||||
content: "\f176";
|
||||
}
|
||||
.bxl.bx-imdb:before {
|
||||
content: "\f177";
|
||||
}
|
||||
.bxl.bx-instagram-alt:before {
|
||||
content: "\f178";
|
||||
}
|
||||
.bxl.bx-instagram:before {
|
||||
content: "\f179";
|
||||
}
|
||||
.bxl.bx-internet-explorer:before {
|
||||
content: "\f17a";
|
||||
}
|
||||
.bxl.bx-invision:before {
|
||||
content: "\f17b";
|
||||
}
|
||||
.bxl.bx-java:before {
|
||||
content: "\f17c";
|
||||
}
|
||||
.bxl.bx-javascript:before {
|
||||
content: "\f17d";
|
||||
}
|
||||
.bxl.bx-joomla:before {
|
||||
content: "\f17e";
|
||||
}
|
||||
.bxl.bx-jquery:before {
|
||||
content: "\f17f";
|
||||
}
|
||||
.bxl.bx-jsfiddle:before {
|
||||
content: "\f180";
|
||||
}
|
||||
.bxl.bx-jwt:before {
|
||||
content: "\f181";
|
||||
}
|
||||
.bxl.bx-kick:before {
|
||||
content: "\f182";
|
||||
}
|
||||
.bxl.bx-kickstarter:before {
|
||||
content: "\f183";
|
||||
}
|
||||
.bxl.bx-kotlin:before {
|
||||
content: "\f184";
|
||||
}
|
||||
.bxl.bx-kubernetes:before {
|
||||
content: "\f185";
|
||||
}
|
||||
.bxl.bx-laravel:before {
|
||||
content: "\f186";
|
||||
}
|
||||
.bxl.bx-leetcode:before {
|
||||
content: "\f187";
|
||||
}
|
||||
.bxl.bx-lemon-squeezy:before {
|
||||
content: "\f188";
|
||||
}
|
||||
.bxl.bx-less:before {
|
||||
content: "\f189";
|
||||
}
|
||||
.bxl.bx-letterboxd:before {
|
||||
content: "\f18a";
|
||||
}
|
||||
.bxl.bx-lichess:before {
|
||||
content: "\f18b";
|
||||
}
|
||||
.bxl.bx-line-chat:before {
|
||||
content: "\f18c";
|
||||
}
|
||||
.bxl.bx-linear-app:before {
|
||||
content: "\f18d";
|
||||
}
|
||||
.bxl.bx-linkedin-square:before {
|
||||
content: "\f18e";
|
||||
}
|
||||
.bxl.bx-linkedin:before {
|
||||
content: "\f18f";
|
||||
}
|
||||
.bxl.bx-linktree:before {
|
||||
content: "\f190";
|
||||
}
|
||||
.bxl.bx-loom:before {
|
||||
content: "\f191";
|
||||
}
|
||||
.bxl.bx-lottie-files:before {
|
||||
content: "\f192";
|
||||
}
|
||||
.bxl.bx-lottie-lab:before {
|
||||
content: "\f193";
|
||||
}
|
||||
.bxl.bx-lovable:before {
|
||||
content: "\f194";
|
||||
}
|
||||
.bxl.bx-lyft:before {
|
||||
content: "\f195";
|
||||
}
|
||||
.bxl.bx-magento:before {
|
||||
content: "\f196";
|
||||
}
|
||||
.bxl.bx-mailchimp:before {
|
||||
content: "\f197";
|
||||
}
|
||||
.bxl.bx-markdown:before {
|
||||
content: "\f198";
|
||||
}
|
||||
.bxl.bx-mastercard:before {
|
||||
content: "\f199";
|
||||
}
|
||||
.bxl.bx-mastodon:before {
|
||||
content: "\f19a";
|
||||
}
|
||||
.bxl.bx-mcp:before {
|
||||
content: "\f19b";
|
||||
}
|
||||
.bxl.bx-medium-old:before {
|
||||
content: "\f19c";
|
||||
}
|
||||
.bxl.bx-medium-square:before {
|
||||
content: "\f19d";
|
||||
}
|
||||
.bxl.bx-medium:before {
|
||||
content: "\f19e";
|
||||
}
|
||||
.bxl.bx-messenger:before {
|
||||
content: "\f19f";
|
||||
}
|
||||
.bxl.bx-meta:before {
|
||||
content: "\f1a0";
|
||||
}
|
||||
.bxl.bx-microsoft-teams:before {
|
||||
content: "\f1a1";
|
||||
}
|
||||
.bxl.bx-microsoft-windows:before {
|
||||
content: "\f1a2";
|
||||
}
|
||||
.bxl.bx-microsoft:before {
|
||||
content: "\f1a3";
|
||||
}
|
||||
.bxl.bx-midjourney:before {
|
||||
content: "\f1a4";
|
||||
}
|
||||
.bxl.bx-mongodb:before {
|
||||
content: "\f1a5";
|
||||
}
|
||||
.bxl.bx-motion-js:before {
|
||||
content: "\f1a6";
|
||||
}
|
||||
.bxl.bx-mozilla:before {
|
||||
content: "\f1a7";
|
||||
}
|
||||
.bxl.bx-my-sql:before {
|
||||
content: "\f1a8";
|
||||
}
|
||||
.bxl.bx-neon-tech:before {
|
||||
content: "\f1a9";
|
||||
}
|
||||
.bxl.bx-neovim:before {
|
||||
content: "\f1aa";
|
||||
}
|
||||
.bxl.bx-nest-js:before {
|
||||
content: "\f1ab";
|
||||
}
|
||||
.bxl.bx-netlify:before {
|
||||
content: "\f1ac";
|
||||
}
|
||||
.bxl.bx-next-js:before {
|
||||
content: "\f1ad";
|
||||
}
|
||||
.bxl.bx-nodejs:before {
|
||||
content: "\f1ae";
|
||||
}
|
||||
.bxl.bx-notion:before {
|
||||
content: "\f1af";
|
||||
}
|
||||
.bxl.bx-npm:before {
|
||||
content: "\f1b0";
|
||||
}
|
||||
.bxl.bx-nuxt-js:before {
|
||||
content: "\f1b1";
|
||||
}
|
||||
.bxl.bx-ok-ru:before {
|
||||
content: "\f1b2";
|
||||
}
|
||||
.bxl.bx-ollama:before {
|
||||
content: "\f1b3";
|
||||
}
|
||||
.bxl.bx-openai:before {
|
||||
content: "\f1b4";
|
||||
}
|
||||
.bxl.bx-opensea:before {
|
||||
content: "\f1b5";
|
||||
}
|
||||
.bxl.bx-opera:before {
|
||||
content: "\f1b6";
|
||||
}
|
||||
.bxl.bx-paddle-p:before {
|
||||
content: "\f1b7";
|
||||
}
|
||||
.bxl.bx-paper-design:before {
|
||||
content: "\f1b8";
|
||||
}
|
||||
.bxl.bx-patreon:before {
|
||||
content: "\f1b9";
|
||||
}
|
||||
.bxl.bx-payload-cms:before {
|
||||
content: "\f1ba";
|
||||
}
|
||||
.bxl.bx-paypal:before {
|
||||
content: "\f1bb";
|
||||
}
|
||||
.bxl.bx-periscope:before {
|
||||
content: "\f1bc";
|
||||
}
|
||||
.bxl.bx-perplexity-ai:before {
|
||||
content: "\f1bd";
|
||||
}
|
||||
.bxl.bx-php:before {
|
||||
content: "\f1be";
|
||||
}
|
||||
.bxl.bx-pinterest-alt:before {
|
||||
content: "\f1bf";
|
||||
}
|
||||
.bxl.bx-pinterest:before {
|
||||
content: "\f1c0";
|
||||
}
|
||||
.bxl.bx-planetscale:before {
|
||||
content: "\f1c1";
|
||||
}
|
||||
.bxl.bx-play-store:before {
|
||||
content: "\f1c2";
|
||||
}
|
||||
.bxl.bx-playstation:before {
|
||||
content: "\f1c3";
|
||||
}
|
||||
.bxl.bx-pocket:before {
|
||||
content: "\f1c4";
|
||||
}
|
||||
.bxl.bx-polar:before {
|
||||
content: "\f1c5";
|
||||
}
|
||||
.bxl.bx-postgresql:before {
|
||||
content: "\f1c6";
|
||||
}
|
||||
.bxl.bx-prisma-orm:before {
|
||||
content: "\f1c7";
|
||||
}
|
||||
.bxl.bx-product-hunt:before {
|
||||
content: "\f1c8";
|
||||
}
|
||||
.bxl.bx-python:before {
|
||||
content: "\f1c9";
|
||||
}
|
||||
.bxl.bx-qdrant:before {
|
||||
content: "\f1ca";
|
||||
}
|
||||
.bxl.bx-qq:before {
|
||||
content: "\f1cb";
|
||||
}
|
||||
.bxl.bx-quora:before {
|
||||
content: "\f1cc";
|
||||
}
|
||||
.bxl.bx-radix-ui:before {
|
||||
content: "\f1cd";
|
||||
}
|
||||
.bxl.bx-railway:before {
|
||||
content: "\f1ce";
|
||||
}
|
||||
.bxl.bx-rasberry-pi:before {
|
||||
content: "\f1cf";
|
||||
}
|
||||
.bxl.bx-react-query:before {
|
||||
content: "\f1d0";
|
||||
}
|
||||
.bxl.bx-react-router:before {
|
||||
content: "\f1d1";
|
||||
}
|
||||
.bxl.bx-react:before {
|
||||
content: "\f1d2";
|
||||
}
|
||||
.bxl.bx-redbubble:before {
|
||||
content: "\f1d3";
|
||||
}
|
||||
.bxl.bx-reddit:before {
|
||||
content: "\f1d4";
|
||||
}
|
||||
.bxl.bx-redux:before {
|
||||
content: "\f1d5";
|
||||
}
|
||||
.bxl.bx-remix-js:before {
|
||||
content: "\f1d6";
|
||||
}
|
||||
.bxl.bx-replit:before {
|
||||
content: "\f1d7";
|
||||
}
|
||||
.bxl.bx-resend:before {
|
||||
content: "\f1d8";
|
||||
}
|
||||
.bxl.bx-roblox:before {
|
||||
content: "\f1d9";
|
||||
}
|
||||
.bxl.bx-sanity:before {
|
||||
content: "\f1da";
|
||||
}
|
||||
.bxl.bx-sass:before {
|
||||
content: "\f1db";
|
||||
}
|
||||
.bxl.bx-sentry:before {
|
||||
content: "\f1dc";
|
||||
}
|
||||
.bxl.bx-shadcn-ui:before {
|
||||
content: "\f1dd";
|
||||
}
|
||||
.bxl.bx-shopify:before {
|
||||
content: "\f1de";
|
||||
}
|
||||
.bxl.bx-sketch:before {
|
||||
content: "\f1df";
|
||||
}
|
||||
.bxl.bx-skype:before {
|
||||
content: "\f1e0";
|
||||
}
|
||||
.bxl.bx-slack-old:before {
|
||||
content: "\f1e1";
|
||||
}
|
||||
.bxl.bx-slack:before {
|
||||
content: "\f1e2";
|
||||
}
|
||||
.bxl.bx-snapchat:before {
|
||||
content: "\f1e3";
|
||||
}
|
||||
.bxl.bx-socket-io:before {
|
||||
content: "\f1e4";
|
||||
}
|
||||
.bxl.bx-soundcloud:before {
|
||||
content: "\f1e5";
|
||||
}
|
||||
.bxl.bx-spotify:before {
|
||||
content: "\f1e6";
|
||||
}
|
||||
.bxl.bx-spring-boot:before {
|
||||
content: "\f1e7";
|
||||
}
|
||||
.bxl.bx-squarespace:before {
|
||||
content: "\f1e8";
|
||||
}
|
||||
.bxl.bx-sst:before {
|
||||
content: "\f1e9";
|
||||
}
|
||||
.bxl.bx-stack-overflow:before {
|
||||
content: "\f1ea";
|
||||
}
|
||||
.bxl.bx-stackblitz:before {
|
||||
content: "\f1eb";
|
||||
}
|
||||
.bxl.bx-steam:before {
|
||||
content: "\f1ec";
|
||||
}
|
||||
.bxl.bx-stripe:before {
|
||||
content: "\f1ed";
|
||||
}
|
||||
.bxl.bx-supabase:before {
|
||||
content: "\f1ee";
|
||||
}
|
||||
.bxl.bx-svelte:before {
|
||||
content: "\f1ef";
|
||||
}
|
||||
.bxl.bx-tailwind-css:before {
|
||||
content: "\f1f0";
|
||||
}
|
||||
.bxl.bx-telegram:before {
|
||||
content: "\f1f1";
|
||||
}
|
||||
.bxl.bx-terraform:before {
|
||||
content: "\f1f2";
|
||||
}
|
||||
.bxl.bx-threads:before {
|
||||
content: "\f1f3";
|
||||
}
|
||||
.bxl.bx-three-js:before {
|
||||
content: "\f1f4";
|
||||
}
|
||||
.bxl.bx-tiktok:before {
|
||||
content: "\f1f5";
|
||||
}
|
||||
.bxl.bx-trello:before {
|
||||
content: "\f1f6";
|
||||
}
|
||||
.bxl.bx-trip-advisor:before {
|
||||
content: "\f1f7";
|
||||
}
|
||||
.bxl.bx-trpc:before {
|
||||
content: "\f1f8";
|
||||
}
|
||||
.bxl.bx-trustpilot:before {
|
||||
content: "\f1f9";
|
||||
}
|
||||
.bxl.bx-tumblr:before {
|
||||
content: "\f1fa";
|
||||
}
|
||||
.bxl.bx-tux:before {
|
||||
content: "\f1fb";
|
||||
}
|
||||
.bxl.bx-twitch:before {
|
||||
content: "\f1fc";
|
||||
}
|
||||
.bxl.bx-twitter-x:before {
|
||||
content: "\f1fd";
|
||||
}
|
||||
.bxl.bx-twitter:before {
|
||||
content: "\f1fe";
|
||||
}
|
||||
.bxl.bx-typescript:before {
|
||||
content: "\f1ff";
|
||||
}
|
||||
.bxl.bx-uber:before {
|
||||
content: "\f200";
|
||||
}
|
||||
.bxl.bx-ubuntu:before {
|
||||
content: "\f201";
|
||||
}
|
||||
.bxl.bx-udacity:before {
|
||||
content: "\f202";
|
||||
}
|
||||
.bxl.bx-union-pay:before {
|
||||
content: "\f203";
|
||||
}
|
||||
.bxl.bx-unity:before {
|
||||
content: "\f204";
|
||||
}
|
||||
.bxl.bx-unsplash:before {
|
||||
content: "\f205";
|
||||
}
|
||||
.bxl.bx-upi:before {
|
||||
content: "\f206";
|
||||
}
|
||||
.bxl.bx-upwork:before {
|
||||
content: "\f207";
|
||||
}
|
||||
.bxl.bx-v0:before {
|
||||
content: "\f208";
|
||||
}
|
||||
.bxl.bx-venmo:before {
|
||||
content: "\f209";
|
||||
}
|
||||
.bxl.bx-vercel:before {
|
||||
content: "\f20a";
|
||||
}
|
||||
.bxl.bx-vimeo:before {
|
||||
content: "\f20b";
|
||||
}
|
||||
.bxl.bx-visa:before {
|
||||
content: "\f20c";
|
||||
}
|
||||
.bxl.bx-visual-studio:before {
|
||||
content: "\f20d";
|
||||
}
|
||||
.bxl.bx-vite-js:before {
|
||||
content: "\f20e";
|
||||
}
|
||||
.bxl.bx-vk:before {
|
||||
content: "\f20f";
|
||||
}
|
||||
.bxl.bx-vuejs:before {
|
||||
content: "\f210";
|
||||
}
|
||||
.bxl.bx-waze:before {
|
||||
content: "\f211";
|
||||
}
|
||||
.bxl.bx-web-components:before {
|
||||
content: "\f212";
|
||||
}
|
||||
.bxl.bx-webflow:before {
|
||||
content: "\f213";
|
||||
}
|
||||
.bxl.bx-wechat:before {
|
||||
content: "\f214";
|
||||
}
|
||||
.bxl.bx-weibo:before {
|
||||
content: "\f215";
|
||||
}
|
||||
.bxl.bx-whatsapp-square:before {
|
||||
content: "\f216";
|
||||
}
|
||||
.bxl.bx-whatsapp:before {
|
||||
content: "\f217";
|
||||
}
|
||||
.bxl.bx-wikipedia:before {
|
||||
content: "\f218";
|
||||
}
|
||||
.bxl.bx-windsurf:before {
|
||||
content: "\f219";
|
||||
}
|
||||
.bxl.bx-wix:before {
|
||||
content: "\f21a";
|
||||
}
|
||||
.bxl.bx-wordpress:before {
|
||||
content: "\f21b";
|
||||
}
|
||||
.bxl.bx-work-os:before {
|
||||
content: "\f21c";
|
||||
}
|
||||
.bxl.bx-xai:before {
|
||||
content: "\f21d";
|
||||
}
|
||||
.bxl.bx-xbox:before {
|
||||
content: "\f21e";
|
||||
}
|
||||
.bxl.bx-xing:before {
|
||||
content: "\f21f";
|
||||
}
|
||||
.bxl.bx-yahoo:before {
|
||||
content: "\f220";
|
||||
}
|
||||
.bxl.bx-yarn:before {
|
||||
content: "\f221";
|
||||
}
|
||||
.bxl.bx-yelp:before {
|
||||
content: "\f222";
|
||||
}
|
||||
.bxl.bx-youtube-music:before {
|
||||
content: "\f223";
|
||||
}
|
||||
.bxl.bx-youtube:before {
|
||||
content: "\f224";
|
||||
}
|
||||
.bxl.bx-zen-browser:before {
|
||||
content: "\f225";
|
||||
}
|
||||
.bxl.bx-zoom-workplace:before {
|
||||
content: "\f226";
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"variable-selector-00": 64286,
|
||||
"bx-500px": 61697,
|
||||
"bx-99designs": 61698,
|
||||
"bx-adobe": 61699,
|
||||
"bx-airbnb": 61700,
|
||||
"bx-algolia": 61701,
|
||||
"bx-amazon": 61702,
|
||||
"bx-amex": 61703,
|
||||
"bx-android": 61704,
|
||||
"bx-angular": 61705,
|
||||
"bx-anthropic": 61706,
|
||||
"bx-apple-music": 61707,
|
||||
"bx-apple": 61708,
|
||||
"bx-arc-browser": 61709,
|
||||
"bx-artstation": 61710,
|
||||
"bx-asana": 61711,
|
||||
"bx-atlassian": 61712,
|
||||
"bx-atom-editor": 61713,
|
||||
"bx-audible": 61714,
|
||||
"bx-auth0": 61715,
|
||||
"bx-autodesk": 61716,
|
||||
"bx-aws": 61717,
|
||||
"bx-baidu": 61718,
|
||||
"bx-bash": 61719,
|
||||
"bx-behance": 61720,
|
||||
"bx-better-auth": 61721,
|
||||
"bx-bing": 61722,
|
||||
"bx-bitcoin-logo": 61723,
|
||||
"bx-blender": 61724,
|
||||
"bx-blogger": 61725,
|
||||
"bx-bluesky": 61726,
|
||||
"bx-bolt-b": 61727,
|
||||
"bx-bootstrap": 61728,
|
||||
"bx-boxicons": 61729,
|
||||
"bx-brave-browser": 61730,
|
||||
"bx-bun": 61731,
|
||||
"bx-buy-me-a-coffee": 61732,
|
||||
"bx-c-plus-plus": 61733,
|
||||
"bx-c-sharp": 61734,
|
||||
"bx-c": 61735,
|
||||
"bx-canva": 61736,
|
||||
"bx-chess-com": 61737,
|
||||
"bx-chrome": 61738,
|
||||
"bx-claude-ai": 61739,
|
||||
"bx-clerk": 61740,
|
||||
"bx-cloudflare": 61741,
|
||||
"bx-codepen": 61742,
|
||||
"bx-convex": 61743,
|
||||
"bx-creative-commons": 61744,
|
||||
"bx-crunchyroll": 61745,
|
||||
"bx-css3": 61746,
|
||||
"bx-cursor-ai": 61747,
|
||||
"bx-dailymotion": 61748,
|
||||
"bx-deepmind": 61749,
|
||||
"bx-deepseek": 61750,
|
||||
"bx-deezer": 61751,
|
||||
"bx-deno": 61752,
|
||||
"bx-dev-to": 61753,
|
||||
"bx-deviantart": 61754,
|
||||
"bx-devpost": 61755,
|
||||
"bx-digg": 61756,
|
||||
"bx-digitalocean": 61757,
|
||||
"bx-discord-alt": 61758,
|
||||
"bx-discord": 61759,
|
||||
"bx-discourse": 61760,
|
||||
"bx-discover": 61761,
|
||||
"bx-django": 61762,
|
||||
"bx-docker": 61763,
|
||||
"bx-dot-env": 61764,
|
||||
"bx-dribbble": 61765,
|
||||
"bx-drizzle-orm": 61766,
|
||||
"bx-dropbox": 61767,
|
||||
"bx-ebay": 61768,
|
||||
"bx-edge": 61769,
|
||||
"bx-ember-js": 61770,
|
||||
"bx-etsy": 61771,
|
||||
"bx-expo": 61772,
|
||||
"bx-express-js": 61773,
|
||||
"bx-facebook-circle": 61774,
|
||||
"bx-facebook-square": 61775,
|
||||
"bx-facebook": 61776,
|
||||
"bx-fastapi": 61777,
|
||||
"bx-fastify": 61778,
|
||||
"bx-figma-alt": 61779,
|
||||
"bx-figma": 61780,
|
||||
"bx-firebase": 61781,
|
||||
"bx-firefox": 61782,
|
||||
"bx-fiverr": 61783,
|
||||
"bx-flask-old": 61784,
|
||||
"bx-flask": 61785,
|
||||
"bx-flickr-square": 61786,
|
||||
"bx-flickr": 61787,
|
||||
"bx-flutter": 61788,
|
||||
"bx-foursquare": 61789,
|
||||
"bx-framer": 61790,
|
||||
"bx-gatsby-js": 61791,
|
||||
"bx-gemini": 61792,
|
||||
"bx-git": 61793,
|
||||
"bx-github-copilot": 61794,
|
||||
"bx-github": 61795,
|
||||
"bx-gitlab": 61796,
|
||||
"bx-gmail": 61797,
|
||||
"bx-go-lang": 61798,
|
||||
"bx-google-antigravity": 61799,
|
||||
"bx-google-cloud": 61800,
|
||||
"bx-google-pay": 61801,
|
||||
"bx-google": 61802,
|
||||
"bx-graphql": 61803,
|
||||
"bx-grok": 61804,
|
||||
"bx-groq-ai": 61805,
|
||||
"bx-gsap": 61806,
|
||||
"bx-gumroad": 61807,
|
||||
"bx-hashnode": 61808,
|
||||
"bx-hcaptcha": 61809,
|
||||
"bx-heroku": 61810,
|
||||
"bx-hono-js": 61811,
|
||||
"bx-html5": 61812,
|
||||
"bx-hugo": 61813,
|
||||
"bx-ibm": 61814,
|
||||
"bx-imdb": 61815,
|
||||
"bx-instagram-alt": 61816,
|
||||
"bx-instagram": 61817,
|
||||
"bx-internet-explorer": 61818,
|
||||
"bx-invision": 61819,
|
||||
"bx-java": 61820,
|
||||
"bx-javascript": 61821,
|
||||
"bx-joomla": 61822,
|
||||
"bx-jquery": 61823,
|
||||
"bx-jsfiddle": 61824,
|
||||
"bx-jwt": 61825,
|
||||
"bx-kick": 61826,
|
||||
"bx-kickstarter": 61827,
|
||||
"bx-kotlin": 61828,
|
||||
"bx-kubernetes": 61829,
|
||||
"bx-laravel": 61830,
|
||||
"bx-leetcode": 61831,
|
||||
"bx-lemon-squeezy": 61832,
|
||||
"bx-less": 61833,
|
||||
"bx-letterboxd": 61834,
|
||||
"bx-lichess": 61835,
|
||||
"bx-line-chat": 61836,
|
||||
"bx-linear-app": 61837,
|
||||
"bx-linkedin-square": 61838,
|
||||
"bx-linkedin": 61839,
|
||||
"bx-linktree": 61840,
|
||||
"bx-loom": 61841,
|
||||
"bx-lottie-files": 61842,
|
||||
"bx-lottie-lab": 61843,
|
||||
"bx-lovable": 61844,
|
||||
"bx-lyft": 61845,
|
||||
"bx-magento": 61846,
|
||||
"bx-mailchimp": 61847,
|
||||
"bx-markdown": 61848,
|
||||
"bx-mastercard": 61849,
|
||||
"bx-mastodon": 61850,
|
||||
"bx-mcp": 61851,
|
||||
"bx-medium-old": 61852,
|
||||
"bx-medium-square": 61853,
|
||||
"bx-medium": 61854,
|
||||
"bx-messenger": 61855,
|
||||
"bx-meta": 61856,
|
||||
"bx-microsoft-teams": 61857,
|
||||
"bx-microsoft-windows": 61858,
|
||||
"bx-microsoft": 61859,
|
||||
"bx-midjourney": 61860,
|
||||
"bx-mongodb": 61861,
|
||||
"bx-motion-js": 61862,
|
||||
"bx-mozilla": 61863,
|
||||
"bx-my-sql": 61864,
|
||||
"bx-neon-tech": 61865,
|
||||
"bx-neovim": 61866,
|
||||
"bx-nest-js": 61867,
|
||||
"bx-netlify": 61868,
|
||||
"bx-next-js": 61869,
|
||||
"bx-nodejs": 61870,
|
||||
"bx-notion": 61871,
|
||||
"bx-npm": 61872,
|
||||
"bx-nuxt-js": 61873,
|
||||
"bx-ok-ru": 61874,
|
||||
"bx-ollama": 61875,
|
||||
"bx-openai": 61876,
|
||||
"bx-opensea": 61877,
|
||||
"bx-opera": 61878,
|
||||
"bx-paddle-p": 61879,
|
||||
"bx-paper-design": 61880,
|
||||
"bx-patreon": 61881,
|
||||
"bx-payload-cms": 61882,
|
||||
"bx-paypal": 61883,
|
||||
"bx-periscope": 61884,
|
||||
"bx-perplexity-ai": 61885,
|
||||
"bx-php": 61886,
|
||||
"bx-pinterest-alt": 61887,
|
||||
"bx-pinterest": 61888,
|
||||
"bx-planetscale": 61889,
|
||||
"bx-play-store": 61890,
|
||||
"bx-playstation": 61891,
|
||||
"bx-pocket": 61892,
|
||||
"bx-polar": 61893,
|
||||
"bx-postgresql": 61894,
|
||||
"bx-prisma-orm": 61895,
|
||||
"bx-product-hunt": 61896,
|
||||
"bx-python": 61897,
|
||||
"bx-qdrant": 61898,
|
||||
"bx-qq": 61899,
|
||||
"bx-quora": 61900,
|
||||
"bx-radix-ui": 61901,
|
||||
"bx-railway": 61902,
|
||||
"bx-rasberry-pi": 61903,
|
||||
"bx-react-query": 61904,
|
||||
"bx-react-router": 61905,
|
||||
"bx-react": 61906,
|
||||
"bx-redbubble": 61907,
|
||||
"bx-reddit": 61908,
|
||||
"bx-redux": 61909,
|
||||
"bx-remix-js": 61910,
|
||||
"bx-replit": 61911,
|
||||
"bx-resend": 61912,
|
||||
"bx-roblox": 61913,
|
||||
"bx-sanity": 61914,
|
||||
"bx-sass": 61915,
|
||||
"bx-sentry": 61916,
|
||||
"bx-shadcn-ui": 61917,
|
||||
"bx-shopify": 61918,
|
||||
"bx-sketch": 61919,
|
||||
"bx-skype": 61920,
|
||||
"bx-slack-old": 61921,
|
||||
"bx-slack": 61922,
|
||||
"bx-snapchat": 61923,
|
||||
"bx-socket-io": 61924,
|
||||
"bx-soundcloud": 61925,
|
||||
"bx-spotify": 61926,
|
||||
"bx-spring-boot": 61927,
|
||||
"bx-squarespace": 61928,
|
||||
"bx-sst": 61929,
|
||||
"bx-stack-overflow": 61930,
|
||||
"bx-stackblitz": 61931,
|
||||
"bx-steam": 61932,
|
||||
"bx-stripe": 61933,
|
||||
"bx-supabase": 61934,
|
||||
"bx-svelte": 61935,
|
||||
"bx-tailwind-css": 61936,
|
||||
"bx-telegram": 61937,
|
||||
"bx-terraform": 61938,
|
||||
"bx-threads": 61939,
|
||||
"bx-three-js": 61940,
|
||||
"bx-tiktok": 61941,
|
||||
"bx-trello": 61942,
|
||||
"bx-trip-advisor": 61943,
|
||||
"bx-trpc": 61944,
|
||||
"bx-trustpilot": 61945,
|
||||
"bx-tumblr": 61946,
|
||||
"bx-tux": 61947,
|
||||
"bx-twitch": 61948,
|
||||
"bx-twitter-x": 61949,
|
||||
"bx-twitter": 61950,
|
||||
"bx-typescript": 61951,
|
||||
"bx-uber": 61952,
|
||||
"bx-ubuntu": 61953,
|
||||
"bx-udacity": 61954,
|
||||
"bx-union-pay": 61955,
|
||||
"bx-unity": 61956,
|
||||
"bx-unsplash": 61957,
|
||||
"bx-upi": 61958,
|
||||
"bx-upwork": 61959,
|
||||
"bx-v0": 61960,
|
||||
"bx-venmo": 61961,
|
||||
"bx-vercel": 61962,
|
||||
"bx-vimeo": 61963,
|
||||
"bx-visa": 61964,
|
||||
"bx-visual-studio": 61965,
|
||||
"bx-vite-js": 61966,
|
||||
"bx-vk": 61967,
|
||||
"bx-vuejs": 61968,
|
||||
"bx-waze": 61969,
|
||||
"bx-web-components": 61970,
|
||||
"bx-webflow": 61971,
|
||||
"bx-wechat": 61972,
|
||||
"bx-weibo": 61973,
|
||||
"bx-whatsapp-square": 61974,
|
||||
"bx-whatsapp": 61975,
|
||||
"bx-wikipedia": 61976,
|
||||
"bx-windsurf": 61977,
|
||||
"bx-wix": 61978,
|
||||
"bx-wordpress": 61979,
|
||||
"bx-work-os": 61980,
|
||||
"bx-xai": 61981,
|
||||
"bx-xbox": 61982,
|
||||
"bx-xing": 61983,
|
||||
"bx-yahoo": 61984,
|
||||
"bx-yarn": 61985,
|
||||
"bx-yelp": 61986,
|
||||
"bx-youtube-music": 61987,
|
||||
"bx-youtube": 61988,
|
||||
"bx-zen-browser": 61989,
|
||||
"bx-zoom-workplace": 61990
|
||||
}
|
||||