Initial commit

This commit is contained in:
Torsten 2025-06-04 21:07:47 +02:00
commit cb3787b025
92 changed files with 309904 additions and 0 deletions

13
RPG/.obsidian/app.json vendored Normal file
View file

@ -0,0 +1,13 @@
{
"promptDelete": false,
"spellcheck": false,
"alwaysUpdateLinks": true,
"readableLineLength": false,
"pdfExportSettings": {
"includeName": true,
"pageSize": "A4",
"landscape": false,
"margin": "1",
"downscalePercent": 100
}
}

4
RPG/.obsidian/appearance.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"cssTheme": "ITS Theme",
"nativeMenus": false
}

8
RPG/.obsidian/community-plugins.json vendored Normal file
View file

@ -0,0 +1,8 @@
[
"obsidian-style-settings",
"fantasy-name",
"fantasy-content-generator",
"obsidian-excalidraw-plugin",
"oz-clear-unused-images",
"mousewheel-image-zoom"
]

31
RPG/.obsidian/core-plugins.json vendored Normal file
View file

@ -0,0 +1,31 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"properties": false,
"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,
"webviewer": false
}

22
RPG/.obsidian/graph.json vendored Normal file
View 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
}

22
RPG/.obsidian/hotkeys.json vendored Normal file
View file

