'use strict' ;
var obsidian = require ( 'obsidian' ) ;
function _interopDefaultLegacy ( e ) { return e && typeof e === 'object' && 'default' in e ? e : { 'default' : e } ; }
var obsidian _ _default = /*#__PURE__*/ _interopDefaultLegacy ( 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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* global Reflect, Promise */
var extendStatics = function ( d , b ) {
extendStatics = Object . setPrototypeOf ||
( { _ _proto _ _ : [ ] } instanceof Array && function ( d , b ) { d . _ _proto _ _ = b ; } ) ||
function ( d , b ) { for ( var p in b ) if ( Object . prototype . hasOwnProperty . call ( b , p ) ) d [ p ] = b [ p ] ; } ;
return extendStatics ( d , b ) ;
} ;
function _ _extends ( d , b ) {
if ( typeof b !== "function" && b !== null )
throw new TypeError ( "Class extends value " + String ( b ) + " is not a constructor or null" ) ;
extendStatics ( d , b ) ;
function _ _ ( ) { this . constructor = d ; }
d . prototype = b === null ? Object . create ( b ) : ( _ _ . prototype = b . prototype , new _ _ ( ) ) ;
}
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 ( ) ) ;
} ) ;
}
function _ _generator ( thisArg , body ) {
var _ = { label : 0 , sent : function ( ) { if ( t [ 0 ] & 1 ) throw t [ 1 ] ; return t [ 1 ] ; } , trys : [ ] , ops : [ ] } , f , y , t , g ;
return g = { next : verb ( 0 ) , "throw" : verb ( 1 ) , "return" : verb ( 2 ) } , typeof Symbol === "function" && ( g [ Symbol . iterator ] = function ( ) { return this ; } ) , g ;
function verb ( n ) { return function ( v ) { return step ( [ n , v ] ) ; } ; }
function step ( op ) {
if ( f ) throw new TypeError ( "Generator is already executing." ) ;
while ( _ ) try {
if ( f = 1 , y && ( t = op [ 0 ] & 2 ? y [ "return" ] : op [ 0 ] ? y [ "throw" ] || ( ( t = y [ "return" ] ) && t . call ( y ) , 0 ) : y . next ) && ! ( t = t . call ( y , op [ 1 ] ) ) . done ) return t ;
if ( y = 0 , t ) op = [ op [ 0 ] & 2 , t . value ] ;
switch ( op [ 0 ] ) {
case 0 : case 1 : t = op ; break ;
case 4 : _ . label ++ ; return { value : op [ 1 ] , done : false } ;
case 5 : _ . label ++ ; y = op [ 1 ] ; op = [ 0 ] ; continue ;
case 7 : op = _ . ops . pop ( ) ; _ . trys . pop ( ) ; continue ;
default :
if ( ! ( t = _ . trys , t = t . length > 0 && t [ t . length - 1 ] ) && ( op [ 0 ] === 6 || op [ 0 ] === 2 ) ) { _ = 0 ; continue ; }
if ( op [ 0 ] === 3 && ( ! t || ( op [ 1 ] > t [ 0 ] && op [ 1 ] < t [ 3 ] ) ) ) { _ . label = op [ 1 ] ; break ; }
if ( op [ 0 ] === 6 && _ . label < t [ 1 ] ) { _ . label = t [ 1 ] ; t = op ; break ; }
if ( t && _ . label < t [ 2 ] ) { _ . label = t [ 2 ] ; _ . ops . push ( op ) ; break ; }
if ( t [ 2 ] ) _ . ops . pop ( ) ;
_ . trys . pop ( ) ; continue ;
}
op = body . call ( thisArg , _ ) ;
} catch ( e ) { op = [ 6 , e ] ; y = 0 ; } finally { f = t = 0 ; }
if ( op [ 0 ] & 5 ) throw op [ 1 ] ; return { value : op [ 0 ] ? op [ 1 ] : void 0 , done : true } ;
}
}
function _ _spreadArray ( to , from ) {
for ( var i = 0 , il = from . length , j = to . length ; i < il ; i ++ , j ++ )
to [ j ] = from [ i ] ;
return to ;
}
function createCommonjsModule ( fn , basedir , module ) {
return module = {
path : basedir ,
exports : { } ,
require : function ( path , base ) {
return commonjsRequire ( path , ( base === undefined || base === null ) ? module . path : base ) ;
}
} , fn ( module , module . exports ) , module . exports ;
}
function commonjsRequire ( ) {
throw new Error ( 'Dynamic requires are not currently supported by @rollup/plugin-commonjs' ) ;
}
var main = createCommonjsModule ( function ( module , exports ) {
Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
const DEFAULT _DAILY _NOTE _FORMAT = "YYYY-MM-DD" ;
const DEFAULT _WEEKLY _NOTE _FORMAT = "gggg-[W]ww" ;
const DEFAULT _MONTHLY _NOTE _FORMAT = "YYYY-MM" ;
const DEFAULT _QUARTERLY _NOTE _FORMAT = "YYYY-[Q]Q" ;
const DEFAULT _YEARLY _NOTE _FORMAT = "YYYY" ;
function shouldUsePeriodicNotesSettings ( periodicity ) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const periodicNotes = window . app . plugins . getPlugin ( "periodic-notes" ) ;
return periodicNotes && periodicNotes . settings ? . [ periodicity ] ? . enabled ;
}
/ * *
* Read the user settings for the ` daily-notes ` plugin
* to keep behavior of creating a new note in - sync .
* /
function getDailyNoteSettings ( ) {
try {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { internalPlugins , plugins } = window . app ;
if ( shouldUsePeriodicNotesSettings ( "daily" ) ) {
const { format , folder , template } = plugins . getPlugin ( "periodic-notes" ) ? . settings ? . daily || { } ;
return {
format : format || DEFAULT _DAILY _NOTE _FORMAT ,
folder : folder ? . trim ( ) || "" ,
template : template ? . trim ( ) || "" ,
} ;
}
const { folder , format , template } = internalPlugins . getPluginById ( "daily-notes" ) ? . instance ? . options || { } ;
return {
format : format || DEFAULT _DAILY _NOTE _FORMAT ,
folder : folder ? . trim ( ) || "" ,
template : template ? . trim ( ) || "" ,
} ;
}
catch ( err ) {
console . info ( "No custom daily note settings found!" , err ) ;
}
}
/ * *
* Read the user settings for the ` weekly-notes ` plugin
* to keep behavior of creating a new note in - sync .
* /
function getWeeklyNoteSettings ( ) {
try {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const pluginManager = window . app . plugins ;
const calendarSettings = pluginManager . getPlugin ( "calendar" ) ? . options ;
const periodicNotesSettings = pluginManager . getPlugin ( "periodic-notes" ) ? . settings ? . weekly ;
if ( shouldUsePeriodicNotesSettings ( "weekly" ) ) {
return {
format : periodicNotesSettings . format || DEFAULT _WEEKLY _NOTE _FORMAT ,
folder : periodicNotesSettings . folder ? . trim ( ) || "" ,
template : periodicNotesSettings . template ? . trim ( ) || "" ,
} ;
}
const settings = calendarSettings || { } ;
return {
format : settings . weeklyNoteFormat || DEFAULT _WEEKLY _NOTE _FORMAT ,
folder : settings . weeklyNoteFolder ? . trim ( ) || "" ,
template : settings . weeklyNoteTemplate ? . trim ( ) || "" ,
} ;
}
catch ( err ) {
console . info ( "No custom weekly note settings found!" , err ) ;
}
}
/ * *
* Read the user settings for the ` periodic-notes ` plugin
* to keep behavior of creating a new note in - sync .
* /
function getMonthlyNoteSettings ( ) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const pluginManager = window . app . plugins ;
try {
const settings = ( shouldUsePeriodicNotesSettings ( "monthly" ) &&
pluginManager . getPlugin ( "periodic-notes" ) ? . settings ? . monthly ) ||
{ } ;
return {
format : settings . format || DEFAULT _MONTHLY _NOTE _FORMAT ,
folder : settings . folder ? . trim ( ) || "" ,
template : settings . template ? . trim ( ) || "" ,
} ;
}
catch ( err ) {
console . info ( "No custom monthly note settings found!" , err ) ;
}
}
/ * *
* Read the user settings for the ` periodic-notes ` plugin
* to keep behavior of creating a new note in - sync .
* /
function getQuarterlyNoteSettings ( ) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const pluginManager = window . app . plugins ;
try {
const settings = ( shouldUsePeriodicNotesSettings ( "quarterly" ) &&
pluginManager . getPlugin ( "periodic-notes" ) ? . settings ? . quarterly ) ||
{ } ;
return {
format : settings . format || DEFAULT _QUARTERLY _NOTE _FORMAT ,
folder : settings . folder ? . trim ( ) || "" ,
template : settings . template ? . trim ( ) || "" ,
} ;
}
catch ( err ) {
console . info ( "No custom quarterly note settings found!" , err ) ;
}
}
/ * *
* Read the user settings for the ` periodic-notes ` plugin
* to keep behavior of creating a new note in - sync .
* /
function getYearlyNoteSettings ( ) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const pluginManager = window . app . plugins ;
try {
const settings = ( shouldUsePeriodicNotesSettings ( "yearly" ) &&
pluginManager . getPlugin ( "periodic-notes" ) ? . settings ? . yearly ) ||
{ } ;
return {
format : settings . format || DEFAULT _YEARLY _NOTE _FORMAT ,
folder : settings . folder ? . trim ( ) || "" ,
template : settings . template ? . trim ( ) || "" ,
} ;
}
catch ( err ) {
console . info ( "No custom yearly note settings found!" , err ) ;
}
}
// Credit: @creationix/path.js
function join ( ... partSegments ) {
// Split the inputs into a list of path commands.
let parts = [ ] ;
for ( let i = 0 , l = partSegments . length ; i < l ; i ++ ) {
parts = parts . concat ( partSegments [ i ] . split ( "/" ) ) ;
}
// Interpret the path commands to get the new resolved path.
const newParts = [ ] ;
for ( let i = 0 , l = parts . length ; i < l ; i ++ ) {
const part = parts [ i ] ;
// Remove leading and trailing slashes
// Also remove "." segments
if ( ! part || part === "." )
continue ;
// Push new path segments.
else
newParts . push ( part ) ;
}
// Preserve the initial slash if there was one.
if ( parts [ 0 ] === "" )
newParts . unshift ( "" ) ;
// Turn back into a single string path.
return newParts . join ( "/" ) ;
}
function basename ( fullPath ) {
let base = fullPath . substring ( fullPath . lastIndexOf ( "/" ) + 1 ) ;
if ( base . lastIndexOf ( "." ) != - 1 )
base = base . substring ( 0 , base . lastIndexOf ( "." ) ) ;
return base ;
}
async function ensureFolderExists ( path ) {
const dirs = path . replace ( /\\/g , "/" ) . split ( "/" ) ;
dirs . pop ( ) ; // remove basename
if ( dirs . length ) {
const dir = join ( ... dirs ) ;
if ( ! window . app . vault . getAbstractFileByPath ( dir ) ) {
await window . app . vault . createFolder ( dir ) ;
}
}
}
async function getNotePath ( directory , filename ) {
if ( ! filename . endsWith ( ".md" ) ) {
filename += ".md" ;
}
const path = obsidian _ _default [ "default" ] . normalizePath ( join ( directory , filename ) ) ;
await ensureFolderExists ( path ) ;
return path ;
}
async function getTemplateInfo ( template ) {
const { metadataCache , vault } = window . app ;
const templatePath = obsidian _ _default [ "default" ] . normalizePath ( template ) ;
if ( templatePath === "/" ) {
return Promise . resolve ( [ "" , null ] ) ;
}
try {
const templateFile = metadataCache . getFirstLinkpathDest ( templatePath , "" ) ;
const contents = await vault . cachedRead ( templateFile ) ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const IFoldInfo = window . app . foldManager . load ( templateFile ) ;
return [ contents , IFoldInfo ] ;
}
catch ( err ) {
console . error ( ` Failed to read the daily note template ' ${ templatePath } ' ` , err ) ;
new obsidian _ _default [ "default" ] . Notice ( "Failed to read the daily note template" ) ;
return [ "" , null ] ;
}
}
/ * *
* dateUID is a way of weekly identifying daily / weekly / monthly notes .
* They are prefixed with the granularity to avoid ambiguity .
* /
function getDateUID ( date , granularity = "day" ) {
const ts = date . clone ( ) . startOf ( granularity ) . format ( ) ;
return ` ${ granularity } - ${ ts } ` ;
}
function removeEscapedCharacters ( format ) {
return format . replace ( /\[[^\]]*\]/g , "" ) ; // remove everything within brackets
}
/ * *
* XXX : When parsing dates that contain both week numbers and months ,
* Moment choses to ignore the week numbers . For the week dateUID , we
* want the opposite behavior . Strip the MMM from the format to patch .
* /
function isFormatAmbiguous ( format , granularity ) {
if ( granularity === "week" ) {
const cleanFormat = removeEscapedCharacters ( format ) ;
return ( /w{1,2}/i . test ( cleanFormat ) &&
( /M{1,4}/ . test ( cleanFormat ) || /D{1,4}/ . test ( cleanFormat ) ) ) ;
}
return false ;
}
function getDateFromFile ( file , granularity ) {
return getDateFromFilename ( file . basename , granularity ) ;
}
function getDateFromPath ( path , granularity ) {
return getDateFromFilename ( basename ( path ) , granularity ) ;
}
function getDateFromFilename ( filename , granularity ) {
const getSettings = {
day : getDailyNoteSettings ,
week : getWeeklyNoteSettings ,
month : getMonthlyNoteSettings ,
quarter : getQuarterlyNoteSettings ,
year : getYearlyNoteSettings ,
} ;
const format = getSettings [ granularity ] ( ) . format . split ( "/" ) . pop ( ) ;
const noteDate = window . moment ( filename , format , true ) ;
if ( ! noteDate . isValid ( ) ) {
return null ;
}
if ( isFormatAmbiguous ( format , granularity ) ) {
if ( granularity === "week" ) {
const cleanFormat = removeEscapedCharacters ( format ) ;
if ( /w{1,2}/i . test ( cleanFormat ) ) {
return window . moment ( filename ,
// If format contains week, remove day & month formatting
format . replace ( /M{1,4}/g , "" ) . replace ( /D{1,4}/g , "" ) , false ) ;
}
}
}
return noteDate ;
}
class DailyNotesFolderMissingError extends Error {
}
/ * *
* This function mimics the behavior of the daily - notes plugin
* so it will replace { { date } } , { { title } } , and { { time } } with the
* formatted timestamp .
*
* Note : it has an added bonus that it 's not ' today ' specific .
* /
async function createDailyNote ( date ) {
const app = window . app ;
const { vault } = app ;
const moment = window . moment ;
const { template , format , folder } = getDailyNoteSettings ( ) ;
const [ templateContents , IFoldInfo ] = await getTemplateInfo ( template ) ;
const filename = date . format ( format ) ;
const normalizedPath = await getNotePath ( folder , filename ) ;
try {
const createdFile = await vault . create ( normalizedPath , templateContents
. replace ( /{{\s*date\s*}}/gi , filename )
. replace ( /{{\s*time\s*}}/gi , moment ( ) . format ( "HH:mm" ) )
. replace ( /{{\s*title\s*}}/gi , filename )
. replace ( /{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi , ( _ , _timeOrDate , calc , timeDelta , unit , momentFormat ) => {
const now = moment ( ) ;
const currentDate = date . clone ( ) . set ( {
hour : now . get ( "hour" ) ,
minute : now . get ( "minute" ) ,
second : now . get ( "second" ) ,
} ) ;
if ( calc ) {
currentDate . add ( parseInt ( timeDelta , 10 ) , unit ) ;
}
if ( momentFormat ) {
return currentDate . format ( momentFormat . substring ( 1 ) . trim ( ) ) ;
}
return currentDate . format ( format ) ;
} )
. replace ( /{{\s*yesterday\s*}}/gi , date . clone ( ) . subtract ( 1 , "day" ) . format ( format ) )
. replace ( /{{\s*tomorrow\s*}}/gi , date . clone ( ) . add ( 1 , "d" ) . format ( format ) ) ) ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
app . foldManager . save ( createdFile , IFoldInfo ) ;
return createdFile ;
}
catch ( err ) {
console . error ( ` Failed to create file: ' ${ normalizedPath } ' ` , err ) ;
new obsidian _ _default [ "default" ] . Notice ( "Unable to create new file." ) ;
}
}
function getDailyNote ( date , dailyNotes ) {
return dailyNotes [ getDateUID ( date , "day" ) ] ? ? null ;
}
function getAllDailyNotes ( ) {
/ * *
* Find all daily notes in the daily note folder
* /
const { vault } = window . app ;
const { folder } = getDailyNoteSettings ( ) ;
const dailyNotesFolder = vault . getAbstractFileByPath ( obsidian _ _default [ "default" ] . normalizePath ( folder ) ) ;
if ( ! dailyNotesFolder ) {
throw new DailyNotesFolderMissingError ( "Failed to find daily notes folder" ) ;
}
const dailyNotes = { } ;
obsidian _ _default [ "default" ] . Vault . recurseChildren ( dailyNotesFolder , ( note ) => {
if ( note instanceof obsidian _ _default [ "default" ] . TFile ) {
const date = getDateFromFile ( note , "day" ) ;
if ( date ) {
const dateString = getDateUID ( date , "day" ) ;
dailyNotes [ dateString ] = note ;
}
}
} ) ;
return dailyNotes ;
}
class WeeklyNotesFolderMissingError extends Error {
}
function getDaysOfWeek ( ) {
const { moment } = window ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let weekStart = moment . localeData ( ) . _week . dow ;
const daysOfWeek = [
"sunday" ,
"monday" ,
"tuesday" ,
"wednesday" ,
"thursday" ,
"friday" ,
"saturday" ,
] ;
while ( weekStart ) {
daysOfWeek . push ( daysOfWeek . shift ( ) ) ;
weekStart -- ;
}
return daysOfWeek ;
}
function getDayOfWeekNumericalValue ( dayOfWeekName ) {
return getDaysOfWeek ( ) . indexOf ( dayOfWeekName . toLowerCase ( ) ) ;
}
async function createWeeklyNote ( date ) {
const { vault } = window . app ;
const { template , format , folder } = getWeeklyNoteSettings ( ) ;
const [ templateContents , IFoldInfo ] = await getTemplateInfo ( template ) ;
const filename = date . format ( format ) ;
const normalizedPath = await getNotePath ( folder , filename ) ;
try {
const createdFile = await vault . create ( normalizedPath , templateContents
. replace ( /{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi , ( _ , _timeOrDate , calc , timeDelta , unit , momentFormat ) => {
const now = window . moment ( ) ;
const currentDate = date . clone ( ) . set ( {
hour : now . get ( "hour" ) ,
minute : now . get ( "minute" ) ,
second : now . get ( "second" ) ,
} ) ;
if ( calc ) {
currentDate . add ( parseInt ( timeDelta , 10 ) , unit ) ;
}
if ( momentFormat ) {
return currentDate . format ( momentFormat . substring ( 1 ) . trim ( ) ) ;
}
return currentDate . format ( format ) ;
} )
. replace ( /{{\s*title\s*}}/gi , filename )
. replace ( /{{\s*time\s*}}/gi , window . moment ( ) . format ( "HH:mm" ) )
. replace ( /{{\s*(sunday|monday|tuesday|wednesday|thursday|friday|saturday)\s*:(.*?)}}/gi , ( _ , dayOfWeek , momentFormat ) => {
const day = getDayOfWeekNumericalValue ( dayOfWeek ) ;
return date . weekday ( day ) . format ( momentFormat . trim ( ) ) ;
} ) ) ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window . app . foldManager . save ( createdFile , IFoldInfo ) ;
return createdFile ;
}
catch ( err ) {
console . error ( ` Failed to create file: ' ${ normalizedPath } ' ` , err ) ;
new obsidian _ _default [ "default" ] . Notice ( "Unable to create new file." ) ;
}
}
function getWeeklyNote ( date , weeklyNotes ) {
return weeklyNotes [ getDateUID ( date , "week" ) ] ? ? null ;
}
function getAllWeeklyNotes ( ) {
const weeklyNotes = { } ;
if ( ! appHasWeeklyNotesPluginLoaded ( ) ) {
return weeklyNotes ;
}
const { vault } = window . app ;
const { folder } = getWeeklyNoteSettings ( ) ;
const weeklyNotesFolder = vault . getAbstractFileByPath ( obsidian _ _default [ "default" ] . normalizePath ( folder ) ) ;
if ( ! weeklyNotesFolder ) {
throw new WeeklyNotesFolderMissingError ( "Failed to find weekly notes folder" ) ;
}
obsidian _ _default [ "default" ] . Vault . recurseChildren ( weeklyNotesFolder , ( note ) => {
if ( note instanceof obsidian _ _default [ "default" ] . TFile ) {
const date = getDateFromFile ( note , "week" ) ;
if ( date ) {
const dateString = getDateUID ( date , "week" ) ;
weeklyNotes [ dateString ] = note ;
}
}
} ) ;
return weeklyNotes ;
}
class MonthlyNotesFolderMissingError extends Error {
}
/ * *
* This function mimics the behavior of the daily - notes plugin
* so it will replace { { date } } , { { title } } , and { { time } } with the
* formatted timestamp .
*
* Note : it has an added bonus that it 's not ' today ' specific .
* /
async function createMonthlyNote ( date ) {
const { vault } = window . app ;
const { template , format , folder } = getMonthlyNoteSettings ( ) ;
const [ templateContents , IFoldInfo ] = await getTemplateInfo ( template ) ;
const filename = date . format ( format ) ;
const normalizedPath = await getNotePath ( folder , filename ) ;
try {
const createdFile = await vault . create ( normalizedPath , templateContents
. replace ( /{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi , ( _ , _timeOrDate , calc , timeDelta , unit , momentFormat ) => {
const now = window . moment ( ) ;
const currentDate = date . clone ( ) . set ( {
hour : now . get ( "hour" ) ,
minute : now . get ( "minute" ) ,
second : now . get ( "second" ) ,
} ) ;
if ( calc ) {
currentDate . add ( parseInt ( timeDelta , 10 ) , unit ) ;
}
if ( momentFormat ) {
return currentDate . format ( momentFormat . substring ( 1 ) . trim ( ) ) ;
}
return currentDate . format ( format ) ;
} )
. replace ( /{{\s*date\s*}}/gi , filename )
. replace ( /{{\s*time\s*}}/gi , window . moment ( ) . format ( "HH:mm" ) )
. replace ( /{{\s*title\s*}}/gi , filename ) ) ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window . app . foldManager . save ( createdFile , IFoldInfo ) ;
return createdFile ;
}
catch ( err ) {
console . error ( ` Failed to create file: ' ${ normalizedPath } ' ` , err ) ;
new obsidian _ _default [ "default" ] . Notice ( "Unable to create new file." ) ;
}
}
function getMonthlyNote ( date , monthlyNotes ) {
return monthlyNotes [ getDateUID ( date , "month" ) ] ? ? null ;
}
function getAllMonthlyNotes ( ) {
const monthlyNotes = { } ;
if ( ! appHasMonthlyNotesPluginLoaded ( ) ) {
return monthlyNotes ;
}
const { vault } = window . app ;
const { folder } = getMonthlyNoteSettings ( ) ;
const monthlyNotesFolder = vault . getAbstractFileByPath ( obsidian _ _default [ "default" ] . normalizePath ( folder ) ) ;
if ( ! monthlyNotesFolder ) {
throw new MonthlyNotesFolderMissingError ( "Failed to find monthly notes folder" ) ;
}
obsidian _ _default [ "default" ] . Vault . recurseChildren ( monthlyNotesFolder , ( note ) => {
if ( note instanceof obsidian _ _default [ "default" ] . TFile ) {
const date = getDateFromFile ( note , "month" ) ;
if ( date ) {
const dateString = getDateUID ( date , "month" ) ;
monthlyNotes [ dateString ] = note ;
}
}
} ) ;
return monthlyNotes ;
}
class QuarterlyNotesFolderMissingError extends Error {
}
/ * *
* This function mimics the behavior of the daily - notes plugin
* so it will replace { { date } } , { { title } } , and { { time } } with the
* formatted timestamp .
*
* Note : it has an added bonus that it 's not ' today ' specific .
* /
async function createQuarterlyNote ( date ) {
const { vault } = window . app ;
const { template , format , folder } = getQuarterlyNoteSettings ( ) ;
const [ templateContents , IFoldInfo ] = await getTemplateInfo ( template ) ;
const filename = date . format ( format ) ;
const normalizedPath = await getNotePath ( folder , filename ) ;
try {
const createdFile = await vault . create ( normalizedPath , templateContents
. replace ( /{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi , ( _ , _timeOrDate , calc , timeDelta , unit , momentFormat ) => {
const now = window . moment ( ) ;
const currentDate = date . clone ( ) . set ( {
hour : now . get ( "hour" ) ,
minute : now . get ( "minute" ) ,
second : now . get ( "second" ) ,
} ) ;
if ( calc ) {
currentDate . add ( parseInt ( timeDelta , 10 ) , unit ) ;
}
if ( momentFormat ) {
return currentDate . format ( momentFormat . substring ( 1 ) . trim ( ) ) ;
}
return currentDate . format ( format ) ;
} )
. replace ( /{{\s*date\s*}}/gi , filename )
. replace ( /{{\s*time\s*}}/gi , window . moment ( ) . format ( "HH:mm" ) )
. replace ( /{{\s*title\s*}}/gi , filename ) ) ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window . app . foldManager . save ( createdFile , IFoldInfo ) ;
return createdFile ;
}
catch ( err ) {
console . error ( ` Failed to create file: ' ${ normalizedPath } ' ` , err ) ;
new obsidian _ _default [ "default" ] . Notice ( "Unable to create new file." ) ;
}
}
function getQuarterlyNote ( date , quarterly ) {
return quarterly [ getDateUID ( date , "quarter" ) ] ? ? null ;
}
function getAllQuarterlyNotes ( ) {
const quarterly = { } ;
if ( ! appHasQuarterlyNotesPluginLoaded ( ) ) {
return quarterly ;
}
const { vault } = window . app ;
const { folder } = getQuarterlyNoteSettings ( ) ;
const quarterlyFolder = vault . getAbstractFileByPath ( obsidian _ _default [ "default" ] . normalizePath ( folder ) ) ;
if ( ! quarterlyFolder ) {
throw new QuarterlyNotesFolderMissingError ( "Failed to find quarterly notes folder" ) ;
}
obsidian _ _default [ "default" ] . Vault . recurseChildren ( quarterlyFolder , ( note ) => {
if ( note instanceof obsidian _ _default [ "default" ] . TFile ) {
const date = getDateFromFile ( note , "quarter" ) ;
if ( date ) {
const dateString = getDateUID ( date , "quarter" ) ;
quarterly [ dateString ] = note ;
}
}
} ) ;
return quarterly ;
}
class YearlyNotesFolderMissingError extends Error {
}
/ * *
* This function mimics the behavior of the daily - notes plugin
* so it will replace { { date } } , { { title } } , and { { time } } with the
* formatted timestamp .
*
* Note : it has an added bonus that it 's not ' today ' specific .
* /
async function createYearlyNote ( date ) {
const { vault } = window . app ;
const { template , format , folder } = getYearlyNoteSettings ( ) ;
const [ templateContents , IFoldInfo ] = await getTemplateInfo ( template ) ;
const filename = date . format ( format ) ;
const normalizedPath = await getNotePath ( folder , filename ) ;
try {
const createdFile = await vault . create ( normalizedPath , templateContents
. replace ( /{{\s*(date|time)\s*(([+-]\d+)([yqmwdhs]))?\s*(:.+?)?}}/gi , ( _ , _timeOrDate , calc , timeDelta , unit , momentFormat ) => {
const now = window . moment ( ) ;
const currentDate = date . clone ( ) . set ( {
hour : now . get ( "hour" ) ,
minute : now . get ( "minute" ) ,
second : now . get ( "second" ) ,
} ) ;
if ( calc ) {
currentDate . add ( parseInt ( timeDelta , 10 ) , unit ) ;
}
if ( momentFormat ) {
return currentDate . format ( momentFormat . substring ( 1 ) . trim ( ) ) ;
}
return currentDate . format ( format ) ;
} )
. replace ( /{{\s*date\s*}}/gi , filename )
. replace ( /{{\s*time\s*}}/gi , window . moment ( ) . format ( "HH:mm" ) )
. replace ( /{{\s*title\s*}}/gi , filename ) ) ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window . app . foldManager . save ( createdFile , IFoldInfo ) ;
return createdFile ;
}
catch ( err ) {
console . error ( ` Failed to create file: ' ${ normalizedPath } ' ` , err ) ;
new obsidian _ _default [ "default" ] . Notice ( "Unable to create new file." ) ;
}
}
function getYearlyNote ( date , yearlyNotes ) {
return yearlyNotes [ getDateUID ( date , "year" ) ] ? ? null ;
}
function getAllYearlyNotes ( ) {
const yearlyNotes = { } ;
if ( ! appHasYearlyNotesPluginLoaded ( ) ) {
return yearlyNotes ;
}
const { vault } = window . app ;
const { folder } = getYearlyNoteSettings ( ) ;
const yearlyNotesFolder = vault . getAbstractFileByPath ( obsidian _ _default [ "default" ] . normalizePath ( folder ) ) ;
if ( ! yearlyNotesFolder ) {
throw new YearlyNotesFolderMissingError ( "Failed to find yearly notes folder" ) ;
}
obsidian _ _default [ "default" ] . Vault . recurseChildren ( yearlyNotesFolder , ( note ) => {
if ( note instanceof obsidian _ _default [ "default" ] . TFile ) {
const date = getDateFromFile ( note , "year" ) ;
if ( date ) {
const dateString = getDateUID ( date , "year" ) ;
yearlyNotes [ dateString ] = note ;
}
}
} ) ;
return yearlyNotes ;
}
function appHasDailyNotesPluginLoaded ( ) {
const { app } = window ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const dailyNotesPlugin = app . internalPlugins . plugins [ "daily-notes" ] ;
if ( dailyNotesPlugin && dailyNotesPlugin . enabled ) {
return true ;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const periodicNotes = app . plugins . getPlugin ( "periodic-notes" ) ;
return periodicNotes && periodicNotes . settings ? . daily ? . enabled ;
}
/ * *
* XXX : "Weekly Notes" live in either the Calendar plugin or the periodic - notes plugin .
* Check both until the weekly notes feature is removed from the Calendar plugin .
* /
function appHasWeeklyNotesPluginLoaded ( ) {
const { app } = window ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if ( app . plugins . getPlugin ( "calendar" ) ) {
return true ;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const periodicNotes = app . plugins . getPlugin ( "periodic-notes" ) ;
return periodicNotes && periodicNotes . settings ? . weekly ? . enabled ;
}
function appHasMonthlyNotesPluginLoaded ( ) {
const { app } = window ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const periodicNotes = app . plugins . getPlugin ( "periodic-notes" ) ;
return periodicNotes && periodicNotes . settings ? . monthly ? . enabled ;
}
function appHasQuarterlyNotesPluginLoaded ( ) {
const { app } = window ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const periodicNotes = app . plugins . getPlugin ( "periodic-notes" ) ;
return periodicNotes && periodicNotes . settings ? . quarterly ? . enabled ;
}
function appHasYearlyNotesPluginLoaded ( ) {
const { app } = window ;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const periodicNotes = app . plugins . getPlugin ( "periodic-notes" ) ;
return periodicNotes && periodicNotes . settings ? . yearly ? . enabled ;
}
function getPeriodicNoteSettings ( granularity ) {
const getSettings = {
day : getDailyNoteSettings ,
week : getWeeklyNoteSettings ,
month : getMonthlyNoteSettings ,
quarter : getQuarterlyNoteSettings ,
year : getYearlyNoteSettings ,
} [ granularity ] ;
return getSettings ( ) ;
}
function createPeriodicNote ( granularity , date ) {
const createFn = {
day : createDailyNote ,
month : createMonthlyNote ,
week : createWeeklyNote ,
} ;
return createFn [ granularity ] ( date ) ;
}
exports . DEFAULT _DAILY _NOTE _FORMAT = DEFAULT _DAILY _NOTE _FORMAT ;
exports . DEFAULT _MONTHLY _NOTE _FORMAT = DEFAULT _MONTHLY _NOTE _FORMAT ;
exports . DEFAULT _QUARTERLY _NOTE _FORMAT = DEFAULT _QUARTERLY _NOTE _FORMAT ;
exports . DEFAULT _WEEKLY _NOTE _FORMAT = DEFAULT _WEEKLY _NOTE _FORMAT ;
exports . DEFAULT _YEARLY _NOTE _FORMAT = DEFAULT _YEARLY _NOTE _FORMAT ;
exports . appHasDailyNotesPluginLoaded = appHasDailyNotesPluginLoaded ;
exports . appHasMonthlyNotesPluginLoaded = appHasMonthlyNotesPluginLoaded ;
exports . appHasQuarterlyNotesPluginLoaded = appHasQuarterlyNotesPluginLoaded ;
exports . appHasWeeklyNotesPluginLoaded = appHasWeeklyNotesPluginLoaded ;
exports . appHasYearlyNotesPluginLoaded = appHasYearlyNotesPluginLoaded ;
exports . createDailyNote = createDailyNote ;
exports . createMonthlyNote = createMonthlyNote ;
exports . createPeriodicNote = createPeriodicNote ;
exports . createQuarterlyNote = createQuarterlyNote ;
exports . createWeeklyNote = createWeeklyNote ;
exports . createYearlyNote = createYearlyNote ;
exports . getAllDailyNotes = getAllDailyNotes ;
exports . getAllMonthlyNotes = getAllMonthlyNotes ;
exports . getAllQuarterlyNotes = getAllQuarterlyNotes ;
exports . getAllWeeklyNotes = getAllWeeklyNotes ;
exports . getAllYearlyNotes = getAllYearlyNotes ;
exports . getDailyNote = getDailyNote ;
exports . getDailyNoteSettings = getDailyNoteSettings ;
exports . getDateFromFile = getDateFromFile ;
exports . getDateFromPath = getDateFromPath ;
exports . getDateUID = getDateUID ;
exports . getMonthlyNote = getMonthlyNote ;
exports . getMonthlyNoteSettings = getMonthlyNoteSettings ;
exports . getPeriodicNoteSettings = getPeriodicNoteSettings ;
exports . getQuarterlyNote = getQuarterlyNote ;
exports . getQuarterlyNoteSettings = getQuarterlyNoteSettings ;
exports . getTemplateInfo = getTemplateInfo ;
exports . getWeeklyNote = getWeeklyNote ;
exports . getWeeklyNoteSettings = getWeeklyNoteSettings ;
exports . getYearlyNote = getYearlyNote ;
exports . getYearlyNoteSettings = getYearlyNoteSettings ;
} ) ;
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
var getRandomValues ;
var rnds8 = new Uint8Array ( 16 ) ;
function rng ( ) {
// lazy load so that environments that need to polyfill have a chance to do so
if ( ! getRandomValues ) {
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
getRandomValues = typeof crypto !== 'undefined' && crypto . getRandomValues && crypto . getRandomValues . bind ( crypto ) || typeof msCrypto !== 'undefined' && typeof msCrypto . getRandomValues === 'function' && msCrypto . getRandomValues . bind ( msCrypto ) ;
if ( ! getRandomValues ) {
throw new Error ( 'crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported' ) ;
}
}
return getRandomValues ( rnds8 ) ;
}
var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i ;
function validate ( uuid ) {
return typeof uuid === 'string' && REGEX . test ( uuid ) ;
}
/ * *
* Convert array of 16 byte values to UUID string format of the form :
* XXXXXXXX - XXXX - XXXX - XXXX - XXXXXXXXXXXX
* /
var byteToHex = [ ] ;
for ( var i = 0 ; i < 256 ; ++ i ) {
byteToHex . push ( ( i + 0x100 ) . toString ( 16 ) . substr ( 1 ) ) ;
}
function stringify ( arr ) {
var offset = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : 0 ;
// Note: Be careful editing this code! It's been tuned for performance
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
var uuid = ( byteToHex [ arr [ offset + 0 ] ] + byteToHex [ arr [ offset + 1 ] ] + byteToHex [ arr [ offset + 2 ] ] + byteToHex [ arr [ offset + 3 ] ] + '-' + byteToHex [ arr [ offset + 4 ] ] + byteToHex [ arr [ offset + 5 ] ] + '-' + byteToHex [ arr [ offset + 6 ] ] + byteToHex [ arr [ offset + 7 ] ] + '-' + byteToHex [ arr [ offset + 8 ] ] + byteToHex [ arr [ offset + 9 ] ] + '-' + byteToHex [ arr [ offset + 10 ] ] + byteToHex [ arr [ offset + 11 ] ] + byteToHex [ arr [ offset + 12 ] ] + byteToHex [ arr [ offset + 13 ] ] + byteToHex [ arr [ offset + 14 ] ] + byteToHex [ arr [ offset + 15 ] ] ) . toLowerCase ( ) ; // Consistency check for valid UUID. If this throws, it's likely due to one
// of the following:
// - One or more input array values don't map to a hex octet (leading to
// "undefined" in the uuid)
// - Invalid input values for the RFC `version` or `variant` fields
if ( ! validate ( uuid ) ) {
throw TypeError ( 'Stringified UUID is invalid' ) ;
}
return uuid ;
}
function v4 ( options , buf , offset ) {
options = options || { } ;
var rnds = options . random || ( options . rng || rng ) ( ) ; // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds [ 6 ] = rnds [ 6 ] & 0x0f | 0x40 ;
rnds [ 8 ] = rnds [ 8 ] & 0x3f | 0x80 ; // Copy bytes to buffer, if provided
if ( buf ) {
offset = offset || 0 ;
for ( var i = 0 ; i < 16 ; ++ i ) {
buf [ offset + i ] = rnds [ i ] ;
}
return buf ;
}
return stringify ( rnds ) ;
}
//! All of these methods are taken from https://www.npmjs.com/package/obsidian-daily-notes-interface.
function join ( ) {
var partSegments = [ ] ;
for ( var _i = 0 ; _i < arguments . length ; _i ++ ) {
partSegments [ _i ] = arguments [ _i ] ;
}
// Split the inputs into a list of path commands.
var parts = [ ] ;
for ( var i = 0 , l = partSegments . length ; i < l ; i ++ ) {
parts = parts . concat ( partSegments [ i ] . split ( "/" ) ) ;
}
// Interpret the path commands to get the new resolved path.
var newParts = [ ] ;
for ( var i = 0 , l = parts . length ; i < l ; i ++ ) {
var part = parts [ i ] ;
// Remove leading and trailing slashes
// Also remove "." segments
if ( ! part || part === "." )
continue ;
// Push new path segments.
else
newParts . push ( part ) ;
}
// Preserve the initial slash if there was one.
if ( parts [ 0 ] === "" )
newParts . unshift ( "" ) ;
// Turn back into a single string path.
return newParts . join ( "/" ) ;
}
function getNotePath ( directory , filename ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var path ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 :
if ( ! filename . endsWith ( ".md" ) ) {
filename += ".md" ;
}
path = obsidian . normalizePath ( join ( directory , filename ) ) ;
return [ 4 /*yield*/ , ensureFolderExists ( path ) ] ;
case 1 :
_a . sent ( ) ;
return [ 2 /*return*/ , path ] ;
}
} ) ;
} ) ;
}
function ensureFolderExists ( path ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var dirs , dir ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 :
dirs = path . replace ( /\\/g , "/" ) . split ( "/" ) ;
dirs . pop ( ) ; // remove basename
if ( ! dirs . length ) return [ 3 /*break*/ , 2 ] ;
dir = join . apply ( void 0 , dirs ) ;
if ( ! ! window . app . vault . getAbstractFileByPath ( dir ) ) return [ 3 /*break*/ , 2 ] ;
return [ 4 /*yield*/ , window . app . vault . createFolder ( dir ) ] ;
case 1 :
_a . sent ( ) ;
_a . label = 2 ;
case 2 : return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
}
function getDailyNotePath ( date ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var _a , format , folder , filename , normalizedPath ;
return _ _generator ( this , function ( _b ) {
switch ( _b . label ) {
case 0 :
_a = main . getDailyNoteSettings ( ) , format = _a . format , folder = _a . folder ;
filename = date . format ( format ) ;
return [ 4 /*yield*/ , getNotePath ( folder , filename ) ] ;
case 1 :
normalizedPath = _b . sent ( ) ;
return [ 2 /*return*/ , normalizedPath ] ;
}
} ) ;
} ) ;
}
var DEFAULT _SETTINGS = {
openFileOnWrite : true ,
openDailyInNewPane : false ,
openFileOnWriteInNewPane : false ,
openFileWithoutWriteInNewPane : false ,
idField : "id" ,
useUID : false ,
} ;
var AdvancedURI = /** @class */ ( function ( _super ) {
_ _extends ( AdvancedURI , _super ) ;
function AdvancedURI ( ) {
return _super !== null && _super . apply ( this , arguments ) || this ;
}
AdvancedURI . prototype . onload = function ( ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var _this = this ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 : return [ 4 /*yield*/ , this . loadSettings ( ) ] ;
case 1 :
_a . sent ( ) ;
this . addSettingTab ( new SettingsTab ( this . app , this ) ) ;
this . addCommand ( {
id : "copy-uri-current-file" ,
name : "copy URI for file" ,
callback : function ( ) { return _this . handleCopyFileURI ( ) ; }
} ) ;
this . addCommand ( {
id : "copy-uri-daily" ,
name : "copy URI for daily note" ,
callback : function ( ) { return new EnterDataModal ( _this ) . open ( ) ; }
} ) ;
this . addCommand ( {
id : "copy-uri-search-and-replace" ,
name : "copy URI for search and replace" ,
callback : function ( ) {
var fileModal = new FileModal ( _this , "Used file for search and replace" ) ;
fileModal . open ( ) ;
fileModal . onChooseItem = function ( filePath ) {
var searchModal = new SearchModal ( _this ) ;
searchModal . open ( ) ;
searchModal . onChooseSuggestion = function ( item ) {
new ReplaceModal ( _this , item , filePath === null || filePath === void 0 ? void 0 : filePath . source ) . open ( ) ;
} ;
} ;
} ,
} ) ;
this . addCommand ( {
id : "copy-uri-command" ,
name : "copy URI for command" ,
callback : function ( ) {
var fileModal = new FileModal ( _this , "Select a file to be opened before executing the command" ) ;
fileModal . open ( ) ;
fileModal . onChooseItem = function ( item ) {
new CommandModal ( _this , item === null || item === void 0 ? void 0 : item . source ) . open ( ) ;
} ;
}
} ) ;
this . registerObsidianProtocolHandler ( "advanced-uri" , function ( e ) { return _ _awaiter ( _this , void 0 , void 0 , function ( ) {
var parameters , createdDailyNote , parameter , file , index , extension , moment _1 , allDailyNotes , dailyNote , _a ;
var _this = this ;
var _b , _c ;
return _ _generator ( this , function ( _d ) {
switch ( _d . label ) {
case 0 :
parameters = e ;
createdDailyNote = false ;
for ( parameter in parameters ) {
parameters [ parameter ] = decodeURIComponent ( parameters [ parameter ] ) ;
}
if ( ! parameters . uid ) return [ 3 /*break*/ , 1 ] ;
parameters . filepath = ( _b = this . getFileFromUID ( parameters . uid ) ) === null || _b === void 0 ? void 0 : _b . path ;
return [ 3 /*break*/ , 8 ] ;
case 1 :
if ( ! parameters . filename ) return [ 3 /*break*/ , 2 ] ;
file = this . app . metadataCache . getFirstLinkpathDest ( parameters . filename , "" ) ;
if ( ! file ) {
file = this . app . vault . getMarkdownFiles ( ) . find ( function ( file ) { var _a ; return ( _a = obsidian . parseFrontMatterAliases ( _this . app . metadataCache . getFileCache ( file ) . frontmatter ) ) === null || _a === void 0 ? void 0 : _a . includes ( parameters . filename ) ; } ) ;
}
parameters . filepath = ( _c = file === null || file === void 0 ? void 0 : file . path ) !== null && _c !== void 0 ? _c : obsidian . normalizePath ( parameters . filename ) ;
return [ 3 /*break*/ , 8 ] ;
case 2 :
if ( ! parameters . filepath ) return [ 3 /*break*/ , 3 ] ;
parameters . filepath = obsidian . normalizePath ( parameters . filepath ) ;
index = parameters . filepath . lastIndexOf ( "." ) ;
extension = parameters . filepath . substring ( index < 0 ? parameters . filepath . length : index ) ;
if ( extension === "" ) {
parameters . filepath = parameters . filepath + ".md" ;
}
return [ 3 /*break*/ , 8 ] ;
case 3 :
if ( ! ( parameters . daily === "true" ) ) return [ 3 /*break*/ , 8 ] ;
if ( ! main . appHasDailyNotesPluginLoaded ( ) ) {
new obsidian . Notice ( "Daily notes plugin is not loaded" ) ;
return [ 2 /*return*/ ] ;
}
moment _1 = window . moment ( Date . now ( ) ) ;
allDailyNotes = main . getAllDailyNotes ( ) ;
dailyNote = main . getDailyNote ( moment _1 , allDailyNotes ) ;
if ( ! ! dailyNote ) return [ 3 /*break*/ , 7 ] ;
if ( ! ( parameters . exists === "true" ) ) return [ 3 /*break*/ , 5 ] ;
_a = parameters ;
return [ 4 /*yield*/ , getDailyNotePath ( moment _1 ) ] ;
case 4 :
_a . filepath = _d . sent ( ) ;
return [ 3 /*break*/ , 7 ] ;
case 5 : return [ 4 /*yield*/ , main . createDailyNote ( moment _1 ) ] ;
case 6 :
dailyNote = _d . sent ( ) ;
createdDailyNote = true ;
_d . label = 7 ;
case 7 :
if ( dailyNote !== undefined ) {
parameters . filepath = dailyNote . path ;
}
_d . label = 8 ;
case 8 :
if ( parameters . workspace || parameters . saveworkspace == "true" ) {
this . handleWorkspace ( parameters ) ;
}
else if ( parameters . commandname || parameters . commandid ) {
this . handleCommand ( parameters ) ;
}
else if ( parameters . filepath && parameters . exists === "true" ) {
this . handleDoesFileExist ( parameters ) ;
}
else if ( parameters . filepath && parameters . data ) {
this . handleWrite ( parameters , createdDailyNote ) ;
}
else if ( parameters . filepath && parameters . heading ) {
this . handleOpen ( parameters ) ;
}
else if ( parameters . filepath && parameters . block ) {
this . handleOpen ( parameters ) ;
}
else if ( ( parameters . search || parameters . searchregex ) && parameters . replace != undefined ) {
this . handleSearchAndReplace ( parameters ) ;
}
else if ( parameters . filepath ) {
this . handleOpen ( parameters ) ;
}
else if ( parameters . settingid ) {
this . handleOpenSettings ( parameters ) ;
}
else if ( parameters . updateplugins ) {
this . handleUpdatePlugins ( parameters ) ;
}
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ; } ) ;
this . registerEvent ( this . app . workspace . on ( 'file-menu' , function ( menu , _ , source ) {
if ( source !== "pane-more-options" ) {
return ;
}
var view = _this . app . workspace . getActiveViewOfType ( obsidian . MarkdownView ) ;
if ( ! view ) {
return ;
}
menu . addItem ( function ( item ) {
item . setTitle ( "Copy Advanced URI" ) . setIcon ( 'link' )
. onClick ( function ( _ ) { return _this . handleCopyFileURI ( ) ; } ) ;
} ) ;
} ) ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . success = function ( parameters ) {
if ( parameters [ "x-success" ] )
obsidian . request ( { url : parameters [ "x-success" ] , } ) ;
} ;
AdvancedURI . prototype . failure = function ( parameters ) {
if ( parameters [ "x-error" ] )
obsidian . request ( { url : parameters [ "x-error" ] } ) ;
} ;
AdvancedURI . prototype . getFileFromUID = function ( uid ) {
var _this = this ;
var files = this . app . vault . getFiles ( ) ;
var idKey = this . settings . idField ;
return files . find ( function ( file ) { var _a ; return obsidian . parseFrontMatterEntry ( ( _a = _this . app . metadataCache . getFileCache ( file ) ) === null || _a === void 0 ? void 0 : _a . frontmatter , idKey ) == uid ; } ) ;
} ;
AdvancedURI . prototype . handleWorkspace = function ( parameters ) {
var _a , _b , _c ;
var workspaces = ( _c = ( _b = ( _a = this . app ) === null || _a === void 0 ? void 0 : _a . internalPlugins ) === null || _b === void 0 ? void 0 : _b . plugins ) === null || _c === void 0 ? void 0 : _c . workspaces ;
if ( ! workspaces ) {
new obsidian . Notice ( "Cannot find Workspaces plugin. Please file an issue." ) ;
this . failure ( parameters ) ;
}
else if ( workspaces . enabled ) {
if ( parameters . saveworkspace == "true" ) {
var active = workspaces . instance . activeWorkspace ;
workspaces . instance . saveWorkspace ( active ) ;
new obsidian . Notice ( "Saved current workspace to " + active ) ;
}
if ( parameters . workspace != undefined ) {
workspaces . instance . loadWorkspace ( parameters . workspace ) ;
}
this . success ( parameters ) ;
}
else {
new obsidian . Notice ( "Workspaces plugin is not enabled" ) ;
this . failure ( parameters ) ;
}
} ;
AdvancedURI . prototype . handleCommand = function ( parameters ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var view , editor , data , lines , rawCommands , command ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 :
if ( ! parameters . filepath ) return [ 3 /*break*/ , 4 ] ;
if ( ! parameters . mode ) return [ 3 /*break*/ , 2 ] ;
return [ 4 /*yield*/ , this . app . workspace . openLinkText ( parameters . filepath , "/" , undefined , {
state : { mode : "source" }
} ) ] ;
case 1 :
_a . sent ( ) ;
view = this . app . workspace . getActiveViewOfType ( obsidian . MarkdownView ) ;
if ( view ) {
editor = view . editor ;
data = editor . getValue ( ) ;
if ( parameters . mode === "append" ) {
editor . setValue ( data + "\n" ) ;
lines = editor . lineCount ( ) ;
editor . setCursor ( { ch : 0 , line : lines } ) ;
}
else if ( parameters . mode === "prepend" ) {
editor . setValue ( "\n" + data ) ;
editor . setCursor ( { ch : 0 , line : 0 } ) ;
}
else if ( parameters . mode === "overwrite" ) {
editor . setValue ( "" ) ;
}
}
return [ 3 /*break*/ , 4 ] ;
case 2 : return [ 4 /*yield*/ , this . app . workspace . openLinkText ( parameters . filepath , "/" , this . settings . openFileWithoutWriteInNewPane , this . getViewStateFromMode ( parameters ) ) ] ;
case 3 :
_a . sent ( ) ;
_a . label = 4 ;
case 4 :
if ( parameters . commandid ) {
this . app . commands . executeCommandById ( parameters . commandid ) ;
}
else if ( parameters . commandname ) {
rawCommands = this . app . commands . commands ;
for ( command in rawCommands ) {
if ( rawCommands [ command ] . name === parameters . commandname ) {
if ( rawCommands [ command ] . callback ) {
rawCommands [ command ] . callback ( ) ;
}
else {
rawCommands [ command ] . checkCallback ( ) ;
}
break ;
}
}
}
this . success ( parameters ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . handleDoesFileExist = function ( parameters ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var exists ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 : return [ 4 /*yield*/ , this . app . vault . adapter . exists ( parameters . filepath ) ] ;
case 1 :
exists = _a . sent ( ) ;
this . copyText ( ( exists ? 1 : 0 ) . toString ( ) ) ;
this . success ( parameters ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . handleSearchAndReplace = function ( parameters ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var file , abstractFile , data , _a , pattern , flags , regex ;
return _ _generator ( this , function ( _b ) {
switch ( _b . label ) {
case 0 :
if ( parameters . filepath ) {
abstractFile = this . app . vault . getAbstractFileByPath ( parameters . filepath ) ;
if ( abstractFile instanceof obsidian . TFile ) {
file = abstractFile ;
}
}
else {
file = this . app . workspace . getActiveFile ( ) ;
}
if ( ! file ) return [ 3 /*break*/ , 3 ] ;
return [ 4 /*yield*/ , this . app . vault . read ( file ) ] ;
case 1 :
data = _b . sent ( ) ;
if ( parameters . searchregex ) {
try {
_a = parameters . searchregex . match ( /(\/?)(.+)\1([a-z]*)/i ) , pattern = _a [ 2 ] , flags = _a [ 3 ] ;
regex = new RegExp ( pattern , flags ) ;
data = data . replace ( regex , parameters . replace ) ;
this . success ( parameters ) ;
}
catch ( error ) {
new obsidian . Notice ( "Can't parse " + parameters . searchregex + " as RegEx" ) ;
this . failure ( parameters ) ;
}
}
else {
data = data . replaceAll ( parameters . search , parameters . replace ) ;
this . success ( parameters ) ;
}
return [ 4 /*yield*/ , this . writeAndOpenFile ( file . path , data , parameters ) ] ;
case 2 :
_b . sent ( ) ;
return [ 3 /*break*/ , 4 ] ;
case 3 :
new obsidian . Notice ( "Cannot find file" ) ;
this . failure ( parameters ) ;
_b . label = 4 ;
case 4 : return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . handleWrite = function ( parameters , createdDailyNote ) {
if ( createdDailyNote === void 0 ) { createdDailyNote = false ; }
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var path , file ;
return _ _generator ( this , function ( _a ) {
path = parameters . filepath ;
file = this . app . vault . getAbstractFileByPath ( path ) ;
if ( parameters . mode === "overwrite" ) {
this . writeAndOpenFile ( path , parameters . data , parameters ) ;
this . success ( parameters ) ;
}
else if ( parameters . mode === "prepend" ) {
if ( file instanceof obsidian . TFile ) {
this . prepend ( file , parameters ) ;
}
else {
this . prepend ( path , parameters ) ;
}
this . success ( parameters ) ;
}
else if ( parameters . mode === "append" ) {
if ( file instanceof obsidian . TFile ) {
this . append ( file , parameters ) ;
}
else {
this . append ( path , parameters ) ;
}
this . success ( parameters ) ;
}
else if ( ! createdDailyNote && file instanceof obsidian . TFile ) {
new obsidian . Notice ( "File already exists" ) ;
this . failure ( parameters ) ;
}
else {
this . writeAndOpenFile ( path , parameters . data , parameters ) ;
this . success ( parameters ) ;
}
return [ 2 /*return*/ ] ;
} ) ;
} ) ;
} ;
AdvancedURI . prototype . handleOpen = function ( parameters ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var fileIsAlreadyOpened , leaf , viewState , view , cache , heading , view , cache , block , view , line ;
var _this = this ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 :
fileIsAlreadyOpened = false ;
this . app . workspace . iterateAllLeaves ( function ( leaf ) {
var _a ;
if ( ( ( _a = leaf . view . file ) === null || _a === void 0 ? void 0 : _a . path ) === parameters . filepath ) {
fileIsAlreadyOpened = true ;
_this . app . workspace . setActiveLeaf ( leaf , true , true ) ;
}
} ) ;
if ( ! fileIsAlreadyOpened ) return [ 3 /*break*/ , 2 ] ;
leaf = this . app . workspace . activeLeaf ;
if ( ! ( parameters . viewmode != undefined ) ) return [ 3 /*break*/ , 2 ] ;
viewState = leaf . getViewState ( ) ;
viewState . state . mode = parameters . viewmode ;
return [ 4 /*yield*/ , leaf . setViewState ( viewState ) ] ;
case 1 :
_a . sent ( ) ;
_a . label = 2 ;
case 2 :
if ( ! ( parameters . heading != undefined ) ) return [ 3 /*break*/ , 4 ] ;
return [ 4 /*yield*/ , this . app . workspace . openLinkText ( parameters . filepath + "#" + parameters . heading , "" , this . settings . openFileWithoutWriteInNewPane , this . getViewStateFromMode ( parameters ) ) ] ;
case 3 :
_a . sent ( ) ;
view = this . app . workspace . getActiveViewOfType ( obsidian . MarkdownView ) ;
if ( ! view )
return [ 2 /*return*/ ] ;
cache = this . app . metadataCache . getFileCache ( view . file ) ;
heading = cache . headings . find ( function ( e ) { return e . heading === parameters . heading ; } ) ;
view . editor . focus ( ) ;
view . editor . setCursor ( { line : heading . position . start . line + 1 , ch : 0 } ) ;
return [ 3 /*break*/ , 9 ] ;
case 4 :
if ( ! ( parameters . block != undefined ) ) return [ 3 /*break*/ , 6 ] ;
return [ 4 /*yield*/ , this . app . workspace . openLinkText ( parameters . filepath + "#^" + parameters . block , "" , this . settings . openFileWithoutWriteInNewPane , this . getViewStateFromMode ( parameters ) ) ] ;
case 5 :
_a . sent ( ) ;
view = this . app . workspace . getActiveViewOfType ( obsidian . MarkdownView ) ;
if ( ! view )
return [ 2 /*return*/ ] ;
cache = this . app . metadataCache . getFileCache ( view . file ) ;
block = cache . blocks [ parameters . block ] ;
view . editor . focus ( ) ;
view . editor . setCursor ( { line : block . position . start . line , ch : 0 } ) ;
return [ 3 /*break*/ , 9 ] ;
case 6 :
if ( ! ! fileIsAlreadyOpened ) return [ 3 /*break*/ , 8 ] ;
return [ 4 /*yield*/ , this . app . workspace . openLinkText ( parameters . filepath , "" , this . settings . openFileWithoutWriteInNewPane , this . getViewStateFromMode ( parameters ) ) ] ;
case 7 :
_a . sent ( ) ;
_a . label = 8 ;
case 8 :
if ( parameters . line != undefined ) {
view = this . app . workspace . getActiveViewOfType ( obsidian . MarkdownView ) ;
if ( ! view )
return [ 2 /*return*/ ] ;
line = Math . min ( parameters . line - 1 , view . editor . lineCount ( ) - 1 ) ;
view . editor . focus ( ) ;
view . editor . setCursor ( { line : line , ch : view . editor . getLine ( line ) . length } ) ;
}
_a . label = 9 ;
case 9 :
if ( ! ( parameters . mode != undefined ) ) return [ 3 /*break*/ , 11 ] ;
return [ 4 /*yield*/ , this . setCursor ( parameters . mode ) ] ;
case 10 :
_a . sent ( ) ;
_a . label = 11 ;
case 11 :
this . success ( parameters ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . append = function ( file , parameters ) {
var _a ;
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var path , dataToWrite , line , data , lines , fileData ;
return _ _generator ( this , function ( _b ) {
switch ( _b . label ) {
case 0 :
if ( ! parameters . heading ) return [ 3 /*break*/ , 3 ] ;
if ( ! ( file instanceof obsidian . TFile ) ) return [ 3 /*break*/ , 2 ] ;
path = file . path ;
line = ( _a = this . getEndAndBeginningOfHeading ( file , parameters . heading ) ) === null || _a === void 0 ? void 0 : _a . lastLine ;
if ( line === undefined )
return [ 2 /*return*/ ] ;
return [ 4 /*yield*/ , this . app . vault . read ( file ) ] ;
case 1 :
data = _b . sent ( ) ;
lines = data . split ( "\n" ) ;
lines . splice . apply ( lines , _ _spreadArray ( [ line , 0 ] , parameters . data . split ( "\n" ) ) ) ;
dataToWrite = lines . join ( "\n" ) ;
_b . label = 2 ;
case 2 : return [ 3 /*break*/ , 7 ] ;
case 3 :
fileData = void 0 ;
if ( ! ( file instanceof obsidian . TFile ) ) return [ 3 /*break*/ , 5 ] ;
return [ 4 /*yield*/ , this . app . vault . read ( file ) ] ;
case 4 :
fileData = _b . sent ( ) ;
path = file . path ;
return [ 3 /*break*/ , 6 ] ;
case 5 :
path = file ;
fileData = "" ;
_b . label = 6 ;
case 6 :
dataToWrite = fileData + "\n" + parameters . data ;
_b . label = 7 ;
case 7 :
this . writeAndOpenFile ( path , dataToWrite , parameters ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . prepend = function ( file , parameters ) {
var _a ;
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var path , dataToWrite , line , data , lines , fileData , cache , line , first , last ;
return _ _generator ( this , function ( _b ) {
switch ( _b . label ) {
case 0 :
if ( ! parameters . heading ) return [ 3 /*break*/ , 3 ] ;
if ( ! ( file instanceof obsidian . TFile ) ) return [ 3 /*break*/ , 2 ] ;
path = file . path ;
line = ( _a = this . getEndAndBeginningOfHeading ( file , parameters . heading ) ) === null || _a === void 0 ? void 0 : _a . firstLine ;
if ( line === undefined )
return [ 2 /*return*/ ] ;
return [ 4 /*yield*/ , this . app . vault . read ( file ) ] ;
case 1 :
data = _b . sent ( ) ;
lines = data . split ( "\n" ) ;
lines . splice . apply ( lines , _ _spreadArray ( [ line , 0 ] , parameters . data . split ( "\n" ) ) ) ;
dataToWrite = lines . join ( "\n" ) ;
_b . label = 2 ;
case 2 : return [ 3 /*break*/ , 6 ] ;
case 3 :
if ( ! ( file instanceof obsidian . TFile ) ) return [ 3 /*break*/ , 5 ] ;
return [ 4 /*yield*/ , this . app . vault . read ( file ) ] ;
case 4 :
fileData = _b . sent ( ) ;
cache = this . app . metadataCache . getFileCache ( file ) ;
console . log ( cache ) ;
if ( cache . frontmatter ) {
line = cache . frontmatter . position . end . line ;
first = fileData . split ( "\n" ) . slice ( 0 , line + 1 ) . join ( "\n" ) ;
last = fileData . split ( "\n" ) . slice ( line + 1 ) . join ( "\n" ) ;
console . log ( first ) ;
console . log ( last ) ;
dataToWrite = first + "\n" + parameters . data + "\n" + last ;
}
else {
dataToWrite = parameters . data + "\n" + fileData ;
}
path = file . path ;
return [ 3 /*break*/ , 6 ] ;
case 5 :
path = file ;
dataToWrite = parameters . data ;
_b . label = 6 ;
case 6 :
this . writeAndOpenFile ( path , dataToWrite , parameters ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . writeAndOpenFile = function ( outputFileName , text , parameters ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var fileIsAlreadyOpened _1 ;
var _this = this ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 : return [ 4 /*yield*/ , this . app . vault . adapter . write ( outputFileName , text ) ] ;
case 1 :
_a . sent ( ) ;
if ( this . settings . openFileOnWrite ) {
fileIsAlreadyOpened _1 = false ;
this . app . workspace . iterateAllLeaves ( function ( leaf ) {
var _a ;
if ( ( ( _a = leaf . view . file ) === null || _a === void 0 ? void 0 : _a . path ) === outputFileName ) {
fileIsAlreadyOpened _1 = true ;
_this . app . workspace . setActiveLeaf ( leaf , true , true ) ;
}
} ) ;
if ( ! fileIsAlreadyOpened _1 )
this . app . workspace . openLinkText ( outputFileName , "" , this . settings . openFileOnWriteInNewPane , this . getViewStateFromMode ( parameters ) ) ;
}
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . getEndAndBeginningOfHeading = function ( file , heading ) {
var _a , _b ;
var cache = this . app . metadataCache . getFileCache ( file ) ;
var sections = cache . sections ;
var foundHeading = ( _a = cache . headings ) === null || _a === void 0 ? void 0 : _a . find ( function ( e ) { return e . heading === heading ; } ) ;
if ( foundHeading ) {
var foundSectionIndex = sections . findIndex ( function ( section ) { return section . type === "heading" && section . position . start . line === foundHeading . position . start . line ; } ) ;
var restSections = sections . slice ( foundSectionIndex + 1 ) ;
var nextHeadingIndex = restSections === null || restSections === void 0 ? void 0 : restSections . findIndex ( function ( e ) { return e . type === "heading" ; } ) ;
var lastSection = ( _b = restSections [ ( nextHeadingIndex !== - 1 ? nextHeadingIndex : restSections . length ) - 1 ] ) !== null && _b !== void 0 ? _b : sections [ foundSectionIndex ] ;
var lastLine = lastSection . position . end . line + 1 ;
return { "lastLine" : lastLine , "firstLine" : sections [ foundSectionIndex ] . position . end . line + 1 } ;
}
else {
new obsidian . Notice ( "Can't find heading" ) ;
}
} ;
AdvancedURI . prototype . setCursor = function ( mode ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var view , editor , viewState , lastLine , lastLineLength ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 :
view = this . app . workspace . getActiveViewOfType ( obsidian . MarkdownView ) ;
if ( ! view ) return [ 3 /*break*/ , 4 ] ;
editor = view . editor ;
viewState = view . leaf . getViewState ( ) ;
viewState . state . mode = "source" ;
if ( ! ( mode === "append" ) ) return [ 3 /*break*/ , 2 ] ;
lastLine = editor . lastLine ( ) ;
lastLineLength = editor . getLine ( lastLine ) . length ;
return [ 4 /*yield*/ , view . leaf . setViewState ( viewState , { focus : true } ) ] ;
case 1 :
_a . sent ( ) ;
editor . setCursor ( { ch : lastLineLength , line : lastLine } ) ;
return [ 3 /*break*/ , 4 ] ;
case 2 :
if ( ! ( mode === "prepend" ) ) return [ 3 /*break*/ , 4 ] ;
return [ 4 /*yield*/ , view . leaf . setViewState ( viewState , { focus : true } ) ] ;
case 3 :
_a . sent ( ) ;
editor . setCursor ( { ch : 0 , line : 0 } ) ;
_a . label = 4 ;
case 4 : return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . handleCopyFileURI = function ( ) {
var _this = this ;
var view = this . app . workspace . getActiveViewOfType ( obsidian . MarkdownView ) ;
if ( ! view )
return ;
var pos = view . editor . getCursor ( ) ;
var cache = this . app . metadataCache . getFileCache ( view . file ) ;
if ( cache . headings ) {
for ( var _i = 0 , _a = cache . headings ; _i < _a . length ; _i ++ ) {
var heading = _a [ _i ] ;
if ( heading . position . start . line <= pos . line && heading . position . end . line >= pos . line ) {
this . copyURI ( {
filepath : view . file . path ,
heading : heading . heading
} ) ;
return ;
}
}
}
if ( cache . blocks ) {
for ( var _b = 0 , _c = Object . keys ( cache . blocks ) ; _b < _c . length ; _b ++ ) {
var blockID = _c [ _b ] ;
var block = cache . blocks [ blockID ] ;
if ( block . position . start . line <= pos . line && block . position . end . line >= pos . line ) {
this . copyURI ( {
filepath : view . file . path ,
block : blockID
} ) ;
return ;
}
}
}
var fileModal = new FileModal ( this , "Choose a file" , false ) ;
fileModal . open ( ) ;
fileModal . onChooseItem = function ( item , _ ) {
new EnterDataModal ( _this , item . source ) . open ( ) ;
} ;
} ;
AdvancedURI . prototype . handleOpenSettings = function ( parameters ) {
if ( this . app . setting . containerEl . parentElement === null ) {
this . app . setting . open ( ) ;
}
if ( parameters . settingid == "plugin-browser" ) {
this . app . setting . openTabById ( "community-plugins" ) ;
this . app . setting . activeTab . containerEl . find ( ".mod-cta" ) . click ( ) ;
}
else if ( parameters . settingid == "theme-browser" ) {
this . app . setting . openTabById ( "appearance" ) ;
this . app . setting . activeTab . containerEl . find ( ".mod-cta" ) . click ( ) ;
}
else {
this . app . setting . openTabById ( parameters . settingid ) ;
}
this . success ( parameters ) ;
} ;
AdvancedURI . prototype . handleUpdatePlugins = function ( parameters ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 :
parameters . settingid = "community-plugins" ;
this . handleOpenSettings ( parameters ) ;
this . app . setting . activeTab . containerEl . findAll ( ".mod-cta" ) . last ( ) . click ( ) ;
new obsidian . Notice ( "Waiting 10 seconds" ) ;
return [ 4 /*yield*/ , new Promise ( function ( resolve ) { return setTimeout ( resolve , 10 * 1000 ) ; } ) ] ;
case 1 :
_a . sent ( ) ;
if ( Object . keys ( this . app . plugins . updates ) . length !== 0 ) {
this . app . setting . activeTab . containerEl . findAll ( ".mod-cta" ) . last ( ) . click ( ) ;
}
this . success ( parameters ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . copyURI = function ( parameters ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var uri , file , _a , parameter ;
return _ _generator ( this , function ( _b ) {
switch ( _b . label ) {
case 0 :
uri = "obsidian://advanced-uri?vault=" + this . app . vault . getName ( ) ;
file = this . app . vault . getAbstractFileByPath ( parameters . filepath ) ;
if ( ! ( this . settings . useUID && file instanceof obsidian . TFile ) ) return [ 3 /*break*/ , 2 ] ;
parameters . filepath = undefined ;
_a = parameters ;
return [ 4 /*yield*/ , this . getURIFromFile ( file ) ] ;
case 1 :
_a . uid = _b . sent ( ) ;
_b . label = 2 ;
case 2 :
for ( parameter in parameters ) {
if ( parameters [ parameter ] != undefined ) {
uri = uri + ( "&" + parameter + "=" + encodeURIComponent ( parameters [ parameter ] ) ) ;
}
}
return [ 4 /*yield*/ , this . copyText ( encodeURI ( uri ) ) ] ;
case 3 :
_b . sent ( ) ;
new obsidian . Notice ( "Advanced URI copied to your clipboard" ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . copyText = function ( text ) {
return navigator . clipboard . writeText ( text ) ;
} ;
AdvancedURI . prototype . getURIFromFile = function ( file ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var fileContent , frontmatter , uid , isYamlEmpty , splitContent , newFileContent ;
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 : return [ 4 /*yield*/ , this . app . vault . read ( file ) ] ;
case 1 :
fileContent = _a . sent ( ) ;
frontmatter = this . app . metadataCache . getFileCache ( file ) . frontmatter ;
uid = obsidian . parseFrontMatterEntry ( frontmatter , this . settings . idField ) ;
if ( uid )
return [ 2 /*return*/ , uid ] ;
isYamlEmpty = ( ( ! frontmatter || frontmatter . length === 0 ) && ! fileContent . match ( /^-{3}\s*\n*\r*-{3}/ ) ) ;
uid = v4 ( ) ;
splitContent = fileContent . split ( "\n" ) ;
if ( isYamlEmpty ) {
splitContent . unshift ( "---" ) ;
splitContent . unshift ( this . settings . idField + ": " + uid ) ;
splitContent . unshift ( "---" ) ;
}
else {
splitContent . splice ( 1 , 0 , this . settings . idField + ": " + uid ) ;
}
newFileContent = splitContent . join ( "\n" ) ;
return [ 4 /*yield*/ , this . app . vault . modify ( file , newFileContent ) ] ;
case 2 :
_a . sent ( ) ;
return [ 2 /*return*/ , uid ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . getViewStateFromMode = function ( parameters ) {
return parameters . viewmode ? { state : { mode : parameters . viewmode } } : undefined ;
} ;
AdvancedURI . prototype . loadSettings = function ( ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var _a , _b , _c , _d ;
return _ _generator ( this , function ( _e ) {
switch ( _e . label ) {
case 0 :
_a = this ;
_c = ( _b = Object ) . assign ;
_d = [ DEFAULT _SETTINGS ] ;
return [ 4 /*yield*/ , this . loadData ( ) ] ;
case 1 :
_a . settings = _c . apply ( _b , _d . concat ( [ _e . sent ( ) ] ) ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
AdvancedURI . prototype . saveSettings = function ( ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
return _ _generator ( this , function ( _a ) {
switch ( _a . label ) {
case 0 : return [ 4 /*yield*/ , this . saveData ( this . settings ) ] ;
case 1 :
_a . sent ( ) ;
return [ 2 /*return*/ ] ;
}
} ) ;
} ) ;
} ;
return AdvancedURI ;
} ( obsidian . Plugin ) ) ;
var SettingsTab = /** @class */ ( function ( _super ) {
_ _extends ( SettingsTab , _super ) ;
function SettingsTab ( app , plugin ) {
var _this = _super . call ( this , app , plugin ) || this ;
_this . plugin = plugin ;
return _this ;
}
SettingsTab . prototype . display = function ( ) {
var _this = this ;
var containerEl = this . containerEl ;
containerEl . empty ( ) ;
containerEl . createEl ( "h2" , { text : this . plugin . manifest . name } ) ;
new obsidian . Setting ( containerEl )
. setName ( "Open file on write" )
. addToggle ( function ( cb ) { return cb . onChange ( function ( value ) {
_this . plugin . settings . openFileOnWrite = value ;
_this . plugin . saveSettings ( ) ;
} ) . setValue ( _this . plugin . settings . openFileOnWrite ) ; } ) ;
new obsidian . Setting ( containerEl )
. setName ( "Open file on write in a new pane" )
. setDisabled ( this . plugin . settings . openFileOnWrite )
. addToggle ( function ( cb ) { return cb . onChange ( function ( value ) {
_this . plugin . settings . openFileOnWriteInNewPane = value ;
_this . plugin . saveSettings ( ) ;
} ) . setValue ( _this . plugin . settings . openFileOnWriteInNewPane ) ; } ) ;
new obsidian . Setting ( containerEl )
. setName ( "Open daily note in a new pane" )
. addToggle ( function ( cb ) { return cb . onChange ( function ( value ) {
_this . plugin . settings . openDailyInNewPane = value ;
_this . plugin . saveSettings ( ) ;
} ) . setValue ( _this . plugin . settings . openDailyInNewPane ) ; } ) ;
new obsidian . Setting ( containerEl )
. setName ( "Open file without write in new pane" )
. addToggle ( function ( cb ) { return cb . onChange ( function ( value ) {
_this . plugin . settings . openFileWithoutWriteInNewPane = value ;
_this . plugin . saveSettings ( ) ;
} ) . setValue ( _this . plugin . settings . openFileWithoutWriteInNewPane ) ; } ) ;
new obsidian . Setting ( containerEl )
. setName ( "Use UID instead of file paths" )
. addToggle ( function ( cb ) { return cb . onChange ( function ( value ) {
_this . plugin . settings . useUID = value ;
_this . plugin . saveSettings ( ) ;
} ) . setValue ( _this . plugin . settings . useUID ) ; } ) ;
new obsidian . Setting ( containerEl )
. setName ( "UID field in frontmatter" )
. addText ( function ( cb ) { return cb . onChange ( function ( value ) {
_this . plugin . settings . idField = value ;
_this . plugin . saveSettings ( ) ;
} ) . setValue ( _this . plugin . settings . idField ) ; } ) ;
} ;
return SettingsTab ;
} ( obsidian . PluginSettingTab ) ) ;
var EnterDataModal = /** @class */ ( function ( _super ) {
_ _extends ( EnterDataModal , _super ) ;
function EnterDataModal ( plugin , file ) {
var _this = _super . call ( this , plugin . app ) || this ;
//null if for normal write mode, its not associated with a special mode like "append" or "prepend"
_this . modes = [ null , "overwrite" , "append" , "prepend" ] ;
_this . plugin = plugin ;
_this . setPlaceholder ( "Type your data to be written to the file or leave it empty to just open it" ) ;
_this . file = file ;
return _this ;
}
EnterDataModal . prototype . getSuggestions = function ( query ) {
var _this = this ;
if ( query == "" )
query = null ;
var suggestions = [ ] ;
var _loop _1 = function ( mode ) {
if ( ! ( mode === "overwrite" && ! query ) ) {
var display = void 0 ;
if ( query ) {
if ( mode ) {
display = "Write \"" + query + "\" in " + mode + " mode" ;
}
else {
display = "Write \"" + query + "\"" ;
}
}
else {
if ( mode ) {
display = "Open in " + mode + " mode" ;
}
else {
display = "Open" ;
}
}
suggestions . push ( {
data : query ,
display : display ,
mode : mode ,
func : function ( ) {
if ( _this . file ) {
_this . plugin . copyURI ( {
filepath : _this . file ,
data : query ,
mode : mode
} ) ;
}
else {
_this . plugin . copyURI ( {
daily : "true" ,
data : query ,
mode : mode
} ) ;
}
}
} ) ;
}
} ;
for ( var _i = 0 , _a = this . modes ; _i < _a . length ; _i ++ ) {
var mode = _a [ _i ] ;
_loop _1 ( mode ) ;
}
return suggestions ;
} ;
EnterDataModal . prototype . renderSuggestion = function ( value , el ) {
el . innerText = value . display ;
} ;
EnterDataModal . prototype . onChooseSuggestion = function ( item , _ ) {
item . func ( ) ;
} ;
return EnterDataModal ;
} ( obsidian . SuggestModal ) ) ;
var FileModal = /** @class */ ( function ( _super ) {
_ _extends ( FileModal , _super ) ;
function FileModal ( plugin , placeHolder , allowNoFile ) {
if ( allowNoFile === void 0 ) { allowNoFile = true ; }
var _this = _super . call ( this , plugin . app ) || this ;
_this . placeHolder = placeHolder ;
_this . allowNoFile = allowNoFile ;
_this . plugin = plugin ;
_this . setPlaceholder ( _this . placeHolder ) ;
return _this ;
}
FileModal . prototype . getItems = function ( ) {
var specialItems = [ ] ;
if ( this . allowNoFile ) {
specialItems . push ( { display : "<Don't specify a file>" , source : undefined } ) ;
}
var file = this . app . workspace . getActiveFile ( ) ;
if ( file ) {
specialItems . push ( { display : "<Current file>" , source : file . path } ) ;
}
return _ _spreadArray ( _ _spreadArray ( [ ] , specialItems ) , this . app . vault . getFiles ( ) . map ( function ( e ) { return { display : e . path , source : e . path } ; } ) ) ;
} ;
FileModal . prototype . getItemText = function ( item ) {
return item . display ;
} ;
FileModal . prototype . onChooseItem = function ( item , evt ) {
} ;
return FileModal ;
} ( obsidian . FuzzySuggestModal ) ) ;
var CommandModal = /** @class */ ( function ( _super ) {
_ _extends ( CommandModal , _super ) ;
function CommandModal ( plugin , file ) {
var _this = _super . call ( this , plugin . app ) || this ;
_this . plugin = plugin ;
_this . file = file ;
return _this ;
}
CommandModal . prototype . getItems = function ( ) {
var rawCommands = this . app . commands . commands ;
var commands = Object . keys ( rawCommands ) . map ( function ( e ) {
return { id : rawCommands [ e ] . id , name : rawCommands [ e ] . name } ;
} ) ;
return commands ;
} ;
CommandModal . prototype . getItemText = function ( item ) {
return item . name ;
} ;
CommandModal . prototype . onChooseItem = function ( item , _ ) {
this . plugin . copyURI ( {
filepath : this . file ,
commandid : item . id
} ) ;
} ;
return CommandModal ;
} ( obsidian . FuzzySuggestModal ) ) ;
var SearchModal = /** @class */ ( function ( _super ) {
_ _extends ( SearchModal , _super ) ;
function SearchModal ( plugin ) {
var _this = _super . call ( this , plugin . app ) || this ;
_this . plugin = plugin ;
_this . setPlaceholder ( "Searched text. RegEx is supported" ) ;
return _this ;
}
SearchModal . prototype . getSuggestions = function ( query ) {
if ( query === "" ) {
query = "..." ;
}
var regex ;
try {
regex = new RegExp ( query ) ;
}
catch ( error ) { }
return [
{
source : query ,
isRegEx : false ,
display : query
} ,
{
source : query ,
display : regex ? "As RegEx: " + query : "Can't parse RegEx" ,
isRegEx : true
}
] ;
} ;
SearchModal . prototype . renderSuggestion = function ( value , el ) {
el . innerText = value . display ;
} ;
SearchModal . prototype . onChooseSuggestion = function ( item , _ ) {
} ;
return SearchModal ;
} ( obsidian . SuggestModal ) ) ;
var ReplaceModal = /** @class */ ( function ( _super ) {
_ _extends ( ReplaceModal , _super ) ;
function ReplaceModal ( plugin , search , filepath ) {
var _this = _super . call ( this , plugin . app ) || this ;
_this . search = search ;
_this . filepath = filepath ;
_this . emptyText = "Empty text (replace with nothing)" ;
_this . plugin = plugin ;
_this . setPlaceholder ( "Replacement text" ) ;
return _this ;
}
ReplaceModal . prototype . getSuggestions = function ( query ) {
if ( query === "" ) {
query = this . emptyText ;
}
return [ query ] ;
} ;
ReplaceModal . prototype . renderSuggestion = function ( value , el ) {
el . innerText = value ;
} ;
ReplaceModal . prototype . onChooseSuggestion = function ( item , _ ) {
if ( this . search . isRegEx ) {
this . plugin . copyURI ( {
filepath : this . filepath ,
searchregex : this . search . source ,
replace : item == this . emptyText ? "" : item
} ) ;
}
else {
this . plugin . copyURI ( {
filepath : this . filepath ,
search : this . search . source ,
replace : item == this . emptyText ? "" : item
} ) ;
}
} ;
return ReplaceModal ;
} ( obsidian . SuggestModal ) ) ;
module . exports = AdvancedURI ;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm5vZGVfbW9kdWxlcy9vYnNpZGlhbi1kYWlseS1ub3Rlcy1pbnRlcmZhY2UvZGlzdC9tYWluLmpzIiwibm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9lc20tYnJvd3Nlci9ybmcuanMiLCJub2RlX21vZHVsZXMvdXVpZC9kaXN0L2VzbS1icm93c2VyL3JlZ2V4LmpzIiwibm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9lc20tYnJvd3Nlci92YWxpZGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy91dWlkL2Rpc3QvZXNtLWJyb3dzZXIvc3RyaW5naWZ5LmpzIiwibm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9lc20tYnJvd3Nlci92NC5qcyIsInNyYy9kYWlseV9ub3RlX3V0aWxzLnRzIiwic3JjL21haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQