Mind Palace Layout
This commit is contained in:
commit
18ab287dc5
58 changed files with 52945 additions and 0 deletions
6
.obsidian/app.json
vendored
Normal file
6
.obsidian/app.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"alwaysUpdateLinks": true,
|
||||
"attachmentFolderPath": "Resources/Assets",
|
||||
"newFileLocation": "folder",
|
||||
"newFileFolderPath": "Scratchpad"
|
||||
}
|
||||
5
.obsidian/appearance.json
vendored
Normal file
5
.obsidian/appearance.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"cssTheme": "AnuPpuccin",
|
||||
"theme": "moonstone",
|
||||
"textFontFamily": "NewYork"
|
||||
}
|
||||
14
.obsidian/community-plugins.json
vendored
Normal file
14
.obsidian/community-plugins.json
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
"obsidian-style-settings",
|
||||
"periodic-notes",
|
||||
"calendar",
|
||||
"obsidian-auto-link-title",
|
||||
"hotkey-helper",
|
||||
"obsidian-git",
|
||||
"obsidian-hover-editor",
|
||||
"link-favicon",
|
||||
"nldates-redux",
|
||||
"url-into-selection",
|
||||
"obsidian42-brat",
|
||||
"simple-embeds"
|
||||
]
|
||||
33
.obsidian/core-plugins.json
vendored
Normal file
33
.obsidian/core-plugins.json
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"file-explorer": true,
|
||||
"global-search": true,
|
||||
"switcher": true,
|
||||
"graph": true,
|
||||
"backlink": true,
|
||||
"canvas": true,
|
||||
"outgoing-link": true,
|
||||
"tag-pane": true,
|
||||
"footnotes": false,
|
||||
"properties": true,
|
||||
"page-preview": true,
|
||||
"daily-notes": true,
|
||||
"templates": true,
|
||||
"note-composer": true,
|
||||
"command-palette": true,
|
||||
"slash-command": false,
|
||||
"editor-status": true,
|
||||
"bookmarks": true,
|
||||
"markdown-importer": false,
|
||||
"zk-prefixer": false,
|
||||
"random-note": false,
|
||||
"outline": true,
|
||||
"word-count": true,
|
||||
"slides": false,
|
||||
"audio-recorder": false,
|
||||
"workspaces": false,
|
||||
"file-recovery": true,
|
||||
"publish": false,
|
||||
"sync": true,
|
||||
"bases": true,
|
||||
"webviewer": false
|
||||
}
|
||||
22
.obsidian/graph.json
vendored
Normal file
22
.obsidian/graph.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"collapse-filter": true,
|
||||
"search": "",
|
||||
"showTags": false,
|
||||
"showAttachments": false,
|
||||
"hideUnresolved": false,
|
||||
"showOrphans": true,
|
||||
"collapse-color-groups": true,
|
||||
"colorGroups": [],
|
||||
"collapse-display": true,
|
||||
"showArrow": false,
|
||||
"textFadeMultiplier": 0,
|
||||
"nodeSizeMultiplier": 1,
|
||||
"lineSizeMultiplier": 1,
|
||||
"collapse-forces": true,
|
||||
"centerStrength": 0.518713248970312,
|
||||
"repelStrength": 10,
|
||||
"linkStrength": 1,
|
||||
"linkDistance": 250,
|
||||
"scale": 1,
|
||||
"close": true
|
||||
}
|
||||
11
.obsidian/hotkeys.json
vendored
Normal file
11
.obsidian/hotkeys.json
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"periodic-notes:open-daily-note": [
|
||||
{
|
||||
"modifiers": [
|
||||
"Mod"
|
||||
],
|
||||
"key": "D"
|
||||
}
|
||||
],
|
||||
"editor:delete-paragraph": []
|
||||
}
|
||||
10
.obsidian/plugins/calendar/data.json
vendored
Normal file
10
.obsidian/plugins/calendar/data.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"shouldConfirmBeforeCreate": true,
|
||||
"weekStart": "locale",
|
||||
"wordsPerDot": 250,
|
||||
"showWeeklyNote": false,
|
||||
"weeklyNoteFormat": "",
|
||||
"weeklyNoteTemplate": "",
|
||||
"weeklyNoteFolder": "",
|
||||
"localeOverride": "system-default"
|
||||
}
|
||||
4459
.obsidian/plugins/calendar/main.js
vendored
Normal file
4459
.obsidian/plugins/calendar/main.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
10
.obsidian/plugins/calendar/manifest.json
vendored
Normal file
10
.obsidian/plugins/calendar/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "calendar",
|
||||
"name": "Calendar",
|
||||
"description": "Calendar view of your daily notes",
|
||||
"version": "1.5.10",
|
||||
"author": "Liam Cain",
|
||||
"authorUrl": "https://github.com/liamcain/",
|
||||
"isDesktopOnly": false,
|
||||
"minAppVersion": "0.9.11"
|
||||
}
|
||||
4
.obsidian/plugins/hotkey-helper/main.js
vendored
Normal file
4
.obsidian/plugins/hotkey-helper/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
9
.obsidian/plugins/hotkey-helper/manifest.json
vendored
Normal file
9
.obsidian/plugins/hotkey-helper/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"id": "hotkey-helper",
|
||||
"name": "Hotkey Helper",
|
||||
"version": "0.3.21",
|
||||
"minAppVersion": "1.5.8",
|
||||
"description": "Easily see and access any plugin's settings or hotkey assignments (and conflicts) from the Community Plugins tab",
|
||||
"author": "PJ Eby",
|
||||
"authorUrl": "https://github.com/pjeby"
|
||||
}
|
||||
7
.obsidian/plugins/hotkey-helper/styles.css
vendored
Normal file
7
.obsidian/plugins/hotkey-helper/styles.css
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.clickable-icon.mod-error,
|
||||
.modal .community-plugin-info button.mod-error,
|
||||
.modal-container .mod-community-plugin .community-modal-button-container button.mod-error {
|
||||
background-color: var(--background-modifier-error);
|
||||
}
|
||||
|
||||
.community-plugin-info > p > button { margin-top: 6px; margin-bottom: 6px;}
|
||||
18
.obsidian/plugins/link-favicon/main.js
vendored
Normal file
18
.obsidian/plugins/link-favicon/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
.obsidian/plugins/link-favicon/manifest.json
vendored
Normal file
10
.obsidian/plugins/link-favicon/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "link-favicon",
|
||||
"name": "Link Favicons",
|
||||
"version": "1.8.5",
|
||||
"minAppVersion": "1.12.0",
|
||||
"description": "See the favicon for a linked website. ",
|
||||
"author": "Johannes Theiner",
|
||||
"authorUrl": "https://github.com/joethei",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
7
.obsidian/plugins/link-favicon/styles.css
vendored
Normal file
7
.obsidian/plugins/link-favicon/styles.css
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||||
if you want to view the source, please visit the github repository of this plugin
|
||||
https://github.com/joethei/obisidian-link-favicon
|
||||
*/
|
||||
|
||||
.link-favicon{cursor:pointer!important;image-rendering:-webkit-optimize-contrast;margin-bottom:.3em;margin-left:.1em;margin-right:.1em;max-height:1em;vertical-align:bottom}.link-favicon-preview{font-size:50px;text-align:center}.link-favicon-preview img{height:50px}.link-favicon[data-color-inversion=true][data-is-readable-a-a=false]{filter:hue-rotate(180deg) invert(1)}.link-favicon-scrollable-content{height:60vh;overflow:auto}
|
||||
4
.obsidian/plugins/nldates-redux/main.js
vendored
Normal file
4
.obsidian/plugins/nldates-redux/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
11
.obsidian/plugins/nldates-redux/manifest.json
vendored
Normal file
11
.obsidian/plugins/nldates-redux/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"id": "nldates-redux",
|
||||
"name": "Natural Language Dates Redux",
|
||||
"description": "Work with dates in natural language. Now with Notion-like behavior!",
|
||||
"version": "0.8.28",
|
||||
"author": "Tommy Bergeron",
|
||||
"authorUrl": "https://github.com/tbergeron",
|
||||
"fundingUrl": "https://www.paypal.com/donate/?hosted_button_id=93Z9BUUD778SG",
|
||||
"isDesktopOnly": false,
|
||||
"minAppVersion": "1.4.0"
|
||||
}
|
||||
771
.obsidian/plugins/obsidian-auto-link-title/main.js
vendored
Normal file
771
.obsidian/plugins/obsidian-auto-link-title/main.js
vendored
Normal file
|
|
@ -0,0 +1,771 @@
|
|||
/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
|
||||
if you want to view the source visit the plugins github repository
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var obsidian = require('obsidian');
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
||||
var e = new Error(message);
|
||||
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
||||
};
|
||||
|
||||
const DEFAULT_SETTINGS = {
|
||||
regex: /^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$/i,
|
||||
lineRegex: /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi,
|
||||
linkRegex: /^\[([^\[\]]*)\]\((https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})\)$/i,
|
||||
linkLineRegex: /\[([^\[\]]*)\]\((https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})\)/gi,
|
||||
imageRegex: /\.(gif|jpe?g|tiff?|png|webp|bmp|tga|psd|ai)$/i,
|
||||
enhanceDefaultPaste: true,
|
||||
shouldPreserveSelectionAsTitle: false,
|
||||
enhanceDropEvents: true,
|
||||
websiteBlacklist: "",
|
||||
maximumTitleLength: 0,
|
||||
useNewScraper: false,
|
||||
linkPreviewApiKey: "",
|
||||
useBetterPasteId: false,
|
||||
};
|
||||
class AutoLinkTitleSettingTab extends obsidian.PluginSettingTab {
|
||||
constructor(app, plugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
display() {
|
||||
let { containerEl } = this;
|
||||
containerEl.empty();
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("Enhance Default Paste")
|
||||
.setDesc("Fetch the link title when pasting a link in the editor with the default paste command")
|
||||
.addToggle((val) => val
|
||||
.setValue(this.plugin.settings.enhanceDefaultPaste)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(value);
|
||||
this.plugin.settings.enhanceDefaultPaste = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("Enhance Drop Events")
|
||||
.setDesc("Fetch the link title when drag and dropping a link from another program")
|
||||
.addToggle((val) => val
|
||||
.setValue(this.plugin.settings.enhanceDropEvents)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(value);
|
||||
this.plugin.settings.enhanceDropEvents = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("Maximum title length")
|
||||
.setDesc("Set the maximum length of the title. Set to 0 to disable.")
|
||||
.addText((val) => val
|
||||
.setValue(this.plugin.settings.maximumTitleLength.toString(10))
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
const titleLength = Number(value);
|
||||
this.plugin.settings.maximumTitleLength =
|
||||
isNaN(titleLength) || titleLength < 0 ? 0 : titleLength;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("Preserve selection as title")
|
||||
.setDesc("Whether to prefer selected text as title over fetched title when pasting")
|
||||
.addToggle((val) => val
|
||||
.setValue(this.plugin.settings.shouldPreserveSelectionAsTitle)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(value);
|
||||
this.plugin.settings.shouldPreserveSelectionAsTitle = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("Website Blacklist")
|
||||
.setDesc("List of strings (comma separated) that disable autocompleting website titles. Can be URLs or arbitrary text.")
|
||||
.addTextArea((val) => val
|
||||
.setValue(this.plugin.settings.websiteBlacklist)
|
||||
.setPlaceholder("localhost, tiktok.com")
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
this.plugin.settings.websiteBlacklist = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("Use New Scraper")
|
||||
.setDesc("Use experimental new scraper, seems to work well on desktop but not mobile.")
|
||||
.addToggle((val) => val
|
||||
.setValue(this.plugin.settings.useNewScraper)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(value);
|
||||
this.plugin.settings.useNewScraper = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("Use Better Fetching Placeholder")
|
||||
.setDesc("Use a more readable placeholder when fetching the title of a link.")
|
||||
.addToggle((val) => val
|
||||
.setValue(this.plugin.settings.useBetterPasteId)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
console.log(value);
|
||||
this.plugin.settings.useBetterPasteId = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName("LinkPreview API Key")
|
||||
.setDesc("API key for the LinkPreview.net service. Get one at https://my.linkpreview.net/access_keys")
|
||||
.addText((text) => text
|
||||
.setValue(this.plugin.settings.linkPreviewApiKey || "")
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
const trimmedValue = value.trim();
|
||||
if (trimmedValue.length > 0 && trimmedValue.length !== 32) {
|
||||
new obsidian.Notice("LinkPreview API key must be 32 characters long");
|
||||
this.plugin.settings.linkPreviewApiKey = "";
|
||||
}
|
||||
else {
|
||||
this.plugin.settings.linkPreviewApiKey = trimmedValue;
|
||||
}
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
class CheckIf {
|
||||
static isMarkdownLinkAlready(editor) {
|
||||
let cursor = editor.getCursor();
|
||||
// Check if the characters before the url are ]( to indicate a markdown link
|
||||
var titleEnd = editor.getRange({ ch: cursor.ch - 2, line: cursor.line }, { ch: cursor.ch, line: cursor.line });
|
||||
return titleEnd == "](";
|
||||
}
|
||||
static isAfterQuote(editor) {
|
||||
let cursor = editor.getCursor();
|
||||
// Check if the characters before the url are " or ' to indicate we want the url directly
|
||||
// This is common in elements like <a href="linkhere"></a>
|
||||
var beforeChar = editor.getRange({ ch: cursor.ch - 1, line: cursor.line }, { ch: cursor.ch, line: cursor.line });
|
||||
return beforeChar == "\"" || beforeChar == "'";
|
||||
}
|
||||
static isUrl(text) {
|
||||
let urlRegex = new RegExp(DEFAULT_SETTINGS.regex);
|
||||
return urlRegex.test(text);
|
||||
}
|
||||
static isImage(text) {
|
||||
let imageRegex = new RegExp(DEFAULT_SETTINGS.imageRegex);
|
||||
return imageRegex.test(text);
|
||||
}
|
||||
static isLinkedUrl(text) {
|
||||
let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex);
|
||||
return urlRegex.test(text);
|
||||
}
|
||||
}
|
||||
|
||||
class EditorExtensions {
|
||||
static getSelectedText(editor) {
|
||||
if (!editor.somethingSelected()) {
|
||||
let wordBoundaries = this.getWordBoundaries(editor);
|
||||
editor.setSelection(wordBoundaries.start, wordBoundaries.end);
|
||||
}
|
||||
return editor.getSelection();
|
||||
}
|
||||
static cursorWithinBoundaries(cursor, match) {
|
||||
let startIndex = match.index;
|
||||
let endIndex = match.index + match[0].length;
|
||||
return startIndex <= cursor.ch && cursor.ch <= endIndex;
|
||||
}
|
||||
static getWordBoundaries(editor) {
|
||||
let cursor = editor.getCursor();
|
||||
// If its a normal URL token this is not a markdown link
|
||||
// In this case we can simply overwrite the link boundaries as-is
|
||||
let lineText = editor.getLine(cursor.line);
|
||||
// First check if we're in a link
|
||||
let linksInLine = lineText.matchAll(DEFAULT_SETTINGS.linkLineRegex);
|
||||
for (let match of linksInLine) {
|
||||
if (this.cursorWithinBoundaries(cursor, match)) {
|
||||
return {
|
||||
start: { line: cursor.line, ch: match.index },
|
||||
end: { line: cursor.line, ch: match.index + match[0].length },
|
||||
};
|
||||
}
|
||||
}
|
||||
// If not, check if we're in just a standard ol' URL.
|
||||
let urlsInLine = lineText.matchAll(DEFAULT_SETTINGS.lineRegex);
|
||||
for (let match of urlsInLine) {
|
||||
if (this.cursorWithinBoundaries(cursor, match)) {
|
||||
return {
|
||||
start: { line: cursor.line, ch: match.index },
|
||||
end: { line: cursor.line, ch: match.index + match[0].length },
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
start: cursor,
|
||||
end: cursor,
|
||||
};
|
||||
}
|
||||
static getEditorPositionFromIndex(content, index) {
|
||||
let substr = content.substr(0, index);
|
||||
let l = 0;
|
||||
let offset = -1;
|
||||
let r = -1;
|
||||
for (; (r = substr.indexOf("\n", r + 1)) !== -1; l++, offset = r)
|
||||
;
|
||||
offset += 1;
|
||||
let ch = content.substr(offset, index - offset).length;
|
||||
return { line: l, ch: ch };
|
||||
}
|
||||
}
|
||||
|
||||
function blank$1(text) {
|
||||
return text === undefined || text === null || text === '';
|
||||
}
|
||||
function notBlank$1(text) {
|
||||
return !blank$1(text);
|
||||
}
|
||||
function scrape(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const response = yield obsidian.requestUrl(url);
|
||||
if (!response.headers['content-type'].includes('text/html'))
|
||||
return getUrlFinalSegment$1(url);
|
||||
const html = response.text;
|
||||
const doc = new DOMParser().parseFromString(html, 'text/html');
|
||||
const title = doc.querySelector('title');
|
||||
if (blank$1(title === null || title === void 0 ? void 0 : title.innerText)) {
|
||||
// If site is javascript based and has a no-title attribute when unloaded, use it.
|
||||
var noTitle = title === null || title === void 0 ? void 0 : title.getAttr('no-title');
|
||||
if (notBlank$1(noTitle)) {
|
||||
return noTitle;
|
||||
}
|
||||
// Otherwise if the site has no title/requires javascript simply return Title Unknown
|
||||
return url;
|
||||
}
|
||||
return title.innerText;
|
||||
}
|
||||
catch (ex) {
|
||||
console.error(ex);
|
||||
return '';
|
||||
}
|
||||
});
|
||||
}
|
||||
function getUrlFinalSegment$1(url) {
|
||||
try {
|
||||
const segments = new URL(url).pathname.split('/');
|
||||
const last = segments.pop() || segments.pop(); // Handle potential trailing slash
|
||||
return last;
|
||||
}
|
||||
catch (_) {
|
||||
return 'File';
|
||||
}
|
||||
}
|
||||
function getPageTitle$1(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!(url.startsWith('http') || url.startsWith('https'))) {
|
||||
url = 'https://' + url;
|
||||
}
|
||||
return scrape(url);
|
||||
});
|
||||
}
|
||||
|
||||
const electronPkg = require("electron");
|
||||
function blank(text) {
|
||||
return text === undefined || text === null || text === "";
|
||||
}
|
||||
function notBlank(text) {
|
||||
return !blank(text);
|
||||
}
|
||||
// async wrapper to load a url and settle on load finish or fail
|
||||
function load(window, url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.webContents.on("did-finish-load", (event) => resolve(event));
|
||||
window.webContents.on("did-fail-load", (event) => reject(event));
|
||||
window.loadURL(url);
|
||||
});
|
||||
});
|
||||
}
|
||||
function electronGetPageTitle(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { remote } = electronPkg;
|
||||
const { BrowserWindow } = remote;
|
||||
try {
|
||||
const window = new BrowserWindow({
|
||||
width: 1000,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
nodeIntegration: true,
|
||||
images: false,
|
||||
},
|
||||
show: false,
|
||||
});
|
||||
window.webContents.setAudioMuted(true);
|
||||
window.webContents.on("will-navigate", (event, newUrl) => {
|
||||
event.preventDefault();
|
||||
window.loadURL(newUrl);
|
||||
});
|
||||
yield load(window, url);
|
||||
try {
|
||||
const title = window.webContents.getTitle();
|
||||
window.destroy();
|
||||
if (notBlank(title)) {
|
||||
return title;
|
||||
}
|
||||
else {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
window.destroy();
|
||||
return url;
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
console.error(ex);
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
function nonElectronGetPageTitle(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const html = yield obsidian.request({ url });
|
||||
const doc = new DOMParser().parseFromString(html, "text/html");
|
||||
const title = doc.querySelectorAll("title")[0];
|
||||
if (title == null || blank(title === null || title === void 0 ? void 0 : title.innerText)) {
|
||||
// If site is javascript based and has a no-title attribute when unloaded, use it.
|
||||
var noTitle = title === null || title === void 0 ? void 0 : title.getAttr("no-title");
|
||||
if (notBlank(noTitle)) {
|
||||
return noTitle;
|
||||
}
|
||||
// Otherwise if the site has no title/requires javascript simply return Title Unknown
|
||||
return url;
|
||||
}
|
||||
return title.innerText;
|
||||
}
|
||||
catch (ex) {
|
||||
console.error(ex);
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
function getUrlFinalSegment(url) {
|
||||
try {
|
||||
const segments = new URL(url).pathname.split('/');
|
||||
const last = segments.pop() || segments.pop(); // Handle potential trailing slash
|
||||
return last;
|
||||
}
|
||||
catch (_) {
|
||||
return "File";
|
||||
}
|
||||
}
|
||||
function tryGetFileType(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const response = yield fetch(url, { method: "HEAD" });
|
||||
// Ensure site returns an ok status code before scraping
|
||||
if (!response.ok) {
|
||||
return "Site Unreachable";
|
||||
}
|
||||
// Ensure site is an actual HTML page and not a pdf or 3 gigabyte video file.
|
||||
let contentType = response.headers.get("content-type");
|
||||
if (!contentType.includes("text/html")) {
|
||||
return getUrlFinalSegment(url);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (err) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
function getPageTitle(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// If we're on Desktop use the Electron scraper
|
||||
if (!(url.startsWith("http") || url.startsWith("https"))) {
|
||||
url = "https://" + url;
|
||||
}
|
||||
// Try to do a HEAD request to see if the site is reachable and if it's an HTML page
|
||||
// If we error out due to CORS, we'll just try to scrape the page anyway.
|
||||
let fileType = yield tryGetFileType(url);
|
||||
if (fileType) {
|
||||
return fileType;
|
||||
}
|
||||
if (electronPkg != null) {
|
||||
return electronGetPageTitle(url);
|
||||
}
|
||||
else {
|
||||
return nonElectronGetPageTitle(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class AutoLinkTitle extends obsidian.Plugin {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.shortTitle = (title) => {
|
||||
if (this.settings.maximumTitleLength === 0) {
|
||||
return title;
|
||||
}
|
||||
if (title.length < this.settings.maximumTitleLength + 3) {
|
||||
return title;
|
||||
}
|
||||
const shortenedTitle = `${title.slice(0, this.settings.maximumTitleLength)}...`;
|
||||
return shortenedTitle;
|
||||
};
|
||||
}
|
||||
onload() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log("loading obsidian-auto-link-title");
|
||||
yield this.loadSettings();
|
||||
this.blacklist = this.settings.websiteBlacklist
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s.length > 0);
|
||||
// Listen to paste event
|
||||
this.pasteFunction = this.pasteUrlWithTitle.bind(this);
|
||||
// Listen to drop event
|
||||
this.dropFunction = this.dropUrlWithTitle.bind(this);
|
||||
this.addCommand({
|
||||
id: "auto-link-title-paste",
|
||||
name: "Paste URL and auto fetch title",
|
||||
editorCallback: (editor) => this.manualPasteUrlWithTitle(editor),
|
||||
hotkeys: [],
|
||||
});
|
||||
this.addCommand({
|
||||
id: "auto-link-title-normal-paste",
|
||||
name: "Normal paste (no fetching behavior)",
|
||||
editorCallback: (editor) => this.normalPaste(editor),
|
||||
hotkeys: [
|
||||
{
|
||||
modifiers: ["Mod", "Shift"],
|
||||
key: "v",
|
||||
},
|
||||
],
|
||||
});
|
||||
this.registerEvent(this.app.workspace.on("editor-paste", this.pasteFunction));
|
||||
this.registerEvent(this.app.workspace.on("editor-drop", this.dropFunction));
|
||||
this.addCommand({
|
||||
id: "enhance-url-with-title",
|
||||
name: "Enhance existing URL with link and title",
|
||||
editorCallback: (editor) => this.addTitleToLink(editor),
|
||||
hotkeys: [
|
||||
{
|
||||
modifiers: ["Mod", "Shift"],
|
||||
key: "e",
|
||||
},
|
||||
],
|
||||
});
|
||||
this.addSettingTab(new AutoLinkTitleSettingTab(this.app, this));
|
||||
});
|
||||
}
|
||||
addTitleToLink(editor) {
|
||||
// Only attempt fetch if online
|
||||
if (!navigator.onLine)
|
||||
return;
|
||||
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
|
||||
// If the cursor is on a raw html link, convert to a markdown link and fetch title
|
||||
if (CheckIf.isUrl(selectedText)) {
|
||||
this.convertUrlToTitledLink(editor, selectedText);
|
||||
}
|
||||
// If the cursor is on the URL part of a markdown link, fetch title and replace existing link title
|
||||
else if (CheckIf.isLinkedUrl(selectedText)) {
|
||||
const link = this.getUrlFromLink(selectedText);
|
||||
this.convertUrlToTitledLink(editor, link);
|
||||
}
|
||||
}
|
||||
normalPaste(editor) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let clipboardText = yield navigator.clipboard.readText();
|
||||
if (clipboardText === null || clipboardText === "")
|
||||
return;
|
||||
editor.replaceSelection(clipboardText);
|
||||
});
|
||||
}
|
||||
// Simulate standard paste but using editor.replaceSelection with clipboard text since we can't seem to dispatch a paste event.
|
||||
manualPasteUrlWithTitle(editor) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const clipboardText = yield navigator.clipboard.readText();
|
||||
// Only attempt fetch if online
|
||||
if (!navigator.onLine) {
|
||||
editor.replaceSelection(clipboardText);
|
||||
return;
|
||||
}
|
||||
if (clipboardText == null || clipboardText == "")
|
||||
return;
|
||||
// If its not a URL, we return false to allow the default paste handler to take care of it.
|
||||
// Similarly, image urls don't have a meaningful <title> attribute so downloading it
|
||||
// to fetch the title is a waste of bandwidth.
|
||||
if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) {
|
||||
editor.replaceSelection(clipboardText);
|
||||
return;
|
||||
}
|
||||
// If it looks like we're pasting the url into a markdown link already, don't fetch title
|
||||
// as the user has already probably put a meaningful title, also it would lead to the title
|
||||
// being inside the link.
|
||||
if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) {
|
||||
editor.replaceSelection(clipboardText);
|
||||
return;
|
||||
}
|
||||
// If url is pasted over selected text and setting is enabled, no need to fetch title,
|
||||
// just insert a link
|
||||
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
|
||||
if (selectedText && this.settings.shouldPreserveSelectionAsTitle) {
|
||||
editor.replaceSelection(`[${selectedText}](${clipboardText})`);
|
||||
return;
|
||||
}
|
||||
// At this point we're just pasting a link in a normal fashion, fetch its title.
|
||||
this.convertUrlToTitledLink(editor, clipboardText);
|
||||
return;
|
||||
});
|
||||
}
|
||||
pasteUrlWithTitle(clipboard, editor) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!this.settings.enhanceDefaultPaste) {
|
||||
return;
|
||||
}
|
||||
if (clipboard.defaultPrevented)
|
||||
return;
|
||||
// Only attempt fetch if online
|
||||
if (!navigator.onLine)
|
||||
return;
|
||||
let clipboardText = clipboard.clipboardData.getData("text/plain");
|
||||
if (clipboardText === null || clipboardText === "")
|
||||
return;
|
||||
// If its not a URL, we return false to allow the default paste handler to take care of it.
|
||||
// Similarly, image urls don't have a meaningful <title> attribute so downloading it
|
||||
// to fetch the title is a waste of bandwidth.
|
||||
if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) {
|
||||
return;
|
||||
}
|
||||
// We've decided to handle the paste, stop propagation to the default handler.
|
||||
clipboard.stopPropagation();
|
||||
clipboard.preventDefault();
|
||||
// If it looks like we're pasting the url into a markdown link already, don't fetch title
|
||||
// as the user has already probably put a meaningful title, also it would lead to the title
|
||||
// being inside the link.
|
||||
if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) {
|
||||
editor.replaceSelection(clipboardText);
|
||||
return;
|
||||
}
|
||||
// If url is pasted over selected text and setting is enabled, no need to fetch title,
|
||||
// just insert a link
|
||||
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
|
||||
if (selectedText && this.settings.shouldPreserveSelectionAsTitle) {
|
||||
editor.replaceSelection(`[${selectedText}](${clipboardText})`);
|
||||
return;
|
||||
}
|
||||
// At this point we're just pasting a link in a normal fashion, fetch its title.
|
||||
this.convertUrlToTitledLink(editor, clipboardText);
|
||||
return;
|
||||
});
|
||||
}
|
||||
dropUrlWithTitle(dropEvent, editor) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!this.settings.enhanceDropEvents) {
|
||||
return;
|
||||
}
|
||||
if (dropEvent.defaultPrevented)
|
||||
return;
|
||||
// Only attempt fetch if online
|
||||
if (!navigator.onLine)
|
||||
return;
|
||||
let dropText = dropEvent.dataTransfer.getData("text/plain");
|
||||
if (dropText === null || dropText === "")
|
||||
return;
|
||||
// If its not a URL, we return false to allow the default paste handler to take care of it.
|
||||
// Similarly, image urls don't have a meaningful <title> attribute so downloading it
|
||||
// to fetch the title is a waste of bandwidth.
|
||||
if (!CheckIf.isUrl(dropText) || CheckIf.isImage(dropText)) {
|
||||
return;
|
||||
}
|
||||
// We've decided to handle the paste, stop propagation to the default handler.
|
||||
dropEvent.stopPropagation();
|
||||
dropEvent.preventDefault();
|
||||
// If it looks like we're pasting the url into a markdown link already, don't fetch title
|
||||
// as the user has already probably put a meaningful title, also it would lead to the title
|
||||
// being inside the link.
|
||||
if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) {
|
||||
editor.replaceSelection(dropText);
|
||||
return;
|
||||
}
|
||||
// If url is pasted over selected text and setting is enabled, no need to fetch title,
|
||||
// just insert a link
|
||||
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
|
||||
if (selectedText && this.settings.shouldPreserveSelectionAsTitle) {
|
||||
editor.replaceSelection(`[${selectedText}](${dropText})`);
|
||||
return;
|
||||
}
|
||||
// At this point we're just pasting a link in a normal fashion, fetch its title.
|
||||
this.convertUrlToTitledLink(editor, dropText);
|
||||
return;
|
||||
});
|
||||
}
|
||||
isBlacklisted(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.loadSettings();
|
||||
this.blacklist = this.settings.websiteBlacklist
|
||||
.split(/,|\n/)
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s.length > 0);
|
||||
return this.blacklist.some((site) => url.includes(site));
|
||||
});
|
||||
}
|
||||
convertUrlToTitledLink(editor, url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (yield this.isBlacklisted(url)) {
|
||||
let domain = new URL(url).hostname;
|
||||
editor.replaceSelection(`[${domain}](${url})`);
|
||||
return;
|
||||
}
|
||||
// Generate a unique id for find/replace operations for the title.
|
||||
const pasteId = this.getPasteId();
|
||||
// Instantly paste so you don't wonder if paste is broken
|
||||
editor.replaceSelection(`[${pasteId}](${url})`);
|
||||
// Fetch title from site, replace Fetching Title with actual title
|
||||
const title = yield this.fetchUrlTitle(url);
|
||||
const escapedTitle = this.escapeMarkdown(title);
|
||||
const shortenedTitle = this.shortTitle(escapedTitle);
|
||||
const text = editor.getValue();
|
||||
const start = text.indexOf(pasteId);
|
||||
if (start < 0) {
|
||||
console.log(`Unable to find text "${pasteId}" in current editor, bailing out; link ${url}`);
|
||||
}
|
||||
else {
|
||||
const end = start + pasteId.length;
|
||||
const startPos = EditorExtensions.getEditorPositionFromIndex(text, start);
|
||||
const endPos = EditorExtensions.getEditorPositionFromIndex(text, end);
|
||||
editor.replaceRange(shortenedTitle, startPos, endPos);
|
||||
}
|
||||
});
|
||||
}
|
||||
escapeMarkdown(text) {
|
||||
var unescaped = text.replace(/\\(\*|_|`|~|\\|\[|\])/g, "$1"); // unescape any "backslashed" character
|
||||
var escaped = unescaped.replace(/(\*|_|`|<|>|~|\\|\[|\])/g, "\\$1"); // escape *, _, `, ~, \, [, ], <, and >
|
||||
var escaped = unescaped.replace(/(\*|_|`|\||<|>|~|\\|\[|\])/g, "\\$1"); // escape *, _, `, ~, \, |, [, ], <, and >
|
||||
return escaped;
|
||||
}
|
||||
fetchUrlTitleViaLinkPreview(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.settings.linkPreviewApiKey.length !== 32) {
|
||||
console.error("LinkPreview API key is not 32 characters long, please check your settings");
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
const apiEndpoint = `https://api.linkpreview.net/?q=${encodeURIComponent(url)}`;
|
||||
const response = yield fetch(apiEndpoint, {
|
||||
headers: {
|
||||
"X-Linkpreview-Api-Key": this.settings.linkPreviewApiKey,
|
||||
},
|
||||
});
|
||||
const data = yield response.json();
|
||||
return data.title;
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
fetchUrlTitle(url) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
let title = "";
|
||||
title = yield this.fetchUrlTitleViaLinkPreview(url);
|
||||
console.log(`Title via Link Preview: ${title}`);
|
||||
if (title === "") {
|
||||
console.log("Title via Link Preview failed, falling back to scraper");
|
||||
if (this.settings.useNewScraper) {
|
||||
console.log("Using new scraper");
|
||||
title = yield getPageTitle$1(url);
|
||||
}
|
||||
else {
|
||||
console.log("Using old scraper");
|
||||
title = yield getPageTitle(url);
|
||||
}
|
||||
}
|
||||
console.log(`Title: ${title}`);
|
||||
title =
|
||||
title.replace(/(\r\n|\n|\r)/gm, "").trim() ||
|
||||
"Title Unavailable | Site Unreachable";
|
||||
return title;
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
return "Error fetching title";
|
||||
}
|
||||
});
|
||||
}
|
||||
getUrlFromLink(link) {
|
||||
let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex);
|
||||
return urlRegex.exec(link)[2];
|
||||
}
|
||||
getPasteId() {
|
||||
var base = "Fetching Title";
|
||||
if (this.settings.useBetterPasteId) {
|
||||
return this.getBetterPasteId(base);
|
||||
}
|
||||
else {
|
||||
return `${base}#${this.createBlockHash()}`;
|
||||
}
|
||||
}
|
||||
getBetterPasteId(base) {
|
||||
// After every character, add 0, 1 or 2 invisible characters
|
||||
// so that to the user it looks just like the base string.
|
||||
// The number of combinations is 3^14 = 4782969
|
||||
let result = "";
|
||||
var invisibleCharacter = "\u200B";
|
||||
var maxInvisibleCharacters = 2;
|
||||
for (var i = 0; i < base.length; i++) {
|
||||
var count = Math.floor(Math.random() * (maxInvisibleCharacters + 1));
|
||||
result += base.charAt(i) + invisibleCharacter.repeat(count);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Custom hashid by @shabegom
|
||||
createBlockHash() {
|
||||
let result = "";
|
||||
var characters = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
var charactersLength = characters.length;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
onunload() {
|
||||
console.log("unloading obsidian-auto-link-title");
|
||||
}
|
||||
loadSettings() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
|
||||
});
|
||||
}
|
||||
saveSettings() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.saveData(this.settings);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AutoLinkTitle;
|
||||
|
||||
|
||||
/* nosourcemap */
|
||||
10
.obsidian/plugins/obsidian-auto-link-title/manifest.json
vendored
Normal file
10
.obsidian/plugins/obsidian-auto-link-title/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "obsidian-auto-link-title",
|
||||
"name": "Auto Link Title",
|
||||
"version": "1.5.5",
|
||||
"minAppVersion": "0.12.17",
|
||||
"description": "This plugin automatically fetches the titles of links from the web",
|
||||
"author": "Matt Furden",
|
||||
"authorUrl": "https://github.com/zolrath",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
1
.obsidian/plugins/obsidian-auto-link-title/styles.css
vendored
Normal file
1
.obsidian/plugins/obsidian-auto-link-title/styles.css
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/* no styles */
|
||||
415
.obsidian/plugins/obsidian-git/main.js
vendored
Normal file
415
.obsidian/plugins/obsidian-git/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
.obsidian/plugins/obsidian-git/manifest.json
vendored
Normal file
10
.obsidian/plugins/obsidian-git/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"author": "Vinzent",
|
||||
"authorUrl": "https://github.com/Vinzent03",
|
||||
"id": "obsidian-git",
|
||||
"name": "Git",
|
||||
"description": "Integrate Git version control with automatic backup and other advanced features.",
|
||||
"isDesktopOnly": false,
|
||||
"fundingUrl": "https://ko-fi.com/vinzent",
|
||||
"version": "2.38.3"
|
||||
}
|
||||
23
.obsidian/plugins/obsidian-git/obsidian_askpass.sh
vendored
Normal file
23
.obsidian/plugins/obsidian-git/obsidian_askpass.sh
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROMPT="$1"
|
||||
TEMP_FILE="$OBSIDIAN_GIT_CREDENTIALS_INPUT"
|
||||
|
||||
cleanup() {
|
||||
rm -f "$TEMP_FILE" "$TEMP_FILE.response"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "$PROMPT" > "$TEMP_FILE"
|
||||
|
||||
while [ ! -e "$TEMP_FILE.response" ]; do
|
||||
if [ ! -e "$TEMP_FILE" ]; then
|
||||
echo "Trigger file got removed: Abort" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
RESPONSE=$(cat "$TEMP_FILE.response")
|
||||
|
||||
echo "$RESPONSE"
|
||||
705
.obsidian/plugins/obsidian-git/styles.css
vendored
Normal file
705
.obsidian/plugins/obsidian-git/styles.css
vendored
Normal file
|
|
@ -0,0 +1,705 @@
|
|||
@keyframes loading {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.workspace-leaf-content[data-type="git-view"] .button-border {
|
||||
border: 2px solid var(--interactive-accent);
|
||||
border-radius: var(--radius-s);
|
||||
}
|
||||
|
||||
.workspace-leaf-content[data-type="git-view"] .view-content {
|
||||
padding-left: 0;
|
||||
padding-top: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.workspace-leaf-content[data-type="git-history-view"] .view-content {
|
||||
padding-left: 0;
|
||||
padding-top: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.loading {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.loading > svg {
|
||||
animation: 2s linear infinite loading;
|
||||
transform-origin: 50% 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.obsidian-git-center {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.obsidian-git-textarea {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.obsidian-git-disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.obsidian-git-center-button {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.tooltip.mod-left {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.tooltip.mod-right {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Limits the scrollbar to the view body */
|
||||
.git-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Re-enable wrapping of nav buttns to prevent overflow on smaller screens #*/
|
||||
.workspace-drawer .git-view .nav-buttons-container {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.git-tools {
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
}
|
||||
.git-tools .type {
|
||||
padding-left: var(--size-2-1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
.git-tools .type[data-type="M"] {
|
||||
color: orange;
|
||||
}
|
||||
.git-tools .type[data-type="D"] {
|
||||
color: red;
|
||||
}
|
||||
.git-tools .buttons {
|
||||
display: flex;
|
||||
}
|
||||
.git-tools .buttons > * {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.workspace-leaf-content[data-type="git-view"] .tree-item-self,
|
||||
.workspace-leaf-content[data-type="git-history-view"] .tree-item-self {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.workspace-leaf-content[data-type="git-view"]
|
||||
.tree-item-self:hover
|
||||
.clickable-icon,
|
||||
.workspace-leaf-content[data-type="git-history-view"]
|
||||
.tree-item-self:hover
|
||||
.clickable-icon {
|
||||
color: var(--icon-color-hover);
|
||||
}
|
||||
|
||||
/* Highlight an item as active if it's diff is currently opened */
|
||||
.is-active .git-tools .buttons > * {
|
||||
color: var(--nav-item-color-active);
|
||||
}
|
||||
|
||||
.git-author {
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
.git-date {
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
.git-ref {
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
/* ====== diff2html ======
|
||||
The following styles are adapted from the obsidian-version-history plugin by
|
||||
@kometenstaub https://github.com/kometenstaub/obsidian-version-history-diff/blob/main/src/styles.scss
|
||||
which itself is adapted from the diff2html library with the following original license:
|
||||
|
||||
https://github.com/rtfpessoa/diff2html/blob/master/LICENSE.md
|
||||
|
||||
Copyright 2014-2016 Rodrigo Fernandes https://rtfpessoa.github.io/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
.theme-dark,
|
||||
.theme-light {
|
||||
--git-delete-bg: #ff475040;
|
||||
--git-delete-hl: #96050a75;
|
||||
--git-insert-bg: #68d36840;
|
||||
--git-insert-hl: #23c02350;
|
||||
--git-change-bg: #ffd55840;
|
||||
--git-selected: #3572b0;
|
||||
|
||||
--git-delete: #cc3333;
|
||||
--git-insert: #399839;
|
||||
--git-change: #d0b44c;
|
||||
--git-move: #3572b0;
|
||||
}
|
||||
|
||||
.git-diff {
|
||||
.d2h-d-none {
|
||||
display: none;
|
||||
}
|
||||
.d2h-wrapper {
|
||||
text-align: left;
|
||||
border-radius: 0.25em;
|
||||
overflow: auto;
|
||||
}
|
||||
.d2h-file-header.d2h-file-header {
|
||||
background-color: var(--background-secondary);
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
font-family:
|
||||
Source Sans Pro,
|
||||
Helvetica Neue,
|
||||
Helvetica,
|
||||
Arial,
|
||||
sans-serif;
|
||||
height: 35px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.d2h-file-header,
|
||||
.d2h-file-stats {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
.d2h-file-header {
|
||||
display: none;
|
||||
}
|
||||
.d2h-file-stats {
|
||||
font-size: 14px;
|
||||
margin-left: auto;
|
||||
}
|
||||
.d2h-lines-added {
|
||||
border: 1px solid var(--color-green);
|
||||
border-radius: 5px 0 0 5px;
|
||||
color: var(--color-green);
|
||||
padding: 2px;
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.d2h-lines-deleted {
|
||||
border: 1px solid var(--color-red);
|
||||
border-radius: 0 5px 5px 0;
|
||||
color: var(--color-red);
|
||||
margin-left: 1px;
|
||||
padding: 2px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.d2h-file-name-wrapper {
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
font-size: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
.d2h-file-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: var(--text-normal);
|
||||
font-size: var(--h5-size);
|
||||
}
|
||||
.d2h-file-wrapper {
|
||||
border: 1px solid var(--background-secondary-alt);
|
||||
border-radius: 3px;
|
||||
margin-bottom: 1em;
|
||||
max-height: 100%;
|
||||
}
|
||||
.d2h-file-collapse {
|
||||
-webkit-box-pack: end;
|
||||
-ms-flex-pack: end;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border: 1px solid var(--background-secondary-alt);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
font-size: 12px;
|
||||
justify-content: flex-end;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
.d2h-file-collapse.d2h-selected {
|
||||
background-color: var(--git-selected);
|
||||
}
|
||||
.d2h-file-collapse-input {
|
||||
margin: 0 4px 0 0;
|
||||
}
|
||||
.d2h-diff-table {
|
||||
border-collapse: collapse;
|
||||
font-family: var(--font-monospace);
|
||||
font-size: var(--code-size);
|
||||
width: 100%;
|
||||
}
|
||||
.d2h-files-diff {
|
||||
width: 100%;
|
||||
}
|
||||
.d2h-file-diff {
|
||||
/*
|
||||
overflow-y: scroll;
|
||||
*/
|
||||
border-radius: 5px;
|
||||
font-size: var(--font-text-size);
|
||||
line-height: var(--line-height-normal);
|
||||
}
|
||||
.d2h-file-side-diff {
|
||||
display: inline-block;
|
||||
margin-bottom: -8px;
|
||||
margin-right: -4px;
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
width: 50%;
|
||||
}
|
||||
.d2h-code-line {
|
||||
padding-left: 6em;
|
||||
padding-right: 1.5em;
|
||||
}
|
||||
.d2h-code-line,
|
||||
.d2h-code-side-line {
|
||||
display: inline-block;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
.d2h-code-side-line {
|
||||
/* needed to be changed */
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.d2h-code-line-ctn {
|
||||
word-wrap: normal;
|
||||
background: none;
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
/* only works for line-by-line */
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.d2h-code-line del,
|
||||
.d2h-code-side-line del {
|
||||
background-color: var(--git-delete-hl);
|
||||
color: var(--text-normal);
|
||||
}
|
||||
.d2h-code-line del,
|
||||
.d2h-code-line ins,
|
||||
.d2h-code-side-line del,
|
||||
.d2h-code-side-line ins {
|
||||
border-radius: 0.2em;
|
||||
display: inline-block;
|
||||
margin-top: -1px;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.d2h-code-line ins,
|
||||
.d2h-code-side-line ins {
|
||||
background-color: var(--git-insert-hl);
|
||||
text-align: left;
|
||||
}
|
||||
.d2h-code-line-prefix {
|
||||
word-wrap: normal;
|
||||
background: none;
|
||||
display: inline;
|
||||
padding: 0;
|
||||
white-space: pre;
|
||||
}
|
||||
.line-num1 {
|
||||
float: left;
|
||||
}
|
||||
.line-num1,
|
||||
.line-num2 {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
/*
|
||||
padding: 0 0.5em;
|
||||
*/
|
||||
text-overflow: ellipsis;
|
||||
width: 2.5em;
|
||||
padding-left: 0;
|
||||
}
|
||||
.line-num2 {
|
||||
float: right;
|
||||
}
|
||||
.d2h-code-linenumber {
|
||||
background-color: var(--background-primary);
|
||||
border: solid var(--background-modifier-border);
|
||||
border-width: 0 1px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: var(--text-faint);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
width: 5.5em;
|
||||
}
|
||||
.d2h-code-linenumber:after {
|
||||
content: "\200b";
|
||||
}
|
||||
.d2h-code-side-linenumber {
|
||||
background-color: var(--background-primary);
|
||||
border: solid var(--background-modifier-border);
|
||||
border-width: 0 1px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: var(--text-faint);
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
padding: 0 0.5em;
|
||||
text-align: right;
|
||||
text-overflow: ellipsis;
|
||||
width: 4em;
|
||||
/* needed to be changed */
|
||||
display: table-cell;
|
||||
position: relative;
|
||||
}
|
||||
.d2h-code-side-linenumber:after {
|
||||
content: "\200b";
|
||||
}
|
||||
.d2h-code-side-emptyplaceholder,
|
||||
.d2h-emptyplaceholder {
|
||||
background-color: var(--background-primary);
|
||||
border-color: var(--background-modifier-border);
|
||||
}
|
||||
.d2h-code-line-prefix,
|
||||
.d2h-code-linenumber,
|
||||
.d2h-code-side-linenumber,
|
||||
.d2h-emptyplaceholder {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.d2h-code-linenumber,
|
||||
.d2h-code-side-linenumber {
|
||||
direction: rtl;
|
||||
}
|
||||
.d2h-del {
|
||||
background-color: var(--git-delete-bg);
|
||||
border-color: var(--git-delete-hl);
|
||||
}
|
||||
.d2h-ins {
|
||||
background-color: var(--git-insert-bg);
|
||||
border-color: var(--git-insert-hl);
|
||||
}
|
||||
.d2h-info {
|
||||
background-color: var(--background-primary);
|
||||
border-color: var(--background-modifier-border);
|
||||
color: var(--text-faint);
|
||||
}
|
||||
.d2h-del,
|
||||
.d2h-ins,
|
||||
.d2h-file-diff .d2h-change {
|
||||
color: var(--text-normal);
|
||||
}
|
||||
.d2h-file-diff .d2h-del.d2h-change {
|
||||
background-color: var(--git-change-bg);
|
||||
}
|
||||
.d2h-file-diff .d2h-ins.d2h-change {
|
||||
background-color: var(--git-insert-bg);
|
||||
}
|
||||
.d2h-file-list-wrapper {
|
||||
a {
|
||||
text-decoration: none;
|
||||
cursor: default;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.d2h-file-list-header {
|
||||
text-align: left;
|
||||
}
|
||||
.d2h-file-list-title {
|
||||
display: none;
|
||||
}
|
||||
.d2h-file-list-line {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
text-align: left;
|
||||
}
|
||||
.d2h-file-list {
|
||||
}
|
||||
.d2h-file-list > li {
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.d2h-file-list > li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.d2h-file-switch {
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
font-size: 10px;
|
||||
}
|
||||
.d2h-icon {
|
||||
fill: currentColor;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.d2h-deleted {
|
||||
color: var(--git-delete);
|
||||
}
|
||||
.d2h-added {
|
||||
color: var(--git-insert);
|
||||
}
|
||||
.d2h-changed {
|
||||
color: var(--git-change);
|
||||
}
|
||||
.d2h-moved {
|
||||
color: var(--git-move);
|
||||
}
|
||||
.d2h-tag {
|
||||
background-color: var(--background-secondary);
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
font-size: 10px;
|
||||
margin-left: 5px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
.d2h-deleted-tag {
|
||||
border: 1px solid var(--git-delete);
|
||||
}
|
||||
.d2h-added-tag {
|
||||
border: 1px solid var(--git-insert);
|
||||
}
|
||||
.d2h-changed-tag {
|
||||
border: 1px solid var(--git-change);
|
||||
}
|
||||
.d2h-moved-tag {
|
||||
border: 1px solid var(--git-move);
|
||||
}
|
||||
|
||||
/* needed for line-by-line*/
|
||||
|
||||
.d2h-diff-tbody {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* My additions */
|
||||
.cm-merge-revert {
|
||||
width: 4em;
|
||||
}
|
||||
/* Ensure that merge revert markers are positioned correctly */
|
||||
.cm-merge-revert > * {
|
||||
position: absolute;
|
||||
background-color: var(--background-secondary);
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================== Line Authoring Information ====================== */
|
||||
|
||||
.cm-gutterElement.obs-git-blame-gutter {
|
||||
/* Add background color to spacing inbetween and around the gutter for better aesthetics */
|
||||
border-width: 0px 2px 0.2px;
|
||||
border-style: solid;
|
||||
border-color: var(--background-secondary);
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.cm-gutterElement.obs-git-blame-gutter > div,
|
||||
.line-author-settings-preview {
|
||||
/* delegate text color to settings */
|
||||
color: var(--obs-git-gutter-text);
|
||||
font-family: monospace;
|
||||
height: 100%; /* ensure, that age-based background color occupies entire parent */
|
||||
text-align: right;
|
||||
padding: 0px 6px;
|
||||
white-space: pre; /* Keep spaces and do not collapse them. */
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
/* hide git blame gutter not to superpose text */
|
||||
.cm-gutterElement.obs-git-blame-gutter {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.git-unified-diff-view,
|
||||
.git-split-diff-view .cm-deletedLine .cm-changedText {
|
||||
background-color: #ee443330;
|
||||
}
|
||||
|
||||
.git-unified-diff-view,
|
||||
.git-split-diff-view .cm-insertedLine .cm-changedText {
|
||||
background-color: #22bb2230;
|
||||
}
|
||||
|
||||
.git-obscure-prompt[git-is-obscured="true"] #git-show-password:after {
|
||||
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"></path><circle cx="12" cy="12" r="3"></circle></svg>');
|
||||
}
|
||||
|
||||
.git-obscure-prompt[git-is-obscured="false"] #git-show-password:after {
|
||||
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye-off"><path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"></path><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"></path><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"></path><path d="m2 2 20 20"></path></svg>');
|
||||
}
|
||||
|
||||
/* Override styling of Codemirror merge view "collapsed lines" indicator */
|
||||
.git-split-diff-view .ͼ2 .cm-collapsedLines {
|
||||
background: var(--interactive-normal);
|
||||
border-radius: var(--radius-m);
|
||||
color: var(--text-accent);
|
||||
font-size: var(--font-small);
|
||||
padding: var(--size-4-1) var(--size-4-1);
|
||||
}
|
||||
.git-split-diff-view .ͼ2 .cm-collapsedLines:hover {
|
||||
background: var(--interactive-hover);
|
||||
color: var(--text-accent-hover);
|
||||
}
|
||||
|
||||
.git-signs-gutter {
|
||||
.cm-gutterElement {
|
||||
display: grid;
|
||||
|
||||
/* Needed to align the sign properly for different line heigts. Such as
|
||||
* when having a heading or list item.
|
||||
*/
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.git-gutter-marker:hover {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.git-gutter-marker.git-add {
|
||||
background-color: var(--color-green);
|
||||
justify-self: center;
|
||||
height: inherit;
|
||||
width: 0.2rem;
|
||||
}
|
||||
|
||||
.git-gutter-marker.git-change {
|
||||
background-color: var(--color-yellow);
|
||||
justify-self: center;
|
||||
height: inherit;
|
||||
width: 0.2rem;
|
||||
}
|
||||
|
||||
.git-gutter-marker.git-changedelete {
|
||||
color: var(--color-yellow);
|
||||
font-weight: var(--font-bold);
|
||||
font-size: 1rem;
|
||||
justify-self: center;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.git-gutter-marker.git-delete {
|
||||
background-color: var(--color-red);
|
||||
height: 0.2rem;
|
||||
width: 0.8rem;
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
.git-gutter-marker.git-topdelete {
|
||||
background-color: var(--color-red);
|
||||
height: 0.2rem;
|
||||
width: 0.8rem;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
div:hover > .git-gutter-marker.git-change {
|
||||
width: 0.6rem;
|
||||
}
|
||||
|
||||
div:hover > .git-gutter-marker.git-add {
|
||||
width: 0.6rem;
|
||||
}
|
||||
|
||||
div:hover > .git-gutter-marker.git-delete {
|
||||
height: 0.6rem;
|
||||
}
|
||||
|
||||
div:hover > .git-gutter-marker.git-topdelete {
|
||||
height: 0.6rem;
|
||||
}
|
||||
|
||||
div:hover > .git-gutter-marker.git-changedelete {
|
||||
font-weight: var(--font-bold);
|
||||
}
|
||||
|
||||
.git-gutter-marker.staged {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Prevent shifting of the editor when git signs gutter is the only gutter present */
|
||||
.cm-gutters.cm-gutters-before:has(> .git-signs-gutter:only-child) {
|
||||
margin-inline-end: 0;
|
||||
.git-signs-gutter {
|
||||
margin-inline-start: -1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.git-changes-status-bar-colored {
|
||||
.git-add {
|
||||
color: var(--color-green);
|
||||
}
|
||||
.git-change {
|
||||
color: var(--color-yellow);
|
||||
}
|
||||
.git-delete {
|
||||
color: var(--color-red);
|
||||
}
|
||||
}
|
||||
|
||||
.git-changes-status-bar .git-add {
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
|
||||
.git-changes-status-bar .git-change {
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
20
.obsidian/plugins/obsidian-hover-editor/main.js
vendored
Normal file
20
.obsidian/plugins/obsidian-hover-editor/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
.obsidian/plugins/obsidian-hover-editor/manifest.json
vendored
Normal file
10
.obsidian/plugins/obsidian-hover-editor/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "obsidian-hover-editor",
|
||||
"name": "Hover Editor",
|
||||
"version": "0.11.29",
|
||||
"minAppVersion": "1.10.6",
|
||||
"description": "Transform the Page Preview hover popover into a floating tab",
|
||||
"author": "NothingIsLost",
|
||||
"authorUrl": "https://github.com/nothingislost",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
582
.obsidian/plugins/obsidian-hover-editor/styles.css
vendored
Normal file
582
.obsidian/plugins/obsidian-hover-editor/styles.css
vendored
Normal file
|
|
@ -0,0 +1,582 @@
|
|||
/* @settings
|
||||
|
||||
name: Hover Editor
|
||||
id: hover-editor
|
||||
settings:
|
||||
-
|
||||
id: titlebar-heading
|
||||
title: Title bar
|
||||
type: heading
|
||||
level: 1
|
||||
collapsed: true
|
||||
-
|
||||
id: titlebar-heading
|
||||
title: Title bar background/foreground
|
||||
type: heading
|
||||
level: 2
|
||||
collapsed: true
|
||||
-
|
||||
id: he-title-bar-active-bg
|
||||
title: Active unpinned title bar background color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: he-title-bar-inactive-bg
|
||||
title: Inactive unpinned title bar background color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: he-title-bar-active-pinned-bg
|
||||
title: Active pinned title bar background color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: he-title-bar-inactive-pinned-bg
|
||||
title: Inactive pinned title bar background color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: he-title-bar-active-fg
|
||||
title: Active title bar foreground color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: he-title-bar-inactive-fg
|
||||
title: Inactive title bar foreground color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: titlebar-action-heading
|
||||
title: Title bar icons
|
||||
type: heading
|
||||
level: 2
|
||||
collapsed: true
|
||||
-
|
||||
id: he-title-bar-inactive-action
|
||||
title: Title bar inactive icon color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: he-title-bar-active-action
|
||||
title: Titlebar active icon color
|
||||
type: variable-themed-color
|
||||
format: hex
|
||||
default-light: '#'
|
||||
default-dark: '#'
|
||||
-
|
||||
id: titlebar-text-heading
|
||||
title: Title bar text
|
||||
type: heading
|
||||
level: 2
|
||||
collapsed: true
|
||||
-
|
||||
id: he-title-bar-font-size
|
||||
title: Title bar Font size
|
||||
type: variable-text
|
||||
description: Accepts any CSS font-size value
|
||||
default: 15px
|
||||
-
|
||||
id: titlebar-height-heading
|
||||
title: Title bar height
|
||||
type: heading
|
||||
level: 2
|
||||
collapsed: true
|
||||
-
|
||||
id: he-title-bar-height
|
||||
title: Title bar height
|
||||
type: variable-text
|
||||
description: Accepts any CSS font-size value
|
||||
default: 28px
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* general styling */
|
||||
--he-popover-opacity-while-dragging: 0.8;
|
||||
--he-popover-border-radius: 6px;
|
||||
--he-popover-header-transition-speed: 0.3s;
|
||||
--he-popover-snap-to-edge-transition-speed: 0.3s;
|
||||
/* resize handle sizing */
|
||||
--he-resize-handle-side-size: 12px;
|
||||
--he-resize-handle-corner-size: 18px;
|
||||
/* view header height */
|
||||
--he-view-header-height: 36px;
|
||||
}
|
||||
|
||||
body {
|
||||
--he-text-on-accent-inactive: var(--text-on-accent); /* couldn't find a good variable that worked across themes */
|
||||
--he-text-on-accent-active: #fff;
|
||||
/* z-index layer settings, probably not a good idea to mess with these */
|
||||
--he-popover-layer-inactive: calc(var(--layer-slides) - 4);
|
||||
--he-popover-layer-active: calc(var(--he-popover-layer-inactive) + 1);
|
||||
--he-popover-layer-new: calc(var(--he-popover-layer-inactive) + 2);
|
||||
--he-leaf-drag-overlay: calc(var(--he-popover-layer-inactive) + 3);
|
||||
/* calculated variables, do not modify */
|
||||
--he-resize-handle-side-offset: calc((var(--he-resize-handle-side-size) - 3px) * -1);
|
||||
--he-resize-handle-corner-offset: calc((var(--he-resize-handle-corner-size) / 2) * -1);
|
||||
--he-resize-handle-side-length: calc(100% - var(--he-resize-handle-corner-size));
|
||||
/* title bar colors */
|
||||
--he-title-bar-active-bg: var(--interactive-accent);
|
||||
--he-title-bar-inactive-bg: #777777;
|
||||
--he-title-bar-inactive-pinned-bg: #777777;
|
||||
--he-title-bar-active-pinned-bg: var(--interactive-accent);
|
||||
|
||||
--he-title-bar-active-fg: var(--he-text-on-accent-active);
|
||||
--he-title-bar-inactive-fg: var(--he-text-on-accent-inactive);
|
||||
/* title bar action/icon colors */
|
||||
--he-title-bar-inactive-action: var(--he-text-on-accent-inactive);
|
||||
--he-title-bar-active-action: var(--he-text-on-accent-active);
|
||||
/* titlebar sizing */
|
||||
--he-title-bar-height: 28px;
|
||||
--he-title-bar-font-size: 15px;
|
||||
}
|
||||
|
||||
.popover.hover-editor .workspace-leaf,
|
||||
.popover.hover-editor .workspace-split {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
Obsidian 1.6 sets a different background for non-root splits,
|
||||
then uses primary as an override at root. Since hover editors
|
||||
don't live in a root split, we have to copy the override:
|
||||
*/
|
||||
.popover.hover-editor .workspace-split .view-content {
|
||||
background-color: var(--background-primary);
|
||||
}
|
||||
|
||||
.popover.hover-editor {
|
||||
min-height: unset;
|
||||
max-height: unset;
|
||||
/* touch action none fixes dragging and resizing on mobile */
|
||||
touch-action: none;
|
||||
/* this is set to allow the drag/resize handles to overflow the popover frame */
|
||||
overflow: visible;
|
||||
border: none;
|
||||
padding: 0;
|
||||
z-index: var(--he-popover-layer-inactive);
|
||||
border-radius: var(--he-popover-border-radius);
|
||||
|
||||
/* Prevent snagging on titlebar */
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.popover.hover-editor .markdown-preview-view {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-active {
|
||||
z-index: var(--he-popover-layer-active);
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-new {
|
||||
z-index: var(--he-popover-layer-new);
|
||||
}
|
||||
|
||||
/* Drag/link overlay needs to overlay popups */
|
||||
.workspace-fake-target-overlay,
|
||||
.workspace-drop-overlay {
|
||||
z-index: var(--he-leaf-drag-overlay);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle {
|
||||
position: absolute;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.top {
|
||||
top: var(--he-resize-handle-side-offset);
|
||||
height: var(--he-resize-handle-side-size);
|
||||
left: calc(var(--he-resize-handle-corner-offset) * -1);
|
||||
width: var(--he-resize-handle-side-length);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.left {
|
||||
height: var(--he-resize-handle-side-length);
|
||||
left: var(--he-resize-handle-side-offset);
|
||||
top: calc(var(--he-resize-handle-corner-offset) * -1);
|
||||
width: var(--he-resize-handle-side-size);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.right {
|
||||
height: var(--he-resize-handle-side-length);
|
||||
right: var(--he-resize-handle-side-offset);
|
||||
top: calc(var(--he-resize-handle-corner-offset) * -1);
|
||||
width: var(--he-resize-handle-side-size);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.bottom {
|
||||
bottom: var(--he-resize-handle-side-offset);
|
||||
height: var(--he-resize-handle-side-size);
|
||||
left: calc(var(--he-resize-handle-corner-offset) * -1);
|
||||
width: var(--he-resize-handle-side-length);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.bottom-left {
|
||||
bottom: var(--he-resize-handle-corner-offset);
|
||||
height: var(--he-resize-handle-corner-size);
|
||||
left: var(--he-resize-handle-corner-offset);
|
||||
width: var(--he-resize-handle-corner-size);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.bottom-right {
|
||||
bottom: var(--he-resize-handle-corner-offset);
|
||||
height: var(--he-resize-handle-corner-size);
|
||||
right: var(--he-resize-handle-corner-offset);
|
||||
width: var(--he-resize-handle-corner-size);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.top-left {
|
||||
top: var(--he-resize-handle-corner-offset);
|
||||
height: var(--he-resize-handle-corner-size);
|
||||
left: var(--he-resize-handle-corner-offset);
|
||||
width: var(--he-resize-handle-corner-size);
|
||||
}
|
||||
|
||||
.popover.hover-editor .resize-handle.top-right {
|
||||
top: var(--he-resize-handle-corner-offset);
|
||||
height: var(--he-resize-handle-corner-size);
|
||||
right: var(--he-resize-handle-corner-offset);
|
||||
width: var(--he-resize-handle-corner-size);
|
||||
}
|
||||
|
||||
/* body.is-dragging-popover .tooltip {
|
||||
opacity: 0;
|
||||
} */
|
||||
|
||||
.popover-header-icon {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.mod-pin-popover > svg {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.mod-pin-popover.is-active > svg {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
.popover-action,
|
||||
.popover-header-icon {
|
||||
margin: 0 8px;
|
||||
cursor: pointer;
|
||||
color: var(--he-title-bar-inactive-action);
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.popover-action.is-active,
|
||||
.mod-pin-popover.is-active {
|
||||
color: var(--he-title-bar-active-action);
|
||||
}
|
||||
|
||||
.popover-action:hover,
|
||||
.popover-header-icon:hover {
|
||||
color: var(--he-title-bar-active-action);
|
||||
}
|
||||
|
||||
.popover-action.is-active svg,
|
||||
.mod-pin-popover.is-active svg {
|
||||
}
|
||||
|
||||
.mod-pin-popover.is-active > svg {
|
||||
transform: unset;
|
||||
}
|
||||
|
||||
.popover.hover-editor .workspace-leaf-content[data-type="empty"] .view-header {
|
||||
/* ensures that minimal theme doesn't hide the popover header */
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.popover.hover-editor .workspace-split > .workspace-leaf:last-child > .workspace-leaf-resize-handle {
|
||||
/* this hides the leaf resize handles that touch the edge of the popover */
|
||||
/* without this the leaf resize handles conflict with the popover resize handles */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-dragging {
|
||||
opacity: var(--he-popover-opacity-while-dragging);
|
||||
}
|
||||
|
||||
.popover.hover-editor:is(.snap-to-viewport, .snap-to-left, .snap-to-right) .resize-handle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popover.hover-editor.snap-to-right .resize-handle.left,
|
||||
.popover.hover-editor.snap-to-left .resize-handle.right {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-dragging.snap-to-left,
|
||||
.popover.hover-editor.is-dragging.snap-to-right,
|
||||
.popover.hover-editor.is-dragging.snap-to-viewport {
|
||||
transition: width var(--he-popover-snap-to-edge-transition-speed),
|
||||
height var(--he-popover-snap-to-edge-transition-speed), top var(--he-popover-snap-to-edge-transition-speed),
|
||||
left var(--he-popover-snap-to-edge-transition-speed);
|
||||
}
|
||||
|
||||
.hover-popover.is-dragging.snap-to-left::after,
|
||||
.hover-popover.is-dragging.snap-to-right::after,
|
||||
.hover-popover.is-dragging.snap-to-viewport::after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
border-radius: var(--he-popover-border-radius);
|
||||
box-shadow: inset 0px 0px 0px 4px var(--interactive-accent);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.popover.hover-editor.snap-to-left {
|
||||
max-height: unset !important;
|
||||
}
|
||||
|
||||
.popover.hover-editor.snap-to-right {
|
||||
right: 0 !important;
|
||||
max-height: unset !important;
|
||||
}
|
||||
|
||||
.popover.hover-editor.snap-to-viewport {
|
||||
max-height: unset !important;
|
||||
max-width: unset !important;
|
||||
}
|
||||
|
||||
.popover.hover-editor .popover-titlebar {
|
||||
display: flex;
|
||||
height: var(--he-title-bar-height);
|
||||
width: 100%;
|
||||
background-color: var(--he-title-bar-inactive-bg);
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-active .popover-titlebar {
|
||||
background-color: var(--he-title-bar-active-bg);
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-pinned.is-pinned .popover-titlebar {
|
||||
background-color: var(--he-title-bar-inactive-pinned-bg);
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-pinned.is-pinned.is-active .popover-titlebar {
|
||||
background-color: var(--he-title-bar-active-pinned-bg);
|
||||
}
|
||||
|
||||
.popover.hover-editor .popover-titlebar .popover-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.popover.hover-editor > .popover-content {
|
||||
margin: 0;
|
||||
border-radius: var(--he-popover-border-radius);
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.popover.hover-popover.hover-editor .pdf-toolbar:not(.pdf-findbar.mod-hidden) {
|
||||
/* Show PDF toolbar in hover editor */
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.popover.hover-editor .popover-titlebar .popover-title {
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
transition: all 0.3s;
|
||||
align-self: center;
|
||||
font-size: var(--he-title-bar-font-size);
|
||||
font-weight: 500;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
color: var(--he-title-bar-inactive-fg);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-active .popover-title {
|
||||
color: var(--he-title-bar-active-fg);
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-active .popover-title:after {
|
||||
background: linear-gradient(to right, transparent, var(--he-title-bar-active-bg));
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-pinned.is-pinned.is-active .popover-title:after {
|
||||
background: linear-gradient(to right, transparent, var(--he-title-bar-active-pinned-bg));
|
||||
}
|
||||
|
||||
.popover.hover-editor.is-pinned.is-pinned .popover-title:after {
|
||||
background: linear-gradient(to right, transparent, var(--he-title-bar-inactive-pinned-bg));
|
||||
}
|
||||
|
||||
.popover.hover-editor .popover-title:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, transparent, var(--he-title-bar-inactive-bg));
|
||||
}
|
||||
|
||||
.popover.hover-editor .mod-show-navbar svg {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.popover.hover-editor > .popover-content > .workspace-split {
|
||||
height: calc(100% - var(--he-title-bar-height));
|
||||
}
|
||||
|
||||
.popover.hover-editor .view-header {
|
||||
border-top: none;
|
||||
transition: all var(--he-popover-header-transition-speed);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Restore 1.5.x view header icons */
|
||||
.view-header .view-header-icon {
|
||||
display: none;
|
||||
padding: var(--size-2-2);
|
||||
margin-right: var(--size-2-3);
|
||||
color: var(--text-muted);
|
||||
align-self: center;
|
||||
cursor: grab;
|
||||
}
|
||||
.view-header .view-header-icon:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.popover.hover-editor .view-header .view-header-icon {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.popover.hover-editor.show-navbar:not(.is-minimized) .popover-title {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.popover.hover-editor:not(.show-navbar) .view-header {
|
||||
height: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.popover.hover-editor.show-navbar .view-header {
|
||||
/* theme devs: if you want to change the header height, you must do so by setting the --he-view-header-height variable */
|
||||
/* if you don't use the variable, you will break internal measurement logic */
|
||||
height: var(--he-view-header-height);
|
||||
overflow: unset;
|
||||
}
|
||||
|
||||
.popover.hover-editor:not(.show-navbar) .view-content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.popover.hover-editor .workspace-leaf-content[data-type="image"] .view-content {
|
||||
padding: 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.popover.hover-editor .workspace-leaf-content[data-type="image"] img {
|
||||
display: block;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: unset;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
body .popover.hover-editor .view-content {
|
||||
/* theme devs: if you want to change the header height, you must do so by setting the --he-view-header-height variable */
|
||||
/* if you don't use the variable, you will break internal measurement logic */
|
||||
height: calc(100% - var(--he-view-header-height));
|
||||
}
|
||||
|
||||
/* start: zoomable images feature */
|
||||
|
||||
.popover.hover-editor.image-zoom .view-content .image-embed:active {
|
||||
aspect-ratio: unset;
|
||||
cursor: zoom-out;
|
||||
display: block;
|
||||
z-index: 200;
|
||||
position: fixed;
|
||||
max-height: calc(100% + 1px);
|
||||
max-width: 100%;
|
||||
height: calc(100% + 1px);
|
||||
width: 100%;
|
||||
object-fit: contain;
|
||||
margin: -0.5px auto 0;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
/* extra specificity to override some community theme styles that cause issues */
|
||||
.popover.hover-editor.image-zoom .view-content .image-embed img:active {
|
||||
top: 50%;
|
||||
z-index: 99;
|
||||
transform: translateY(-50%);
|
||||
padding: 0;
|
||||
margin: 0 auto;
|
||||
width: calc(100% - 20px);
|
||||
height: unset;
|
||||
max-height: 95vh;
|
||||
object-fit: contain;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
opacity: 1;
|
||||
max-width: unset;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.popover.hover-editor.image-zoom .view-content .image-embed:active:after {
|
||||
background-color: var(--background-primary);
|
||||
opacity: 0.9;
|
||||
content: " ";
|
||||
height: calc(100% + 1px);
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 1px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.popover.hover-editor.image-zoom .view-content img {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
/* extra specificity to override some community theme styles that cause issues */
|
||||
.popover.hover-editor.image-zoom .workspace-leaf-content[data-type="image"] img {
|
||||
cursor: zoom-in;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
object-fit: contain;
|
||||
height: unset;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
opacity: 1;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
/* end: zoomable images feature */
|
||||
74
.obsidian/plugins/obsidian-style-settings/data.json
vendored
Normal file
74
.obsidian/plugins/obsidian-style-settings/data.json
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"anuppuccin-theme-settings@@anuppuccin-theme-light": "ctp-rosepine-light",
|
||||
"anuppuccin-theme-settings@@anuppuccin-theme-dark": "ctp-frappe",
|
||||
"anuppuccin-theme-settings@@anuppuccin-light-theme-accents": "ctp-accent-light-teal",
|
||||
"anuppuccin-theme-settings@@anuppuccin-theme-accents": "ctp-accent-teal",
|
||||
"anuppuccin-theme-settings@@anuppuccin-accent-toggle": true,
|
||||
"anuppuccin-theme-settings@@ctp-custom-peach@@light": "#DD7F67",
|
||||
"anuppuccin-theme-settings@@ctp-custom-teal@@dark": "#11B7C5",
|
||||
"anuppuccin-theme-settings@@ctp-custom-teal@@light": "#1A7DA4",
|
||||
"anuppuccin-theme-settings@@ctp-custom-subtext1@@light": "#EE653A",
|
||||
"anuppuccin-theme-settings@@ctp-custom-subtext0@@dark": "#FB35D8",
|
||||
"anuppuccin-theme-settings@@ctp-custom-subtext0@@light": "#0C9FCE",
|
||||
"anuppuccin-theme-settings@@ctp-custom-overlay2@@dark": "#0AD1D0",
|
||||
"anuppuccin-theme-settings@@ctp-custom-overlay2@@light": "#525252",
|
||||
"anuppuccin-theme-settings@@ctp-custom-overlay1@@dark": "#FFA600",
|
||||
"anuppuccin-theme-settings@@ctp-custom-overlay1@@light": "#CCCCCC",
|
||||
"anuppuccin-theme-settings@@ctp-custom-overlay0@@dark": "#4CFFD2",
|
||||
"anuppuccin-theme-settings@@ctp-custom-overlay0@@light": "#0C9FCE",
|
||||
"anuppuccin-theme-settings@@anp-active-line": "anp-no-highlight",
|
||||
"anuppuccin-theme-settings@@anp-callout-select": "anp-callout-sleek",
|
||||
"anuppuccin-theme-settings@@anp-callout-color-toggle": true,
|
||||
"anuppuccin-theme-settings@@anp-custom-checkboxes": true,
|
||||
"anuppuccin-theme-settings@@anp-speech-bubble": true,
|
||||
"anuppuccin-theme-settings@@tag-radius": 2,
|
||||
"anuppuccin-theme-settings@@cards-border-width": "4px",
|
||||
"anuppuccin-theme-settings@@anp-color-transition-toggle": true,
|
||||
"anuppuccin-theme-settings@@anp-cursor": "pointer",
|
||||
"anuppuccin-theme-settings@@anp-toggle-scrollbars": true,
|
||||
"anuppuccin-theme-settings@@anp-editor-font-source": "\"\"",
|
||||
"anuppuccin-theme-settings@@anp-editor-font-lp": "\"New York\"",
|
||||
"anuppuccin-theme-settings@@bold-weight": "700",
|
||||
"anuppuccin-theme-settings@@anp-font-live-preview-wt": "400",
|
||||
"anuppuccin-theme-settings@@anp-header-color-toggle": true,
|
||||
"anuppuccin-theme-settings@@anp-header-divider-color-toggle": true,
|
||||
"anuppuccin-theme-settings@@h1-weight": 900,
|
||||
"anuppuccin-theme-settings@@h1-line-height": 1.2,
|
||||
"anuppuccin-theme-settings@@anp-h1-divider": true,
|
||||
"anuppuccin-theme-settings@@h2-size": 1.9,
|
||||
"anuppuccin-theme-settings@@h2-weight": 100,
|
||||
"anuppuccin-theme-settings@@h3-size": 1.6,
|
||||
"anuppuccin-theme-settings@@h3-weight": 700,
|
||||
"anuppuccin-theme-settings@@anp-h3-color-custom": "anp-h3-green",
|
||||
"anuppuccin-theme-settings@@h4-weight": 700,
|
||||
"anuppuccin-theme-settings@@h5-weight": 700,
|
||||
"anuppuccin-theme-settings@@h6-size": 1.1,
|
||||
"anuppuccin-theme-settings@@h6-weight": 700,
|
||||
"anuppuccin-theme-settings@@anp-decoration-toggle": true,
|
||||
"anuppuccin-theme-settings@@anp-colorful-frame": true,
|
||||
"anuppuccin-theme-settings@@anp-colorful-frame-opacity": 1,
|
||||
"anuppuccin-theme-settings@@anp-file-icons": true,
|
||||
"anuppuccin-theme-settings@@anp-file-label-align": "0",
|
||||
"anuppuccin-theme-settings@@anp-alt-rainbow-style": "anp-full-rainbow-color-toggle",
|
||||
"anuppuccin-theme-settings@@anp-rainbow-file-toggle": true,
|
||||
"anuppuccin-theme-settings@@anp-rainbow-folder-bg-opacity": 0.9,
|
||||
"anuppuccin-theme-settings@@anp-simple-rainbow-title-toggle": true,
|
||||
"anuppuccin-theme-settings@@anp-simple-rainbow-indentation-toggle": true,
|
||||
"anuppuccin-theme-settings@@anp-stacked-header-width": 30,
|
||||
"anuppuccin-theme-settings@@anp-alt-tab-style": "anp-safari-tab-toggle",
|
||||
"anuppuccin-theme-settings@@anp-alt-tab-custom-height": 40,
|
||||
"anuppuccin-theme-settings@@anp-disable-newtab-align": true,
|
||||
"anuppuccin-theme-settings@@anp-depth-tab-opacity": 0.6,
|
||||
"anuppuccin-theme-settings@@anp-depth-tab-gap": 10,
|
||||
"anuppuccin-theme-settings@@anp-safari-tab-radius": 5,
|
||||
"anuppuccin-theme-settings@@anp-safari-tab-gap": 3,
|
||||
"anuppuccin-theme-settings@@anp-safari-tab-animated": true,
|
||||
"anuppuccin-theme-settings@@anp-layout-select": "anp-card-layout",
|
||||
"anuppuccin-theme-settings@@anp-card-radius": 8,
|
||||
"anuppuccin-theme-settings@@anp-card-layout-padding": 1,
|
||||
"anuppuccin-theme-settings@@anp-card-shadows": true,
|
||||
"anuppuccin-theme-settings@@anp-card-layout-actions": true,
|
||||
"anuppuccin-theme-settings@@anp-card-layout-filebrowser": true,
|
||||
"anuppuccin-theme-settings@@anp-border-radius": 16,
|
||||
"anuppuccin-theme-settings@@anp-border-padding": 20
|
||||
}
|
||||
165
.obsidian/plugins/obsidian-style-settings/main.js
vendored
Normal file
165
.obsidian/plugins/obsidian-style-settings/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
.obsidian/plugins/obsidian-style-settings/manifest.json
vendored
Normal file
10
.obsidian/plugins/obsidian-style-settings/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "obsidian-style-settings",
|
||||
"name": "Style Settings",
|
||||
"version": "1.0.9",
|
||||
"minAppVersion": "0.11.5",
|
||||
"description": "Offers controls for adjusting theme, plugin, and snippet CSS variables.",
|
||||
"author": "mgmeyers",
|
||||
"authorUrl": "https://github.com/mgmeyers/obsidian-style-settings",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
243
.obsidian/plugins/obsidian-style-settings/styles.css
vendored
Normal file
243
.obsidian/plugins/obsidian-style-settings/styles.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
.obsidian/plugins/obsidian42-brat/brat-migrations.json
vendored
Normal file
5
.obsidian/plugins/obsidian42-brat/brat-migrations.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"appliedMigrations": [
|
||||
"tokens-to-secretstorage-v1"
|
||||
]
|
||||
}
|
||||
24
.obsidian/plugins/obsidian42-brat/data.json
vendored
Normal file
24
.obsidian/plugins/obsidian42-brat/data.json
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"pluginList": [
|
||||
"samwarnick/obsidian-simple-embeds"
|
||||
],
|
||||
"pluginSubListFrozenVersion": [
|
||||
{
|
||||
"repo": "samwarnick/obsidian-simple-embeds",
|
||||
"version": "latest"
|
||||
}
|
||||
],
|
||||
"themesList": [],
|
||||
"updateAtStartup": true,
|
||||
"updateThemesAtStartup": true,
|
||||
"enableAfterInstall": true,
|
||||
"loggingEnabled": false,
|
||||
"loggingPath": "BRAT-log",
|
||||
"loggingVerboseEnabled": false,
|
||||
"debuggingMode": false,
|
||||
"notificationsEnabled": true,
|
||||
"globalTokenName": "",
|
||||
"personalAccessToken": "",
|
||||
"selectLatestPluginVersionByDefault": false,
|
||||
"allowIncompatiblePlugins": false
|
||||
}
|
||||
45
.obsidian/plugins/obsidian42-brat/main.js
vendored
Normal file
45
.obsidian/plugins/obsidian42-brat/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
14
.obsidian/plugins/obsidian42-brat/manifest.json
vendored
Normal file
14
.obsidian/plugins/obsidian42-brat/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"id": "obsidian42-brat",
|
||||
"name": "BRAT",
|
||||
"version": "2.0.4",
|
||||
"minAppVersion": "1.11.4",
|
||||
"description": "Easily install a beta version of a plugin for testing.",
|
||||
"author": "TfTHacker",
|
||||
"authorUrl": "https://github.com/TfTHacker/obsidian42-brat",
|
||||
"helpUrl": "https://tfthacker.com/BRAT",
|
||||
"isDesktopOnly": false,
|
||||
"fundingUrl": {
|
||||
"Visit my site": "https://tfthacker.com"
|
||||
}
|
||||
}
|
||||
152
.obsidian/plugins/obsidian42-brat/styles.css
vendored
Normal file
152
.obsidian/plugins/obsidian42-brat/styles.css
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
.brat-modal .modal-button-container {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.brat-modal .disabled-setting {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.brat-modal .disabled-setting:hover {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Input validation styles */
|
||||
.brat-settings .valid-input,
|
||||
.brat-modal .valid-repository {
|
||||
border-color: var(--color-green);
|
||||
}
|
||||
.brat-settings .invalid-input,
|
||||
.brat-modal .invalid-repository {
|
||||
border-color: var(--color-red);
|
||||
}
|
||||
.brat-settings .validation-error,
|
||||
.brat-modal .validation-error {
|
||||
border-color: var(--color-orange);
|
||||
}
|
||||
|
||||
/* Version selector */
|
||||
.brat-version-selector {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
justify-content: left;
|
||||
}
|
||||
|
||||
.brat-token-input {
|
||||
min-width: 33%;
|
||||
}
|
||||
|
||||
/* Token info container styles */
|
||||
.brat-token-info {
|
||||
margin-top: 8px;
|
||||
font-size: 0.8em;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
/* Token status indicators */
|
||||
.brat-token-info.valid,
|
||||
.brat-token-status.valid {
|
||||
color: var(--color-green);
|
||||
}
|
||||
|
||||
.brat-token-info.invalid,
|
||||
.brat-token-status.invalid {
|
||||
color: var(--color-red);
|
||||
}
|
||||
|
||||
.brat-token-info.valid {
|
||||
border-left: 3px solid var(--color-green);
|
||||
}
|
||||
|
||||
.brat-token-info.invalid {
|
||||
border-left: 3px solid var(--color-red);
|
||||
}
|
||||
|
||||
/* Token details and status */
|
||||
.brat-token-status {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.brat-token-details {
|
||||
margin-top: 4px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Token warnings */
|
||||
.brat-token-warning {
|
||||
color: var(--color-orange);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Token additional info */
|
||||
.brat-token-scopes,
|
||||
.brat-token-rate {
|
||||
color: var(--text-muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* Flex break utility */
|
||||
.brat-modal .break {
|
||||
flex-basis: 100%;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Validation status */
|
||||
.brat-modal .validation-status-error {
|
||||
color: var(--text-error);
|
||||
}
|
||||
|
||||
.brat-modal .validation-status {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 0.8em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.confirm-modal .ok-button {
|
||||
margin-right: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* Hide filtered plugin items */
|
||||
.brat-plugin-item[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide filtered theme items */
|
||||
.brat-theme-item[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Filter and button layout */
|
||||
.brat-filter-and-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
|
||||
.brat-filter-input {
|
||||
max-width: 300px;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 4px;
|
||||
background-color: var(--background-secondary);
|
||||
color: var(--text-normal);
|
||||
}
|
||||
|
||||
.brat-filter-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--interactive-accent);
|
||||
}
|
||||
|
||||
.brat-filter-and-button .setting-item {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.brat-filter-and-button .setting-item-control {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
33
.obsidian/plugins/periodic-notes/data.json
vendored
Normal file
33
.obsidian/plugins/periodic-notes/data.json
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"showGettingStartedBanner": true,
|
||||
"hasMigratedDailyNoteSettings": false,
|
||||
"hasMigratedWeeklyNoteSettings": false,
|
||||
"daily": {
|
||||
"format": "YYYY-MM-DD",
|
||||
"template": "",
|
||||
"folder": "Logs/Daily",
|
||||
"enabled": true
|
||||
},
|
||||
"weekly": {
|
||||
"format": "",
|
||||
"template": "",
|
||||
"folder": "Logs/Weekly",
|
||||
"enabled": true
|
||||
},
|
||||
"monthly": {
|
||||
"format": "YYYY-MM",
|
||||
"template": "",
|
||||
"folder": "Logs/Monthly",
|
||||
"enabled": true
|
||||
},
|
||||
"quarterly": {
|
||||
"format": "",
|
||||
"template": "",
|
||||
"folder": ""
|
||||
},
|
||||
"yearly": {
|
||||
"format": "",
|
||||
"template": "",
|
||||
"folder": ""
|
||||
}
|
||||
}
|
||||
5561
.obsidian/plugins/periodic-notes/main.js
vendored
Normal file
5561
.obsidian/plugins/periodic-notes/main.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
10
.obsidian/plugins/periodic-notes/manifest.json
vendored
Normal file
10
.obsidian/plugins/periodic-notes/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "periodic-notes",
|
||||
"name": "Periodic Notes",
|
||||
"description": "Create/manage your daily, weekly, and monthly notes",
|
||||
"version": "0.0.17",
|
||||
"author": "Liam Cain",
|
||||
"authorUrl": "https://github.com/liamcain/",
|
||||
"isDesktopOnly": false,
|
||||
"minAppVersion": "0.10.11"
|
||||
}
|
||||
30
.obsidian/plugins/periodic-notes/styles.css
vendored
Normal file
30
.obsidian/plugins/periodic-notes/styles.css
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
.periodic-modal {
|
||||
min-width: 40vw;
|
||||
}
|
||||
|
||||
.settings-banner {
|
||||
background-color: var(--background-primary-alt);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
padding: 1.5em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.settings-banner h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.settings-banner h4 {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
.has-error {
|
||||
color: var(--text-error);
|
||||
}
|
||||
|
||||
input.has-error {
|
||||
color: var(--text-error);
|
||||
border-color: var(--text-error);
|
||||
}
|
||||
1
.obsidian/plugins/simple-embeds/genericPreviewCache.json
vendored
Normal file
1
.obsidian/plugins/simple-embeds/genericPreviewCache.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
29773
.obsidian/plugins/simple-embeds/main.js
vendored
Normal file
29773
.obsidian/plugins/simple-embeds/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
.obsidian/plugins/simple-embeds/manifest.json
vendored
Normal file
1
.obsidian/plugins/simple-embeds/manifest.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"id":"simple-embeds","name":"Simple Embeds","version":"1.15.0","minAppVersion":"0.15.0","description":"Replaces links, like Twitter and YouTube, with embeds when previewing a file.","author":"Sam Warnick","authorUrl":"https://github.com/samwarnick","isDesktopOnly":false}
|
||||
233
.obsidian/plugins/simple-embeds/styles.css
vendored
Normal file
233
.obsidian/plugins/simple-embeds/styles.css
vendored
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
.embed-container {
|
||||
max-width: 550px; /* This is the max width of Twitter embeds */
|
||||
}
|
||||
.is-live-preview .embed-container.hide-link ~ span.external-link {
|
||||
display: none;
|
||||
}
|
||||
.embed-container.center {
|
||||
margin: 0 auto;
|
||||
}
|
||||
.embed-container.full-width {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
/* Instagram */
|
||||
.embed-container.instagram iframe {
|
||||
width: 100%;
|
||||
max-width: 550px;
|
||||
}
|
||||
.embed-container.instagram blockquote {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Noteflight and Flat.io */
|
||||
.embed-container:is(.flat_io, .noteflight) {
|
||||
max-width: 750px;
|
||||
}
|
||||
.embed-container.flat_io iframe {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
.embed-container.noteflight iframe {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
/* GitHub Gists */
|
||||
.embed-container.github_gist {
|
||||
max-width: 100%;
|
||||
}
|
||||
.embed-container.github_gist iframe {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* YouTube */
|
||||
.video-wrapper {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
min-width: 300px;
|
||||
min-height: calc(300px * 0.5625);
|
||||
}
|
||||
.video-wrapper iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Apple Podcasts & TV */
|
||||
|
||||
.embed-container.apple-podcasts iframe,
|
||||
.embed-container.apple-tv iframe {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.embed-container.apple-tv .fake-link {
|
||||
display: block;
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
top: calc(50% - 75px);
|
||||
left: calc(50% - 75px);
|
||||
}
|
||||
|
||||
/* Generic Preview */
|
||||
.embed-container.generic-preview .preview {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
background: var(--background-secondary);
|
||||
border: 1px solid var(--background-modifier-border);;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.embed-container.generic-preview .preview:hover {
|
||||
background: var(--background-secondary-alt);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.embed-container.generic-preview .preview .image-container {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.embed-container.generic-preview .preview .content {
|
||||
margin: 0.5rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.embed-container.generic-preview .preview .content .title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.embed-container.generic-preview .preview .content .description {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
.simple-embeds-settings details > summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.simple-embeds-settings details > summary::before {
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
content: "";
|
||||
font-size: 9px;
|
||||
margin-right: 5px;
|
||||
display: inline-block;
|
||||
vertical-align: -0.3em;
|
||||
background-color: currentColor;
|
||||
/* Icon from https://heroicons.com */
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='h-6 w-6' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5l7 7-7 7' /%3E%3C/svg%3E");
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.simple-embeds-settings details[open] > summary::before {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.simple-embeds-settings details > summary h4 {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
/* https://github.com/paulirish/lite-youtube-embed */
|
||||
|
||||
lite-youtube {
|
||||
background-color: #000;
|
||||
position: relative;
|
||||
display: block;
|
||||
contain: content;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
cursor: pointer;
|
||||
/* max-width: 720px; */
|
||||
}
|
||||
|
||||
/* gradient */
|
||||
lite-youtube::before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);
|
||||
background-position: top;
|
||||
background-repeat: repeat-x;
|
||||
height: 60px;
|
||||
padding-bottom: 50px;
|
||||
width: 100%;
|
||||
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* responsive iframe with a 16:9 aspect ratio
|
||||
thanks https://css-tricks.com/responsive-iframes/
|
||||
*/
|
||||
lite-youtube::after {
|
||||
content: "";
|
||||
display: block;
|
||||
padding-bottom: calc(100% / (16 / 9));
|
||||
}
|
||||
lite-youtube > iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* play button */
|
||||
lite-youtube > .lty-playbtn {
|
||||
width: 68px;
|
||||
height: 48px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
background-color: transparent;
|
||||
/* YT's actual play button svg */
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 68 48"><path fill="%23f00" fill-opacity="0.8" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z"></path><path d="M 45,24 27,14 27,34" fill="%23fff"></path></svg>');
|
||||
filter: grayscale(100%);
|
||||
transition: filter 0.1s cubic-bezier(0, 0, 0.2, 1);
|
||||
border: none;
|
||||
}
|
||||
|
||||
lite-youtube:hover > .lty-playbtn,
|
||||
lite-youtube .lty-playbtn:focus {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
/* Post-click styles */
|
||||
lite-youtube.lyt-activated {
|
||||
cursor: unset;
|
||||
}
|
||||
lite-youtube.lyt-activated::before,
|
||||
lite-youtube.lyt-activated > .lty-playbtn {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.lyt-visually-hidden {
|
||||
clip: rect(0 0 0 0);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
width: 1px;
|
||||
}
|
||||
10
.obsidian/plugins/url-into-selection/main.js
vendored
Normal file
10
.obsidian/plugins/url-into-selection/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
.obsidian/plugins/url-into-selection/manifest.json
vendored
Normal file
8
.obsidian/plugins/url-into-selection/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"id": "url-into-selection",
|
||||
"name": "Paste URL into selection",
|
||||
"description": "Paste URL \"into\" selected text to create markdown links.",
|
||||
"isDesktopOnly": false,
|
||||
"js": "main.js",
|
||||
"version": "1.11.4"
|
||||
}
|
||||
7
.obsidian/themes/AnuPpuccin/manifest.json
vendored
Normal file
7
.obsidian/themes/AnuPpuccin/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "AnuPpuccin",
|
||||
"version": "1.5.0",
|
||||
"minAppVersion": "1.6.0",
|
||||
"author": "Anubis",
|
||||
"authorUrl": "https://github.com/AnubisNekhet"
|
||||
}
|
||||
9080
.obsidian/themes/AnuPpuccin/theme.css
vendored
Normal file
9080
.obsidian/themes/AnuPpuccin/theme.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
229
.obsidian/workspace.json
vendored
Normal file
229
.obsidian/workspace.json
vendored
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
{
|
||||
"main": {
|
||||
"id": "b0766bfba6d96ad8",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "4b28d70396ab62d5",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "523c3454e17a9af2",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "graph",
|
||||
"state": {},
|
||||
"icon": "lucide-git-fork",
|
||||
"title": "Graph view"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
},
|
||||
"left": {
|
||||
"id": "8528e1a663696326",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "c045a6b5ec351697",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "ad7cc2b439bb5c9f",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "file-explorer",
|
||||
"state": {
|
||||
"sortOrder": "alphabetical",
|
||||
"autoReveal": false
|
||||
},
|
||||
"icon": "lucide-folder-closed",
|
||||
"title": "Files"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "20989f7c8b992439",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical"
|
||||
},
|
||||
"icon": "lucide-search",
|
||||
"title": "Search"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "a002966c4fa46607",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bookmarks",
|
||||
"state": {},
|
||||
"icon": "lucide-bookmark",
|
||||
"title": "Bookmarks"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
},
|
||||
"right": {
|
||||
"id": "e0cdc4032215366b",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "27da5e0ee1de57f9",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "6b1b368c90d05e2a",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "Welcome.md",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
"showSearch": false,
|
||||
"searchQuery": "",
|
||||
"backlinkCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-coming-in",
|
||||
"title": "Backlinks for Welcome"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "4332f773df6d8a0f",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"file": "Welcome.md",
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-going-out",
|
||||
"title": "Outgoing links from Welcome"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "002b8fa5c591bb38",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "tag",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"useHierarchy": true,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-tags",
|
||||
"title": "Tags"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3281458928b919ae",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "all-properties",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-archive",
|
||||
"title": "All properties"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "12a906ccddab91be",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "Welcome.md",
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "Outline of Welcome"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c8a7d7be0e633299",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "calendar",
|
||||
"state": {},
|
||||
"icon": "calendar-with-checkmark",
|
||||
"title": "Calendar"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "42cff20645d08777",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "git-view",
|
||||
"state": {},
|
||||
"icon": "git-pull-request",
|
||||
"title": "Source Control"
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 6
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
},
|
||||
"left-ribbon": {
|
||||
"hiddenItems": {
|
||||
"switcher:Open quick switcher": false,
|
||||
"graph:Open graph view": false,
|
||||
"canvas:Create new canvas": false,
|
||||
"daily-notes:Open today's daily note": false,
|
||||
"templates:Insert template": false,
|
||||
"command-palette:Open command palette": false,
|
||||
"bases:Create new base": false,
|
||||
"obsidian-git:Open Git source control": false,
|
||||
"obsidian42-brat:BRAT": false,
|
||||
"periodic-notes:Open today": false
|
||||
}
|
||||
},
|
||||
"active": "523c3454e17a9af2",
|
||||
"lastOpenFiles": [
|
||||
"Ideas/Simmering/3d printed suction ash tray.md",
|
||||
"Ideas/Ongoing/Optimus.md",
|
||||
"Ideas/Ongoing/bubb.is.md",
|
||||
"Ideas/Fresh/agentic vm manager.md",
|
||||
"Projects/Thinking/GodHand - Agentic VM Manager.md",
|
||||
"Learning/Ongoing/AI.md",
|
||||
"Learning/Back Burner/Linux Foundation.md",
|
||||
"Learning/Back Burner",
|
||||
"Learning/Ongoing",
|
||||
"Learning",
|
||||
"Projects/Doing/Pelagia Portal.md",
|
||||
"Projects/Doing",
|
||||
"Projects/Thinking",
|
||||
"Projects",
|
||||
"Logs/Daily/2026-05-24.md",
|
||||
"Ideas/Fresh",
|
||||
"Ideas/Simmering",
|
||||
"Scratchpad/test.md",
|
||||
"Scratchpad",
|
||||
"Resources/Templates",
|
||||
"Welcome.md"
|
||||
]
|
||||
}
|
||||
3
Ideas/Fresh/agentic vm manager.md
Normal file
3
Ideas/Fresh/agentic vm manager.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
A project that focuses specifically on an AI agent that spins up, configures, and controls a full desktop VM (think: agent opens a browser, uses GUI apps, takes screenshots to verify state). Tools like OpenClaw touch on this but it's not their core focus. This project focuses on the combination of VM orchestration + computer-use-style agents.
|
||||
|
||||
Can be used to develop and test non native applications. Example - swift, android, etc
|
||||
1
Ideas/Ongoing/Optimus.md
Normal file
1
Ideas/Ongoing/Optimus.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Optimus is a remote pc/server management tool
|
||||
1
Ideas/Ongoing/bubb.is.md
Normal file
1
Ideas/Ongoing/bubb.is.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
A relationship portal
|
||||
1
Ideas/Simmering/3d printed suction ash tray.md
Normal file
1
Ideas/Simmering/3d printed suction ash tray.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
self explanatory - stick it anywhere
|
||||
0
Learning/Back Burner/Linux Foundation.md
Normal file
0
Learning/Back Burner/Linux Foundation.md
Normal file
0
Learning/Ongoing/AI.md
Normal file
0
Learning/Ongoing/AI.md
Normal file
4
Logs/Daily/2026-05-24.md
Normal file
4
Logs/Daily/2026-05-24.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Installed obsidian for the first time today
|
||||
Woke up to a beautiful day
|
||||
Had tea for breakfast and spoke to Appu
|
||||
Momo had his UPSC exam today
|
||||
0
Projects/Doing/Pelagia Portal.md
Normal file
0
Projects/Doing/Pelagia Portal.md
Normal file
40
Projects/Thinking/GodHand - Agentic VM Manager.md
Normal file
40
Projects/Thinking/GodHand - Agentic VM Manager.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[[agentic vm manager]]
|
||||
|
||||
# Plan
|
||||
**Positioning**
|
||||
|
||||
The wedge is "agent owns the VM lifecycle, not just the screen." Most computer-use demos assume a desktop already exists; OpenClaw, Anthropic's reference container, and Self-Operating Computer mostly treat the VM as a given. Your project treats `spin up → configure → drive → snapshot → tear down` as one programmable surface. Call out two concrete capabilities competitors lack: (1) the agent can request a fresh, reproducible desktop per task, and (2) it can snapshot/branch state mid-task to explore alternatives or retry from a known-good checkpoint. That framing alone gives the repo a clear reason to exist.
|
||||
|
||||
**Architecture sketch**
|
||||
|
||||
Four layers, kept deliberately small:
|
||||
|
||||
1. _VM substrate_ — Docker+VNC for the default path (fast, cross-platform, easy for contributors to run), QEMU/KVM as an optional backend for full-OS scenarios. Expose both behind one `Sandbox` interface with `create`, `snapshot`, `restore`, `destroy`, `exec`.
|
||||
2. _Capture/control_ — screenshots via VNC framebuffer or `scrot`; input via `xdotool` or direct VNC events. Keep latency budget under ~300ms round-trip or the agent loop gets painful.
|
||||
3. _Agent loop_ — Claude (or any vision LLM) in a perceive→plan→act→verify cycle. The verify step is where most projects cut corners; make it a first-class screenshot-diff + assertion mechanism.
|
||||
4. _Orchestrator_ — Python service exposing a task API: "given this goal and this base image, return a trace." Traces are the artifact you publish.
|
||||
|
||||
**8-week milestone plan**
|
||||
|
||||
Weeks 1–2: Docker+VNC sandbox with clean lifecycle API, screenshot capture, basic input injection. Goal: a script that boots a fresh Ubuntu+Firefox container, takes a screenshot, clicks a button, exits cleanly.
|
||||
|
||||
Weeks 3–4: Agent loop with Claude's computer-use API. Get one end-to-end task working reliably (e.g., "open Firefox, search Wikipedia for X, screenshot the result"). Build the trace format here — every step logged with screenshot, action, model reasoning.
|
||||
|
||||
Weeks 5–6: Snapshot/restore as a first-class primitive. This is your differentiator. Implement branching: agent hits a decision point, forks the VM, tries both paths, picks the winner. Even a toy demo of this is rare and memorable.
|
||||
|
||||
Week 7: QEMU backend for one "real OS" demo (installing software, multi-app workflows). Doesn't need parity with Docker path; just prove the abstraction holds.
|
||||
|
||||
Week 8: Benchmark suite (10–20 tasks), README, demo video, blog post. The video matters more than you'd think for portfolio reach.
|
||||
|
||||
**Things worth deciding now**
|
||||
|
||||
A benchmark gives the project teeth — even a small homegrown one (file management, browser tasks, multi-app workflows) lets you make claims with numbers. OSWorld and WebArena exist if you want external comparison, but adapting them costs a week; consider whether that's worth it for your goals.
|
||||
|
||||
Pick a license early (Apache-2.0 is the path of least resistance for portfolio work). And decide upfront whether the agent layer is pluggable or Claude-specific — pluggable is more work but dramatically expands who'll try it.
|
||||
|
||||
**Prior art to study before you start**
|
||||
|
||||
Anthropic's computer-use reference implementation (the Docker container is a useful baseline to surpass), OpenClaw, Self-Operating Computer, OSWorld, and Microsoft's OmniParser. Spend a day reading their code before writing yours — you'll find each one has a specific weakness your project can address explicitly in the README.
|
||||
|
||||
Want me to go deeper on any piece — the snapshot/branching design, the trace format, or the benchmark task list?
|
||||
|
||||
Loading…
Add table
Reference in a new issue