@ -0,0 +1,22 @@
{
"fantasy-name:fantasy-name-insert-human-male": [
{
"modifiers": [
"Alt",
"Mod",
"Shift"
],
"key": "M"
}
],
"fantasy-name:fantasy-name-insert-human-female": [
{
"modifiers": [
"Alt",
"Mod",
"Shift"
],
"key": "F"
}
]
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,9 @@
{
"id": "fantasy-content-generator",
"name": "Fantasy Content Generator",
"version": "1.2.4",
"minAppVersion": "0.15.0",
"description": "A Fantasy Content Generator for Obsidian for All Your TTRPG / World Building Needs",
"author": "Gregory Jagermeister ",
"isDesktopOnly": false
}

View file

@ -0,0 +1,36 @@
.theme-light .OFCGDetails {
border: 1px solid #ccc;
box-shadow: 0px 12px 0px 0px rgba(255, 255, 255, 0.37);
background-color: #f0f0f0;
}
.theme-light .OFCGDetails[open] summary {
border-bottom: 1px solid #666;
margin-bottom: 0.5em;
}
.theme-dark .OFCGDetails {
border: 1px solid #272727;
box-shadow: 0px 12px 0px 0px rgba(0, 0, 0, 0.37);
background-color: #313131;
padding: 0.5em 0.5em 0.5em;
margin: 1em;
}
.OFCGSSummary {
font-weight: bold;
margin: -0.5em -0.5em 0.5em;
padding: 0.5em;
}
.OFCGDetails[open] {
padding: 0.5em;
}
.theme-dark .OFCGDetails[open] summary {
border-bottom: 1px solid #aaa;
margin-bottom: 0.5em;
}
.FCGInput>input[type="file"] {
display: none;
}

View file

@ -0,0 +1,128 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// index.ts
var fantasy_name_exports = {};
__export(fantasy_name_exports, {
default: () => FantasyNameGenerator
});
module.exports = __toCommonJS(fantasy_name_exports);
var import_obsidian = require("obsidian");
var insertName = (editor, name) => {
const cursor = editor.getCursor();
editor.replaceRange(name, cursor);
editor.setCursor(cursor.line, cursor.ch + name.length);
};
var API_URL = "https://fantasyname.lukewh.com?family=t";
var editorCallback = async (editor, { gender, ancestry, family }) => {
let url = API_URL;
const params = [];
if (gender) {
params.push(`gender=${gender}`);
}
if (ancestry) {
params.push(`ancestry=${ancestry}`);
}
if (params.length) {
url = `${url}&${params.join("&")}`;
}
const resp = await (0, import_obsidian.requestUrl)(url);
const name = resp.text;
new import_obsidian.Notice(`Name: ${name}`);
insertName(editor, name);
};
var FantasyNameGenerator = class extends import_obsidian.Plugin {
async onload() {
console.log("loading fantasy-name plugin");
const commands = [
{
id: "fantasy-name-insert-human",
name: "Insert fantasy name: Human",
editorCallback: (editor) => editorCallback(editor, {})
},
{
id: "fantasy-name-insert-human-female",
name: "Insert fantasy name: Human - Female",
editorCallback: (editor) => editorCallback(editor, { gender: "f" /* FEMALE */ })
},
{
id: "fantasy-name-insert-human-male",
name: "Insert fantasy name: Human - Male",
editorCallback: (editor) => editorCallback(editor, { gender: "m" /* MALE */ })
},
{
id: "fantasy-name-insert-elf",
name: "Insert fantasy name: Elf",
editorCallback: (editor) => editorCallback(editor, { ancestry: "e" /* ELF */ })
},
{
id: "fantasy-name-insert-elf-female",
name: "Insert fantasy name: Elf - Female",
editorCallback: (editor) => editorCallback(editor, { ancestry: "e" /* ELF */, gender: "f" /* FEMALE */ })
},
{
id: "fantasy-name-insert-elf-male",
name: "Insert fantasy name: Elf - Male",
editorCallback: (editor) => editorCallback(editor, { ancestry: "e" /* ELF */, gender: "m" /* MALE */ })
},
{
id: "fantasy-name-insert-dwarf",
name: "Insert fantasy name: Dwarf",
editorCallback: (editor) => editorCallback(editor, { ancestry: "d" /* DWARF */ })
},
{
id: "fantasy-name-insert-dwarf-female",
name: "Insert fantasy name: Dwarf - Female",
editorCallback: (editor) => editorCallback(editor, { ancestry: "d" /* DWARF */, gender: "f" /* FEMALE */ })
},
{
id: "fantasy-name-insert-dwarf-male",
name: "Insert fantasy name: Dwarf - Male",
editorCallback: (editor) => editorCallback(editor, { ancestry: "d" /* DWARF */, gender: "m" /* MALE */ })
},
{
id: "fantasy-name-insert-orc",
name: "Insert fantasy name: Orc",
editorCallback: (editor) => editorCallback(editor, { ancestry: "o" /* ORC */ })
},
{
id: "fantasy-name-insert-orc-female",
name: "Insert fantasy name: Orc - Female",
editorCallback: (editor) => editorCallback(editor, { ancestry: "o" /* ORC */, gender: "f" /* FEMALE */ })
},
{
id: "fantasy-name-insert-orc-male",
name: "Insert fantasy name: Orc - Male",
editorCallback: (editor) => editorCallback(editor, { ancestry: "o" /* ORC */, gender: "m" /* MALE */ })
}
];
for (const command of commands) {
this.addCommand(command);
}
}
onunload() {
console.log("unloading fantasy-name plugin");
}
};
/* nosourcemap */

View file

@ -0,0 +1,11 @@
{
"id": "fantasy-name",
"name": "Fantasy name generator",
"version": "0.1.0",
"minAppVersion": "1.3.5",
"description": "Insert a random fantasy name.",
"author": "Lukewh",
"authorUrl": "https://lukewh.com",
"fundingUrl": "https://ko-fi.com/lukewh",
"isDesktopOnly": false
}

View file

@ -0,0 +1,525 @@
/*
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());
});
}
/**
* ReplaceTerm enables us to store the parameters for a replacement to add a new size parameter.
*/
class ReplaceTerm {
constructor(replaceFrom, replaceWith) {
this.replaceFrom = replaceFrom;
this.replaceWith = replaceWith;
}
// Generate a string that can be used in a string.replace() call as the string to replace
getReplaceFromString(oldSize) {
return this.replaceFrom(oldSize);
}
// Generate a string that can be used in a string.replace() call as the replacement string
getReplaceWithString(newSize) {
return this.replaceWith(newSize);
}
}
class Util {
/**
* For a given file content decide if a string is inside a table
* @param searchString string
* @param fileValue file content
* @private
*/
static isInTable(searchString, fileValue) {
return fileValue.search(new RegExp(`^\\|.+${searchString}.+\\|$`, "m")) !== -1;
}
/**
* Get the image name from a given src uri of a local image
* (URI like app://local/C:/.../image.png?1677337704730)
* @param imageUri uri of the image
* @private
*/
static getLocalImageNameFromUri(imageUri) {
imageUri = decodeURI(imageUri);
const imageNameMatch = imageUri.match(/([^\/?\\]+)(\?.*?|)$/);
const imageName = imageNameMatch ? imageNameMatch[1] : "";
// Handle linux not correctly decoding the %2F before the Filename to a \
const hasLinuxDecodingIssue = imageName.startsWith("2F");
return hasLinuxDecodingIssue ? imageName.slice(2) : imageName;
}
/**
* Get the parameters needed to handle the zoom for a local image.
* Source can be either a obsidian link like [[image.png]] or a markdown link like [image.png](image.png)
* @param imageName Name of the image
* @param fileText content of the current file
* @returns parameters to handle the zoom
*/
static getLocalImageZoomParams(imageName, fileText) {
imageName = this.determineImageName(imageName, fileText);
// Get the folder name if the image is located in a folder
const folderName = this.getFolderNameIfExist(imageName, fileText);
imageName = `${folderName}${imageName}`;
const isInTable = Util.isInTable(imageName, fileText);
// Separator to use for the replacement
const sizeSeparator = isInTable ? "\\|" : "|";
// Separator to use for the regex: isInTable ? \\\| : \|
const regexSeparator = isInTable ? "\\\\\\|" : "\\|";
const imageAttributes = this.getImageAttributes(imageName, fileText);
imageName = `${imageName}${imageAttributes}`;
// check character before the imageName to check if markdown link or obsidian link
const imageNamePosition = fileText.indexOf(imageName);
const isObsidianLink = fileText.charAt(imageNamePosition - 1) === "[";
if (isObsidianLink) {
return Util.generateReplaceTermForObsidianSyntax(imageName, regexSeparator, sizeSeparator);
}
else {
return Util.generateReplaceTermForMarkdownSyntax(imageName, regexSeparator, sizeSeparator, fileText);
}
}
/**
* When using markdown link syntax the image name can be encoded. This function checks if the image name is encoded and if not encodes it.
*
* @param origImageName Image name
* @param fileText File content
* @returns image name with the correct encoding
*/
static determineImageName(origImageName, fileText) {
const encodedImageName = encodeURI(origImageName);
const spaceEncodedImageName = origImageName.replace(/ /g, "%20");
// Try matching original, full URI encoded, and space encoded
const imageNameVariants = [origImageName, encodedImageName, spaceEncodedImageName];
for (const variant of imageNameVariants) {
if (fileText.includes(variant)) {
return variant;
}
}
throw new Error("Image not found in file");
}
/**
* Extracts the folder name from the given image name by looking for the first "[" or "(" character
* that appears before the image name in the file text.
* @param imageName The name of the image.
* @param fileText The text of the file that contains the image.
* @returns The name of the folder that contains the image, or an empty string if no folder is found.
*/
static getFolderNameIfExist(imageName, fileText) {
const index = fileText.indexOf(imageName);
if (index === -1) {
throw new Error("Image not found in file");
}
const stringBeforeFileName = fileText.substring(0, index);
const lastOpeningBracket = stringBeforeFileName.lastIndexOf("["); // Obsidian link
const lastOpeningParenthesis = stringBeforeFileName.lastIndexOf("("); // Markdown link
const lastOpeningBracketOrParenthesis = Math.max(lastOpeningBracket, lastOpeningParenthesis);
const folderName = stringBeforeFileName.substring(lastOpeningBracketOrParenthesis + 1);
return folderName;
}
/**
* Extracts any image attributes like |ctr for ITS Theme that appear after the given image name in the file.
* @param imageName - The name of the image to search for.
* @param fileText - The content of the file to search in.
* @returns A string containing any image attributes that appear after the image name.
*/
static getImageAttributes(imageName, fileText) {
const index = fileText.indexOf(imageName);
const stringAfterFileName = fileText.substring(index + imageName.length);
const regExpMatchArray = stringAfterFileName.match(/([^\]]*?)\\?\|\d+]]|([^\]]*?)]]|/);
if (regExpMatchArray) {
if (!!regExpMatchArray[1]) {
return regExpMatchArray[1];
}
else if (!!regExpMatchArray[2]) {
return regExpMatchArray[2];
}
}
return "";
}
/**
* Get the parameters needed to handle the zoom for images in markdown format.
* Example: ![image.png](image.png)
* @param imageName Name of the image
* @param fileText content of the current file
* @returns parameters to handle the zoom
* @private
*
*/
static generateReplaceTermForMarkdownSyntax(imageName, regexSeparator, sizeSeparator, fileText) {
const sizeMatchRegExp = new RegExp(`${regexSeparator}(\\d+)]${escapeRegex("(" + imageName + ")")}`);
const replaceSizeExistFrom = (oldSize) => `${sizeSeparator}${oldSize}](${imageName})`;
const replaceSizeExistWith = (newSize) => `${sizeSeparator}${newSize}](${imageName})`;
const replaceSizeNotExistsFrom = (oldSize) => `](${imageName})`;
const replaceSizeNotExistsWith = (newSize) => `${sizeSeparator}${newSize}](${imageName})`;
const replaceSizeExist = new ReplaceTerm(replaceSizeExistFrom, replaceSizeExistWith);
const replaceSizeNotExist = new ReplaceTerm(replaceSizeNotExistsFrom, replaceSizeNotExistsWith);
return {
sizeMatchRegExp: sizeMatchRegExp,
replaceSizeExist: replaceSizeExist,
replaceSizeNotExist: replaceSizeNotExist,
};
}
/**
* Get the parameters needed to handle the zoom for images in markdown format.
* Example: ![[image.png]]
* @param imageName Name of the image
* @param fileText content of the current file
* @returns parameters to handle the zoom
* @private
*
*/
static generateReplaceTermForObsidianSyntax(imageName, regexSeparator, sizeSeparator) {
const sizeMatchRegExp = new RegExp(`${escapeRegex(imageName)}${regexSeparator}(\\d+)`);
const replaceSizeExistFrom = (oldSize) => `${imageName}${sizeSeparator}${oldSize}`;
const replaceSizeExistWith = (newSize) => `${imageName}${sizeSeparator}${newSize}`;
const replaceSizeNotExistsFrom = (oldSize) => `${imageName}`;
const replaceSizeNotExistsWith = (newSize) => `${imageName}${sizeSeparator}${newSize}`;
const replaceSizeExist = new ReplaceTerm(replaceSizeExistFrom, replaceSizeExistWith);
const replaceSizeNotExist = new ReplaceTerm(replaceSizeNotExistsFrom, replaceSizeNotExistsWith);
return {
sizeMatchRegExp: sizeMatchRegExp,
replaceSizeExist: replaceSizeExist,
replaceSizeNotExist: replaceSizeNotExist,
};
}
/**
* Get the parameters needed to handle the zoom for a remote image.
* Format: https://www.example.com/image.png
* @param imageUri URI of the image
* @param fileText content of the current file
* @returns parameters to handle the zoom
*/
static getRemoteImageZoomParams(imageUri, fileText) {
const isInTable = Util.isInTable(imageUri, fileText);
// Separator to use for the replacement
const sizeSeparator = isInTable ? "\\|" : "|";
// Separator to use for the regex: isInTable ? \\\| : \|
const regexSeparator = isInTable ? "\\\\\\|" : "\\|";
return Util.generateReplaceTermForMarkdownSyntax(imageUri, regexSeparator, sizeSeparator, fileText);
}
}
/**
* Function to escape a string into a valid searchable string for a regex
* @param string string to escape
* @returns escaped string
*/
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
var ModifierKey;
(function (ModifierKey) {
ModifierKey["ALT"] = "AltLeft";
ModifierKey["CTRL"] = "ControlLeft";
ModifierKey["SHIFT"] = "ShiftLeft";
ModifierKey["ALT_RIGHT"] = "AltRight";
ModifierKey["CTRL_RIGHT"] = "ControlRight";
ModifierKey["SHIFT_RIGHT"] = "ShiftRight";
})(ModifierKey || (ModifierKey = {}));
const DEFAULT_SETTINGS = {
modifierKey: ModifierKey.ALT,
stepSize: 25,
initialSize: 500
};
class MouseWheelZoomPlugin extends obsidian.Plugin {
constructor() {
super(...arguments);
this.isKeyHeldDown = false;
this.wheelOpt = { passive: false, capture: true };
this.wheelEvent = 'wheel';
}
onload() {
return __awaiter(this, void 0, void 0, function* () {
yield this.loadSettings();
this.registerEvent(this.app.workspace.on("window-open", (newWindow) => this.registerEvents(newWindow.win)));
this.registerEvents(window);
this.addSettingTab(new MouseWheelZoomSettingsTab(this.app, this));
console.log("Loaded: Mousewheel image zoom");
});
}
/**
* When the config key is released, we enable the scroll again and reset the key held down flag.
*/
onConfigKeyUp(currentWindow) {
this.isKeyHeldDown = false;
this.enableScroll(currentWindow);
}
onunload(currentWindow = window) {
// Re-enable the normal scrolling behavior when the plugin unloads
this.enableScroll(currentWindow);
}
/**
* Registers image resizing events for the specified window
* @param currentWindow window in which to register events
* @private
*/
registerEvents(currentWindow) {
const doc = currentWindow.document;
this.registerDomEvent(doc, "keydown", (evt) => {
if (evt.code === this.settings.modifierKey.toString()) {
this.isKeyHeldDown = true;
if (this.settings.modifierKey !== ModifierKey.SHIFT && this.settings.modifierKey !== ModifierKey.SHIFT_RIGHT) { // Ignore shift to allow horizontal scrolling
// Disable the normal scrolling behavior when the key is held down
this.disableScroll(currentWindow);
}
}
});
this.registerDomEvent(doc, "keyup", (evt) => {
if (evt.code === this.settings.modifierKey.toString()) {
this.onConfigKeyUp(currentWindow);
}
});
this.registerDomEvent(doc, "wheel", (evt) => {
if (this.isKeyHeldDown) {
// When for example using Alt + Tab to switch between windows, the key is still recognized as held down.
// We check if the key is really held down by checking if the key is still pressed in the event when the
// wheel event is triggered.
if (!this.isConfiguredKeyDown(evt)) {
this.onConfigKeyUp(currentWindow);
return;
}
const eventTarget = evt.target;
const targetIsCanvas = eventTarget.hasClass("canvas-node-content-blocker");
const targetIsCanvasNode = eventTarget.closest(".canvas-node-content") !== null;
const targetIsImage = eventTarget.nodeName === "IMG";
if (targetIsCanvas || targetIsCanvasNode || targetIsImage) {
this.disableScroll(currentWindow);
}
if (targetIsCanvas) {
// seems we're trying to zoom on some canvas node.
this.handleZoomForCanvas(evt, eventTarget);
}
else if (targetIsCanvasNode) ;
else if (targetIsImage) {
// Handle the zooming of the image
this.handleZoom(evt, eventTarget);
}
}
});
}
/**
* Handles zooming with the mousewheel on canvas node
* @param evt wheel event
* @param eventTarget targeted canvas node element
* @private
*/
handleZoomForCanvas(evt, eventTarget) {
// get active canvas
const isCanvas = this.app.workspace.getActiveViewOfType(obsidian.View).getViewType() === "canvas";
if (!isCanvas) {
throw new Error("Can't find canvas");
}
// Unfortunately the current type definitions don't include any canvas functionality...
const canvas = this.app.workspace.getActiveViewOfType(obsidian.View).canvas;
// get triggered canvasNode
const canvasNode = Array.from(canvas.nodes.values())
.find(node => node.contentBlockerEl == eventTarget);
// Adjust delta based on the direction of the resize
let delta = evt.deltaY > 0 ? this.settings.stepSize : this.settings.stepSize * -1;
// Calculate new dimensions directly using the delta and aspectRatio
const aspectRatio = canvasNode.width / canvasNode.height;
const newWidth = canvasNode.width + delta;
const newHeight = newWidth / aspectRatio;
// Resize the canvas node using the new dimensions
canvasNode.resize({ width: newWidth, height: newHeight });
}
/**
* Handles zooming with the mousewheel on an image
* @param evt wheel event
* @param eventTarget targeted image element
* @private
*/
handleZoom(evt, eventTarget) {
return __awaiter(this, void 0, void 0, function* () {
const imageUri = eventTarget.attributes.getNamedItem("src").textContent;
const activeFile = yield this.getActivePaneWithImage(eventTarget);
let fileText = yield this.app.vault.read(activeFile);
const originalFileText = fileText;
// Get parameters like the regex or the replacement terms based on the fact if the image is locally stored or not.
const zoomParams = this.getZoomParams(imageUri, fileText, eventTarget);
// Check if there is already a size parameter for this image.
const sizeMatches = fileText.match(zoomParams.sizeMatchRegExp);
// Element already has a size entry
if (sizeMatches !== null) {
const oldSize = parseInt(sizeMatches[1]);
let newSize = oldSize;
if (evt.deltaY < 0) {
newSize += this.settings.stepSize;
}
else if (evt.deltaY > 0 && newSize > this.settings.stepSize) {
newSize -= this.settings.stepSize;
}
fileText = fileText.replace(zoomParams.replaceSizeExist.getReplaceFromString(oldSize), zoomParams.replaceSizeExist.getReplaceWithString(newSize));
}
else { // Element has no size entry -> give it an initial size
const initialSize = this.settings.initialSize;
var image = new Image();
image.src = imageUri;
var width = image.naturalWidth;
var minWidth = Math.min(width, initialSize);
fileText = fileText.replace(zoomParams.replaceSizeNotExist.getReplaceFromString(0), zoomParams.replaceSizeNotExist.getReplaceWithString(minWidth));
}
// Save changed size
if (fileText !== originalFileText) {
yield this.app.vault.modify(activeFile, fileText);
}
});
}
/**
* Loop through all panes and get the pane that hosts a markdown file with the image to zoom
* @param imageElement The HTML Element of the image
* @private
*/
getActivePaneWithImage(imageElement) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise(((resolve, reject) => {
this.app.workspace.iterateAllLeaves(leaf => {
if (leaf.view.containerEl.contains(imageElement) && leaf.view instanceof obsidian.MarkdownView) {
resolve(leaf.view.file);
}
});
reject(new Error("No file belonging to the image found"));
}));
});
}
getZoomParams(imageUri, fileText, target) {
if (imageUri.contains("http")) {
return Util.getRemoteImageZoomParams(imageUri, fileText);
}
else if (target.classList.value.match("excalidraw-svg.*")) {
const src = target.attributes.getNamedItem("filesource").textContent;
// remove ".md" from the end of the src
const imageName = src.substring(0, src.length - 3);
// Only get text after "/"
const imageNameAfterSlash = imageName.substring(imageName.lastIndexOf("/") + 1);
return Util.getLocalImageZoomParams(imageNameAfterSlash, fileText);
}
else if (imageUri.contains("app://")) {
const imageName = Util.getLocalImageNameFromUri(imageUri);
return Util.getLocalImageZoomParams(imageName, fileText);
}
throw new Error("Image is not zoomable");
}
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);
});
}
// Utilities to disable and enable scrolling //
preventDefault(ev) {
ev.preventDefault();
}
/**
* Disables the normal scroll event
*/
disableScroll(currentWindow) {
currentWindow.addEventListener(this.wheelEvent, this.preventDefault, this.wheelOpt);
}
/**
* Enables the normal scroll event
*/
enableScroll(currentWindow) {
currentWindow.removeEventListener(this.wheelEvent, this.preventDefault, this.wheelOpt);
}
isConfiguredKeyDown(evt) {
switch (this.settings.modifierKey) {
case ModifierKey.ALT:
case ModifierKey.ALT_RIGHT:
return evt.altKey;
case ModifierKey.CTRL:
case ModifierKey.CTRL_RIGHT:
return evt.ctrlKey;
case ModifierKey.SHIFT:
case ModifierKey.SHIFT_RIGHT:
return evt.shiftKey;
}
}
}
class MouseWheelZoomSettingsTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
let { containerEl } = this;
containerEl.empty();
containerEl.createEl('h2', { text: 'Settings for mousewheel zoom' });
new obsidian.Setting(containerEl)
.setName('Trigger Key')
.setDesc('Key that needs to be pressed down for mousewheel zoom to work.')
.addDropdown(dropdown => dropdown
.addOption(ModifierKey.CTRL, "Ctrl")
.addOption(ModifierKey.ALT, "Alt")
.addOption(ModifierKey.SHIFT, "Shift")
.addOption(ModifierKey.CTRL_RIGHT, "Right Ctrl")
.addOption(ModifierKey.ALT_RIGHT, "Right Alt")
.addOption(ModifierKey.SHIFT_RIGHT, "Right Shift")
.setValue(this.plugin.settings.modifierKey)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.modifierKey = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName('Step size')
.setDesc('Step value by which the size of the image should be increased/decreased')
.addSlider(slider => {
slider
.setValue(25)
.setLimits(0, 100, 1)
.setDynamicTooltip()
.setValue(this.plugin.settings.stepSize)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.stepSize = value;
yield this.plugin.saveSettings();
}));
});
new obsidian.Setting(containerEl)
.setName('Initial Size')
.setDesc('Initial image size if no size was defined beforehand')
.addSlider(slider => {
slider
.setValue(500)
.setLimits(0, 1000, 25)
.setDynamicTooltip()
.setValue(this.plugin.settings.initialSize)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.initialSize = value;
yield this.plugin.saveSettings();
}));
});
}
}
module.exports = MouseWheelZoomPlugin;
/* nosourcemap */

View file

@ -0,0 +1,10 @@
{
"id": "mousewheel-image-zoom",
"name": "Mousewheel Image zoom",
"version": "1.0.22",
"minAppVersion": "0.9.12",
"description": "This plugin enables you to increase/decrease the size of an image by scrolling",
"author": "Nico Jeske",
"authorUrl": "https://github.com/nicojeske/mousewheel-image-zoom",
"isDesktopOnly": true
}

View file

@ -0,0 +1,799 @@
{
"folder": "Excalidraw",
"cropFolder": "",
"annotateFolder": "",
"embedUseExcalidrawFolder": false,
"templateFilePath": "Excalidraw/Template.excalidraw",
"scriptFolderPath": "Excalidraw/Scripts",
"fontAssetsPath": "Excalidraw/CJK Fonts",
"loadChineseFonts": false,
"loadJapaneseFonts": false,
"loadKoreanFonts": false,
"compress": true,
"decompressForMDView": false,
"onceOffCompressFlagReset": true,
"onceOffGPTVersionReset": true,
"autosave": true,
"autosaveIntervalDesktop": 60000,
"autosaveIntervalMobile": 30000,
"drawingFilenamePrefix": "Drawing ",
"drawingEmbedPrefixWithFilename": true,
"drawingFilnameEmbedPostfix": " ",
"drawingFilenameDateTime": "YYYY-MM-DD HH.mm.ss",
"useExcalidrawExtension": true,
"cropPrefix": "cropped_",
"annotatePrefix": "annotated_",
"annotatePreserveSize": false,
"previewImageType": "SVGIMG",
"renderingConcurrency": 3,
"allowImageCache": true,
"allowImageCacheInScene": true,
"displayExportedImageIfAvailable": false,
"previewMatchObsidianTheme": false,
"width": "400",
"height": "",
"overrideObsidianFontSize": false,
"dynamicStyling": "colorful",
"isLeftHanded": false,
"iframeMatchExcalidrawTheme": true,
"matchTheme": false,
"matchThemeAlways": false,
"matchThemeTrigger": false,
"defaultMode": "normal",
"defaultPenMode": "never",
"penModeDoubleTapEraser": true,
"penModeSingleFingerPanning": true,
"penModeCrosshairVisible": true,
"renderImageInMarkdownReadingMode": false,
"renderImageInHoverPreviewForMDNotes": false,
"renderImageInMarkdownToPDF": false,
"allowPinchZoom": false,
"allowWheelZoom": false,
"zoomToFitOnOpen": true,
"zoomToFitOnResize": true,
"zoomToFitMaxLevel": 2,
"linkPrefix": "📍",
"urlPrefix": "🌐",
"parseTODO": false,
"todo": "☐",
"done": "🗹",
"hoverPreviewWithoutCTRL": false,
"linkOpacity": 1,
"openInAdjacentPane": true,
"showSecondOrderLinks": true,
"focusOnFileTab": true,
"openInMainWorkspace": true,
"showLinkBrackets": true,
"allowCtrlClick": true,
"forceWrap": false,
"pageTransclusionCharLimit": 200,
"wordWrappingDefault": 0,
"removeTransclusionQuoteSigns": true,
"iframelyAllowed": true,
"pngExportScale": 1,
"exportWithTheme": true,
"exportWithBackground": true,
"exportPaddingSVG": 10,
"exportEmbedScene": false,
"keepInSync": false,
"autoexportSVG": false,
"autoexportPNG": false,
"autoExportLightAndDark": false,
"autoexportExcalidraw": false,
"embedType": "excalidraw",
"embedMarkdownCommentLinks": true,
"embedWikiLink": true,
"syncExcalidraw": false,
"experimentalFileType": false,
"experimentalFileTag": "✏️",
"experimentalLivePreview": true,
"fadeOutExcalidrawMarkup": false,
"loadPropertySuggestions": true,
"experimentalEnableFourthFont": false,
"experimantalFourthFont": "Virgil",
"addDummyTextElement": false,
"zoteroCompatibility": false,
"fieldSuggester": true,
"compatibilityMode": false,
"drawingOpenCount": 0,
"library": "deprecated",
"library2": {
"type": "excalidrawlib",
"version": 2,
"source": "https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/2.8.3",
"libraryItems": []
},
"imageElementNotice": true,
"mdSVGwidth": 500,
"mdSVGmaxHeight": 800,
"mdFont": "Virgil",
"mdFontColor": "Black",
"mdBorderColor": "Black",
"mdCSS": "",
"scriptEngineSettings": {},
"defaultTrayMode": true,
"previousRelease": "2.8.3",
"showReleaseNotes": true,
"showNewVersionNotification": true,
"latexBoilerplate": "\\color{blue}",
"latexPreambleLocation": "preamble.sty",
"taskboneEnabled": false,
"taskboneAPIkey": "",
"pinnedScripts": [],
"customPens": [
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
},
{
"type": "highlighter",
"freedrawOnly": true,
"strokeColor": "#FFC47C",
"backgroundColor": "#FFC47C",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": null,
"penOptions": {
"highlighter": true,
"constantPressure": true,
"hasOutline": true,
"outlineWidth": 4,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"taper": 0,
"cap": true,
"easing": "linear"
},
"end": {
"taper": 0,
"cap": true,
"easing": "linear"
}
}
}
},
{
"type": "finetip",
"freedrawOnly": false,
"strokeColor": "#3E6F8D",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0.5,
"roughness": 0,
"penOptions": {
"highlighter": false,
"hasOutline": false,
"outlineWidth": 1,
"constantPressure": true,
"options": {
"smoothing": 0.4,
"thinning": -0.5,
"streamline": 0.4,
"easing": "linear",
"start": {
"taper": 5,
"cap": false,
"easing": "linear"
},
"end": {
"taper": 5,
"cap": false,
"easing": "linear"
}
}
}
},
{
"type": "fountain",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 2,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"smoothing": 0.2,
"thinning": 0.6,
"streamline": 0.2,
"easing": "easeInOutSine",
"start": {
"taper": 150,
"cap": true,
"easing": "linear"
},
"end": {
"taper": 1,
"cap": true,
"easing": "linear"
}
}
}
},
{
"type": "marker",
"freedrawOnly": true,
"strokeColor": "#B83E3E",
"backgroundColor": "#FF7C7C",
"fillStyle": "dashed",
"strokeWidth": 2,
"roughness": 3,
"penOptions": {
"highlighter": false,
"constantPressure": true,
"hasOutline": true,
"outlineWidth": 4,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"taper": 0,
"cap": true,
"easing": "linear"
},
"end": {
"taper": 0,
"cap": true,
"easing": "linear"
}
}
}
},
{
"type": "thick-thin",
"freedrawOnly": true,
"strokeColor": "#CECDCC",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": null,
"penOptions": {
"highlighter": true,
"constantPressure": true,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"taper": 0,
"cap": true,
"easing": "linear"
},
"end": {
"cap": true,
"taper": true,
"easing": "linear"
}
}
}
},
{
"type": "thin-thick-thin",
"freedrawOnly": true,
"strokeColor": "#CECDCC",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": null,
"penOptions": {
"highlighter": true,
"constantPressure": true,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 1,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "linear",
"start": {
"cap": true,
"taper": true,
"easing": "linear"
},
"end": {
"cap": true,
"taper": true,
"easing": "linear"
}
}
}
},
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
},
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
},
{
"type": "default",
"freedrawOnly": false,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 0,
"roughness": 0,
"penOptions": {
"highlighter": false,
"constantPressure": false,
"hasOutline": false,
"outlineWidth": 1,
"options": {
"thinning": 0.6,
"smoothing": 0.5,
"streamline": 0.5,
"easing": "easeOutSine",
"start": {
"cap": true,
"taper": 0,
"easing": "linear"
},
"end": {
"cap": true,
"taper": 0,
"easing": "linear"
}
}
}
}
],
"numberOfCustomPens": 0,
"pdfScale": 4,
"pdfBorderBox": true,
"pdfFrame": false,
"pdfGapSize": 20,
"pdfGroupPages": false,
"pdfLockAfterImport": true,
"pdfNumColumns": 1,
"pdfNumRows": 1,
"pdfDirection": "right",
"pdfImportScale": 0.3,
"gridSettings": {
"DYNAMIC_COLOR": true,
"COLOR": "#000000",
"OPACITY": 50
},
"laserSettings": {
"DECAY_LENGTH": 50,
"DECAY_TIME": 1000,
"COLOR": "#ff0000"
},
"embeddableMarkdownDefaults": {
"useObsidianDefaults": false,
"backgroundMatchCanvas": false,
"backgroundMatchElement": true,
"backgroundColor": "#fff",
"backgroundOpacity": 60,
"borderMatchElement": true,
"borderColor": "#fff",
"borderOpacity": 0,
"filenameVisible": false
},
"markdownNodeOneClickEditing": false,
"canvasImmersiveEmbed": true,
"startupScriptPath": "",
"openAIAPIToken": "",
"openAIDefaultTextModel": "gpt-3.5-turbo-1106",
"openAIDefaultVisionModel": "gpt-4o",
"openAIDefaultImageGenerationModel": "dall-e-3",
"openAIURL": "https://api.openai.com/v1/chat/completions",
"openAIImageGenerationURL": "https://api.openai.com/v1/images/generations",
"openAIImageEditsURL": "https://api.openai.com/v1/images/edits",
"openAIImageVariationURL": "https://api.openai.com/v1/images/variations",
"modifierKeyConfig": {
"Mac": {
"LocalFileDragAction": {
"defaultAction": "image-import",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "embeddable"
}
]
},
"WebBrowserDragAction": {
"defaultAction": "image-url",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "link"
},
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": true,
"meta_ctrl": false,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
}
]
},
"InternalDragAction": {
"defaultAction": "link",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": true,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": true,
"result": "image-fullsize"
}
]
},
"LinkClickAction": {
"defaultAction": "new-tab",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "active-pane"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "new-tab"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "new-pane"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "popout-window"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": true,
"result": "md-properties"
}
]
}
},
"Win": {
"LocalFileDragAction": {
"defaultAction": "image-import",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "embeddable"
}
]
},
"WebBrowserDragAction": {
"defaultAction": "image-url",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-url"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image-import"
}
]
},
"InternalDragAction": {
"defaultAction": "link",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "link"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "embeddable"
},
{
"shift": true,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "image"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "image-fullsize"
}
]
},
"LinkClickAction": {
"defaultAction": "new-tab",
"rules": [
{
"shift": false,
"ctrl_cmd": false,
"alt_opt": false,
"meta_ctrl": false,
"result": "active-pane"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": false,
"result": "new-tab"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "new-pane"
},
{
"shift": true,
"ctrl_cmd": true,
"alt_opt": true,
"meta_ctrl": false,
"result": "popout-window"
},
{
"shift": false,
"ctrl_cmd": true,
"alt_opt": false,
"meta_ctrl": true,
"result": "md-properties"
}
]
}
}
},
"slidingPanesSupport": false,
"areaZoomLimit": 1,
"longPressDesktop": 500,
"longPressMobile": 500,
"doubleClickLinkOpenViewMode": true,
"isDebugMode": false,
"rank": "Bronze",
"modifierKeyOverrides": [
{
"modifiers": [
"Mod"
],
"key": "Enter"
},
{
"modifiers": [
"Mod"
],
"key": "k"
},
{
"modifiers": [
"Mod"
],
"key": "G"
}
],
"showSplashscreen": true,
"pdfSettings": {
"pageSize": "A4",
"pageOrientation": "portrait",
"fitToPage": 1,
"paperColor": "white",
"customPaperColor": "#ffffff",
"alignment": "center",
"margin": "normal"
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,12 @@
{
"id": "obsidian-excalidraw-plugin",
"name": "Excalidraw",
"version": "2.8.3",
"minAppVersion": "1.1.6",
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian",
"authorUrl": "https://www.zsolt.blog",
"fundingUrl": "https://ko-fi.com/zsolt",
"helpUrl": "https://github.com/zsviczian/obsidian-excalidraw-plugin#readme",
"isDesktopOnly": false
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-leaflet-plugin",
"name": "Leaflet",
"description": "Interactive maps inside your notes",
"version": "6.0.5",
"minAppVersion": "0.12.12",
"author": "Jeremy Valentine",
"repo": "valentine195/obsidian-leaflet-plugin",
"isDesktopOnly": false
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
{
"ITS@@select": "wotc-beyond",
"ITS@@accent-color": false,
"ITS@@s-d": false,
"ITS@@slrvb-g": false,
"ITS@@slrvb-b": false,
"ITS@@t-d": false,
"ITS@@drwn": false,
"ITS@@nord": false,
"ITS@@mini": false,
"ITS@@notion": false,
"ITS@@its-d": false
}

File diff suppressed because one or more lines are too long

View 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
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,7 @@
{
"deleteOption": ".trash",
"logsModal": true,
"excludedFolders": "",
"ribbonIcon": true,
"excludeSubfolders": false
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,11 @@
{
"id": "oz-clear-unused-images",
"name": "Clear Unused Images",
"version": "1.1.1",
"minAppVersion": "0.11.13",
"description": "Clear the images that you are not using anymore in your markdown notes to save space.",
"author": "Ozan",
"authorUrl": "https://www.ozan.pl",
"fundingUrl": "https://ko-fi.com/ozante",
"isDesktopOnly": false
}

View file

@ -0,0 +1,10 @@
.unused-images-logs {
margin-bottom: 13px;
margin-top: 5px;
}
.unused-images-center-wrapper {
display: flex;
align-items: center;
justify-content: center;
}

View file

@ -0,0 +1,7 @@
{
"name": "ITS Theme",
"version": "1.3.33",
"minAppVersion": "0.16.0",
"author": "SlRvb",
"authorUrl": "https://github.com/SlRvb"
}

14470
RPG/.obsidian/themes/ITS Theme/theme.css vendored Normal file

File diff suppressed because one or more lines are too long

27
RPG/.obsidian/types.json vendored Normal file
View file

@ -0,0 +1,27 @@
{
"types": {
"aliases": "aliases",
"cssclasses": "multitext",
"tags": "tags",
"excalidraw-plugin": "text",
"excalidraw-export-transparent": "checkbox",
"excalidraw-mask": "checkbox",
"excalidraw-export-dark": "checkbox",
"excalidraw-export-padding": "number",
"excalidraw-export-pngscale": "number",
"excalidraw-export-embed-scene": "checkbox",
"excalidraw-link-prefix": "text",
"excalidraw-url-prefix": "text",
"excalidraw-link-brackets": "checkbox",
"excalidraw-onload-script": "text",
"excalidraw-linkbutton-opacity": "number",
"excalidraw-default-mode": "text",
"excalidraw-font": "text",
"excalidraw-font-color": "text",
"excalidraw-border-color": "text",
"excalidraw-css": "text",
"excalidraw-autoexport": "text",
"excalidraw-embeddable-theme": "text",
"excalidraw-open-md": "checkbox"
}
}

217
RPG/.obsidian/workspace-mobile.json vendored Normal file
View file

@ -0,0 +1,217 @@
{
"main": {
"id": "5ca7428bc79d22ef",
"type": "split",
"children": [
{
"id": "f07956f5cf238d56",
"type": "tabs",
"children": [
{
"id": "70a6195e739beb24",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "1-Sessions/Info Snippets/Paladin Apokryphen.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "Paladin Apokryphen"
}
},
{
"id": "f3ac97d0d1692e78",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "1-Sessions/Info Snippets/Die Verdammten - Strafkompanie.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "Die Verdammten - Strafkompanie"
}
},
{
"id": "ffc6e50ff8ce5ecb",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "1-Sessions/Info Snippets/Rastaktivitäten.md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "Rastaktivitäten"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "d228c4c665507026",
"type": "mobile-drawer",
"children": [
{
"id": "d5d649bce33dd405",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "Files"
}
},
{
"id": "1b74facf6e6f34bd",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "Search"
}
},
{
"id": "5dbe6ce619b2cbde",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "Tags"
}
},
{
"id": "95a2de307c2f9ede",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "Bookmarks"
}
}
],
"currentTab": 0,
"pinned": true
},
"right": {
"id": "90eb9c2e9f86861c",
"type": "mobile-drawer",
"children": [
{
"id": "a662c451346b2a47",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "1-Sessions/Info Snippets/Paladin Apokryphen.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "Backlinks"
}
},
{
"id": "08baccfd8373d07b",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "Outgoing links"
}
},
{
"id": "53f65ef69cf73337",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "Outline"
}
}
],
"currentTab": 0
},
"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,
"fantasy-content-generator:Fantasy Generators": false,
"obsidian-excalidraw-plugin:New drawing": false,
"oz-clear-unused-images:Clear Unused Images": false
}
},
"active": "70a6195e739beb24",
"lastOpenFiles": [
"1-Sessions/Info Snippets/Neues Wildnis System Kreaturen häuten.md",
"1-Sessions/Info Snippets/Meisterarbeit Krit Range plus 1.md",
"1-Sessions/Info Snippets/Golem der Exterminator Klasse.md",
"1-Sessions/Info Snippets/Die Verdammten - Strafkompanie.md",
"1-Sessions/Info Snippets/Der Kreuzritter Stadtstaat.md",
"1-Sessions/Info Snippets/Definiere Schatz und Schatzkarte.md",
"1-Sessions/Sitzung 003, 21.03.2025.md",
"1-Sessions/Info Snippets/Rastaktivitäten.md",
"1-Sessions/Info Snippets/Paladin Apokryphen.md",
"1-Sessions/Info Snippets/Plot ehemals friedliche Kreaturen werden aggressiv.md",
"1-Sessions/Info Snippets/Baphomet.md",
"1-Sessions/Info Snippets/Titel Prälat.md",
"1-Sessions/Info Snippets/Ritualbecken gefüllt mit frischem Blut.md",
"1-Sessions/Info Snippets",
"1-Sessions/Sitzung 004, prep.md",
"3-Welt/Königreich Taloria/Westreiche/Westreiche_Nord-Karte.md",
"3-Welt/Königreich Taloria/Westreiche/Westreiche-Karte.md",
"Sessions/Sitzung 003, 21.03.2025_prep.md",
"Spieler/Michi/Rain.md",
"zz_archiv/images/rain.jpeg",
"Welt/Königreich Taloria/Westreiche/Siedlungen/Rabenforst/Elias.md",
"Welt/Königreich Taloria/Westreiche/Siedlungen/Rabenforst/Iliane.md",
"Welt/Königreich Taloria/Westreiche/Siedlungen/Methaven/Vater Damian.md",
"Welt/Königreich Taloria/Westreiche/Siedlungen/Methaven/Rambastulon.md",
"Welt/Königreich Taloria/Westreiche/Siedlungen/Methaven/Peloc.md",
"Spieler/Udo/Terian.md",
"Spieler/Silke/Harissa.md",
"Spieler/Mike/Gregor Eisenhorn.md"
]
}

444
RPG/.trash/Westreiche_5.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 54 MiB

BIN
RPG/.trash/fur_trader.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

View file

@ -0,0 +1,2 @@
Dämon ?
Teufel ?

View file

@ -0,0 +1 @@
Selbstheilung: + Stufe selbst , - Stufe andere

View file

@ -0,0 +1 @@
Irgend etwas scheint sie von innen zu verzehren

View file

@ -0,0 +1,7 @@
TP Regeneration
Negative Effekte entfernen
Sicherheit (Wache)
Tarnung des Lagers
Schriftrollen Fertigung (?)
Suppenherstellung (?)
Schutzritual

View file

@ -0,0 +1 @@
01.07.130, Dorf Methaven, Westreiche

View file

@ -0,0 +1,5 @@
01.07.130, Dorf Methaven, Westreiche
Einstiegsabenteuer angepasst aus dem Internet "The delian tomb" ( 5 Room dungeon )
[[Das Grabmal des alten Ritters]]

View file

@ -0,0 +1,66 @@
17.07.130, Dorf Methaven, Westreiche
[[Tarazul]] - Marco
[[Rain]] - Michi
[[Gregor Eisenhorn]] - Mike
[[Harissa]] - Silke
[[Terian]] - Udo
Erwartet: Gruppe zieht nach Garana, der Handwerkerstadt, um ihren Rubin loszuwerden
Pro Tag muss das Wetter bestimmt werden: [[Wettertabelle]]
---
ABER ES KAM WIE IMMER GANZ ANDERS: Die Gruppe hat entschlossen, Rain dabei zu begleiten, ihre Schuld gegenüber den Druiden zu begleichen, und eine Karawane in den Rabenforst zu eskortieren
Die Karawane besteht aus 3 Maultier-Karren, geführt von Halblingen
Auf dem Weg Überfall von 6 Banditen, knappe Kiste.
Übergabe an die Druiden, Mission erfüllt.
Zurück in Methaven wird ein Status Check des teuren Rubins in der Gruppenkasse geprüft: **00** gewürfelt
Der Rubin ist gestohlen worden !
(Mega saure Spieler, vor allem Silke und Marco)
Festgelegter Dieb: Ein Kobold, der auch die Tavernenkasse geleert hat.
Gruppe stellt Kobold, erbeutet nicht nur den Rubin zurück, sondern auch die Tavernenkasse und ein paar zusätzliche Kleinigkeiten ( seltene Münzen ). Bis auf die Tavernenkasse behält die Gruppe alles für sich.
**ep Vergabe ausstehend**
...
Mögliche Events:
Abenteurer kommen reich bepackt mit Beute (60%) und geben einen aus: Sie erzählen vom Höllenstein Verlies
Abenteurer kommen völlig zerstört vorbei (20%) und erzählen vom Höllenstein Verlies
---
Aktuell aktive Fraktionen:
---
Aktuelle Hintergrundereignisse:
---
NSC, die auftauchen können:
---
Informationen, die heute enthüllt werden können:
---
WICHTIGE Regeln:
[ ] Abnutzung von Ausrüstung
[ ] Wöchentliche Ereignisse

View file

@ -0,0 +1,32 @@
24.07.130, Dorf Methaven, Westreiche
[[Tarazul]] - Marco
[[Rain]] - Michi
[[Gregor Eisenhorn]] - Mike
[[Harissa]] - Silke
[[Terian]] - Udo
WICHTIGE Themen:
[ ] EP Vergabe von letzter Runde
[ ] Wöchentliche Ereignisse
---
Übriggebliebene Prep Notizen, der Weg nach Gharana:
Station 1: Ankheg oder Ogerspuren, die in Richtung des Dörfchens Weiherlaach deuten.
Station 2: Gräfliche Zollstation am Jülsch ( Baron Siegenstein: Goldene Münze auf Blau/Gelbem Grund), 1 Kreuzer pro Mann ( bei Rückreise 1 Kreuzer pro Frau)
Station 3: Ankunft vor Garana, Eintritt 1 Kreuzer pro Person
Garana hat eine Steinmauer, und wird bewacht. Ausser am Sonntag (Markttag) kostet der Zutritt kein Geld, sonst 1 Kreuzer pro Person und Transportmittel.
In Garana gibt es eine Bibliothekarengilde (Bruderschaft des Wortes), die gegen Entgelt zugang zu Folianten ermöglicht
Pferde gibt es ebenso: Guldaq, der Pferdehändler
Pareta, Schmuckhändlerin
Geraldo der Mechnicus, Vorsteher der Feinschmiedegilde, einer noch neuen Gilde
Unterkunft:
Gutbürgerlich: 3 Kreuzer pro Übernachtung, inklusive einem Mahl. Regeneration über Nacht +2 TP
Gehoben/adlig: 8 Kreuzer pro Übernachtung, 3xEssen und Zugang zu einem Badezuber. Regeneration über Nacht +3 TP

View file

@ -0,0 +1,19 @@
**Temperatur:**
1-14: Für die Jahreszeit normales Wetter
15-17: Kälter als normal
18-20: Wärmer als normal
**Wind:**
1-12: Kein Wind
13-17: Leichter Wind
18-20: Starker Wind
**Niederschlag:**
1-12: Kein Niederschlag, klarer bis leicht bewölkter Himmel (Sichtweite 3 km)
13-17: Leichter Regen, leicht bewölkter Himmel (Sichtweite 1,5 km, Nachteil auf Wahrnehmung)
18-20: Schwerer Regen, dunkle Wolken am Himmel (Sichtweite 90 m, Nachteil auf Wahrnehmung)
**Nebel:**
1-16: Kein Nebel
17-19: Leichter Nebel (Nachteil auf Wahrnehmung)
20: Dichter Nebel (Sichtweite 30-90 m, Nachteil auf Wahrnehmung)

View file

@ -0,0 +1,11 @@
![[mage_placeholder.png|134]]
Magier, gespielt von Marco
Geburtstag 10.10.114
Kontaktperson: [[Vater Damian]]
Aktuelle Quests
<geheim>
Mögliche Quests
<geheim>

View file

@ -0,0 +1,13 @@
Kämpferin
Ansprechpartner: [[Peloc]] der Fellhändler
Geburtstag: 04.08.111
![[rain.jpeg|325]]
Aktuelle Quests:
*NSC KONTAKTE*
Wurde am 03.07.130 von [[Elias]] dem Druiden von Krätze geheilt, die sie sich beim Rasten in Methaven zuzog.

View file

@ -0,0 +1,19 @@
![[paladin_placeholder_2.png|250]]
Paladin, gespielt von Mike
Geburtstag: 21.06.113
(imun gegen Krankheiten)
keine Ansprechpartner,
verbannt aus der Hauptstadt
Aktuelle Quests:
*Erlange großen Ruhm um zu deiner Familie in die Hauptstadt wieder zurückkehren zu dürfen.*
*Prep*
Die Verbindung zu seiner Gottheit manifestiert sich im Laufe der Zeit. Er kann verschiedene (Erz-)Engel Amaunators kontaktieren und ihnen Bündnisse vorschlagen.

View file

@ -0,0 +1,7 @@
![[Harissa.jpeg|100]]
Waldläuferin, gespielt von Silke
Ansprechpartner: [[Iliane]], die Waldläuferin
Geburtstag: 02.08.114
Aktuelle Quests:

View file

@ -0,0 +1,15 @@
![[cleric_placeholder.png|212]]
Amaunator Priester, gespielt von Udo
Ansprechpartner: [[Vater Damian]] in Methaven
Aktuelle Quests:
Mögliche Quests:
- Traum: Reinigung eines entweihten Tempels oder Schreins
- Wiederbeschaffung einer heiligen Reliquie
- Kryptische Versatzstücke eines Rätsels, die zu einem Ort führen, an dem der Priester seinen Glauben durch Prüfungen beweisen muss.

View file

@ -0,0 +1,2 @@
Hauptstadt des Königreichs Taloria

View file

@ -0,0 +1,3 @@
Das Einsteigerabenteuer für die Gruppe, gegeben an die Charaktere [[Tarazul]], [[Rain]], [[Gregor Eisenhorn]], [[Harissa]] und [[Terian]]
![[Delian_Tomb.png]]

View file

@ -0,0 +1,5 @@
Fellhändler
Kontakte zu Elfen und Druiden
Kontaktperson für [[Rain]]
![[fur_trader 1.jpg|675]]

View file

@ -0,0 +1,5 @@
Magier, Lehrmeister von [[Tarazul]]
Aufenthaltsort: Methaven (eigenes Steinhaus im Ort)
![[rambastulon.png]]
hat eine wechselbare Holzhand
trägt Maske aufgrund seines entstellten Gesichtes

View file

@ -0,0 +1,5 @@
Priester des Amaunator Schreins in Methaven
![[Vater_Damian.jpg|325]]
Ansprechpartner für den Abenteurer Priester [[Terian]]

View file

@ -0,0 +1,5 @@
Druide
![[Druide_Elias.jpg]]
Hat am 03.07.130 [[Rain]] von Krankheit (Krätze) befreit.

View file

@ -0,0 +1,7 @@
königliche Waldläuferin
militärische Ausbildung
![[Iliane_Ranger.jpg|450]]
Ausbilderin von [[Harissa]]

View file

@ -0,0 +1 @@
![[Westreiche.png|825]]

View file

@ -0,0 +1 @@
![[Westreiche_Nord.png|1350]]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
![[Rassengrösse.jpg|1100]]

BIN
RPG/Harissa.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
RPG/cleric_placeholder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

BIN
RPG/mage_placeholder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 KiB

View file

@ -0,0 +1 @@
https://watabou.itch.io/medieval-fantasy-city-generator

View file

@ -0,0 +1,22 @@
**Bandits Keep: D&D A Game of Exploration**
Event based adventure
Location based adventure <-- more exploration
*Hook*: Treasure maps leading to specific treasure locations
*Hook*: Tavern is waiting for overdue supplies => find out what happened to the caravan
- Hint at the unknown in a way that is appealing. (someone coming back from the wilderness with loot)
- Hint at the fact that a lot is going on.
- Have TOO MUCH stuff for the group ( with a couple of obvious stuff, dont overload them)
Let the world move, but dont punish the players for it.
**Earthmote: Design your own 16-bit Hexmaps for DnD Campaigns**
( Zechio from itch.io + Hex Kit )
https://2minutetabletop.com/product/world-map-hex-tiles-pack/

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View file

@ -0,0 +1,45 @@
Unterstadt der Zwerge ist abgeriegelt aufgrund marodierender Frostriesen
Lieferauftrag von Utensilien für den Magierturm der Nachbarstadt
Druiden planen aufgrund einer Prophezeiung die Stadt zu renaturieren.
Sekte: Schattendruiden => Bringe den Kopf des Anführers
=> Anführer ist ein Drache!
In einer der Höhlen unterhalb des Tempels strahlt starke Lebenskraft ab, aus denen die Priester Heiltränke
gewinnen. Aber vor 2 Tagen kehrte einer unserer Brüder aus dieser Höhle nicht zurück.
Unsere zwei kampfstärksten Brüder brachen auf um ihn zu suchen, aber sie kehrten ebenfalls nicht zurück.
Wenn dies das Werk einer bösen Macht ist, droht uns allen großes Unheil. In der Höhle wächste ein
wundersamer Baum. Bringt mir einen seiner Zweige, und ich werde euch den mächtigsten Heiltrank
zubereiten, den ihr je gesehen habt.
Schatzkarte zu einer verborgenen Höhle (hinter einem Fels). Bewacht von einem Luftelementar ein Schatz (Ring+Gold)
Der lokale Lord vermisst einen seiner Freunde. Er vor 2 Tagen zum lezten mal gesehen.
Um Plünderer fernzuhalten wurde das Haus versiegelt und verschlossen. Der Lord kann den Schlüssel geben.
Hinweise auf den Verbleib werden gut bezahlt.
-> Das Haus ist ordentlich. Kein Zeichen eines Kampfes.
-> Angefanges Gemälde eines kleinen gelben Vogels in einem Käfig
-> Bibliothek im ersten Stock enthält aufgeschlagenes Buch mit einem Spruch.
-> Ident erfogleich: Teleportationszauber, aber anders als bekannte. Eher ein Rückrufzauber
mit festgelegte unbekannten Ziel.
-> Teleportation in unterirdische Ruine. Heruntergekommen, bewacht von Konstrukten (Helm Horror)
Räume sind teilweise vom eindringenden Erdreich verschüttet
Riesen Golem, Lehmgolem
-> Zentrale Beschwörungskammer mit aufgeschlagenem Buch
-> Alain Rich ist in einem Diwan Raum, in dem es Rast+Nahrung gibt.
Er hat das Buch zum Übersetzen erhalten, weil er Altelfisch kennt und wurde
in diesen Kerker versetzt. Bis jetzt hat er keinen Ausgang gefunden.
Aktuelles Gewölbe ist ein Labor der alten Elfen
Mit Beseitigung der Golems kann Alain das Buch in der Beschwörungskammer entziffern
und erzeugt ein Portal zurück.
Belohnung von Alain: Magische Stiefel des festen Stands.
Belohnung des Lords: Angeboten, aber abgelehnt
Orks haben sich in einer alten Fort Ruine festgesetzt, auf den Kopf des Anführers sind 1000 Goldstücke Belohnung ausgesetzt.
Die Orks haben befestigte Hinterhalte mit Bogenschützen und Mörderlöchern angelegt.
Im Fort selbst ist eine kleine Schatzkammer mit 350 GM und 20 +1 Pfeilen
Ein magisches Artefakt ist auf der Insel der Toten, auf der Horden von Untoten frei umherwandern. Niemand ist je zurückgekehrt.