'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 ( ) ) ;
} ) ;
}
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : { } ;
var luxon = { } ;
Object . defineProperty ( luxon , '__esModule' , { value : true } ) ;
function _defineProperties ( target , props ) {
for ( var i = 0 ; i < props . length ; i ++ ) {
var descriptor = props [ i ] ;
descriptor . enumerable = descriptor . enumerable || false ;
descriptor . configurable = true ;
if ( "value" in descriptor ) descriptor . writable = true ;
Object . defineProperty ( target , descriptor . key , descriptor ) ;
}
}
function _createClass ( Constructor , protoProps , staticProps ) {
if ( protoProps ) _defineProperties ( Constructor . prototype , protoProps ) ;
if ( staticProps ) _defineProperties ( Constructor , staticProps ) ;
return Constructor ;
}
function _extends ( ) {
_extends = Object . assign || function ( target ) {
for ( var i = 1 ; i < arguments . length ; i ++ ) {
var source = arguments [ i ] ;
for ( var key in source ) {
if ( Object . prototype . hasOwnProperty . call ( source , key ) ) {
target [ key ] = source [ key ] ;
}
}
}
return target ;
} ;
return _extends . apply ( this , arguments ) ;
}
function _inheritsLoose ( subClass , superClass ) {
subClass . prototype = Object . create ( superClass . prototype ) ;
subClass . prototype . constructor = subClass ;
_setPrototypeOf ( subClass , superClass ) ;
}
function _getPrototypeOf ( o ) {
_getPrototypeOf = Object . setPrototypeOf ? Object . getPrototypeOf : function _getPrototypeOf ( o ) {
return o . _ _proto _ _ || Object . getPrototypeOf ( o ) ;
} ;
return _getPrototypeOf ( o ) ;
}
function _setPrototypeOf ( o , p ) {
_setPrototypeOf = Object . setPrototypeOf || function _setPrototypeOf ( o , p ) {
o . _ _proto _ _ = p ;
return o ;
} ;
return _setPrototypeOf ( o , p ) ;
}
function _isNativeReflectConstruct ( ) {
if ( typeof Reflect === "undefined" || ! Reflect . construct ) return false ;
if ( Reflect . construct . sham ) return false ;
if ( typeof Proxy === "function" ) return true ;
try {
Boolean . prototype . valueOf . call ( Reflect . construct ( Boolean , [ ] , function ( ) { } ) ) ;
return true ;
} catch ( e ) {
return false ;
}
}
function _construct ( Parent , args , Class ) {
if ( _isNativeReflectConstruct ( ) ) {
_construct = Reflect . construct ;
} else {
_construct = function _construct ( Parent , args , Class ) {
var a = [ null ] ;
a . push . apply ( a , args ) ;
var Constructor = Function . bind . apply ( Parent , a ) ;
var instance = new Constructor ( ) ;
if ( Class ) _setPrototypeOf ( instance , Class . prototype ) ;
return instance ;
} ;
}
return _construct . apply ( null , arguments ) ;
}
function _isNativeFunction ( fn ) {
return Function . toString . call ( fn ) . indexOf ( "[native code]" ) !== - 1 ;
}
function _wrapNativeSuper ( Class ) {
var _cache = typeof Map === "function" ? new Map ( ) : undefined ;
_wrapNativeSuper = function _wrapNativeSuper ( Class ) {
if ( Class === null || ! _isNativeFunction ( Class ) ) return Class ;
if ( typeof Class !== "function" ) {
throw new TypeError ( "Super expression must either be null or a function" ) ;
}
if ( typeof _cache !== "undefined" ) {
if ( _cache . has ( Class ) ) return _cache . get ( Class ) ;
_cache . set ( Class , Wrapper ) ;
}
function Wrapper ( ) {
return _construct ( Class , arguments , _getPrototypeOf ( this ) . constructor ) ;
}
Wrapper . prototype = Object . create ( Class . prototype , {
constructor : {
value : Wrapper ,
enumerable : false ,
writable : true ,
configurable : true
}
} ) ;
return _setPrototypeOf ( Wrapper , Class ) ;
} ;
return _wrapNativeSuper ( Class ) ;
}
function _objectWithoutPropertiesLoose ( source , excluded ) {
if ( source == null ) return { } ;
var target = { } ;
var sourceKeys = Object . keys ( source ) ;
var key , i ;
for ( i = 0 ; i < sourceKeys . length ; i ++ ) {
key = sourceKeys [ i ] ;
if ( excluded . indexOf ( key ) >= 0 ) continue ;
target [ key ] = source [ key ] ;
}
return target ;
}
function _unsupportedIterableToArray ( o , minLen ) {
if ( ! o ) return ;
if ( typeof o === "string" ) return _arrayLikeToArray ( o , minLen ) ;
var n = Object . prototype . toString . call ( o ) . slice ( 8 , - 1 ) ;
if ( n === "Object" && o . constructor ) n = o . constructor . name ;
if ( n === "Map" || n === "Set" ) return Array . from ( o ) ;
if ( n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/ . test ( n ) ) return _arrayLikeToArray ( o , minLen ) ;
}
function _arrayLikeToArray ( arr , len ) {
if ( len == null || len > arr . length ) len = arr . length ;
for ( var i = 0 , arr2 = new Array ( len ) ; i < len ; i ++ ) arr2 [ i ] = arr [ i ] ;
return arr2 ;
}
function _createForOfIteratorHelperLoose ( o , allowArrayLike ) {
var it = typeof Symbol !== "undefined" && o [ Symbol . iterator ] || o [ "@@iterator" ] ;
if ( it ) return ( it = it . call ( o ) ) . next . bind ( it ) ;
if ( Array . isArray ( o ) || ( it = _unsupportedIterableToArray ( o ) ) || allowArrayLike && o && typeof o . length === "number" ) {
if ( it ) o = it ;
var i = 0 ;
return function ( ) {
if ( i >= o . length ) return {
done : true
} ;
return {
done : false ,
value : o [ i ++ ]
} ;
} ;
}
throw new TypeError ( "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method." ) ;
}
// these aren't really private, but nor are they really useful to document
/ * *
* @ private
* /
var LuxonError = /*#__PURE__*/ function ( _Error ) {
_inheritsLoose ( LuxonError , _Error ) ;
function LuxonError ( ) {
return _Error . apply ( this , arguments ) || this ;
}
return LuxonError ;
} ( /*#__PURE__*/ _wrapNativeSuper ( Error ) ) ;
/ * *
* @ private
* /
var InvalidDateTimeError = /*#__PURE__*/ function ( _LuxonError ) {
_inheritsLoose ( InvalidDateTimeError , _LuxonError ) ;
function InvalidDateTimeError ( reason ) {
return _LuxonError . call ( this , "Invalid DateTime: " + reason . toMessage ( ) ) || this ;
}
return InvalidDateTimeError ;
} ( LuxonError ) ;
/ * *
* @ private
* /
var InvalidIntervalError = /*#__PURE__*/ function ( _LuxonError2 ) {
_inheritsLoose ( InvalidIntervalError , _LuxonError2 ) ;
function InvalidIntervalError ( reason ) {
return _LuxonError2 . call ( this , "Invalid Interval: " + reason . toMessage ( ) ) || this ;
}
return InvalidIntervalError ;
} ( LuxonError ) ;
/ * *
* @ private
* /
var InvalidDurationError = /*#__PURE__*/ function ( _LuxonError3 ) {
_inheritsLoose ( InvalidDurationError , _LuxonError3 ) ;
function InvalidDurationError ( reason ) {
return _LuxonError3 . call ( this , "Invalid Duration: " + reason . toMessage ( ) ) || this ;
}
return InvalidDurationError ;
} ( LuxonError ) ;
/ * *
* @ private
* /
var ConflictingSpecificationError = /*#__PURE__*/ function ( _LuxonError4 ) {
_inheritsLoose ( ConflictingSpecificationError , _LuxonError4 ) ;
function ConflictingSpecificationError ( ) {
return _LuxonError4 . apply ( this , arguments ) || this ;
}
return ConflictingSpecificationError ;
} ( LuxonError ) ;
/ * *
* @ private
* /
var InvalidUnitError = /*#__PURE__*/ function ( _LuxonError5 ) {
_inheritsLoose ( InvalidUnitError , _LuxonError5 ) ;
function InvalidUnitError ( unit ) {
return _LuxonError5 . call ( this , "Invalid unit " + unit ) || this ;
}
return InvalidUnitError ;
} ( LuxonError ) ;
/ * *
* @ private
* /
var InvalidArgumentError = /*#__PURE__*/ function ( _LuxonError6 ) {
_inheritsLoose ( InvalidArgumentError , _LuxonError6 ) ;
function InvalidArgumentError ( ) {
return _LuxonError6 . apply ( this , arguments ) || this ;
}
return InvalidArgumentError ;
} ( LuxonError ) ;
/ * *
* @ private
* /
var ZoneIsAbstractError = /*#__PURE__*/ function ( _LuxonError7 ) {
_inheritsLoose ( ZoneIsAbstractError , _LuxonError7 ) ;
function ZoneIsAbstractError ( ) {
return _LuxonError7 . call ( this , "Zone is an abstract class" ) || this ;
}
return ZoneIsAbstractError ;
} ( LuxonError ) ;
/ * *
* @ private
* /
var n = "numeric" ,
s = "short" ,
l = "long" ;
var DATE _SHORT = {
year : n ,
month : n ,
day : n
} ;
var DATE _MED = {
year : n ,
month : s ,
day : n
} ;
var DATE _MED _WITH _WEEKDAY = {
year : n ,
month : s ,
day : n ,
weekday : s
} ;
var DATE _FULL = {
year : n ,
month : l ,
day : n
} ;
var DATE _HUGE = {
year : n ,
month : l ,
day : n ,
weekday : l
} ;
var TIME _SIMPLE = {
hour : n ,
minute : n
} ;
var TIME _WITH _SECONDS = {
hour : n ,
minute : n ,
second : n
} ;
var TIME _WITH _SHORT _OFFSET = {
hour : n ,
minute : n ,
second : n ,
timeZoneName : s
} ;
var TIME _WITH _LONG _OFFSET = {
hour : n ,
minute : n ,
second : n ,
timeZoneName : l
} ;
var TIME _24 _SIMPLE = {
hour : n ,
minute : n ,
hourCycle : "h23"
} ;
var TIME _24 _WITH _SECONDS = {
hour : n ,
minute : n ,
second : n ,
hourCycle : "h23"
} ;
var TIME _24 _WITH _SHORT _OFFSET = {
hour : n ,
minute : n ,
second : n ,
hourCycle : "h23" ,
timeZoneName : s
} ;
var TIME _24 _WITH _LONG _OFFSET = {
hour : n ,
minute : n ,
second : n ,
hourCycle : "h23" ,
timeZoneName : l
} ;
var DATETIME _SHORT = {
year : n ,
month : n ,
day : n ,
hour : n ,
minute : n
} ;
var DATETIME _SHORT _WITH _SECONDS = {
year : n ,
month : n ,
day : n ,
hour : n ,
minute : n ,
second : n
} ;
var DATETIME _MED = {
year : n ,
month : s ,
day : n ,
hour : n ,
minute : n
} ;
var DATETIME _MED _WITH _SECONDS = {
year : n ,
month : s ,
day : n ,
hour : n ,
minute : n ,
second : n
} ;
var DATETIME _MED _WITH _WEEKDAY = {
year : n ,
month : s ,
day : n ,
weekday : s ,
hour : n ,
minute : n
} ;
var DATETIME _FULL = {
year : n ,
month : l ,
day : n ,
hour : n ,
minute : n ,
timeZoneName : s
} ;
var DATETIME _FULL _WITH _SECONDS = {
year : n ,
month : l ,
day : n ,
hour : n ,
minute : n ,
second : n ,
timeZoneName : s
} ;
var DATETIME _HUGE = {
year : n ,
month : l ,
day : n ,
weekday : l ,
hour : n ,
minute : n ,
timeZoneName : l
} ;
var DATETIME _HUGE _WITH _SECONDS = {
year : n ,
month : l ,
day : n ,
weekday : l ,
hour : n ,
minute : n ,
second : n ,
timeZoneName : l
} ;
/ * *
* @ private
* /
// TYPES
function isUndefined ( o ) {
return typeof o === "undefined" ;
}
function isNumber ( o ) {
return typeof o === "number" ;
}
function isInteger ( o ) {
return typeof o === "number" && o % 1 === 0 ;
}
function isString ( o ) {
return typeof o === "string" ;
}
function isDate ( o ) {
return Object . prototype . toString . call ( o ) === "[object Date]" ;
} // CAPABILITIES
function hasRelative ( ) {
try {
return typeof Intl !== "undefined" && ! ! Intl . RelativeTimeFormat ;
} catch ( e ) {
return false ;
}
} // OBJECTS AND ARRAYS
function maybeArray ( thing ) {
return Array . isArray ( thing ) ? thing : [ thing ] ;
}
function bestBy ( arr , by , compare ) {
if ( arr . length === 0 ) {
return undefined ;
}
return arr . reduce ( function ( best , next ) {
var pair = [ by ( next ) , next ] ;
if ( ! best ) {
return pair ;
} else if ( compare ( best [ 0 ] , pair [ 0 ] ) === best [ 0 ] ) {
return best ;
} else {
return pair ;
}
} , null ) [ 1 ] ;
}
function pick ( obj , keys ) {
return keys . reduce ( function ( a , k ) {
a [ k ] = obj [ k ] ;
return a ;
} , { } ) ;
}
function hasOwnProperty ( obj , prop ) {
return Object . prototype . hasOwnProperty . call ( obj , prop ) ;
} // NUMBERS AND STRINGS
function integerBetween ( thing , bottom , top ) {
return isInteger ( thing ) && thing >= bottom && thing <= top ;
} // x % n but takes the sign of n instead of x
function floorMod ( x , n ) {
return x - n * Math . floor ( x / n ) ;
}
function padStart ( input , n ) {
if ( n === void 0 ) {
n = 2 ;
}
var minus = input < 0 ? "-" : "" ;
var target = minus ? input * - 1 : input ;
var result ;
if ( target . toString ( ) . length < n ) {
result = ( "0" . repeat ( n ) + target ) . slice ( - n ) ;
} else {
result = target . toString ( ) ;
}
return "" + minus + result ;
}
function parseInteger ( string ) {
if ( isUndefined ( string ) || string === null || string === "" ) {
return undefined ;
} else {
return parseInt ( string , 10 ) ;
}
}
function parseMillis ( fraction ) {
// Return undefined (instead of 0) in these cases, where fraction is not set
if ( isUndefined ( fraction ) || fraction === null || fraction === "" ) {
return undefined ;
} else {
var f = parseFloat ( "0." + fraction ) * 1000 ;
return Math . floor ( f ) ;
}
}
function roundTo ( number , digits , towardZero ) {
if ( towardZero === void 0 ) {
towardZero = false ;
}
var factor = Math . pow ( 10 , digits ) ,
rounder = towardZero ? Math . trunc : Math . round ;
return rounder ( number * factor ) / factor ;
} // DATE BASICS
function isLeapYear ( year ) {
return year % 4 === 0 && ( year % 100 !== 0 || year % 400 === 0 ) ;
}
function daysInYear ( year ) {
return isLeapYear ( year ) ? 366 : 365 ;
}
function daysInMonth ( year , month ) {
var modMonth = floorMod ( month - 1 , 12 ) + 1 ,
modYear = year + ( month - modMonth ) / 12 ;
if ( modMonth === 2 ) {
return isLeapYear ( modYear ) ? 29 : 28 ;
} else {
return [ 31 , null , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] [ modMonth - 1 ] ;
}
} // covert a calendar object to a local timestamp (epoch, but with the offset baked in)
function objToLocalTS ( obj ) {
var d = Date . UTC ( obj . year , obj . month - 1 , obj . day , obj . hour , obj . minute , obj . second , obj . millisecond ) ; // for legacy reasons, years between 0 and 99 are interpreted as 19XX; revert that
if ( obj . year < 100 && obj . year >= 0 ) {
d = new Date ( d ) ;
d . setUTCFullYear ( d . getUTCFullYear ( ) - 1900 ) ;
}
return + d ;
}
function weeksInWeekYear ( weekYear ) {
var p1 = ( weekYear + Math . floor ( weekYear / 4 ) - Math . floor ( weekYear / 100 ) + Math . floor ( weekYear / 400 ) ) % 7 ,
last = weekYear - 1 ,
p2 = ( last + Math . floor ( last / 4 ) - Math . floor ( last / 100 ) + Math . floor ( last / 400 ) ) % 7 ;
return p1 === 4 || p2 === 3 ? 53 : 52 ;
}
function untruncateYear ( year ) {
if ( year > 99 ) {
return year ;
} else return year > 60 ? 1900 + year : 2000 + year ;
} // PARSING
function parseZoneInfo ( ts , offsetFormat , locale , timeZone ) {
if ( timeZone === void 0 ) {
timeZone = null ;
}
var date = new Date ( ts ) ,
intlOpts = {
hourCycle : "h23" ,
year : "numeric" ,
month : "2-digit" ,
day : "2-digit" ,
hour : "2-digit" ,
minute : "2-digit"
} ;
if ( timeZone ) {
intlOpts . timeZone = timeZone ;
}
var modified = _extends ( {
timeZoneName : offsetFormat
} , intlOpts ) ;
var parsed = new Intl . DateTimeFormat ( locale , modified ) . formatToParts ( date ) . find ( function ( m ) {
return m . type . toLowerCase ( ) === "timezonename" ;
} ) ;
return parsed ? parsed . value : null ;
} // signedOffset('-5', '30') -> -330
function signedOffset ( offHourStr , offMinuteStr ) {
var offHour = parseInt ( offHourStr , 10 ) ; // don't || this because we want to preserve -0
if ( Number . isNaN ( offHour ) ) {
offHour = 0 ;
}
var offMin = parseInt ( offMinuteStr , 10 ) || 0 ,
offMinSigned = offHour < 0 || Object . is ( offHour , - 0 ) ? - offMin : offMin ;
return offHour * 60 + offMinSigned ;
} // COERCION
function asNumber ( value ) {
var numericValue = Number ( value ) ;
if ( typeof value === "boolean" || value === "" || Number . isNaN ( numericValue ) ) throw new InvalidArgumentError ( "Invalid unit value " + value ) ;
return numericValue ;
}
function normalizeObject ( obj , normalizer ) {
var normalized = { } ;
for ( var u in obj ) {
if ( hasOwnProperty ( obj , u ) ) {
var v = obj [ u ] ;
if ( v === undefined || v === null ) continue ;
normalized [ normalizer ( u ) ] = asNumber ( v ) ;
}
}
return normalized ;
}
function formatOffset ( offset , format ) {
var hours = Math . trunc ( Math . abs ( offset / 60 ) ) ,
minutes = Math . trunc ( Math . abs ( offset % 60 ) ) ,
sign = offset >= 0 ? "+" : "-" ;
switch ( format ) {
case "short" :
return "" + sign + padStart ( hours , 2 ) + ":" + padStart ( minutes , 2 ) ;
case "narrow" :
return "" + sign + hours + ( minutes > 0 ? ":" + minutes : "" ) ;
case "techie" :
return "" + sign + padStart ( hours , 2 ) + padStart ( minutes , 2 ) ;
default :
throw new RangeError ( "Value format " + format + " is out of range for property format" ) ;
}
}
function timeObject ( obj ) {
return pick ( obj , [ "hour" , "minute" , "second" , "millisecond" ] ) ;
}
var ianaRegex = /[A-Za-z_+-]{1,256}(:?\/[A-Za-z_+-]{1,256}(\/[A-Za-z_+-]{1,256})?)?/ ;
/ * *
* @ private
* /
var monthsLong = [ "January" , "February" , "March" , "April" , "May" , "June" , "July" , "August" , "September" , "October" , "November" , "December" ] ;
var monthsShort = [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" ] ;
var monthsNarrow = [ "J" , "F" , "M" , "A" , "M" , "J" , "J" , "A" , "S" , "O" , "N" , "D" ] ;
function months ( length ) {
switch ( length ) {
case "narrow" :
return [ ] . concat ( monthsNarrow ) ;
case "short" :
return [ ] . concat ( monthsShort ) ;
case "long" :
return [ ] . concat ( monthsLong ) ;
case "numeric" :
return [ "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "11" , "12" ] ;
case "2-digit" :
return [ "01" , "02" , "03" , "04" , "05" , "06" , "07" , "08" , "09" , "10" , "11" , "12" ] ;
default :
return null ;
}
}
var weekdaysLong = [ "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" , "Sunday" ] ;
var weekdaysShort = [ "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" , "Sun" ] ;
var weekdaysNarrow = [ "M" , "T" , "W" , "T" , "F" , "S" , "S" ] ;
function weekdays ( length ) {
switch ( length ) {
case "narrow" :
return [ ] . concat ( weekdaysNarrow ) ;
case "short" :
return [ ] . concat ( weekdaysShort ) ;
case "long" :
return [ ] . concat ( weekdaysLong ) ;
case "numeric" :
return [ "1" , "2" , "3" , "4" , "5" , "6" , "7" ] ;
default :
return null ;
}
}
var meridiems = [ "AM" , "PM" ] ;
var erasLong = [ "Before Christ" , "Anno Domini" ] ;
var erasShort = [ "BC" , "AD" ] ;
var erasNarrow = [ "B" , "A" ] ;
function eras ( length ) {
switch ( length ) {
case "narrow" :
return [ ] . concat ( erasNarrow ) ;
case "short" :
return [ ] . concat ( erasShort ) ;
case "long" :
return [ ] . concat ( erasLong ) ;
default :
return null ;
}
}
function meridiemForDateTime ( dt ) {
return meridiems [ dt . hour < 12 ? 0 : 1 ] ;
}
function weekdayForDateTime ( dt , length ) {
return weekdays ( length ) [ dt . weekday - 1 ] ;
}
function monthForDateTime ( dt , length ) {
return months ( length ) [ dt . month - 1 ] ;
}
function eraForDateTime ( dt , length ) {
return eras ( length ) [ dt . year < 0 ? 0 : 1 ] ;
}
function formatRelativeTime ( unit , count , numeric , narrow ) {
if ( numeric === void 0 ) {
numeric = "always" ;
}
if ( narrow === void 0 ) {
narrow = false ;
}
var units = {
years : [ "year" , "yr." ] ,
quarters : [ "quarter" , "qtr." ] ,
months : [ "month" , "mo." ] ,
weeks : [ "week" , "wk." ] ,
days : [ "day" , "day" , "days" ] ,
hours : [ "hour" , "hr." ] ,
minutes : [ "minute" , "min." ] ,
seconds : [ "second" , "sec." ]
} ;
var lastable = [ "hours" , "minutes" , "seconds" ] . indexOf ( unit ) === - 1 ;
if ( numeric === "auto" && lastable ) {
var isDay = unit === "days" ;
switch ( count ) {
case 1 :
return isDay ? "tomorrow" : "next " + units [ unit ] [ 0 ] ;
case - 1 :
return isDay ? "yesterday" : "last " + units [ unit ] [ 0 ] ;
case 0 :
return isDay ? "today" : "this " + units [ unit ] [ 0 ] ;
}
}
var isInPast = Object . is ( count , - 0 ) || count < 0 ,
fmtValue = Math . abs ( count ) ,
singular = fmtValue === 1 ,
lilUnits = units [ unit ] ,
fmtUnit = narrow ? singular ? lilUnits [ 1 ] : lilUnits [ 2 ] || lilUnits [ 1 ] : singular ? units [ unit ] [ 0 ] : unit ;
return isInPast ? fmtValue + " " + fmtUnit + " ago" : "in " + fmtValue + " " + fmtUnit ;
}
function stringifyTokens ( splits , tokenToString ) {
var s = "" ;
for ( var _iterator = _createForOfIteratorHelperLoose ( splits ) , _step ; ! ( _step = _iterator ( ) ) . done ; ) {
var token = _step . value ;
if ( token . literal ) {
s += token . val ;
} else {
s += tokenToString ( token . val ) ;
}
}
return s ;
}
var _macroTokenToFormatOpts = {
D : DATE _SHORT ,
DD : DATE _MED ,
DDD : DATE _FULL ,
DDDD : DATE _HUGE ,
t : TIME _SIMPLE ,
tt : TIME _WITH _SECONDS ,
ttt : TIME _WITH _SHORT _OFFSET ,
tttt : TIME _WITH _LONG _OFFSET ,
T : TIME _24 _SIMPLE ,
TT : TIME _24 _WITH _SECONDS ,
TTT : TIME _24 _WITH _SHORT _OFFSET ,
TTTT : TIME _24 _WITH _LONG _OFFSET ,
f : DATETIME _SHORT ,
ff : DATETIME _MED ,
fff : DATETIME _FULL ,
ffff : DATETIME _HUGE ,
F : DATETIME _SHORT _WITH _SECONDS ,
FF : DATETIME _MED _WITH _SECONDS ,
FFF : DATETIME _FULL _WITH _SECONDS ,
FFFF : DATETIME _HUGE _WITH _SECONDS
} ;
/ * *
* @ private
* /
var Formatter = /*#__PURE__*/ function ( ) {
Formatter . create = function create ( locale , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
return new Formatter ( locale , opts ) ;
} ;
Formatter . parseFormat = function parseFormat ( fmt ) {
var current = null ,
currentFull = "" ,
bracketed = false ;
var splits = [ ] ;
for ( var i = 0 ; i < fmt . length ; i ++ ) {
var c = fmt . charAt ( i ) ;
if ( c === "'" ) {
if ( currentFull . length > 0 ) {
splits . push ( {
literal : bracketed ,
val : currentFull
} ) ;
}
current = null ;
currentFull = "" ;
bracketed = ! bracketed ;
} else if ( bracketed ) {
currentFull += c ;
} else if ( c === current ) {
currentFull += c ;
} else {
if ( currentFull . length > 0 ) {
splits . push ( {
literal : false ,
val : currentFull
} ) ;
}
currentFull = c ;
current = c ;
}
}
if ( currentFull . length > 0 ) {
splits . push ( {
literal : bracketed ,
val : currentFull
} ) ;
}
return splits ;
} ;
Formatter . macroTokenToFormatOpts = function macroTokenToFormatOpts ( token ) {
return _macroTokenToFormatOpts [ token ] ;
} ;
function Formatter ( locale , formatOpts ) {
this . opts = formatOpts ;
this . loc = locale ;
this . systemLoc = null ;
}
var _proto = Formatter . prototype ;
_proto . formatWithSystemDefault = function formatWithSystemDefault ( dt , opts ) {
if ( this . systemLoc === null ) {
this . systemLoc = this . loc . redefaultToSystem ( ) ;
}
var df = this . systemLoc . dtFormatter ( dt , _extends ( { } , this . opts , opts ) ) ;
return df . format ( ) ;
} ;
_proto . formatDateTime = function formatDateTime ( dt , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var df = this . loc . dtFormatter ( dt , _extends ( { } , this . opts , opts ) ) ;
return df . format ( ) ;
} ;
_proto . formatDateTimeParts = function formatDateTimeParts ( dt , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var df = this . loc . dtFormatter ( dt , _extends ( { } , this . opts , opts ) ) ;
return df . formatToParts ( ) ;
} ;
_proto . resolvedOptions = function resolvedOptions ( dt , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var df = this . loc . dtFormatter ( dt , _extends ( { } , this . opts , opts ) ) ;
return df . resolvedOptions ( ) ;
} ;
_proto . num = function num ( n , p ) {
if ( p === void 0 ) {
p = 0 ;
}
// we get some perf out of doing this here, annoyingly
if ( this . opts . forceSimple ) {
return padStart ( n , p ) ;
}
var opts = _extends ( { } , this . opts ) ;
if ( p > 0 ) {
opts . padTo = p ;
}
return this . loc . numberFormatter ( opts ) . format ( n ) ;
} ;
_proto . formatDateTimeFromString = function formatDateTimeFromString ( dt , fmt ) {
var _this = this ;
var knownEnglish = this . loc . listingMode ( ) === "en" ,
useDateTimeFormatter = this . loc . outputCalendar && this . loc . outputCalendar !== "gregory" ,
string = function string ( opts , extract ) {
return _this . loc . extract ( dt , opts , extract ) ;
} ,
formatOffset = function formatOffset ( opts ) {
if ( dt . isOffsetFixed && dt . offset === 0 && opts . allowZ ) {
return "Z" ;
}
return dt . isValid ? dt . zone . formatOffset ( dt . ts , opts . format ) : "" ;
} ,
meridiem = function meridiem ( ) {
return knownEnglish ? meridiemForDateTime ( dt ) : string ( {
hour : "numeric" ,
hourCycle : "h12"
} , "dayperiod" ) ;
} ,
month = function month ( length , standalone ) {
return knownEnglish ? monthForDateTime ( dt , length ) : string ( standalone ? {
month : length
} : {
month : length ,
day : "numeric"
} , "month" ) ;
} ,
weekday = function weekday ( length , standalone ) {
return knownEnglish ? weekdayForDateTime ( dt , length ) : string ( standalone ? {
weekday : length
} : {
weekday : length ,
month : "long" ,
day : "numeric"
} , "weekday" ) ;
} ,
maybeMacro = function maybeMacro ( token ) {
var formatOpts = Formatter . macroTokenToFormatOpts ( token ) ;
if ( formatOpts ) {
return _this . formatWithSystemDefault ( dt , formatOpts ) ;
} else {
return token ;
}
} ,
era = function era ( length ) {
return knownEnglish ? eraForDateTime ( dt , length ) : string ( {
era : length
} , "era" ) ;
} ,
tokenToString = function tokenToString ( token ) {
// Where possible: http://cldr.unicode.org/translation/date-time-1/date-time#TOC-Standalone-vs.-Format-Styles
switch ( token ) {
// ms
case "S" :
return _this . num ( dt . millisecond ) ;
case "u" : // falls through
case "SSS" :
return _this . num ( dt . millisecond , 3 ) ;
// seconds
case "s" :
return _this . num ( dt . second ) ;
case "ss" :
return _this . num ( dt . second , 2 ) ;
// minutes
case "m" :
return _this . num ( dt . minute ) ;
case "mm" :
return _this . num ( dt . minute , 2 ) ;
// hours
case "h" :
return _this . num ( dt . hour % 12 === 0 ? 12 : dt . hour % 12 ) ;
case "hh" :
return _this . num ( dt . hour % 12 === 0 ? 12 : dt . hour % 12 , 2 ) ;
case "H" :
return _this . num ( dt . hour ) ;
case "HH" :
return _this . num ( dt . hour , 2 ) ;
// offset
case "Z" :
// like +6
return formatOffset ( {
format : "narrow" ,
allowZ : _this . opts . allowZ
} ) ;
case "ZZ" :
// like +06:00
return formatOffset ( {
format : "short" ,
allowZ : _this . opts . allowZ
} ) ;
case "ZZZ" :
// like +0600
return formatOffset ( {
format : "techie" ,
allowZ : _this . opts . allowZ
} ) ;
case "ZZZZ" :
// like EST
return dt . zone . offsetName ( dt . ts , {
format : "short" ,
locale : _this . loc . locale
} ) ;
case "ZZZZZ" :
// like Eastern Standard Time
return dt . zone . offsetName ( dt . ts , {
format : "long" ,
locale : _this . loc . locale
} ) ;
// zone
case "z" :
// like America/New_York
return dt . zoneName ;
// meridiems
case "a" :
return meridiem ( ) ;
// dates
case "d" :
return useDateTimeFormatter ? string ( {
day : "numeric"
} , "day" ) : _this . num ( dt . day ) ;
case "dd" :
return useDateTimeFormatter ? string ( {
day : "2-digit"
} , "day" ) : _this . num ( dt . day , 2 ) ;
// weekdays - standalone
case "c" :
// like 1
return _this . num ( dt . weekday ) ;
case "ccc" :
// like 'Tues'
return weekday ( "short" , true ) ;
case "cccc" :
// like 'Tuesday'
return weekday ( "long" , true ) ;
case "ccccc" :
// like 'T'
return weekday ( "narrow" , true ) ;
// weekdays - format
case "E" :
// like 1
return _this . num ( dt . weekday ) ;
case "EEE" :
// like 'Tues'
return weekday ( "short" , false ) ;
case "EEEE" :
// like 'Tuesday'
return weekday ( "long" , false ) ;
case "EEEEE" :
// like 'T'
return weekday ( "narrow" , false ) ;
// months - standalone
case "L" :
// like 1
return useDateTimeFormatter ? string ( {
month : "numeric" ,
day : "numeric"
} , "month" ) : _this . num ( dt . month ) ;
case "LL" :
// like 01, doesn't seem to work
return useDateTimeFormatter ? string ( {
month : "2-digit" ,
day : "numeric"
} , "month" ) : _this . num ( dt . month , 2 ) ;
case "LLL" :
// like Jan
return month ( "short" , true ) ;
case "LLLL" :
// like January
return month ( "long" , true ) ;
case "LLLLL" :
// like J
return month ( "narrow" , true ) ;
// months - format
case "M" :
// like 1
return useDateTimeFormatter ? string ( {
month : "numeric"
} , "month" ) : _this . num ( dt . month ) ;
case "MM" :
// like 01
return useDateTimeFormatter ? string ( {
month : "2-digit"
} , "month" ) : _this . num ( dt . month , 2 ) ;
case "MMM" :
// like Jan
return month ( "short" , false ) ;
case "MMMM" :
// like January
return month ( "long" , false ) ;
case "MMMMM" :
// like J
return month ( "narrow" , false ) ;
// years
case "y" :
// like 2014
return useDateTimeFormatter ? string ( {
year : "numeric"
} , "year" ) : _this . num ( dt . year ) ;
case "yy" :
// like 14
return useDateTimeFormatter ? string ( {
year : "2-digit"
} , "year" ) : _this . num ( dt . year . toString ( ) . slice ( - 2 ) , 2 ) ;
case "yyyy" :
// like 0012
return useDateTimeFormatter ? string ( {
year : "numeric"
} , "year" ) : _this . num ( dt . year , 4 ) ;
case "yyyyyy" :
// like 000012
return useDateTimeFormatter ? string ( {
year : "numeric"
} , "year" ) : _this . num ( dt . year , 6 ) ;
// eras
case "G" :
// like AD
return era ( "short" ) ;
case "GG" :
// like Anno Domini
return era ( "long" ) ;
case "GGGGG" :
return era ( "narrow" ) ;
case "kk" :
return _this . num ( dt . weekYear . toString ( ) . slice ( - 2 ) , 2 ) ;
case "kkkk" :
return _this . num ( dt . weekYear , 4 ) ;
case "W" :
return _this . num ( dt . weekNumber ) ;
case "WW" :
return _this . num ( dt . weekNumber , 2 ) ;
case "o" :
return _this . num ( dt . ordinal ) ;
case "ooo" :
return _this . num ( dt . ordinal , 3 ) ;
case "q" :
// like 1
return _this . num ( dt . quarter ) ;
case "qq" :
// like 01
return _this . num ( dt . quarter , 2 ) ;
case "X" :
return _this . num ( Math . floor ( dt . ts / 1000 ) ) ;
case "x" :
return _this . num ( dt . ts ) ;
default :
return maybeMacro ( token ) ;
}
} ;
return stringifyTokens ( Formatter . parseFormat ( fmt ) , tokenToString ) ;
} ;
_proto . formatDurationFromString = function formatDurationFromString ( dur , fmt ) {
var _this2 = this ;
var tokenToField = function tokenToField ( token ) {
switch ( token [ 0 ] ) {
case "S" :
return "millisecond" ;
case "s" :
return "second" ;
case "m" :
return "minute" ;
case "h" :
return "hour" ;
case "d" :
return "day" ;
case "M" :
return "month" ;
case "y" :
return "year" ;
default :
return null ;
}
} ,
tokenToString = function tokenToString ( lildur ) {
return function ( token ) {
var mapped = tokenToField ( token ) ;
if ( mapped ) {
return _this2 . num ( lildur . get ( mapped ) , token . length ) ;
} else {
return token ;
}
} ;
} ,
tokens = Formatter . parseFormat ( fmt ) ,
realTokens = tokens . reduce ( function ( found , _ref ) {
var literal = _ref . literal ,
val = _ref . val ;
return literal ? found : found . concat ( val ) ;
} , [ ] ) ,
collapsed = dur . shiftTo . apply ( dur , realTokens . map ( tokenToField ) . filter ( function ( t ) {
return t ;
} ) ) ;
return stringifyTokens ( tokens , tokenToString ( collapsed ) ) ;
} ;
return Formatter ;
} ( ) ;
var Invalid = /*#__PURE__*/ function ( ) {
function Invalid ( reason , explanation ) {
this . reason = reason ;
this . explanation = explanation ;
}
var _proto = Invalid . prototype ;
_proto . toMessage = function toMessage ( ) {
if ( this . explanation ) {
return this . reason + ": " + this . explanation ;
} else {
return this . reason ;
}
} ;
return Invalid ;
} ( ) ;
/ * *
* @ interface
* /
var Zone = /*#__PURE__*/ function ( ) {
function Zone ( ) { }
var _proto = Zone . prototype ;
/ * *
* Returns the offset ' s common name ( such as EST ) at the specified timestamp
* @ abstract
* @ param { number } ts - Epoch milliseconds for which to get the name
* @ param { Object } opts - Options to affect the format
* @ param { string } opts . format - What style of offset to return . Accepts 'long' or 'short' .
* @ param { string } opts . locale - What locale to return the offset name in .
* @ return { string }
* /
_proto . offsetName = function offsetName ( ts , opts ) {
throw new ZoneIsAbstractError ( ) ;
}
/ * *
* Returns the offset ' s value as a string
* @ abstract
* @ param { number } ts - Epoch milliseconds for which to get the offset
* @ param { string } format - What style of offset to return .
* Accepts 'narrow' , 'short' , or 'techie' . Returning '+6' , '+06:00' , or '+0600' respectively
* @ return { string }
* /
;
_proto . formatOffset = function formatOffset ( ts , format ) {
throw new ZoneIsAbstractError ( ) ;
}
/ * *
* Return the offset in minutes for this zone at the specified timestamp .
* @ abstract
* @ param { number } ts - Epoch milliseconds for which to compute the offset
* @ return { number }
* /
;
_proto . offset = function offset ( ts ) {
throw new ZoneIsAbstractError ( ) ;
}
/ * *
* Return whether this Zone is equal to another zone
* @ abstract
* @ param { Zone } otherZone - the zone to compare
* @ return { boolean }
* /
;
_proto . equals = function equals ( otherZone ) {
throw new ZoneIsAbstractError ( ) ;
}
/ * *
* Return whether this Zone is valid .
* @ abstract
* @ type { boolean }
* /
;
_createClass ( Zone , [ {
key : "type" ,
get :
/ * *
* The type of zone
* @ abstract
* @ type { string }
* /
function get ( ) {
throw new ZoneIsAbstractError ( ) ;
}
/ * *
* The name of this zone .
* @ abstract
* @ type { string }
* /
} , {
key : "name" ,
get : function get ( ) {
throw new ZoneIsAbstractError ( ) ;
}
/ * *
* Returns whether the offset is known to be fixed for the whole year .
* @ abstract
* @ type { boolean }
* /
} , {
key : "isUniversal" ,
get : function get ( ) {
throw new ZoneIsAbstractError ( ) ;
}
} , {
key : "isValid" ,
get : function get ( ) {
throw new ZoneIsAbstractError ( ) ;
}
} ] ) ;
return Zone ;
} ( ) ;
var singleton$1 = null ;
/ * *
* Represents the local zone for this JavaScript environment .
* @ implements { Zone }
* /
var SystemZone = /*#__PURE__*/ function ( _Zone ) {
_inheritsLoose ( SystemZone , _Zone ) ;
function SystemZone ( ) {
return _Zone . apply ( this , arguments ) || this ;
}
var _proto = SystemZone . prototype ;
/** @override **/
_proto . offsetName = function offsetName ( ts , _ref ) {
var format = _ref . format ,
locale = _ref . locale ;
return parseZoneInfo ( ts , format , locale ) ;
}
/** @override **/
;
_proto . formatOffset = function formatOffset$1 ( ts , format ) {
return formatOffset ( this . offset ( ts ) , format ) ;
}
/** @override **/
;
_proto . offset = function offset ( ts ) {
return - new Date ( ts ) . getTimezoneOffset ( ) ;
}
/** @override **/
;
_proto . equals = function equals ( otherZone ) {
return otherZone . type === "system" ;
}
/** @override **/
;
_createClass ( SystemZone , [ {
key : "type" ,
get :
/** @override **/
function get ( ) {
return "system" ;
}
/** @override **/
} , {
key : "name" ,
get : function get ( ) {
return new Intl . DateTimeFormat ( ) . resolvedOptions ( ) . timeZone ;
}
/** @override **/
} , {
key : "isUniversal" ,
get : function get ( ) {
return false ;
}
} , {
key : "isValid" ,
get : function get ( ) {
return true ;
}
} ] , [ {
key : "instance" ,
get :
/ * *
* Get a singleton instance of the local zone
* @ return { SystemZone }
* /
function get ( ) {
if ( singleton$1 === null ) {
singleton$1 = new SystemZone ( ) ;
}
return singleton$1 ;
}
} ] ) ;
return SystemZone ;
} ( Zone ) ;
var matchingRegex = RegExp ( "^" + ianaRegex . source + "$" ) ;
var dtfCache = { } ;
function makeDTF ( zone ) {
if ( ! dtfCache [ zone ] ) {
dtfCache [ zone ] = new Intl . DateTimeFormat ( "en-US" , {
hourCycle : "h23" ,
timeZone : zone ,
year : "numeric" ,
month : "2-digit" ,
day : "2-digit" ,
hour : "2-digit" ,
minute : "2-digit" ,
second : "2-digit"
} ) ;
}
return dtfCache [ zone ] ;
}
var typeToPos = {
year : 0 ,
month : 1 ,
day : 2 ,
hour : 3 ,
minute : 4 ,
second : 5
} ;
function hackyOffset ( dtf , date ) {
var formatted = dtf . format ( date ) . replace ( /\u200E/g , "" ) ,
parsed = /(\d+)\/(\d+)\/(\d+),? (\d+):(\d+):(\d+)/ . exec ( formatted ) ,
fMonth = parsed [ 1 ] ,
fDay = parsed [ 2 ] ,
fYear = parsed [ 3 ] ,
fHour = parsed [ 4 ] ,
fMinute = parsed [ 5 ] ,
fSecond = parsed [ 6 ] ;
return [ fYear , fMonth , fDay , fHour , fMinute , fSecond ] ;
}
function partsOffset ( dtf , date ) {
var formatted = dtf . formatToParts ( date ) ,
filled = [ ] ;
for ( var i = 0 ; i < formatted . length ; i ++ ) {
var _formatted$i = formatted [ i ] ,
type = _formatted$i . type ,
value = _formatted$i . value ,
pos = typeToPos [ type ] ;
if ( ! isUndefined ( pos ) ) {
filled [ pos ] = parseInt ( value , 10 ) ;
}
}
return filled ;
}
var ianaZoneCache = { } ;
/ * *
* A zone identified by an IANA identifier , like America / New _York
* @ implements { Zone }
* /
var IANAZone = /*#__PURE__*/ function ( _Zone ) {
_inheritsLoose ( IANAZone , _Zone ) ;
/ * *
* @ param { string } name - Zone name
* @ return { IANAZone }
* /
IANAZone . create = function create ( name ) {
if ( ! ianaZoneCache [ name ] ) {
ianaZoneCache [ name ] = new IANAZone ( name ) ;
}
return ianaZoneCache [ name ] ;
}
/ * *
* Reset local caches . Should only be necessary in testing scenarios .
* @ return { void }
* /
;
IANAZone . resetCache = function resetCache ( ) {
ianaZoneCache = { } ;
dtfCache = { } ;
}
/ * *
* Returns whether the provided string is a valid specifier . This only checks the string ' s format , not that the specifier identifies a known zone ; see isValidZone for that .
* @ param { string } s - The string to check validity on
* @ example IANAZone . isValidSpecifier ( "America/New_York" ) //=> true
* @ example IANAZone . isValidSpecifier ( "Fantasia/Castle" ) //=> true
* @ example IANAZone . isValidSpecifier ( "Sport~~blorp" ) //=> false
* @ return { boolean }
* /
;
IANAZone . isValidSpecifier = function isValidSpecifier ( s ) {
return ! ! ( s && s . match ( matchingRegex ) ) ;
}
/ * *
* Returns whether the provided string identifies a real zone
* @ param { string } zone - The string to check
* @ example IANAZone . isValidZone ( "America/New_York" ) //=> true
* @ example IANAZone . isValidZone ( "Fantasia/Castle" ) //=> false
* @ example IANAZone . isValidZone ( "Sport~~blorp" ) //=> false
* @ return { boolean }
* /
;
IANAZone . isValidZone = function isValidZone ( zone ) {
try {
new Intl . DateTimeFormat ( "en-US" , {
timeZone : zone
} ) . format ( ) ;
return true ;
} catch ( e ) {
return false ;
}
} // Etc/GMT+8 -> -480
/** @ignore */
;
IANAZone . parseGMTOffset = function parseGMTOffset ( specifier ) {
if ( specifier ) {
var match = specifier . match ( /^Etc\/GMT(0|[+-]\d{1,2})$/i ) ;
if ( match ) {
return - 60 * parseInt ( match [ 1 ] ) ;
}
}
return null ;
} ;
function IANAZone ( name ) {
var _this ;
_this = _Zone . call ( this ) || this ;
/** @private **/
_this . zoneName = name ;
/** @private **/
_this . valid = IANAZone . isValidZone ( name ) ;
return _this ;
}
/** @override **/
var _proto = IANAZone . prototype ;
/** @override **/
_proto . offsetName = function offsetName ( ts , _ref ) {
var format = _ref . format ,
locale = _ref . locale ;
return parseZoneInfo ( ts , format , locale , this . name ) ;
}
/** @override **/
;
_proto . formatOffset = function formatOffset$1 ( ts , format ) {
return formatOffset ( this . offset ( ts ) , format ) ;
}
/** @override **/
;
_proto . offset = function offset ( ts ) {
var date = new Date ( ts ) ;
if ( isNaN ( date ) ) return NaN ;
var dtf = makeDTF ( this . name ) ,
_ref2 = dtf . formatToParts ? partsOffset ( dtf , date ) : hackyOffset ( dtf , date ) ,
year = _ref2 [ 0 ] ,
month = _ref2 [ 1 ] ,
day = _ref2 [ 2 ] ,
hour = _ref2 [ 3 ] ,
minute = _ref2 [ 4 ] ,
second = _ref2 [ 5 ] ;
var asUTC = objToLocalTS ( {
year : year ,
month : month ,
day : day ,
hour : hour ,
minute : minute ,
second : second ,
millisecond : 0
} ) ;
var asTS = + date ;
var over = asTS % 1000 ;
asTS -= over >= 0 ? over : 1000 + over ;
return ( asUTC - asTS ) / ( 60 * 1000 ) ;
}
/** @override **/
;
_proto . equals = function equals ( otherZone ) {
return otherZone . type === "iana" && otherZone . name === this . name ;
}
/** @override **/
;
_createClass ( IANAZone , [ {
key : "type" ,
get : function get ( ) {
return "iana" ;
}
/** @override **/
} , {
key : "name" ,
get : function get ( ) {
return this . zoneName ;
}
/** @override **/
} , {
key : "isUniversal" ,
get : function get ( ) {
return false ;
}
} , {
key : "isValid" ,
get : function get ( ) {
return this . valid ;
}
} ] ) ;
return IANAZone ;
} ( Zone ) ;
var singleton = null ;
/ * *
* A zone with a fixed offset ( meaning no DST )
* @ implements { Zone }
* /
var FixedOffsetZone = /*#__PURE__*/ function ( _Zone ) {
_inheritsLoose ( FixedOffsetZone , _Zone ) ;
/ * *
* Get an instance with a specified offset
* @ param { number } offset - The offset in minutes
* @ return { FixedOffsetZone }
* /
FixedOffsetZone . instance = function instance ( offset ) {
return offset === 0 ? FixedOffsetZone . utcInstance : new FixedOffsetZone ( offset ) ;
}
/ * *
* Get an instance of FixedOffsetZone from a UTC offset string , like "UTC+6"
* @ param { string } s - The offset string to parse
* @ example FixedOffsetZone . parseSpecifier ( "UTC+6" )
* @ example FixedOffsetZone . parseSpecifier ( "UTC+06" )
* @ example FixedOffsetZone . parseSpecifier ( "UTC-6:00" )
* @ return { FixedOffsetZone }
* /
;
FixedOffsetZone . parseSpecifier = function parseSpecifier ( s ) {
if ( s ) {
var r = s . match ( /^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i ) ;
if ( r ) {
return new FixedOffsetZone ( signedOffset ( r [ 1 ] , r [ 2 ] ) ) ;
}
}
return null ;
} ;
function FixedOffsetZone ( offset ) {
var _this ;
_this = _Zone . call ( this ) || this ;
/** @private **/
_this . fixed = offset ;
return _this ;
}
/** @override **/
var _proto = FixedOffsetZone . prototype ;
/** @override **/
_proto . offsetName = function offsetName ( ) {
return this . name ;
}
/** @override **/
;
_proto . formatOffset = function formatOffset$1 ( ts , format ) {
return formatOffset ( this . fixed , format ) ;
}
/** @override **/
;
/** @override **/
_proto . offset = function offset ( ) {
return this . fixed ;
}
/** @override **/
;
_proto . equals = function equals ( otherZone ) {
return otherZone . type === "fixed" && otherZone . fixed === this . fixed ;
}
/** @override **/
;
_createClass ( FixedOffsetZone , [ {
key : "type" ,
get : function get ( ) {
return "fixed" ;
}
/** @override **/
} , {
key : "name" ,
get : function get ( ) {
return this . fixed === 0 ? "UTC" : "UTC" + formatOffset ( this . fixed , "narrow" ) ;
}
} , {
key : "isUniversal" ,
get : function get ( ) {
return true ;
}
} , {
key : "isValid" ,
get : function get ( ) {
return true ;
}
} ] , [ {
key : "utcInstance" ,
get :
/ * *
* Get a singleton instance of UTC
* @ return { FixedOffsetZone }
* /
function get ( ) {
if ( singleton === null ) {
singleton = new FixedOffsetZone ( 0 ) ;
}
return singleton ;
}
} ] ) ;
return FixedOffsetZone ;
} ( Zone ) ;
/ * *
* A zone that failed to parse . You should never need to instantiate this .
* @ implements { Zone }
* /
var InvalidZone = /*#__PURE__*/ function ( _Zone ) {
_inheritsLoose ( InvalidZone , _Zone ) ;
function InvalidZone ( zoneName ) {
var _this ;
_this = _Zone . call ( this ) || this ;
/** @private */
_this . zoneName = zoneName ;
return _this ;
}
/** @override **/
var _proto = InvalidZone . prototype ;
/** @override **/
_proto . offsetName = function offsetName ( ) {
return null ;
}
/** @override **/
;
_proto . formatOffset = function formatOffset ( ) {
return "" ;
}
/** @override **/
;
_proto . offset = function offset ( ) {
return NaN ;
}
/** @override **/
;
_proto . equals = function equals ( ) {
return false ;
}
/** @override **/
;
_createClass ( InvalidZone , [ {
key : "type" ,
get : function get ( ) {
return "invalid" ;
}
/** @override **/
} , {
key : "name" ,
get : function get ( ) {
return this . zoneName ;
}
/** @override **/
} , {
key : "isUniversal" ,
get : function get ( ) {
return false ;
}
} , {
key : "isValid" ,
get : function get ( ) {
return false ;
}
} ] ) ;
return InvalidZone ;
} ( Zone ) ;
/ * *
* @ private
* /
function normalizeZone ( input , defaultZone ) {
var offset ;
if ( isUndefined ( input ) || input === null ) {
return defaultZone ;
} else if ( input instanceof Zone ) {
return input ;
} else if ( isString ( input ) ) {
var lowered = input . toLowerCase ( ) ;
if ( lowered === "local" || lowered === "system" ) return defaultZone ; else if ( lowered === "utc" || lowered === "gmt" ) return FixedOffsetZone . utcInstance ; else if ( ( offset = IANAZone . parseGMTOffset ( input ) ) != null ) {
// handle Etc/GMT-4, which V8 chokes on
return FixedOffsetZone . instance ( offset ) ;
} else if ( IANAZone . isValidSpecifier ( lowered ) ) return IANAZone . create ( input ) ; else return FixedOffsetZone . parseSpecifier ( lowered ) || new InvalidZone ( input ) ;
} else if ( isNumber ( input ) ) {
return FixedOffsetZone . instance ( input ) ;
} else if ( typeof input === "object" && input . offset && typeof input . offset === "number" ) {
// This is dumb, but the instanceof check above doesn't seem to really work
// so we're duck checking it
return input ;
} else {
return new InvalidZone ( input ) ;
}
}
var now = function now ( ) {
return Date . now ( ) ;
} ,
defaultZone = "system" ,
defaultLocale = null ,
defaultNumberingSystem = null ,
defaultOutputCalendar = null ,
throwOnInvalid ;
/ * *
* Settings contains static getters and setters that control Luxon ' s overall behavior . Luxon is a simple library with few options , but the ones it does have live here .
* /
var Settings = /*#__PURE__*/ function ( ) {
function Settings ( ) { }
/ * *
* Reset Luxon ' s global caches . Should only be necessary in testing scenarios .
* @ return { void }
* /
Settings . resetCaches = function resetCaches ( ) {
Locale . resetCache ( ) ;
IANAZone . resetCache ( ) ;
} ;
_createClass ( Settings , null , [ {
key : "now" ,
get :
/ * *
* Get the callback for returning the current timestamp .
* @ type { function }
* /
function get ( ) {
return now ;
}
/ * *
* Set the callback for returning the current timestamp .
* The function should return a number , which will be interpreted as an Epoch millisecond count
* @ type { function }
* @ example Settings . now = ( ) => Date . now ( ) + 3000 // pretend it is 3 seconds in the future
* @ example Settings . now = ( ) => 0 // always pretend it's Jan 1, 1970 at midnight in UTC time
* /
,
set : function set ( n ) {
now = n ;
}
/ * *
* Set the default time zone to create DateTimes in . Does not affect existing instances .
* Use the value "system" to reset this value to the system ' s time zone .
* @ type { string }
* /
} , {
key : "defaultZone" ,
get :
/ * *
* Get the default time zone object currently used to create DateTimes . Does not affect existing instances .
* The default value is the system ' s time zone ( the one set on the machine that runs this code ) .
* @ type { Zone }
* /
function get ( ) {
return normalizeZone ( defaultZone , SystemZone . instance ) ;
}
/ * *
* Get the default locale to create DateTimes with . Does not affect existing instances .
* @ type { string }
* /
,
set : function set ( zone ) {
defaultZone = zone ;
}
} , {
key : "defaultLocale" ,
get : function get ( ) {
return defaultLocale ;
}
/ * *
* Set the default locale to create DateTimes with . Does not affect existing instances .
* @ type { string }
* /
,
set : function set ( locale ) {
defaultLocale = locale ;
}
/ * *
* Get the default numbering system to create DateTimes with . Does not affect existing instances .
* @ type { string }
* /
} , {
key : "defaultNumberingSystem" ,
get : function get ( ) {
return defaultNumberingSystem ;
}
/ * *
* Set the default numbering system to create DateTimes with . Does not affect existing instances .
* @ type { string }
* /
,
set : function set ( numberingSystem ) {
defaultNumberingSystem = numberingSystem ;
}
/ * *
* Get the default output calendar to create DateTimes with . Does not affect existing instances .
* @ type { string }
* /
} , {
key : "defaultOutputCalendar" ,
get : function get ( ) {
return defaultOutputCalendar ;
}
/ * *
* Set the default output calendar to create DateTimes with . Does not affect existing instances .
* @ type { string }
* /
,
set : function set ( outputCalendar ) {
defaultOutputCalendar = outputCalendar ;
}
/ * *
* Get whether Luxon will throw when it encounters invalid DateTimes , Durations , or Intervals
* @ type { boolean }
* /
} , {
key : "throwOnInvalid" ,
get : function get ( ) {
return throwOnInvalid ;
}
/ * *
* Set whether Luxon will throw when it encounters invalid DateTimes , Durations , or Intervals
* @ type { boolean }
* /
,
set : function set ( t ) {
throwOnInvalid = t ;
}
} ] ) ;
return Settings ;
} ( ) ;
var _excluded = [ "base" ] ;
var intlDTCache = { } ;
function getCachedDTF ( locString , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var key = JSON . stringify ( [ locString , opts ] ) ;
var dtf = intlDTCache [ key ] ;
if ( ! dtf ) {
dtf = new Intl . DateTimeFormat ( locString , opts ) ;
intlDTCache [ key ] = dtf ;
}
return dtf ;
}
var intlNumCache = { } ;
function getCachedINF ( locString , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var key = JSON . stringify ( [ locString , opts ] ) ;
var inf = intlNumCache [ key ] ;
if ( ! inf ) {
inf = new Intl . NumberFormat ( locString , opts ) ;
intlNumCache [ key ] = inf ;
}
return inf ;
}
var intlRelCache = { } ;
function getCachedRTF ( locString , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var _opts = opts ;
_opts . base ;
var cacheKeyOpts = _objectWithoutPropertiesLoose ( _opts , _excluded ) ; // exclude `base` from the options
var key = JSON . stringify ( [ locString , cacheKeyOpts ] ) ;
var inf = intlRelCache [ key ] ;
if ( ! inf ) {
inf = new Intl . RelativeTimeFormat ( locString , opts ) ;
intlRelCache [ key ] = inf ;
}
return inf ;
}
var sysLocaleCache = null ;
function systemLocale ( ) {
if ( sysLocaleCache ) {
return sysLocaleCache ;
} else {
sysLocaleCache = new Intl . DateTimeFormat ( ) . resolvedOptions ( ) . locale ;
return sysLocaleCache ;
}
}
function parseLocaleString ( localeStr ) {
// I really want to avoid writing a BCP 47 parser
// see, e.g. https://github.com/wooorm/bcp-47
// Instead, we'll do this:
// a) if the string has no -u extensions, just leave it alone
// b) if it does, use Intl to resolve everything
// c) if Intl fails, try again without the -u
var uIndex = localeStr . indexOf ( "-u-" ) ;
if ( uIndex === - 1 ) {
return [ localeStr ] ;
} else {
var options ;
var smaller = localeStr . substring ( 0 , uIndex ) ;
try {
options = getCachedDTF ( localeStr ) . resolvedOptions ( ) ;
} catch ( e ) {
options = getCachedDTF ( smaller ) . resolvedOptions ( ) ;
}
var _options = options ,
numberingSystem = _options . numberingSystem ,
calendar = _options . calendar ; // return the smaller one so that we can append the calendar and numbering overrides to it
return [ smaller , numberingSystem , calendar ] ;
}
}
function intlConfigString ( localeStr , numberingSystem , outputCalendar ) {
if ( outputCalendar || numberingSystem ) {
localeStr += "-u" ;
if ( outputCalendar ) {
localeStr += "-ca-" + outputCalendar ;
}
if ( numberingSystem ) {
localeStr += "-nu-" + numberingSystem ;
}
return localeStr ;
} else {
return localeStr ;
}
}
function mapMonths ( f ) {
var ms = [ ] ;
for ( var i = 1 ; i <= 12 ; i ++ ) {
var dt = DateTime . utc ( 2016 , i , 1 ) ;
ms . push ( f ( dt ) ) ;
}
return ms ;
}
function mapWeekdays ( f ) {
var ms = [ ] ;
for ( var i = 1 ; i <= 7 ; i ++ ) {
var dt = DateTime . utc ( 2016 , 11 , 13 + i ) ;
ms . push ( f ( dt ) ) ;
}
return ms ;
}
function listStuff ( loc , length , defaultOK , englishFn , intlFn ) {
var mode = loc . listingMode ( defaultOK ) ;
if ( mode === "error" ) {
return null ;
} else if ( mode === "en" ) {
return englishFn ( length ) ;
} else {
return intlFn ( length ) ;
}
}
function supportsFastNumbers ( loc ) {
if ( loc . numberingSystem && loc . numberingSystem !== "latn" ) {
return false ;
} else {
return loc . numberingSystem === "latn" || ! loc . locale || loc . locale . startsWith ( "en" ) || new Intl . DateTimeFormat ( loc . intl ) . resolvedOptions ( ) . numberingSystem === "latn" ;
}
}
/ * *
* @ private
* /
var PolyNumberFormatter = /*#__PURE__*/ function ( ) {
function PolyNumberFormatter ( intl , forceSimple , opts ) {
this . padTo = opts . padTo || 0 ;
this . floor = opts . floor || false ;
if ( ! forceSimple ) {
var intlOpts = {
useGrouping : false
} ;
if ( opts . padTo > 0 ) intlOpts . minimumIntegerDigits = opts . padTo ;
this . inf = getCachedINF ( intl , intlOpts ) ;
}
}
var _proto = PolyNumberFormatter . prototype ;
_proto . format = function format ( i ) {
if ( this . inf ) {
var fixed = this . floor ? Math . floor ( i ) : i ;
return this . inf . format ( fixed ) ;
} else {
// to match the browser's numberformatter defaults
var _fixed = this . floor ? Math . floor ( i ) : roundTo ( i , 3 ) ;
return padStart ( _fixed , this . padTo ) ;
}
} ;
return PolyNumberFormatter ;
} ( ) ;
/ * *
* @ private
* /
var PolyDateFormatter = /*#__PURE__*/ function ( ) {
function PolyDateFormatter ( dt , intl , opts ) {
this . opts = opts ;
var z ;
if ( dt . zone . isUniversal ) {
// UTC-8 or Etc/UTC-8 are not part of tzdata, only Etc/GMT+8 and the like.
// That is why fixed-offset TZ is set to that unless it is:
// 1. Representing offset 0 when UTC is used to maintain previous behavior and does not become GMT.
// 2. Unsupported by the browser:
// - some do not support Etc/
// - < Etc/GMT-14, > Etc/GMT+12, and 30-minute or 45-minute offsets are not part of tzdata
var gmtOffset = - 1 * ( dt . offset / 60 ) ;
var offsetZ = gmtOffset >= 0 ? "Etc/GMT+" + gmtOffset : "Etc/GMT" + gmtOffset ;
var isOffsetZoneSupported = IANAZone . isValidZone ( offsetZ ) ;
if ( dt . offset !== 0 && isOffsetZoneSupported ) {
z = offsetZ ;
this . dt = dt ;
} else {
// Not all fixed-offset zones like Etc/+4:30 are present in tzdata.
// So we have to make do. Two cases:
// 1. The format options tell us to show the zone. We can't do that, so the best
// we can do is format the date in UTC.
// 2. The format options don't tell us to show the zone. Then we can adjust them
// the time and tell the formatter to show it to us in UTC, so that the time is right
// and the bad zone doesn't show up.
z = "UTC" ;
if ( opts . timeZoneName ) {
this . dt = dt ;
} else {
this . dt = dt . offset === 0 ? dt : DateTime . fromMillis ( dt . ts + dt . offset * 60 * 1000 ) ;
}
}
} else if ( dt . zone . type === "system" ) {
this . dt = dt ;
} else {
this . dt = dt ;
z = dt . zone . name ;
}
var intlOpts = _extends ( { } , this . opts ) ;
if ( z ) {
intlOpts . timeZone = z ;
}
this . dtf = getCachedDTF ( intl , intlOpts ) ;
}
var _proto2 = PolyDateFormatter . prototype ;
_proto2 . format = function format ( ) {
return this . dtf . format ( this . dt . toJSDate ( ) ) ;
} ;
_proto2 . formatToParts = function formatToParts ( ) {
return this . dtf . formatToParts ( this . dt . toJSDate ( ) ) ;
} ;
_proto2 . resolvedOptions = function resolvedOptions ( ) {
return this . dtf . resolvedOptions ( ) ;
} ;
return PolyDateFormatter ;
} ( ) ;
/ * *
* @ private
* /
var PolyRelFormatter = /*#__PURE__*/ function ( ) {
function PolyRelFormatter ( intl , isEnglish , opts ) {
this . opts = _extends ( {
style : "long"
} , opts ) ;
if ( ! isEnglish && hasRelative ( ) ) {
this . rtf = getCachedRTF ( intl , opts ) ;
}
}
var _proto3 = PolyRelFormatter . prototype ;
_proto3 . format = function format ( count , unit ) {
if ( this . rtf ) {
return this . rtf . format ( count , unit ) ;
} else {
return formatRelativeTime ( unit , count , this . opts . numeric , this . opts . style !== "long" ) ;
}
} ;
_proto3 . formatToParts = function formatToParts ( count , unit ) {
if ( this . rtf ) {
return this . rtf . formatToParts ( count , unit ) ;
} else {
return [ ] ;
}
} ;
return PolyRelFormatter ;
} ( ) ;
/ * *
* @ private
* /
var Locale = /*#__PURE__*/ function ( ) {
Locale . fromOpts = function fromOpts ( opts ) {
return Locale . create ( opts . locale , opts . numberingSystem , opts . outputCalendar , opts . defaultToEN ) ;
} ;
Locale . create = function create ( locale , numberingSystem , outputCalendar , defaultToEN ) {
if ( defaultToEN === void 0 ) {
defaultToEN = false ;
}
var specifiedLocale = locale || Settings . defaultLocale ; // the system locale is useful for human readable strings but annoying for parsing/formatting known formats
var localeR = specifiedLocale || ( defaultToEN ? "en-US" : systemLocale ( ) ) ;
var numberingSystemR = numberingSystem || Settings . defaultNumberingSystem ;
var outputCalendarR = outputCalendar || Settings . defaultOutputCalendar ;
return new Locale ( localeR , numberingSystemR , outputCalendarR , specifiedLocale ) ;
} ;
Locale . resetCache = function resetCache ( ) {
sysLocaleCache = null ;
intlDTCache = { } ;
intlNumCache = { } ;
intlRelCache = { } ;
} ;
Locale . fromObject = function fromObject ( _temp ) {
var _ref = _temp === void 0 ? { } : _temp ,
locale = _ref . locale ,
numberingSystem = _ref . numberingSystem ,
outputCalendar = _ref . outputCalendar ;
return Locale . create ( locale , numberingSystem , outputCalendar ) ;
} ;
function Locale ( locale , numbering , outputCalendar , specifiedLocale ) {
var _parseLocaleString = parseLocaleString ( locale ) ,
parsedLocale = _parseLocaleString [ 0 ] ,
parsedNumberingSystem = _parseLocaleString [ 1 ] ,
parsedOutputCalendar = _parseLocaleString [ 2 ] ;
this . locale = parsedLocale ;
this . numberingSystem = numbering || parsedNumberingSystem || null ;
this . outputCalendar = outputCalendar || parsedOutputCalendar || null ;
this . intl = intlConfigString ( this . locale , this . numberingSystem , this . outputCalendar ) ;
this . weekdaysCache = {
format : { } ,
standalone : { }
} ;
this . monthsCache = {
format : { } ,
standalone : { }
} ;
this . meridiemCache = null ;
this . eraCache = { } ;
this . specifiedLocale = specifiedLocale ;
this . fastNumbersCached = null ;
}
var _proto4 = Locale . prototype ;
_proto4 . listingMode = function listingMode ( defaultOK ) {
var isActuallyEn = this . isEnglish ( ) ;
var hasNoWeirdness = ( this . numberingSystem === null || this . numberingSystem === "latn" ) && ( this . outputCalendar === null || this . outputCalendar === "gregory" ) ;
return isActuallyEn && hasNoWeirdness ? "en" : "intl" ;
} ;
_proto4 . clone = function clone ( alts ) {
if ( ! alts || Object . getOwnPropertyNames ( alts ) . length === 0 ) {
return this ;
} else {
return Locale . create ( alts . locale || this . specifiedLocale , alts . numberingSystem || this . numberingSystem , alts . outputCalendar || this . outputCalendar , alts . defaultToEN || false ) ;
}
} ;
_proto4 . redefaultToEN = function redefaultToEN ( alts ) {
if ( alts === void 0 ) {
alts = { } ;
}
return this . clone ( _extends ( { } , alts , {
defaultToEN : true
} ) ) ;
} ;
_proto4 . redefaultToSystem = function redefaultToSystem ( alts ) {
if ( alts === void 0 ) {
alts = { } ;
}
return this . clone ( _extends ( { } , alts , {
defaultToEN : false
} ) ) ;
} ;
_proto4 . months = function months$1 ( length , format , defaultOK ) {
var _this = this ;
if ( format === void 0 ) {
format = false ;
}
if ( defaultOK === void 0 ) {
defaultOK = true ;
}
return listStuff ( this , length , defaultOK , months , function ( ) {
var intl = format ? {
month : length ,
day : "numeric"
} : {
month : length
} ,
formatStr = format ? "format" : "standalone" ;
if ( ! _this . monthsCache [ formatStr ] [ length ] ) {
_this . monthsCache [ formatStr ] [ length ] = mapMonths ( function ( dt ) {
return _this . extract ( dt , intl , "month" ) ;
} ) ;
}
return _this . monthsCache [ formatStr ] [ length ] ;
} ) ;
} ;
_proto4 . weekdays = function weekdays$1 ( length , format , defaultOK ) {
var _this2 = this ;
if ( format === void 0 ) {
format = false ;
}
if ( defaultOK === void 0 ) {
defaultOK = true ;
}
return listStuff ( this , length , defaultOK , weekdays , function ( ) {
var intl = format ? {
weekday : length ,
year : "numeric" ,
month : "long" ,
day : "numeric"
} : {
weekday : length
} ,
formatStr = format ? "format" : "standalone" ;
if ( ! _this2 . weekdaysCache [ formatStr ] [ length ] ) {
_this2 . weekdaysCache [ formatStr ] [ length ] = mapWeekdays ( function ( dt ) {
return _this2 . extract ( dt , intl , "weekday" ) ;
} ) ;
}
return _this2 . weekdaysCache [ formatStr ] [ length ] ;
} ) ;
} ;
_proto4 . meridiems = function meridiems$1 ( defaultOK ) {
var _this3 = this ;
if ( defaultOK === void 0 ) {
defaultOK = true ;
}
return listStuff ( this , undefined , defaultOK , function ( ) {
return meridiems ;
} , function ( ) {
// In theory there could be aribitrary day periods. We're gonna assume there are exactly two
// for AM and PM. This is probably wrong, but it's makes parsing way easier.
if ( ! _this3 . meridiemCache ) {
var intl = {
hour : "numeric" ,
hourCycle : "h12"
} ;
_this3 . meridiemCache = [ DateTime . utc ( 2016 , 11 , 13 , 9 ) , DateTime . utc ( 2016 , 11 , 13 , 19 ) ] . map ( function ( dt ) {
return _this3 . extract ( dt , intl , "dayperiod" ) ;
} ) ;
}
return _this3 . meridiemCache ;
} ) ;
} ;
_proto4 . eras = function eras$1 ( length , defaultOK ) {
var _this4 = this ;
if ( defaultOK === void 0 ) {
defaultOK = true ;
}
return listStuff ( this , length , defaultOK , eras , function ( ) {
var intl = {
era : length
} ; // This is problematic. Different calendars are going to define eras totally differently. What I need is the minimum set of dates
// to definitely enumerate them.
if ( ! _this4 . eraCache [ length ] ) {
_this4 . eraCache [ length ] = [ DateTime . utc ( - 40 , 1 , 1 ) , DateTime . utc ( 2017 , 1 , 1 ) ] . map ( function ( dt ) {
return _this4 . extract ( dt , intl , "era" ) ;
} ) ;
}
return _this4 . eraCache [ length ] ;
} ) ;
} ;
_proto4 . extract = function extract ( dt , intlOpts , field ) {
var df = this . dtFormatter ( dt , intlOpts ) ,
results = df . formatToParts ( ) ,
matching = results . find ( function ( m ) {
return m . type . toLowerCase ( ) === field ;
} ) ;
return matching ? matching . value : null ;
} ;
_proto4 . numberFormatter = function numberFormatter ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
// this forcesimple option is never used (the only caller short-circuits on it, but it seems safer to leave)
// (in contrast, the rest of the condition is used heavily)
return new PolyNumberFormatter ( this . intl , opts . forceSimple || this . fastNumbers , opts ) ;
} ;
_proto4 . dtFormatter = function dtFormatter ( dt , intlOpts ) {
if ( intlOpts === void 0 ) {
intlOpts = { } ;
}
return new PolyDateFormatter ( dt , this . intl , intlOpts ) ;
} ;
_proto4 . relFormatter = function relFormatter ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
return new PolyRelFormatter ( this . intl , this . isEnglish ( ) , opts ) ;
} ;
_proto4 . isEnglish = function isEnglish ( ) {
return this . locale === "en" || this . locale . toLowerCase ( ) === "en-us" || new Intl . DateTimeFormat ( this . intl ) . resolvedOptions ( ) . locale . startsWith ( "en-us" ) ;
} ;
_proto4 . equals = function equals ( other ) {
return this . locale === other . locale && this . numberingSystem === other . numberingSystem && this . outputCalendar === other . outputCalendar ;
} ;
_createClass ( Locale , [ {
key : "fastNumbers" ,
get : function get ( ) {
if ( this . fastNumbersCached == null ) {
this . fastNumbersCached = supportsFastNumbers ( this ) ;
}
return this . fastNumbersCached ;
}
} ] ) ;
return Locale ;
} ( ) ;
/ *
* This file handles parsing for well - specified formats . Here ' s how it works :
* Two things go into parsing : a regex to match with and an extractor to take apart the groups in the match .
* An extractor is just a function that takes a regex match array and returns a { year : ... , month : ... } object
* parse ( ) does the work of executing the regex and applying the extractor . It takes multiple regex / extractor pairs to try in sequence .
* Extractors can take a "cursor" representing the offset in the match to look at . This makes it easy to combine extractors .
* combineExtractors ( ) does the work of combining them , keeping track of the cursor through multiple extractions .
* Some extractions are super dumb and simpleParse and fromStrings help DRY them .
* /
function combineRegexes ( ) {
for ( var _len = arguments . length , regexes = new Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
regexes [ _key ] = arguments [ _key ] ;
}
var full = regexes . reduce ( function ( f , r ) {
return f + r . source ;
} , "" ) ;
return RegExp ( "^" + full + "$" ) ;
}
function combineExtractors ( ) {
for ( var _len2 = arguments . length , extractors = new Array ( _len2 ) , _key2 = 0 ; _key2 < _len2 ; _key2 ++ ) {
extractors [ _key2 ] = arguments [ _key2 ] ;
}
return function ( m ) {
return extractors . reduce ( function ( _ref , ex ) {
var mergedVals = _ref [ 0 ] ,
mergedZone = _ref [ 1 ] ,
cursor = _ref [ 2 ] ;
var _ex = ex ( m , cursor ) ,
val = _ex [ 0 ] ,
zone = _ex [ 1 ] ,
next = _ex [ 2 ] ;
return [ _extends ( { } , mergedVals , val ) , mergedZone || zone , next ] ;
} , [ { } , null , 1 ] ) . slice ( 0 , 2 ) ;
} ;
}
function parse ( s ) {
if ( s == null ) {
return [ null , null ] ;
}
for ( var _len3 = arguments . length , patterns = new Array ( _len3 > 1 ? _len3 - 1 : 0 ) , _key3 = 1 ; _key3 < _len3 ; _key3 ++ ) {
patterns [ _key3 - 1 ] = arguments [ _key3 ] ;
}
for ( var _i = 0 , _patterns = patterns ; _i < _patterns . length ; _i ++ ) {
var _patterns$ _i = _patterns [ _i ] ,
regex = _patterns$ _i [ 0 ] ,
extractor = _patterns$ _i [ 1 ] ;
var m = regex . exec ( s ) ;
if ( m ) {
return extractor ( m ) ;
}
}
return [ null , null ] ;
}
function simpleParse ( ) {
for ( var _len4 = arguments . length , keys = new Array ( _len4 ) , _key4 = 0 ; _key4 < _len4 ; _key4 ++ ) {
keys [ _key4 ] = arguments [ _key4 ] ;
}
return function ( match , cursor ) {
var ret = { } ;
var i ;
for ( i = 0 ; i < keys . length ; i ++ ) {
ret [ keys [ i ] ] = parseInteger ( match [ cursor + i ] ) ;
}
return [ ret , null , cursor + i ] ;
} ;
} // ISO and SQL parsing
var offsetRegex = /(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/ ,
isoTimeBaseRegex = /(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/ ,
isoTimeRegex = RegExp ( "" + isoTimeBaseRegex . source + offsetRegex . source + "?" ) ,
isoTimeExtensionRegex = RegExp ( "(?:T" + isoTimeRegex . source + ")?" ) ,
isoYmdRegex = /([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/ ,
isoWeekRegex = /(\d{4})-?W(\d\d)(?:-?(\d))?/ ,
isoOrdinalRegex = /(\d{4})-?(\d{3})/ ,
extractISOWeekData = simpleParse ( "weekYear" , "weekNumber" , "weekDay" ) ,
extractISOOrdinalData = simpleParse ( "year" , "ordinal" ) ,
sqlYmdRegex = /(\d{4})-(\d\d)-(\d\d)/ ,
// dumbed-down version of the ISO one
sqlTimeRegex = RegExp ( isoTimeBaseRegex . source + " ?(?:" + offsetRegex . source + "|(" + ianaRegex . source + "))?" ) ,
sqlTimeExtensionRegex = RegExp ( "(?: " + sqlTimeRegex . source + ")?" ) ;
function int ( match , pos , fallback ) {
var m = match [ pos ] ;
return isUndefined ( m ) ? fallback : parseInteger ( m ) ;
}
function extractISOYmd ( match , cursor ) {
var item = {
year : int ( match , cursor ) ,
month : int ( match , cursor + 1 , 1 ) ,
day : int ( match , cursor + 2 , 1 )
} ;
return [ item , null , cursor + 3 ] ;
}
function extractISOTime ( match , cursor ) {
var item = {
hours : int ( match , cursor , 0 ) ,
minutes : int ( match , cursor + 1 , 0 ) ,
seconds : int ( match , cursor + 2 , 0 ) ,
milliseconds : parseMillis ( match [ cursor + 3 ] )
} ;
return [ item , null , cursor + 4 ] ;
}
function extractISOOffset ( match , cursor ) {
var local = ! match [ cursor ] && ! match [ cursor + 1 ] ,
fullOffset = signedOffset ( match [ cursor + 1 ] , match [ cursor + 2 ] ) ,
zone = local ? null : FixedOffsetZone . instance ( fullOffset ) ;
return [ { } , zone , cursor + 3 ] ;
}
function extractIANAZone ( match , cursor ) {
var zone = match [ cursor ] ? IANAZone . create ( match [ cursor ] ) : null ;
return [ { } , zone , cursor + 1 ] ;
} // ISO time parsing
var isoTimeOnly = RegExp ( "^T?" + isoTimeBaseRegex . source + "$" ) ; // ISO duration parsing
var isoDuration = /^-?P(?:(?:(-?\d{1,9})Y)?(?:(-?\d{1,9})M)?(?:(-?\d{1,9})W)?(?:(-?\d{1,9})D)?(?:T(?:(-?\d{1,9})H)?(?:(-?\d{1,9})M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,9}))?S)?)?)$/ ;
function extractISODuration ( match ) {
var s = match [ 0 ] ,
yearStr = match [ 1 ] ,
monthStr = match [ 2 ] ,
weekStr = match [ 3 ] ,
dayStr = match [ 4 ] ,
hourStr = match [ 5 ] ,
minuteStr = match [ 6 ] ,
secondStr = match [ 7 ] ,
millisecondsStr = match [ 8 ] ;
var hasNegativePrefix = s [ 0 ] === "-" ;
var negativeSeconds = secondStr && secondStr [ 0 ] === "-" ;
var maybeNegate = function maybeNegate ( num , force ) {
if ( force === void 0 ) {
force = false ;
}
return num !== undefined && ( force || num && hasNegativePrefix ) ? - num : num ;
} ;
return [ {
years : maybeNegate ( parseInteger ( yearStr ) ) ,
months : maybeNegate ( parseInteger ( monthStr ) ) ,
weeks : maybeNegate ( parseInteger ( weekStr ) ) ,
days : maybeNegate ( parseInteger ( dayStr ) ) ,
hours : maybeNegate ( parseInteger ( hourStr ) ) ,
minutes : maybeNegate ( parseInteger ( minuteStr ) ) ,
seconds : maybeNegate ( parseInteger ( secondStr ) , secondStr === "-0" ) ,
milliseconds : maybeNegate ( parseMillis ( millisecondsStr ) , negativeSeconds )
} ] ;
} // These are a little braindead. EDT *should* tell us that we're in, say, America/New_York
// and not just that we're in -240 *right now*. But since I don't think these are used that often
// I'm just going to ignore that
var obsOffsets = {
GMT : 0 ,
EDT : - 4 * 60 ,
EST : - 5 * 60 ,
CDT : - 5 * 60 ,
CST : - 6 * 60 ,
MDT : - 6 * 60 ,
MST : - 7 * 60 ,
PDT : - 7 * 60 ,
PST : - 8 * 60
} ;
function fromStrings ( weekdayStr , yearStr , monthStr , dayStr , hourStr , minuteStr , secondStr ) {
var result = {
year : yearStr . length === 2 ? untruncateYear ( parseInteger ( yearStr ) ) : parseInteger ( yearStr ) ,
month : monthsShort . indexOf ( monthStr ) + 1 ,
day : parseInteger ( dayStr ) ,
hour : parseInteger ( hourStr ) ,
minute : parseInteger ( minuteStr )
} ;
if ( secondStr ) result . second = parseInteger ( secondStr ) ;
if ( weekdayStr ) {
result . weekday = weekdayStr . length > 3 ? weekdaysLong . indexOf ( weekdayStr ) + 1 : weekdaysShort . indexOf ( weekdayStr ) + 1 ;
}
return result ;
} // RFC 2822/5322
var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/ ;
function extractRFC2822 ( match ) {
var weekdayStr = match [ 1 ] ,
dayStr = match [ 2 ] ,
monthStr = match [ 3 ] ,
yearStr = match [ 4 ] ,
hourStr = match [ 5 ] ,
minuteStr = match [ 6 ] ,
secondStr = match [ 7 ] ,
obsOffset = match [ 8 ] ,
milOffset = match [ 9 ] ,
offHourStr = match [ 10 ] ,
offMinuteStr = match [ 11 ] ,
result = fromStrings ( weekdayStr , yearStr , monthStr , dayStr , hourStr , minuteStr , secondStr ) ;
var offset ;
if ( obsOffset ) {
offset = obsOffsets [ obsOffset ] ;
} else if ( milOffset ) {
offset = 0 ;
} else {
offset = signedOffset ( offHourStr , offMinuteStr ) ;
}
return [ result , new FixedOffsetZone ( offset ) ] ;
}
function preprocessRFC2822 ( s ) {
// Remove comments and folding whitespace and replace multiple-spaces with a single space
return s . replace ( /\([^)]*\)|[\n\t]/g , " " ) . replace ( /(\s\s+)/g , " " ) . trim ( ) ;
} // http date
var rfc1123 = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/ ,
rfc850 = /^(Monday|Tuesday|Wedsday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/ ,
ascii = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/ ;
function extractRFC1123Or850 ( match ) {
var weekdayStr = match [ 1 ] ,
dayStr = match [ 2 ] ,
monthStr = match [ 3 ] ,
yearStr = match [ 4 ] ,
hourStr = match [ 5 ] ,
minuteStr = match [ 6 ] ,
secondStr = match [ 7 ] ,
result = fromStrings ( weekdayStr , yearStr , monthStr , dayStr , hourStr , minuteStr , secondStr ) ;
return [ result , FixedOffsetZone . utcInstance ] ;
}
function extractASCII ( match ) {
var weekdayStr = match [ 1 ] ,
monthStr = match [ 2 ] ,
dayStr = match [ 3 ] ,
hourStr = match [ 4 ] ,
minuteStr = match [ 5 ] ,
secondStr = match [ 6 ] ,
yearStr = match [ 7 ] ,
result = fromStrings ( weekdayStr , yearStr , monthStr , dayStr , hourStr , minuteStr , secondStr ) ;
return [ result , FixedOffsetZone . utcInstance ] ;
}
var isoYmdWithTimeExtensionRegex = combineRegexes ( isoYmdRegex , isoTimeExtensionRegex ) ;
var isoWeekWithTimeExtensionRegex = combineRegexes ( isoWeekRegex , isoTimeExtensionRegex ) ;
var isoOrdinalWithTimeExtensionRegex = combineRegexes ( isoOrdinalRegex , isoTimeExtensionRegex ) ;
var isoTimeCombinedRegex = combineRegexes ( isoTimeRegex ) ;
var extractISOYmdTimeAndOffset = combineExtractors ( extractISOYmd , extractISOTime , extractISOOffset ) ;
var extractISOWeekTimeAndOffset = combineExtractors ( extractISOWeekData , extractISOTime , extractISOOffset ) ;
var extractISOOrdinalDateAndTime = combineExtractors ( extractISOOrdinalData , extractISOTime , extractISOOffset ) ;
var extractISOTimeAndOffset = combineExtractors ( extractISOTime , extractISOOffset ) ;
/ * *
* @ private
* /
function parseISODate ( s ) {
return parse ( s , [ isoYmdWithTimeExtensionRegex , extractISOYmdTimeAndOffset ] , [ isoWeekWithTimeExtensionRegex , extractISOWeekTimeAndOffset ] , [ isoOrdinalWithTimeExtensionRegex , extractISOOrdinalDateAndTime ] , [ isoTimeCombinedRegex , extractISOTimeAndOffset ] ) ;
}
function parseRFC2822Date ( s ) {
return parse ( preprocessRFC2822 ( s ) , [ rfc2822 , extractRFC2822 ] ) ;
}
function parseHTTPDate ( s ) {
return parse ( s , [ rfc1123 , extractRFC1123Or850 ] , [ rfc850 , extractRFC1123Or850 ] , [ ascii , extractASCII ] ) ;
}
function parseISODuration ( s ) {
return parse ( s , [ isoDuration , extractISODuration ] ) ;
}
var extractISOTimeOnly = combineExtractors ( extractISOTime ) ;
function parseISOTimeOnly ( s ) {
return parse ( s , [ isoTimeOnly , extractISOTimeOnly ] ) ;
}
var sqlYmdWithTimeExtensionRegex = combineRegexes ( sqlYmdRegex , sqlTimeExtensionRegex ) ;
var sqlTimeCombinedRegex = combineRegexes ( sqlTimeRegex ) ;
var extractISOYmdTimeOffsetAndIANAZone = combineExtractors ( extractISOYmd , extractISOTime , extractISOOffset , extractIANAZone ) ;
var extractISOTimeOffsetAndIANAZone = combineExtractors ( extractISOTime , extractISOOffset , extractIANAZone ) ;
function parseSQL ( s ) {
return parse ( s , [ sqlYmdWithTimeExtensionRegex , extractISOYmdTimeOffsetAndIANAZone ] , [ sqlTimeCombinedRegex , extractISOTimeOffsetAndIANAZone ] ) ;
}
var INVALID$2 = "Invalid Duration" ; // unit conversion constants
var lowOrderMatrix = {
weeks : {
days : 7 ,
hours : 7 * 24 ,
minutes : 7 * 24 * 60 ,
seconds : 7 * 24 * 60 * 60 ,
milliseconds : 7 * 24 * 60 * 60 * 1000
} ,
days : {
hours : 24 ,
minutes : 24 * 60 ,
seconds : 24 * 60 * 60 ,
milliseconds : 24 * 60 * 60 * 1000
} ,
hours : {
minutes : 60 ,
seconds : 60 * 60 ,
milliseconds : 60 * 60 * 1000
} ,
minutes : {
seconds : 60 ,
milliseconds : 60 * 1000
} ,
seconds : {
milliseconds : 1000
}
} ,
casualMatrix = _extends ( {
years : {
quarters : 4 ,
months : 12 ,
weeks : 52 ,
days : 365 ,
hours : 365 * 24 ,
minutes : 365 * 24 * 60 ,
seconds : 365 * 24 * 60 * 60 ,
milliseconds : 365 * 24 * 60 * 60 * 1000
} ,
quarters : {
months : 3 ,
weeks : 13 ,
days : 91 ,
hours : 91 * 24 ,
minutes : 91 * 24 * 60 ,
seconds : 91 * 24 * 60 * 60 ,
milliseconds : 91 * 24 * 60 * 60 * 1000
} ,
months : {
weeks : 4 ,
days : 30 ,
hours : 30 * 24 ,
minutes : 30 * 24 * 60 ,
seconds : 30 * 24 * 60 * 60 ,
milliseconds : 30 * 24 * 60 * 60 * 1000
}
} , lowOrderMatrix ) ,
daysInYearAccurate = 146097.0 / 400 ,
daysInMonthAccurate = 146097.0 / 4800 ,
accurateMatrix = _extends ( {
years : {
quarters : 4 ,
months : 12 ,
weeks : daysInYearAccurate / 7 ,
days : daysInYearAccurate ,
hours : daysInYearAccurate * 24 ,
minutes : daysInYearAccurate * 24 * 60 ,
seconds : daysInYearAccurate * 24 * 60 * 60 ,
milliseconds : daysInYearAccurate * 24 * 60 * 60 * 1000
} ,
quarters : {
months : 3 ,
weeks : daysInYearAccurate / 28 ,
days : daysInYearAccurate / 4 ,
hours : daysInYearAccurate * 24 / 4 ,
minutes : daysInYearAccurate * 24 * 60 / 4 ,
seconds : daysInYearAccurate * 24 * 60 * 60 / 4 ,
milliseconds : daysInYearAccurate * 24 * 60 * 60 * 1000 / 4
} ,
months : {
weeks : daysInMonthAccurate / 7 ,
days : daysInMonthAccurate ,
hours : daysInMonthAccurate * 24 ,
minutes : daysInMonthAccurate * 24 * 60 ,
seconds : daysInMonthAccurate * 24 * 60 * 60 ,
milliseconds : daysInMonthAccurate * 24 * 60 * 60 * 1000
}
} , lowOrderMatrix ) ; // units ordered by size
var orderedUnits$1 = [ "years" , "quarters" , "months" , "weeks" , "days" , "hours" , "minutes" , "seconds" , "milliseconds" ] ;
var reverseUnits = orderedUnits$1 . slice ( 0 ) . reverse ( ) ; // clone really means "create another instance just like this one, but with these changes"
function clone$1 ( dur , alts , clear ) {
if ( clear === void 0 ) {
clear = false ;
}
// deep merge for vals
var conf = {
values : clear ? alts . values : _extends ( { } , dur . values , alts . values || { } ) ,
loc : dur . loc . clone ( alts . loc ) ,
conversionAccuracy : alts . conversionAccuracy || dur . conversionAccuracy
} ;
return new Duration ( conf ) ;
}
function antiTrunc ( n ) {
return n < 0 ? Math . floor ( n ) : Math . ceil ( n ) ;
} // NB: mutates parameters
function convert ( matrix , fromMap , fromUnit , toMap , toUnit ) {
var conv = matrix [ toUnit ] [ fromUnit ] ,
raw = fromMap [ fromUnit ] / conv ,
sameSign = Math . sign ( raw ) === Math . sign ( toMap [ toUnit ] ) ,
// ok, so this is wild, but see the matrix in the tests
added = ! sameSign && toMap [ toUnit ] !== 0 && Math . abs ( raw ) <= 1 ? antiTrunc ( raw ) : Math . trunc ( raw ) ;
toMap [ toUnit ] += added ;
fromMap [ fromUnit ] -= added * conv ;
} // NB: mutates parameters
function normalizeValues ( matrix , vals ) {
reverseUnits . reduce ( function ( previous , current ) {
if ( ! isUndefined ( vals [ current ] ) ) {
if ( previous ) {
convert ( matrix , vals , previous , vals , current ) ;
}
return current ;
} else {
return previous ;
}
} , null ) ;
}
/ * *
* A Duration object represents a period of time , like "2 months" or "1 day, 1 hour" . Conceptually , it ' s just a map of units to their quantities , accompanied by some additional configuration and methods for creating , parsing , interrogating , transforming , and formatting them . They can be used on their own or in conjunction with other Luxon types ; for example , you can use { @ link DateTime . plus } to add a Duration object to a DateTime , producing another DateTime .
*
* Here is a brief overview of commonly used methods and getters in Duration :
*
* * * * Creation * * To create a Duration , use { @ link Duration . fromMillis } , { @ link Duration . fromObject } , or { @ link Duration . fromISO } .
* * * * Unit values * * See the { @ link Duration # years } , { @ link Duration . months } , { @ link Duration # weeks } , { @ link Duration # days } , { @ link Duration # hours } , { @ link Duration # minutes } , { @ link Duration # seconds } , { @ link Duration # milliseconds } accessors .
* * * * Configuration * * See { @ link Duration # locale } and { @ link Duration # numberingSystem } accessors .
* * * * Transformation * * To create new Durations out of old ones use { @ link Duration # plus } , { @ link Duration # minus } , { @ link Duration # normalize } , { @ link Duration # set } , { @ link Duration # reconfigure } , { @ link Duration # shiftTo } , and { @ link Duration # negate } .
* * * * Output * * To convert the Duration into other representations , see { @ link Duration # as } , { @ link Duration # toISO } , { @ link Duration # toFormat } , and { @ link Duration # toJSON }
*
* There ' s are more methods documented below . In addition , for more information on subtler topics like internationalization and validity , see the external documentation .
* /
var Duration = /*#__PURE__*/ function ( ) {
/ * *
* @ private
* /
function Duration ( config ) {
var accurate = config . conversionAccuracy === "longterm" || false ;
/ * *
* @ access private
* /
this . values = config . values ;
/ * *
* @ access private
* /
this . loc = config . loc || Locale . create ( ) ;
/ * *
* @ access private
* /
this . conversionAccuracy = accurate ? "longterm" : "casual" ;
/ * *
* @ access private
* /
this . invalid = config . invalid || null ;
/ * *
* @ access private
* /
this . matrix = accurate ? accurateMatrix : casualMatrix ;
/ * *
* @ access private
* /
this . isLuxonDuration = true ;
}
/ * *
* Create Duration from a number of milliseconds .
* @ param { number } count of milliseconds
* @ param { Object } opts - options for parsing
* @ param { string } [ opts . locale = 'en-US' ] - the locale to use
* @ param { string } opts . numberingSystem - the numbering system to use
* @ param { string } [ opts . conversionAccuracy = 'casual' ] - the conversion system to use
* @ return { Duration }
* /
Duration . fromMillis = function fromMillis ( count , opts ) {
return Duration . fromObject ( {
milliseconds : count
} , opts ) ;
}
/ * *
* Create a Duration from a JavaScript object with keys like 'years' and 'hours' .
* If this object is empty then a zero milliseconds duration is returned .
* @ param { Object } obj - the object to create the DateTime from
* @ param { number } obj . years
* @ param { number } obj . quarters
* @ param { number } obj . months
* @ param { number } obj . weeks
* @ param { number } obj . days
* @ param { number } obj . hours
* @ param { number } obj . minutes
* @ param { number } obj . seconds
* @ param { number } obj . milliseconds
* @ param { Object } [ opts = [ ] ] - options for creating this Duration
* @ param { string } [ opts . locale = 'en-US' ] - the locale to use
* @ param { string } opts . numberingSystem - the numbering system to use
* @ param { string } [ opts . conversionAccuracy = 'casual' ] - the conversion system to use
* @ return { Duration }
* /
;
Duration . fromObject = function fromObject ( obj , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
if ( obj == null || typeof obj !== "object" ) {
throw new InvalidArgumentError ( "Duration.fromObject: argument expected to be an object, got " + ( obj === null ? "null" : typeof obj ) ) ;
}
return new Duration ( {
values : normalizeObject ( obj , Duration . normalizeUnit ) ,
loc : Locale . fromObject ( opts ) ,
conversionAccuracy : opts . conversionAccuracy
} ) ;
}
/ * *
* Create a Duration from an ISO 8601 duration string .
* @ param { string } text - text to parse
* @ param { Object } opts - options for parsing
* @ param { string } [ opts . locale = 'en-US' ] - the locale to use
* @ param { string } opts . numberingSystem - the numbering system to use
* @ param { string } [ opts . conversionAccuracy = 'casual' ] - the conversion system to use
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Durations
* @ example Duration . fromISO ( 'P3Y6M1W4DT12H30M5S' ) . toObject ( ) //=> { years: 3, months: 6, weeks: 1, days: 4, hours: 12, minutes: 30, seconds: 5 }
* @ example Duration . fromISO ( 'PT23H' ) . toObject ( ) //=> { hours: 23 }
* @ example Duration . fromISO ( 'P5Y3M' ) . toObject ( ) //=> { years: 5, months: 3 }
* @ return { Duration }
* /
;
Duration . fromISO = function fromISO ( text , opts ) {
var _parseISODuration = parseISODuration ( text ) ,
parsed = _parseISODuration [ 0 ] ;
if ( parsed ) {
return Duration . fromObject ( parsed , opts ) ;
} else {
return Duration . invalid ( "unparsable" , "the input \"" + text + "\" can't be parsed as ISO 8601" ) ;
}
}
/ * *
* Create a Duration from an ISO 8601 time string .
* @ param { string } text - text to parse
* @ param { Object } opts - options for parsing
* @ param { string } [ opts . locale = 'en-US' ] - the locale to use
* @ param { string } opts . numberingSystem - the numbering system to use
* @ param { string } [ opts . conversionAccuracy = 'casual' ] - the conversion system to use
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Times
* @ example Duration . fromISOTime ( '11:22:33.444' ) . toObject ( ) //=> { hours: 11, minutes: 22, seconds: 33, milliseconds: 444 }
* @ example Duration . fromISOTime ( '11:00' ) . toObject ( ) //=> { hours: 11, minutes: 0, seconds: 0 }
* @ example Duration . fromISOTime ( 'T11:00' ) . toObject ( ) //=> { hours: 11, minutes: 0, seconds: 0 }
* @ example Duration . fromISOTime ( '1100' ) . toObject ( ) //=> { hours: 11, minutes: 0, seconds: 0 }
* @ example Duration . fromISOTime ( 'T1100' ) . toObject ( ) //=> { hours: 11, minutes: 0, seconds: 0 }
* @ return { Duration }
* /
;
Duration . fromISOTime = function fromISOTime ( text , opts ) {
var _parseISOTimeOnly = parseISOTimeOnly ( text ) ,
parsed = _parseISOTimeOnly [ 0 ] ;
if ( parsed ) {
return Duration . fromObject ( parsed , opts ) ;
} else {
return Duration . invalid ( "unparsable" , "the input \"" + text + "\" can't be parsed as ISO 8601" ) ;
}
}
/ * *
* Create an invalid Duration .
* @ param { string } reason - simple string of why this datetime is invalid . Should not contain parameters or anything else data - dependent
* @ param { string } [ explanation = null ] - longer explanation , may include parameters and other useful debugging information
* @ return { Duration }
* /
;
Duration . invalid = function invalid ( reason , explanation ) {
if ( explanation === void 0 ) {
explanation = null ;
}
if ( ! reason ) {
throw new InvalidArgumentError ( "need to specify a reason the Duration is invalid" ) ;
}
var invalid = reason instanceof Invalid ? reason : new Invalid ( reason , explanation ) ;
if ( Settings . throwOnInvalid ) {
throw new InvalidDurationError ( invalid ) ;
} else {
return new Duration ( {
invalid : invalid
} ) ;
}
}
/ * *
* @ private
* /
;
Duration . normalizeUnit = function normalizeUnit ( unit ) {
var normalized = {
year : "years" ,
years : "years" ,
quarter : "quarters" ,
quarters : "quarters" ,
month : "months" ,
months : "months" ,
week : "weeks" ,
weeks : "weeks" ,
day : "days" ,
days : "days" ,
hour : "hours" ,
hours : "hours" ,
minute : "minutes" ,
minutes : "minutes" ,
second : "seconds" ,
seconds : "seconds" ,
millisecond : "milliseconds" ,
milliseconds : "milliseconds"
} [ unit ? unit . toLowerCase ( ) : unit ] ;
if ( ! normalized ) throw new InvalidUnitError ( unit ) ;
return normalized ;
}
/ * *
* Check if an object is a Duration . Works across context boundaries
* @ param { object } o
* @ return { boolean }
* /
;
Duration . isDuration = function isDuration ( o ) {
return o && o . isLuxonDuration || false ;
}
/ * *
* Get the locale of a Duration , such 'en-GB'
* @ type { string }
* /
;
var _proto = Duration . prototype ;
/ * *
* Returns a string representation of this Duration formatted according to the specified format string . You may use these tokens :
* * ` S ` for milliseconds
* * ` s ` for seconds
* * ` m ` for minutes
* * ` h ` for hours
* * ` d ` for days
* * ` M ` for months
* * ` y ` for years
* Notes :
* * Add padding by repeating the token , e . g . "yy" pads the years to two digits , "hhhh" pads the hours out to four digits
* * The duration will be converted to the set of units in the format string using { @ link Duration . shiftTo } and the Durations ' s conversion accuracy setting .
* @ param { string } fmt - the format string
* @ param { Object } opts - options
* @ param { boolean } [ opts . floor = true ] - floor numerical values
* @ example Duration . fromObject ( { years : 1 , days : 6 , seconds : 2 } ) . toFormat ( "y d s" ) //=> "1 6 2"
* @ example Duration . fromObject ( { years : 1 , days : 6 , seconds : 2 } ) . toFormat ( "yy dd sss" ) //=> "01 06 002"
* @ example Duration . fromObject ( { years : 1 , days : 6 , seconds : 2 } ) . toFormat ( "M S" ) //=> "12 518402000"
* @ return { string }
* /
_proto . toFormat = function toFormat ( fmt , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
// reverse-compat since 1.2; we always round down now, never up, and we do it by default
var fmtOpts = _extends ( { } , opts , {
floor : opts . round !== false && opts . floor !== false
} ) ;
return this . isValid ? Formatter . create ( this . loc , fmtOpts ) . formatDurationFromString ( this , fmt ) : INVALID$2 ;
}
/ * *
* Returns a JavaScript object with this Duration ' s values .
* @ example Duration . fromObject ( { years : 1 , days : 6 , seconds : 2 } ) . toObject ( ) //=> { years: 1, days: 6, seconds: 2 }
* @ return { Object }
* /
;
_proto . toObject = function toObject ( ) {
if ( ! this . isValid ) return { } ;
return _extends ( { } , this . values ) ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of this Duration .
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Durations
* @ example Duration . fromObject ( { years : 3 , seconds : 45 } ) . toISO ( ) //=> 'P3YT45S'
* @ example Duration . fromObject ( { months : 4 , seconds : 45 } ) . toISO ( ) //=> 'P4MT45S'
* @ example Duration . fromObject ( { months : 5 } ) . toISO ( ) //=> 'P5M'
* @ example Duration . fromObject ( { minutes : 5 } ) . toISO ( ) //=> 'PT5M'
* @ example Duration . fromObject ( { milliseconds : 6 } ) . toISO ( ) //=> 'PT0.006S'
* @ return { string }
* /
;
_proto . toISO = function toISO ( ) {
// we could use the formatter, but this is an easier way to get the minimum string
if ( ! this . isValid ) return null ;
var s = "P" ;
if ( this . years !== 0 ) s += this . years + "Y" ;
if ( this . months !== 0 || this . quarters !== 0 ) s += this . months + this . quarters * 3 + "M" ;
if ( this . weeks !== 0 ) s += this . weeks + "W" ;
if ( this . days !== 0 ) s += this . days + "D" ;
if ( this . hours !== 0 || this . minutes !== 0 || this . seconds !== 0 || this . milliseconds !== 0 ) s += "T" ;
if ( this . hours !== 0 ) s += this . hours + "H" ;
if ( this . minutes !== 0 ) s += this . minutes + "M" ;
if ( this . seconds !== 0 || this . milliseconds !== 0 ) // this will handle "floating point madness" by removing extra decimal places
// https://stackoverflow.com/questions/588004/is-floating-point-math-broken
s += roundTo ( this . seconds + this . milliseconds / 1000 , 3 ) + "S" ;
if ( s === "P" ) s += "T0S" ;
return s ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of this Duration , formatted as a time of day .
* Note that this will return null if the duration is invalid , negative , or equal to or greater than 24 hours .
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Times
* @ param { Object } opts - options
* @ param { boolean } [ opts . suppressMilliseconds = false ] - exclude milliseconds from the format if they ' re 0
* @ param { boolean } [ opts . suppressSeconds = false ] - exclude seconds from the format if they ' re 0
* @ param { boolean } [ opts . includePrefix = false ] - include the ` T ` prefix
* @ param { string } [ opts . format = 'extended' ] - choose between the basic and extended format
* @ example Duration . fromObject ( { hours : 11 } ) . toISOTime ( ) //=> '11:00:00.000'
* @ example Duration . fromObject ( { hours : 11 } ) . toISOTime ( { suppressMilliseconds : true } ) //=> '11:00:00'
* @ example Duration . fromObject ( { hours : 11 } ) . toISOTime ( { suppressSeconds : true } ) //=> '11:00'
* @ example Duration . fromObject ( { hours : 11 } ) . toISOTime ( { includePrefix : true } ) //=> 'T11:00:00.000'
* @ example Duration . fromObject ( { hours : 11 } ) . toISOTime ( { format : 'basic' } ) //=> '110000.000'
* @ return { string }
* /
;
_proto . toISOTime = function toISOTime ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
if ( ! this . isValid ) return null ;
var millis = this . toMillis ( ) ;
if ( millis < 0 || millis >= 86400000 ) return null ;
opts = _extends ( {
suppressMilliseconds : false ,
suppressSeconds : false ,
includePrefix : false ,
format : "extended"
} , opts ) ;
var value = this . shiftTo ( "hours" , "minutes" , "seconds" , "milliseconds" ) ;
var fmt = opts . format === "basic" ? "hhmm" : "hh:mm" ;
if ( ! opts . suppressSeconds || value . seconds !== 0 || value . milliseconds !== 0 ) {
fmt += opts . format === "basic" ? "ss" : ":ss" ;
if ( ! opts . suppressMilliseconds || value . milliseconds !== 0 ) {
fmt += ".SSS" ;
}
}
var str = value . toFormat ( fmt ) ;
if ( opts . includePrefix ) {
str = "T" + str ;
}
return str ;
}
/ * *
* Returns an ISO 8601 representation of this Duration appropriate for use in JSON .
* @ return { string }
* /
;
_proto . toJSON = function toJSON ( ) {
return this . toISO ( ) ;
}
/ * *
* Returns an ISO 8601 representation of this Duration appropriate for use in debugging .
* @ return { string }
* /
;
_proto . toString = function toString ( ) {
return this . toISO ( ) ;
}
/ * *
* Returns an milliseconds value of this Duration .
* @ return { number }
* /
;
_proto . toMillis = function toMillis ( ) {
return this . as ( "milliseconds" ) ;
}
/ * *
* Returns an milliseconds value of this Duration . Alias of { @ link toMillis }
* @ return { number }
* /
;
_proto . valueOf = function valueOf ( ) {
return this . toMillis ( ) ;
}
/ * *
* Make this Duration longer by the specified amount . Return a newly - constructed Duration .
* @ param { Duration | Object | number } duration - The amount to add . Either a Luxon Duration , a number of milliseconds , the object argument to Duration . fromObject ( )
* @ return { Duration }
* /
;
_proto . plus = function plus ( duration ) {
if ( ! this . isValid ) return this ;
var dur = friendlyDuration ( duration ) ,
result = { } ;
for ( var _iterator = _createForOfIteratorHelperLoose ( orderedUnits$1 ) , _step ; ! ( _step = _iterator ( ) ) . done ; ) {
var k = _step . value ;
if ( hasOwnProperty ( dur . values , k ) || hasOwnProperty ( this . values , k ) ) {
result [ k ] = dur . get ( k ) + this . get ( k ) ;
}
}
return clone$1 ( this , {
values : result
} , true ) ;
}
/ * *
* Make this Duration shorter by the specified amount . Return a newly - constructed Duration .
* @ param { Duration | Object | number } duration - The amount to subtract . Either a Luxon Duration , a number of milliseconds , the object argument to Duration . fromObject ( )
* @ return { Duration }
* /
;
_proto . minus = function minus ( duration ) {
if ( ! this . isValid ) return this ;
var dur = friendlyDuration ( duration ) ;
return this . plus ( dur . negate ( ) ) ;
}
/ * *
* Scale this Duration by the specified amount . Return a newly - constructed Duration .
* @ param { function } fn - The function to apply to each unit . Arity is 1 or 2 : the value of the unit and , optionally , the unit name . Must return a number .
* @ example Duration . fromObject ( { hours : 1 , minutes : 30 } ) . mapUnits ( x => x * 2 ) //=> { hours: 2, minutes: 60 }
* @ example Duration . fromObject ( { hours : 1 , minutes : 30 } ) . mapUnits ( ( x , u ) => u === "hour" ? x * 2 : x ) //=> { hours: 2, minutes: 30 }
* @ return { Duration }
* /
;
_proto . mapUnits = function mapUnits ( fn ) {
if ( ! this . isValid ) return this ;
var result = { } ;
for ( var _i = 0 , _Object$keys = Object . keys ( this . values ) ; _i < _Object$keys . length ; _i ++ ) {
var k = _Object$keys [ _i ] ;
result [ k ] = asNumber ( fn ( this . values [ k ] , k ) ) ;
}
return clone$1 ( this , {
values : result
} , true ) ;
}
/ * *
* Get the value of unit .
* @ param { string } unit - a unit such as 'minute' or 'day'
* @ example Duration . fromObject ( { years : 2 , days : 3 } ) . get ( 'years' ) //=> 2
* @ example Duration . fromObject ( { years : 2 , days : 3 } ) . get ( 'months' ) //=> 0
* @ example Duration . fromObject ( { years : 2 , days : 3 } ) . get ( 'days' ) //=> 3
* @ return { number }
* /
;
_proto . get = function get ( unit ) {
return this [ Duration . normalizeUnit ( unit ) ] ;
}
/ * *
* "Set" the values of specified units . Return a newly - constructed Duration .
* @ param { Object } values - a mapping of units to numbers
* @ example dur . set ( { years : 2017 } )
* @ example dur . set ( { hours : 8 , minutes : 30 } )
* @ return { Duration }
* /
;
_proto . set = function set ( values ) {
if ( ! this . isValid ) return this ;
var mixed = _extends ( { } , this . values , normalizeObject ( values , Duration . normalizeUnit ) ) ;
return clone$1 ( this , {
values : mixed
} ) ;
}
/ * *
* "Set" the locale and / or numberingSystem . Returns a newly - constructed Duration .
* @ example dur . reconfigure ( { locale : 'en-GB' } )
* @ return { Duration }
* /
;
_proto . reconfigure = function reconfigure ( _temp ) {
var _ref = _temp === void 0 ? { } : _temp ,
locale = _ref . locale ,
numberingSystem = _ref . numberingSystem ,
conversionAccuracy = _ref . conversionAccuracy ;
var loc = this . loc . clone ( {
locale : locale ,
numberingSystem : numberingSystem
} ) ,
opts = {
loc : loc
} ;
if ( conversionAccuracy ) {
opts . conversionAccuracy = conversionAccuracy ;
}
return clone$1 ( this , opts ) ;
}
/ * *
* Return the length of the duration in the specified unit .
* @ param { string } unit - a unit such as 'minutes' or 'days'
* @ example Duration . fromObject ( { years : 1 } ) . as ( 'days' ) //=> 365
* @ example Duration . fromObject ( { years : 1 } ) . as ( 'months' ) //=> 12
* @ example Duration . fromObject ( { hours : 60 } ) . as ( 'days' ) //=> 2.5
* @ return { number }
* /
;
_proto . as = function as ( unit ) {
return this . isValid ? this . shiftTo ( unit ) . get ( unit ) : NaN ;
}
/ * *
* Reduce this Duration to its canonical representation in its current units .
* @ example Duration . fromObject ( { years : 2 , days : 5000 } ) . normalize ( ) . toObject ( ) //=> { years: 15, days: 255 }
* @ example Duration . fromObject ( { hours : 12 , minutes : - 45 } ) . normalize ( ) . toObject ( ) //=> { hours: 11, minutes: 15 }
* @ return { Duration }
* /
;
_proto . normalize = function normalize ( ) {
if ( ! this . isValid ) return this ;
var vals = this . toObject ( ) ;
normalizeValues ( this . matrix , vals ) ;
return clone$1 ( this , {
values : vals
} , true ) ;
}
/ * *
* Convert this Duration into its representation in a different set of units .
* @ example Duration . fromObject ( { hours : 1 , seconds : 30 } ) . shiftTo ( 'minutes' , 'milliseconds' ) . toObject ( ) //=> { minutes: 60, milliseconds: 30000 }
* @ return { Duration }
* /
;
_proto . shiftTo = function shiftTo ( ) {
for ( var _len = arguments . length , units = new Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
units [ _key ] = arguments [ _key ] ;
}
if ( ! this . isValid ) return this ;
if ( units . length === 0 ) {
return this ;
}
units = units . map ( function ( u ) {
return Duration . normalizeUnit ( u ) ;
} ) ;
var built = { } ,
accumulated = { } ,
vals = this . toObject ( ) ;
var lastUnit ;
for ( var _iterator2 = _createForOfIteratorHelperLoose ( orderedUnits$1 ) , _step2 ; ! ( _step2 = _iterator2 ( ) ) . done ; ) {
var k = _step2 . value ;
if ( units . indexOf ( k ) >= 0 ) {
lastUnit = k ;
var own = 0 ; // anything we haven't boiled down yet should get boiled to this unit
for ( var ak in accumulated ) {
own += this . matrix [ ak ] [ k ] * accumulated [ ak ] ;
accumulated [ ak ] = 0 ;
} // plus anything that's already in this unit
if ( isNumber ( vals [ k ] ) ) {
own += vals [ k ] ;
}
var i = Math . trunc ( own ) ;
built [ k ] = i ;
accumulated [ k ] = own - i ; // we'd like to absorb these fractions in another unit
// plus anything further down the chain that should be rolled up in to this
for ( var down in vals ) {
if ( orderedUnits$1 . indexOf ( down ) > orderedUnits$1 . indexOf ( k ) ) {
convert ( this . matrix , vals , down , built , k ) ;
}
} // otherwise, keep it in the wings to boil it later
} else if ( isNumber ( vals [ k ] ) ) {
accumulated [ k ] = vals [ k ] ;
}
} // anything leftover becomes the decimal for the last unit
// lastUnit must be defined since units is not empty
for ( var key in accumulated ) {
if ( accumulated [ key ] !== 0 ) {
built [ lastUnit ] += key === lastUnit ? accumulated [ key ] : accumulated [ key ] / this . matrix [ lastUnit ] [ key ] ;
}
}
return clone$1 ( this , {
values : built
} , true ) . normalize ( ) ;
}
/ * *
* Return the negative of this Duration .
* @ example Duration . fromObject ( { hours : 1 , seconds : 30 } ) . negate ( ) . toObject ( ) //=> { hours: -1, seconds: -30 }
* @ return { Duration }
* /
;
_proto . negate = function negate ( ) {
if ( ! this . isValid ) return this ;
var negated = { } ;
for ( var _i2 = 0 , _Object$keys2 = Object . keys ( this . values ) ; _i2 < _Object$keys2 . length ; _i2 ++ ) {
var k = _Object$keys2 [ _i2 ] ;
negated [ k ] = - this . values [ k ] ;
}
return clone$1 ( this , {
values : negated
} , true ) ;
}
/ * *
* Get the years .
* @ type { number }
* /
;
/ * *
* Equality check
* Two Durations are equal iff they have the same units and the same values for each unit .
* @ param { Duration } other
* @ return { boolean }
* /
_proto . equals = function equals ( other ) {
if ( ! this . isValid || ! other . isValid ) {
return false ;
}
if ( ! this . loc . equals ( other . loc ) ) {
return false ;
}
function eq ( v1 , v2 ) {
// Consider 0 and undefined as equal
if ( v1 === undefined || v1 === 0 ) return v2 === undefined || v2 === 0 ;
return v1 === v2 ;
}
for ( var _iterator3 = _createForOfIteratorHelperLoose ( orderedUnits$1 ) , _step3 ; ! ( _step3 = _iterator3 ( ) ) . done ; ) {
var u = _step3 . value ;
if ( ! eq ( this . values [ u ] , other . values [ u ] ) ) {
return false ;
}
}
return true ;
} ;
_createClass ( Duration , [ {
key : "locale" ,
get : function get ( ) {
return this . isValid ? this . loc . locale : null ;
}
/ * *
* Get the numbering system of a Duration , such 'beng' . The numbering system is used when formatting the Duration
*
* @ type { string }
* /
} , {
key : "numberingSystem" ,
get : function get ( ) {
return this . isValid ? this . loc . numberingSystem : null ;
}
} , {
key : "years" ,
get : function get ( ) {
return this . isValid ? this . values . years || 0 : NaN ;
}
/ * *
* Get the quarters .
* @ type { number }
* /
} , {
key : "quarters" ,
get : function get ( ) {
return this . isValid ? this . values . quarters || 0 : NaN ;
}
/ * *
* Get the months .
* @ type { number }
* /
} , {
key : "months" ,
get : function get ( ) {
return this . isValid ? this . values . months || 0 : NaN ;
}
/ * *
* Get the weeks
* @ type { number }
* /
} , {
key : "weeks" ,
get : function get ( ) {
return this . isValid ? this . values . weeks || 0 : NaN ;
}
/ * *
* Get the days .
* @ type { number }
* /
} , {
key : "days" ,
get : function get ( ) {
return this . isValid ? this . values . days || 0 : NaN ;
}
/ * *
* Get the hours .
* @ type { number }
* /
} , {
key : "hours" ,
get : function get ( ) {
return this . isValid ? this . values . hours || 0 : NaN ;
}
/ * *
* Get the minutes .
* @ type { number }
* /
} , {
key : "minutes" ,
get : function get ( ) {
return this . isValid ? this . values . minutes || 0 : NaN ;
}
/ * *
* Get the seconds .
* @ return { number }
* /
} , {
key : "seconds" ,
get : function get ( ) {
return this . isValid ? this . values . seconds || 0 : NaN ;
}
/ * *
* Get the milliseconds .
* @ return { number }
* /
} , {
key : "milliseconds" ,
get : function get ( ) {
return this . isValid ? this . values . milliseconds || 0 : NaN ;
}
/ * *
* Returns whether the Duration is invalid . Invalid durations are returned by diff operations
* on invalid DateTimes or Intervals .
* @ return { boolean }
* /
} , {
key : "isValid" ,
get : function get ( ) {
return this . invalid === null ;
}
/ * *
* Returns an error code if this Duration became invalid , or null if the Duration is valid
* @ return { string }
* /
} , {
key : "invalidReason" ,
get : function get ( ) {
return this . invalid ? this . invalid . reason : null ;
}
/ * *
* Returns an explanation of why this Duration became invalid , or null if the Duration is valid
* @ type { string }
* /
} , {
key : "invalidExplanation" ,
get : function get ( ) {
return this . invalid ? this . invalid . explanation : null ;
}
} ] ) ;
return Duration ;
} ( ) ;
function friendlyDuration ( durationish ) {
if ( isNumber ( durationish ) ) {
return Duration . fromMillis ( durationish ) ;
} else if ( Duration . isDuration ( durationish ) ) {
return durationish ;
} else if ( typeof durationish === "object" ) {
return Duration . fromObject ( durationish ) ;
} else {
throw new InvalidArgumentError ( "Unknown duration argument " + durationish + " of type " + typeof durationish ) ;
}
}
var INVALID$1 = "Invalid Interval" ; // checks if the start is equal to or before the end
function validateStartEnd ( start , end ) {
if ( ! start || ! start . isValid ) {
return Interval . invalid ( "missing or invalid start" ) ;
} else if ( ! end || ! end . isValid ) {
return Interval . invalid ( "missing or invalid end" ) ;
} else if ( end < start ) {
return Interval . invalid ( "end before start" , "The end of an interval must be after its start, but you had start=" + start . toISO ( ) + " and end=" + end . toISO ( ) ) ;
} else {
return null ;
}
}
/ * *
* An Interval object represents a half - open interval of time , where each endpoint is a { @ link DateTime } . Conceptually , it ' s a container for those two endpoints , accompanied by methods for creating , parsing , interrogating , comparing , transforming , and formatting them .
*
* Here is a brief overview of the most commonly used methods and getters in Interval :
*
* * * * Creation * * To create an Interval , use { @ link Interval . fromDateTimes } , { @ link Interval . after } , { @ link Interval . before } , or { @ link Interval . fromISO } .
* * * * Accessors * * Use { @ link Interval # start } and { @ link Interval # end } to get the start and end .
* * * * Interrogation * * To analyze the Interval , use { @ link Interval # count } , { @ link Interval # length } , { @ link Interval # hasSame } , { @ link Interval # contains } , { @ link Interval # isAfter } , or { @ link Interval # isBefore } .
* * * * Transformation * * To create other Intervals out of this one , use { @ link Interval # set } , { @ link Interval # splitAt } , { @ link Interval # splitBy } , { @ link Interval # divideEqually } , { @ link Interval # merge } , { @ link Interval # xor } , { @ link Interval # union } , { @ link Interval # intersection } , or { @ link Interval # difference } .
* * * * Comparison * * To compare this Interval to another one , use { @ link Interval # equals } , { @ link Interval # overlaps } , { @ link Interval # abutsStart } , { @ link Interval # abutsEnd } , { @ link Interval # engulfs }
* * * * Output * * To convert the Interval into other representations , see { @ link Interval # toString } , { @ link Interval # toISO } , { @ link Interval # toISODate } , { @ link Interval # toISOTime } , { @ link Interval # toFormat } , and { @ link Interval # toDuration } .
* /
var Interval = /*#__PURE__*/ function ( ) {
/ * *
* @ private
* /
function Interval ( config ) {
/ * *
* @ access private
* /
this . s = config . start ;
/ * *
* @ access private
* /
this . e = config . end ;
/ * *
* @ access private
* /
this . invalid = config . invalid || null ;
/ * *
* @ access private
* /
this . isLuxonInterval = true ;
}
/ * *
* Create an invalid Interval .
* @ param { string } reason - simple string of why this Interval is invalid . Should not contain parameters or anything else data - dependent
* @ param { string } [ explanation = null ] - longer explanation , may include parameters and other useful debugging information
* @ return { Interval }
* /
Interval . invalid = function invalid ( reason , explanation ) {
if ( explanation === void 0 ) {
explanation = null ;
}
if ( ! reason ) {
throw new InvalidArgumentError ( "need to specify a reason the Interval is invalid" ) ;
}
var invalid = reason instanceof Invalid ? reason : new Invalid ( reason , explanation ) ;
if ( Settings . throwOnInvalid ) {
throw new InvalidIntervalError ( invalid ) ;
} else {
return new Interval ( {
invalid : invalid
} ) ;
}
}
/ * *
* Create an Interval from a start DateTime and an end DateTime . Inclusive of the start but not the end .
* @ param { DateTime | Date | Object } start
* @ param { DateTime | Date | Object } end
* @ return { Interval }
* /
;
Interval . fromDateTimes = function fromDateTimes ( start , end ) {
var builtStart = friendlyDateTime ( start ) ,
builtEnd = friendlyDateTime ( end ) ;
var validateError = validateStartEnd ( builtStart , builtEnd ) ;
if ( validateError == null ) {
return new Interval ( {
start : builtStart ,
end : builtEnd
} ) ;
} else {
return validateError ;
}
}
/ * *
* Create an Interval from a start DateTime and a Duration to extend to .
* @ param { DateTime | Date | Object } start
* @ param { Duration | Object | number } duration - the length of the Interval .
* @ return { Interval }
* /
;
Interval . after = function after ( start , duration ) {
var dur = friendlyDuration ( duration ) ,
dt = friendlyDateTime ( start ) ;
return Interval . fromDateTimes ( dt , dt . plus ( dur ) ) ;
}
/ * *
* Create an Interval from an end DateTime and a Duration to extend backwards to .
* @ param { DateTime | Date | Object } end
* @ param { Duration | Object | number } duration - the length of the Interval .
* @ return { Interval }
* /
;
Interval . before = function before ( end , duration ) {
var dur = friendlyDuration ( duration ) ,
dt = friendlyDateTime ( end ) ;
return Interval . fromDateTimes ( dt . minus ( dur ) , dt ) ;
}
/ * *
* Create an Interval from an ISO 8601 string .
* Accepts ` <start>/<end> ` , ` <start>/<duration> ` , and ` <duration>/<end> ` formats .
* @ param { string } text - the ISO string to parse
* @ param { Object } [ opts ] - options to pass { @ link DateTime . fromISO } and optionally { @ link Duration . fromISO }
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Time_intervals
* @ return { Interval }
* /
;
Interval . fromISO = function fromISO ( text , opts ) {
var _split = ( text || "" ) . split ( "/" , 2 ) ,
s = _split [ 0 ] ,
e = _split [ 1 ] ;
if ( s && e ) {
var start , startIsValid ;
try {
start = DateTime . fromISO ( s , opts ) ;
startIsValid = start . isValid ;
} catch ( e ) {
startIsValid = false ;
}
var end , endIsValid ;
try {
end = DateTime . fromISO ( e , opts ) ;
endIsValid = end . isValid ;
} catch ( e ) {
endIsValid = false ;
}
if ( startIsValid && endIsValid ) {
return Interval . fromDateTimes ( start , end ) ;
}
if ( startIsValid ) {
var dur = Duration . fromISO ( e , opts ) ;
if ( dur . isValid ) {
return Interval . after ( start , dur ) ;
}
} else if ( endIsValid ) {
var _dur = Duration . fromISO ( s , opts ) ;
if ( _dur . isValid ) {
return Interval . before ( end , _dur ) ;
}
}
}
return Interval . invalid ( "unparsable" , "the input \"" + text + "\" can't be parsed as ISO 8601" ) ;
}
/ * *
* Check if an object is an Interval . Works across context boundaries
* @ param { object } o
* @ return { boolean }
* /
;
Interval . isInterval = function isInterval ( o ) {
return o && o . isLuxonInterval || false ;
}
/ * *
* Returns the start of the Interval
* @ type { DateTime }
* /
;
var _proto = Interval . prototype ;
/ * *
* Returns the length of the Interval in the specified unit .
* @ param { string } unit - the unit ( such as 'hours' or 'days' ) to return the length in .
* @ return { number }
* /
_proto . length = function length ( unit ) {
if ( unit === void 0 ) {
unit = "milliseconds" ;
}
return this . isValid ? this . toDuration . apply ( this , [ unit ] ) . get ( unit ) : NaN ;
}
/ * *
* Returns the count of minutes , hours , days , months , or years included in the Interval , even in part .
* Unlike { @ link Interval # length } this counts sections of the calendar , not periods of time , e . g . specifying 'day'
* asks 'what dates are included in this interval?' , not 'how many days long is this interval?'
* @ param { string } [ unit = 'milliseconds' ] - the unit of time to count .
* @ return { number }
* /
;
_proto . count = function count ( unit ) {
if ( unit === void 0 ) {
unit = "milliseconds" ;
}
if ( ! this . isValid ) return NaN ;
var start = this . start . startOf ( unit ) ,
end = this . end . startOf ( unit ) ;
return Math . floor ( end . diff ( start , unit ) . get ( unit ) ) + 1 ;
}
/ * *
* Returns whether this Interval ' s start and end are both in the same unit of time
* @ param { string } unit - the unit of time to check sameness on
* @ return { boolean }
* /
;
_proto . hasSame = function hasSame ( unit ) {
return this . isValid ? this . isEmpty ( ) || this . e . minus ( 1 ) . hasSame ( this . s , unit ) : false ;
}
/ * *
* Return whether this Interval has the same start and end DateTimes .
* @ return { boolean }
* /
;
_proto . isEmpty = function isEmpty ( ) {
return this . s . valueOf ( ) === this . e . valueOf ( ) ;
}
/ * *
* Return whether this Interval ' s start is after the specified DateTime .
* @ param { DateTime } dateTime
* @ return { boolean }
* /
;
_proto . isAfter = function isAfter ( dateTime ) {
if ( ! this . isValid ) return false ;
return this . s > dateTime ;
}
/ * *
* Return whether this Interval ' s end is before the specified DateTime .
* @ param { DateTime } dateTime
* @ return { boolean }
* /
;
_proto . isBefore = function isBefore ( dateTime ) {
if ( ! this . isValid ) return false ;
return this . e <= dateTime ;
}
/ * *
* Return whether this Interval contains the specified DateTime .
* @ param { DateTime } dateTime
* @ return { boolean }
* /
;
_proto . contains = function contains ( dateTime ) {
if ( ! this . isValid ) return false ;
return this . s <= dateTime && this . e > dateTime ;
}
/ * *
* "Sets" the start and / or end dates . Returns a newly - constructed Interval .
* @ param { Object } values - the values to set
* @ param { DateTime } values . start - the starting DateTime
* @ param { DateTime } values . end - the ending DateTime
* @ return { Interval }
* /
;
_proto . set = function set ( _temp ) {
var _ref = _temp === void 0 ? { } : _temp ,
start = _ref . start ,
end = _ref . end ;
if ( ! this . isValid ) return this ;
return Interval . fromDateTimes ( start || this . s , end || this . e ) ;
}
/ * *
* Split this Interval at each of the specified DateTimes
* @ param { ... DateTime } dateTimes - the unit of time to count .
* @ return { Array }
* /
;
_proto . splitAt = function splitAt ( ) {
var _this = this ;
if ( ! this . isValid ) return [ ] ;
for ( var _len = arguments . length , dateTimes = new Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
dateTimes [ _key ] = arguments [ _key ] ;
}
var sorted = dateTimes . map ( friendlyDateTime ) . filter ( function ( d ) {
return _this . contains ( d ) ;
} ) . sort ( ) ,
results = [ ] ;
var s = this . s ,
i = 0 ;
while ( s < this . e ) {
var added = sorted [ i ] || this . e ,
next = + added > + this . e ? this . e : added ;
results . push ( Interval . fromDateTimes ( s , next ) ) ;
s = next ;
i += 1 ;
}
return results ;
}
/ * *
* Split this Interval into smaller Intervals , each of the specified length .
* Left over time is grouped into a smaller interval
* @ param { Duration | Object | number } duration - The length of each resulting interval .
* @ return { Array }
* /
;
_proto . splitBy = function splitBy ( duration ) {
var dur = friendlyDuration ( duration ) ;
if ( ! this . isValid || ! dur . isValid || dur . as ( "milliseconds" ) === 0 ) {
return [ ] ;
}
var s = this . s ,
idx = 1 ,
next ;
var results = [ ] ;
while ( s < this . e ) {
var added = this . start . plus ( dur . mapUnits ( function ( x ) {
return x * idx ;
} ) ) ;
next = + added > + this . e ? this . e : added ;
results . push ( Interval . fromDateTimes ( s , next ) ) ;
s = next ;
idx += 1 ;
}
return results ;
}
/ * *
* Split this Interval into the specified number of smaller intervals .
* @ param { number } numberOfParts - The number of Intervals to divide the Interval into .
* @ return { Array }
* /
;
_proto . divideEqually = function divideEqually ( numberOfParts ) {
if ( ! this . isValid ) return [ ] ;
return this . splitBy ( this . length ( ) / numberOfParts ) . slice ( 0 , numberOfParts ) ;
}
/ * *
* Return whether this Interval overlaps with the specified Interval
* @ param { Interval } other
* @ return { boolean }
* /
;
_proto . overlaps = function overlaps ( other ) {
return this . e > other . s && this . s < other . e ;
}
/ * *
* Return whether this Interval 's end is adjacent to the specified Interval' s start .
* @ param { Interval } other
* @ return { boolean }
* /
;
_proto . abutsStart = function abutsStart ( other ) {
if ( ! this . isValid ) return false ;
return + this . e === + other . s ;
}
/ * *
* Return whether this Interval 's start is adjacent to the specified Interval' s end .
* @ param { Interval } other
* @ return { boolean }
* /
;
_proto . abutsEnd = function abutsEnd ( other ) {
if ( ! this . isValid ) return false ;
return + other . e === + this . s ;
}
/ * *
* Return whether this Interval engulfs the start and end of the specified Interval .
* @ param { Interval } other
* @ return { boolean }
* /
;
_proto . engulfs = function engulfs ( other ) {
if ( ! this . isValid ) return false ;
return this . s <= other . s && this . e >= other . e ;
}
/ * *
* Return whether this Interval has the same start and end as the specified Interval .
* @ param { Interval } other
* @ return { boolean }
* /
;
_proto . equals = function equals ( other ) {
if ( ! this . isValid || ! other . isValid ) {
return false ;
}
return this . s . equals ( other . s ) && this . e . equals ( other . e ) ;
}
/ * *
* Return an Interval representing the intersection of this Interval and the specified Interval .
* Specifically , the resulting Interval has the maximum start time and the minimum end time of the two Intervals .
* Returns null if the intersection is empty , meaning , the intervals don ' t intersect .
* @ param { Interval } other
* @ return { Interval }
* /
;
_proto . intersection = function intersection ( other ) {
if ( ! this . isValid ) return this ;
var s = this . s > other . s ? this . s : other . s ,
e = this . e < other . e ? this . e : other . e ;
if ( s >= e ) {
return null ;
} else {
return Interval . fromDateTimes ( s , e ) ;
}
}
/ * *
* Return an Interval representing the union of this Interval and the specified Interval .
* Specifically , the resulting Interval has the minimum start time and the maximum end time of the two Intervals .
* @ param { Interval } other
* @ return { Interval }
* /
;
_proto . union = function union ( other ) {
if ( ! this . isValid ) return this ;
var s = this . s < other . s ? this . s : other . s ,
e = this . e > other . e ? this . e : other . e ;
return Interval . fromDateTimes ( s , e ) ;
}
/ * *
* Merge an array of Intervals into a equivalent minimal set of Intervals .
* Combines overlapping and adjacent Intervals .
* @ param { Array } intervals
* @ return { Array }
* /
;
Interval . merge = function merge ( intervals ) {
var _intervals$sort$reduc = intervals . sort ( function ( a , b ) {
return a . s - b . s ;
} ) . reduce ( function ( _ref2 , item ) {
var sofar = _ref2 [ 0 ] ,
current = _ref2 [ 1 ] ;
if ( ! current ) {
return [ sofar , item ] ;
} else if ( current . overlaps ( item ) || current . abutsStart ( item ) ) {
return [ sofar , current . union ( item ) ] ;
} else {
return [ sofar . concat ( [ current ] ) , item ] ;
}
} , [ [ ] , null ] ) ,
found = _intervals$sort$reduc [ 0 ] ,
final = _intervals$sort$reduc [ 1 ] ;
if ( final ) {
found . push ( final ) ;
}
return found ;
}
/ * *
* Return an array of Intervals representing the spans of time that only appear in one of the specified Intervals .
* @ param { Array } intervals
* @ return { Array }
* /
;
Interval . xor = function xor ( intervals ) {
var _Array$prototype ;
var start = null ,
currentCount = 0 ;
var results = [ ] ,
ends = intervals . map ( function ( i ) {
return [ {
time : i . s ,
type : "s"
} , {
time : i . e ,
type : "e"
} ] ;
} ) ,
flattened = ( _Array$prototype = Array . prototype ) . concat . apply ( _Array$prototype , ends ) ,
arr = flattened . sort ( function ( a , b ) {
return a . time - b . time ;
} ) ;
for ( var _iterator = _createForOfIteratorHelperLoose ( arr ) , _step ; ! ( _step = _iterator ( ) ) . done ; ) {
var i = _step . value ;
currentCount += i . type === "s" ? 1 : - 1 ;
if ( currentCount === 1 ) {
start = i . time ;
} else {
if ( start && + start !== + i . time ) {
results . push ( Interval . fromDateTimes ( start , i . time ) ) ;
}
start = null ;
}
}
return Interval . merge ( results ) ;
}
/ * *
* Return an Interval representing the span of time in this Interval that doesn ' t overlap with any of the specified Intervals .
* @ param { ... Interval } intervals
* @ return { Array }
* /
;
_proto . difference = function difference ( ) {
var _this2 = this ;
for ( var _len2 = arguments . length , intervals = new Array ( _len2 ) , _key2 = 0 ; _key2 < _len2 ; _key2 ++ ) {
intervals [ _key2 ] = arguments [ _key2 ] ;
}
return Interval . xor ( [ this ] . concat ( intervals ) ) . map ( function ( i ) {
return _this2 . intersection ( i ) ;
} ) . filter ( function ( i ) {
return i && ! i . isEmpty ( ) ;
} ) ;
}
/ * *
* Returns a string representation of this Interval appropriate for debugging .
* @ return { string }
* /
;
_proto . toString = function toString ( ) {
if ( ! this . isValid ) return INVALID$1 ;
return "[" + this . s . toISO ( ) + " \u2013 " + this . e . toISO ( ) + ")" ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of this Interval .
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Time_intervals
* @ param { Object } opts - The same options as { @ link DateTime # toISO }
* @ return { string }
* /
;
_proto . toISO = function toISO ( opts ) {
if ( ! this . isValid ) return INVALID$1 ;
return this . s . toISO ( opts ) + "/" + this . e . toISO ( opts ) ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of date of this Interval .
* The time components are ignored .
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Time_intervals
* @ return { string }
* /
;
_proto . toISODate = function toISODate ( ) {
if ( ! this . isValid ) return INVALID$1 ;
return this . s . toISODate ( ) + "/" + this . e . toISODate ( ) ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of time of this Interval .
* The date components are ignored .
* @ see https : //en.wikipedia.org/wiki/ISO_8601#Time_intervals
* @ param { Object } opts - The same options as { @ link DateTime . toISO }
* @ return { string }
* /
;
_proto . toISOTime = function toISOTime ( opts ) {
if ( ! this . isValid ) return INVALID$1 ;
return this . s . toISOTime ( opts ) + "/" + this . e . toISOTime ( opts ) ;
}
/ * *
* Returns a string representation of this Interval formatted according to the specified format string .
* @ param { string } dateFormat - the format string . This string formats the start and end time . See { @ link DateTime . toFormat } for details .
* @ param { Object } opts - options
* @ param { string } [ opts . separator = ' – ' ] - a separator to place between the start and end representations
* @ return { string }
* /
;
_proto . toFormat = function toFormat ( dateFormat , _temp2 ) {
var _ref3 = _temp2 === void 0 ? { } : _temp2 ,
_ref3$separator = _ref3 . separator ,
separator = _ref3$separator === void 0 ? " – " : _ref3$separator ;
if ( ! this . isValid ) return INVALID$1 ;
return "" + this . s . toFormat ( dateFormat ) + separator + this . e . toFormat ( dateFormat ) ;
}
/ * *
* Return a Duration representing the time spanned by this interval .
* @ param { string | string [ ] } [ unit = [ 'milliseconds' ] ] - the unit or units ( such as 'hours' or 'days' ) to include in the duration .
* @ param { Object } opts - options that affect the creation of the Duration
* @ param { string } [ opts . conversionAccuracy = 'casual' ] - the conversion system to use
* @ example Interval . fromDateTimes ( dt1 , dt2 ) . toDuration ( ) . toObject ( ) //=> { milliseconds: 88489257 }
* @ example Interval . fromDateTimes ( dt1 , dt2 ) . toDuration ( 'days' ) . toObject ( ) //=> { days: 1.0241812152777778 }
* @ example Interval . fromDateTimes ( dt1 , dt2 ) . toDuration ( [ 'hours' , 'minutes' ] ) . toObject ( ) //=> { hours: 24, minutes: 34.82095 }
* @ example Interval . fromDateTimes ( dt1 , dt2 ) . toDuration ( [ 'hours' , 'minutes' , 'seconds' ] ) . toObject ( ) //=> { hours: 24, minutes: 34, seconds: 49.257 }
* @ example Interval . fromDateTimes ( dt1 , dt2 ) . toDuration ( 'seconds' ) . toObject ( ) //=> { seconds: 88489.257 }
* @ return { Duration }
* /
;
_proto . toDuration = function toDuration ( unit , opts ) {
if ( ! this . isValid ) {
return Duration . invalid ( this . invalidReason ) ;
}
return this . e . diff ( this . s , unit , opts ) ;
}
/ * *
* Run mapFn on the interval start and end , returning a new Interval from the resulting DateTimes
* @ param { function } mapFn
* @ return { Interval }
* @ example Interval . fromDateTimes ( dt1 , dt2 ) . mapEndpoints ( endpoint => endpoint . toUTC ( ) )
* @ example Interval . fromDateTimes ( dt1 , dt2 ) . mapEndpoints ( endpoint => endpoint . plus ( { hours : 2 } ) )
* /
;
_proto . mapEndpoints = function mapEndpoints ( mapFn ) {
return Interval . fromDateTimes ( mapFn ( this . s ) , mapFn ( this . e ) ) ;
} ;
_createClass ( Interval , [ {
key : "start" ,
get : function get ( ) {
return this . isValid ? this . s : null ;
}
/ * *
* Returns the end of the Interval
* @ type { DateTime }
* /
} , {
key : "end" ,
get : function get ( ) {
return this . isValid ? this . e : null ;
}
/ * *
* Returns whether this Interval 's end is at least its start, meaning that the Interval isn' t 'backwards' .
* @ type { boolean }
* /
} , {
key : "isValid" ,
get : function get ( ) {
return this . invalidReason === null ;
}
/ * *
* Returns an error code if this Interval is invalid , or null if the Interval is valid
* @ type { string }
* /
} , {
key : "invalidReason" ,
get : function get ( ) {
return this . invalid ? this . invalid . reason : null ;
}
/ * *
* Returns an explanation of why this Interval became invalid , or null if the Interval is valid
* @ type { string }
* /
} , {
key : "invalidExplanation" ,
get : function get ( ) {
return this . invalid ? this . invalid . explanation : null ;
}
} ] ) ;
return Interval ;
} ( ) ;
/ * *
* The Info class contains static methods for retrieving general time and date related data . For example , it has methods for finding out if a time zone has a DST , for listing the months in any supported locale , and for discovering which of Luxon features are available in the current environment .
* /
var Info = /*#__PURE__*/ function ( ) {
function Info ( ) { }
/ * *
* Return whether the specified zone contains a DST .
* @ param { string | Zone } [ zone = 'local' ] - Zone to check . Defaults to the environment ' s local zone .
* @ return { boolean }
* /
Info . hasDST = function hasDST ( zone ) {
if ( zone === void 0 ) {
zone = Settings . defaultZone ;
}
var proto = DateTime . now ( ) . setZone ( zone ) . set ( {
month : 12
} ) ;
return ! zone . isUniversal && proto . offset !== proto . set ( {
month : 6
} ) . offset ;
}
/ * *
* Return whether the specified zone is a valid IANA specifier .
* @ param { string } zone - Zone to check
* @ return { boolean }
* /
;
Info . isValidIANAZone = function isValidIANAZone ( zone ) {
return IANAZone . isValidSpecifier ( zone ) && IANAZone . isValidZone ( zone ) ;
}
/ * *
* Converts the input into a { @ link Zone } instance .
*
* * If ` input ` is already a Zone instance , it is returned unchanged .
* * If ` input ` is a string containing a valid time zone name , a Zone instance
* with that name is returned .
* * If ` input ` is a string that doesn ' t refer to a known time zone , a Zone
* instance with { @ link Zone . isValid } == false is returned .
* * If ` input is a number, a Zone instance with the specified fixed offset
* in minutes is returned .
* * If ` input ` is ` null ` or ` undefined ` , the default zone is returned .
* @ param { string | Zone | number } [ input ] - the value to be converted
* @ return { Zone }
* /
;
Info . normalizeZone = function normalizeZone$1 ( input ) {
return normalizeZone ( input , Settings . defaultZone ) ;
}
/ * *
* Return an array of standalone month names .
* @ see https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
* @ param { string } [ length = 'long' ] - the length of the month representation , such as "numeric" , "2-digit" , "narrow" , "short" , "long"
* @ param { Object } opts - options
* @ param { string } [ opts . locale ] - the locale code
* @ param { string } [ opts . numberingSystem = null ] - the numbering system
* @ param { string } [ opts . locObj = null ] - an existing locale object to use
* @ param { string } [ opts . outputCalendar = 'gregory' ] - the calendar
* @ example Info . months ( ) [ 0 ] //=> 'January'
* @ example Info . months ( 'short' ) [ 0 ] //=> 'Jan'
* @ example Info . months ( 'numeric' ) [ 0 ] //=> '1'
* @ example Info . months ( 'short' , { locale : 'fr-CA' } ) [ 0 ] //=> 'janv.'
* @ example Info . months ( 'numeric' , { locale : 'ar' } ) [ 0 ] //=> '١ '
* @ example Info . months ( 'long' , { outputCalendar : 'islamic' } ) [ 0 ] //=> 'Rabiʻ I'
* @ return { Array }
* /
;
Info . months = function months ( length , _temp ) {
if ( length === void 0 ) {
length = "long" ;
}
var _ref = _temp === void 0 ? { } : _temp ,
_ref$locale = _ref . locale ,
locale = _ref$locale === void 0 ? null : _ref$locale ,
_ref$numberingSystem = _ref . numberingSystem ,
numberingSystem = _ref$numberingSystem === void 0 ? null : _ref$numberingSystem ,
_ref$locObj = _ref . locObj ,
locObj = _ref$locObj === void 0 ? null : _ref$locObj ,
_ref$outputCalendar = _ref . outputCalendar ,
outputCalendar = _ref$outputCalendar === void 0 ? "gregory" : _ref$outputCalendar ;
return ( locObj || Locale . create ( locale , numberingSystem , outputCalendar ) ) . months ( length ) ;
}
/ * *
* Return an array of format month names .
* Format months differ from standalone months in that they ' re meant to appear next to the day of the month . In some languages , that
* changes the string .
* See { @ link Info # months }
* @ param { string } [ length = 'long' ] - the length of the month representation , such as "numeric" , "2-digit" , "narrow" , "short" , "long"
* @ param { Object } opts - options
* @ param { string } [ opts . locale ] - the locale code
* @ param { string } [ opts . numberingSystem = null ] - the numbering system
* @ param { string } [ opts . locObj = null ] - an existing locale object to use
* @ param { string } [ opts . outputCalendar = 'gregory' ] - the calendar
* @ return { Array }
* /
;
Info . monthsFormat = function monthsFormat ( length , _temp2 ) {
if ( length === void 0 ) {
length = "long" ;
}
var _ref2 = _temp2 === void 0 ? { } : _temp2 ,
_ref2$locale = _ref2 . locale ,
locale = _ref2$locale === void 0 ? null : _ref2$locale ,
_ref2$numberingSystem = _ref2 . numberingSystem ,
numberingSystem = _ref2$numberingSystem === void 0 ? null : _ref2$numberingSystem ,
_ref2$locObj = _ref2 . locObj ,
locObj = _ref2$locObj === void 0 ? null : _ref2$locObj ,
_ref2$outputCalendar = _ref2 . outputCalendar ,
outputCalendar = _ref2$outputCalendar === void 0 ? "gregory" : _ref2$outputCalendar ;
return ( locObj || Locale . create ( locale , numberingSystem , outputCalendar ) ) . months ( length , true ) ;
}
/ * *
* Return an array of standalone week names .
* @ see https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
* @ param { string } [ length = 'long' ] - the length of the weekday representation , such as "narrow" , "short" , "long" .
* @ param { Object } opts - options
* @ param { string } [ opts . locale ] - the locale code
* @ param { string } [ opts . numberingSystem = null ] - the numbering system
* @ param { string } [ opts . locObj = null ] - an existing locale object to use
* @ example Info . weekdays ( ) [ 0 ] //=> 'Monday'
* @ example Info . weekdays ( 'short' ) [ 0 ] //=> 'Mon'
* @ example Info . weekdays ( 'short' , { locale : 'fr-CA' } ) [ 0 ] //=> 'lun.'
* @ example Info . weekdays ( 'short' , { locale : 'ar' } ) [ 0 ] //=> 'الاثنين'
* @ return { Array }
* /
;
Info . weekdays = function weekdays ( length , _temp3 ) {
if ( length === void 0 ) {
length = "long" ;
}
var _ref3 = _temp3 === void 0 ? { } : _temp3 ,
_ref3$locale = _ref3 . locale ,
locale = _ref3$locale === void 0 ? null : _ref3$locale ,
_ref3$numberingSystem = _ref3 . numberingSystem ,
numberingSystem = _ref3$numberingSystem === void 0 ? null : _ref3$numberingSystem ,
_ref3$locObj = _ref3 . locObj ,
locObj = _ref3$locObj === void 0 ? null : _ref3$locObj ;
return ( locObj || Locale . create ( locale , numberingSystem , null ) ) . weekdays ( length ) ;
}
/ * *
* Return an array of format week names .
* Format weekdays differ from standalone weekdays in that they ' re meant to appear next to more date information . In some languages , that
* changes the string .
* See { @ link Info # weekdays }
* @ param { string } [ length = 'long' ] - the length of the month representation , such as "narrow" , "short" , "long" .
* @ param { Object } opts - options
* @ param { string } [ opts . locale = null ] - the locale code
* @ param { string } [ opts . numberingSystem = null ] - the numbering system
* @ param { string } [ opts . locObj = null ] - an existing locale object to use
* @ return { Array }
* /
;
Info . weekdaysFormat = function weekdaysFormat ( length , _temp4 ) {
if ( length === void 0 ) {
length = "long" ;
}
var _ref4 = _temp4 === void 0 ? { } : _temp4 ,
_ref4$locale = _ref4 . locale ,
locale = _ref4$locale === void 0 ? null : _ref4$locale ,
_ref4$numberingSystem = _ref4 . numberingSystem ,
numberingSystem = _ref4$numberingSystem === void 0 ? null : _ref4$numberingSystem ,
_ref4$locObj = _ref4 . locObj ,
locObj = _ref4$locObj === void 0 ? null : _ref4$locObj ;
return ( locObj || Locale . create ( locale , numberingSystem , null ) ) . weekdays ( length , true ) ;
}
/ * *
* Return an array of meridiems .
* @ param { Object } opts - options
* @ param { string } [ opts . locale ] - the locale code
* @ example Info . meridiems ( ) //=> [ 'AM', 'PM' ]
* @ example Info . meridiems ( { locale : 'my' } ) //=> [ 'နံနက်', 'ညနေ' ]
* @ return { Array }
* /
;
Info . meridiems = function meridiems ( _temp5 ) {
var _ref5 = _temp5 === void 0 ? { } : _temp5 ,
_ref5$locale = _ref5 . locale ,
locale = _ref5$locale === void 0 ? null : _ref5$locale ;
return Locale . create ( locale ) . meridiems ( ) ;
}
/ * *
* Return an array of eras , such as [ 'BC' , 'AD' ] . The locale can be specified , but the calendar system is always Gregorian .
* @ param { string } [ length = 'short' ] - the length of the era representation , such as "short" or "long" .
* @ param { Object } opts - options
* @ param { string } [ opts . locale ] - the locale code
* @ example Info . eras ( ) //=> [ 'BC', 'AD' ]
* @ example Info . eras ( 'long' ) //=> [ 'Before Christ', 'Anno Domini' ]
* @ example Info . eras ( 'long' , { locale : 'fr' } ) //=> [ 'avant Jésus-Christ', 'après Jésus-Christ' ]
* @ return { Array }
* /
;
Info . eras = function eras ( length , _temp6 ) {
if ( length === void 0 ) {
length = "short" ;
}
var _ref6 = _temp6 === void 0 ? { } : _temp6 ,
_ref6$locale = _ref6 . locale ,
locale = _ref6$locale === void 0 ? null : _ref6$locale ;
return Locale . create ( locale , null , "gregory" ) . eras ( length ) ;
}
/ * *
* Return the set of available features in this environment .
* Some features of Luxon are not available in all environments . For example , on older browsers , timezone support is not available . Use this function to figure out if that ' s the case .
* Keys :
* * ` relative ` : whether this environment supports relative time formatting
* @ example Info . features ( ) //=> { intl: true, intlTokens: false, zones: true, relative: false }
* @ return { Object }
* /
;
Info . features = function features ( ) {
return {
relative : hasRelative ( )
} ;
} ;
return Info ;
} ( ) ;
function dayDiff ( earlier , later ) {
var utcDayStart = function utcDayStart ( dt ) {
return dt . toUTC ( 0 , {
keepLocalTime : true
} ) . startOf ( "day" ) . valueOf ( ) ;
} ,
ms = utcDayStart ( later ) - utcDayStart ( earlier ) ;
return Math . floor ( Duration . fromMillis ( ms ) . as ( "days" ) ) ;
}
function highOrderDiffs ( cursor , later , units ) {
var differs = [ [ "years" , function ( a , b ) {
return b . year - a . year ;
} ] , [ "quarters" , function ( a , b ) {
return b . quarter - a . quarter ;
} ] , [ "months" , function ( a , b ) {
return b . month - a . month + ( b . year - a . year ) * 12 ;
} ] , [ "weeks" , function ( a , b ) {
var days = dayDiff ( a , b ) ;
return ( days - days % 7 ) / 7 ;
} ] , [ "days" , dayDiff ] ] ;
var results = { } ;
var lowestOrder , highWater ;
for ( var _i = 0 , _differs = differs ; _i < _differs . length ; _i ++ ) {
var _differs$ _i = _differs [ _i ] ,
unit = _differs$ _i [ 0 ] ,
differ = _differs$ _i [ 1 ] ;
if ( units . indexOf ( unit ) >= 0 ) {
var _cursor$plus ;
lowestOrder = unit ;
var delta = differ ( cursor , later ) ;
highWater = cursor . plus ( ( _cursor$plus = { } , _cursor$plus [ unit ] = delta , _cursor$plus ) ) ;
if ( highWater > later ) {
var _cursor$plus2 ;
cursor = cursor . plus ( ( _cursor$plus2 = { } , _cursor$plus2 [ unit ] = delta - 1 , _cursor$plus2 ) ) ;
delta -= 1 ;
} else {
cursor = highWater ;
}
results [ unit ] = delta ;
}
}
return [ cursor , results , highWater , lowestOrder ] ;
}
function _diff ( earlier , later , units , opts ) {
var _highOrderDiffs = highOrderDiffs ( earlier , later , units ) ,
cursor = _highOrderDiffs [ 0 ] ,
results = _highOrderDiffs [ 1 ] ,
highWater = _highOrderDiffs [ 2 ] ,
lowestOrder = _highOrderDiffs [ 3 ] ;
var remainingMillis = later - cursor ;
var lowerOrderUnits = units . filter ( function ( u ) {
return [ "hours" , "minutes" , "seconds" , "milliseconds" ] . indexOf ( u ) >= 0 ;
} ) ;
if ( lowerOrderUnits . length === 0 ) {
if ( highWater < later ) {
var _cursor$plus3 ;
highWater = cursor . plus ( ( _cursor$plus3 = { } , _cursor$plus3 [ lowestOrder ] = 1 , _cursor$plus3 ) ) ;
}
if ( highWater !== cursor ) {
results [ lowestOrder ] = ( results [ lowestOrder ] || 0 ) + remainingMillis / ( highWater - cursor ) ;
}
}
var duration = Duration . fromObject ( results , opts ) ;
if ( lowerOrderUnits . length > 0 ) {
var _Duration$fromMillis ;
return ( _Duration$fromMillis = Duration . fromMillis ( remainingMillis , opts ) ) . shiftTo . apply ( _Duration$fromMillis , lowerOrderUnits ) . plus ( duration ) ;
} else {
return duration ;
}
}
var numberingSystems = {
arab : "[\u0660-\u0669]" ,
arabext : "[\u06F0-\u06F9]" ,
bali : "[\u1B50-\u1B59]" ,
beng : "[\u09E6-\u09EF]" ,
deva : "[\u0966-\u096F]" ,
fullwide : "[\uFF10-\uFF19]" ,
gujr : "[\u0AE6-\u0AEF]" ,
hanidec : "[〇 |一|二|三|四|五|六|七|八|九]" ,
khmr : "[\u17E0-\u17E9]" ,
knda : "[\u0CE6-\u0CEF]" ,
laoo : "[\u0ED0-\u0ED9]" ,
limb : "[\u1946-\u194F]" ,
mlym : "[\u0D66-\u0D6F]" ,
mong : "[\u1810-\u1819]" ,
mymr : "[\u1040-\u1049]" ,
orya : "[\u0B66-\u0B6F]" ,
tamldec : "[\u0BE6-\u0BEF]" ,
telu : "[\u0C66-\u0C6F]" ,
thai : "[\u0E50-\u0E59]" ,
tibt : "[\u0F20-\u0F29]" ,
latn : "\\d"
} ;
var numberingSystemsUTF16 = {
arab : [ 1632 , 1641 ] ,
arabext : [ 1776 , 1785 ] ,
bali : [ 6992 , 7001 ] ,
beng : [ 2534 , 2543 ] ,
deva : [ 2406 , 2415 ] ,
fullwide : [ 65296 , 65303 ] ,
gujr : [ 2790 , 2799 ] ,
khmr : [ 6112 , 6121 ] ,
knda : [ 3302 , 3311 ] ,
laoo : [ 3792 , 3801 ] ,
limb : [ 6470 , 6479 ] ,
mlym : [ 3430 , 3439 ] ,
mong : [ 6160 , 6169 ] ,
mymr : [ 4160 , 4169 ] ,
orya : [ 2918 , 2927 ] ,
tamldec : [ 3046 , 3055 ] ,
telu : [ 3174 , 3183 ] ,
thai : [ 3664 , 3673 ] ,
tibt : [ 3872 , 3881 ]
} ;
var hanidecChars = numberingSystems . hanidec . replace ( /[\[|\]]/g , "" ) . split ( "" ) ;
function parseDigits ( str ) {
var value = parseInt ( str , 10 ) ;
if ( isNaN ( value ) ) {
value = "" ;
for ( var i = 0 ; i < str . length ; i ++ ) {
var code = str . charCodeAt ( i ) ;
if ( str [ i ] . search ( numberingSystems . hanidec ) !== - 1 ) {
value += hanidecChars . indexOf ( str [ i ] ) ;
} else {
for ( var key in numberingSystemsUTF16 ) {
var _numberingSystemsUTF = numberingSystemsUTF16 [ key ] ,
min = _numberingSystemsUTF [ 0 ] ,
max = _numberingSystemsUTF [ 1 ] ;
if ( code >= min && code <= max ) {
value += code - min ;
}
}
}
}
return parseInt ( value , 10 ) ;
} else {
return value ;
}
}
function digitRegex ( _ref , append ) {
var numberingSystem = _ref . numberingSystem ;
if ( append === void 0 ) {
append = "" ;
}
return new RegExp ( "" + numberingSystems [ numberingSystem || "latn" ] + append ) ;
}
var MISSING _FTP = "missing Intl.DateTimeFormat.formatToParts support" ;
function intUnit ( regex , post ) {
if ( post === void 0 ) {
post = function post ( i ) {
return i ;
} ;
}
return {
regex : regex ,
deser : function deser ( _ref ) {
var s = _ref [ 0 ] ;
return post ( parseDigits ( s ) ) ;
}
} ;
}
var NBSP = String . fromCharCode ( 160 ) ;
var spaceOrNBSP = "( |" + NBSP + ")" ;
var spaceOrNBSPRegExp = new RegExp ( spaceOrNBSP , "g" ) ;
function fixListRegex ( s ) {
// make dots optional and also make them literal
// make space and non breakable space characters interchangeable
return s . replace ( /\./g , "\\.?" ) . replace ( spaceOrNBSPRegExp , spaceOrNBSP ) ;
}
function stripInsensitivities ( s ) {
return s . replace ( /\./g , "" ) // ignore dots that were made optional
. replace ( spaceOrNBSPRegExp , " " ) // interchange space and nbsp
. toLowerCase ( ) ;
}
function oneOf ( strings , startIndex ) {
if ( strings === null ) {
return null ;
} else {
return {
regex : RegExp ( strings . map ( fixListRegex ) . join ( "|" ) ) ,
deser : function deser ( _ref2 ) {
var s = _ref2 [ 0 ] ;
return strings . findIndex ( function ( i ) {
return stripInsensitivities ( s ) === stripInsensitivities ( i ) ;
} ) + startIndex ;
}
} ;
}
}
function offset ( regex , groups ) {
return {
regex : regex ,
deser : function deser ( _ref3 ) {
var h = _ref3 [ 1 ] ,
m = _ref3 [ 2 ] ;
return signedOffset ( h , m ) ;
} ,
groups : groups
} ;
}
function simple ( regex ) {
return {
regex : regex ,
deser : function deser ( _ref4 ) {
var s = _ref4 [ 0 ] ;
return s ;
}
} ;
}
function escapeToken ( value ) {
return value . replace ( /[\-\[\]{}()*+?.,\\\^$|#\s]/g , "\\$&" ) ;
}
function unitForToken ( token , loc ) {
var one = digitRegex ( loc ) ,
two = digitRegex ( loc , "{2}" ) ,
three = digitRegex ( loc , "{3}" ) ,
four = digitRegex ( loc , "{4}" ) ,
six = digitRegex ( loc , "{6}" ) ,
oneOrTwo = digitRegex ( loc , "{1,2}" ) ,
oneToThree = digitRegex ( loc , "{1,3}" ) ,
oneToSix = digitRegex ( loc , "{1,6}" ) ,
oneToNine = digitRegex ( loc , "{1,9}" ) ,
twoToFour = digitRegex ( loc , "{2,4}" ) ,
fourToSix = digitRegex ( loc , "{4,6}" ) ,
literal = function literal ( t ) {
return {
regex : RegExp ( escapeToken ( t . val ) ) ,
deser : function deser ( _ref5 ) {
var s = _ref5 [ 0 ] ;
return s ;
} ,
literal : true
} ;
} ,
unitate = function unitate ( t ) {
if ( token . literal ) {
return literal ( t ) ;
}
switch ( t . val ) {
// era
case "G" :
return oneOf ( loc . eras ( "short" , false ) , 0 ) ;
case "GG" :
return oneOf ( loc . eras ( "long" , false ) , 0 ) ;
// years
case "y" :
return intUnit ( oneToSix ) ;
case "yy" :
return intUnit ( twoToFour , untruncateYear ) ;
case "yyyy" :
return intUnit ( four ) ;
case "yyyyy" :
return intUnit ( fourToSix ) ;
case "yyyyyy" :
return intUnit ( six ) ;
// months
case "M" :
return intUnit ( oneOrTwo ) ;
case "MM" :
return intUnit ( two ) ;
case "MMM" :
return oneOf ( loc . months ( "short" , true , false ) , 1 ) ;
case "MMMM" :
return oneOf ( loc . months ( "long" , true , false ) , 1 ) ;
case "L" :
return intUnit ( oneOrTwo ) ;
case "LL" :
return intUnit ( two ) ;
case "LLL" :
return oneOf ( loc . months ( "short" , false , false ) , 1 ) ;
case "LLLL" :
return oneOf ( loc . months ( "long" , false , false ) , 1 ) ;
// dates
case "d" :
return intUnit ( oneOrTwo ) ;
case "dd" :
return intUnit ( two ) ;
// ordinals
case "o" :
return intUnit ( oneToThree ) ;
case "ooo" :
return intUnit ( three ) ;
// time
case "HH" :
return intUnit ( two ) ;
case "H" :
return intUnit ( oneOrTwo ) ;
case "hh" :
return intUnit ( two ) ;
case "h" :
return intUnit ( oneOrTwo ) ;
case "mm" :
return intUnit ( two ) ;
case "m" :
return intUnit ( oneOrTwo ) ;
case "q" :
return intUnit ( oneOrTwo ) ;
case "qq" :
return intUnit ( two ) ;
case "s" :
return intUnit ( oneOrTwo ) ;
case "ss" :
return intUnit ( two ) ;
case "S" :
return intUnit ( oneToThree ) ;
case "SSS" :
return intUnit ( three ) ;
case "u" :
return simple ( oneToNine ) ;
// meridiem
case "a" :
return oneOf ( loc . meridiems ( ) , 0 ) ;
// weekYear (k)
case "kkkk" :
return intUnit ( four ) ;
case "kk" :
return intUnit ( twoToFour , untruncateYear ) ;
// weekNumber (W)
case "W" :
return intUnit ( oneOrTwo ) ;
case "WW" :
return intUnit ( two ) ;
// weekdays
case "E" :
case "c" :
return intUnit ( one ) ;
case "EEE" :
return oneOf ( loc . weekdays ( "short" , false , false ) , 1 ) ;
case "EEEE" :
return oneOf ( loc . weekdays ( "long" , false , false ) , 1 ) ;
case "ccc" :
return oneOf ( loc . weekdays ( "short" , true , false ) , 1 ) ;
case "cccc" :
return oneOf ( loc . weekdays ( "long" , true , false ) , 1 ) ;
// offset/zone
case "Z" :
case "ZZ" :
return offset ( new RegExp ( "([+-]" + oneOrTwo . source + ")(?::(" + two . source + "))?" ) , 2 ) ;
case "ZZZ" :
return offset ( new RegExp ( "([+-]" + oneOrTwo . source + ")(" + two . source + ")?" ) , 2 ) ;
// we don't support ZZZZ (PST) or ZZZZZ (Pacific Standard Time) in parsing
// because we don't have any way to figure out what they are
case "z" :
return simple ( /[a-z_+-/]{1,256}?/i ) ;
default :
return literal ( t ) ;
}
} ;
var unit = unitate ( token ) || {
invalidReason : MISSING _FTP
} ;
unit . token = token ;
return unit ;
}
var partTypeStyleToTokenVal = {
year : {
"2-digit" : "yy" ,
numeric : "yyyyy"
} ,
month : {
numeric : "M" ,
"2-digit" : "MM" ,
short : "MMM" ,
long : "MMMM"
} ,
day : {
numeric : "d" ,
"2-digit" : "dd"
} ,
weekday : {
short : "EEE" ,
long : "EEEE"
} ,
dayperiod : "a" ,
dayPeriod : "a" ,
hour : {
numeric : "h" ,
"2-digit" : "hh"
} ,
minute : {
numeric : "m" ,
"2-digit" : "mm"
} ,
second : {
numeric : "s" ,
"2-digit" : "ss"
}
} ;
function tokenForPart ( part , locale , formatOpts ) {
var type = part . type ,
value = part . value ;
if ( type === "literal" ) {
return {
literal : true ,
val : value
} ;
}
var style = formatOpts [ type ] ;
var val = partTypeStyleToTokenVal [ type ] ;
if ( typeof val === "object" ) {
val = val [ style ] ;
}
if ( val ) {
return {
literal : false ,
val : val
} ;
}
return undefined ;
}
function buildRegex ( units ) {
var re = units . map ( function ( u ) {
return u . regex ;
} ) . reduce ( function ( f , r ) {
return f + "(" + r . source + ")" ;
} , "" ) ;
return [ "^" + re + "$" , units ] ;
}
function match ( input , regex , handlers ) {
var matches = input . match ( regex ) ;
if ( matches ) {
var all = { } ;
var matchIndex = 1 ;
for ( var i in handlers ) {
if ( hasOwnProperty ( handlers , i ) ) {
var h = handlers [ i ] ,
groups = h . groups ? h . groups + 1 : 1 ;
if ( ! h . literal && h . token ) {
all [ h . token . val [ 0 ] ] = h . deser ( matches . slice ( matchIndex , matchIndex + groups ) ) ;
}
matchIndex += groups ;
}
}
return [ matches , all ] ;
} else {
return [ matches , { } ] ;
}
}
function dateTimeFromMatches ( matches ) {
var toField = function toField ( token ) {
switch ( token ) {
case "S" :
return "millisecond" ;
case "s" :
return "second" ;
case "m" :
return "minute" ;
case "h" :
case "H" :
return "hour" ;
case "d" :
return "day" ;
case "o" :
return "ordinal" ;
case "L" :
case "M" :
return "month" ;
case "y" :
return "year" ;
case "E" :
case "c" :
return "weekday" ;
case "W" :
return "weekNumber" ;
case "k" :
return "weekYear" ;
case "q" :
return "quarter" ;
default :
return null ;
}
} ;
var zone ;
if ( ! isUndefined ( matches . Z ) ) {
zone = new FixedOffsetZone ( matches . Z ) ;
} else if ( ! isUndefined ( matches . z ) ) {
zone = IANAZone . create ( matches . z ) ;
} else {
zone = null ;
}
if ( ! isUndefined ( matches . q ) ) {
matches . M = ( matches . q - 1 ) * 3 + 1 ;
}
if ( ! isUndefined ( matches . h ) ) {
if ( matches . h < 12 && matches . a === 1 ) {
matches . h += 12 ;
} else if ( matches . h === 12 && matches . a === 0 ) {
matches . h = 0 ;
}
}
if ( matches . G === 0 && matches . y ) {
matches . y = - matches . y ;
}
if ( ! isUndefined ( matches . u ) ) {
matches . S = parseMillis ( matches . u ) ;
}
var vals = Object . keys ( matches ) . reduce ( function ( r , k ) {
var f = toField ( k ) ;
if ( f ) {
r [ f ] = matches [ k ] ;
}
return r ;
} , { } ) ;
return [ vals , zone ] ;
}
var dummyDateTimeCache = null ;
function getDummyDateTime ( ) {
if ( ! dummyDateTimeCache ) {
dummyDateTimeCache = DateTime . fromMillis ( 1555555555555 ) ;
}
return dummyDateTimeCache ;
}
function maybeExpandMacroToken ( token , locale ) {
if ( token . literal ) {
return token ;
}
var formatOpts = Formatter . macroTokenToFormatOpts ( token . val ) ;
if ( ! formatOpts ) {
return token ;
}
var formatter = Formatter . create ( locale , formatOpts ) ;
var parts = formatter . formatDateTimeParts ( getDummyDateTime ( ) ) ;
var tokens = parts . map ( function ( p ) {
return tokenForPart ( p , locale , formatOpts ) ;
} ) ;
if ( tokens . includes ( undefined ) ) {
return token ;
}
return tokens ;
}
function expandMacroTokens ( tokens , locale ) {
var _Array$prototype ;
return ( _Array$prototype = Array . prototype ) . concat . apply ( _Array$prototype , tokens . map ( function ( t ) {
return maybeExpandMacroToken ( t , locale ) ;
} ) ) ;
}
/ * *
* @ private
* /
function explainFromTokens ( locale , input , format ) {
var tokens = expandMacroTokens ( Formatter . parseFormat ( format ) , locale ) ,
units = tokens . map ( function ( t ) {
return unitForToken ( t , locale ) ;
} ) ,
disqualifyingUnit = units . find ( function ( t ) {
return t . invalidReason ;
} ) ;
if ( disqualifyingUnit ) {
return {
input : input ,
tokens : tokens ,
invalidReason : disqualifyingUnit . invalidReason
} ;
} else {
var _buildRegex = buildRegex ( units ) ,
regexString = _buildRegex [ 0 ] ,
handlers = _buildRegex [ 1 ] ,
regex = RegExp ( regexString , "i" ) ,
_match = match ( input , regex , handlers ) ,
rawMatches = _match [ 0 ] ,
matches = _match [ 1 ] ,
_ref6 = matches ? dateTimeFromMatches ( matches ) : [ null , null ] ,
result = _ref6 [ 0 ] ,
zone = _ref6 [ 1 ] ;
if ( hasOwnProperty ( matches , "a" ) && hasOwnProperty ( matches , "H" ) ) {
throw new ConflictingSpecificationError ( "Can't include meridiem when specifying 24-hour format" ) ;
}
return {
input : input ,
tokens : tokens ,
regex : regex ,
rawMatches : rawMatches ,
matches : matches ,
result : result ,
zone : zone
} ;
}
}
function parseFromTokens ( locale , input , format ) {
var _explainFromTokens = explainFromTokens ( locale , input , format ) ,
result = _explainFromTokens . result ,
zone = _explainFromTokens . zone ,
invalidReason = _explainFromTokens . invalidReason ;
return [ result , zone , invalidReason ] ;
}
var nonLeapLadder = [ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 ] ,
leapLadder = [ 0 , 31 , 60 , 91 , 121 , 152 , 182 , 213 , 244 , 274 , 305 , 335 ] ;
function unitOutOfRange ( unit , value ) {
return new Invalid ( "unit out of range" , "you specified " + value + " (of type " + typeof value + ") as a " + unit + ", which is invalid" ) ;
}
function dayOfWeek ( year , month , day ) {
var js = new Date ( Date . UTC ( year , month - 1 , day ) ) . getUTCDay ( ) ;
return js === 0 ? 7 : js ;
}
function computeOrdinal ( year , month , day ) {
return day + ( isLeapYear ( year ) ? leapLadder : nonLeapLadder ) [ month - 1 ] ;
}
function uncomputeOrdinal ( year , ordinal ) {
var table = isLeapYear ( year ) ? leapLadder : nonLeapLadder ,
month0 = table . findIndex ( function ( i ) {
return i < ordinal ;
} ) ,
day = ordinal - table [ month0 ] ;
return {
month : month0 + 1 ,
day : day
} ;
}
/ * *
* @ private
* /
function gregorianToWeek ( gregObj ) {
var year = gregObj . year ,
month = gregObj . month ,
day = gregObj . day ,
ordinal = computeOrdinal ( year , month , day ) ,
weekday = dayOfWeek ( year , month , day ) ;
var weekNumber = Math . floor ( ( ordinal - weekday + 10 ) / 7 ) ,
weekYear ;
if ( weekNumber < 1 ) {
weekYear = year - 1 ;
weekNumber = weeksInWeekYear ( weekYear ) ;
} else if ( weekNumber > weeksInWeekYear ( year ) ) {
weekYear = year + 1 ;
weekNumber = 1 ;
} else {
weekYear = year ;
}
return _extends ( {
weekYear : weekYear ,
weekNumber : weekNumber ,
weekday : weekday
} , timeObject ( gregObj ) ) ;
}
function weekToGregorian ( weekData ) {
var weekYear = weekData . weekYear ,
weekNumber = weekData . weekNumber ,
weekday = weekData . weekday ,
weekdayOfJan4 = dayOfWeek ( weekYear , 1 , 4 ) ,
yearInDays = daysInYear ( weekYear ) ;
var ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 3 ,
year ;
if ( ordinal < 1 ) {
year = weekYear - 1 ;
ordinal += daysInYear ( year ) ;
} else if ( ordinal > yearInDays ) {
year = weekYear + 1 ;
ordinal -= daysInYear ( weekYear ) ;
} else {
year = weekYear ;
}
var _uncomputeOrdinal = uncomputeOrdinal ( year , ordinal ) ,
month = _uncomputeOrdinal . month ,
day = _uncomputeOrdinal . day ;
return _extends ( {
year : year ,
month : month ,
day : day
} , timeObject ( weekData ) ) ;
}
function gregorianToOrdinal ( gregData ) {
var year = gregData . year ,
month = gregData . month ,
day = gregData . day ;
var ordinal = computeOrdinal ( year , month , day ) ;
return _extends ( {
year : year ,
ordinal : ordinal
} , timeObject ( gregData ) ) ;
}
function ordinalToGregorian ( ordinalData ) {
var year = ordinalData . year ,
ordinal = ordinalData . ordinal ;
var _uncomputeOrdinal2 = uncomputeOrdinal ( year , ordinal ) ,
month = _uncomputeOrdinal2 . month ,
day = _uncomputeOrdinal2 . day ;
return _extends ( {
year : year ,
month : month ,
day : day
} , timeObject ( ordinalData ) ) ;
}
function hasInvalidWeekData ( obj ) {
var validYear = isInteger ( obj . weekYear ) ,
validWeek = integerBetween ( obj . weekNumber , 1 , weeksInWeekYear ( obj . weekYear ) ) ,
validWeekday = integerBetween ( obj . weekday , 1 , 7 ) ;
if ( ! validYear ) {
return unitOutOfRange ( "weekYear" , obj . weekYear ) ;
} else if ( ! validWeek ) {
return unitOutOfRange ( "week" , obj . week ) ;
} else if ( ! validWeekday ) {
return unitOutOfRange ( "weekday" , obj . weekday ) ;
} else return false ;
}
function hasInvalidOrdinalData ( obj ) {
var validYear = isInteger ( obj . year ) ,
validOrdinal = integerBetween ( obj . ordinal , 1 , daysInYear ( obj . year ) ) ;
if ( ! validYear ) {
return unitOutOfRange ( "year" , obj . year ) ;
} else if ( ! validOrdinal ) {
return unitOutOfRange ( "ordinal" , obj . ordinal ) ;
} else return false ;
}
function hasInvalidGregorianData ( obj ) {
var validYear = isInteger ( obj . year ) ,
validMonth = integerBetween ( obj . month , 1 , 12 ) ,
validDay = integerBetween ( obj . day , 1 , daysInMonth ( obj . year , obj . month ) ) ;
if ( ! validYear ) {
return unitOutOfRange ( "year" , obj . year ) ;
} else if ( ! validMonth ) {
return unitOutOfRange ( "month" , obj . month ) ;
} else if ( ! validDay ) {
return unitOutOfRange ( "day" , obj . day ) ;
} else return false ;
}
function hasInvalidTimeData ( obj ) {
var hour = obj . hour ,
minute = obj . minute ,
second = obj . second ,
millisecond = obj . millisecond ;
var validHour = integerBetween ( hour , 0 , 23 ) || hour === 24 && minute === 0 && second === 0 && millisecond === 0 ,
validMinute = integerBetween ( minute , 0 , 59 ) ,
validSecond = integerBetween ( second , 0 , 59 ) ,
validMillisecond = integerBetween ( millisecond , 0 , 999 ) ;
if ( ! validHour ) {
return unitOutOfRange ( "hour" , hour ) ;
} else if ( ! validMinute ) {
return unitOutOfRange ( "minute" , minute ) ;
} else if ( ! validSecond ) {
return unitOutOfRange ( "second" , second ) ;
} else if ( ! validMillisecond ) {
return unitOutOfRange ( "millisecond" , millisecond ) ;
} else return false ;
}
var INVALID = "Invalid DateTime" ;
var MAX _DATE = 8.64 e15 ;
function unsupportedZone ( zone ) {
return new Invalid ( "unsupported zone" , "the zone \"" + zone . name + "\" is not supported" ) ;
} // we cache week data on the DT object and this intermediates the cache
function possiblyCachedWeekData ( dt ) {
if ( dt . weekData === null ) {
dt . weekData = gregorianToWeek ( dt . c ) ;
}
return dt . weekData ;
} // clone really means, "make a new object with these modifications". all "setters" really use this
// to create a new object while only changing some of the properties
function clone ( inst , alts ) {
var current = {
ts : inst . ts ,
zone : inst . zone ,
c : inst . c ,
o : inst . o ,
loc : inst . loc ,
invalid : inst . invalid
} ;
return new DateTime ( _extends ( { } , current , alts , {
old : current
} ) ) ;
} // find the right offset a given local time. The o input is our guess, which determines which
// offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
function fixOffset ( localTS , o , tz ) {
// Our UTC time is just a guess because our offset is just a guess
var utcGuess = localTS - o * 60 * 1000 ; // Test whether the zone matches the offset for this ts
var o2 = tz . offset ( utcGuess ) ; // If so, offset didn't change and we're done
if ( o === o2 ) {
return [ utcGuess , o ] ;
} // If not, change the ts by the difference in the offset
utcGuess -= ( o2 - o ) * 60 * 1000 ; // If that gives us the local time we want, we're done
var o3 = tz . offset ( utcGuess ) ;
if ( o2 === o3 ) {
return [ utcGuess , o2 ] ;
} // If it's different, we're in a hole time. The offset has changed, but the we don't adjust the time
return [ localTS - Math . min ( o2 , o3 ) * 60 * 1000 , Math . max ( o2 , o3 ) ] ;
} // convert an epoch timestamp into a calendar object with the given offset
function tsToObj ( ts , offset ) {
ts += offset * 60 * 1000 ;
var d = new Date ( ts ) ;
return {
year : d . getUTCFullYear ( ) ,
month : d . getUTCMonth ( ) + 1 ,
day : d . getUTCDate ( ) ,
hour : d . getUTCHours ( ) ,
minute : d . getUTCMinutes ( ) ,
second : d . getUTCSeconds ( ) ,
millisecond : d . getUTCMilliseconds ( )
} ;
} // convert a calendar object to a epoch timestamp
function objToTS ( obj , offset , zone ) {
return fixOffset ( objToLocalTS ( obj ) , offset , zone ) ;
} // create a new DT instance by adding a duration, adjusting for DSTs
function adjustTime ( inst , dur ) {
var oPre = inst . o ,
year = inst . c . year + Math . trunc ( dur . years ) ,
month = inst . c . month + Math . trunc ( dur . months ) + Math . trunc ( dur . quarters ) * 3 ,
c = _extends ( { } , inst . c , {
year : year ,
month : month ,
day : Math . min ( inst . c . day , daysInMonth ( year , month ) ) + Math . trunc ( dur . days ) + Math . trunc ( dur . weeks ) * 7
} ) ,
millisToAdd = Duration . fromObject ( {
years : dur . years - Math . trunc ( dur . years ) ,
quarters : dur . quarters - Math . trunc ( dur . quarters ) ,
months : dur . months - Math . trunc ( dur . months ) ,
weeks : dur . weeks - Math . trunc ( dur . weeks ) ,
days : dur . days - Math . trunc ( dur . days ) ,
hours : dur . hours ,
minutes : dur . minutes ,
seconds : dur . seconds ,
milliseconds : dur . milliseconds
} ) . as ( "milliseconds" ) ,
localTS = objToLocalTS ( c ) ;
var _fixOffset = fixOffset ( localTS , oPre , inst . zone ) ,
ts = _fixOffset [ 0 ] ,
o = _fixOffset [ 1 ] ;
if ( millisToAdd !== 0 ) {
ts += millisToAdd ; // that could have changed the offset by going over a DST, but we want to keep the ts the same
o = inst . zone . offset ( ts ) ;
}
return {
ts : ts ,
o : o
} ;
} // helper useful in turning the results of parsing into real dates
// by handling the zone options
function parseDataToDateTime ( parsed , parsedZone , opts , format , text ) {
var setZone = opts . setZone ,
zone = opts . zone ;
if ( parsed && Object . keys ( parsed ) . length !== 0 ) {
var interpretationZone = parsedZone || zone ,
inst = DateTime . fromObject ( parsed , _extends ( { } , opts , {
zone : interpretationZone
} ) ) ;
return setZone ? inst : inst . setZone ( zone ) ;
} else {
return DateTime . invalid ( new Invalid ( "unparsable" , "the input \"" + text + "\" can't be parsed as " + format ) ) ;
}
} // if you want to output a technical format (e.g. RFC 2822), this helper
// helps handle the details
function toTechFormat ( dt , format , allowZ ) {
if ( allowZ === void 0 ) {
allowZ = true ;
}
return dt . isValid ? Formatter . create ( Locale . create ( "en-US" ) , {
allowZ : allowZ ,
forceSimple : true
} ) . formatDateTimeFromString ( dt , format ) : null ;
} // technical time formats (e.g. the time part of ISO 8601), take some options
// and this commonizes their handling
function toTechTimeFormat ( dt , _ref ) {
var _ref$suppressSeconds = _ref . suppressSeconds ,
suppressSeconds = _ref$suppressSeconds === void 0 ? false : _ref$suppressSeconds ,
_ref$suppressMillisec = _ref . suppressMilliseconds ,
suppressMilliseconds = _ref$suppressMillisec === void 0 ? false : _ref$suppressMillisec ,
includeOffset = _ref . includeOffset ,
_ref$includePrefix = _ref . includePrefix ,
includePrefix = _ref$includePrefix === void 0 ? false : _ref$includePrefix ,
_ref$includeZone = _ref . includeZone ,
includeZone = _ref$includeZone === void 0 ? false : _ref$includeZone ,
_ref$spaceZone = _ref . spaceZone ,
spaceZone = _ref$spaceZone === void 0 ? false : _ref$spaceZone ,
_ref$format = _ref . format ,
format = _ref$format === void 0 ? "extended" : _ref$format ;
var fmt = format === "basic" ? "HHmm" : "HH:mm" ;
if ( ! suppressSeconds || dt . second !== 0 || dt . millisecond !== 0 ) {
fmt += format === "basic" ? "ss" : ":ss" ;
if ( ! suppressMilliseconds || dt . millisecond !== 0 ) {
fmt += ".SSS" ;
}
}
if ( ( includeZone || includeOffset ) && spaceZone ) {
fmt += " " ;
}
if ( includeZone ) {
fmt += "z" ;
} else if ( includeOffset ) {
fmt += format === "basic" ? "ZZZ" : "ZZ" ;
}
var str = toTechFormat ( dt , fmt ) ;
if ( includePrefix ) {
str = "T" + str ;
}
return str ;
} // defaults for unspecified units in the supported calendars
var defaultUnitValues = {
month : 1 ,
day : 1 ,
hour : 0 ,
minute : 0 ,
second : 0 ,
millisecond : 0
} ,
defaultWeekUnitValues = {
weekNumber : 1 ,
weekday : 1 ,
hour : 0 ,
minute : 0 ,
second : 0 ,
millisecond : 0
} ,
defaultOrdinalUnitValues = {
ordinal : 1 ,
hour : 0 ,
minute : 0 ,
second : 0 ,
millisecond : 0
} ; // Units in the supported calendars, sorted by bigness
var orderedUnits = [ "year" , "month" , "day" , "hour" , "minute" , "second" , "millisecond" ] ,
orderedWeekUnits = [ "weekYear" , "weekNumber" , "weekday" , "hour" , "minute" , "second" , "millisecond" ] ,
orderedOrdinalUnits = [ "year" , "ordinal" , "hour" , "minute" , "second" , "millisecond" ] ; // standardize case and plurality in units
function normalizeUnit ( unit ) {
var normalized = {
year : "year" ,
years : "year" ,
month : "month" ,
months : "month" ,
day : "day" ,
days : "day" ,
hour : "hour" ,
hours : "hour" ,
minute : "minute" ,
minutes : "minute" ,
quarter : "quarter" ,
quarters : "quarter" ,
second : "second" ,
seconds : "second" ,
millisecond : "millisecond" ,
milliseconds : "millisecond" ,
weekday : "weekday" ,
weekdays : "weekday" ,
weeknumber : "weekNumber" ,
weeksnumber : "weekNumber" ,
weeknumbers : "weekNumber" ,
weekyear : "weekYear" ,
weekyears : "weekYear" ,
ordinal : "ordinal"
} [ unit . toLowerCase ( ) ] ;
if ( ! normalized ) throw new InvalidUnitError ( unit ) ;
return normalized ;
} // this is a dumbed down version of fromObject() that runs about 60% faster
// but doesn't do any validation, makes a bunch of assumptions about what units
// are present, and so on.
// this is a dumbed down version of fromObject() that runs about 60% faster
// but doesn't do any validation, makes a bunch of assumptions about what units
// are present, and so on.
function quickDT ( obj , opts ) {
var zone = normalizeZone ( opts . zone , Settings . defaultZone ) ,
loc = Locale . fromObject ( opts ) ,
tsNow = Settings . now ( ) ;
var ts , o ; // assume we have the higher-order units
if ( ! isUndefined ( obj . year ) ) {
for ( var _iterator = _createForOfIteratorHelperLoose ( orderedUnits ) , _step ; ! ( _step = _iterator ( ) ) . done ; ) {
var u = _step . value ;
if ( isUndefined ( obj [ u ] ) ) {
obj [ u ] = defaultUnitValues [ u ] ;
}
}
var invalid = hasInvalidGregorianData ( obj ) || hasInvalidTimeData ( obj ) ;
if ( invalid ) {
return DateTime . invalid ( invalid ) ;
}
var offsetProvis = zone . offset ( tsNow ) ;
var _objToTS = objToTS ( obj , offsetProvis , zone ) ;
ts = _objToTS [ 0 ] ;
o = _objToTS [ 1 ] ;
} else {
ts = tsNow ;
}
return new DateTime ( {
ts : ts ,
zone : zone ,
loc : loc ,
o : o
} ) ;
}
function diffRelative ( start , end , opts ) {
var round = isUndefined ( opts . round ) ? true : opts . round ,
format = function format ( c , unit ) {
c = roundTo ( c , round || opts . calendary ? 0 : 2 , true ) ;
var formatter = end . loc . clone ( opts ) . relFormatter ( opts ) ;
return formatter . format ( c , unit ) ;
} ,
differ = function differ ( unit ) {
if ( opts . calendary ) {
if ( ! end . hasSame ( start , unit ) ) {
return end . startOf ( unit ) . diff ( start . startOf ( unit ) , unit ) . get ( unit ) ;
} else return 0 ;
} else {
return end . diff ( start , unit ) . get ( unit ) ;
}
} ;
if ( opts . unit ) {
return format ( differ ( opts . unit ) , opts . unit ) ;
}
for ( var _iterator2 = _createForOfIteratorHelperLoose ( opts . units ) , _step2 ; ! ( _step2 = _iterator2 ( ) ) . done ; ) {
var unit = _step2 . value ;
var count = differ ( unit ) ;
if ( Math . abs ( count ) >= 1 ) {
return format ( count , unit ) ;
}
}
return format ( start > end ? - 0 : 0 , opts . units [ opts . units . length - 1 ] ) ;
}
function lastOpts ( argList ) {
var opts = { } ,
args ;
if ( argList . length > 0 && typeof argList [ argList . length - 1 ] === "object" ) {
opts = argList [ argList . length - 1 ] ;
args = Array . from ( argList ) . slice ( 0 , argList . length - 1 ) ;
} else {
args = Array . from ( argList ) ;
}
return [ opts , args ] ;
}
/ * *
* A DateTime is an immutable data structure representing a specific date and time and accompanying methods . It contains class and instance methods for creating , parsing , interrogating , transforming , and formatting them .
*
* A DateTime comprises of :
* * A timestamp . Each DateTime instance refers to a specific millisecond of the Unix epoch .
* * A time zone . Each instance is considered in the context of a specific zone ( by default the local system ' s zone ) .
* * Configuration properties that effect how output strings are formatted , such as ` locale ` , ` numberingSystem ` , and ` outputCalendar ` .
*
* Here is a brief overview of the most commonly used functionality it provides :
*
* * * * Creation * * : To create a DateTime from its components , use one of its factory class methods : { @ link DateTime . local } , { @ link DateTime . utc } , and ( most flexibly ) { @ link DateTime . fromObject } . To create one from a standard string format , use { @ link DateTime . fromISO } , { @ link DateTime . fromHTTP } , and { @ link DateTime . fromRFC2822 } . To create one from a custom string format , use { @ link DateTime . fromFormat } . To create one from a native JS date , use { @ link DateTime . fromJSDate } .
* * * * Gregorian calendar and time * * : To examine the Gregorian properties of a DateTime individually ( i . e as opposed to collectively through { @ link DateTime # toObject } ) , use the { @ link DateTime # year } , { @ link DateTime # month } ,
* { @ link DateTime # day } , { @ link DateTime # hour } , { @ link DateTime # minute } , { @ link DateTime # second } , { @ link DateTime # millisecond } accessors .
* * * * Week calendar * * : For ISO week calendar attributes , see the { @ link DateTime # weekYear } , { @ link DateTime # weekNumber } , and { @ link DateTime # weekday } accessors .
* * * * Configuration * * See the { @ link DateTime # locale } and { @ link DateTime # numberingSystem } accessors .
* * * * Transformation * * : To transform the DateTime into other DateTimes , use { @ link DateTime # set } , { @ link DateTime # reconfigure } , { @ link DateTime # setZone } , { @ link DateTime # setLocale } , { @ link DateTime . plus } , { @ link DateTime # minus } , { @ link DateTime # endOf } , { @ link DateTime # startOf } , { @ link DateTime # toUTC } , and { @ link DateTime # toLocal } .
* * * * Output * * : To convert the DateTime to other representations , use the { @ link DateTime # toRelative } , { @ link DateTime # toRelativeCalendar } , { @ link DateTime # toJSON } , { @ link DateTime # toISO } , { @ link DateTime # toHTTP } , { @ link DateTime # toObject } , { @ link DateTime # toRFC2822 } , { @ link DateTime # toString } , { @ link DateTime # toLocaleString } , { @ link DateTime # toFormat } , { @ link DateTime # toMillis } and { @ link DateTime # toJSDate } .
*
* There ' s plenty others documented below . In addition , for more information on subtler topics like internationalization , time zones , alternative calendars , validity , and so on , see the external documentation .
* /
var DateTime = /*#__PURE__*/ function ( ) {
/ * *
* @ access private
* /
function DateTime ( config ) {
var zone = config . zone || Settings . defaultZone ;
var invalid = config . invalid || ( Number . isNaN ( config . ts ) ? new Invalid ( "invalid input" ) : null ) || ( ! zone . isValid ? unsupportedZone ( zone ) : null ) ;
/ * *
* @ access private
* /
this . ts = isUndefined ( config . ts ) ? Settings . now ( ) : config . ts ;
var c = null ,
o = null ;
if ( ! invalid ) {
var unchanged = config . old && config . old . ts === this . ts && config . old . zone . equals ( zone ) ;
if ( unchanged ) {
var _ref2 = [ config . old . c , config . old . o ] ;
c = _ref2 [ 0 ] ;
o = _ref2 [ 1 ] ;
} else {
var ot = zone . offset ( this . ts ) ;
c = tsToObj ( this . ts , ot ) ;
invalid = Number . isNaN ( c . year ) ? new Invalid ( "invalid input" ) : null ;
c = invalid ? null : c ;
o = invalid ? null : ot ;
}
}
/ * *
* @ access private
* /
this . _zone = zone ;
/ * *
* @ access private
* /
this . loc = config . loc || Locale . create ( ) ;
/ * *
* @ access private
* /
this . invalid = invalid ;
/ * *
* @ access private
* /
this . weekData = null ;
/ * *
* @ access private
* /
this . c = c ;
/ * *
* @ access private
* /
this . o = o ;
/ * *
* @ access private
* /
this . isLuxonDateTime = true ;
} // CONSTRUCT
/ * *
* Create a DateTime for the current instant , in the system ' s time zone .
*
* Use Settings to override these default values if needed .
* @ example DateTime . now ( ) . toISO ( ) //~> now in the ISO format
* @ return { DateTime }
* /
DateTime . now = function now ( ) {
return new DateTime ( { } ) ;
}
/ * *
* Create a local DateTime
* @ param { number } [ year ] - The calendar year . If omitted ( as in , call ` local() ` with no arguments ) , the current time will be used
* @ param { number } [ month = 1 ] - The month , 1 - indexed
* @ param { number } [ day = 1 ] - The day of the month , 1 - indexed
* @ param { number } [ hour = 0 ] - The hour of the day , in 24 - hour time
* @ param { number } [ minute = 0 ] - The minute of the hour , meaning a number between 0 and 59
* @ param { number } [ second = 0 ] - The second of the minute , meaning a number between 0 and 59
* @ param { number } [ millisecond = 0 ] - The millisecond of the second , meaning a number between 0 and 999
* @ example DateTime . local ( ) //~> now
* @ example DateTime . local ( { zone : "America/New_York" } ) //~> now, in US east coast time
* @ example DateTime . local ( 2017 ) //~> 2017-01-01T00:00:00
* @ example DateTime . local ( 2017 , 3 ) //~> 2017-03-01T00:00:00
* @ example DateTime . local ( 2017 , 3 , 12 , { locale : "fr" } ) //~> 2017-03-12T00:00:00, with a French locale
* @ example DateTime . local ( 2017 , 3 , 12 , 5 ) //~> 2017-03-12T05:00:00
* @ example DateTime . local ( 2017 , 3 , 12 , 5 , { zone : "utc" } ) //~> 2017-03-12T05:00:00, in UTC
* @ example DateTime . local ( 2017 , 3 , 12 , 5 , 45 ) //~> 2017-03-12T05:45:00
* @ example DateTime . local ( 2017 , 3 , 12 , 5 , 45 , 10 ) //~> 2017-03-12T05:45:10
* @ example DateTime . local ( 2017 , 3 , 12 , 5 , 45 , 10 , 765 ) //~> 2017-03-12T05:45:10.765
* @ return { DateTime }
* /
;
DateTime . local = function local ( ) {
var _lastOpts = lastOpts ( arguments ) ,
opts = _lastOpts [ 0 ] ,
args = _lastOpts [ 1 ] ,
year = args [ 0 ] ,
month = args [ 1 ] ,
day = args [ 2 ] ,
hour = args [ 3 ] ,
minute = args [ 4 ] ,
second = args [ 5 ] ,
millisecond = args [ 6 ] ;
return quickDT ( {
year : year ,
month : month ,
day : day ,
hour : hour ,
minute : minute ,
second : second ,
millisecond : millisecond
} , opts ) ;
}
/ * *
* Create a DateTime in UTC
* @ param { number } [ year ] - The calendar year . If omitted ( as in , call ` utc() ` with no arguments ) , the current time will be used
* @ param { number } [ month = 1 ] - The month , 1 - indexed
* @ param { number } [ day = 1 ] - The day of the month
* @ param { number } [ hour = 0 ] - The hour of the day , in 24 - hour time
* @ param { number } [ minute = 0 ] - The minute of the hour , meaning a number between 0 and 59
* @ param { number } [ second = 0 ] - The second of the minute , meaning a number between 0 and 59
* @ param { number } [ millisecond = 0 ] - The millisecond of the second , meaning a number between 0 and 999
* @ param { Object } options - configuration options for the DateTime
* @ param { string } [ options . locale ] - a locale to set on the resulting DateTime instance
* @ param { string } [ options . outputCalendar ] - the output calendar to set on the resulting DateTime instance
* @ param { string } [ options . numberingSystem ] - the numbering system to set on the resulting DateTime instance
* @ example DateTime . utc ( ) //~> now
* @ example DateTime . utc ( 2017 ) //~> 2017-01-01T00:00:00Z
* @ example DateTime . utc ( 2017 , 3 ) //~> 2017-03-01T00:00:00Z
* @ example DateTime . utc ( 2017 , 3 , 12 ) //~> 2017-03-12T00:00:00Z
* @ example DateTime . utc ( 2017 , 3 , 12 , 5 ) //~> 2017-03-12T05:00:00Z
* @ example DateTime . utc ( 2017 , 3 , 12 , 5 , 45 ) //~> 2017-03-12T05:45:00Z
* @ example DateTime . utc ( 2017 , 3 , 12 , 5 , 45 , { locale : "fr" } ) //~> 2017-03-12T05:45:00Z with a French locale
* @ example DateTime . utc ( 2017 , 3 , 12 , 5 , 45 , 10 ) //~> 2017-03-12T05:45:10Z
* @ example DateTime . utc ( 2017 , 3 , 12 , 5 , 45 , 10 , 765 , { locale : "fr" } ) //~> 2017-03-12T05:45:10.765Z with a French locale
* @ return { DateTime }
* /
;
DateTime . utc = function utc ( ) {
var _lastOpts2 = lastOpts ( arguments ) ,
opts = _lastOpts2 [ 0 ] ,
args = _lastOpts2 [ 1 ] ,
year = args [ 0 ] ,
month = args [ 1 ] ,
day = args [ 2 ] ,
hour = args [ 3 ] ,
minute = args [ 4 ] ,
second = args [ 5 ] ,
millisecond = args [ 6 ] ;
opts . zone = FixedOffsetZone . utcInstance ;
return quickDT ( {
year : year ,
month : month ,
day : day ,
hour : hour ,
minute : minute ,
second : second ,
millisecond : millisecond
} , opts ) ;
}
/ * *
* Create a DateTime from a JavaScript Date object . Uses the default zone .
* @ param { Date } date - a JavaScript Date object
* @ param { Object } options - configuration options for the DateTime
* @ param { string | Zone } [ options . zone = 'local' ] - the zone to place the DateTime into
* @ return { DateTime }
* /
;
DateTime . fromJSDate = function fromJSDate ( date , options ) {
if ( options === void 0 ) {
options = { } ;
}
var ts = isDate ( date ) ? date . valueOf ( ) : NaN ;
if ( Number . isNaN ( ts ) ) {
return DateTime . invalid ( "invalid input" ) ;
}
var zoneToUse = normalizeZone ( options . zone , Settings . defaultZone ) ;
if ( ! zoneToUse . isValid ) {
return DateTime . invalid ( unsupportedZone ( zoneToUse ) ) ;
}
return new DateTime ( {
ts : ts ,
zone : zoneToUse ,
loc : Locale . fromObject ( options )
} ) ;
}
/ * *
* Create a DateTime from a number of milliseconds since the epoch ( meaning since 1 January 1970 00 : 00 : 00 UTC ) . Uses the default zone .
* @ param { number } milliseconds - a number of milliseconds since 1970 UTC
* @ param { Object } options - configuration options for the DateTime
* @ param { string | Zone } [ options . zone = 'local' ] - the zone to place the DateTime into
* @ param { string } [ options . locale ] - a locale to set on the resulting DateTime instance
* @ param { string } options . outputCalendar - the output calendar to set on the resulting DateTime instance
* @ param { string } options . numberingSystem - the numbering system to set on the resulting DateTime instance
* @ return { DateTime }
* /
;
DateTime . fromMillis = function fromMillis ( milliseconds , options ) {
if ( options === void 0 ) {
options = { } ;
}
if ( ! isNumber ( milliseconds ) ) {
throw new InvalidArgumentError ( "fromMillis requires a numerical input, but received a " + typeof milliseconds + " with value " + milliseconds ) ;
} else if ( milliseconds < - MAX _DATE || milliseconds > MAX _DATE ) {
// this isn't perfect because because we can still end up out of range because of additional shifting, but it's a start
return DateTime . invalid ( "Timestamp out of range" ) ;
} else {
return new DateTime ( {
ts : milliseconds ,
zone : normalizeZone ( options . zone , Settings . defaultZone ) ,
loc : Locale . fromObject ( options )
} ) ;
}
}
/ * *
* Create a DateTime from a number of seconds since the epoch ( meaning since 1 January 1970 00 : 00 : 00 UTC ) . Uses the default zone .
* @ param { number } seconds - a number of seconds since 1970 UTC
* @ param { Object } options - configuration options for the DateTime
* @ param { string | Zone } [ options . zone = 'local' ] - the zone to place the DateTime into
* @ param { string } [ options . locale ] - a locale to set on the resulting DateTime instance
* @ param { string } options . outputCalendar - the output calendar to set on the resulting DateTime instance
* @ param { string } options . numberingSystem - the numbering system to set on the resulting DateTime instance
* @ return { DateTime }
* /
;
DateTime . fromSeconds = function fromSeconds ( seconds , options ) {
if ( options === void 0 ) {
options = { } ;
}
if ( ! isNumber ( seconds ) ) {
throw new InvalidArgumentError ( "fromSeconds requires a numerical input" ) ;
} else {
return new DateTime ( {
ts : seconds * 1000 ,
zone : normalizeZone ( options . zone , Settings . defaultZone ) ,
loc : Locale . fromObject ( options )
} ) ;
}
}
/ * *
* Create a DateTime from a JavaScript object with keys like 'year' and 'hour' with reasonable defaults .
* @ param { Object } obj - the object to create the DateTime from
* @ param { number } obj . year - a year , such as 1987
* @ param { number } obj . month - a month , 1 - 12
* @ param { number } obj . day - a day of the month , 1 - 31 , depending on the month
* @ param { number } obj . ordinal - day of the year , 1 - 365 or 366
* @ param { number } obj . weekYear - an ISO week year
* @ param { number } obj . weekNumber - an ISO week number , between 1 and 52 or 53 , depending on the year
* @ param { number } obj . weekday - an ISO weekday , 1 - 7 , where 1 is Monday and 7 is Sunday
* @ param { number } obj . hour - hour of the day , 0 - 23
* @ param { number } obj . minute - minute of the hour , 0 - 59
* @ param { number } obj . second - second of the minute , 0 - 59
* @ param { number } obj . millisecond - millisecond of the second , 0 - 999
* @ param { Object } opts - options for creating this DateTime
* @ param { string | Zone } [ opts . zone = 'local' ] - interpret the numbers in the context of a particular zone . Can take any value taken as the first argument to setZone ( )
* @ param { string } [ opts . locale = 'system' s locale ' ] - a locale to set on the resulting DateTime instance
* @ param { string } opts . outputCalendar - the output calendar to set on the resulting DateTime instance
* @ param { string } opts . numberingSystem - the numbering system to set on the resulting DateTime instance
* @ example DateTime . fromObject ( { year : 1982 , month : 5 , day : 25 } ) . toISODate ( ) //=> '1982-05-25'
* @ example DateTime . fromObject ( { year : 1982 } ) . toISODate ( ) //=> '1982-01-01'
* @ example DateTime . fromObject ( { hour : 10 , minute : 26 , second : 6 } ) //~> today at 10:26:06
* @ example DateTime . fromObject ( { hour : 10 , minute : 26 , second : 6 } , { zone : 'utc' } ) ,
* @ example DateTime . fromObject ( { hour : 10 , minute : 26 , second : 6 } , { zone : 'local' } )
* @ example DateTime . fromObject ( { hour : 10 , minute : 26 , second : 6 } , { zone : 'America/New_York' } )
* @ example DateTime . fromObject ( { weekYear : 2016 , weekNumber : 2 , weekday : 3 } ) . toISODate ( ) //=> '2016-01-13'
* @ return { DateTime }
* /
;
DateTime . fromObject = function fromObject ( obj , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
obj = obj || { } ;
var zoneToUse = normalizeZone ( opts . zone , Settings . defaultZone ) ;
if ( ! zoneToUse . isValid ) {
return DateTime . invalid ( unsupportedZone ( zoneToUse ) ) ;
}
var tsNow = Settings . now ( ) ,
offsetProvis = zoneToUse . offset ( tsNow ) ,
normalized = normalizeObject ( obj , normalizeUnit ) ,
containsOrdinal = ! isUndefined ( normalized . ordinal ) ,
containsGregorYear = ! isUndefined ( normalized . year ) ,
containsGregorMD = ! isUndefined ( normalized . month ) || ! isUndefined ( normalized . day ) ,
containsGregor = containsGregorYear || containsGregorMD ,
definiteWeekDef = normalized . weekYear || normalized . weekNumber ,
loc = Locale . fromObject ( opts ) ; // cases:
// just a weekday -> this week's instance of that weekday, no worries
// (gregorian data or ordinal) + (weekYear or weekNumber) -> error
// (gregorian month or day) + ordinal -> error
// otherwise just use weeks or ordinals or gregorian, depending on what's specified
if ( ( containsGregor || containsOrdinal ) && definiteWeekDef ) {
throw new ConflictingSpecificationError ( "Can't mix weekYear/weekNumber units with year/month/day or ordinals" ) ;
}
if ( containsGregorMD && containsOrdinal ) {
throw new ConflictingSpecificationError ( "Can't mix ordinal dates with month/day" ) ;
}
var useWeekData = definiteWeekDef || normalized . weekday && ! containsGregor ; // configure ourselves to deal with gregorian dates or week stuff
var units ,
defaultValues ,
objNow = tsToObj ( tsNow , offsetProvis ) ;
if ( useWeekData ) {
units = orderedWeekUnits ;
defaultValues = defaultWeekUnitValues ;
objNow = gregorianToWeek ( objNow ) ;
} else if ( containsOrdinal ) {
units = orderedOrdinalUnits ;
defaultValues = defaultOrdinalUnitValues ;
objNow = gregorianToOrdinal ( objNow ) ;
} else {
units = orderedUnits ;
defaultValues = defaultUnitValues ;
} // set default values for missing stuff
var foundFirst = false ;
for ( var _iterator3 = _createForOfIteratorHelperLoose ( units ) , _step3 ; ! ( _step3 = _iterator3 ( ) ) . done ; ) {
var u = _step3 . value ;
var v = normalized [ u ] ;
if ( ! isUndefined ( v ) ) {
foundFirst = true ;
} else if ( foundFirst ) {
normalized [ u ] = defaultValues [ u ] ;
} else {
normalized [ u ] = objNow [ u ] ;
}
} // make sure the values we have are in range
var higherOrderInvalid = useWeekData ? hasInvalidWeekData ( normalized ) : containsOrdinal ? hasInvalidOrdinalData ( normalized ) : hasInvalidGregorianData ( normalized ) ,
invalid = higherOrderInvalid || hasInvalidTimeData ( normalized ) ;
if ( invalid ) {
return DateTime . invalid ( invalid ) ;
} // compute the actual time
var gregorian = useWeekData ? weekToGregorian ( normalized ) : containsOrdinal ? ordinalToGregorian ( normalized ) : normalized ,
_objToTS2 = objToTS ( gregorian , offsetProvis , zoneToUse ) ,
tsFinal = _objToTS2 [ 0 ] ,
offsetFinal = _objToTS2 [ 1 ] ,
inst = new DateTime ( {
ts : tsFinal ,
zone : zoneToUse ,
o : offsetFinal ,
loc : loc
} ) ; // gregorian data + weekday serves only to validate
if ( normalized . weekday && containsGregor && obj . weekday !== inst . weekday ) {
return DateTime . invalid ( "mismatched weekday" , "you can't specify both a weekday of " + normalized . weekday + " and a date of " + inst . toISO ( ) ) ;
}
return inst ;
}
/ * *
* Create a DateTime from an ISO 8601 string
* @ param { string } text - the ISO string
* @ param { Object } opts - options to affect the creation
* @ param { string | Zone } [ opts . zone = 'local' ] - use this zone if no offset is specified in the input string itself . Will also convert the time to this zone
* @ param { boolean } [ opts . setZone = false ] - override the zone with a fixed - offset zone specified in the string itself , if it specifies one
* @ param { string } [ opts . locale = 'system' s locale ' ] - a locale to set on the resulting DateTime instance
* @ param { string } [ opts . outputCalendar ] - the output calendar to set on the resulting DateTime instance
* @ param { string } [ opts . numberingSystem ] - the numbering system to set on the resulting DateTime instance
* @ example DateTime . fromISO ( '2016-05-25T09:08:34.123' )
* @ example DateTime . fromISO ( '2016-05-25T09:08:34.123+06:00' )
* @ example DateTime . fromISO ( '2016-05-25T09:08:34.123+06:00' , { setZone : true } )
* @ example DateTime . fromISO ( '2016-05-25T09:08:34.123' , { zone : 'utc' } )
* @ example DateTime . fromISO ( '2016-W05-4' )
* @ return { DateTime }
* /
;
DateTime . fromISO = function fromISO ( text , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var _parseISODate = parseISODate ( text ) ,
vals = _parseISODate [ 0 ] ,
parsedZone = _parseISODate [ 1 ] ;
return parseDataToDateTime ( vals , parsedZone , opts , "ISO 8601" , text ) ;
}
/ * *
* Create a DateTime from an RFC 2822 string
* @ param { string } text - the RFC 2822 string
* @ param { Object } opts - options to affect the creation
* @ param { string | Zone } [ opts . zone = 'local' ] - convert the time to this zone . Since the offset is always specified in the string itself , this has no effect on the interpretation of string , merely the zone the resulting DateTime is expressed in .
* @ param { boolean } [ opts . setZone = false ] - override the zone with a fixed - offset zone specified in the string itself , if it specifies one
* @ param { string } [ opts . locale = 'system' s locale ' ] - a locale to set on the resulting DateTime instance
* @ param { string } opts . outputCalendar - the output calendar to set on the resulting DateTime instance
* @ param { string } opts . numberingSystem - the numbering system to set on the resulting DateTime instance
* @ example DateTime . fromRFC2822 ( '25 Nov 2016 13:23:12 GMT' )
* @ example DateTime . fromRFC2822 ( 'Fri, 25 Nov 2016 13:23:12 +0600' )
* @ example DateTime . fromRFC2822 ( '25 Nov 2016 13:23 Z' )
* @ return { DateTime }
* /
;
DateTime . fromRFC2822 = function fromRFC2822 ( text , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var _parseRFC2822Date = parseRFC2822Date ( text ) ,
vals = _parseRFC2822Date [ 0 ] ,
parsedZone = _parseRFC2822Date [ 1 ] ;
return parseDataToDateTime ( vals , parsedZone , opts , "RFC 2822" , text ) ;
}
/ * *
* Create a DateTime from an HTTP header date
* @ see https : //www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
* @ param { string } text - the HTTP header date
* @ param { Object } opts - options to affect the creation
* @ param { string | Zone } [ opts . zone = 'local' ] - convert the time to this zone . Since HTTP dates are always in UTC , this has no effect on the interpretation of string , merely the zone the resulting DateTime is expressed in .
* @ param { boolean } [ opts . setZone = false ] - override the zone with the fixed - offset zone specified in the string . For HTTP dates , this is always UTC , so this option is equivalent to setting the ` zone ` option to 'utc' , but this option is included for consistency with similar methods .
* @ param { string } [ opts . locale = 'system' s locale ' ] - a locale to set on the resulting DateTime instance
* @ param { string } opts . outputCalendar - the output calendar to set on the resulting DateTime instance
* @ param { string } opts . numberingSystem - the numbering system to set on the resulting DateTime instance
* @ example DateTime . fromHTTP ( 'Sun, 06 Nov 1994 08:49:37 GMT' )
* @ example DateTime . fromHTTP ( 'Sunday, 06-Nov-94 08:49:37 GMT' )
* @ example DateTime . fromHTTP ( 'Sun Nov 6 08:49:37 1994' )
* @ return { DateTime }
* /
;
DateTime . fromHTTP = function fromHTTP ( text , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var _parseHTTPDate = parseHTTPDate ( text ) ,
vals = _parseHTTPDate [ 0 ] ,
parsedZone = _parseHTTPDate [ 1 ] ;
return parseDataToDateTime ( vals , parsedZone , opts , "HTTP" , opts ) ;
}
/ * *
* Create a DateTime from an input string and format string .
* Defaults to en - US if no locale has been specified , regardless of the system ' s locale . For a table of tokens and their interpretations , see [ here ] ( https : //moment.github.io/luxon/#/parsing?id=table-of-tokens).
* @ param { string } text - the string to parse
* @ param { string } fmt - the format the string is expected to be in ( see the link below for the formats )
* @ param { Object } opts - options to affect the creation
* @ param { string | Zone } [ opts . zone = 'local' ] - use this zone if no offset is specified in the input string itself . Will also convert the DateTime to this zone
* @ param { boolean } [ opts . setZone = false ] - override the zone with a zone specified in the string itself , if it specifies one
* @ param { string } [ opts . locale = 'en-US' ] - a locale string to use when parsing . Will also set the DateTime to this locale
* @ param { string } opts . numberingSystem - the numbering system to use when parsing . Will also set the resulting DateTime to this numbering system
* @ param { string } opts . outputCalendar - the output calendar to set on the resulting DateTime instance
* @ return { DateTime }
* /
;
DateTime . fromFormat = function fromFormat ( text , fmt , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
if ( isUndefined ( text ) || isUndefined ( fmt ) ) {
throw new InvalidArgumentError ( "fromFormat requires an input string and a format" ) ;
}
var _opts = opts ,
_opts$locale = _opts . locale ,
locale = _opts$locale === void 0 ? null : _opts$locale ,
_opts$numberingSystem = _opts . numberingSystem ,
numberingSystem = _opts$numberingSystem === void 0 ? null : _opts$numberingSystem ,
localeToUse = Locale . fromOpts ( {
locale : locale ,
numberingSystem : numberingSystem ,
defaultToEN : true
} ) ,
_parseFromTokens = parseFromTokens ( localeToUse , text , fmt ) ,
vals = _parseFromTokens [ 0 ] ,
parsedZone = _parseFromTokens [ 1 ] ,
invalid = _parseFromTokens [ 2 ] ;
if ( invalid ) {
return DateTime . invalid ( invalid ) ;
} else {
return parseDataToDateTime ( vals , parsedZone , opts , "format " + fmt , text ) ;
}
}
/ * *
* @ deprecated use fromFormat instead
* /
;
DateTime . fromString = function fromString ( text , fmt , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
return DateTime . fromFormat ( text , fmt , opts ) ;
}
/ * *
* Create a DateTime from a SQL date , time , or datetime
* Defaults to en - US if no locale has been specified , regardless of the system ' s locale
* @ param { string } text - the string to parse
* @ param { Object } opts - options to affect the creation
* @ param { string | Zone } [ opts . zone = 'local' ] - use this zone if no offset is specified in the input string itself . Will also convert the DateTime to this zone
* @ param { boolean } [ opts . setZone = false ] - override the zone with a zone specified in the string itself , if it specifies one
* @ param { string } [ opts . locale = 'en-US' ] - a locale string to use when parsing . Will also set the DateTime to this locale
* @ param { string } opts . numberingSystem - the numbering system to use when parsing . Will also set the resulting DateTime to this numbering system
* @ param { string } opts . outputCalendar - the output calendar to set on the resulting DateTime instance
* @ example DateTime . fromSQL ( '2017-05-15' )
* @ example DateTime . fromSQL ( '2017-05-15 09:12:34' )
* @ example DateTime . fromSQL ( '2017-05-15 09:12:34.342' )
* @ example DateTime . fromSQL ( '2017-05-15 09:12:34.342+06:00' )
* @ example DateTime . fromSQL ( '2017-05-15 09:12:34.342 America/Los_Angeles' )
* @ example DateTime . fromSQL ( '2017-05-15 09:12:34.342 America/Los_Angeles' , { setZone : true } )
* @ example DateTime . fromSQL ( '2017-05-15 09:12:34.342' , { zone : 'America/Los_Angeles' } )
* @ example DateTime . fromSQL ( '09:12:34.342' )
* @ return { DateTime }
* /
;
DateTime . fromSQL = function fromSQL ( text , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var _parseSQL = parseSQL ( text ) ,
vals = _parseSQL [ 0 ] ,
parsedZone = _parseSQL [ 1 ] ;
return parseDataToDateTime ( vals , parsedZone , opts , "SQL" , text ) ;
}
/ * *
* Create an invalid DateTime .
* @ param { string } reason - simple string of why this DateTime is invalid . Should not contain parameters or anything else data - dependent
* @ param { string } [ explanation = null ] - longer explanation , may include parameters and other useful debugging information
* @ return { DateTime }
* /
;
DateTime . invalid = function invalid ( reason , explanation ) {
if ( explanation === void 0 ) {
explanation = null ;
}
if ( ! reason ) {
throw new InvalidArgumentError ( "need to specify a reason the DateTime is invalid" ) ;
}
var invalid = reason instanceof Invalid ? reason : new Invalid ( reason , explanation ) ;
if ( Settings . throwOnInvalid ) {
throw new InvalidDateTimeError ( invalid ) ;
} else {
return new DateTime ( {
invalid : invalid
} ) ;
}
}
/ * *
* Check if an object is a DateTime . Works across context boundaries
* @ param { object } o
* @ return { boolean }
* /
;
DateTime . isDateTime = function isDateTime ( o ) {
return o && o . isLuxonDateTime || false ;
} // INFO
/ * *
* Get the value of unit .
* @ param { string } unit - a unit such as 'minute' or 'day'
* @ example DateTime . local ( 2017 , 7 , 4 ) . get ( 'month' ) ; //=> 7
* @ example DateTime . local ( 2017 , 7 , 4 ) . get ( 'day' ) ; //=> 4
* @ return { number }
* /
;
var _proto = DateTime . prototype ;
_proto . get = function get ( unit ) {
return this [ unit ] ;
}
/ * *
* Returns whether the DateTime is valid . Invalid DateTimes occur when :
* * The DateTime was created from invalid calendar information , such as the 13 th month or February 30
* * The DateTime was created by an operation on another invalid date
* @ type { boolean }
* /
;
/ * *
* Returns the resolved Intl options for this DateTime .
* This is useful in understanding the behavior of formatting methods
* @ param { Object } opts - the same options as toLocaleString
* @ return { Object }
* /
_proto . resolvedLocaleOptions = function resolvedLocaleOptions ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var _Formatter$create$res = Formatter . create ( this . loc . clone ( opts ) , opts ) . resolvedOptions ( this ) ,
locale = _Formatter$create$res . locale ,
numberingSystem = _Formatter$create$res . numberingSystem ,
calendar = _Formatter$create$res . calendar ;
return {
locale : locale ,
numberingSystem : numberingSystem ,
outputCalendar : calendar
} ;
} // TRANSFORM
/ * *
* "Set" the DateTime ' s zone to UTC . Returns a newly - constructed DateTime .
*
* Equivalent to { @ link DateTime . setZone } ( 'utc' )
* @ param { number } [ offset = 0 ] - optionally , an offset from UTC in minutes
* @ param { Object } [ opts = { } ] - options to pass to ` setZone() `
* @ return { DateTime }
* /
;
_proto . toUTC = function toUTC ( offset , opts ) {
if ( offset === void 0 ) {
offset = 0 ;
}
if ( opts === void 0 ) {
opts = { } ;
}
return this . setZone ( FixedOffsetZone . instance ( offset ) , opts ) ;
}
/ * *
* "Set" the DateTime 's zone to the host' s local zone . Returns a newly - constructed DateTime .
*
* Equivalent to ` setZone('local') `
* @ return { DateTime }
* /
;
_proto . toLocal = function toLocal ( ) {
return this . setZone ( Settings . defaultZone ) ;
}
/ * *
* "Set" the DateTime ' s zone to specified zone . Returns a newly - constructed DateTime .
*
* By default , the setter keeps the underlying time the same ( as in , the same timestamp ) , but the new instance will report different local times and consider DSTs when making computations , as with { @ link DateTime . plus } . You may wish to use { @ link DateTime . toLocal } and { @ link DateTime . toUTC } which provide simple convenience wrappers for commonly used zones .
* @ param { string | Zone } [ zone = 'local' ] - a zone identifier . As a string , that can be any IANA zone supported by the host environment , or a fixed - offset name of the form 'UTC+3' , or the strings 'local' or 'utc' . You may also supply an instance of a { @ link DateTime . Zone } class .
* @ param { Object } opts - options
* @ param { boolean } [ opts . keepLocalTime = false ] - If true , adjust the underlying time so that the local time stays the same , but in the target zone . You should rarely need this .
* @ return { DateTime }
* /
;
_proto . setZone = function setZone ( zone , _temp ) {
var _ref3 = _temp === void 0 ? { } : _temp ,
_ref3$keepLocalTime = _ref3 . keepLocalTime ,
keepLocalTime = _ref3$keepLocalTime === void 0 ? false : _ref3$keepLocalTime ,
_ref3$keepCalendarTim = _ref3 . keepCalendarTime ,
keepCalendarTime = _ref3$keepCalendarTim === void 0 ? false : _ref3$keepCalendarTim ;
zone = normalizeZone ( zone , Settings . defaultZone ) ;
if ( zone . equals ( this . zone ) ) {
return this ;
} else if ( ! zone . isValid ) {
return DateTime . invalid ( unsupportedZone ( zone ) ) ;
} else {
var newTS = this . ts ;
if ( keepLocalTime || keepCalendarTime ) {
var offsetGuess = zone . offset ( this . ts ) ;
var asObj = this . toObject ( ) ;
var _objToTS3 = objToTS ( asObj , offsetGuess , zone ) ;
newTS = _objToTS3 [ 0 ] ;
}
return clone ( this , {
ts : newTS ,
zone : zone
} ) ;
}
}
/ * *
* "Set" the locale , numberingSystem , or outputCalendar . Returns a newly - constructed DateTime .
* @ param { Object } properties - the properties to set
* @ example DateTime . local ( 2017 , 5 , 25 ) . reconfigure ( { locale : 'en-GB' } )
* @ return { DateTime }
* /
;
_proto . reconfigure = function reconfigure ( _temp2 ) {
var _ref4 = _temp2 === void 0 ? { } : _temp2 ,
locale = _ref4 . locale ,
numberingSystem = _ref4 . numberingSystem ,
outputCalendar = _ref4 . outputCalendar ;
var loc = this . loc . clone ( {
locale : locale ,
numberingSystem : numberingSystem ,
outputCalendar : outputCalendar
} ) ;
return clone ( this , {
loc : loc
} ) ;
}
/ * *
* "Set" the locale . Returns a newly - constructed DateTime .
* Just a convenient alias for reconfigure ( { locale } )
* @ example DateTime . local ( 2017 , 5 , 25 ) . setLocale ( 'en-GB' )
* @ return { DateTime }
* /
;
_proto . setLocale = function setLocale ( locale ) {
return this . reconfigure ( {
locale : locale
} ) ;
}
/ * *
* "Set" the values of specified units . Returns a newly - constructed DateTime .
* You can only set units with this method ; for "setting" metadata , see { @ link DateTime . reconfigure } and { @ link DateTime . setZone } .
* @ param { Object } values - a mapping of units to numbers
* @ example dt . set ( { year : 2017 } )
* @ example dt . set ( { hour : 8 , minute : 30 } )
* @ example dt . set ( { weekday : 5 } )
* @ example dt . set ( { year : 2005 , ordinal : 234 } )
* @ return { DateTime }
* /
;
_proto . set = function set ( values ) {
if ( ! this . isValid ) return this ;
var normalized = normalizeObject ( values , normalizeUnit ) ,
settingWeekStuff = ! isUndefined ( normalized . weekYear ) || ! isUndefined ( normalized . weekNumber ) || ! isUndefined ( normalized . weekday ) ,
containsOrdinal = ! isUndefined ( normalized . ordinal ) ,
containsGregorYear = ! isUndefined ( normalized . year ) ,
containsGregorMD = ! isUndefined ( normalized . month ) || ! isUndefined ( normalized . day ) ,
containsGregor = containsGregorYear || containsGregorMD ,
definiteWeekDef = normalized . weekYear || normalized . weekNumber ;
if ( ( containsGregor || containsOrdinal ) && definiteWeekDef ) {
throw new ConflictingSpecificationError ( "Can't mix weekYear/weekNumber units with year/month/day or ordinals" ) ;
}
if ( containsGregorMD && containsOrdinal ) {
throw new ConflictingSpecificationError ( "Can't mix ordinal dates with month/day" ) ;
}
var mixed ;
if ( settingWeekStuff ) {
mixed = weekToGregorian ( _extends ( { } , gregorianToWeek ( this . c ) , normalized ) ) ;
} else if ( ! isUndefined ( normalized . ordinal ) ) {
mixed = ordinalToGregorian ( _extends ( { } , gregorianToOrdinal ( this . c ) , normalized ) ) ;
} else {
mixed = _extends ( { } , this . toObject ( ) , normalized ) ; // if we didn't set the day but we ended up on an overflow date,
// use the last day of the right month
if ( isUndefined ( normalized . day ) ) {
mixed . day = Math . min ( daysInMonth ( mixed . year , mixed . month ) , mixed . day ) ;
}
}
var _objToTS4 = objToTS ( mixed , this . o , this . zone ) ,
ts = _objToTS4 [ 0 ] ,
o = _objToTS4 [ 1 ] ;
return clone ( this , {
ts : ts ,
o : o
} ) ;
}
/ * *
* Add a period of time to this DateTime and return the resulting DateTime
*
* Adding hours , minutes , seconds , or milliseconds increases the timestamp by the right number of milliseconds . Adding days , months , or years shifts the calendar , accounting for DSTs and leap years along the way . Thus , ` dt.plus({ hours: 24 }) ` may result in a different time than ` dt.plus({ days: 1 }) ` if there ' s a DST shift in between .
* @ param { Duration | Object | number } duration - The amount to add . Either a Luxon Duration , a number of milliseconds , the object argument to Duration . fromObject ( )
* @ example DateTime . now ( ) . plus ( 123 ) //~> in 123 milliseconds
* @ example DateTime . now ( ) . plus ( { minutes : 15 } ) //~> in 15 minutes
* @ example DateTime . now ( ) . plus ( { days : 1 } ) //~> this time tomorrow
* @ example DateTime . now ( ) . plus ( { days : - 1 } ) //~> this time yesterday
* @ example DateTime . now ( ) . plus ( { hours : 3 , minutes : 13 } ) //~> in 3 hr, 13 min
* @ example DateTime . now ( ) . plus ( Duration . fromObject ( { hours : 3 , minutes : 13 } ) ) //~> in 3 hr, 13 min
* @ return { DateTime }
* /
;
_proto . plus = function plus ( duration ) {
if ( ! this . isValid ) return this ;
var dur = friendlyDuration ( duration ) ;
return clone ( this , adjustTime ( this , dur ) ) ;
}
/ * *
* Subtract a period of time to this DateTime and return the resulting DateTime
* See { @ link DateTime . plus }
* @ param { Duration | Object | number } duration - The amount to subtract . Either a Luxon Duration , a number of milliseconds , the object argument to Duration . fromObject ( )
@ return { DateTime }
* /
;
_proto . minus = function minus ( duration ) {
if ( ! this . isValid ) return this ;
var dur = friendlyDuration ( duration ) . negate ( ) ;
return clone ( this , adjustTime ( this , dur ) ) ;
}
/ * *
* "Set" this DateTime to the beginning of a unit of time .
* @ param { string } unit - The unit to go to the beginning of . Can be 'year' , 'quarter' , 'month' , 'week' , 'day' , 'hour' , 'minute' , 'second' , or 'millisecond' .
* @ example DateTime . local ( 2014 , 3 , 3 ) . startOf ( 'month' ) . toISODate ( ) ; //=> '2014-03-01'
* @ example DateTime . local ( 2014 , 3 , 3 ) . startOf ( 'year' ) . toISODate ( ) ; //=> '2014-01-01'
* @ example DateTime . local ( 2014 , 3 , 3 ) . startOf ( 'week' ) . toISODate ( ) ; //=> '2014-03-03', weeks always start on Mondays
* @ example DateTime . local ( 2014 , 3 , 3 , 5 , 30 ) . startOf ( 'day' ) . toISOTime ( ) ; //=> '00:00.000-05:00'
* @ example DateTime . local ( 2014 , 3 , 3 , 5 , 30 ) . startOf ( 'hour' ) . toISOTime ( ) ; //=> '05:00:00.000-05:00'
* @ return { DateTime }
* /
;
_proto . startOf = function startOf ( unit ) {
if ( ! this . isValid ) return this ;
var o = { } ,
normalizedUnit = Duration . normalizeUnit ( unit ) ;
switch ( normalizedUnit ) {
case "years" :
o . month = 1 ;
// falls through
case "quarters" :
case "months" :
o . day = 1 ;
// falls through
case "weeks" :
case "days" :
o . hour = 0 ;
// falls through
case "hours" :
o . minute = 0 ;
// falls through
case "minutes" :
o . second = 0 ;
// falls through
case "seconds" :
o . millisecond = 0 ;
break ;
// no default, invalid units throw in normalizeUnit()
}
if ( normalizedUnit === "weeks" ) {
o . weekday = 1 ;
}
if ( normalizedUnit === "quarters" ) {
var q = Math . ceil ( this . month / 3 ) ;
o . month = ( q - 1 ) * 3 + 1 ;
}
return this . set ( o ) ;
}
/ * *
* "Set" this DateTime to the end ( meaning the last millisecond ) of a unit of time
* @ param { string } unit - The unit to go to the end of . Can be 'year' , 'quarter' , 'month' , 'week' , 'day' , 'hour' , 'minute' , 'second' , or 'millisecond' .
* @ example DateTime . local ( 2014 , 3 , 3 ) . endOf ( 'month' ) . toISO ( ) ; //=> '2014-03-31T23:59:59.999-05:00'
* @ example DateTime . local ( 2014 , 3 , 3 ) . endOf ( 'year' ) . toISO ( ) ; //=> '2014-12-31T23:59:59.999-05:00'
* @ example DateTime . local ( 2014 , 3 , 3 ) . endOf ( 'week' ) . toISO ( ) ; // => '2014-03-09T23:59:59.999-05:00', weeks start on Mondays
* @ example DateTime . local ( 2014 , 3 , 3 , 5 , 30 ) . endOf ( 'day' ) . toISO ( ) ; //=> '2014-03-03T23:59:59.999-05:00'
* @ example DateTime . local ( 2014 , 3 , 3 , 5 , 30 ) . endOf ( 'hour' ) . toISO ( ) ; //=> '2014-03-03T05:59:59.999-05:00'
* @ return { DateTime }
* /
;
_proto . endOf = function endOf ( unit ) {
var _this$plus ;
return this . isValid ? this . plus ( ( _this$plus = { } , _this$plus [ unit ] = 1 , _this$plus ) ) . startOf ( unit ) . minus ( 1 ) : this ;
} // OUTPUT
/ * *
* Returns a string representation of this DateTime formatted according to the specified format string .
* * * You may not want this . * * See { @ link DateTime . toLocaleString } for a more flexible formatting tool . For a table of tokens and their interpretations , see [ here ] ( https : //moment.github.io/luxon/#/formatting?id=table-of-tokens).
* Defaults to en - US if no locale has been specified , regardless of the system ' s locale .
* @ param { string } fmt - the format string
* @ param { Object } opts - opts to override the configuration options on this DateTime
* @ example DateTime . now ( ) . toFormat ( 'yyyy LLL dd' ) //=> '2017 Apr 22'
* @ example DateTime . now ( ) . setLocale ( 'fr' ) . toFormat ( 'yyyy LLL dd' ) //=> '2017 avr. 22'
* @ example DateTime . now ( ) . toFormat ( 'yyyy LLL dd' , { locale : "fr" } ) //=> '2017 avr. 22'
* @ example DateTime . now ( ) . toFormat ( "HH 'hours and' mm 'minutes'" ) //=> '20 hours and 55 minutes'
* @ return { string }
* /
;
_proto . toFormat = function toFormat ( fmt , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
return this . isValid ? Formatter . create ( this . loc . redefaultToEN ( opts ) ) . formatDateTimeFromString ( this , fmt ) : INVALID ;
}
/ * *
* Returns a localized string representing this date . Accepts the same options as the Intl . DateTimeFormat constructor and any presets defined by Luxon , such as ` DateTime.DATE_FULL ` or ` DateTime.TIME_SIMPLE ` .
* The exact behavior of this method is browser - specific , but in general it will return an appropriate representation
* of the DateTime in the assigned locale .
* Defaults to the system ' s locale if no locale has been specified
* @ see https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
* @ param formatOpts { Object } - Intl . DateTimeFormat constructor options and configuration options
* @ param { Object } opts - opts to override the configuration options on this DateTime
* @ example DateTime . now ( ) . toLocaleString ( ) ; //=> 4/20/2017
* @ example DateTime . now ( ) . setLocale ( 'en-gb' ) . toLocaleString ( ) ; //=> '20/04/2017'
* @ example DateTime . now ( ) . toLocaleString ( { locale : 'en-gb' } ) ; //=> '20/04/2017'
* @ example DateTime . now ( ) . toLocaleString ( DateTime . DATE _FULL ) ; //=> 'April 20, 2017'
* @ example DateTime . now ( ) . toLocaleString ( DateTime . TIME _SIMPLE ) ; //=> '11:32 AM'
* @ example DateTime . now ( ) . toLocaleString ( DateTime . DATETIME _SHORT ) ; //=> '4/20/2017, 11:32 AM'
* @ example DateTime . now ( ) . toLocaleString ( { weekday : 'long' , month : 'long' , day : '2-digit' } ) ; //=> 'Thursday, April 20'
* @ example DateTime . now ( ) . toLocaleString ( { weekday : 'short' , month : 'short' , day : '2-digit' , hour : '2-digit' , minute : '2-digit' } ) ; //=> 'Thu, Apr 20, 11:27 AM'
* @ example DateTime . now ( ) . toLocaleString ( { hour : '2-digit' , minute : '2-digit' , hourCycle : 'h23' } ) ; //=> '11:32'
* @ return { string }
* /
;
_proto . toLocaleString = function toLocaleString ( formatOpts , opts ) {
if ( formatOpts === void 0 ) {
formatOpts = DATE _SHORT ;
}
if ( opts === void 0 ) {
opts = { } ;
}
return this . isValid ? Formatter . create ( this . loc . clone ( opts ) , formatOpts ) . formatDateTime ( this ) : INVALID ;
}
/ * *
* Returns an array of format "parts" , meaning individual tokens along with metadata . This is allows callers to post - process individual sections of the formatted output .
* Defaults to the system ' s locale if no locale has been specified
* @ see https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/formatToParts
* @ param opts { Object } - Intl . DateTimeFormat constructor options , same as ` toLocaleString ` .
* @ example DateTime . now ( ) . toLocaleParts ( ) ; //=> [
* //=> { type: 'day', value: '25' },
* //=> { type: 'literal', value: '/' },
* //=> { type: 'month', value: '05' },
* //=> { type: 'literal', value: '/' },
* //=> { type: 'year', value: '1982' }
* //=> ]
* /
;
_proto . toLocaleParts = function toLocaleParts ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
return this . isValid ? Formatter . create ( this . loc . clone ( opts ) , opts ) . formatDateTimeParts ( this ) : [ ] ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of this DateTime
* @ param { Object } opts - options
* @ param { boolean } [ opts . suppressMilliseconds = false ] - exclude milliseconds from the format if they ' re 0
* @ param { boolean } [ opts . suppressSeconds = false ] - exclude seconds from the format if they ' re 0
* @ param { boolean } [ opts . includeOffset = true ] - include the offset , such as 'Z' or '-04:00'
* @ param { string } [ opts . format = 'extended' ] - choose between the basic and extended format
* @ example DateTime . utc ( 1982 , 5 , 25 ) . toISO ( ) //=> '1982-05-25T00:00:00.000Z'
* @ example DateTime . now ( ) . toISO ( ) //=> '2017-04-22T20:47:05.335-04:00'
* @ example DateTime . now ( ) . toISO ( { includeOffset : false } ) //=> '2017-04-22T20:47:05.335'
* @ example DateTime . now ( ) . toISO ( { format : 'basic' } ) //=> '20170422T204705.335-0400'
* @ return { string }
* /
;
_proto . toISO = function toISO ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
if ( ! this . isValid ) {
return null ;
}
return this . toISODate ( opts ) + "T" + this . toISOTime ( opts ) ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of this DateTime ' s date component
* @ param { Object } opts - options
* @ param { string } [ opts . format = 'extended' ] - choose between the basic and extended format
* @ example DateTime . utc ( 1982 , 5 , 25 ) . toISODate ( ) //=> '1982-05-25'
* @ example DateTime . utc ( 1982 , 5 , 25 ) . toISODate ( { format : 'basic' } ) //=> '19820525'
* @ return { string }
* /
;
_proto . toISODate = function toISODate ( _temp3 ) {
var _ref5 = _temp3 === void 0 ? { } : _temp3 ,
_ref5$format = _ref5 . format ,
format = _ref5$format === void 0 ? "extended" : _ref5$format ;
var fmt = format === "basic" ? "yyyyMMdd" : "yyyy-MM-dd" ;
if ( this . year > 9999 ) {
fmt = "+" + fmt ;
}
return toTechFormat ( this , fmt ) ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of this DateTime ' s week date
* @ example DateTime . utc ( 1982 , 5 , 25 ) . toISOWeekDate ( ) //=> '1982-W21-2'
* @ return { string }
* /
;
_proto . toISOWeekDate = function toISOWeekDate ( ) {
return toTechFormat ( this , "kkkk-'W'WW-c" ) ;
}
/ * *
* Returns an ISO 8601 - compliant string representation of this DateTime ' s time component
* @ param { Object } opts - options
* @ param { boolean } [ opts . suppressMilliseconds = false ] - exclude milliseconds from the format if they ' re 0
* @ param { boolean } [ opts . suppressSeconds = false ] - exclude seconds from the format if they ' re 0
* @ param { boolean } [ opts . includeOffset = true ] - include the offset , such as 'Z' or '-04:00'
* @ param { boolean } [ opts . includePrefix = false ] - include the ` T ` prefix
* @ param { string } [ opts . format = 'extended' ] - choose between the basic and extended format
* @ example DateTime . utc ( ) . set ( { hour : 7 , minute : 34 } ) . toISOTime ( ) //=> '07:34:19.361Z'
* @ example DateTime . utc ( ) . set ( { hour : 7 , minute : 34 , seconds : 0 , milliseconds : 0 } ) . toISOTime ( { suppressSeconds : true } ) //=> '07:34Z'
* @ example DateTime . utc ( ) . set ( { hour : 7 , minute : 34 } ) . toISOTime ( { format : 'basic' } ) //=> '073419.361Z'
* @ example DateTime . utc ( ) . set ( { hour : 7 , minute : 34 } ) . toISOTime ( { includePrefix : true } ) //=> 'T07:34:19.361Z'
* @ return { string }
* /
;
_proto . toISOTime = function toISOTime ( _temp4 ) {
var _ref6 = _temp4 === void 0 ? { } : _temp4 ,
_ref6$suppressMillise = _ref6 . suppressMilliseconds ,
suppressMilliseconds = _ref6$suppressMillise === void 0 ? false : _ref6$suppressMillise ,
_ref6$suppressSeconds = _ref6 . suppressSeconds ,
suppressSeconds = _ref6$suppressSeconds === void 0 ? false : _ref6$suppressSeconds ,
_ref6$includeOffset = _ref6 . includeOffset ,
includeOffset = _ref6$includeOffset === void 0 ? true : _ref6$includeOffset ,
_ref6$includePrefix = _ref6 . includePrefix ,
includePrefix = _ref6$includePrefix === void 0 ? false : _ref6$includePrefix ,
_ref6$format = _ref6 . format ,
format = _ref6$format === void 0 ? "extended" : _ref6$format ;
return toTechTimeFormat ( this , {
suppressSeconds : suppressSeconds ,
suppressMilliseconds : suppressMilliseconds ,
includeOffset : includeOffset ,
includePrefix : includePrefix ,
format : format
} ) ;
}
/ * *
* Returns an RFC 2822 - compatible string representation of this DateTime , always in UTC
* @ example DateTime . utc ( 2014 , 7 , 13 ) . toRFC2822 ( ) //=> 'Sun, 13 Jul 2014 00:00:00 +0000'
* @ example DateTime . local ( 2014 , 7 , 13 ) . toRFC2822 ( ) //=> 'Sun, 13 Jul 2014 00:00:00 -0400'
* @ return { string }
* /
;
_proto . toRFC2822 = function toRFC2822 ( ) {
return toTechFormat ( this , "EEE, dd LLL yyyy HH:mm:ss ZZZ" , false ) ;
}
/ * *
* Returns a string representation of this DateTime appropriate for use in HTTP headers .
* Specifically , the string conforms to RFC 1123.
* @ see https : //www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
* @ example DateTime . utc ( 2014 , 7 , 13 ) . toHTTP ( ) //=> 'Sun, 13 Jul 2014 00:00:00 GMT'
* @ example DateTime . utc ( 2014 , 7 , 13 , 19 ) . toHTTP ( ) //=> 'Sun, 13 Jul 2014 19:00:00 GMT'
* @ return { string }
* /
;
_proto . toHTTP = function toHTTP ( ) {
return toTechFormat ( this . toUTC ( ) , "EEE, dd LLL yyyy HH:mm:ss 'GMT'" ) ;
}
/ * *
* Returns a string representation of this DateTime appropriate for use in SQL Date
* @ example DateTime . utc ( 2014 , 7 , 13 ) . toSQLDate ( ) //=> '2014-07-13'
* @ return { string }
* /
;
_proto . toSQLDate = function toSQLDate ( ) {
return toTechFormat ( this , "yyyy-MM-dd" ) ;
}
/ * *
* Returns a string representation of this DateTime appropriate for use in SQL Time
* @ param { Object } opts - options
* @ param { boolean } [ opts . includeZone = false ] - include the zone , such as 'America/New_York' . Overrides includeOffset .
* @ param { boolean } [ opts . includeOffset = true ] - include the offset , such as 'Z' or '-04:00'
* @ example DateTime . utc ( ) . toSQL ( ) //=> '05:15:16.345'
* @ example DateTime . now ( ) . toSQL ( ) //=> '05:15:16.345 -04:00'
* @ example DateTime . now ( ) . toSQL ( { includeOffset : false } ) //=> '05:15:16.345'
* @ example DateTime . now ( ) . toSQL ( { includeZone : false } ) //=> '05:15:16.345 America/New_York'
* @ return { string }
* /
;
_proto . toSQLTime = function toSQLTime ( _temp5 ) {
var _ref7 = _temp5 === void 0 ? { } : _temp5 ,
_ref7$includeOffset = _ref7 . includeOffset ,
includeOffset = _ref7$includeOffset === void 0 ? true : _ref7$includeOffset ,
_ref7$includeZone = _ref7 . includeZone ,
includeZone = _ref7$includeZone === void 0 ? false : _ref7$includeZone ;
return toTechTimeFormat ( this , {
includeOffset : includeOffset ,
includeZone : includeZone ,
spaceZone : true
} ) ;
}
/ * *
* Returns a string representation of this DateTime appropriate for use in SQL DateTime
* @ param { Object } opts - options
* @ param { boolean } [ opts . includeZone = false ] - include the zone , such as 'America/New_York' . Overrides includeOffset .
* @ param { boolean } [ opts . includeOffset = true ] - include the offset , such as 'Z' or '-04:00'
* @ example DateTime . utc ( 2014 , 7 , 13 ) . toSQL ( ) //=> '2014-07-13 00:00:00.000 Z'
* @ example DateTime . local ( 2014 , 7 , 13 ) . toSQL ( ) //=> '2014-07-13 00:00:00.000 -04:00'
* @ example DateTime . local ( 2014 , 7 , 13 ) . toSQL ( { includeOffset : false } ) //=> '2014-07-13 00:00:00.000'
* @ example DateTime . local ( 2014 , 7 , 13 ) . toSQL ( { includeZone : true } ) //=> '2014-07-13 00:00:00.000 America/New_York'
* @ return { string }
* /
;
_proto . toSQL = function toSQL ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
if ( ! this . isValid ) {
return null ;
}
return this . toSQLDate ( ) + " " + this . toSQLTime ( opts ) ;
}
/ * *
* Returns a string representation of this DateTime appropriate for debugging
* @ return { string }
* /
;
_proto . toString = function toString ( ) {
return this . isValid ? this . toISO ( ) : INVALID ;
}
/ * *
* Returns the epoch milliseconds of this DateTime . Alias of { @ link DateTime . toMillis }
* @ return { number }
* /
;
_proto . valueOf = function valueOf ( ) {
return this . toMillis ( ) ;
}
/ * *
* Returns the epoch milliseconds of this DateTime .
* @ return { number }
* /
;
_proto . toMillis = function toMillis ( ) {
return this . isValid ? this . ts : NaN ;
}
/ * *
* Returns the epoch seconds of this DateTime .
* @ return { number }
* /
;
_proto . toSeconds = function toSeconds ( ) {
return this . isValid ? this . ts / 1000 : NaN ;
}
/ * *
* Returns an ISO 8601 representation of this DateTime appropriate for use in JSON .
* @ return { string }
* /
;
_proto . toJSON = function toJSON ( ) {
return this . toISO ( ) ;
}
/ * *
* Returns a BSON serializable equivalent to this DateTime .
* @ return { Date }
* /
;
_proto . toBSON = function toBSON ( ) {
return this . toJSDate ( ) ;
}
/ * *
* Returns a JavaScript object with this DateTime ' s year , month , day , and so on .
* @ param opts - options for generating the object
* @ param { boolean } [ opts . includeConfig = false ] - include configuration attributes in the output
* @ example DateTime . now ( ) . toObject ( ) //=> { year: 2017, month: 4, day: 22, hour: 20, minute: 49, second: 42, millisecond: 268 }
* @ return { Object }
* /
;
_proto . toObject = function toObject ( opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
if ( ! this . isValid ) return { } ;
var base = _extends ( { } , this . c ) ;
if ( opts . includeConfig ) {
base . outputCalendar = this . outputCalendar ;
base . numberingSystem = this . loc . numberingSystem ;
base . locale = this . loc . locale ;
}
return base ;
}
/ * *
* Returns a JavaScript Date equivalent to this DateTime .
* @ return { Date }
* /
;
_proto . toJSDate = function toJSDate ( ) {
return new Date ( this . isValid ? this . ts : NaN ) ;
} // COMPARE
/ * *
* Return the difference between two DateTimes as a Duration .
* @ param { DateTime } otherDateTime - the DateTime to compare this one to
* @ param { string | string [ ] } [ unit = [ 'milliseconds' ] ] - the unit or array of units ( such as 'hours' or 'days' ) to include in the duration .
* @ param { Object } opts - options that affect the creation of the Duration
* @ param { string } [ opts . conversionAccuracy = 'casual' ] - the conversion system to use
* @ example
* var i1 = DateTime . fromISO ( '1982-05-25T09:45' ) ,
* i2 = DateTime . fromISO ( '1983-10-14T10:30' ) ;
* i2 . diff ( i1 ) . toObject ( ) //=> { milliseconds: 43807500000 }
* i2 . diff ( i1 , 'hours' ) . toObject ( ) //=> { hours: 12168.75 }
* i2 . diff ( i1 , [ 'months' , 'days' ] ) . toObject ( ) //=> { months: 16, days: 19.03125 }
* i2 . diff ( i1 , [ 'months' , 'days' , 'hours' ] ) . toObject ( ) //=> { months: 16, days: 19, hours: 0.75 }
* @ return { Duration }
* /
;
_proto . diff = function diff ( otherDateTime , unit , opts ) {
if ( unit === void 0 ) {
unit = "milliseconds" ;
}
if ( opts === void 0 ) {
opts = { } ;
}
if ( ! this . isValid || ! otherDateTime . isValid ) {
return Duration . invalid ( "created by diffing an invalid DateTime" ) ;
}
var durOpts = _extends ( {
locale : this . locale ,
numberingSystem : this . numberingSystem
} , opts ) ;
var units = maybeArray ( unit ) . map ( Duration . normalizeUnit ) ,
otherIsLater = otherDateTime . valueOf ( ) > this . valueOf ( ) ,
earlier = otherIsLater ? this : otherDateTime ,
later = otherIsLater ? otherDateTime : this ,
diffed = _diff ( earlier , later , units , durOpts ) ;
return otherIsLater ? diffed . negate ( ) : diffed ;
}
/ * *
* Return the difference between this DateTime and right now .
* See { @ link DateTime . diff }
* @ param { string | string [ ] } [ unit = [ 'milliseconds' ] ] - the unit or units units ( such as 'hours' or 'days' ) to include in the duration
* @ param { Object } opts - options that affect the creation of the Duration
* @ param { string } [ opts . conversionAccuracy = 'casual' ] - the conversion system to use
* @ return { Duration }
* /
;
_proto . diffNow = function diffNow ( unit , opts ) {
if ( unit === void 0 ) {
unit = "milliseconds" ;
}
if ( opts === void 0 ) {
opts = { } ;
}
return this . diff ( DateTime . now ( ) , unit , opts ) ;
}
/ * *
* Return an Interval spanning between this DateTime and another DateTime
* @ param { DateTime } otherDateTime - the other end point of the Interval
* @ return { Interval }
* /
;
_proto . until = function until ( otherDateTime ) {
return this . isValid ? Interval . fromDateTimes ( this , otherDateTime ) : this ;
}
/ * *
* Return whether this DateTime is in the same unit of time as another DateTime .
* Higher - order units must also be identical for this function to return ` true ` .
* Note that time zones are * * ignored * * in this comparison , which compares the * * local * * calendar time . Use { @ link DateTime . setZone } to convert one of the dates if needed .
* @ param { DateTime } otherDateTime - the other DateTime
* @ param { string } unit - the unit of time to check sameness on
* @ example DateTime . now ( ) . hasSame ( otherDT , 'day' ) ; //~> true if otherDT is in the same current calendar day
* @ return { boolean }
* /
;
_proto . hasSame = function hasSame ( otherDateTime , unit ) {
if ( ! this . isValid ) return false ;
var inputMs = otherDateTime . valueOf ( ) ;
var otherZoneDateTime = this . setZone ( otherDateTime . zone , {
keepLocalTime : true
} ) ;
return otherZoneDateTime . startOf ( unit ) <= inputMs && inputMs <= otherZoneDateTime . endOf ( unit ) ;
}
/ * *
* Equality check
* Two DateTimes are equal iff they represent the same millisecond , have the same zone and location , and are both valid .
* To compare just the millisecond values , use ` +dt1 === +dt2 ` .
* @ param { DateTime } other - the other DateTime
* @ return { boolean }
* /
;
_proto . equals = function equals ( other ) {
return this . isValid && other . isValid && this . valueOf ( ) === other . valueOf ( ) && this . zone . equals ( other . zone ) && this . loc . equals ( other . loc ) ;
}
/ * *
* Returns a string representation of a this time relative to now , such as "in two days" . Can only internationalize if your
* platform supports Intl . RelativeTimeFormat . Rounds down by default .
* @ param { Object } options - options that affect the output
* @ param { DateTime } [ options . base = DateTime . now ( ) ] - the DateTime to use as the basis to which this time is compared . Defaults to now .
* @ param { string } [ options . style = "long" ] - the style of units , must be "long" , "short" , or "narrow"
* @ param { string | string [ ] } options . unit - use a specific unit or array of units ; if omitted , or an array , the method will pick the best unit . Use an array or one of "years" , "quarters" , "months" , "weeks" , "days" , "hours" , "minutes" , or "seconds"
* @ param { boolean } [ options . round = true ] - whether to round the numbers in the output .
* @ param { number } [ options . padding = 0 ] - padding in milliseconds . This allows you to round up the result if it fits inside the threshold . Don ' t use in combination with { round : false } because the decimal output will include the padding .
* @ param { string } options . locale - override the locale of this DateTime
* @ param { string } options . numberingSystem - override the numberingSystem of this DateTime . The Intl system may choose not to honor this
* @ example DateTime . now ( ) . plus ( { days : 1 } ) . toRelative ( ) //=> "in 1 day"
* @ example DateTime . now ( ) . setLocale ( "es" ) . toRelative ( { days : 1 } ) //=> "dentro de 1 día"
* @ example DateTime . now ( ) . plus ( { days : 1 } ) . toRelative ( { locale : "fr" } ) //=> "dans 23 heures"
* @ example DateTime . now ( ) . minus ( { days : 2 } ) . toRelative ( ) //=> "2 days ago"
* @ example DateTime . now ( ) . minus ( { days : 2 } ) . toRelative ( { unit : "hours" } ) //=> "48 hours ago"
* @ example DateTime . now ( ) . minus ( { hours : 36 } ) . toRelative ( { round : false } ) //=> "1.5 days ago"
* /
;
_proto . toRelative = function toRelative ( options ) {
if ( options === void 0 ) {
options = { } ;
}
if ( ! this . isValid ) return null ;
var base = options . base || DateTime . fromObject ( { } , {
zone : this . zone
} ) ,
padding = options . padding ? this < base ? - options . padding : options . padding : 0 ;
var units = [ "years" , "months" , "days" , "hours" , "minutes" , "seconds" ] ;
var unit = options . unit ;
if ( Array . isArray ( options . unit ) ) {
units = options . unit ;
unit = undefined ;
}
return diffRelative ( base , this . plus ( padding ) , _extends ( { } , options , {
numeric : "always" ,
units : units ,
unit : unit
} ) ) ;
}
/ * *
* Returns a string representation of this date relative to today , such as "yesterday" or "next month" .
* Only internationalizes on platforms that supports Intl . RelativeTimeFormat .
* @ param { Object } options - options that affect the output
* @ param { DateTime } [ options . base = DateTime . now ( ) ] - the DateTime to use as the basis to which this time is compared . Defaults to now .
* @ param { string } options . locale - override the locale of this DateTime
* @ param { string } options . unit - use a specific unit ; if omitted , the method will pick the unit . Use one of "years" , "quarters" , "months" , "weeks" , or "days"
* @ param { string } options . numberingSystem - override the numberingSystem of this DateTime . The Intl system may choose not to honor this
* @ example DateTime . now ( ) . plus ( { days : 1 } ) . toRelativeCalendar ( ) //=> "tomorrow"
* @ example DateTime . now ( ) . setLocale ( "es" ) . plus ( { days : 1 } ) . toRelative ( ) //=> ""mañana"
* @ example DateTime . now ( ) . plus ( { days : 1 } ) . toRelativeCalendar ( { locale : "fr" } ) //=> "demain"
* @ example DateTime . now ( ) . minus ( { days : 2 } ) . toRelativeCalendar ( ) //=> "2 days ago"
* /
;
_proto . toRelativeCalendar = function toRelativeCalendar ( options ) {
if ( options === void 0 ) {
options = { } ;
}
if ( ! this . isValid ) return null ;
return diffRelative ( options . base || DateTime . fromObject ( { } , {
zone : this . zone
} ) , this , _extends ( { } , options , {
numeric : "auto" ,
units : [ "years" , "months" , "days" ] ,
calendary : true
} ) ) ;
}
/ * *
* Return the min of several date times
* @ param { ... DateTime } dateTimes - the DateTimes from which to choose the minimum
* @ return { DateTime } the min DateTime , or undefined if called with no argument
* /
;
DateTime . min = function min ( ) {
for ( var _len = arguments . length , dateTimes = new Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
dateTimes [ _key ] = arguments [ _key ] ;
}
if ( ! dateTimes . every ( DateTime . isDateTime ) ) {
throw new InvalidArgumentError ( "min requires all arguments be DateTimes" ) ;
}
return bestBy ( dateTimes , function ( i ) {
return i . valueOf ( ) ;
} , Math . min ) ;
}
/ * *
* Return the max of several date times
* @ param { ... DateTime } dateTimes - the DateTimes from which to choose the maximum
* @ return { DateTime } the max DateTime , or undefined if called with no argument
* /
;
DateTime . max = function max ( ) {
for ( var _len2 = arguments . length , dateTimes = new Array ( _len2 ) , _key2 = 0 ; _key2 < _len2 ; _key2 ++ ) {
dateTimes [ _key2 ] = arguments [ _key2 ] ;
}
if ( ! dateTimes . every ( DateTime . isDateTime ) ) {
throw new InvalidArgumentError ( "max requires all arguments be DateTimes" ) ;
}
return bestBy ( dateTimes , function ( i ) {
return i . valueOf ( ) ;
} , Math . max ) ;
} // MISC
/ * *
* Explain how a string would be parsed by fromFormat ( )
* @ param { string } text - the string to parse
* @ param { string } fmt - the format the string is expected to be in ( see description )
* @ param { Object } options - options taken by fromFormat ( )
* @ return { Object }
* /
;
DateTime . fromFormatExplain = function fromFormatExplain ( text , fmt , options ) {
if ( options === void 0 ) {
options = { } ;
}
var _options = options ,
_options$locale = _options . locale ,
locale = _options$locale === void 0 ? null : _options$locale ,
_options$numberingSys = _options . numberingSystem ,
numberingSystem = _options$numberingSys === void 0 ? null : _options$numberingSys ,
localeToUse = Locale . fromOpts ( {
locale : locale ,
numberingSystem : numberingSystem ,
defaultToEN : true
} ) ;
return explainFromTokens ( localeToUse , text , fmt ) ;
}
/ * *
* @ deprecated use fromFormatExplain instead
* /
;
DateTime . fromStringExplain = function fromStringExplain ( text , fmt , options ) {
if ( options === void 0 ) {
options = { } ;
}
return DateTime . fromFormatExplain ( text , fmt , options ) ;
} // FORMAT PRESETS
/ * *
* { @ link DateTime . toLocaleString } format like 10 / 14 / 1983
* @ type { Object }
* /
;
_createClass ( DateTime , [ {
key : "isValid" ,
get : function get ( ) {
return this . invalid === null ;
}
/ * *
* Returns an error code if this DateTime is invalid , or null if the DateTime is valid
* @ type { string }
* /
} , {
key : "invalidReason" ,
get : function get ( ) {
return this . invalid ? this . invalid . reason : null ;
}
/ * *
* Returns an explanation of why this DateTime became invalid , or null if the DateTime is valid
* @ type { string }
* /
} , {
key : "invalidExplanation" ,
get : function get ( ) {
return this . invalid ? this . invalid . explanation : null ;
}
/ * *
* Get the locale of a DateTime , such 'en-GB' . The locale is used when formatting the DateTime
*
* @ type { string }
* /
} , {
key : "locale" ,
get : function get ( ) {
return this . isValid ? this . loc . locale : null ;
}
/ * *
* Get the numbering system of a DateTime , such 'beng' . The numbering system is used when formatting the DateTime
*
* @ type { string }
* /
} , {
key : "numberingSystem" ,
get : function get ( ) {
return this . isValid ? this . loc . numberingSystem : null ;
}
/ * *
* Get the output calendar of a DateTime , such 'islamic' . The output calendar is used when formatting the DateTime
*
* @ type { string }
* /
} , {
key : "outputCalendar" ,
get : function get ( ) {
return this . isValid ? this . loc . outputCalendar : null ;
}
/ * *
* Get the time zone associated with this DateTime .
* @ type { Zone }
* /
} , {
key : "zone" ,
get : function get ( ) {
return this . _zone ;
}
/ * *
* Get the name of the time zone .
* @ type { string }
* /
} , {
key : "zoneName" ,
get : function get ( ) {
return this . isValid ? this . zone . name : null ;
}
/ * *
* Get the year
* @ example DateTime . local ( 2017 , 5 , 25 ) . year //=> 2017
* @ type { number }
* /
} , {
key : "year" ,
get : function get ( ) {
return this . isValid ? this . c . year : NaN ;
}
/ * *
* Get the quarter
* @ example DateTime . local ( 2017 , 5 , 25 ) . quarter //=> 2
* @ type { number }
* /
} , {
key : "quarter" ,
get : function get ( ) {
return this . isValid ? Math . ceil ( this . c . month / 3 ) : NaN ;
}
/ * *
* Get the month ( 1 - 12 ) .
* @ example DateTime . local ( 2017 , 5 , 25 ) . month //=> 5
* @ type { number }
* /
} , {
key : "month" ,
get : function get ( ) {
return this . isValid ? this . c . month : NaN ;
}
/ * *
* Get the day of the month ( 1 - 30 ish ) .
* @ example DateTime . local ( 2017 , 5 , 25 ) . day //=> 25
* @ type { number }
* /
} , {
key : "day" ,
get : function get ( ) {
return this . isValid ? this . c . day : NaN ;
}
/ * *
* Get the hour of the day ( 0 - 23 ) .
* @ example DateTime . local ( 2017 , 5 , 25 , 9 ) . hour //=> 9
* @ type { number }
* /
} , {
key : "hour" ,
get : function get ( ) {
return this . isValid ? this . c . hour : NaN ;
}
/ * *
* Get the minute of the hour ( 0 - 59 ) .
* @ example DateTime . local ( 2017 , 5 , 25 , 9 , 30 ) . minute //=> 30
* @ type { number }
* /
} , {
key : "minute" ,
get : function get ( ) {
return this . isValid ? this . c . minute : NaN ;
}
/ * *
* Get the second of the minute ( 0 - 59 ) .
* @ example DateTime . local ( 2017 , 5 , 25 , 9 , 30 , 52 ) . second //=> 52
* @ type { number }
* /
} , {
key : "second" ,
get : function get ( ) {
return this . isValid ? this . c . second : NaN ;
}
/ * *
* Get the millisecond of the second ( 0 - 999 ) .
* @ example DateTime . local ( 2017 , 5 , 25 , 9 , 30 , 52 , 654 ) . millisecond //=> 654
* @ type { number }
* /
} , {
key : "millisecond" ,
get : function get ( ) {
return this . isValid ? this . c . millisecond : NaN ;
}
/ * *
* Get the week year
* @ see https : //en.wikipedia.org/wiki/ISO_week_date
* @ example DateTime . local ( 2014 , 12 , 31 ) . weekYear //=> 2015
* @ type { number }
* /
} , {
key : "weekYear" ,
get : function get ( ) {
return this . isValid ? possiblyCachedWeekData ( this ) . weekYear : NaN ;
}
/ * *
* Get the week number of the week year ( 1 - 52 ish ) .
* @ see https : //en.wikipedia.org/wiki/ISO_week_date
* @ example DateTime . local ( 2017 , 5 , 25 ) . weekNumber //=> 21
* @ type { number }
* /
} , {
key : "weekNumber" ,
get : function get ( ) {
return this . isValid ? possiblyCachedWeekData ( this ) . weekNumber : NaN ;
}
/ * *
* Get the day of the week .
* 1 is Monday and 7 is Sunday
* @ see https : //en.wikipedia.org/wiki/ISO_week_date
* @ example DateTime . local ( 2014 , 11 , 31 ) . weekday //=> 4
* @ type { number }
* /
} , {
key : "weekday" ,
get : function get ( ) {
return this . isValid ? possiblyCachedWeekData ( this ) . weekday : NaN ;
}
/ * *
* Get the ordinal ( meaning the day of the year )
* @ example DateTime . local ( 2017 , 5 , 25 ) . ordinal //=> 145
* @ type { number | DateTime }
* /
} , {
key : "ordinal" ,
get : function get ( ) {
return this . isValid ? gregorianToOrdinal ( this . c ) . ordinal : NaN ;
}
/ * *
* Get the human readable short month name , such as 'Oct' .
* Defaults to the system ' s locale if no locale has been specified
* @ example DateTime . local ( 2017 , 10 , 30 ) . monthShort //=> Oct
* @ type { string }
* /
} , {
key : "monthShort" ,
get : function get ( ) {
return this . isValid ? Info . months ( "short" , {
locObj : this . loc
} ) [ this . month - 1 ] : null ;
}
/ * *
* Get the human readable long month name , such as 'October' .
* Defaults to the system ' s locale if no locale has been specified
* @ example DateTime . local ( 2017 , 10 , 30 ) . monthLong //=> October
* @ type { string }
* /
} , {
key : "monthLong" ,
get : function get ( ) {
return this . isValid ? Info . months ( "long" , {
locObj : this . loc
} ) [ this . month - 1 ] : null ;
}
/ * *
* Get the human readable short weekday , such as 'Mon' .
* Defaults to the system ' s locale if no locale has been specified
* @ example DateTime . local ( 2017 , 10 , 30 ) . weekdayShort //=> Mon
* @ type { string }
* /
} , {
key : "weekdayShort" ,
get : function get ( ) {
return this . isValid ? Info . weekdays ( "short" , {
locObj : this . loc
} ) [ this . weekday - 1 ] : null ;
}
/ * *
* Get the human readable long weekday , such as 'Monday' .
* Defaults to the system ' s locale if no locale has been specified
* @ example DateTime . local ( 2017 , 10 , 30 ) . weekdayLong //=> Monday
* @ type { string }
* /
} , {
key : "weekdayLong" ,
get : function get ( ) {
return this . isValid ? Info . weekdays ( "long" , {
locObj : this . loc
} ) [ this . weekday - 1 ] : null ;
}
/ * *
* Get the UTC offset of this DateTime in minutes
* @ example DateTime . now ( ) . offset //=> -240
* @ example DateTime . utc ( ) . offset //=> 0
* @ type { number }
* /
} , {
key : "offset" ,
get : function get ( ) {
return this . isValid ? + this . o : NaN ;
}
/ * *
* Get the short human name for the zone ' s current offset , for example "EST" or "EDT" .
* Defaults to the system ' s locale if no locale has been specified
* @ type { string }
* /
} , {
key : "offsetNameShort" ,
get : function get ( ) {
if ( this . isValid ) {
return this . zone . offsetName ( this . ts , {
format : "short" ,
locale : this . locale
} ) ;
} else {
return null ;
}
}
/ * *
* Get the long human name for the zone ' s current offset , for example "Eastern Standard Time" or "Eastern Daylight Time" .
* Defaults to the system ' s locale if no locale has been specified
* @ type { string }
* /
} , {
key : "offsetNameLong" ,
get : function get ( ) {
if ( this . isValid ) {
return this . zone . offsetName ( this . ts , {
format : "long" ,
locale : this . locale
} ) ;
} else {
return null ;
}
}
/ * *
* Get whether this zone ' s offset ever changes , as in a DST .
* @ type { boolean }
* /
} , {
key : "isOffsetFixed" ,
get : function get ( ) {
return this . isValid ? this . zone . isUniversal : null ;
}
/ * *
* Get whether the DateTime is in a DST .
* @ type { boolean }
* /
} , {
key : "isInDST" ,
get : function get ( ) {
if ( this . isOffsetFixed ) {
return false ;
} else {
return this . offset > this . set ( {
month : 1
} ) . offset || this . offset > this . set ( {
month : 5
} ) . offset ;
}
}
/ * *
* Returns true if this DateTime is in a leap year , false otherwise
* @ example DateTime . local ( 2016 ) . isInLeapYear //=> true
* @ example DateTime . local ( 2013 ) . isInLeapYear //=> false
* @ type { boolean }
* /
} , {
key : "isInLeapYear" ,
get : function get ( ) {
return isLeapYear ( this . year ) ;
}
/ * *
* Returns the number of days in this DateTime ' s month
* @ example DateTime . local ( 2016 , 2 ) . daysInMonth //=> 29
* @ example DateTime . local ( 2016 , 3 ) . daysInMonth //=> 31
* @ type { number }
* /
} , {
key : "daysInMonth" ,
get : function get ( ) {
return daysInMonth ( this . year , this . month ) ;
}
/ * *
* Returns the number of days in this DateTime ' s year
* @ example DateTime . local ( 2016 ) . daysInYear //=> 366
* @ example DateTime . local ( 2013 ) . daysInYear //=> 365
* @ type { number }
* /
} , {
key : "daysInYear" ,
get : function get ( ) {
return this . isValid ? daysInYear ( this . year ) : NaN ;
}
/ * *
* Returns the number of weeks in this DateTime ' s year
* @ see https : //en.wikipedia.org/wiki/ISO_week_date
* @ example DateTime . local ( 2004 ) . weeksInWeekYear //=> 53
* @ example DateTime . local ( 2013 ) . weeksInWeekYear //=> 52
* @ type { number }
* /
} , {
key : "weeksInWeekYear" ,
get : function get ( ) {
return this . isValid ? weeksInWeekYear ( this . weekYear ) : NaN ;
}
} ] , [ {
key : "DATE_SHORT" ,
get : function get ( ) {
return DATE _SHORT ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Oct 14, 1983'
* @ type { Object }
* /
} , {
key : "DATE_MED" ,
get : function get ( ) {
return DATE _MED ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Fri, Oct 14, 1983'
* @ type { Object }
* /
} , {
key : "DATE_MED_WITH_WEEKDAY" ,
get : function get ( ) {
return DATE _MED _WITH _WEEKDAY ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'October 14, 1983'
* @ type { Object }
* /
} , {
key : "DATE_FULL" ,
get : function get ( ) {
return DATE _FULL ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Tuesday, October 14, 1983'
* @ type { Object }
* /
} , {
key : "DATE_HUGE" ,
get : function get ( ) {
return DATE _HUGE ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30 AM' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "TIME_SIMPLE" ,
get : function get ( ) {
return TIME _SIMPLE ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30:23 AM' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "TIME_WITH_SECONDS" ,
get : function get ( ) {
return TIME _WITH _SECONDS ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30:23 AM EDT' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "TIME_WITH_SHORT_OFFSET" ,
get : function get ( ) {
return TIME _WITH _SHORT _OFFSET ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30:23 AM Eastern Daylight Time' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "TIME_WITH_LONG_OFFSET" ,
get : function get ( ) {
return TIME _WITH _LONG _OFFSET ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30' , always 24 - hour .
* @ type { Object }
* /
} , {
key : "TIME_24_SIMPLE" ,
get : function get ( ) {
return TIME _24 _SIMPLE ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30:23' , always 24 - hour .
* @ type { Object }
* /
} , {
key : "TIME_24_WITH_SECONDS" ,
get : function get ( ) {
return TIME _24 _WITH _SECONDS ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30:23 EDT' , always 24 - hour .
* @ type { Object }
* /
} , {
key : "TIME_24_WITH_SHORT_OFFSET" ,
get : function get ( ) {
return TIME _24 _WITH _SHORT _OFFSET ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '09:30:23 Eastern Daylight Time' , always 24 - hour .
* @ type { Object }
* /
} , {
key : "TIME_24_WITH_LONG_OFFSET" ,
get : function get ( ) {
return TIME _24 _WITH _LONG _OFFSET ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '10/14/1983, 9:30 AM' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_SHORT" ,
get : function get ( ) {
return DATETIME _SHORT ;
}
/ * *
* { @ link DateTime . toLocaleString } format like '10/14/1983, 9:30:33 AM' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_SHORT_WITH_SECONDS" ,
get : function get ( ) {
return DATETIME _SHORT _WITH _SECONDS ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Oct 14, 1983, 9:30 AM' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_MED" ,
get : function get ( ) {
return DATETIME _MED ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Oct 14, 1983, 9:30:33 AM' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_MED_WITH_SECONDS" ,
get : function get ( ) {
return DATETIME _MED _WITH _SECONDS ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Fri, 14 Oct 1983, 9:30 AM' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_MED_WITH_WEEKDAY" ,
get : function get ( ) {
return DATETIME _MED _WITH _WEEKDAY ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'October 14, 1983, 9:30 AM EDT' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_FULL" ,
get : function get ( ) {
return DATETIME _FULL ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'October 14, 1983, 9:30:33 AM EDT' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_FULL_WITH_SECONDS" ,
get : function get ( ) {
return DATETIME _FULL _WITH _SECONDS ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Friday, October 14, 1983, 9:30 AM Eastern Daylight Time' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_HUGE" ,
get : function get ( ) {
return DATETIME _HUGE ;
}
/ * *
* { @ link DateTime . toLocaleString } format like 'Friday, October 14, 1983, 9:30:33 AM Eastern Daylight Time' . Only 12 - hour if the locale is .
* @ type { Object }
* /
} , {
key : "DATETIME_HUGE_WITH_SECONDS" ,
get : function get ( ) {
return DATETIME _HUGE _WITH _SECONDS ;
}
} ] ) ;
return DateTime ;
} ( ) ;
function friendlyDateTime ( dateTimeish ) {
if ( DateTime . isDateTime ( dateTimeish ) ) {
return dateTimeish ;
} else if ( dateTimeish && dateTimeish . valueOf && isNumber ( dateTimeish . valueOf ( ) ) ) {
return DateTime . fromJSDate ( dateTimeish ) ;
} else if ( dateTimeish && typeof dateTimeish === "object" ) {
return DateTime . fromObject ( dateTimeish ) ;
} else {
throw new InvalidArgumentError ( "Unknown datetime argument: " + dateTimeish + ", of type " + typeof dateTimeish ) ;
}
}
var VERSION = "2.0.2" ;
var DateTime _1 = luxon . DateTime = DateTime ;
var Duration _1 = luxon . Duration = Duration ;
luxon . FixedOffsetZone = FixedOffsetZone ;
luxon . IANAZone = IANAZone ;
luxon . Info = Info ;
luxon . Interval = Interval ;
luxon . InvalidZone = InvalidZone ;
luxon . Settings = Settings ;
luxon . SystemZone = SystemZone ;
luxon . VERSION = VERSION ;
luxon . Zone = Zone ;
////////////////////
// Query Settings //
////////////////////
const DEFAULT _QUERY _SETTINGS = {
renderNullAs : "\\-" ,
taskLinkLocation : "end" ,
taskLinkText : "🔗" ,
warnOnEmptyResult : true ,
refreshInterval : 250 ,
defaultDateFormat : "MMMM dd, yyyy" ,
defaultDateTimeFormat : "h:mm a - MMMM dd, yyyy" ,
maxRecursiveRenderDepth : 6 ,
tableIdColumnName : "File" ,
tableGroupColumnName : "Group" ,
} ;
/** Default settings for dataview on install. */
const DEFAULT _SETTINGS = Object . assign ( Object . assign ( { } , DEFAULT _QUERY _SETTINGS ) , {
inlineQueryPrefix : "=" ,
inlineJsQueryPrefix : "$=" ,
enableDataviewJs : false ,
enableInlineDataviewJs : false ,
prettyRenderInlineFields : true ,
schemaVersion : 1 ,
} ) ;
/** Functional return type for error handling. */
class Success {
constructor ( value ) {
this . value = value ;
this . successful = true ;
}
map ( f ) {
return new Success ( f ( this . value ) ) ;
}
flatMap ( f ) {
return f ( this . value ) ;
}
orElse ( _value ) {
return this . value ;
}
orElseThrow ( _message ) {
return this . value ;
}
}
class Failure {
constructor ( error ) {
this . error = error ;
this . successful = false ;
}
map ( _f ) {
return this ;
}
flatMap ( _f ) {
return this ;
}
orElse ( value ) {
return value ;
}
orElseThrow ( message ) {
if ( message )
throw new Error ( message ( this . error ) ) ;
else
throw new Error ( "" + this . error ) ;
}
}
var Result ;
( function ( Result ) {
function success ( value ) {
return new Success ( value ) ;
}
Result . success = success ;
function failure ( error ) {
return new Failure ( error ) ;
}
Result . failure = failure ;
function flatMap2 ( first , second , f ) {
if ( first . successful ) {
if ( second . successful )
return f ( first . value , second . value ) ;
else
return failure ( second . error ) ;
}
else {
return failure ( first . error ) ;
}
}
Result . flatMap2 = flatMap2 ;
function map2 ( first , second , f ) {
return flatMap2 ( first , second , ( a , b ) => success ( f ( a , b ) ) ) ;
}
Result . map2 = map2 ;
} ) ( Result || ( Result = { } ) ) ;
var parsimmon _umd _min = { exports : { } } ;
( function ( module , exports ) {
! function ( n , t ) { module . exports = t ( ) ; } ( "undefined" != typeof self ? self : commonjsGlobal , function ( ) { return function ( n ) { var t = { } ; function r ( e ) { if ( t [ e ] ) return t [ e ] . exports ; var u = t [ e ] = { i : e , l : ! 1 , exports : { } } ; return n [ e ] . call ( u . exports , u , u . exports , r ) , u . l = ! 0 , u . exports } return r . m = n , r . c = t , r . d = function ( n , t , e ) { r . o ( n , t ) || Object . defineProperty ( n , t , { configurable : ! 1 , enumerable : ! 0 , get : e } ) ; } , r . r = function ( n ) { Object . defineProperty ( n , "__esModule" , { value : ! 0 } ) ; } , r . n = function ( n ) { var t = n && n . _ _esModule ? function ( ) { return n . default } : function ( ) { return n } ; return r . d ( t , "a" , t ) , t } , r . o = function ( n , t ) { return Object . prototype . hasOwnProperty . call ( n , t ) } , r . p = "" , r ( r . s = 0 ) } ( [ function ( n , t , r ) { function e ( n ) { if ( ! ( this instanceof e ) ) return new e ( n ) ; this . _ = n ; } var u = e . prototype ; function o ( n , t ) { for ( var r = 0 ; r < n ; r ++ ) t ( r ) ; } function i ( n , t , r ) { return function ( n , t ) { o ( t . length , function ( r ) { n ( t [ r ] , r , t ) ; } ) ; } ( function ( r , e , u ) { t = n ( t , r , e , u ) ; } , r ) , t } function f ( n , t ) { return i ( function ( t , r , e , u ) { return t . concat ( [ n ( r , e , u ) ] ) } , [ ] , t ) } function a ( n , t ) { var r = { v : 0 , buf : t } ; return o ( n , function ( ) { var n ; r = { v : r . v << 1 | ( n = r . buf , n [ 0 ] >> 7 ) , buf : function ( n ) { var t = i ( function ( n , t , r , e ) { return n . concat ( r === e . length - 1 ? Buffer . from ( [ t , 0 ] ) . readUInt16BE ( 0 ) : e . readUInt16BE ( r ) ) } , [ ] , n ) ; return Buffer . from ( f ( function ( n ) { return ( n << 1 & 65535 ) >> 8 } , t ) ) } ( r . buf ) } ; } ) , r } function c ( ) { return "undefined" != typeof Buffer } function s ( ) { if ( ! c ( ) ) throw new Error ( "Buffer global does not exist; please use webpack if you need to parse Buffers in the browser." ) } function l ( n ) { s ( ) ; var t = i ( function ( n , t ) { return n + t } , 0 , n ) ; if ( t % 8 != 0 ) throw new Error ( "The bits [" + n . join ( ", " ) + "] add up to " + t + " which is not an even number of bytes; the total should be divisible by 8" ) ; var r , u = t / 8 , o = ( r = function ( n ) { return n > 48 } , i ( function ( n , t ) { return n || ( r ( t ) ? t : n ) } , null , n ) ) ; if ( o ) throw new Error ( o + " bit range requested exceeds 48 bit (6 byte) Number max." ) ; return new e ( function ( t , r ) { var e = u + r ; return e > t . length ? x ( r , u . toString ( ) + " bytes" ) : b ( e , i ( function ( n , t ) { var r = a ( t , n . buf ) ; return { coll : n . coll . concat ( r . v ) , buf : r . buf } } , { coll : [ ] , buf : t . slice ( r , e ) } , n ) . coll ) } ) } function p ( n , t ) { return new e ( function ( r , e ) { return s ( ) , e + t > r . length ? x ( e , t + " bytes for " + n ) : b ( e + t , r . slice ( e , e + t ) ) } ) } function h ( n , t ) { if ( "number" != typeof ( r = t ) || Math . floor ( r ) !== r || t < 0 || t > 6 ) throw new Error ( n + " requires integer length in range [0, 6]." ) ; var r ; } function d ( n ) { return h ( "uintBE" , n ) , p ( "uintBE(" + n + ")" , n ) . map ( function ( t ) { return t . readUIntBE ( 0 , n ) } ) } function v ( n ) { return h ( "uintLE" , n ) , p ( "uintLE(" + n + ")" , n ) . map ( function ( t ) { return t . readUIntLE ( 0 , n ) } ) } function g ( n ) { return h ( "intBE" , n ) , p ( "intBE(" + n + ")" , n ) . map ( function ( t ) { return t . readIntBE ( 0 , n ) } ) } function m ( n ) { return h ( "intLE" , n ) , p ( "intLE(" + n + ")" , n ) . map ( function ( t ) { return t . readIntLE ( 0 , n ) } ) } function y ( n ) { return n instanceof e } function E ( n ) { return "[object Array]" === { } . toString . call ( n ) } function w ( n ) { return c ( ) && Buffer . isBuffer ( n ) } function b ( n , t ) { return { status : ! 0 , index : n , value : t , furthest : - 1 , expected : [ ] } } function x ( n , t ) { return E ( t ) || ( t = [ t ] ) , { status : ! 1 , index : - 1 , value : null , furthest : n , expected : t } } function B ( n , t ) { if ( ! t ) return n ; if ( n . furthest > t . furthest ) return n ; var r = n . furthest === t . furthest ? function ( n , t ) { if ( function ( ) { if ( void 0 !== e . _supportsSet ) return e . _supportsSet ; var n = "undefined" != typeof Set ; return e . _supportsSet = n , n } ( ) && Array . from ) { for ( var r = new Set ( n ) , u = 0 ; u < t . length ; u ++ ) r . add ( t [ u ] ) ; var o = Array . from ( r ) ; return o . sort ( ) , o } for ( var i = { } , f = 0 ; f < n . length ; f ++ ) i [ n [ f ] ] = ! 0 ; for ( var a = 0 ; a < t . length ; a ++ ) i [ t [ a ] ] = ! 0 ; var c = [ ] ; for ( var s in i ) ( { } ) . hasOwnProperty . call ( i , s ) && c . push ( s ) ; return c . sort ( ) , c } ( n . expected , t . expected ) : t . expected ; return { status : n . status , index : n . index , value : n . value , furthest : t . furthest , expected : r } } var j = { } ; function S ( n , t ) { if ( w ( n ) ) return { offset : t , line : - 1 , column : - 1 } ; n in j || ( j [ n ] = { } ) ; for ( var r = j [ n ] , e = 0 , u = 0 , o = 0 , i = t ; i >= 0 ; ) { if ( i in r ) { e = r [ i ] . line , 0 === o && ( o = r [ i ] . lineStart ) ; break } "\n" === n . charAt ( i ) && ( u ++ , 0 === o && ( o = i + 1 ) ) , i -- ; } var f = e + u , a = t - o ; return r [ t ] = { line : f , lineStart : o } , { offset : t , line : f + 1 , column : a + 1 } } function _ ( n ) { if ( ! y ( n ) ) throw new Error ( "not a parser: " + n ) } function L ( n , t ) { return "string" == typeof n ? n . charAt ( t ) : n [ t ] } function O ( n ) { if ( "number" != typeof n ) throw new Error ( "not a number: " + n ) } functi
} ( parsimmon _umd _min ) ) ;
var emojiRegex = ( ) => {
// https://mths.be/emoji
return / \ u D 8 3 C \ u D F F 4 \ u D B 4 0 \ u D C 6 7 \ u D B 4 0 \ u D C 6 2 ( ? : \ u D B 4 0 \ u D C 7 7 \ u D B 4 0 \ u D C 6 C \ u D B 4 0 \ u D C 7 3 | \ u D B 4 0 \ u D C 7 3 \ u D B 4 0 \ u D C 6 3 \ u D B 4 0 \ u D C 7 4 | \ u D B 4 0 \ u D C 6 5 \ u D B 4 0 \ u D C 6 E \ u D B 4 0 \ u D C 6 7 ) \ u D B 4 0 \ u D C 7 F | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F F \ u 2 0 0 D \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? ) \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F F \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) | \ u D 8 3 E \ u D E F 1 \ u D 8 3 C \ u D F F F \ u 2 0 0 D \ u D 8 3 E \ u D E F 2 ) ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F E ] ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F E \ u 2 0 0 D \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? ) \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F E \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) | \ u D 8 3 E \ u D E F 1 \ u D 8 3 C \ u D F F E \ u 2 0 0 D \ u D 8 3 E \ u D E F 2 ) ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F D \ u D F F F ] ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F D \ u 2 0 0 D \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? ) \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F D \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) | \ u D 8 3 E \ u D E F 1 \ u D 8 3 C \ u D F F D \ u 2 0 0 D \ u D 8 3 E \ u D E F 2 ) ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F C \ u D F F E \ u D F F F ] ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F C \ u 2 0 0 D \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? ) \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F C \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) | \ u D 8 3 E \ u D E F 1 \ u D 8 3 C \ u D F F C \ u 2 0 0 D \ u D 8 3 E \ u D E F 2 ) ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F D - \ u D F F F ] ) | ( ? : \ u D 8 3 E \ u D D D 1 \ u D 8 3 C \ u D F F B \ u 2 0 0 D \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? ) \ u D 8 3 E \ u D D D 1 | \ u D 8 3 D \ u D C 6 9 \ u D 8 3 C \ u D F F B \ u 2 0 0 D \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) | \ u D 8 3 E \ u D E F 1 \ u D 8 3 C \ u D F F B \ u 2 0 0 D \ u D 8 3 E \ u D E F 2 ) ( ? : \ u D 8 3 C [ \ u D F F C - \ u D F F F ] ) | \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C \ u D F F B ( ? : \ u 2 0 0 D ( ? : \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) | \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ) | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) | \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ) ) | \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F C - \ u D F F F ] ) | [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] \ u F E 0 F | [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 7 C \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) ) ? | ( ? : \ u D 8 3 C [ \ u D F F C - \ u D F F F ] ) \ u 2 0 0 D \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) | \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ) | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) | \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F F ] ) ) ) | \ u 2 0 0 D ( ? : \ u 2 7 6 4 ( ? : \ u F E 0 F \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? | \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 8 B \ u 2 0 0 D ) ? ) \ u D 8 3 D \ u D C 6 8 | ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) \ u 2 0 0 D ( ? : \ u D 8 3 D \ u D C 6 6 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 6 | \ u D 8 3 D \ u D C 6 7 \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) ) | \ u D 8 3 D \ u D C 6 6 \ u 2 0 0 D \ u D 8 3 D \ u D C 6 6 | \ u D 8 3 D \ u D C 6 7 \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 7 C \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F F \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F E ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 7 C \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F E \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B - \ u D F F D \ u D F F F ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 7 C \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F D \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F C \ u D F F E \ u D F F F ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 7 C \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | \ u D 8 3 C \ u D F F C \ u 2 0 0 D ( ? : \ u D 8 3 E \ u D D 1 D \ u 2 0 0 D \ u D 8 3 D \ u D C 6 8 ( ? : \ u D 8 3 C [ \ u D F F B \ u D F F D - \ u D F F F ] ) | \ u D 8 3 C [ \ u D F 3 E \ u D F 7 3 \ u D F 7 C \ u D F 9 3 \ u D F A 4 \ u D F A 8 \ u D F E B \ u D F E D ] | \ u D 8 3 D [ \ u D C B B \ u D C B C \ u D D 2 7 \ u D D 2 C \ u D E 8 0 \ u D E 9 2 ] | \ u D 8 3 E [ \ u D D A F - \ u D D B 3 \ u D D B C \ u D D B D ] ) | ( ? : \ u D 8 3 C \ u D F F F \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F E \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F D \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F C \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] ) \ u F E 0 F | \ u 2 0 0 D ( ? : ( ? : \ u D 8 3 D [ \ u D C 6 8 \ u D C 6 9 ] ) \ u 2 0 0 D ( ? : \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) | \ u D 8 3 D [ \ u D C 6 6 \ u D C 6 7 ] ) | \ u D 8 3 C \ u D F F F \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F E \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F D \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F C \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] | \ u D 8 3 C \ u D F F F | \ u D 8 3 C \ u D F F E | \ u D 8 3 C \ u D F F D | \ u D 8 3 C \ u D F F C | \ u 2 0 0 D [ \ u 2 6 9 5 \ u 2 6 9 6 \ u 2 7 0 8 ] ) ? | ( ? : \ u D 8 3 D \ u D C
} ;
/** Normalize a duration to all of the proper units. */
function normalizeDuration ( dur ) {
return dur . shiftTo ( "years" , "months" , "weeks" , "days" , "hours" , "minutes" , "seconds" , "milliseconds" ) . normalize ( ) ;
}
/** Strip the time components of a date time object. */
function stripTime ( dt ) {
return DateTime _1 . fromObject ( {
year : dt . year ,
month : dt . month ,
day : dt . day ,
} ) ;
}
/** Try to extract a YYYYMMDD date from a string. */
function extractDate ( str ) {
let dateMatch = /(\d{4})-(\d{2})-(\d{2})/ . exec ( str ) ;
if ( ! dateMatch )
dateMatch = /(\d{4})(\d{2})(\d{2})/ . exec ( str ) ;
if ( dateMatch ) {
let year = Number . parseInt ( dateMatch [ 1 ] ) ;
let month = Number . parseInt ( dateMatch [ 2 ] ) ;
let day = Number . parseInt ( dateMatch [ 3 ] ) ;
return DateTime _1 . fromObject ( { year , month , day } ) ;
}
return undefined ;
}
/** Get the folder containing the given path (i.e., like computing 'path/..'). */
function getParentFolder ( path ) {
return path . split ( "/" ) . slice ( 0 , - 1 ) . join ( "/" ) ;
}
/** Get the "title" for a file, by stripping other parts of the path as well as the extension. */
function getFileTitle ( path ) {
if ( path . includes ( "/" ) )
path = path . substring ( path . lastIndexOf ( "/" ) + 1 ) ;
if ( path . endsWith ( ".md" ) )
path = path . substring ( 0 , path . length - 3 ) ;
return path ;
}
/** Get the extension of a file from the file path. */
function getExtension ( path ) {
if ( ! path . includes ( "." ) )
return "" ;
return path . substring ( path . lastIndexOf ( "." ) + 1 ) ;
}
/** Try calling the given function; on failure, return the error message. */
function tryOrPropogate ( func ) {
try {
return func ( ) ;
}
catch ( error ) {
return Result . failure ( "" + error + "\n\n" + error . stack ) ;
}
}
/** Try asynchronously calling the given function; on failure, return the error message. */
function asyncTryOrPropogate ( func ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
try {
return yield func ( ) ;
}
catch ( error ) {
return Result . failure ( "" + error + "\n\n" + error . stack ) ;
}
} ) ;
}
/ * *
* Escape regex characters in a string .
* See https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions.
* /
function escapeRegex ( str ) {
return str . replace ( /[.*+?^${}()|[\]\\]/g , "\\$&" ) ;
}
/** A parsimmon parser which canonicalizes variable names while properly respecting emoji. */
const VAR _NAME _CANONICALIZER = parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regex ( new RegExp ( emojiRegex ( ) , "" ) ) , parsimmon _umd _min . exports . regex ( /[0-9\p{Letter}_-]+/u ) . map ( str => str . toLocaleLowerCase ( ) ) , parsimmon _umd _min . exports . whitespace . map ( _ => "-" ) , parsimmon _umd _min . exports . any . map ( _ => "" ) )
. many ( )
. map ( result => result . join ( "" ) ) ;
/** Convert an arbitrary variable name into something JS/query friendly. */
function canonicalizeVarName ( name ) {
return VAR _NAME _CANONICALIZER . tryParse ( name ) ;
}
const HEADER _CANONICALIZER = parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regex ( new RegExp ( emojiRegex ( ) , "" ) ) , parsimmon _umd _min . exports . regex ( /[0-9\p{Letter}_-]+/u ) , parsimmon _umd _min . exports . whitespace . map ( _ => " " ) , parsimmon _umd _min . exports . any . map ( _ => " " ) )
. many ( )
. map ( result => {
return result . join ( "" ) . split ( /\s+/ ) . join ( " " ) . trim ( ) ;
} ) ;
/ * *
* Normalizes the text in a header to be something that is actually linkable to . This mimics
* how Obsidian does it ' s normalization , collapsing repeated spaces and stripping out control characters .
* /
function normalizeHeaderForLink ( header ) {
return HEADER _CANONICALIZER . tryParse ( header ) ;
}
/** A specific task. */
class Task {
constructor ( init ) {
Object . assign ( this , init ) ;
this . subtasks = ( this . subtasks || [ ] ) . map ( t => new Task ( t ) ) ;
}
/** Create a task from a record. */
static fromObject ( obj ) {
return new Task ( obj ) ;
}
id ( ) {
return ` ${ this . path } - ${ this . line } ` ;
}
markdown ( ) {
let result = ` - [ ${ this . completed ? "x" : " " } ] ${ this . text } ` ;
return result ;
}
/** Return a new task where the created and completed fields are assigned to the given defaults if not present. */
withDefaultDates ( defaultCreated , defaultCompleted ) {
var _a , _b ;
let newTask = new Task ( this ) ;
newTask . created = ( _a = newTask . created ) !== null && _a !== void 0 ? _a : defaultCreated ;
if ( newTask . completed )
newTask . completion = ( _b = newTask . completion ) !== null && _b !== void 0 ? _b : defaultCompleted ;
newTask . subtasks = newTask . subtasks . map ( t => t . withDefaultDates ( defaultCreated , defaultCompleted ) ) ;
return newTask ;
}
toObject ( inlineAnnotations = true ) {
let result = {
text : this . text ,
line : this . line ,
path : this . path ,
completed : this . completed ,
fullyCompleted : this . fullyCompleted ,
real : this . real ,
link : this . link ,
section : this . section ,
header : this . section ,
subtasks : this . subtasks . map ( t => t . toObject ( inlineAnnotations ) ) ,
annotated : ! ! this . due || ! ! this . completion || ( ! ! this . annotations && Object . keys ( this . annotations ) . length > 0 ) ,
} ;
if ( this . created )
result . created = this . created ;
if ( this . due )
result . due = this . due ;
if ( this . completion )
result . completion = this . completion ;
if ( this . annotations ) {
if ( inlineAnnotations ) {
for ( let [ key , value ] of Object . entries ( this . annotations ) ) {
if ( key in result )
continue ;
result [ key ] = value ;
}
}
else {
result . annotations = this . annotations ;
}
}
return result ;
}
}
/** An Obsidian link with all associated metadata. */
class Link {
constructor ( fields ) {
Object . assign ( this , fields ) ;
}
static file ( path , embed = false , display ) {
return new Link ( {
path ,
embed ,
display ,
type : "file" ,
} ) ;
}
static header ( path , header , embed , display ) {
// Headers need to be normalized to alpha-numeric & with extra spacing removed.
return new Link ( {
path ,
embed ,
display ,
subpath : normalizeHeaderForLink ( header ) ,
type : "header" ,
} ) ;
}
static block ( path , blockId , embed , display ) {
return new Link ( {
path ,
embed ,
display ,
subpath : blockId ,
type : "block" ,
} ) ;
}
static fromObject ( object ) {
return new Link ( object ) ;
}
/** Checks for link equality (i.e., that the links are pointing to the same exact location). */
equals ( other ) {
return this . path == other . path && this . type == other . type && this . subpath == other . subpath ;
}
toString ( ) {
return this . markdown ( ) ;
}
/** Convert this link to a raw object which */
toObject ( ) {
return { path : this . path , type : this . type , subpath : this . subpath , display : this . display , embed : this . embed } ;
}
/** Return a new link which points to the same location but with a new display value. */
withDisplay ( display ) {
return new Link ( Object . assign ( { } , this , { display } ) ) ;
}
/** Convert a file link into a link to a specific header. */
withHeader ( header ) {
return Link . header ( this . path , header , this . embed , this . display ) ;
}
/** Convert any link into a link to its file. */
toFile ( ) {
return Link . file ( this . path , this . embed , this . display ) ;
}
/** Convert this link into an embedded link. */
toEmbed ( ) {
if ( this . embed )
return this ;
else {
let link = new Link ( this ) ;
link . embed = true ;
return link ;
}
}
/** Convert this link to markdown so it can be rendered. */
markdown ( ) {
let result = ( this . embed ? "!" : "" ) + "[[" + this . path ;
if ( this . type == "header" )
result += "#" + this . subpath ;
else if ( this . type == "block" )
result += "#^" + this . subpath ;
if ( this . display )
result += "|" + this . display ;
else {
result += "|" + getFileTitle ( this . path ) ;
if ( this . type == "header" || this . type == "block" )
result += " > " + this . subpath ;
}
result += "]]" ;
return result ;
}
/** The stripped name of the file this link points into. */
fileName ( ) {
return getFileTitle ( this . path ) . replace ( ".md" , "" ) ;
}
}
var Values ;
( function ( Values ) {
/** Convert an arbitary value into a reasonable, Markdown-friendly string if possible. */
function toString ( field , setting = DEFAULT _QUERY _SETTINGS , recursive = false ) {
let wrapped = wrapValue ( field ) ;
if ( ! wrapped )
return "null" ;
switch ( wrapped . type ) {
case "string" :
return wrapped . value ;
case "number" :
case "boolean" :
case "html" :
case "null" :
return "" + wrapped . value ;
case "link" :
return wrapped . value . markdown ( ) ;
case "task" :
return wrapped . value . markdown ( ) ;
case "function" :
return "<function>" ;
case "array" :
let result = "" ;
if ( recursive )
result += "[" ;
result += wrapped . value . map ( f => toString ( f , setting , true ) ) . join ( ", " ) ;
if ( recursive )
result += "]" ;
return result ;
case "object" :
return ( "{ " +
Object . entries ( wrapped . value )
. map ( e => e [ 0 ] + ": " + toString ( e [ 1 ] , setting , true ) )
. join ( ", " ) +
" }" ) ;
case "date" :
if ( wrapped . value . second == 0 && wrapped . value . hour == 0 && wrapped . value . minute == 0 ) {
return wrapped . value . toFormat ( setting . defaultDateFormat ) ;
}
return wrapped . value . toFormat ( setting . defaultDateTimeFormat ) ;
case "duration" :
return wrapped . value . toISOTime ( ) ;
}
}
Values . toString = toString ;
/** Wrap a literal value so you can switch on it easily. */
function wrapValue ( val ) {
if ( isNull ( val ) )
return { type : "null" , value : val } ;
else if ( isNumber ( val ) )
return { type : "number" , value : val } ;
else if ( isString ( val ) )
return { type : "string" , value : val } ;
else if ( isBoolean ( val ) )
return { type : "boolean" , value : val } ;
else if ( isDuration ( val ) )
return { type : "duration" , value : val } ;
else if ( isDate ( val ) )
return { type : "date" , value : val } ;
else if ( isHtml ( val ) )
return { type : "html" , value : val } ;
else if ( isArray ( val ) )
return { type : "array" , value : val } ;
else if ( isLink ( val ) )
return { type : "link" , value : val } ;
else if ( isTask ( val ) )
return { type : "task" , value : val } ;
else if ( isFunction ( val ) )
return { type : "function" , value : val } ;
else if ( isObject ( val ) )
return { type : "object" , value : val } ;
else
return undefined ;
}
Values . wrapValue = wrapValue ;
/** Compare two arbitrary JavaScript values. Produces a total ordering over ANY possible dataview value. */
function compareValue ( val1 , val2 , linkNormalizer ) {
var _a , _b ;
// Handle undefined/nulls first.
if ( val1 === undefined )
val1 = null ;
if ( val2 === undefined )
val2 = null ;
if ( val1 === null && val2 === null )
return 0 ;
else if ( val1 === null )
return - 1 ;
else if ( val2 === null )
return 1 ;
// A non-null value now which we can wrap & compare on.
let wrap1 = wrapValue ( val1 ) ;
let wrap2 = wrapValue ( val2 ) ;
if ( wrap1 === undefined && wrap2 === undefined )
return 0 ;
else if ( wrap1 === undefined )
return - 1 ;
else if ( wrap2 === undefined )
return 1 ;
if ( wrap1 . type != wrap2 . type )
return wrap1 . type . localeCompare ( wrap2 . type ) ;
switch ( wrap1 . type ) {
case "string" :
return wrap1 . value . localeCompare ( wrap2 . value ) ;
case "number" :
if ( wrap1 . value < wrap2 . value )
return - 1 ;
else if ( wrap1 . value == wrap2 . value )
return 0 ;
return 1 ;
case "null" :
return 0 ;
case "boolean" :
if ( wrap1 . value == wrap2 . value )
return 0 ;
else
return wrap1 . value ? 1 : - 1 ;
case "link" :
let link1 = wrap1 . value ;
let link2 = wrap2 . value ;
let normalize = linkNormalizer !== null && linkNormalizer !== void 0 ? linkNormalizer : ( ( x ) => x ) ;
// We can't compare by file name or display, since that would break link equality. Compare by path.
let pathCompare = normalize ( link1 . path ) . localeCompare ( normalize ( link2 . path ) ) ;
if ( pathCompare != 0 )
return pathCompare ;
// Then compare by type.
let typeCompare = link1 . type . localeCompare ( link2 . type ) ;
if ( typeCompare != 0 )
return typeCompare ;
// Then compare by subpath existence.
if ( link1 . subpath && ! link2 . subpath )
return 1 ;
if ( ! link1 . subpath && link2 . subpath )
return - 1 ;
if ( ! link1 . subpath && ! link2 . subpath )
return 0 ;
// Since both have a subpath, compare by subpath.
return ( ( _a = link1 . subpath ) !== null && _a !== void 0 ? _a : "" ) . localeCompare ( ( _b = link2 . subpath ) !== null && _b !== void 0 ? _b : "" ) ;
case "task" :
let task1 = wrap1 . value ;
let task2 = wrap2 . value ;
// Use object comparison & compare the unique identifiers (path, line, and text as backup).
return compareValue ( { path : task1 . path , line : task1 . line , text : task1 . text } , { path : task2 . path , line : task2 . line , text : task2 . text } ) ;
case "date" :
return wrap1 . value < wrap2 . value
? - 1
: wrap1 . value . equals ( wrap2 . value )
? 0
: 1 ;
case "duration" :
return wrap1 . value < wrap2 . value
? - 1
: wrap1 . value . equals ( wrap2 . value )
? 0
: 1 ;
case "array" :
let f1 = wrap1 . value ;
let f2 = wrap2 . value ;
for ( let index = 0 ; index < Math . min ( f1 . length , f2 . length ) ; index ++ ) {
let comp = compareValue ( f1 [ index ] , f2 [ index ] ) ;
if ( comp != 0 )
return comp ;
}
return f1 . length - f2 . length ;
case "object" :
let o1 = wrap1 . value ;
let o2 = wrap2 . value ;
let k1 = Array . from ( Object . keys ( o1 ) ) ;
let k2 = Array . from ( Object . keys ( o2 ) ) ;
k1 . sort ( ) ;
k2 . sort ( ) ;
let keyCompare = compareValue ( k1 , k2 ) ;
if ( keyCompare != 0 )
return keyCompare ;
for ( let key of k1 ) {
let comp = compareValue ( o1 [ key ] , o2 [ key ] ) ;
if ( comp != 0 )
return comp ;
}
return 0 ;
case "html" :
return 0 ;
case "function" :
return 0 ;
}
}
Values . compareValue = compareValue ;
/** Find the corresponding Dataveiw type for an arbitrary value. */
function typeOf ( val ) {
var _a ;
return ( _a = wrapValue ( val ) ) === null || _a === void 0 ? void 0 : _a . type ;
}
Values . typeOf = typeOf ;
/** Determine if the given value is "truthy" (i.e., is non-null and has data in it). */
function isTruthy ( field ) {
let wrapped = wrapValue ( field ) ;
if ( ! wrapped )
return false ;
switch ( wrapped . type ) {
case "number" :
return wrapped . value != 0 ;
case "string" :
return wrapped . value . length > 0 ;
case "boolean" :
return wrapped . value ;
case "link" :
return ! ! wrapped . value . path ;
case "task" :
return wrapped . value . text . length > 0 ;
case "date" :
return wrapped . value . toMillis ( ) != 0 ;
case "duration" :
return wrapped . value . as ( "seconds" ) != 0 ;
case "object" :
return Object . keys ( wrapped . value ) . length > 0 ;
case "array" :
return wrapped . value . length > 0 ;
case "null" :
return false ;
case "html" :
return true ;
case "function" :
return true ;
}
}
Values . isTruthy = isTruthy ;
/** Deep copy a field. */
function deepCopy ( field ) {
if ( field === null || field === undefined )
return field ;
if ( Values . isArray ( field ) ) {
return [ ] . concat ( field . map ( v => deepCopy ( v ) ) ) ;
}
else if ( Values . isObject ( field ) ) {
let result = { } ;
for ( let [ key , value ] of Object . entries ( field ) )
result [ key ] = deepCopy ( value ) ;
return result ;
}
else {
return field ;
}
}
Values . deepCopy = deepCopy ;
function isString ( val ) {
return typeof val == "string" ;
}
Values . isString = isString ;
function isNumber ( val ) {
return typeof val == "number" ;
}
Values . isNumber = isNumber ;
function isDate ( val ) {
return val instanceof DateTime _1 ;
}
Values . isDate = isDate ;
function isDuration ( val ) {
return val instanceof Duration _1 ;
}
Values . isDuration = isDuration ;
function isNull ( val ) {
return val === null || val === undefined ;
}
Values . isNull = isNull ;
function isArray ( val ) {
return Array . isArray ( val ) ;
}
Values . isArray = isArray ;
function isBoolean ( val ) {
return typeof val === "boolean" ;
}
Values . isBoolean = isBoolean ;
function isLink ( val ) {
return val instanceof Link ;
}
Values . isLink = isLink ;
function isTask ( val ) {
return val instanceof Task ;
}
Values . isTask = isTask ;
function isHtml ( val ) {
if ( typeof HTMLElement !== "undefined" ) {
return val instanceof HTMLElement ;
}
else {
return false ;
}
}
Values . isHtml = isHtml ;
function isObject ( val ) {
return ( typeof val == "object" &&
! isHtml ( val ) &&
! isArray ( val ) &&
! isDuration ( val ) &&
! isDate ( val ) &&
! isLink ( val ) &&
! isTask ( val ) ) ;
}
Values . isObject = isObject ;
function isFunction ( val ) {
return typeof val == "function" ;
}
Values . isFunction = isFunction ;
} ) ( Values || ( Values = { } ) ) ;
var Groupings ;
( function ( Groupings ) {
function base ( value ) {
return { type : "base" , value } ;
}
Groupings . base = base ;
function grouped ( values ) {
return { type : "grouped" , groups : values } ;
}
Groupings . grouped = grouped ;
} ) ( Groupings || ( Groupings = { } ) ) ;
/** Implementation of DataArray, minus the dynamic variable access, which is implemented via proxy. */
class DataArrayImpl {
constructor ( values , settings , defaultComparator = Values . compareValue ) {
this . values = values ;
this . settings = settings ;
this . defaultComparator = defaultComparator ;
this . length = values . length ;
}
static wrap ( arr , settings , defaultComparator = Values . compareValue ) {
return new Proxy ( new DataArrayImpl ( arr , settings , defaultComparator ) , DataArrayImpl . ARRAY _PROXY ) ;
}
lwrap ( values ) {
return DataArrayImpl . wrap ( values , this . settings , this . defaultComparator ) ;
}
where ( predicate ) {
return this . lwrap ( this . values . filter ( predicate ) ) ;
}
filter ( predicate ) {
return this . where ( predicate ) ;
}
map ( f ) {
return this . lwrap ( this . values . map ( f ) ) ;
}
flatMap ( f ) {
let result = [ ] ;
for ( let index = 0 ; index < this . length ; index ++ ) {
let value = f ( this . values [ index ] , index , this . values ) ;
if ( ! value || value . length == 0 )
continue ;
for ( let r of value )
result . push ( r ) ;
}
return this . lwrap ( result ) ;
}
mutate ( f ) {
this . values . forEach ( f ) ;
return this ;
}
limit ( count ) {
return this . lwrap ( this . values . slice ( 0 , count ) ) ;
}
slice ( start , end ) {
return this . lwrap ( this . values . slice ( start , end ) ) ;
}
concat ( other ) {
return this . lwrap ( this . values . concat ( other . values ) ) ;
}
/** Return the first index of the given (optionally starting the search) */
indexOf ( element , fromIndex ) {
return this . findIndex ( e => this . defaultComparator ( e , element ) == 0 , fromIndex ) ;
}
/** Return the first element that satisfies the given predicate. */
find ( pred ) {
let index = this . findIndex ( pred ) ;
if ( index == - 1 )
return undefined ;
else
return this . values [ index ] ;
}
findIndex ( pred , fromIndex ) {
for ( let index = fromIndex !== null && fromIndex !== void 0 ? fromIndex : 0 ; index < this . length ; index ++ ) {
if ( pred ( this . values [ index ] , index , this . values ) )
return index ;
}
return - 1 ;
}
includes ( element ) {
return this . indexOf ( element , 0 ) != - 1 ;
}
join ( sep ) {
return this . map ( s => Values . toString ( s , this . settings ) )
. array ( )
. join ( sep !== null && sep !== void 0 ? sep : ", " ) ;
}
sort ( key , direction , comparator ) {
if ( this . values . length == 0 )
return this ;
let realComparator = comparator !== null && comparator !== void 0 ? comparator : this . defaultComparator ;
// Associate each entry with it's index for the key function, and then do a normal sort.
let copy = [ ] . concat ( this . array ( ) ) . map ( ( elem , index ) => {
return { index : index , value : elem } ;
} ) ;
copy . sort ( ( a , b ) => {
let aKey = key ( a . value , a . index , this . values ) ;
let bKey = key ( b . value , b . index , this . values ) ;
return direction === "desc" ? - realComparator ( aKey , bKey ) : realComparator ( aKey , bKey ) ;
} ) ;
return this . lwrap ( copy . map ( e => e . value ) ) ;
}
groupBy ( key , comparator ) {
if ( this . values . length == 0 )
return this . lwrap ( [ ] ) ;
// JavaScript sucks and we can't make hash maps over arbitrary types (only strings/ints), so
// we do a poor man algorithm where we SORT, followed by grouping.
let intermediate = this . sort ( key , "asc" , comparator ) ;
comparator = comparator !== null && comparator !== void 0 ? comparator : this . defaultComparator ;
let result = [ ] ;
let currentRow = [ intermediate [ 0 ] ] ;
let current = key ( intermediate [ 0 ] , 0 , intermediate . values ) ;
for ( let index = 1 ; index < intermediate . length ; index ++ ) {
let newKey = key ( intermediate [ index ] , index , intermediate . values ) ;
if ( comparator ( current , newKey ) != 0 ) {
result . push ( { key : current , rows : this . lwrap ( currentRow ) } ) ;
current = newKey ;
currentRow = [ intermediate [ index ] ] ;
}
else {
currentRow . push ( intermediate [ index ] ) ;
}
}
result . push ( { key : current , rows : this . lwrap ( currentRow ) } ) ;
return this . lwrap ( result ) ;
}
distinct ( key , comparator ) {
if ( this . values . length == 0 )
return this ;
let realKey = key !== null && key !== void 0 ? key : ( x => x ) ;
// For similar reasons to groupBy, do a sort and take the first element of each block.
let intermediate = this . map ( ( x , index ) => {
return { key : realKey ( x , index , this . values ) , value : x } ;
} ) . sort ( x => x . key , "asc" , comparator ) ;
comparator = comparator !== null && comparator !== void 0 ? comparator : this . defaultComparator ;
let result = [ intermediate [ 0 ] . value ] ;
for ( let index = 1 ; index < intermediate . length ; index ++ ) {
if ( comparator ( intermediate [ index - 1 ] . key , intermediate [ index ] . key ) != 0 ) {
result . push ( intermediate [ index ] . value ) ;
}
}
return this . lwrap ( result ) ;
}
every ( f ) {
return this . values . every ( f ) ;
}
some ( f ) {
return this . values . some ( f ) ;
}
none ( f ) {
return this . values . every ( ( v , i , a ) => ! f ( v , i , a ) ) ;
}
first ( ) {
return this . values . length > 0 ? this . values [ 0 ] : undefined ;
}
last ( ) {
return this . values . length > 0 ? this . values [ this . values . length - 1 ] : undefined ;
}
to ( key ) {
let result = [ ] ;
for ( let child of this . values ) {
let value = child [ key ] ;
if ( value === undefined || value === null )
continue ;
if ( Array . isArray ( value ) || DataArray . isDataArray ( value ) )
value . forEach ( v => result . push ( v ) ) ;
else
result . push ( value ) ;
}
return this . lwrap ( result ) ;
}
into ( key ) {
let result = [ ] ;
for ( let child of this . values ) {
let value = child [ key ] ;
if ( value === undefined || value === null )
continue ;
result . push ( value ) ;
}
return this . lwrap ( result ) ;
}
expand ( key ) {
let result = [ ] ;
let queue = [ ] . concat ( this . values ) ;
while ( queue . length > 0 ) {
let next = queue . pop ( ) ;
let value = next [ key ] ;
if ( value === undefined || value === null )
continue ;
if ( Array . isArray ( value ) )
value . forEach ( v => queue . push ( v ) ) ;
else if ( value instanceof DataArrayImpl )
value . forEach ( v => queue . push ( v ) ) ;
else
queue . push ( value ) ;
result . push ( next ) ;
}
return this . lwrap ( result ) ;
}
forEach ( f ) {
for ( let index = 0 ; index < this . values . length ; index ++ ) {
f ( this . values [ index ] , index , this . values ) ;
}
}
array ( ) {
return [ ] . concat ( this . values ) ;
}
[ Symbol . iterator ] ( ) {
return this . values [ Symbol . iterator ] ( ) ;
}
toString ( ) {
return this . values . toString ( ) ;
}
}
DataArrayImpl . ARRAY _FUNCTIONS = new Set ( [
"where" ,
"filter" ,
"map" ,
"flatMap" ,
"mutate" ,
"slice" ,
"concat" ,
"indexOf" ,
"limit" ,
"find" ,
"findIndex" ,
"includes" ,
"join" ,
"sort" ,
"groupBy" ,
"distinct" ,
"every" ,
"some" ,
"none" ,
"first" ,
"last" ,
"to" ,
"into" ,
"lwrap" ,
"expand" ,
"forEach" ,
"length" ,
"values" ,
"array" ,
"defaultComparator" ,
"toString" ,
] ) ;
DataArrayImpl . ARRAY _PROXY = {
get : function ( target , prop , reciever ) {
if ( typeof prop === "symbol" )
return target [ prop ] ;
else if ( typeof prop === "number" )
return target . values [ prop ] ;
else if ( ! isNaN ( parseInt ( prop ) ) )
return target . values [ parseInt ( prop ) ] ;
else if ( DataArrayImpl . ARRAY _FUNCTIONS . has ( prop . toString ( ) ) )
return target [ prop . toString ( ) ] ;
return target . to ( prop ) ;
} ,
} ;
/** Provides utility functions for generating data arrays. */
var DataArray ;
( function ( DataArray ) {
/** Create a new Dataview data array. */
function wrap ( raw , settings ) {
return DataArrayImpl . wrap ( raw , settings ) ;
}
DataArray . wrap = wrap ;
/** Create a new DataArray from an iterable object. */
function from ( raw , settings ) {
let data = [ ] ;
for ( let elem of raw )
data . push ( elem ) ;
return DataArrayImpl . wrap ( data , settings ) ;
}
DataArray . from = from ;
/** Return true if the given object is a data array. */
function isDataArray ( obj ) {
return obj instanceof DataArrayImpl ;
}
DataArray . isDataArray = isDataArray ;
} ) ( DataArray || ( DataArray = { } ) ) ;
/** Test-environment-friendly function which fetches the current system locale. */
function currentLocale ( ) {
if ( typeof window === "undefined" )
return "en-US" ;
return window . navigator . language ;
}
/** Render simple fields compactly, removing wrapping content like paragraph and span. */
function renderCompactMarkdown ( markdown , container , sourcePath , component ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let subcontainer = container . createSpan ( ) ;
yield obsidian . MarkdownRenderer . renderMarkdown ( markdown , subcontainer , sourcePath , component ) ;
let paragraph = subcontainer . querySelector ( "p" ) ;
if ( subcontainer . children . length == 1 && paragraph ) {
while ( paragraph . firstChild ) {
subcontainer . appendChild ( paragraph . firstChild ) ;
}
subcontainer . removeChild ( paragraph ) ;
}
} ) ;
}
/** Create a list inside the given container, with the given data. */
function renderList ( container , elements , component , originFile , settings ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let listEl = container . createEl ( "ul" , { cls : [ "dataview" , "list-view-ul" ] } ) ;
for ( let elem of elements ) {
let li = listEl . createEl ( "li" ) ;
yield renderValue ( elem , li , originFile , component , settings , true , "list" ) ;
}
} ) ;
}
/** Create a table inside the given container, with the given data. */
function renderTable ( container , headers , values , component , originFile , settings ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let tableEl = container . createEl ( "table" , { cls : [ "dataview" , "table-view-table" ] } ) ;
let theadEl = tableEl . createEl ( "thead" , { cls : "table-view-thead" } ) ;
let headerEl = theadEl . createEl ( "tr" , { cls : "table-view-tr-header" } ) ;
for ( let header of headers ) {
headerEl . createEl ( "th" , { text : header , cls : "table-view-th" } ) ;
}
let tbodyEl = tableEl . createEl ( "tbody" , { cls : "table-view-tbody" } ) ;
for ( let row of values ) {
let rowEl = tbodyEl . createEl ( "tr" ) ;
for ( let value of row ) {
let td = rowEl . createEl ( "td" ) ;
yield renderValue ( value , td , originFile , component , settings , true ) ;
}
}
} ) ;
}
/** Render a pre block with an error in it; returns the element to allow for dynamic updating. */
function renderErrorPre ( container , error ) {
let pre = container . createEl ( "pre" , { cls : [ "dataview" , "dataview-error" ] } ) ;
pre . appendText ( error ) ;
return pre ;
}
/** Render a DateTime in a minimal format to save space. */
function renderMinimalDate ( time , settings ) {
// If there is no relevant time specified, fall back to just rendering the date.
if ( time . second == 0 && time . minute == 0 && time . hour == 0 ) {
return time . toFormat ( settings . defaultDateFormat , { locale : currentLocale ( ) } ) ;
}
return time . toFormat ( settings . defaultDateTimeFormat , { locale : currentLocale ( ) } ) ;
}
/** Render a duration in a minimal format to save space. */
function renderMinimalDuration ( dur ) {
dur = normalizeDuration ( dur ) ;
let result = "" ;
if ( dur . years )
result += ` ${ dur . years } years, ` ;
if ( dur . months )
result += ` ${ dur . months } months, ` ;
if ( dur . weeks )
result += ` ${ dur . weeks } weeks, ` ;
if ( dur . days )
result += ` ${ dur . days } days, ` ;
if ( dur . hours )
result += ` ${ dur . hours } hours, ` ;
if ( dur . minutes )
result += ` ${ dur . minutes } minutes, ` ;
if ( dur . seconds )
result += ` ${ Math . round ( dur . seconds ) } seconds, ` ;
if ( dur . milliseconds )
result += ` ${ Math . round ( dur . milliseconds ) } ms, ` ;
if ( result . endsWith ( ", " ) )
result = result . substring ( 0 , result . length - 2 ) ;
return result ;
}
/** Prettily render a value into a container with the given settings. */
function renderValue ( field , container , originFile , component , settings , expandList = false , context = "root" , depth = 0 ) {
var _a , _b ;
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Prevent infinite recursion.
if ( depth > settings . maxRecursiveRenderDepth ) {
container . appendText ( "..." ) ;
return ;
}
if ( Values . isNull ( field ) ) {
yield renderCompactMarkdown ( settings . renderNullAs , container , originFile , component ) ;
}
else if ( Values . isDate ( field ) ) {
container . appendText ( renderMinimalDate ( field , settings ) ) ;
}
else if ( Values . isDuration ( field ) ) {
container . appendText ( renderMinimalDuration ( field ) ) ;
}
else if ( Values . isString ( field ) || Values . isBoolean ( field ) || Values . isNumber ( field ) ) {
yield renderCompactMarkdown ( "" + field , container , originFile , component ) ;
}
else if ( Values . isArray ( field ) || DataArray . isDataArray ( field ) ) {
if ( expandList ) {
let list = container . createEl ( "ul" , {
cls : [
"dataview" ,
"dataview-ul" ,
context == "list" ? "dataview-result-list-ul" : "dataview-result-list-root-ul" ,
] ,
} ) ;
for ( let child of field ) {
let li = list . createEl ( "li" , { cls : "dataview-result-list-li" } ) ;
yield renderValue ( child , li , originFile , component , settings , expandList , "list" , depth + 1 ) ;
}
}
else {
if ( field . length == 0 ) {
container . appendText ( "<empty list>" ) ;
return ;
}
let span = container . createEl ( "span" , { cls : [ "dataview" , "dataview-result-list-span" ] } ) ;
let first = true ;
for ( let val of field ) {
if ( first )
first = false ;
else
span . appendText ( ", " ) ;
yield renderValue ( val , span , originFile , component , settings , expandList , "list" , depth + 1 ) ;
}
}
}
else if ( Values . isLink ( field ) ) {
yield renderCompactMarkdown ( field . markdown ( ) , container , originFile , component ) ;
}
else if ( Values . isHtml ( field ) ) {
container . appendChild ( field ) ;
}
else if ( Values . isFunction ( field ) ) {
container . appendText ( "<function>" ) ;
}
else if ( Values . isObject ( field ) ) {
// Don't render classes in case they have recursive references; spoopy.
if ( ! Values . isTask ( field ) && ( ( _a = field === null || field === void 0 ? void 0 : field . constructor ) === null || _a === void 0 ? void 0 : _a . name ) && ( ( _b = field === null || field === void 0 ? void 0 : field . constructor ) === null || _b === void 0 ? void 0 : _b . name ) != "Object" ) {
container . appendText ( ` < ${ field . constructor . name } > ` ) ;
return ;
}
if ( expandList ) {
let list = container . createEl ( "ul" , { cls : [ "dataview" , "dataview-ul" , "dataview-result-object-ul" ] } ) ;
for ( let [ key , value ] of Object . entries ( field ) ) {
let li = list . createEl ( "li" , { cls : [ "dataview" , "dataview-li" , "dataview-result-object-li" ] } ) ;
li . appendText ( key + ": " ) ;
yield renderValue ( value , li , originFile , component , settings , expandList , context , depth + 1 ) ;
}
}
else {
if ( Object . keys ( field ) . length == 0 ) {
container . appendText ( "<empty object>" ) ;
return ;
}
let span = container . createEl ( "span" , { cls : [ "dataview" , "dataview-result-object-span" ] } ) ;
let first = true ;
for ( let [ key , value ] of Object . entries ( field ) ) {
if ( first )
first = false ;
else
span . appendText ( ", " ) ;
span . appendText ( key + ": " ) ;
yield renderValue ( value , span , originFile , component , settings , expandList , context , depth + 1 ) ;
}
}
}
else {
container . appendText ( "Unrecognized: " + JSON . stringify ( field ) ) ;
}
} ) ;
}
/** Utility methods for creating & comparing fields. */
var Fields ;
( function ( Fields ) {
function variable ( name ) {
return { type : "variable" , name } ;
}
Fields . variable = variable ;
function literal ( value ) {
return { type : "literal" , value } ;
}
Fields . literal = literal ;
function binaryOp ( left , op , right ) {
return { type : "binaryop" , left , op , right } ;
}
Fields . binaryOp = binaryOp ;
function index ( obj , index ) {
return { type : "index" , object : obj , index } ;
}
Fields . index = index ;
/** Converts a string in dot-notation-format into a variable which indexes. */
function indexVariable ( name ) {
let parts = name . split ( "." ) ;
let result = Fields . variable ( parts [ 0 ] ) ;
for ( let index = 1 ; index < parts . length ; index ++ ) {
result = Fields . index ( result , Fields . literal ( parts [ index ] ) ) ;
}
return result ;
}
Fields . indexVariable = indexVariable ;
function lambda ( args , value ) {
return { type : "lambda" , arguments : args , value } ;
}
Fields . lambda = lambda ;
function func ( func , args ) {
return { type : "function" , func , arguments : args } ;
}
Fields . func = func ;
function list ( values ) {
return { type : "list" , values } ;
}
Fields . list = list ;
function object ( values ) {
return { type : "object" , values } ;
}
Fields . object = object ;
function negate ( child ) {
return { type : "negated" , child } ;
}
Fields . negate = negate ;
function isCompareOp ( op ) {
return op == "<=" || op == "<" || op == ">" || op == ">=" || op == "!=" || op == "=" ;
}
Fields . isCompareOp = isCompareOp ;
Fields . NULL = Fields . literal ( null ) ;
} ) ( Fields || ( Fields = { } ) ) ;
/** AST implementation for queries over data sources. */
/** Utility functions for creating and manipulating sources. */
var Sources ;
( function ( Sources ) {
function tag ( tag ) {
return { type : "tag" , tag } ;
}
Sources . tag = tag ;
function csv ( path ) {
return { type : "csv" , path } ;
}
Sources . csv = csv ;
function folder ( prefix ) {
return { type : "folder" , folder : prefix } ;
}
Sources . folder = folder ;
function link ( file , incoming ) {
return { type : "link" , file , direction : incoming ? "incoming" : "outgoing" } ;
}
Sources . link = link ;
function binaryOp ( left , op , right ) {
return { type : "binaryop" , left , op , right } ;
}
Sources . binaryOp = binaryOp ;
function negate ( child ) {
return { type : "negate" , child } ;
}
Sources . negate = negate ;
function empty ( ) {
return { type : "empty" } ;
}
Sources . empty = empty ;
} ) ( Sources || ( Sources = { } ) ) ;
/** Emoji regex without any additional flags. */
const EMOJI _REGEX = new RegExp ( emojiRegex ( ) , "" ) ;
/** Provides a lookup table for unit durations of the given type. */
const DURATION _TYPES = {
year : Duration _1 . fromObject ( { years : 1 } ) ,
years : Duration _1 . fromObject ( { years : 1 } ) ,
yr : Duration _1 . fromObject ( { years : 1 } ) ,
yrs : Duration _1 . fromObject ( { years : 1 } ) ,
month : Duration _1 . fromObject ( { months : 1 } ) ,
months : Duration _1 . fromObject ( { months : 1 } ) ,
mo : Duration _1 . fromObject ( { months : 1 } ) ,
mos : Duration _1 . fromObject ( { months : 1 } ) ,
week : Duration _1 . fromObject ( { weeks : 1 } ) ,
weeks : Duration _1 . fromObject ( { weeks : 1 } ) ,
wk : Duration _1 . fromObject ( { weeks : 1 } ) ,
wks : Duration _1 . fromObject ( { weeks : 1 } ) ,
w : Duration _1 . fromObject ( { weeks : 1 } ) ,
day : Duration _1 . fromObject ( { days : 1 } ) ,
days : Duration _1 . fromObject ( { days : 1 } ) ,
d : Duration _1 . fromObject ( { days : 1 } ) ,
hour : Duration _1 . fromObject ( { hours : 1 } ) ,
hours : Duration _1 . fromObject ( { hours : 1 } ) ,
hr : Duration _1 . fromObject ( { hours : 1 } ) ,
hrs : Duration _1 . fromObject ( { hours : 1 } ) ,
h : Duration _1 . fromObject ( { hours : 1 } ) ,
minute : Duration _1 . fromObject ( { minutes : 1 } ) ,
minutes : Duration _1 . fromObject ( { minutes : 1 } ) ,
min : Duration _1 . fromObject ( { minutes : 1 } ) ,
mins : Duration _1 . fromObject ( { minutes : 1 } ) ,
m : Duration _1 . fromObject ( { minutes : 1 } ) ,
second : Duration _1 . fromObject ( { seconds : 1 } ) ,
seconds : Duration _1 . fromObject ( { seconds : 1 } ) ,
sec : Duration _1 . fromObject ( { seconds : 1 } ) ,
secs : Duration _1 . fromObject ( { seconds : 1 } ) ,
s : Duration _1 . fromObject ( { seconds : 1 } ) ,
} ;
/ * *
* Keywords which cannot be used as variables directly . Use ` row.<thing> ` if it is a variable you have defined and want
* to access .
* /
const KEYWORDS = [ "FROM" , "WHERE" , "LIMIT" , "GROUP" , "FLATTEN" ] ;
///////////////
// Utilities //
///////////////
/** Attempt to parse the inside of a link to pull out display name, subpath, etc. */
function parseInnerLink ( link ) {
let display = undefined ;
if ( link . includes ( "|" ) ) {
let split = link . split ( "|" ) ;
link = split [ 0 ] ;
display = split [ 1 ] ;
}
if ( link . includes ( "#" ) ) {
let split = link . split ( "#" ) ;
return Link . header ( split [ 0 ] , split [ 1 ] , false , display ) ;
}
else if ( link . includes ( "^" ) ) {
let split = link . split ( "^" ) ;
return Link . block ( split [ 0 ] , split [ 1 ] , false , display ) ;
}
return Link . file ( link , false , display ) ;
}
/** Create a left-associative binary parser which parses the given sub-element and separator. Handles whitespace. */
function createBinaryParser ( child , sep , combine ) {
return parsimmon _umd _min . exports . seqMap ( child , parsimmon _umd _min . exports . seq ( parsimmon _umd _min . exports . optWhitespace , sep , parsimmon _umd _min . exports . optWhitespace , child ) . many ( ) , ( first , rest ) => {
if ( rest . length == 0 )
return first ;
let node = combine ( first , rest [ 0 ] [ 1 ] , rest [ 0 ] [ 3 ] ) ;
for ( let index = 1 ; index < rest . length ; index ++ ) {
node = combine ( node , rest [ index ] [ 1 ] , rest [ index ] [ 3 ] ) ;
}
return node ;
} ) ;
}
function chainOpt ( base , ... funcs ) {
return parsimmon _umd _min . exports . custom ( ( success , failure ) => {
return ( input , i ) => {
let result = base . _ ( input , i ) ;
if ( ! result . status )
return result ;
for ( let func of funcs ) {
let next = func ( result . value ) . _ ( input , result . index ) ;
if ( ! next . status )
return result ;
result = next ;
}
return result ;
} ;
} ) ;
}
const EXPRESSION = parsimmon _umd _min . exports . createLanguage ( {
// A floating point number; the decimal point is optional.
number : q => parsimmon _umd _min . exports . regexp ( /-?[0-9]+(\.[0-9]+)?/ )
. map ( str => Number . parseFloat ( str ) )
. desc ( "number" ) ,
// A quote-surrounded string which supports escape characters ('\').
string : q => parsimmon _umd _min . exports . string ( '"' )
. then ( parsimmon _umd _min . exports . alt ( q . escapeCharacter , parsimmon _umd _min . exports . noneOf ( '"\\' ) )
. atLeast ( 0 )
. map ( chars => chars . join ( "" ) ) )
. skip ( parsimmon _umd _min . exports . string ( '"' ) )
. desc ( "string" ) ,
escapeCharacter : _ => parsimmon _umd _min . exports . string ( "\\" )
. then ( parsimmon _umd _min . exports . any )
. map ( escaped => {
// If we are escaping a backslash or a quote, pass in on in escaped form
if ( escaped === '"' )
return '"' ;
if ( escaped === "\\" )
return "\\" ;
else
return "\\" + escaped ;
} ) ,
// A boolean true/false value.
bool : _ => parsimmon _umd _min . exports . regexp ( /true|false|True|False/ )
. map ( str => str . toLowerCase ( ) == "true" )
. desc ( "boolean ('true' or 'false')" ) ,
// A tag of the form '#stuff/hello-there'.
tag : _ => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "#" ) , parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regexp ( /[\p{Letter}0-9_/-]/u ) , parsimmon _umd _min . exports . regexp ( EMOJI _REGEX ) ) . many ( ) , ( start , rest ) => start + rest . join ( "" ) ) . desc ( "tag ('#hello/stuff')" ) ,
// A variable identifier, which is alphanumeric and must start with a letter or... emoji.
identifier : _ => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regexp ( /\p{Letter}/u ) , parsimmon _umd _min . exports . regexp ( EMOJI _REGEX ) ) , parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regexp ( /[0-9\p{Letter}_-]/u ) , parsimmon _umd _min . exports . regexp ( EMOJI _REGEX ) ) . many ( ) , ( first , rest ) => first + rest . join ( "" ) ) . desc ( "variable identifier" ) ,
// A variable identifier, which is alphanumeric and must start with a letter. Can include dots.
identifierDot : _ => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regexp ( /\p{Letter}/u ) , parsimmon _umd _min . exports . regexp ( EMOJI _REGEX ) ) , parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regexp ( /[0-9\p{Letter}\._-]/u ) , parsimmon _umd _min . exports . regexp ( EMOJI _REGEX ) ) . many ( ) , ( first , rest ) => first + rest . join ( "" ) ) . desc ( "variable identifier" ) ,
// An Obsidian link of the form [[<link>]].
link : _ => parsimmon _umd _min . exports . regexp ( /\[\[([^\[\]]*?)\]\]/u , 1 )
. map ( linkInner => parseInnerLink ( linkInner ) )
. desc ( "file link" ) ,
// An embeddable link which can start with '!'. This overlaps with the normal negation operator, so it is only
// provided for metadata parsing.
embedLink : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "!" ) . atMost ( 1 ) , q . link , ( p , l ) => {
if ( p . length > 0 )
l . embed = true ;
return l ;
} ) ,
// Binary plus or minus operator.
binaryPlusMinus : _ => parsimmon _umd _min . exports . regexp ( /\+|-/ )
. map ( str => str )
. desc ( "'+' or '-'" ) ,
// Binary times or divide operator.
binaryMulDiv : _ => parsimmon _umd _min . exports . regexp ( /\*|\// )
. map ( str => str )
. desc ( "'*' or '/'" ) ,
// Binary comparison operator.
binaryCompareOp : _ => parsimmon _umd _min . exports . regexp ( />=|<=|!=|>|<|=/ )
. map ( str => str )
. desc ( "'>=' or '<=' or '!=' or '=' or '>' or '<'" ) ,
// Binary boolean combination operator.
binaryBooleanOp : _ => parsimmon _umd _min . exports . regexp ( /and|or|&|\|/i )
. map ( str => {
if ( str . toLowerCase ( ) == "and" )
return "&" ;
else if ( str . toLowerCase ( ) == "or" )
return "|" ;
else
return str ;
} )
. desc ( "'and' or 'or'" ) ,
// A date which can be YYYY-MM[-DDTHH:mm:ss].
rootDate : _ => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /\d{4}/ ) , parsimmon _umd _min . exports . string ( "-" ) , parsimmon _umd _min . exports . regexp ( /\d{2}/ ) , ( year , _ , month ) => {
return DateTime _1 . fromObject ( { year : Number . parseInt ( year ) , month : Number . parseInt ( month ) } ) ;
} ) . desc ( "date in format YYYY-MM[-DDTHH-MM-SS.MS]" ) ,
date : q => chainOpt ( q . rootDate , ( ym ) => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "-" ) , parsimmon _umd _min . exports . regexp ( /\d{2}/ ) , ( _ , day ) => ym . set ( { day : Number . parseInt ( day ) } ) ) , ( ymd ) => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "T" ) , parsimmon _umd _min . exports . regexp ( /\d{2}/ ) , ( _ , hour ) => ymd . set ( { hour : Number . parseInt ( hour ) } ) ) , ( ymdh ) => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( ":" ) , parsimmon _umd _min . exports . regexp ( /\d{2}/ ) , ( _ , minute ) => ymdh . set ( { minute : Number . parseInt ( minute ) } ) ) , ( ymdhm ) => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( ":" ) , parsimmon _umd _min . exports . regexp ( /\d{2}/ ) , ( _ , second ) => ymdhm . set ( { second : Number . parseInt ( second ) } ) ) , ( ymdhms ) => parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "." ) , parsimmon _umd _min . exports . regexp ( /\d{3}/ ) , ( _ , millisecond ) => ymdhms . set ( { millisecond : Number . parseInt ( millisecond ) } ) ) , parsimmon _umd _min . exports . succeed ( ymdhms ) // pass
) , ( dt ) => parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "+" ) . or ( parsimmon _umd _min . exports . string ( "-" ) ) , parsimmon _umd _min . exports . regexp ( /\d{1,2}(:\d{2})?/ ) , ( pm , hr ) => dt . setZone ( "UTC" + pm + hr ) ) , parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "Z" ) , ( ) => dt . setZone ( "utc" ) ) ) ) ,
// A date, plus various shorthand times of day it could be.
datePlus : q => parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . string ( "now" ) . map ( _ => DateTime _1 . local ( ) ) , parsimmon _umd _min . exports . string ( "today" ) . map ( _ => DateTime _1 . local ( ) . startOf ( "day" ) ) , parsimmon _umd _min . exports . string ( "tomorrow" ) . map ( _ => DateTime _1 . local ( )
. startOf ( "day" )
. plus ( Duration _1 . fromObject ( { days : 1 } ) ) ) , parsimmon _umd _min . exports . string ( "som" ) . map ( _ => DateTime _1 . local ( ) . startOf ( "month" ) ) , parsimmon _umd _min . exports . string ( "soy" ) . map ( _ => DateTime _1 . local ( ) . startOf ( "year" ) ) , parsimmon _umd _min . exports . string ( "eom" ) . map ( _ => DateTime _1 . local ( ) . endOf ( "month" ) ) , parsimmon _umd _min . exports . string ( "eoy" ) . map ( _ => DateTime _1 . local ( ) . endOf ( "year" ) ) , q . date ) ,
// A duration of time.
durationType : _ => parsimmon _umd _min . exports . alt ( ... Object . keys ( DURATION _TYPES )
. sort ( ( a , b ) => b . length - a . length )
. map ( parsimmon _umd _min . exports . string ) ) ,
duration : q => parsimmon _umd _min . exports . seqMap ( q . number , parsimmon _umd _min . exports . optWhitespace , q . durationType , ( count , _ , t ) => DURATION _TYPES [ t ] . mapUnits ( x => x * count ) )
. sepBy1 ( parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) . or ( parsimmon _umd _min . exports . optWhitespace ) )
. map ( durations => durations . reduce ( ( p , c ) => p . plus ( c ) ) ) ,
// A raw null value.
rawNull : _ => parsimmon _umd _min . exports . string ( "null" ) ,
// Source parsing.
tagSource : q => q . tag . map ( tag => Sources . tag ( tag ) ) ,
csvSource : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "csv(" ) . skip ( parsimmon _umd _min . exports . optWhitespace ) , q . string , parsimmon _umd _min . exports . string ( ")" ) , ( _1 , path , _2 ) => Sources . csv ( path ) ) ,
linkIncomingSource : q => q . link . map ( link => Sources . link ( link . path , true ) ) ,
linkOutgoingSource : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "outgoing(" ) . skip ( parsimmon _umd _min . exports . optWhitespace ) , q . link , parsimmon _umd _min . exports . string ( ")" ) , ( _1 , link , _2 ) => Sources . link ( link . path , false ) ) ,
folderSource : q => q . string . map ( str => Sources . folder ( str ) ) ,
parensSource : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "(" ) , parsimmon _umd _min . exports . optWhitespace , q . source , parsimmon _umd _min . exports . optWhitespace , parsimmon _umd _min . exports . string ( ")" ) , ( _1 , _2 , field , _3 , _4 ) => field ) ,
negateSource : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . string ( "-" ) , parsimmon _umd _min . exports . string ( "!" ) ) , q . atomSource , ( _ , source ) => Sources . negate ( source ) ) ,
atomSource : q => parsimmon _umd _min . exports . alt ( q . parensSource , q . negateSource , q . linkOutgoingSource , q . linkIncomingSource , q . folderSource , q . tagSource , q . csvSource ) ,
binaryOpSource : q => createBinaryParser ( q . atomSource , q . binaryBooleanOp . map ( s => s ) , Sources . binaryOp ) ,
source : q => q . binaryOpSource ,
// Field parsing.
variableField : q => q . identifier
. chain ( r => {
if ( KEYWORDS . includes ( r . toUpperCase ( ) ) ) {
return parsimmon _umd _min . exports . fail ( "Variable fields cannot be a keyword (" + KEYWORDS . join ( " or " ) + ")" ) ;
}
else {
return parsimmon _umd _min . exports . succeed ( Fields . variable ( r ) ) ;
}
} )
. desc ( "variable" ) ,
numberField : q => q . number . map ( val => Fields . literal ( val ) ) . desc ( "number" ) ,
stringField : q => q . string . map ( val => Fields . literal ( val ) ) . desc ( "string" ) ,
boolField : q => q . bool . map ( val => Fields . literal ( val ) ) . desc ( "boolean" ) ,
dateField : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "date(" ) , parsimmon _umd _min . exports . optWhitespace , q . datePlus , parsimmon _umd _min . exports . optWhitespace , parsimmon _umd _min . exports . string ( ")" ) , ( prefix , _1 , date , _2 , postfix ) => Fields . literal ( date ) ) . desc ( "date" ) ,
durationField : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "dur(" ) , parsimmon _umd _min . exports . optWhitespace , q . duration , parsimmon _umd _min . exports . optWhitespace , parsimmon _umd _min . exports . string ( ")" ) , ( prefix , _1 , dur , _2 , postfix ) => Fields . literal ( dur ) ) . desc ( "duration" ) ,
nullField : q => q . rawNull . map ( _ => Fields . NULL ) ,
linkField : q => q . link . map ( f => Fields . literal ( f ) ) ,
listField : q => q . field
. sepBy ( parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) )
. wrap ( parsimmon _umd _min . exports . string ( "[" ) . skip ( parsimmon _umd _min . exports . optWhitespace ) , parsimmon _umd _min . exports . optWhitespace . then ( parsimmon _umd _min . exports . string ( "]" ) ) )
. map ( l => Fields . list ( l ) )
. desc ( "list ('[1, 2, 3]')" ) ,
objectField : q => parsimmon _umd _min . exports . seqMap ( q . identifier . or ( q . string ) , parsimmon _umd _min . exports . string ( ":" ) . trim ( parsimmon _umd _min . exports . optWhitespace ) , q . field , ( name , _sep , value ) => {
return { name , value } ;
} )
. sepBy ( parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) )
. wrap ( parsimmon _umd _min . exports . string ( "{" ) . skip ( parsimmon _umd _min . exports . optWhitespace ) , parsimmon _umd _min . exports . optWhitespace . then ( parsimmon _umd _min . exports . string ( "}" ) ) )
. map ( vals => {
let res = { } ;
for ( let entry of vals )
res [ entry . name ] = entry . value ;
return Fields . object ( res ) ;
} )
. desc ( "object ('{ a: 1, b: 2 }')" ) ,
atomInlineField : q => parsimmon _umd _min . exports . alt ( q . date , q . duration . map ( d => normalizeDuration ( d ) ) , q . string , q . embedLink , q . bool , q . number , q . rawNull ) ,
inlineFieldList : q => q . atomInlineField . sepBy ( parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) . lookahead ( q . atomInlineField ) ) ,
inlineField : q => parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . seqMap ( q . atomInlineField , parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) , q . inlineFieldList , ( f , _s , l ) => [ f ] . concat ( l ) ) , q . atomInlineField ) ,
atomField : q => parsimmon _umd _min . exports . alt ( q . negatedField , q . linkField , q . listField , q . objectField , q . lambdaField , q . parensField , q . boolField , q . numberField , q . stringField , q . dateField , q . durationField , q . nullField , q . variableField ) ,
indexField : q => parsimmon _umd _min . exports . seqMap ( q . atomField , parsimmon _umd _min . exports . alt ( q . dotPostfix , q . indexPostfix , q . functionPostfix ) . many ( ) , ( obj , postfixes ) => {
let result = obj ;
for ( let post of postfixes ) {
switch ( post . type ) {
case "dot" :
case "index" :
result = Fields . index ( result , post . field ) ;
break ;
case "function" :
result = Fields . func ( result , post . fields ) ;
break ;
}
}
return result ;
} ) ,
negatedField : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "!" ) , q . indexField , ( _ , field ) => Fields . negate ( field ) ) . desc ( "negated field" ) ,
parensField : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "(" ) , parsimmon _umd _min . exports . optWhitespace , q . field , parsimmon _umd _min . exports . optWhitespace , parsimmon _umd _min . exports . string ( ")" ) , ( _1 , _2 , field , _3 , _4 ) => field ) ,
lambdaField : q => parsimmon _umd _min . exports . seqMap ( q . identifier
. sepBy ( parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) )
. wrap ( parsimmon _umd _min . exports . string ( "(" ) . trim ( parsimmon _umd _min . exports . optWhitespace ) , parsimmon _umd _min . exports . string ( ")" ) . trim ( parsimmon _umd _min . exports . optWhitespace ) ) , parsimmon _umd _min . exports . string ( "=>" ) . trim ( parsimmon _umd _min . exports . optWhitespace ) , q . field , ( ident , _ignore , value ) => {
return { type : "lambda" , arguments : ident , value } ;
} ) ,
dotPostfix : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "." ) , q . identifier , ( _ , field ) => {
return { type : "dot" , field : Fields . literal ( field ) } ;
} ) ,
indexPostfix : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "[" ) , parsimmon _umd _min . exports . optWhitespace , q . field , parsimmon _umd _min . exports . optWhitespace , parsimmon _umd _min . exports . string ( "]" ) , ( _ , _2 , field , _3 , _4 ) => {
return { type : "index" , field } ;
} ) ,
functionPostfix : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . string ( "(" ) , parsimmon _umd _min . exports . optWhitespace , q . field . sepBy ( parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) ) , parsimmon _umd _min . exports . optWhitespace , parsimmon _umd _min . exports . string ( ")" ) , ( _ , _1 , fields , _2 , _3 ) => {
return { type : "function" , fields } ;
} ) ,
// The precedence hierarchy of operators - multiply/divide, add/subtract, compare, and then boolean operations.
binaryMulDivField : q => createBinaryParser ( q . indexField , q . binaryMulDiv , Fields . binaryOp ) ,
binaryPlusMinusField : q => createBinaryParser ( q . binaryMulDivField , q . binaryPlusMinus , Fields . binaryOp ) ,
binaryCompareField : q => createBinaryParser ( q . binaryPlusMinusField , q . binaryCompareOp , Fields . binaryOp ) ,
binaryBooleanField : q => createBinaryParser ( q . binaryCompareField , q . binaryBooleanOp , Fields . binaryOp ) ,
binaryOpField : q => q . binaryBooleanField ,
field : q => q . binaryOpField ,
} ) ;
/ * *
* Attempt to parse a field from the given text , returning a string error if the
* parse failed .
* /
function parseField ( text ) {
try {
return Result . success ( EXPRESSION . field . tryParse ( text ) ) ;
}
catch ( error ) {
return Result . failure ( "" + error ) ;
}
}
/** Parse inline fields and other embedded metadata in a line. */
/** The wrapper characters that can be used to define an inline field. */
const INLINE _FIELD _WRAPPERS = Object . freeze ( {
"[" : "]" ,
"(" : ")" ,
} ) ;
/ * *
* Find a matching closing bracket that occurs at or after ` start ` , respecting nesting and escapes . If found ,
* returns the value contained within and the string index after the end of the value .
* /
function findClosing ( line , start , open , close ) {
let nesting = 0 ;
let escaped = false ;
for ( let index = start ; index < line . length ; index ++ ) {
let char = line . charAt ( index ) ;
// Allows for double escapes like '\\' to be rendered normally.
if ( char == "\\" ) {
escaped = ! escaped ;
continue ;
}
if ( escaped ) {
escaped = false ;
continue ;
}
if ( char == open )
nesting ++ ;
else if ( char == close )
nesting -- ;
// Only occurs if we are on a close character and trhere is no more nesting.
if ( nesting < 0 )
return { value : line . substring ( start , index ) . trim ( ) , endIndex : index + 1 } ;
escaped = false ;
}
return undefined ;
}
/** Find the '::' separator in an inline field. */
function findSeparator ( line , start ) {
let sep = line . indexOf ( "::" , start ) ;
let key = line . substring ( start , sep ) ;
// Fail the match if we find any separator characters (not allowed in keys).
for ( let sep of Object . keys ( INLINE _FIELD _WRAPPERS ) . concat ( Object . values ( INLINE _FIELD _WRAPPERS ) ) ) {
if ( key . includes ( sep ) )
return undefined ;
}
return { key : key . trim ( ) , valueIndex : sep + 2 } ;
}
/** Try to completely parse an inline field starting at the given position. Assuems `start` is on a wrapping character. */
function findSpecificInlineField ( line , start ) {
let open = line . charAt ( start ) ;
let key = findSeparator ( line , start + 1 ) ;
if ( key === undefined )
return undefined ;
let value = findClosing ( line , key . valueIndex , open , INLINE _FIELD _WRAPPERS [ open ] ) ;
if ( value === undefined )
return undefined ;
return {
key : key . key ,
value : value . value ,
start : start ,
startValue : key . valueIndex ,
end : value . endIndex ,
wrapping : open ,
} ;
}
/** Parse a textual inline field value into something we can work with. */
function parseInlineValue ( value ) {
// The stripped literal field parser understands all of the non-array/non-object fields and can parse them for us.
// Inline field objects are not currently supported; inline array objects have to be handled by the parser
// separately.
let inline = EXPRESSION . inlineField . parse ( value ) ;
if ( inline . status )
return inline . value ;
else
return value ;
}
/ * * E x t r a c t s i n l i n e f i e l d s o f t h e f o r m ' [ k e y : : v a l u e ] ' f r o m a l i n e o f t e x t . T h i s i s d o n e i n a r e l a t i v e l y
* "robust" way to avoid failing due to bad nesting or other interfering Markdown symbols :
*
* - Look for any wrappers ( '[' and '(' ) in the line , trying to parse whatever comes after it as an inline key : : .
* - If successful , scan until you find a matching end bracket , and parse whatever remains as an inline value .
* /
function extractInlineFields ( line ) {
let fields = [ ] ;
for ( let wrapper of Object . keys ( INLINE _FIELD _WRAPPERS ) ) {
let foundIndex = line . indexOf ( wrapper ) ;
while ( foundIndex >= 0 ) {
let parsedField = findSpecificInlineField ( line , foundIndex ) ;
if ( ! parsedField ) {
foundIndex = line . indexOf ( wrapper , foundIndex + 1 ) ;
continue ;
}
fields . push ( parsedField ) ;
foundIndex = line . indexOf ( wrapper , parsedField . end ) ;
}
}
fields . sort ( ( a , b ) => a . start - b . start ) ;
return fields ;
}
/** All extracted markdown file metadata obtained from a file. */
class PageMetadata {
constructor ( path , init ) {
this . path = path ;
this . fields = new Map ( ) ;
this . tags = new Set ( ) ;
this . aliases = new Set ( ) ;
this . links = [ ] ;
this . tasks = [ ] ;
Object . assign ( this , init ) ;
}
/** Parse all subtags out of the given tag. I.e., #hello/i/am would yield [#hello/i/am, #hello/i, #hello]. */
static parseSubtags ( tag ) {
let result = [ tag ] ;
while ( tag . includes ( "/" ) ) {
tag = tag . substring ( 0 , tag . lastIndexOf ( "/" ) ) ;
result . push ( tag ) ;
}
return result ;
}
/** The name (based on path) of this file. */
name ( ) {
return getFileTitle ( this . path ) ;
}
/** The containing folder (based on path) of this file. */
folder ( ) {
return getParentFolder ( this . path ) ;
}
/** The extension of this file (likely 'md'). */
extension ( ) {
return getExtension ( this . path ) ;
}
/** Return a set of tags AND all of their parent tags (so #hello/yes would become #hello, #hello/yes). */
fullTags ( ) {
// TODO: Memoize this, probably.
let result = new Set ( ) ;
for ( let tag of this . tags ) {
for ( let subtag of PageMetadata . parseSubtags ( tag ) )
result . add ( subtag ) ;
}
return result ;
}
/** Convert all links in this file to file links. */
fileLinks ( ) {
return this . links . map ( link => Link . file ( link . path ) ) ;
}
/** Map this metadata to a full object; uses the index for additional data lookups. */
toObject ( index ) {
// Static fields first. Note this object should not have any pointers to the original object (so that the
// index cannot accidentally be mutated).
let result = {
file : {
path : this . path ,
folder : this . folder ( ) ,
name : this . name ( ) ,
link : Link . file ( this . path , false ) ,
outlinks : this . fileLinks ( ) ,
inlinks : Array . from ( index . links . getInverse ( this . path ) ) . map ( l => Link . file ( l , false ) ) ,
etags : Array . from ( this . tags ) ,
tags : Array . from ( this . fullTags ( ) ) ,
aliases : Array . from ( this . aliases ) ,
tasks : this . tasks . map ( t => t . toObject ( ) ) ,
ctime : this . ctime ,
cday : stripTime ( this . ctime ) ,
mtime : this . mtime ,
mday : stripTime ( this . mtime ) ,
size : this . size ,
ext : this . extension ( ) ,
} ,
} ;
// Add the current day if present.
if ( this . day )
result . file . day = this . day ;
// Then append the computed fields.
for ( let [ key , value ] of this . fields ) {
if ( key === "file" )
continue ; // Don't allow fields to override 'file'.
result [ key ] = value ;
}
return result ;
}
}
/** Importer for markdown documents. */
/** Attempt to find a date associated with the given page from metadata or filenames. */
function findDate ( file , fields ) {
var _a , _b ;
for ( let key of fields . keys ( ) ) {
if ( ! ( key . toLocaleLowerCase ( ) == "date" || key . toLocaleLowerCase ( ) == "day" ) )
continue ;
let value = fields . get ( key ) ;
if ( Values . isDate ( value ) )
return value ;
else if ( Values . isLink ( value ) ) {
let date = extractDate ( value . path ) ;
if ( date )
return date ;
date = extractDate ( ( _a = value . subpath ) !== null && _a !== void 0 ? _a : "" ) ;
if ( date )
return date ;
date = extractDate ( ( _b = value . display ) !== null && _b !== void 0 ? _b : "" ) ;
if ( date )
return date ;
}
}
return extractDate ( getFileTitle ( file ) ) ;
}
/** Recursively convert frontmatter into fields. We have to dance around YAML structure. */
function parseFrontmatter ( value ) {
if ( value == null ) {
return null ;
}
else if ( typeof value === "object" ) {
if ( Array . isArray ( value ) ) {
let result = [ ] ;
for ( let child of value ) {
result . push ( parseFrontmatter ( child ) ) ;
}
return result ;
}
else {
let object = value ;
let result = { } ;
for ( let key in object ) {
result [ key ] = parseFrontmatter ( object [ key ] ) ;
}
return result ;
}
}
else if ( typeof value === "number" ) {
return value ;
}
else if ( typeof value === "boolean" ) {
return value ;
}
else if ( typeof value === "string" ) {
let dateParse = EXPRESSION . date . parse ( value ) ;
if ( dateParse . status )
return dateParse . value ;
let durationParse = EXPRESSION . duration . parse ( value ) ;
if ( durationParse . status )
return durationParse . value ;
let linkParse = EXPRESSION . embedLink . parse ( value ) ;
if ( linkParse . status )
return linkParse . value ;
return value ;
}
// Backup if we don't understand the type.
return null ;
}
/** Add an inline field to a nexisting field array, converting a single value into an array if it is present multiple times. */
function addInlineField ( fields , name , value ) {
if ( fields . has ( name ) ) {
let existing = fields . get ( name ) ;
if ( Values . isArray ( existing ) )
fields . set ( name , existing . concat ( [ value ] ) ) ;
else
fields . set ( name , [ existing , value ] ) ;
}
else {
fields . set ( name , value ) ;
}
}
/** Matches lines of the form "- [ ] <task thing>". */
const TASK _REGEX = /^(\s*)[-*]\s*(\[[ Xx\.]?\])?\s*([^-*].*)$/iu ;
/** Extract markdown metadata from the given Obsidian markdown file. */
function parsePage ( file , cache , markdownData ) {
var _a ;
let tags = new Set ( ) ;
let aliases = new Set ( ) ;
let fields = new Map ( ) ;
// Pull out the easy-to-extract information from the cache first...
let fileCache = cache . getFileCache ( file ) ;
if ( fileCache ) {
// File tags, including front-matter and in-file tags.
( _a = obsidian . getAllTags ( fileCache ) ) === null || _a === void 0 ? void 0 : _a . forEach ( t => tags . add ( t ) ) ;
// Front-matter file tags, aliases, AND frontmatter properties.
if ( fileCache . frontmatter ) {
let frontTags = obsidian . parseFrontMatterTags ( fileCache . frontmatter ) ;
if ( frontTags ) {
for ( let tag of frontTags ) {
if ( ! tag . startsWith ( "#" ) )
tag = "#" + tag ;
tags . add ( tag ) ;
}
}
let frontAliases = obsidian . parseFrontMatterAliases ( fileCache . frontmatter ) ;
if ( frontAliases ) {
for ( let alias of frontAliases )
aliases . add ( alias ) ;
}
let frontFields = parseFrontmatter ( fileCache . frontmatter ) ;
for ( let [ key , value ] of Object . entries ( frontFields ) )
fields . set ( key , value ) ;
}
}
// Grab links from the frontmatter cache.
let links = [ ] ;
if ( file . path in cache . resolvedLinks ) {
for ( let resolved in cache . resolvedLinks [ file . path ] )
links . push ( Link . file ( resolved ) ) ;
}
// Merge frontmatter fields with parsed fields.
for ( let [ name , values ] of markdownData . fields . entries ( ) ) {
for ( let value of values )
addInlineField ( fields , name , value ) ;
}
// Add task defaults; this should probably be done in the task parsing directly
// once the parser has access to the common file metadata.
let pageCtime = DateTime _1 . fromMillis ( file . stat . ctime ) ;
let fixedTasks = markdownData . tasks . map ( t => t . withDefaultDates ( pageCtime , undefined ) ) ;
return new PageMetadata ( file . path , {
fields ,
tags ,
aliases ,
links ,
tasks : fixedTasks ,
ctime : pageCtime ,
mtime : DateTime _1 . fromMillis ( file . stat . mtime ) ,
size : file . stat . size ,
day : findDate ( file . path , fields ) ,
} ) ;
}
var papaparse _min = { exports : { } } ;
/ * @ l i c e n s e
Papa Parse
v5 . 3.1
https : //github.com/mholt/PapaParse
License : MIT
* /
( function ( module , exports ) {
! function ( e , t ) { module . exports = t ( ) ; } ( commonjsGlobal , function s ( ) { var f = "undefined" != typeof self ? self : "undefined" != typeof window ? window : void 0 !== f ? f : { } ; var n = ! f . document && ! ! f . postMessage , o = n && /blob:/i . test ( ( f . location || { } ) . protocol ) , a = { } , h = 0 , b = { parse : function ( e , t ) { var i = ( t = t || { } ) . dynamicTyping || ! 1 ; M ( i ) && ( t . dynamicTypingFunction = i , i = { } ) ; if ( t . dynamicTyping = i , t . transform = ! ! M ( t . transform ) && t . transform , t . worker && b . WORKERS _SUPPORTED ) { var r = function ( ) { if ( ! b . WORKERS _SUPPORTED ) return ! 1 ; var e = ( i = f . URL || f . webkitURL || null , r = s . toString ( ) , b . BLOB _URL || ( b . BLOB _URL = i . createObjectURL ( new Blob ( [ "(" , r , ")();" ] , { type : "text/javascript" } ) ) ) ) , t = new f . Worker ( e ) ; var i , r ; return t . onmessage = _ , t . id = h ++ , a [ t . id ] = t } ( ) ; return r . userStep = t . step , r . userChunk = t . chunk , r . userComplete = t . complete , r . userError = t . error , t . step = M ( t . step ) , t . chunk = M ( t . chunk ) , t . complete = M ( t . complete ) , t . error = M ( t . error ) , delete t . worker , void r . postMessage ( { input : e , config : t , workerId : r . id } ) } var n = null ; b . NODE _STREAM _INPUT , "string" == typeof e ? n = t . download ? new l ( t ) : new p ( t ) : ! 0 === e . readable && M ( e . read ) && M ( e . on ) ? n = new g ( t ) : ( f . File && e instanceof File || e instanceof Object ) && ( n = new c ( t ) ) ; return n . stream ( e ) } , unparse : function ( e , t ) { var n = ! 1 , _ = ! 0 , m = "," , y = "\r\n" , s = '"' , a = s + s , i = ! 1 , r = null , o = ! 1 ; ! function ( ) { if ( "object" != typeof t ) return ; "string" != typeof t . delimiter || b . BAD _DELIMITERS . filter ( function ( e ) { return - 1 !== t . delimiter . indexOf ( e ) } ) . length || ( m = t . delimiter ) ; ( "boolean" == typeof t . quotes || "function" == typeof t . quotes || Array . isArray ( t . quotes ) ) && ( n = t . quotes ) ; "boolean" != typeof t . skipEmptyLines && "string" != typeof t . skipEmptyLines || ( i = t . skipEmptyLines ) ; "string" == typeof t . newline && ( y = t . newline ) ; "string" == typeof t . quoteChar && ( s = t . quoteChar ) ; "boolean" == typeof t . header && ( _ = t . header ) ; if ( Array . isArray ( t . columns ) ) { if ( 0 === t . columns . length ) throw new Error ( "Option columns is empty" ) ; r = t . columns ; } void 0 !== t . escapeChar && ( a = t . escapeChar + s ) ; "boolean" == typeof t . escapeFormulae && ( o = t . escapeFormulae ) ; } ( ) ; var h = new RegExp ( j ( s ) , "g" ) ; "string" == typeof e && ( e = JSON . parse ( e ) ) ; if ( Array . isArray ( e ) ) { if ( ! e . length || Array . isArray ( e [ 0 ] ) ) return u ( null , e , i ) ; if ( "object" == typeof e [ 0 ] ) return u ( r || Object . keys ( e [ 0 ] ) , e , i ) } else if ( "object" == typeof e ) return "string" == typeof e . data && ( e . data = JSON . parse ( e . data ) ) , Array . isArray ( e . data ) && ( e . fields || ( e . fields = e . meta && e . meta . fields ) , e . fields || ( e . fields = Array . isArray ( e . data [ 0 ] ) ? e . fields : "object" == typeof e . data [ 0 ] ? Object . keys ( e . data [ 0 ] ) : [ ] ) , Array . isArray ( e . data [ 0 ] ) || "object" == typeof e . data [ 0 ] || ( e . data = [ e . data ] ) ) , u ( e . fields || [ ] , e . data || [ ] , i ) ; throw new Error ( "Unable to serialize unrecognized input" ) ; function u ( e , t , i ) { var r = "" ; "string" == typeof e && ( e = JSON . parse ( e ) ) , "string" == typeof t && ( t = JSON . parse ( t ) ) ; var n = Array . isArray ( e ) && 0 < e . length , s = ! Array . isArray ( t [ 0 ] ) ; if ( n && _ ) { for ( var a = 0 ; a < e . length ; a ++ ) 0 < a && ( r += m ) , r += v ( e [ a ] , a ) ; 0 < t . length && ( r += y ) ; } for ( var o = 0 ; o < t . length ; o ++ ) { var h = n ? e . length : t [ o ] . length , u = ! 1 , f = n ? 0 === Object . keys ( t [ o ] ) . length : 0 === t [ o ] . length ; if ( i && ! n && ( u = "greedy" === i ? "" === t [ o ] . join ( "" ) . trim ( ) : 1 === t [ o ] . length && 0 === t [ o ] [ 0 ] . length ) , "greedy" === i && n ) { for ( var d = [ ] , l = 0 ; l < h ; l ++ ) { var c = s ? e [ l ] : l ; d . push ( t [ o ] [ c ] ) ; } u = "" === d . join ( "" ) . trim ( ) ; } if ( ! u ) { for ( var p = 0 ; p < h ; p ++ ) { 0 < p && ! f && ( r += m ) ; var g = n && s ? e [ p ] : p ; r += v ( t [ o ] [ g ] , p ) ; } o < t . length - 1 && ( ! i || 0 < h && ! f ) && ( r += y ) ; } } return r } function v ( e , t ) { if ( null == e ) return "" ; if ( e . constructor === Date ) return JSON . stringify ( e ) . slice ( 1 , 25 ) ; ! 0 === o && "string" == typeof e && null !== e . match ( /^[=+\-@].*$/ ) && ( e = "'" + e ) ; var i = e . toString ( ) . replace ( h , a ) , r = "boolean" == typeof n && n || "function" == typeof n && n ( e , t ) || Array . isArray ( n ) && n [ t ] || function ( e , t ) { for ( var i = 0 ; i < t . length ; i ++ ) if ( - 1 < e . indexOf ( t [ i ] ) ) return ! 0 ; return ! 1 } ( i , b . BAD _DELIMITERS ) || - 1 < i . indexOf ( m ) || " " === i . charAt ( 0 ) || " " === i . charAt ( i . length - 1 ) ; return r ? s + i + s : i } } } ; if ( b . RECORD _SEP = String . fromCharCode ( 30 ) , b . UNIT _SEP = String . fromCharCode ( 31 ) , b . BYTE _ORDER _MARK = "\ufeff" , b . BAD _DELIMITERS = [ "\r" , "\n" , '"' , b . BYTE _ORDER _MARK ] , b . WORKERS _SUPPORTED = ! n && ! ! f . Worker , b . NODE _STREAM _INPUT = 1 , b . LocalChunkSize = 10485760 , b . RemoteChunkSize = 5242880 , b . DefaultDelimiter = "," , b . Parser = E , b . ParserHandle = i , b . NetworkStreamer = l , b . FileStreamer = c , b . StringStreamer = p , b . ReadableStreamStreamer = g , f . jQuery ) { var d = f . j
} ( papaparse _min ) ) ;
/** Parse a CSV file into a collection of data rows. */
function parseCsv ( content ) {
let parsed = papaparse _min . exports . parse ( content , {
header : true ,
skipEmptyLines : true ,
comments : "#" ,
dynamicTyping : true ,
} ) ;
let rows = [ ] ;
for ( let parsedRow of parsed . data ) {
let fields = parseFrontmatter ( parsedRow ) ;
let result = { } ;
for ( let [ key , value ] of Object . entries ( fields ) ) {
result [ key ] = value ;
result [ canonicalizeVarName ( key ) ] = value ;
}
rows . push ( result ) ;
}
return rows ;
}
var Transferable ;
( function ( Transferable ) {
/** Convert a literal value to a serializer-friendly transferable value. Does not work for all types. */
function transferable ( value ) {
// Handle non-dataview values first.
if ( value instanceof Map ) {
let copied = new Map ( ) ;
for ( let [ key , val ] of value . entries ( ) )
copied . set ( transferable ( key ) , transferable ( val ) ) ;
return copied ;
}
else if ( value instanceof Set ) {
let copied = new Set ( ) ;
for ( let val of value )
copied . add ( transferable ( val ) ) ;
return copied ;
}
let wrapped = Values . wrapValue ( value ) ;
if ( wrapped === undefined )
throw Error ( "Unrecognized transferable value: " + value ) ;
switch ( wrapped . type ) {
case "null" :
case "number" :
case "string" :
case "boolean" :
return wrapped . value ;
case "date" :
return {
"___transfer-type" : "date" ,
value : transferable ( wrapped . value . toObject ( ) ) ,
options : { zone : wrapped . value . zoneName } ,
} ;
case "duration" :
return { "___transfer-type" : "duration" , value : transferable ( wrapped . value . toObject ( ) ) } ;
case "array" :
return wrapped . value . map ( v => transferable ( v ) ) ;
case "object" :
let result = { } ;
for ( let [ key , value ] of Object . entries ( wrapped . value ) )
result [ key ] = transferable ( value ) ;
return result ;
case "link" :
return { "___transfer-type" : "link" , value : transferable ( wrapped . value . toObject ( ) ) } ;
case "task" :
return { "___transfer-type" : "task" , value : transferable ( wrapped . value . toObject ( false ) ) } ;
default :
throw Error ( "Unrecognized transferable literal value: " + value ) ;
}
}
Transferable . transferable = transferable ;
/** Convert a transferable value back to a literal value we can work with. */
function value ( transferable ) {
if ( transferable === null ) {
return null ;
}
else if ( transferable === undefined ) {
return undefined ;
}
else if ( transferable instanceof Map ) {
let real = new Map ( ) ;
for ( let [ key , val ] of transferable . entries ( ) )
real . set ( value ( key ) , value ( val ) ) ;
return real ;
}
else if ( transferable instanceof Set ) {
let real = new Set ( ) ;
for ( let val of transferable )
real . add ( value ( val ) ) ;
return real ;
}
else if ( Array . isArray ( transferable ) ) {
return transferable . map ( v => value ( v ) ) ;
}
else if ( typeof transferable === "object" ) {
if ( "___transfer-type" in transferable ) {
switch ( transferable [ "___transfer-type" ] ) {
case "date" :
let rawDate = DateTime _1 . fromObject ( value ( transferable . value ) ) ;
let dateOpts = value ( transferable . options ) ;
if ( dateOpts . zone )
rawDate . setZone ( dateOpts . zone ) ;
return rawDate ;
case "duration" :
return Duration _1 . fromObject ( value ( transferable . value ) ) ;
case "link" :
return Link . fromObject ( value ( transferable . value ) ) ;
case "task" :
return Task . fromObject ( value ( transferable . value ) ) ;
default :
throw Error ( ` Unrecognized transfer type ' ${ transferable [ "___transfer-type" ] } ' ` ) ;
}
}
let result = { } ;
for ( let [ key , val ] of Object . entries ( transferable ) )
result [ key ] = value ( val ) ;
return result ;
}
return transferable ;
}
Transferable . value = value ;
} ) ( Transferable || ( Transferable = { } ) ) ;
function decodeBase64 ( base64 , enableUnicode ) {
var binaryString = atob ( base64 ) ;
if ( enableUnicode ) {
var binaryView = new Uint8Array ( binaryString . length ) ;
for ( var i = 0 , n = binaryString . length ; i < n ; ++ i ) {
binaryView [ i ] = binaryString . charCodeAt ( i ) ;
}
return String . fromCharCode . apply ( null , new Uint16Array ( binaryView . buffer ) ) ;
}
return binaryString ;
}
function createURL ( base64 , sourcemapArg , enableUnicodeArg ) {
var sourcemap = sourcemapArg === undefined ? null : sourcemapArg ;
var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg ;
var source = decodeBase64 ( base64 , enableUnicode ) ;
var start = source . indexOf ( '\n' , 10 ) + 1 ;
var body = source . substring ( start ) + ( sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '' ) ;
var blob = new Blob ( [ body ] , { type : 'application/javascript' } ) ;
return URL . createObjectURL ( blob ) ;
}
function createBase64WorkerFactory ( base64 , sourcemapArg , enableUnicodeArg ) {
var url ;
return function WorkerFactory ( options ) {
url = url || createURL ( base64 , sourcemapArg , enableUnicodeArg ) ;
return new Worker ( url , options ) ;
} ;
}
var WorkerFactory = createBase64WorkerFactory ( ' Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIC8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICAgIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLg0KDQogICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55DQogICAgcHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLg0KDQogICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEgNCiAgICBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkNCiAgICBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsDQogICAgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NDQogICAgTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1INCiAgICBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SDQogICAgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4NCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLw0KDQogICAgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikgew0KICAgICAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH0NCiAgICAgICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7DQogICAgICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9DQogICAgICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvclsidGhyb3ciXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9DQogICAgICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA / IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfQ0KICAgICAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpOw0KICAgICAgICB9KTsNCiAgICB9CgogICAgdmFyIGNvbW1vbmpzR2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDoge307CgogICAgdmFyIGx1eG9uID0ge307CgogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGx1eG9uLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7CgogICAgZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsKICAgICAgICBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7CiAgICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOwogICAgICAgIGlmICgidmFsdWUiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOwogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsKICAgICAgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7CiAgICAgIGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsKICAgICAgcmV0dXJuIENvbnN0cnVjdG9yOwogICAgfQoKICAgIGZ1bmN0aW9uIF9leHRlbmRzKCkgewogICAgICBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgewogICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOwoKICAgICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsKICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsKICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgICB9OwoKICAgICAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9CgogICAgZnVuY3Rpb24gX2luaGVyaXRzTG9vc2Uoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsKICAg
/* eslint-enable */
/** Controls and creates Dataview file importers, allowing for asynchronous loading and parsing of files. */
/** Multi-threaded file parser which debounces rapid file requests automatically. */
class FileImporter {
constructor ( numWorkers , vault , metadataCache ) {
this . numWorkers = numWorkers ;
this . vault = vault ;
this . metadataCache = metadataCache ;
this . workers = [ ] ;
this . busy = [ ] ;
this . reloadQueue = [ ] ;
this . reloadSet = new Set ( ) ;
this . callbacks = new Map ( ) ;
for ( let index = 0 ; index < numWorkers ; index ++ ) {
let worker = new WorkerFactory ( { name : "Dataview Indexer " + ( index + 1 ) } ) ;
worker . onmessage = evt => this . finish ( evt . data . path , Transferable . value ( evt . data . result ) , index ) ;
this . workers . push ( worker ) ;
this . busy . push ( false ) ;
}
}
/ * *
* Queue the given file for reloading . Multiple reload requests for the same file in a short time period will be de - bounced
* and all be resolved by a single actual file reload .
* /
reload ( file ) {
let promise = new Promise ( ( resolve , _reject ) => {
var _a ;
if ( this . callbacks . has ( file . path ) )
( _a = this . callbacks . get ( file . path ) ) === null || _a === void 0 ? void 0 : _a . push ( resolve ) ;
else
this . callbacks . set ( file . path , [ resolve ] ) ;
} ) ;
// De-bounce repeated requests for the same file.
if ( this . reloadSet . has ( file . path ) )
return promise ;
this . reloadSet . add ( file . path ) ;
// Immediately run this task if there are available workers; otherwise, add it to the queue.
let workerId = this . nextAvailableWorker ( ) ;
if ( workerId !== undefined ) {
this . send ( file , workerId ) ;
}
else {
this . reloadQueue . push ( file ) ;
}
return promise ;
}
/** Finish the parsing of a file, potentially queueing a new file. */
finish ( path , data , index ) {
var _a ;
// Cache the callbacks before we do book-keeping.
let calls = [ ] . concat ( ( _a = this . callbacks . get ( path ) ) !== null && _a !== void 0 ? _a : [ ] ) ;
// Book-keeping to clear metadata & allow the file to be re-loaded again.
this . reloadSet . delete ( path ) ;
this . callbacks . delete ( path ) ;
// Notify the queue this file is available for new work.
this . busy [ index ] = false ;
// Queue a new job onto this worker.
let job = this . reloadQueue . shift ( ) ;
if ( job !== undefined )
this . send ( job , index ) ;
// Resolve promises to let users know this file has finished.
for ( let callback of calls )
callback ( data ) ;
}
/** Send a new task to the given worker ID. */
send ( file , workerId ) {
this . busy [ workerId ] = true ;
this . vault . read ( file ) . then ( c => this . workers [ workerId ] . postMessage ( {
path : file . path ,
contents : c ,
metadata : this . metadataCache . getFileCache ( file ) ,
} ) ) ;
}
/** Find the next available, non-busy worker; return undefined if all workers are busy. */
nextAvailableWorker ( ) {
let index = this . busy . indexOf ( false ) ;
return index == - 1 ? undefined : index ;
}
}
/** A generic index which indexes variables of the form key -> value[], allowing both forward and reverse lookups. */
class IndexMap {
/** Create a new, empty index map. */
constructor ( ) {
this . map = new Map ( ) ;
this . invMap = new Map ( ) ;
}
/** Returns all values for the given key. */
get ( key ) {
let result = this . map . get ( key ) ;
if ( result ) {
return new Set ( result ) ;
}
else {
return new Set ( ) ;
}
}
/** Returns all keys that reference the given key. */
getInverse ( value ) {
let result = this . invMap . get ( value ) ;
if ( result ) {
return new Set ( result ) ;
}
else {
return new Set ( ) ;
}
}
set ( key , values ) {
var _a ;
if ( this . map . has ( key ) )
this . delete ( key ) ;
this . map . set ( key , values ) ;
for ( let value of values ) {
if ( ! this . invMap . has ( value ) )
this . invMap . set ( value , new Set ( ) ) ;
( _a = this . invMap . get ( value ) ) === null || _a === void 0 ? void 0 : _a . add ( key ) ;
}
return this ;
}
/** Clears all values for the given key so they can be re-added. */
delete ( key ) {
var _a ;
let oldValues = this . map . get ( key ) ;
if ( ! oldValues )
return false ;
this . map . delete ( key ) ;
for ( let value of oldValues ) {
( _a = this . invMap . get ( value ) ) === null || _a === void 0 ? void 0 : _a . delete ( key ) ;
}
return true ;
}
/** Rename all references to the given key to a new value. */
rename ( oldKey , newKey ) {
let oldValues = this . map . get ( oldKey ) ;
if ( ! oldValues )
return false ;
this . delete ( oldKey ) ;
this . set ( newKey , oldValues ) ;
return true ;
}
/** Clear the entire index. */
clear ( ) {
this . map . clear ( ) ;
this . invMap . clear ( ) ;
}
}
/** Aggregate index which has several sub-indices and will initialize all of them. */
class FullIndex {
/** Construct a new index over the given vault and metadata cache. */
constructor ( vault , metadataCache , events ) {
this . vault = vault ;
this . metadataCache = metadataCache ;
this . events = events ;
this . pages = new Map ( ) ;
this . tags = new IndexMap ( ) ;
this . etags = new IndexMap ( ) ;
this . links = new IndexMap ( ) ;
this . folders = new IndexMap ( ) ;
this . revision = 0 ;
// Handles asynchronous reloading of files on web workers.
this . importer = new FileImporter ( 4 , this . vault , this . metadataCache ) ;
// Prefix listens to file creation/deletion/rename, and not modifies, so we let it set up it's own listeners.
this . prefix = PrefixIndex . create ( this . vault , ( ) => ( this . revision += 1 ) ) ;
// The CSV cache also needs to listen to filesystem events for cache invalidation.
this . csv = new CsvCache ( this . vault ) ;
}
/** Generate a full index from the given vault. */
static create ( vault , metadata , events ) {
return new FullIndex ( vault , metadata , events ) ;
}
/** Runs through the whole vault to set up initial file */
initialize ( ) {
// Traverse all markdown files & fill in initial data.
let start = new Date ( ) . getTime ( ) ;
this . vault . getMarkdownFiles ( ) . forEach ( file => this . reload ( file ) ) ;
console . log ( "Dataview: Task & metadata parsing queued in %.3fs." , ( new Date ( ) . getTime ( ) - start ) / 1000.0 ) ;
// The metadata cache is updated on file changes.
this . metadataCache . on ( "changed" , file => this . reload ( file ) ) ;
// Renames do not set off the metadata cache; catch these explicitly.
this . vault . on ( "rename" , ( file , oldPath ) => {
this . folders . delete ( oldPath ) ;
if ( file instanceof obsidian . TFile ) {
this . pages . delete ( oldPath ) ;
this . tags . delete ( oldPath ) ;
this . etags . delete ( oldPath ) ;
this . links . delete ( oldPath ) ;
this . reload ( file ) ;
}
this . revision += 1 ;
this . events . trigger ( "dataview:metadata-change" , "rename" , file , oldPath ) ;
} ) ;
// File creation does cause a metadata change, but deletes do not. Clear the caches for this.
this . vault . on ( "delete" , af => {
if ( ! ( af instanceof obsidian . TFile ) )
return ;
let file = af ;
this . pages . delete ( file . path ) ;
this . tags . delete ( file . path ) ;
this . etags . delete ( file . path ) ;
this . links . delete ( file . path ) ;
this . folders . delete ( file . path ) ;
this . revision += 1 ;
this . events . trigger ( "dataview:metadata-change" , "delete" , file ) ;
} ) ;
// Initialize sub-indices.
this . prefix . initialize ( ) ;
}
/** Queue a file for reloading; this is done asynchronously in the background and may take a few seconds. */
reload ( file ) {
this . importer . reload ( file ) . then ( r => this . reloadInternal ( file , r ) ) ;
}
/** "Touch" the index, incrementing the revision number and causing downstream views to reload. */
touch ( ) {
this . revision += 1 ;
}
reloadInternal ( file , parsed ) {
let meta = parsePage ( file , this . metadataCache , parsed ) ;
this . pages . set ( file . path , meta ) ;
this . tags . set ( file . path , meta . fullTags ( ) ) ;
this . etags . set ( file . path , meta . tags ) ;
this . links . set ( file . path , new Set ( meta . links . map ( l => l . path ) ) ) ;
this . folders . set ( file . path , new Set ( [ getParentFolder ( file . path ) ] ) ) ;
this . revision += 1 ;
this . events . trigger ( "dataview:metadata-change" , "update" , file ) ;
}
}
/** A node in the prefix tree. */
class PrefixIndexNode {
constructor ( element ) {
this . element = element ;
this . files = new Set ( ) ;
this . totalCount = 0 ;
this . children = new Map ( ) ;
}
static add ( root , path ) {
let parts = path . split ( "/" ) ;
let node = root ;
for ( let index = 0 ; index < parts . length - 1 ; index ++ ) {
if ( ! node . children . has ( parts [ index ] ) )
node . children . set ( parts [ index ] , new PrefixIndexNode ( parts [ index ] ) ) ;
node . totalCount += 1 ;
node = node . children . get ( parts [ index ] ) ;
}
node . totalCount += 1 ;
node . files . add ( path ) ;
}
static remove ( root , path ) {
let parts = path . split ( "/" ) ;
let node = root ;
let nodes = [ ] ;
for ( let index = 0 ; index < parts . length - 1 ; index ++ ) {
if ( ! node . children . has ( parts [ index ] ) )
return ;
nodes . push ( node ) ;
node = node . children . get ( parts [ index ] ) ;
}
if ( ! node . files . has ( path ) )
return ;
node . files . delete ( path ) ;
node . totalCount -= 1 ;
for ( let p of nodes )
p . totalCount -= 1 ;
}
static find ( root , prefix ) {
if ( prefix . length == 0 || prefix == "/" )
return root ;
let parts = prefix . split ( "/" ) ;
let node = root ;
for ( let index = 0 ; index < parts . length ; index ++ ) {
if ( ! node . children . has ( parts [ index ] ) )
return null ;
node = node . children . get ( parts [ index ] ) ;
}
return node ;
}
/** Gather all files at and under the given node, optionally filtering the result by the given filter. */
static gather ( root , filter ) {
let result = new Set ( ) ;
PrefixIndexNode . gatherRec ( root , result ) ;
if ( filter ) {
return new Set ( Array . from ( result ) . filter ( filter ) ) ;
}
else {
return result ;
}
}
static gatherRec ( root , output ) {
for ( let file of root . files )
output . add ( file ) ;
for ( let child of root . children . values ( ) )
this . gatherRec ( child , output ) ;
}
}
/** Indexes files by their full prefix - essentially a simple prefix tree. */
class PrefixIndex {
constructor ( vault , updateRevision ) {
this . vault = vault ;
this . updateRevision = updateRevision ;
this . root = new PrefixIndexNode ( "" ) ;
}
static create ( vault , updateRevision ) {
return new PrefixIndex ( vault , updateRevision ) ;
}
/** Run through the whole vault to set up the initial prefix index. */
initialize ( ) {
let timeStart = new Date ( ) . getTime ( ) ;
for ( let file of this . vault . getFiles ( ) )
PrefixIndexNode . add ( this . root , file . path ) ;
console . log ( "Dataview: File prefix tree built in %.3fs." , ( new Date ( ) . getTime ( ) - timeStart ) / 1000.0 ) ;
// TODO: I'm not sure if there is an event for all files in a folder, or just the folder.
// I'm assuming the former naively for now until I inevitably fix it.
this . vault . on ( "delete" , file => {
PrefixIndexNode . remove ( this . root , file . path ) ;
this . updateRevision ( ) ;
} ) ;
this . vault . on ( "create" , file => {
PrefixIndexNode . add ( this . root , file . path ) ;
this . updateRevision ( ) ;
} ) ;
this . vault . on ( "rename" , ( file , old ) => {
PrefixIndexNode . remove ( this . root , old ) ;
PrefixIndexNode . add ( this . root , file . path ) ;
this . updateRevision ( ) ;
} ) ;
}
/** Get the list of all files under the given path. */
get ( prefix , filter ) {
let node = PrefixIndexNode . find ( this . root , prefix ) ;
if ( node == null || node == undefined )
return new Set ( ) ;
return PrefixIndexNode . gather ( node , filter ) ;
}
/** Determines if the given path exists in the prefix index. */
pathExists ( path ) {
let node = PrefixIndexNode . find ( this . root , getParentFolder ( path ) ) ;
return node != null && node . files . has ( path ) ;
}
/** Determines if the given prefix exists in the prefix index. */
nodeExists ( prefix ) {
return PrefixIndexNode . find ( this . root , prefix ) != null ;
}
/ * *
* Use the in - memory prefix index to convert a relative path to an absolute one .
* /
resolveRelative ( path , origin ) {
if ( ! origin )
return path ;
else if ( path . startsWith ( "/" ) )
return path . substring ( 1 ) ;
let relativePath = getParentFolder ( origin ) + "/" + path ;
if ( this . pathExists ( relativePath ) )
return relativePath ;
else
return path ;
}
}
/** Simple path filters which filter file types. */
var PathFilters ;
( function ( PathFilters ) {
function csv ( path ) {
return path . toLowerCase ( ) . endsWith ( ".csv" ) ;
}
PathFilters . csv = csv ;
function markdown ( path ) {
let lcPath = path . toLowerCase ( ) ;
return lcPath . endsWith ( ".md" ) || lcPath . endsWith ( ".markdown" ) ;
}
PathFilters . markdown = markdown ;
} ) ( PathFilters || ( PathFilters = { } ) ) ;
/ * *
* Caches in - use CSVs to make high - frequency reloads ( such as actively looking at a document
* that uses CSV ) fast .
* /
class CsvCache {
constructor ( vault ) {
this . vault = vault ;
this . cache = new Map ( ) ;
}
/** Load a CSV file from the cache, doing a fresh load if it has not been loaded. */
get ( path ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Clear old entries on every fresh load, since the path being loaded may be stale.
this . clearOldEntries ( ) ;
let existing = this . cache . get ( path ) ;
if ( existing )
return Result . success ( existing . data ) ;
else {
let value = yield this . load ( path ) ;
if ( value . successful )
this . cache . set ( path , { data : value . value , loadTime : DateTime _1 . now ( ) } ) ;
return value ;
}
} ) ;
}
/** Do the actual raw loading of a CSV path (which is either local or an HTTP request). */
load ( path ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Allow http://, https://, and file:// prefixes which use AJAX.
if ( path . startsWith ( "http://" ) || path . startsWith ( "https://" ) || path . startsWith ( "file://" ) ) {
try {
let result = yield fetch ( path , {
method : "GET" ,
mode : "no-cors" ,
redirect : "follow" ,
} ) ;
return Result . success ( parseCsv ( yield result . text ( ) ) ) ;
}
catch ( ex ) {
return Result . failure ( "" + ex + "\n\n" + ex . stack ) ;
}
}
// Otherwise, assume it is a fully-qualified file path.
try {
let fileData = yield this . vault . adapter . read ( path ) ;
return Result . success ( parseCsv ( fileData ) ) ;
}
catch ( ex ) {
return Result . failure ( ` Failed to load data from path ' ${ path } '. ` ) ;
}
} ) ;
}
/** Clear old entries in the cache (as measured by insertion time). */
clearOldEntries ( ) {
let currentTime = DateTime _1 . now ( ) ;
let keysToRemove = new Set ( ) ;
for ( let [ key , value ] of this . cache . entries ( ) ) {
let entryAge = Math . abs ( currentTime . diff ( value . loadTime , "seconds" ) . seconds ) ;
if ( entryAge > CsvCache . CACHE _EXPIRY _SECONDS )
keysToRemove . add ( key ) ;
}
keysToRemove . forEach ( key => this . cache . delete ( key ) ) ;
}
}
CsvCache . CACHE _EXPIRY _SECONDS = 5 * 60 ;
/ * *
* Render a task grouping ( indenting nested groupings for clarity ) . This will automatically bind the tasks to be checkable ,
* which requires access to a vault .
* /
function renderTasks ( container , tasks , originFile , component , vault , settings ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
switch ( tasks . type ) {
case "base" :
yield renderTaskList ( container , tasks . value , component , vault , settings ) ;
break ;
case "grouped" :
for ( let { key , value } of tasks . groups ) {
let header = container . createEl ( "h4" ) ;
yield renderValue ( key , header , originFile , component , settings ) ;
let div = container . createDiv ( { cls : [ "dataview" , "result-group" ] } ) ;
yield renderTasks ( div , value , originFile , component , vault , settings ) ;
}
break ;
}
} ) ;
}
/** Render a list of tasks as a single list. */
function renderTaskList ( container , tasks , component , vault , settings ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let ul = container . createEl ( "ul" , { cls : "contains-task-list" } ) ;
for ( let task of tasks ) {
let li = ul . createEl ( "li" ) ;
if ( task . real ) {
li . addClass ( "task-list-item" ) ;
if ( task . completed )
li . addClass ( "is-checked" ) ;
}
// Append the task link if it is present.
let text = task . text ;
switch ( settings . taskLinkLocation ) {
case "start" :
if ( ! settings . taskLinkText )
break ;
text = task . link . withDisplay ( settings . taskLinkText ) . markdown ( ) + " " + text ;
break ;
case "end" :
if ( ! settings . taskLinkText )
break ;
text += " " + task . link . withDisplay ( settings . taskLinkText ) . markdown ( ) ;
break ;
}
// Render the text as markdown so that bolds, links, and other things work properly.
yield obsidian . MarkdownRenderer . renderMarkdown ( text , li , task . path , new obsidian . Component ( ) ) ;
// Unwrap the paragraph element that is created.
let paragraph = li . querySelector ( "p" ) ;
if ( paragraph ) {
li . innerHTML = paragraph . innerHTML ;
paragraph . remove ( ) ;
}
if ( task . real ) {
let checkbox = createCheckbox ( task . path , task . line , task . text , task . completed ) ;
li . prepend ( checkbox ) ;
addCheckHandler ( checkbox , vault , component ) ;
}
if ( task . subtasks . length > 0 ) {
renderTaskList ( li , task . subtasks , component , vault , settings ) ;
}
}
} ) ;
}
function createCheckbox ( file , line , text , checked ) {
let check = document . createElement ( "input" ) ;
check . addClass ( "task-list-item-checkbox" ) ;
check . type = "checkbox" ;
check . dataset [ "file" ] = file ;
check . dataset [ "lineno" ] = "" + line ;
// This field is technically optional, but is provided to double-check
// we are editing the right line!
check . dataset [ "text" ] = text ;
if ( checked ) {
check . setAttribute ( "checked" , "" ) ;
}
return check ;
}
function addCheckHandler ( checkbox , vault , component ) {
component . registerDomEvent ( checkbox , "click" , event => {
var _a , _b , _c , _d ;
let file = checkbox . dataset [ "file" ] ;
let lineno = checkbox . dataset [ "lineno" ] ;
let text = checkbox . dataset [ "text" ] ;
if ( ! file || ! lineno || ! text )
return ;
if ( ! checkbox . hasAttribute ( "checked" ) ) {
let newCheckbox = createCheckbox ( file , parseInt ( lineno ) , text , true ) ;
( _a = checkbox . parentElement ) === null || _a === void 0 ? void 0 : _a . addClass ( "is-checked" ) ;
( _b = checkbox . parentElement ) === null || _b === void 0 ? void 0 : _b . replaceChild ( newCheckbox , checkbox ) ;
setTaskCheckedInFile ( vault , file , parseInt ( lineno ) , text , false , true ) ;
addCheckHandler ( newCheckbox , vault , component ) ;
}
else {
let newCheckbox = createCheckbox ( file , parseInt ( lineno ) , text , false ) ;
( _c = checkbox . parentElement ) === null || _c === void 0 ? void 0 : _c . removeClass ( "is-checked" ) ;
( _d = checkbox . parentElement ) === null || _d === void 0 ? void 0 : _d . replaceChild ( newCheckbox , checkbox ) ;
setTaskCheckedInFile ( vault , file , parseInt ( lineno ) , text , true , false ) ;
addCheckHandler ( newCheckbox , vault , component ) ;
}
} ) ;
}
/** Check a task in a file by rewriting it. */
function setTaskCheckedInFile ( vault , path , taskLine , taskText , wasChecked , check ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( check == wasChecked )
return ;
let text = yield vault . adapter . read ( path ) ;
let splitText = text . replace ( "\r" , "" ) . split ( "\n" ) ;
if ( splitText . length < taskLine )
return ;
let match = TASK _REGEX . exec ( splitText [ taskLine ] ) ;
if ( ! match )
return ;
let foundText = match [ 3 ] ;
let checkMarking = match [ 2 ]
. trim ( )
. substring ( 1 , match [ 2 ] . trim ( ) . length - 1 )
. trim ( ) ;
let foundCompleted = checkMarking == "X" || checkMarking == "x" ;
if ( taskText . trim ( ) != foundText . trim ( ) )
return ;
if ( wasChecked != foundCompleted )
return ;
if ( check ) {
splitText [ taskLine ] = splitText [ taskLine ]
. replace ( "- [ ]" , "- [x]" )
. replace ( "- []" , "- [x]" )
. replace ( "-[]" , "- [x]" )
. replace ( "-[ ]" , "- [x]" ) ;
}
else {
splitText [ taskLine ] = splitText [ taskLine ]
. replace ( "- [X]" , "- [ ]" )
. replace ( "-[X]" , "- [ ]" )
. replace ( "- [x]" , "- [ ]" )
. replace ( "-[x]" , "- [ ]" ) ;
}
let hasRn = text . contains ( "\r" ) ;
if ( hasRn ) {
let final = splitText . join ( "\r\n" ) ;
yield vault . adapter . write ( path , final ) ;
}
else {
let final = splitText . join ( "\n" ) ;
yield vault . adapter . write ( path , final ) ;
}
} ) ;
}
/** Utility functions for quickly creating fields. */
var QueryFields ;
( function ( QueryFields ) {
function named ( name , field ) {
return { name , field } ;
}
QueryFields . named = named ;
function sortBy ( field , dir ) {
return { field , direction : dir } ;
}
QueryFields . sortBy = sortBy ;
} ) ( QueryFields || ( QueryFields = { } ) ) ;
/** A parsimmon-powered parser-combinator implementation of the query language. */
const QUERY _LANGUAGE = parsimmon _umd _min . exports . createLanguage ( {
// Simple atom parsing, like words, identifiers, numbers.
queryType : q => parsimmon _umd _min . exports . alt ( parsimmon _umd _min . exports . regexp ( /TABLE|LIST|TASK/i ) )
. map ( str => str . toLowerCase ( ) )
. desc ( "query type ('TABLE', 'LIST', or 'TASK')" ) ,
explicitNamedField : q => parsimmon _umd _min . exports . seqMap ( EXPRESSION . field . skip ( parsimmon _umd _min . exports . whitespace ) , parsimmon _umd _min . exports . regexp ( /AS/i ) . skip ( parsimmon _umd _min . exports . whitespace ) , EXPRESSION . identifier . or ( EXPRESSION . string ) , ( field , _as , ident ) => QueryFields . named ( ident , field ) ) ,
namedField : q => parsimmon _umd _min . exports . alt ( q . explicitNamedField , EXPRESSION . identifierDot . map ( ident => QueryFields . named ( ident , Fields . indexVariable ( ident ) ) ) ) ,
sortField : q => parsimmon _umd _min . exports . seqMap ( EXPRESSION . field . skip ( parsimmon _umd _min . exports . optWhitespace ) , parsimmon _umd _min . exports . regexp ( /ASCENDING|DESCENDING|ASC|DESC/i ) . atMost ( 1 ) , ( field , dir ) => {
let direction = dir . length == 0 ? "ascending" : dir [ 0 ] . toLowerCase ( ) ;
if ( direction == "desc" )
direction = "descending" ;
if ( direction == "asc" )
direction = "ascending" ;
return {
field : field ,
direction : direction ,
} ;
} ) ,
headerClause : q => q . queryType . skip ( parsimmon _umd _min . exports . whitespace ) . chain ( qtype => {
switch ( qtype ) {
case "table" :
return parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /WITHOUT\s+ID/i )
. skip ( parsimmon _umd _min . exports . optWhitespace )
. atMost ( 1 ) , parsimmon _umd _min . exports . sepBy ( q . namedField , parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) ) , ( withoutId , fields ) => {
return { type : "table" , fields , showId : withoutId . length == 0 } ;
} ) ;
case "list" :
return parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /WITHOUT\s+ID/i )
. skip ( parsimmon _umd _min . exports . optWhitespace )
. atMost ( 1 ) , EXPRESSION . field . atMost ( 1 ) , ( withoutId , format ) => {
return {
type : "list" ,
format : format . length == 1 ? format [ 0 ] : undefined ,
showId : withoutId . length == 0 ,
} ;
} ) ;
case "task" :
return parsimmon _umd _min . exports . succeed ( { type : "task" } ) ;
default :
return parsimmon _umd _min . exports . fail ( ` Unrecognized query type ' ${ qtype } ' ` ) ;
}
} ) ,
fromClause : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /FROM/i ) , parsimmon _umd _min . exports . whitespace , EXPRESSION . source , ( _1 , _2 , source ) => source ) ,
whereClause : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /WHERE/i ) , parsimmon _umd _min . exports . whitespace , EXPRESSION . field , ( where , _ , field ) => {
return { type : "where" , clause : field } ;
} ) ,
sortByClause : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /SORT/i ) , parsimmon _umd _min . exports . whitespace , q . sortField . sepBy1 ( parsimmon _umd _min . exports . string ( "," ) . trim ( parsimmon _umd _min . exports . optWhitespace ) ) , ( sort , _1 , fields ) => {
return { type : "sort" , fields } ;
} ) ,
limitClause : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /LIMIT/i ) , parsimmon _umd _min . exports . whitespace , EXPRESSION . field , ( limit , _1 , field ) => {
return { type : "limit" , amount : field } ;
} ) ,
flattenClause : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /FLATTEN/i ) . skip ( parsimmon _umd _min . exports . whitespace ) , q . namedField , ( _ , field ) => {
return { type : "flatten" , field } ;
} ) ,
groupByClause : q => parsimmon _umd _min . exports . seqMap ( parsimmon _umd _min . exports . regexp ( /GROUP BY/i ) . skip ( parsimmon _umd _min . exports . whitespace ) , q . namedField , ( _ , field ) => {
return { type : "group" , field } ;
} ) ,
// Full query parsing.
clause : q => parsimmon _umd _min . exports . alt ( q . fromClause , q . whereClause , q . sortByClause , q . limitClause , q . groupByClause , q . flattenClause ) ,
query : q => parsimmon _umd _min . exports . seqMap ( q . headerClause . trim ( parsimmon _umd _min . exports . optWhitespace ) , q . fromClause . trim ( parsimmon _umd _min . exports . optWhitespace ) . atMost ( 1 ) , q . clause . trim ( parsimmon _umd _min . exports . optWhitespace ) . many ( ) , ( header , from , clauses ) => {
return {
header ,
source : from . length == 0 ? Sources . folder ( "" ) : from [ 0 ] ,
operations : clauses ,
settings : DEFAULT _QUERY _SETTINGS ,
} ;
} ) ,
} ) ;
/ * *
* Attempt to parse a query from the given query text , returning a string error
* if the parse failed .
* /
function parseQuery ( text ) {
try {
let query = QUERY _LANGUAGE . query . tryParse ( text ) ;
return Result . success ( query ) ;
}
catch ( error ) {
return Result . failure ( "" + error ) ;
}
}
/** Provides a global dispatch table for evaluating binary operators, including comparison. */
/** Provides implementations for binary operators on two types using a registry. */
class BinaryOpHandler {
constructor ( ) {
this . map = new Map ( ) ;
}
static create ( ) {
return new BinaryOpHandler ( ) ;
}
register ( left , op , right , func ) {
this . map . set ( BinaryOpHandler . repr ( op , left , right ) , func ) ;
return this ;
}
registerComm ( left , op , right , func ) {
return this . register ( left , op , right , func ) . register ( right , op , left , ( a , b , ctx ) => func ( b , a , ctx ) ) ;
}
/** Implement a comparison function. */
compare ( type , compare ) {
return this . register ( type , "<" , type , ( a , b , ctx ) => compare ( a , b , ctx ) < 0 )
. register ( type , "<=" , type , ( a , b , ctx ) => compare ( a , b , ctx ) <= 0 )
. register ( type , ">" , type , ( a , b , ctx ) => compare ( a , b , ctx ) > 0 )
. register ( type , ">=" , type , ( a , b , ctx ) => compare ( a , b , ctx ) >= 0 )
. register ( type , "=" , type , ( a , b , ctx ) => compare ( a , b , ctx ) == 0 )
. register ( type , "!=" , type , ( a , b , ctx ) => compare ( a , b , ctx ) != 0 ) ;
}
/** Attempt to evaluate the given binary operator on the two literal fields. */
evaluate ( op , left , right , ctx ) {
let leftType = Values . typeOf ( left ) ;
let rightType = Values . typeOf ( right ) ;
if ( ! leftType )
return Result . failure ( ` Unrecognized value ' ${ left } ' ` ) ;
else if ( ! rightType )
return Result . failure ( ` Unrecognized value ' ${ right } ' ` ) ;
let handler = this . map . get ( BinaryOpHandler . repr ( op , leftType , rightType ) ) ;
if ( handler )
return Result . success ( handler ( left , right , ctx ) ) ;
// Right-'*' fallback:
let handler2 = this . map . get ( BinaryOpHandler . repr ( op , leftType , "*" ) ) ;
if ( handler2 )
return Result . success ( handler2 ( left , right , ctx ) ) ;
// Left-'*' fallback:
let handler3 = this . map . get ( BinaryOpHandler . repr ( op , "*" , rightType ) ) ;
if ( handler3 )
return Result . success ( handler3 ( left , right , ctx ) ) ;
// Double '*' fallback.
let handler4 = this . map . get ( BinaryOpHandler . repr ( op , "*" , "*" ) ) ;
if ( handler4 )
return Result . success ( handler4 ( left , right , ctx ) ) ;
return Result . failure ( ` Operator ' ${ op } ' is not supported for ' ${ leftType } ' and ' ${ rightType } ` ) ;
}
/** Create a string representation of the given triplet for unique lookup in the map. */
static repr ( op , left , right ) {
return ` ${ left } , ${ op } , ${ right } ` ;
}
}
/** Configure and create a binary OP handler with the given parameters. */
function createBinaryOps ( linkNormalizer ) {
return ( BinaryOpHandler . create ( )
// TODO: Consider not using a universal comparison function.
. compare ( "*" , ( a , b ) => Values . compareValue ( a , b , linkNormalizer ) )
// Global boolean operations.
. register ( "*" , "&" , "*" , ( a , b ) => Values . isTruthy ( a ) && Values . isTruthy ( b ) )
. register ( "*" , "|" , "*" , ( a , b ) => Values . isTruthy ( a ) || Values . isTruthy ( b ) )
// Number implementations.
. register ( "number" , "+" , "number" , ( a , b ) => a + b )
. register ( "number" , "-" , "number" , ( a , b ) => a - b )
. register ( "number" , "*" , "number" , ( a , b ) => a * b )
. register ( "number" , "/" , "number" , ( a , b ) => a / b )
// String implementations.
. register ( "string" , "+" , "*" , ( a , b , ctx ) => a + Values . toString ( b , ctx . settings ) )
. register ( "*" , "+" , "string" , ( a , b , ctx ) => Values . toString ( a , ctx . settings ) + b )
. registerComm ( "string" , "*" , "number" , ( a , b ) => ( b < 0 ? "" : a . repeat ( b ) ) )
// Date Operations.
. register ( "date" , "-" , "date" , ( a , b ) => {
return normalizeDuration ( a . diff ( b , [ "years" , "months" , "days" , "hours" , "minutes" , "seconds" , "milliseconds" ] ) ) ;
} )
. register ( "date" , "-" , "duration" , ( a , b ) => a . minus ( b ) )
. registerComm ( "date" , "+" , "duration" , ( a , b ) => a . plus ( b ) )
// Duration Operations.
. register ( "duration" , "+" , "duration" , ( a , b ) => normalizeDuration ( a . plus ( b ) ) )
. register ( "duration" , "-" , "duration" , ( a , b ) => normalizeDuration ( a . minus ( b ) ) )
// Array operations.
. register ( "array" , "+" , "array" , ( a , b ) => [ ] . concat ( a ) . concat ( b ) )
// Object operations.
. register ( "object" , "+" , "object" , ( a , b ) => Object . assign ( { } , a , b ) ) ) ;
}
/** Default function implementations for the expression evaluator. */
/ * *
* Allows for the creation of functions that check the number and type of their arguments , and dispatch
* to different implemenations based on the types of the inputs .
* /
class FunctionBuilder {
constructor ( name ) {
this . name = name ;
this . variants = [ ] ;
this . vectorized = { } ;
}
/** Add a general function variant which accepts any number of arguments of any type. */
vararg ( impl ) {
this . variants . push ( { args : [ ] , varargs : true , impl } ) ;
return this ;
}
/** Add a function variant which takes in a single argument. */
add1 ( argType , impl ) {
this . variants . push ( {
args : [ argType ] ,
varargs : false ,
impl : ( c , ... rest ) => impl ( rest [ 0 ] , c ) ,
} ) ;
return this ;
}
/** Add a function variant which takes in two typed arguments. */
add2 ( arg1 , arg2 , impl ) {
this . variants . push ( {
args : [ arg1 , arg2 ] ,
varargs : false ,
impl : ( c , ... rest ) => impl ( rest [ 0 ] , rest [ 1 ] , c ) ,
} ) ;
return this ;
}
/** Add a function variant which takes in three typed arguments. */
add3 ( arg1 , arg2 , arg3 , impl ) {
this . variants . push ( {
args : [ arg1 , arg2 , arg3 ] ,
varargs : false ,
impl : ( c , ... rest ) => impl ( rest [ 0 ] , rest [ 1 ] , rest [ 2 ] , c ) ,
} ) ;
return this ;
}
/** Add vectorized variants which accept the given number of arguments and delegate. */
vectorize ( numArgs , positions ) {
this . vectorized [ numArgs ] = positions ;
return this ;
}
/** Return a function which checks the number and type of arguments, passing them on to the first matching variant. */
build ( ) {
let self = ( context , ... args ) => {
let types = [ ] ;
for ( let arg of args ) {
let argType = Values . typeOf ( arg ) ;
if ( ! argType )
throw Error ( ` Unrecognized argument type for argument ' ${ arg } ' ` ) ;
types . push ( argType ) ;
}
// Handle vectorization, possibly in multiple fields.
if ( this . vectorized [ types . length ] ) {
let vectorizedPositions = this . vectorized [ types . length ] . filter ( k => types [ k ] == "array" ) ;
if ( vectorizedPositions . length > 0 ) {
let minLength = vectorizedPositions
. map ( p => args [ p ] . length )
. reduce ( ( p , c ) => Math . min ( p , c ) ) ;
// Call the subfunction for each element in the longest array.
// If you call a vectorized function with different-length arrays,
// the output is limited by the length of the shortest array.
let result = [ ] ;
for ( let vpos = 0 ; vpos < minLength ; vpos ++ ) {
let subargs = [ ] ;
for ( let index = 0 ; index < args . length ; index ++ ) {
if ( vectorizedPositions . includes ( index ) ) {
let arr = args [ index ] ;
subargs . push ( arr [ vpos ] ) ;
}
else {
subargs . push ( args [ index ] ) ;
}
}
result . push ( self ( context , ... subargs ) ) ;
}
return result ;
}
}
outer : for ( let variant of this . variants ) {
if ( variant . varargs )
return variant . impl ( context , ... args ) ;
if ( variant . args . length != types . length )
continue ;
for ( let index = 0 ; index < variant . args . length ; index ++ ) {
if ( variant . args [ index ] != "*" && variant . args [ index ] != types [ index ] )
continue outer ;
}
return variant . impl ( context , ... args ) ;
}
throw Error ( ` No implementation of ' ${ this . name } ' found for arguments: ${ types . join ( ", " ) } ` ) ;
} ;
return self ;
}
}
/** Utilities for managing function implementations. */
var Functions ;
( function ( Functions ) {
/** Bind a context to a function implementation, yielding a function which does not need the context argument. */
function bind ( func , context ) {
return ( ... args ) => func ( context , ... args ) ;
}
Functions . bind = bind ;
/** Bind a context to all functions in the given map, yielding a new map of bound functions. */
function bindAll ( funcs , context ) {
let result = { } ;
for ( let [ key , func ] of Object . entries ( funcs ) ) {
result [ key ] = Functions . bind ( func , context ) ;
}
return result ;
}
Functions . bindAll = bindAll ;
} ) ( Functions || ( Functions = { } ) ) ;
/ * *
* Collection of all defined functions ; defined here so that they can be called from within dataview ,
* and test code .
* /
var DefaultFunctions ;
( function ( DefaultFunctions ) {
/** Compute the length of a data type. */
DefaultFunctions . length = new FunctionBuilder ( "length" )
. add1 ( "array" , a => a . length )
. add1 ( "object" , a => Object . keys ( a ) . length )
. add1 ( "string" , a => a . length )
. add1 ( "null" , _a => 0 )
. build ( ) ;
/** List constructor function. */
DefaultFunctions . list = ( _context , ... args ) => args ;
/** Object constructor function. */
DefaultFunctions . object = ( _context , ... args ) => {
if ( args . length % 2 != 0 )
throw Error ( "object() requires an even number of arguments" ) ;
let result = { } ;
for ( let index = 0 ; index < args . length ; index += 2 ) {
let key = args [ index ] ;
if ( ! Values . isString ( key ) )
throw Error ( "keys should be of type string for object(key1, value1, ...)" ) ;
result [ key ] = args [ index + 1 ] ;
}
return result ;
} ;
/** Internal link constructor function. */
DefaultFunctions . link = new FunctionBuilder ( "link" )
. add1 ( "string" , ( a , c ) => Link . file ( c . linkHandler . normalize ( a ) , false ) )
. add1 ( "link" , a => a )
. add1 ( "null" , _a => null )
. vectorize ( 1 , [ 0 ] )
. add2 ( "string" , "string" , ( t , d , c ) => Link . file ( c . linkHandler . normalize ( t ) , false , d ) )
. add2 ( "link" , "string" , ( t , d ) => t . withDisplay ( d ) )
. add2 ( "null" , "*" , ( ) => null )
. add2 ( "*" , "null" , ( t , _n , c ) => DefaultFunctions . link ( c , t ) )
. vectorize ( 2 , [ 0 , 1 ] )
. build ( ) ;
/** External link constructor function. */
DefaultFunctions . elink = new FunctionBuilder ( "elink" )
. add2 ( "string" , "string" , ( a , d ) => {
let elem = document . createElement ( "a" ) ;
elem . textContent = d ;
elem . rel = "noopener" ;
elem . target = "_blank" ;
elem . classList . add ( "external-link" ) ;
elem . href = a ;
return elem ;
} )
. add2 ( "string" , "null" , ( s , _n , c ) => DefaultFunctions . elink ( c , s , s ) )
. add2 ( "null" , "*" , ( ) => null )
. vectorize ( 2 , [ 0 ] )
. add1 ( "string" , ( a , c ) => DefaultFunctions . elink ( c , a , a ) )
. add1 ( "null" , ( ) => null )
. vectorize ( 1 , [ 0 ] )
. build ( ) ;
/** Date constructor function. */
DefaultFunctions . date = new FunctionBuilder ( "date" )
. add1 ( "string" , str => {
let parsedDate = EXPRESSION . date . parse ( str ) ;
if ( parsedDate . status )
return parsedDate . value ;
else
return null ;
} )
. add1 ( "date" , d => d )
. add1 ( "link" , ( link , c ) => {
var _c , _d , _e , _f ;
// Try to parse from the display...
if ( link . display ) {
let parsedDate = EXPRESSION . date . parse ( link . display ) ;
if ( parsedDate . status )
return parsedDate . value ;
}
// Then try to parse from the path...
let parsedDate = EXPRESSION . date . parse ( link . path ) ;
if ( parsedDate . status )
return parsedDate . value ;
// Then pull it from the file.
let resolved = c . linkHandler . resolve ( link . path ) ;
if ( resolved && ( ( _d = ( _c = resolved ) === null || _c === void 0 ? void 0 : _c . file ) === null || _d === void 0 ? void 0 : _d . day ) ) {
return ( _f = ( _e = resolved ) === null || _e === void 0 ? void 0 : _e . file ) === null || _f === void 0 ? void 0 : _f . day ;
}
return null ;
} )
. add1 ( "null" , ( ) => null )
. vectorize ( 1 , [ 0 ] )
. build ( ) ;
/** Format a date using a luxon/moment-style date format. */
DefaultFunctions . dateformat = new FunctionBuilder ( "dateformat" )
. add2 ( "date" , "string" , ( date , format ) => date . toFormat ( format , { locale : currentLocale ( ) } ) )
. vectorize ( 2 , [ 0 ] )
. build ( ) ;
const NUMBER _REGEX = /-?[0-9]+(\.[0-9]+)?/ ;
/** Number constructor function. */
DefaultFunctions . number = new FunctionBuilder ( "number" )
. add1 ( "number" , a => a )
. add1 ( "string" , str => {
let match = NUMBER _REGEX . exec ( str ) ;
if ( match )
return Number . parseFloat ( match [ 0 ] ) ;
else
return null ;
} )
. add1 ( "null" , ( ) => null )
. vectorize ( 1 , [ 0 ] )
. build ( ) ;
/ * *
* Convert any value to a reasonable internal string representation . Most useful for dates , strings , numbers , and
* so on .
* /
DefaultFunctions . string = new FunctionBuilder ( "string" ) . add1 ( "*" , ( a , ctx ) => Values . toString ( a , ctx . settings ) ) . build ( ) ;
DefaultFunctions . round = new FunctionBuilder ( "round" )
. add1 ( "number" , n => Math . round ( n ) )
. add1 ( "null" , ( ) => null )
. vectorize ( 1 , [ 0 ] )
. add2 ( "number" , "number" , ( n , p ) => {
if ( p <= 0 )
return Math . round ( n ) ;
return parseFloat ( n . toFixed ( p ) ) ;
} )
. add2 ( "number" , "null" , n => Math . round ( n ) )
. add2 ( "null" , "*" , ( ) => null )
. vectorize ( 2 , [ 0 ] )
. build ( ) ;
DefaultFunctions . min = new FunctionBuilder ( "min" )
. add2 ( "*" , "null" , ( a , _n ) => a )
. add2 ( "null" , "*" , ( _n , a ) => a )
. add2 ( "*" , "*" , ( a , b , ctx ) => ( Values . compareValue ( a , b , ctx . linkHandler . normalize ) <= 0 ? a : b ) )
. add1 ( "array" , ( a , ctx ) => DefaultFunctions . min ( ctx , ... a ) )
. vararg ( ( ctx , ... args ) => ( args . length == 0 ? null : args . reduce ( ( p , c ) => DefaultFunctions . min ( ctx , p , c ) ) ) )
. build ( ) ;
DefaultFunctions . max = new FunctionBuilder ( "max" )
. add2 ( "*" , "null" , ( a , _n ) => a )
. add2 ( "null" , "*" , ( _n , a ) => a )
. add2 ( "*" , "*" , ( a , b , ctx ) => ( Values . compareValue ( a , b , ctx . linkHandler . normalize ) > 0 ? a : b ) )
. add1 ( "array" , ( a , ctx ) => DefaultFunctions . max ( ctx , ... a ) )
. vararg ( ( ctx , ... args ) => ( args . length == 0 ? null : args . reduce ( ( p , c ) => DefaultFunctions . max ( ctx , p , c ) ) ) )
. build ( ) ;
DefaultFunctions . minby = new FunctionBuilder ( "minby" )
. add2 ( "array" , "function" , ( arr , func , ctx ) => {
if ( arr . length == 0 )
return null ;
let values = arr . map ( v => {
return { value : v , mapped : func ( ctx , v ) } ;
} ) ;
let filtered = values . filter ( v => ! Values . isNull ( v . mapped ) ) ;
if ( filtered . length == 0 )
return arr [ 0 ] ;
return filtered . reduce ( ( p , c ) => {
if ( Values . compareValue ( p . mapped , c . mapped , ctx . linkHandler . normalize ) <= 0 )
return p ;
else
return c ;
} ) . value ;
} )
. build ( ) ;
DefaultFunctions . maxby = new FunctionBuilder ( "maxby" )
. add2 ( "array" , "function" , ( arr , func , ctx ) => {
if ( arr . length == 0 )
return null ;
let values = arr . map ( v => {
return { value : v , mapped : func ( ctx , v ) } ;
} ) ;
let filtered = values . filter ( v => ! Values . isNull ( v . mapped ) ) ;
if ( filtered . length == 0 )
return arr [ 0 ] ;
return filtered . reduce ( ( p , c ) => {
if ( Values . compareValue ( p . mapped , c . mapped , ctx . linkHandler . normalize ) > 0 )
return p ;
else
return c ;
} ) . value ;
} )
. build ( ) ;
DefaultFunctions . striptime = new FunctionBuilder ( "striptime" )
. add1 ( "date" , d => DateTime _1 . fromObject ( { year : d . year , month : d . month , day : d . day } ) )
. add1 ( "null" , _n => null )
. vectorize ( 1 , [ 0 ] )
. build ( ) ;
// Default contains, which looks through data structures recursively.
DefaultFunctions . contains = new FunctionBuilder ( "contains" )
. add2 ( "array" , "*" , ( l , elem , context ) => l . some ( e => DefaultFunctions . contains ( context , e , elem ) ) )
. add2 ( "string" , "string" , ( haystack , needle ) => haystack . includes ( needle ) )
. add2 ( "object" , "string" , ( obj , key ) => key in obj )
. add2 ( "*" , "*" , ( elem1 , elem2 , context ) => context . evaluate ( Fields . binaryOp ( Fields . literal ( elem1 ) , "=" , Fields . literal ( elem2 ) ) ) . orElseThrow ( ) )
. vectorize ( 2 , [ 1 ] )
. build ( ) ;
// Case insensitive version of contains.
DefaultFunctions . icontains = new FunctionBuilder ( "icontains" )
. add2 ( "array" , "*" , ( l , elem , context ) => l . some ( e => DefaultFunctions . icontains ( context , e , elem ) ) )
. add2 ( "string" , "string" , ( haystack , needle ) => haystack . toLocaleLowerCase ( ) . includes ( needle . toLocaleLowerCase ( ) ) )
. add2 ( "object" , "string" , ( obj , key ) => key in obj )
. add2 ( "*" , "*" , ( elem1 , elem2 , context ) => context . evaluate ( Fields . binaryOp ( Fields . literal ( elem1 ) , "=" , Fields . literal ( elem2 ) ) ) . orElseThrow ( ) )
. vectorize ( 2 , [ 1 ] )
. build ( ) ;
// "exact" contains, does not look recursively.
DefaultFunctions . econtains = new FunctionBuilder ( "econtains" )
. add2 ( "array" , "*" , ( l , elem , context ) => l . some ( e => context . evaluate ( Fields . binaryOp ( Fields . literal ( elem ) , "=" , Fields . literal ( e ) ) ) . orElseThrow ( ) ) )
. add2 ( "string" , "string" , ( haystack , needle ) => haystack . includes ( needle ) )
. add2 ( "object" , "string" , ( obj , key ) => key in obj )
. add2 ( "*" , "*" , ( elem1 , elem2 , context ) => context . evaluate ( Fields . binaryOp ( Fields . literal ( elem1 ) , "=" , Fields . literal ( elem2 ) ) ) . orElseThrow ( ) )
. vectorize ( 2 , [ 1 ] )
. build ( ) ;
// Case insensitive contains which looks for exact word matches (i.e., boundry-to-boundry match).
DefaultFunctions . containsword = new FunctionBuilder ( "containsword" )
. add2 ( "string" , "string" , ( hay , needle ) => ! ! hay . match ( new RegExp ( ".*\\b" + escapeRegex ( needle ) + "\\b.*" , "i" ) ) )
. add2 ( "null" , "*" , ( _a , _b ) => null )
. add2 ( "*" , "null" , ( _a , _b ) => null )
. vectorize ( 2 , [ 0 , 1 ] )
. build ( ) ;
/** Extract 0 or more keys from a given object via indexing. */
DefaultFunctions . extract = ( context , ... args ) => {
if ( args . length == 0 )
return "extract(object, key1, ...) requires at least 1 argument" ;
// Manually handle vectorization in the first argument.
let object = args [ 0 ] ;
if ( Values . isArray ( object ) )
return object . map ( v => DefaultFunctions . extract ( context , v , ... args . slice ( 1 ) ) ) ;
let result = { } ;
for ( let index = 1 ; index < args . length ; index ++ ) {
let key = args [ index ] ;
if ( ! Values . isString ( key ) )
throw Error ( "extract(object, key1, ...) must be called with string keys" ) ;
result [ key ] = context . evaluate ( Fields . index ( Fields . literal ( object ) , Fields . literal ( key ) ) ) . orElseThrow ( ) ;
}
return result ;
} ;
// Reverse aan array or string.
DefaultFunctions . reverse = new FunctionBuilder ( "reverse" )
. add1 ( "array" , l => {
let result = [ ] ;
for ( let index = l . length - 1 ; index >= 0 ; index -- )
result . push ( l [ index ] ) ;
return result ;
} )
. add1 ( "string" , l => {
let result = "" ;
for ( let c = 0 ; c < l . length ; c ++ )
result += l [ l . length - c - 1 ] ;
return result ;
} )
. add1 ( "*" , e => e )
. build ( ) ;
// Sort an array; if given two arguments, sorts by the key returned.
DefaultFunctions . sort = new FunctionBuilder ( "sort" )
. add1 ( "array" , ( list , context ) => DefaultFunctions . sort ( context , list , ( _ctx , a ) => a ) )
. add2 ( "array" , "function" , ( list , key , context ) => {
let result = [ ] . concat ( list ) ;
result . sort ( ( a , b ) => {
let akey = key ( context , a ) ;
let bkey = key ( context , b ) ;
let le = context
. evaluate ( Fields . binaryOp ( Fields . literal ( akey ) , "<" , Fields . literal ( bkey ) ) )
. orElseThrow ( ) ;
if ( Values . isTruthy ( le ) )
return - 1 ;
let eq = context
. evaluate ( Fields . binaryOp ( Fields . literal ( akey ) , "=" , Fields . literal ( bkey ) ) )
. orElseThrow ( ) ;
if ( Values . isTruthy ( eq ) )
return 0 ;
return 1 ;
} ) ;
return result ;
} )
. add1 ( "*" , e => e )
. build ( ) ;
DefaultFunctions . regexmatch = new FunctionBuilder ( "regexmatch" )
. add2 ( "string" , "string" , ( pattern , field ) => {
if ( ! pattern . startsWith ( "^" ) && ! pattern . endsWith ( "$" ) )
pattern = "^" + pattern + "$" ;
return ! ! field . match ( pattern ) ;
} )
. add2 ( "null" , "*" , ( _n , _a ) => false )
. add2 ( "*" , "null" , ( _a , _n ) => false )
. vectorize ( 2 , [ 0 , 1 ] )
. build ( ) ;
DefaultFunctions . regexreplace = new FunctionBuilder ( "regexreplace" )
. add3 ( "string" , "string" , "string" , ( field , pat , rep ) => {
try {
let reg = new RegExp ( pat , "g" ) ;
return field . replace ( reg , rep ) ;
}
catch ( ex ) {
throw Error ( ` Invalid regexp ' ${ pat } ' in regexreplace ` ) ;
}
} )
. add3 ( "null" , "*" , "*" , ( ) => null )
. add3 ( "*" , "null" , "*" , ( ) => null )
. add3 ( "*" , "*" , "null" , ( ) => null )
. vectorize ( 3 , [ 0 , 1 , 2 ] )
. build ( ) ;
DefaultFunctions . lower = new FunctionBuilder ( "lower" )
. add1 ( "string" , s => s . toLocaleLowerCase ( ) )
. add1 ( "null" , ( ) => null )
. vectorize ( 1 , [ 0 ] )
. build ( ) ;
DefaultFunctions . upper = new FunctionBuilder ( "upper" )
. add1 ( "string" , s => s . toLocaleUpperCase ( ) )
. add1 ( "null" , ( ) => null )
. vectorize ( 1 , [ 0 ] )
. build ( ) ;
DefaultFunctions . replace = new FunctionBuilder ( "replace" )
. add3 ( "string" , "string" , "string" , ( str , pat , repr ) => str . split ( pat ) . join ( repr ) )
. add3 ( "null" , "*" , "*" , ( ) => null )
. add3 ( "*" , "null" , "*" , ( ) => null )
. add3 ( "*" , "*" , "null" , ( ) => null )
. vectorize ( 3 , [ 0 , 1 , 2 ] )
. build ( ) ;
// Ensure undefined matches turn into empty strings for split/2 and split/3.
const splitImpl = ( str , delim , limit ) => str . split ( new RegExp ( delim ) , limit ) . map ( str => str || "" ) ;
/** Split a string on a given string. */
DefaultFunctions . split = new FunctionBuilder ( "split" )
. add2 ( "string" , "string" , ( string , splitter ) => splitImpl ( string , splitter ) )
. add3 ( "string" , "string" , "number" , ( string , splitter , limit ) => splitImpl ( string , splitter , limit ) )
. build ( ) ;
DefaultFunctions . startswith = new FunctionBuilder ( "startswith" )
. add2 ( "string" , "string" , ( str , starting ) => str . startsWith ( starting ) )
. vectorize ( 2 , [ 0 , 1 ] )
. build ( ) ;
DefaultFunctions . endswith = new FunctionBuilder ( "endswith" )
. add2 ( "string" , "string" , ( str , ending ) => str . endsWith ( ending ) )
. vectorize ( 2 , [ 0 , 1 ] )
. build ( ) ;
DefaultFunctions . padleft = new FunctionBuilder ( "padleft" )
. add2 ( "string" , "number" , ( str , len ) => str . padStart ( len , " " ) )
. add3 ( "string" , "number" , "string" , ( str , len , padding ) => str . padStart ( len , padding ) )
. vectorize ( 2 , [ 0 , 1 ] )
. vectorize ( 3 , [ 0 , 1 , 2 ] )
. build ( ) ;
DefaultFunctions . padright = new FunctionBuilder ( "padright" )
. add2 ( "string" , "number" , ( str , len ) => str . padEnd ( len , " " ) )
. add3 ( "string" , "number" , "string" , ( str , len , padding ) => str . padEnd ( len , padding ) )
. vectorize ( 2 , [ 0 , 1 ] )
. vectorize ( 3 , [ 0 , 1 , 2 ] )
. build ( ) ;
DefaultFunctions . fdefault = new FunctionBuilder ( "default" )
. add2 ( "*" , "*" , ( v , bk ) => ( Values . isNull ( v ) ? bk : v ) )
. vectorize ( 2 , [ 0 , 1 ] )
. build ( ) ;
DefaultFunctions . ldefault = new FunctionBuilder ( "ldefault" )
. add2 ( "*" , "*" , ( v , bk ) => ( Values . isNull ( v ) ? bk : v ) )
. build ( ) ;
DefaultFunctions . choice = new FunctionBuilder ( "choice" )
. add3 ( "*" , "*" , "*" , ( b , left , right ) => ( Values . isTruthy ( b ) ? left : right ) )
. vectorize ( 3 , [ 0 ] )
. build ( ) ;
DefaultFunctions . reduce = new FunctionBuilder ( "reduce" )
. add2 ( "array" , "string" , ( lis , op , context ) => {
if ( lis . length == 0 )
return null ;
if ( op != "+" && op != "-" && op != "*" && op != "/" && op != "&" && op != "|" )
throw Error ( "reduce(array, op) supports '+', '-', '/', '*', '&', and '|'" ) ;
let value = lis [ 0 ] ;
for ( let index = 1 ; index < lis . length ; index ++ ) {
value = context
. evaluate ( Fields . binaryOp ( Fields . literal ( value ) , op , Fields . literal ( lis [ index ] ) ) )
. orElseThrow ( ) ;
}
return value ;
} )
. add2 ( "array" , "function" , ( lis , op , context ) => {
if ( lis . length == 0 )
return null ;
let value = lis [ 0 ] ;
for ( let index = 1 ; index < lis . length ; index ++ ) {
// Skip null values to reduce the pain of summing over fields that may or may not exist.
if ( Values . isNull ( lis [ index ] ) )
continue ;
value = op ( context , value , lis [ index ] ) ;
}
return value ;
} )
. add2 ( "null" , "*" , ( ) => null )
. add2 ( "*" , "null" , ( ) => null )
. vectorize ( 2 , [ 1 ] )
. build ( ) ;
DefaultFunctions . sum = new FunctionBuilder ( "sum" )
. add1 ( "array" , ( arr , c ) => DefaultFunctions . reduce ( c , arr , "+" ) )
. add1 ( "*" , e => e )
. build ( ) ;
DefaultFunctions . product = new FunctionBuilder ( "product" )
. add1 ( "array" , ( arr , c ) => DefaultFunctions . reduce ( c , arr , "*" ) )
. add1 ( "*" , e => e )
. build ( ) ;
DefaultFunctions . join = new FunctionBuilder ( "join" )
. add2 ( "array" , "string" , ( arr , sep , ctx ) => arr . map ( e => Values . toString ( e , ctx . settings ) ) . join ( sep ) )
. add2 ( "array" , "null" , ( arr , _s , context ) => DefaultFunctions . join ( context , arr , ", " ) )
. add2 ( "*" , "string" , ( elem , sep , ctx ) => Values . toString ( elem , ctx . settings ) )
. add1 ( "array" , ( arr , context ) => DefaultFunctions . join ( context , arr , ", " ) )
. add1 ( "*" , ( e , ctx ) => Values . toString ( e , ctx . settings ) )
. vectorize ( 2 , [ 1 ] )
. build ( ) ;
DefaultFunctions . any = new FunctionBuilder ( "any" )
. add1 ( "array" , arr => arr . some ( v => Values . isTruthy ( v ) ) )
. add2 ( "array" , "function" , ( arr , f , ctx ) => arr . some ( v => Values . isTruthy ( f ( ctx , v ) ) ) )
. vararg ( ( _ctx , ... args ) => args . some ( v => Values . isTruthy ( v ) ) )
. build ( ) ;
DefaultFunctions . all = new FunctionBuilder ( "all" )
. add1 ( "array" , arr => arr . every ( v => Values . isTruthy ( v ) ) )
. add2 ( "array" , "function" , ( arr , f , ctx ) => arr . every ( v => Values . isTruthy ( f ( ctx , v ) ) ) )
. vararg ( ( _ctx , ... args ) => args . every ( v => Values . isTruthy ( v ) ) )
. build ( ) ;
DefaultFunctions . none = new FunctionBuilder ( "all" )
. add1 ( "array" , arr => ! arr . some ( v => Values . isTruthy ( v ) ) )
. add2 ( "array" , "function" , ( arr , f , ctx ) => ! arr . some ( v => Values . isTruthy ( f ( ctx , v ) ) ) )
. vararg ( ( _ctx , ... args ) => ! args . some ( v => Values . isTruthy ( v ) ) )
. build ( ) ;
DefaultFunctions . filter = new FunctionBuilder ( "filter" )
. add2 ( "array" , "function" , ( arr , f , ctx ) => arr . filter ( v => Values . isTruthy ( f ( ctx , v ) ) ) )
. add2 ( "null" , "*" , ( ) => null )
. build ( ) ;
DefaultFunctions . map = new FunctionBuilder ( "map" )
. add2 ( "array" , "function" , ( arr , f , ctx ) => arr . map ( v => f ( ctx , v ) ) )
. add2 ( "null" , "*" , ( ) => null )
. build ( ) ;
DefaultFunctions . nonnull = new FunctionBuilder ( "nonnull" )
. vararg ( ( _ctx , ... args ) => args . filter ( v => Values . typeOf ( v ) != "null" ) )
. build ( ) ;
} ) ( DefaultFunctions || ( DefaultFunctions = { } ) ) ;
/** Default function implementations for the expression evaluator. */
const DEFAULT _FUNCTIONS = {
// Constructors.
list : DefaultFunctions . list ,
array : DefaultFunctions . list ,
link : DefaultFunctions . link ,
elink : DefaultFunctions . elink ,
date : DefaultFunctions . date ,
dateformat : DefaultFunctions . dateformat ,
number : DefaultFunctions . number ,
string : DefaultFunctions . string ,
object : DefaultFunctions . object ,
// Math Operations.
round : DefaultFunctions . round ,
min : DefaultFunctions . min ,
max : DefaultFunctions . max ,
minby : DefaultFunctions . minby ,
maxby : DefaultFunctions . maxby ,
// String operations.
regexreplace : DefaultFunctions . regexreplace ,
regexmatch : DefaultFunctions . regexmatch ,
replace : DefaultFunctions . replace ,
lower : DefaultFunctions . lower ,
upper : DefaultFunctions . upper ,
split : DefaultFunctions . split ,
startswith : DefaultFunctions . startswith ,
endswith : DefaultFunctions . endswith ,
padleft : DefaultFunctions . padleft ,
padright : DefaultFunctions . padright ,
// Date Operations.
striptime : DefaultFunctions . striptime ,
// List operations.
length : DefaultFunctions . length ,
contains : DefaultFunctions . contains ,
icontains : DefaultFunctions . icontains ,
econtains : DefaultFunctions . econtains ,
containsword : DefaultFunctions . containsword ,
reverse : DefaultFunctions . reverse ,
sort : DefaultFunctions . sort ,
// Aggregation operations like reduce.
reduce : DefaultFunctions . reduce ,
join : DefaultFunctions . join ,
sum : DefaultFunctions . sum ,
product : DefaultFunctions . product ,
all : DefaultFunctions . all ,
any : DefaultFunctions . any ,
none : DefaultFunctions . none ,
filter : DefaultFunctions . filter ,
map : DefaultFunctions . map ,
nonnull : DefaultFunctions . nonnull ,
// Object/Utility operations.
extract : DefaultFunctions . extract ,
default : DefaultFunctions . fdefault ,
ldefault : DefaultFunctions . ldefault ,
choice : DefaultFunctions . choice ,
} ;
/** Core implementation of the query language evaluation engine. */
/ * *
* Evaluation context that expressions can be evaluated in . Includes global state , as well as available functions and a handler
* for binary operators .
* /
class Context {
/ * *
* Create a new context with the given namespace of globals , as well as optionally with custom binary operator , function ,
* and link handlers .
* /
constructor ( linkHandler , settings , globals = { } , binaryOps = createBinaryOps ( linkHandler . normalize ) , functions = DEFAULT _FUNCTIONS ) {
this . linkHandler = linkHandler ;
this . settings = settings ;
this . globals = globals ;
this . binaryOps = binaryOps ;
this . functions = functions ;
}
/** Set a global value in this context. */
set ( name , value ) {
this . globals [ name ] = value ;
return this ;
}
/** Get the value of a global variable by name. Returns null if not present. */
get ( name ) {
var _a ;
return ( _a = this . globals [ name ] ) !== null && _a !== void 0 ? _a : null ;
}
/** Try to evaluate an arbitary field in this context, raising an exception on failure. */
tryEvaluate ( field , data = { } ) {
return this . evaluate ( field , data ) . orElseThrow ( ) ;
}
/** Evaluate an arbitrary field in this context. */
evaluate ( field , data = { } ) {
var _a , _b ;
switch ( field . type ) {
case "literal" :
return Result . success ( field . value ) ;
case "variable" :
if ( field . name in data )
return Result . success ( data [ field . name ] ) ;
else if ( field . name in this . globals )
return Result . success ( this . globals [ field . name ] ) ;
else
return Result . success ( null ) ;
case "negated" :
return this . evaluate ( field . child , data ) . map ( s => ! Values . isTruthy ( s ) ) ;
case "binaryop" :
return Result . flatMap2 ( this . evaluate ( field . left , data ) , this . evaluate ( field . right , data ) , ( a , b ) => this . binaryOps . evaluate ( field . op , a , b , this ) ) ;
case "list" :
let result = [ ] ;
for ( let child of field . values ) {
let subeval = this . evaluate ( child , data ) ;
if ( ! subeval . successful )
return subeval ;
result . push ( subeval . value ) ;
}
return Result . success ( result ) ;
case "object" :
let objResult = { } ;
for ( let [ key , child ] of Object . entries ( field ) ) {
let subeval = this . evaluate ( child , data ) ;
if ( ! subeval . successful )
return subeval ;
objResult [ key ] = subeval . value ;
}
return Result . success ( objResult ) ;
case "lambda" :
// Just relying on JS to capture 'data' for us implicitly; unsure
// if this is correct thing to do. Could cause wierd behaviors.
return Result . success ( ( ctx , ... args ) => {
let copy = Object . assign ( { } , data ) ;
for ( let arg = 0 ; arg < Math . min ( args . length , field . arguments . length ) ; arg ++ ) {
copy [ field . arguments [ arg ] ] = args [ arg ] ;
}
return ctx . evaluate ( field . value , copy ) . orElseThrow ( ) ;
} ) ;
case "function" :
let rawFunc = field . func . type == "variable"
? Result . success ( field . func . name )
: this . evaluate ( field . func , data ) ;
if ( ! rawFunc . successful )
return rawFunc ;
let func = rawFunc . value ;
let args = [ ] ;
for ( let arg of field . arguments ) {
let resolved = this . evaluate ( arg , data ) ;
if ( ! resolved . successful )
return resolved ;
args . push ( resolved . value ) ;
}
let call ;
if ( Values . isFunction ( func ) )
call = func ;
else if ( Values . isString ( func ) && func in this . functions )
call = this . functions [ func ] ;
else if ( Values . isString ( func ) )
return Result . failure ( ` Unrecognized function name ' ${ func } ' ` ) ;
else
return Result . failure ( ` Cannot call type ' ${ Values . typeOf ( func ) } ' as a function ` ) ;
try {
return Result . success ( call ( this , ... args ) ) ;
}
catch ( e ) {
return Result . failure ( e . message ) ;
}
case "index" :
// TODO: Will move this out to an 'primitives' module and add more content to it.
let literalIndex = field . index . type == "variable"
? Result . success ( field . index . name )
: this . evaluate ( field . index , data ) ;
let checkedIndex = literalIndex . flatMap ( s => Values . isString ( s ) || Values . isNumber ( s )
? Result . success ( s )
: Result . failure ( "Can only index with a string, variable, or number" ) ) ;
if ( ! checkedIndex . successful )
return checkedIndex ;
let index = checkedIndex . value ;
let checkedObject = field . object . type == "variable" && field . object . name == "row"
? Result . success ( Object . assign ( { } , this . globals , data ) )
: this . evaluate ( field . object , data ) ;
if ( ! checkedObject . successful )
return checkedObject ;
let object = Values . wrapValue ( checkedObject . value ) ;
if ( ! object )
return Result . failure ( "Unrecognized object to index into: " + object ) ;
switch ( object . type ) {
case "object" :
if ( ! Values . isString ( index ) )
return Result . failure ( 'can only index into objects with strings (a.b or a["b"])' ) ;
return Result . success ( ( _a = object . value [ index ] ) !== null && _a !== void 0 ? _a : null ) ;
case "link" :
if ( ! Values . isString ( index ) )
return Result . failure ( 'can only index into links with strings (a.b or a["b"])' ) ;
let linkValue = this . linkHandler . resolve ( object . value . path ) ;
if ( Values . isNull ( linkValue ) )
return Result . success ( null ) ;
return Result . success ( ( _b = linkValue [ index ] ) !== null && _b !== void 0 ? _b : null ) ;
case "array" :
if ( Values . isNumber ( index ) ) {
if ( index >= object . value . length || index < 0 )
return Result . success ( null ) ;
else
return Result . success ( object . value [ index ] ) ;
}
else if ( Values . isString ( index ) ) {
let result = [ ] ;
for ( let value of object . value ) {
let next = this . evaluate ( Fields . index ( Fields . literal ( value ) , Fields . literal ( index ) ) ) ;
if ( ! next . successful )
continue ;
result . push ( next . value ) ;
}
return Result . success ( result ) ;
}
else {
return Result . failure ( "Array indexing requires either a number (to get a specific element), or a string (to map all elements inside the array)" ) ;
}
case "string" :
if ( ! Values . isNumber ( index ) )
return Result . failure ( "string indexing requires a numeric index (string[index])" ) ;
if ( index >= object . value . length || index < 0 )
return Result . success ( null ) ;
return Result . success ( object . value [ index ] ) ;
case "date" :
if ( ! Values . isString ( index ) )
return Result . failure ( "date indexing requires a string representing the unit" ) ;
switch ( index ) {
case "year" :
return Result . success ( object . value . year ) ;
case "month" :
return Result . success ( object . value . month ) ;
case "weekyear" :
return Result . success ( object . value . weekNumber ) ;
case "week" :
return Result . success ( Math . floor ( object . value . day / 7 ) + 1 ) ;
case "weekday" :
return Result . success ( object . value . weekday ) ;
case "day" :
return Result . success ( object . value . day ) ;
case "hour" :
return Result . success ( object . value . hour ) ;
case "minute" :
return Result . success ( object . value . minute ) ;
case "second" :
return Result . success ( object . value . second ) ;
case "millisecond" :
return Result . success ( object . value . millisecond ) ;
default :
return Result . success ( null ) ;
}
case "duration" :
if ( ! Values . isString ( index ) )
return Result . failure ( "duration indexing requires a string representing the unit" ) ;
switch ( index ) {
case "year" :
case "years" :
return Result . success ( object . value . years ) ;
case "month" :
case "months" :
return Result . success ( object . value . months ) ;
case "weeks" :
return Result . success ( object . value . weeks ) ;
case "day" :
case "days" :
return Result . success ( object . value . days ) ;
case "hour" :
case "hours" :
return Result . success ( object . value . hours ) ;
case "minute" :
case "minutes" :
return Result . success ( object . value . minutes ) ;
case "second" :
case "seconds" :
return Result . success ( object . value . seconds ) ;
case "millisecond" :
case "milliseconds" :
return Result . success ( object . value . milliseconds ) ;
default :
return Result . success ( null ) ;
}
default :
return Result . success ( null ) ;
}
}
}
}
/** Collect data matching a source query. */
/** Find source paths which match the given source. */
function matchingSourcePaths ( source , index , originFile = "" ) {
var _a ;
switch ( source . type ) {
case "empty" :
return Result . success ( new Set ( ) ) ;
case "tag" :
return Result . success ( index . tags . getInverse ( source . tag ) ) ;
case "csv" :
return Result . success ( new Set ( [ index . prefix . resolveRelative ( source . path , originFile ) ] ) ) ;
case "folder" :
// Prefer loading from the folder at the given path.
if ( index . prefix . nodeExists ( source . folder ) )
return Result . success ( index . prefix . get ( source . folder , PathFilters . markdown ) ) ;
// But allow for loading individual files if they exist.
if ( index . prefix . pathExists ( source . folder ) )
return Result . success ( new Set ( [ source . folder ] ) ) ;
else if ( index . prefix . pathExists ( source . folder + ".md" ) )
return Result . success ( new Set ( [ source . folder + ".md" ] ) ) ;
// For backwards-compat, return an empty result even if the folder does not exist.
return Result . success ( new Set ( ) ) ;
case "link" :
let fullPath = ( _a = index . metadataCache . getFirstLinkpathDest ( source . file , originFile ) ) === null || _a === void 0 ? void 0 : _a . path ;
if ( ! fullPath )
return Result . failure ( ` Could not resolve link " ${ source . file } " during link lookup - does it exist? ` ) ;
if ( source . direction === "incoming" ) {
// To find all incoming links (i.e., things that link to this), use the index that Obsidian provides.
// TODO: Use an actual index so this isn't a fullscan.
let resolved = index . metadataCache . resolvedLinks ;
let incoming = new Set ( ) ;
for ( let [ key , value ] of Object . entries ( resolved ) ) {
if ( fullPath in value )
incoming . add ( key ) ;
}
return Result . success ( incoming ) ;
}
else {
let resolved = index . metadataCache . resolvedLinks ;
if ( ! ( fullPath in resolved ) )
return Result . failure ( ` Could not find file " ${ source . file } " during link lookup - does it exist? ` ) ;
return Result . success ( new Set ( Object . keys ( index . metadataCache . resolvedLinks [ fullPath ] ) ) ) ;
}
case "binaryop" :
return Result . flatMap2 ( matchingSourcePaths ( source . left , index , originFile ) , matchingSourcePaths ( source . right , index , originFile ) , ( left , right ) => {
if ( source . op == "&" ) {
let result = new Set ( ) ;
for ( let elem of right ) {
if ( left . has ( elem ) )
result . add ( elem ) ;
}
return Result . success ( result ) ;
}
else if ( source . op == "|" ) {
let result = new Set ( left ) ;
for ( let elem of right )
result . add ( elem ) ;
return Result . success ( result ) ;
}
else {
return Result . failure ( ` Unrecognized operator ' ${ source . op } '. ` ) ;
}
} ) ;
case "negate" :
return matchingSourcePaths ( source . child , index , originFile ) . map ( child => {
// TODO: This is obviously very inefficient. Can be improved by complicating the
// return type of this function & optimizing 'and' / 'or'.
let allFiles = new Set ( index . vault . getMarkdownFiles ( ) . map ( f => f . path ) ) ;
child . forEach ( f => allFiles . delete ( f ) ) ;
return allFiles ;
} ) ;
}
}
/** Convert a path to the data for that path; usually markdown pages, but could also be other file types (like CSV). */
function resolvePathData ( path , index ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( PathFilters . csv ( path ) )
return resolveCsvData ( path , index ) ;
else
return resolveMarkdownData ( path , index ) ;
} ) ;
}
// TODO: We shouldn't be doing path normalization here relative to an origin file,
/** Convert a CSV path to the data in the CSV (in dataview format). */
function resolveCsvData ( path , index ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let rawData = yield index . csv . get ( path ) ;
return rawData . map ( rows => {
return rows . map ( ( row , index ) => {
return {
id : ` ${ path } # ${ index } ` ,
data : row ,
} ;
} ) ;
} ) ;
} ) ;
}
/** Convert a path pointing to a markdown page, into the associated metadata. */
function resolveMarkdownData ( path , index ) {
let page = index . pages . get ( path ) ;
if ( ! page )
return Result . success ( [ ] ) ;
return Result . success ( [
{
id : Link . file ( path ) ,
data : page . toObject ( index ) ,
} ,
] ) ;
}
/** Resolve a source to the collection of data rows that it matches. */
function resolveSource ( source , index , originFile = "" ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let paths = matchingSourcePaths ( source , index , originFile ) ;
if ( ! paths . successful )
return Result . failure ( paths . error ) ;
let result = [ ] ;
for ( let path of paths . value ) {
let resolved = yield resolvePathData ( path , index ) ;
if ( ! resolved . successful )
return resolved ;
for ( let val of resolved . value )
result . push ( val ) ;
}
return Result . success ( result ) ;
} ) ;
}
function iden ( x ) {
return x ;
}
/** Shared execution code which just takes in arbitrary data, runs operations over it, and returns it + per-row errors. */
function executeCore ( rows , context , ops ) {
let diagnostics = [ ] ;
let identMeaning = { type : "path" } ;
let startTime = new Date ( ) . getTime ( ) ;
for ( let op of ops ) {
let opStartTime = new Date ( ) . getTime ( ) ;
let incomingRows = rows . length ;
let errors = [ ] ;
switch ( op . type ) {
case "where" :
let whereResult = [ ] ;
for ( let index = 0 ; index < rows . length ; index ++ ) {
let row = rows [ index ] ;
let value = context . evaluate ( op . clause , row . data ) ;
if ( ! value . successful )
errors . push ( { index , message : value . error } ) ;
else if ( Values . isTruthy ( value . value ) )
whereResult . push ( row ) ;
}
rows = whereResult ;
break ;
case "sort" :
let sortFields = op . fields ;
let taggedData = [ ] ;
outer : for ( let index = 0 ; index < rows . length ; index ++ ) {
let row = rows [ index ] ;
let rowSorts = [ ] ;
for ( let sIndex = 0 ; sIndex < sortFields . length ; sIndex ++ ) {
let value = context . evaluate ( sortFields [ sIndex ] . field , row . data ) ;
if ( ! value . successful ) {
errors . push ( { index , message : value . error } ) ;
continue outer ;
}
rowSorts . push ( value . value ) ;
}
taggedData . push ( { data : row , fields : rowSorts } ) ;
}
// Sort rows by the sort fields, and then return the finished result.
taggedData . sort ( ( a , b ) => {
for ( let index = 0 ; index < sortFields . length ; index ++ ) {
let factor = sortFields [ index ] . direction === "ascending" ? 1 : - 1 ;
let le = context . binaryOps
. evaluate ( "<" , a . fields [ index ] , b . fields [ index ] , context )
. orElse ( false ) ;
if ( Values . isTruthy ( le ) )
return factor * - 1 ;
let ge = context . binaryOps
. evaluate ( ">" , a . fields [ index ] , b . fields [ index ] , context )
. orElse ( false ) ;
if ( Values . isTruthy ( ge ) )
return factor * 1 ;
}
return 0 ;
} ) ;
rows = taggedData . map ( v => v . data ) ;
break ;
case "limit" :
let limiting = context . evaluate ( op . amount ) ;
if ( ! limiting . successful )
return Result . failure ( "Failed to execute 'limit' statement: " + limiting . error ) ;
if ( ! Values . isNumber ( limiting . value ) )
return Result . failure ( ` Failed to execute 'limit' statement: limit should be a number, but got ' ${ Values . typeOf ( limiting . value ) } ' ( ${ limiting . value } ) ` ) ;
rows = rows . slice ( 0 , limiting . value ) ;
break ;
case "group" :
let groupData = [ ] ;
for ( let index = 0 ; index < rows . length ; index ++ ) {
let value = context . evaluate ( op . field . field , rows [ index ] . data ) ;
if ( ! value . successful ) {
errors . push ( { index , message : value . error } ) ;
continue ;
}
groupData . push ( { data : rows [ index ] , key : value . value } ) ;
}
// Sort by the key, which we will group on shortly.
groupData . sort ( ( a , b ) => {
let le = context . binaryOps . evaluate ( "<" , a . key , b . key , context ) . orElse ( false ) ;
if ( Values . isTruthy ( le ) )
return - 1 ;
let ge = context . binaryOps . evaluate ( ">" , a . key , b . key , context ) . orElse ( false ) ;
if ( Values . isTruthy ( ge ) )
return 1 ;
return 0 ;
} ) ;
// Then walk through and find fields that are equal.
let finalGroupData = [ ] ;
if ( groupData . length > 0 )
finalGroupData . push ( {
key : groupData [ 0 ] . key ,
rows : [ groupData [ 0 ] . data . data ] ,
[ op . field . name ] : groupData [ 0 ] . key ,
} ) ;
for ( let index = 1 ; index < groupData . length ; index ++ ) {
let curr = groupData [ index ] , prev = groupData [ index - 1 ] ;
if ( context . binaryOps . evaluate ( "=" , curr . key , prev . key , context ) . orElse ( false ) ) {
finalGroupData [ finalGroupData . length - 1 ] . rows . push ( curr . data . data ) ;
}
else {
finalGroupData . push ( {
key : curr . key ,
rows : [ curr . data . data ] ,
[ op . field . name ] : curr . key ,
} ) ;
}
}
rows = finalGroupData . map ( d => {
return { id : d . key , data : d } ;
} ) ;
identMeaning = { type : "group" , name : op . field . name , on : identMeaning } ;
break ;
case "flatten" :
let flattenResult = [ ] ;
for ( let index = 0 ; index < rows . length ; index ++ ) {
let row = rows [ index ] ;
let value = context . evaluate ( op . field . field , row . data ) ;
if ( ! value . successful ) {
errors . push ( { index , message : value . error } ) ;
continue ;
}
let datapoints = Values . isArray ( value . value ) ? value . value : [ value . value ] ;
for ( let v of datapoints ) {
let copy = Values . deepCopy ( row ) ;
copy . data [ op . field . name ] = v ;
flattenResult . push ( copy ) ;
}
}
rows = flattenResult ;
if ( identMeaning . type == "group" && identMeaning . name == op . field . name )
identMeaning = identMeaning . on ;
break ;
default :
return Result . failure ( "Unrecognized query operation '" + op . type + "'" ) ;
}
if ( errors . length >= incomingRows && incomingRows > 0 ) {
return Result . failure ( ` Every row during operation ' ${ op . type } ' failed with an error; first ${ Math . min ( 3 , errors . length ) } : \n
$ { errors
. slice ( 0 , 3 )
. map ( d => "- " + d . message )
. join ( "\n" ) } ` );
}
diagnostics . push ( {
incomingRows ,
errors ,
outgoingRows : rows . length ,
timeMs : new Date ( ) . getTime ( ) - opStartTime ,
} ) ;
}
return Result . success ( {
data : rows ,
idMeaning : identMeaning ,
ops ,
diagnostics ,
timeMs : new Date ( ) . getTime ( ) - startTime ,
} ) ;
}
/** Expanded version of executeCore which adds an additional "extraction" step to the pipeline. */
function executeCoreExtract ( rows , context , ops , fields ) {
let internal = executeCore ( rows , context , ops ) ;
if ( ! internal . successful )
return internal ;
let core = internal . value ;
let startTime = new Date ( ) . getTime ( ) ;
let errors = [ ] ;
let res = [ ] ;
outer : for ( let index = 0 ; index < core . data . length ; index ++ ) {
let page = { id : core . data [ index ] . id , data : { } } ;
for ( let [ name , field ] of Object . entries ( fields ) ) {
let value = context . evaluate ( field , core . data [ index ] . data ) ;
if ( ! value . successful ) {
errors . push ( { index : index , message : value . error } ) ;
continue outer ;
}
page . data [ name ] = value . value ;
}
res . push ( page ) ;
}
if ( errors . length >= core . data . length && core . data . length > 0 ) {
return Result . failure ( ` Every row during final data extraction failed with an error; first ${ Math . max ( errors . length , 3 ) } : \n
$ { errors
. slice ( 0 , 3 )
. map ( d => "- " + d . message )
. join ( "\n" ) } ` );
}
let execTime = new Date ( ) . getTime ( ) - startTime ;
return Result . success ( {
data : res ,
idMeaning : core . idMeaning ,
diagnostics : core . diagnostics . concat ( [
{
timeMs : execTime ,
incomingRows : core . data . length ,
outgoingRows : res . length ,
errors ,
} ,
] ) ,
ops : core . ops . concat ( [ { type : "extract" , fields } ] ) ,
timeMs : core . timeMs + execTime ,
} ) ;
}
/** Execute a list-based query, returning the final results. */
function executeList ( query , index , origin , settings ) {
var _a , _b ;
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Start by collecting all of the files that match the 'from' queries.
let fileset = yield resolveSource ( query . source , index , origin ) ;
if ( ! fileset . successful )
return Result . failure ( fileset . error ) ;
// Extract information about the origin page to add to the root context.
let rootContext = new Context ( defaultLinkHandler ( index , origin ) , settings , {
this : ( _b = ( _a = index . pages . get ( origin ) ) === null || _a === void 0 ? void 0 : _a . toObject ( index ) ) !== null && _b !== void 0 ? _b : { } ,
} ) ;
let targetField = query . header . format ;
let fields = targetField ? { target : targetField } : { } ;
return executeCoreExtract ( fileset . value , rootContext , query . operations , fields ) . map ( core => {
let data = core . data . map ( p => {
var _a ;
return iden ( {
primary : p . id ,
value : ( _a = p . data [ "target" ] ) !== null && _a !== void 0 ? _a : undefined ,
} ) ;
} ) ;
return { primaryMeaning : core . idMeaning , core , data } ;
} ) ;
} ) ;
}
/** Execute a table query. */
function executeTable ( query , index , origin , settings ) {
var _a , _b ;
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Start by collecting all of the files that match the 'from' queries.
let fileset = yield resolveSource ( query . source , index , origin ) ;
if ( ! fileset . successful )
return Result . failure ( fileset . error ) ;
// Extract information about the origin page to add to the root context.
let rootContext = new Context ( defaultLinkHandler ( index , origin ) , settings , {
this : ( _b = ( _a = index . pages . get ( origin ) ) === null || _a === void 0 ? void 0 : _a . toObject ( index ) ) !== null && _b !== void 0 ? _b : { } ,
} ) ;
let targetFields = query . header . fields ;
let fields = { } ;
for ( let field of targetFields )
fields [ field . name ] = field . field ;
return executeCoreExtract ( fileset . value , rootContext , query . operations , fields ) . map ( core => {
let names = targetFields . map ( f => f . name ) ;
let data = core . data . map ( p => iden ( {
id : p . id ,
values : targetFields . map ( f => p . data [ f . name ] ) ,
} ) ) ;
return { core , names , data , idMeaning : core . idMeaning } ;
} ) ;
} ) ;
}
/** Maps a raw core execution result to a task grouping which is much easier to */
function extractTaskGroupings ( id , rows ) {
switch ( id . type ) {
case "path" :
return { type : "base" , value : rows . map ( r => Task . fromObject ( r ) ) } ;
case "group" :
let key = id . name ;
return {
type : "grouped" ,
groups : rows . map ( r => iden ( {
key : r [ key ] ,
value : extractTaskGroupings ( id . on , r . rows ) ,
} ) ) ,
} ;
}
}
/** Execute a task query, returning all matching tasks. */
function executeTask ( query , origin , index , settings ) {
var _a , _b ;
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let fileset = matchingSourcePaths ( query . source , index , origin ) ;
if ( ! fileset . successful )
return Result . failure ( fileset . error ) ;
// Collect tasks from pages which match.
let incomingTasks = [ ] ;
for ( let path of fileset . value ) {
let page = index . pages . get ( path ) ;
if ( ! page )
continue ;
let pageData = page . toObject ( index ) ;
let rpage = page ;
let pageTasks = page . tasks . map ( t => {
let copy = t . toObject ( ) ;
// Add page data to this copy.
for ( let [ key , value ] of Object . entries ( pageData ) ) {
if ( key in copy )
continue ;
copy [ key ] = value ;
}
return { id : ` ${ rpage . path } # ${ t . line } ` , data : copy } ;
} ) ;
for ( let task of pageTasks )
incomingTasks . push ( task ) ;
}
// Extract information about the origin page to add to the root context.
let rootContext = new Context ( defaultLinkHandler ( index , origin ) , settings , {
this : ( _b = ( _a = index . pages . get ( origin ) ) === null || _a === void 0 ? void 0 : _a . toObject ( index ) ) !== null && _b !== void 0 ? _b : { } ,
} ) ;
return executeCore ( incomingTasks , rootContext , query . operations ) . map ( core => {
return {
core ,
tasks : extractTaskGroupings ( core . idMeaning , core . data . map ( r => r . data ) ) ,
} ;
} ) ;
} ) ;
}
/** Execute a single field inline a file, returning the evaluated result. */
function executeInline ( field , origin , index , settings ) {
var _a , _b ;
return new Context ( defaultLinkHandler ( index , origin ) , settings , {
this : ( _b = ( _a = index . pages . get ( origin ) ) === null || _a === void 0 ? void 0 : _a . toObject ( index ) ) !== null && _b !== void 0 ? _b : { } ,
} ) . evaluate ( field ) ;
}
/** The default link resolver used when creating contexts. */
function defaultLinkHandler ( index , origin ) {
return {
resolve : link => {
let realFile = index . metadataCache . getFirstLinkpathDest ( link , origin ) ;
if ( ! realFile )
return null ;
let realPage = index . pages . get ( realFile . path ) ;
if ( ! realPage )
return null ;
return realPage . toObject ( index ) ;
} ,
normalize : link => {
var _a ;
let realFile = index . metadataCache . getFirstLinkpathDest ( link , origin ) ;
return ( _a = realFile === null || realFile === void 0 ? void 0 : realFile . path ) !== null && _a !== void 0 ? _a : link ;
} ,
exists : link => {
let realFile = index . metadataCache . getFirstLinkpathDest ( link , origin ) ;
return ! ! realFile ;
} ,
} ;
}
/** The general, externally accessible plugin API (available at `app.plugins.plugins.dataview.api`). */
/** Asynchronous API calls related to file / system IO. */
class DataviewIOApi {
constructor ( api ) {
this . api = api ;
}
/** Load the contents of a CSV asynchronously, returning a data array of rows (or undefined if it does not exist). */
csv ( path , originFile ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( ! Values . isLink ( path ) && ! Values . isString ( path ) ) {
throw Error ( ` dv.io.csv only handles string or link paths; was provided type ' ${ typeof path } '. ` ) ;
}
let data = yield this . api . index . csv . get ( this . normalize ( path , originFile ) ) ;
if ( data . successful )
return DataArray . from ( data . value , this . api . settings ) ;
else
throw Error ( ` Could not find CSV for path ' ${ path } ' (relative to origin ' ${ originFile !== null && originFile !== void 0 ? originFile : "/" } ') ` ) ;
} ) ;
}
/** Asynchronously load the contents of any link or path in an Obsidian vault. */
load ( path , originFile ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( ! Values . isLink ( path ) && ! Values . isString ( path ) ) {
throw Error ( ` dv.io.load only handles string or link paths; was provided type ' ${ typeof path } '. ` ) ;
}
return this . api . index . vault . adapter . read ( this . normalize ( path , originFile ) ) ;
} ) ;
}
/** Normalize a link or path relative to an optional origin file. Returns a textual fully-qualified-path. */
normalize ( path , originFile ) {
let realPath ;
if ( Values . isLink ( path ) )
realPath = path . path ;
else
realPath = path ;
return this . api . index . prefix . resolveRelative ( realPath , originFile ) ;
}
}
class DataviewApi {
constructor ( app , index , settings ) {
this . app = app ;
this . index = index ;
this . settings = settings ;
/** Value utility functions for comparisons and type-checking. */
this . value = Values ;
this . evaluationContext = new Context ( defaultLinkHandler ( index , "" ) , settings ) ;
this . func = Functions . bindAll ( DEFAULT _FUNCTIONS , this . evaluationContext ) ;
this . io = new DataviewIOApi ( this ) ;
}
/////////////////////////////
// Index + Data Collection //
/////////////////////////////
/** Return an array of paths (as strings) corresponding to pages which match the query. */
pagePaths ( query , originFile ) {
let source ;
try {
if ( ! query || query . trim ( ) === "" )
source = Sources . folder ( "" ) ;
else
source = EXPRESSION . source . tryParse ( query ) ;
}
catch ( ex ) {
throw new Error ( ` Failed to parse query in 'pagePaths': ${ ex } ` ) ;
}
return matchingSourcePaths ( source , this . index , originFile )
. map ( s => DataArray . from ( s , this . settings ) )
. orElseThrow ( ) ;
}
/** Map a page path to the actual data contained within that page. */
page ( path , originFile ) {
if ( ! ( typeof path === "string" ) && ! Values . isLink ( path ) ) {
throw Error ( "dv.page only handles string and link paths; was provided type '" + typeof path + "'" ) ;
}
let rawPath = path instanceof Link ? path . path : path ;
let normPath = this . app . metadataCache . getFirstLinkpathDest ( rawPath , originFile !== null && originFile !== void 0 ? originFile : "" ) ;
if ( ! normPath )
return undefined ;
let pageObject = this . index . pages . get ( normPath . path ) ;
if ( ! pageObject )
return undefined ;
return pageObject . toObject ( this . index ) ;
}
/** Return an array of page objects corresponding to pages which match the query. */
pages ( query , originFile ) {
return this . pagePaths ( query , originFile ) . flatMap ( p => {
let res = this . page ( p , originFile ) ;
return res ? [ res ] : [ ] ;
} ) ;
}
/////////////
// Utility //
/////////////
/ * *
* Convert an input element or array into a Dataview data - array . If the input is already a data array ,
* it is returned unchanged .
* /
array ( raw ) {
if ( DataArray . isDataArray ( raw ) )
return raw ;
if ( Array . isArray ( raw ) )
return DataArray . wrap ( raw , this . settings ) ;
return DataArray . wrap ( [ raw ] , this . settings ) ;
}
/** Return true if theg given value is a javascript array OR a dataview data array. */
isArray ( raw ) {
return DataArray . isDataArray ( raw ) || Array . isArray ( raw ) ;
}
/** Create a dataview file link to the given path. */
fileLink ( path , embed = false , display ) {
return Link . file ( path , embed , display ) ;
}
/** Attempt to extract a date from a string, link or date. */
date ( pathlike ) {
return this . func . date ( pathlike ) ;
}
/ * *
* Compare two arbitrary JavaScript values using Dataview ' s default comparison rules . Returns a negative value if
* a < b , 0 if a = b , and a positive value if a > b .
* /
compare ( a , b ) {
return Values . compareValue ( a , b ) ;
}
/** Return true if the two given JavaScript values are equal using Dataview's default comparison rules. */
equal ( a , b ) {
return this . compare ( a , b ) == 0 ;
}
///////////////
// Rendering //
///////////////
/** Render a dataview list of the given values. */
list ( values , container , component , filePath ) {
if ( ! values )
return ;
if ( DataArray . isDataArray ( values ) )
values = values . array ( ) ;
renderList ( container , values , component , filePath , this . settings ) ;
}
/** Render a dataview table with the given headers, and the 2D array of values. */
table ( headers , values , container , component , filePath ) {
if ( ! values )
values = [ ] ;
if ( DataArray . isDataArray ( values ) )
values = values . array ( ) ;
renderTable ( container , headers , values , component , filePath , this . settings ) ;
}
/** Render a dataview task view with the given tasks. */
taskList ( tasks , groupByFile = true , container , component , filePath = "" ) {
var _a ;
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( DataArray . isDataArray ( tasks ) )
tasks = tasks . array ( ) ;
let taskComponent = new obsidian . Component ( ) ;
component . addChild ( taskComponent ) ;
if ( groupByFile ) {
let byFile = new Map ( ) ;
for ( let task of tasks ) {
if ( ! byFile . has ( task . path ) )
byFile . set ( task . path , [ ] ) ;
( _a = byFile . get ( task . path ) ) === null || _a === void 0 ? void 0 : _a . push ( task ) ;
}
let groupings = Groupings . grouped ( Array . from ( byFile . entries ( ) ) . map ( ( [ path , tasks ] ) => {
return { key : Link . file ( path ) , value : Groupings . base ( tasks ) } ;
} ) ) ;
let subcontainer = container . createDiv ( ) ;
yield renderTasks ( subcontainer , groupings , filePath , taskComponent , this . app . vault , this . settings ) ;
}
else {
let subcontainer = container . createDiv ( ) ;
yield renderTasks ( subcontainer , Groupings . base ( tasks ) , filePath , taskComponent , this . app . vault , this . settings ) ;
}
} ) ;
}
/** Render an arbitrary value into a container. */
renderValue ( value , container , component , filePath , inline = false ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield renderValue ( value , container , filePath , component , this . settings , inline ) ;
} ) ;
}
}
/** Fancy wrappers for the JavaScript API, used both by external plugins AND by the dataview javascript view. */
/** Asynchronous API calls related to file / system IO. */
class DataviewInlineIOApi {
constructor ( api , currentFile ) {
this . api = api ;
this . currentFile = currentFile ;
}
/** Load the contents of a CSV asynchronously, returning a data array of rows (or undefined if it does not exist). */
csv ( path , originFile ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
return this . api . csv ( path , originFile || this . currentFile ) ;
} ) ;
}
/** Asynchronously load the contents of any link or path in an Obsidian vault. */
load ( path , originFile ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
return this . api . load ( path , originFile || this . currentFile ) ;
} ) ;
}
/** Normalize a link or path relative to an optional origin file. Returns a textual fully-qualified-path. */
normalize ( path , originFile ) {
return this . api . normalize ( path , originFile || this . currentFile ) ;
}
}
class DataviewInlineApi {
constructor ( index , component , container , app , settings , currentFilePath ) {
var _a , _b ;
/** Value utilities which allow for type-checking and comparisons. */
this . value = Values ;
this . index = index ;
this . component = component ;
this . container = container ;
this . app = app ;
this . currentFilePath = currentFilePath ;
this . settings = settings ;
this . api = new DataviewApi ( this . app , this . index , this . settings ) ;
this . io = new DataviewInlineIOApi ( this . api . io , this . currentFilePath ) ;
// Set up the evaluation context with variables from the current file.
let fileMeta = ( _b = ( _a = this . index . pages . get ( this . currentFilePath ) ) === null || _a === void 0 ? void 0 : _a . toObject ( this . index ) ) !== null && _b !== void 0 ? _b : { } ;
this . evaluationContext = new Context ( defaultLinkHandler ( this . index , this . currentFilePath ) , settings , fileMeta ) ;
this . func = Functions . bindAll ( DEFAULT _FUNCTIONS , this . evaluationContext ) ;
}
/////////////////////////////
// Index + Data Collection //
/////////////////////////////
/** Return an array of paths (as strings) corresponding to pages which match the query. */
pagePaths ( query ) {
return this . api . pagePaths ( query , this . currentFilePath ) ;
}
/** Map a page path to the actual data contained within that page. */
page ( path ) {
return this . api . page ( path , this . currentFilePath ) ;
}
/** Return an array of page objects corresponding to pages which match the query. */
pages ( query ) {
return this . api . pages ( query , this . currentFilePath ) ;
}
/** Return the information about the current page. */
current ( ) {
return this . page ( this . currentFilePath ) ;
}
/////////////
// Utility //
/////////////
/ * *
* Convert an input element or array into a Dataview data - array . If the input is already a data array ,
* it is returned unchanged .
* /
array ( raw ) {
return this . api . array ( raw ) ;
}
/** Return true if theg given value is a javascript array OR a dataview data array. */
isArray ( raw ) {
return this . api . isArray ( raw ) ;
}
/** Create a dataview file link to the given path. */
fileLink ( path , embed = false , display ) {
return Link . file ( path , embed , display ) ;
}
/** Attempt to extract a date from a string, link or date. */
date ( pathlike ) {
return this . api . date ( pathlike ) ;
}
/ * *
* Compare two arbitrary JavaScript values using Dataview ' s default comparison rules . Returns a negative value if
* a < b , 0 if a = b , and a positive value if a > b .
* /
compare ( a , b ) {
return Values . compareValue ( a , b ) ;
}
/** Return true if the two given JavaScript values are equal using Dataview's default comparison rules. */
equal ( a , b ) {
return this . compare ( a , b ) == 0 ;
}
/////////////////////////
// Rendering Functions //
/////////////////////////
/** Render an HTML element, containing arbitrary text. */
el ( el , text ) {
let wrapped = Values . wrapValue ( text ) ;
if ( wrapped === null || wrapped === undefined ) {
this . container . createEl ( el , { text } ) ;
return ;
}
let _el = this . container . createEl ( el ) ;
renderValue ( wrapped . value , _el , this . currentFilePath , this . component , this . settings , true ) ;
}
/** Render an HTML header; the level can be anything from 1 - 6. */
header ( level , text ) {
let headerType ;
switch ( level ) {
case 1 :
headerType = "h1" ;
break ;
case 2 :
headerType = "h2" ;
break ;
case 3 :
headerType = "h3" ;
break ;
case 4 :
headerType = "h4" ;
break ;
case 5 :
headerType = "h5" ;
break ;
case 6 :
headerType = "h6" ;
break ;
default :
throw new Error ( ` Invalid header level ${ level } ` ) ;
}
this . el ( headerType , text ) ;
}
/** Render an HTML paragraph, containing arbitrary text. */
paragraph ( text ) {
this . el ( "p" , text ) ;
}
/** Render an inline span, containing arbitrary text. */
span ( text ) {
this . el ( "span" , text ) ;
}
/ * *
* Render HTML from the output of a template "view" saved as a file in the vault .
* Takes a filename and arbitrary input data .
* /
view ( viewName , input ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Look for `${viewName}.js` first, then for `${viewName}/view.js`.
let simpleViewFile = this . app . metadataCache . getFirstLinkpathDest ( viewName + ".js" , this . currentFilePath ) ;
if ( simpleViewFile ) {
let contents = yield this . app . vault . read ( simpleViewFile ) ;
let func = new Function ( "dv" , "input" , contents ) ;
try {
// This may directly render, in which case it will likely return undefined or null.
let result = yield Promise . resolve ( func ( this , input ) ) ;
if ( result )
yield renderValue ( result , this . container , this . currentFilePath , this . component , this . settings , true ) ;
}
catch ( ex ) {
renderErrorPre ( this . container , ` Dataview: Failed to execute view ' ${ simpleViewFile . path } '. \n \n ${ ex } ` ) ;
}
return ;
}
// No `{viewName}.js`, so look for a folder instead.
let viewPath = ` ${ viewName } /view.js ` ;
let viewFile = this . app . metadataCache . getFirstLinkpathDest ( viewPath , this . currentFilePath ) ;
if ( ! viewFile ) {
renderErrorPre ( this . container , ` Dataview: custom view not found for ' ${ viewPath } ' or ' ${ viewName } .js'. ` ) ;
return ;
}
let viewContents = yield this . app . vault . read ( viewFile ) ;
let viewFunction = new Function ( "dv" , "input" , viewContents ) ;
try {
let result = yield Promise . resolve ( viewFunction ( this , input ) ) ;
if ( result )
yield renderValue ( result , this . container , this . currentFilePath , this . component , this . settings , true ) ;
}
catch ( ex ) {
renderErrorPre ( this . container , ` Dataview: Error while executing view ' ${ viewFile . path } '. \n \n ${ ex } ` ) ;
}
// Check for optional CSS.
let cssFile = this . app . metadataCache . getFirstLinkpathDest ( ` ${ viewName } /view.css ` , this . currentFilePath ) ;
if ( ! cssFile )
return ;
let cssContents = yield this . app . vault . read ( cssFile ) ;
this . container . createEl ( "style" , { text : cssContents , attr : { scope : " " } } ) ;
} ) ;
}
/** Render a dataview list of the given values. */
list ( values ) {
return this . api . list ( values , this . container , this . component , this . currentFilePath ) ;
}
/** Render a dataview table with the given headers, and the 2D array of values. */
table ( headers , values ) {
return this . api . table ( headers , values , this . container , this . component , this . currentFilePath ) ;
}
/** Render a dataview task view with the given tasks. */
taskList ( tasks , groupByFile = true ) {
return this . api . taskList ( tasks , groupByFile , this . container , this . component , this . currentFilePath ) ;
}
}
/ * *
* Evaluate a script where 'this' for the script is set to the given context . Allows you to define global variables .
* /
function evalInContext ( script , context ) {
return function ( ) {
return eval ( script ) ;
} . call ( context ) ;
}
/ * *
* Evaluate a script possibly asynchronously , if the script contains ` async/await ` blocks .
* /
function asyncEvalInContext ( script , context ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( script . includes ( "await" ) ) {
return evalInContext ( "(async () => { " + script + " })()" , context ) ;
}
else {
return Promise . resolve ( evalInContext ( script , context ) ) ;
}
} ) ;
}
/** Make a full API context which a script can be evaluted in. */
function makeApiContext ( index , component , app , settings , container , originFile ) {
return new DataviewInlineApi ( index , component , container , app , settings , originFile ) ;
}
class DataviewPlugin extends obsidian . Plugin {
onload ( ) {
var _a ;
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Settings initialization; write defaults first time around.
this . settings = Object . assign ( DEFAULT _SETTINGS , ( _a = ( yield this . loadData ( ) ) ) !== null && _a !== void 0 ? _a : { } ) ;
this . addSettingTab ( new DataviewSettingsTab ( this . app , this ) ) ;
this . index = FullIndex . create ( this . app . vault , this . app . metadataCache , this . app . metadataCache ) ;
this . api = new DataviewApi ( this . app , this . index , this . settings ) ;
// Dataview query language code blocks.
this . registerHighPriorityCodeblockProcessor ( "dataview" , ( source , el , ctx ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return this . dataview ( source , el , ctx , ctx . sourcePath ) ; } ) ) ;
// DataviewJS codeblocks.
this . registerHighPriorityCodeblockProcessor ( "dataviewjs" , ( source , el , ctx ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return this . dataviewjs ( source , el , ctx , ctx . sourcePath ) ; } ) ) ;
// Dataview inline queries.
this . registerPriorityMarkdownPostProcessor ( - 100 , ( el , ctx ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return this . dataviewInline ( el , ctx , ctx . sourcePath ) ; } ) ) ;
// Dataview inline-inline query fancy rendering. Runs at a low priority; should apply to Dataview views.
this . registerPriorityMarkdownPostProcessor ( 100 , ( el , ctx ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Allow for lame people to disable the pretty rendering.
if ( ! this . settings . prettyRenderInlineFields )
return ;
// Handle p, header elements explicitly (opt-in rather than opt-out for now).
for ( let p of el . findAllSelf ( "p,h1,h2,h3,h4,h5,h6,li,span" ) )
yield replaceInlineFields ( ctx , p , ctx . sourcePath , this . settings ) ;
} ) ) ;
// Run index initialization, which actually traverses the vault to index files.
if ( ! this . app . workspace . layoutReady ) {
this . app . workspace . onLayoutReady ( ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return this . index . initialize ( ) ; } ) ) ;
}
else {
this . index . initialize ( ) ;
}
// Not required anymore, though holding onto it for backwards-compatibility.
this . app . metadataCache . trigger ( "dataview:api-ready" , this . api ) ;
console . log ( "Dataview: Version 0.4.x Loaded" ) ;
} ) ;
}
onunload ( ) { }
registerPriorityMarkdownPostProcessor ( priority , processor ) {
let realProcessor = ( el , ctx ) => processor ( el , ctx ) ;
realProcessor . sortOrder = priority ;
this . registerMarkdownPostProcessor ( realProcessor ) ;
}
/ * *
* Utility function for registering high priority codeblocks which run before any other post processing , such as
* emoji - twitter .
* /
registerHighPriorityCodeblockProcessor ( language , processor ) {
this . registerPriorityMarkdownPostProcessor ( - 100 , ( el , ctx ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let codeblocks = el . querySelectorAll ( "pre > code" ) ;
if ( ! codeblocks )
return ;
for ( let index = 0 ; index < codeblocks . length ; index ++ ) {
let codeblock = codeblocks . item ( index ) ;
let clanguages = Array . from ( codeblock . classList )
. filter ( c => c . startsWith ( "language-" ) )
. map ( c => c . substring ( "language-" . length ) ) ;
clanguages = clanguages . concat ( Array . from ( codeblock . classList )
. filter ( c => c . startsWith ( ":" ) )
. map ( c => c . substring ( ":" . length ) ) ) ;
if ( ! clanguages . contains ( language ) )
continue ;
if ( ! codeblock . parentElement )
continue ;
let code = codeblock . innerText ;
// We know the parent element is a pre, replace it.
let replacement = document . createElement ( "div" ) ;
codeblock . parentElement . replaceWith ( replacement ) ;
yield processor ( code , replacement , ctx ) ;
}
} ) ) ;
}
/ * *
* Based on the source , generate a dataview view . This works by doing an initial parsing pass , and then adding
* a long - lived view object to the given component for life - cycle management .
* /
dataview ( source , el , component , sourcePath ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let maybeQuery = tryOrPropogate ( ( ) => parseQuery ( source ) ) ;
// In case of parse error, just render the error.
if ( ! maybeQuery . successful ) {
renderErrorPre ( el , "Dataview: " + maybeQuery . error ) ;
return ;
}
let query = maybeQuery . value ;
switch ( query . header . type ) {
case "task" :
component . addChild ( new DataviewTaskRenderer ( query , el , this . index , sourcePath , this . app . vault , this . settings ) ) ;
break ;
case "list" :
component . addChild ( new DataviewListRenderer ( query , el , this . index , sourcePath , this . settings ) ) ;
break ;
case "table" :
component . addChild ( new DataviewTableRenderer ( query , el , this . index , sourcePath , this . settings ) ) ;
break ;
}
} ) ;
}
/** Generate a DataviewJS view running the given source in the given element. */
dataviewjs ( source , el , component , sourcePath ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
component . addChild ( new DataviewJSRenderer ( source , el , this . app , this . index , sourcePath , this . settings ) ) ;
} ) ;
}
/** Render all dataview inline expressions in the given element. */
dataviewInline ( el , component , sourcePath ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
// Search for <code> blocks inside this element; for each one, look for things of the form `= ...`.
let codeblocks = el . querySelectorAll ( "code" ) ;
for ( let index = 0 ; index < codeblocks . length ; index ++ ) {
let codeblock = codeblocks . item ( index ) ;
let text = codeblock . innerText . trim ( ) ;
if ( text . startsWith ( this . settings . inlineJsQueryPrefix ) ) {
let code = text . substring ( this . settings . inlineJsQueryPrefix . length ) . trim ( ) ;
component . addChild ( new DataviewInlineJSRenderer ( code , el , codeblock , this . app , this . index , sourcePath , this . settings ) ) ;
}
else if ( text . startsWith ( this . settings . inlineQueryPrefix ) ) {
let potentialField = text . substring ( this . settings . inlineQueryPrefix . length ) . trim ( ) ;
let field = tryOrPropogate ( ( ) => parseField ( potentialField ) ) ;
if ( ! field . successful ) {
let errorBlock = el . createEl ( "div" ) ;
renderErrorPre ( errorBlock , ` Dataview (inline field ' ${ potentialField } '): ${ field . error } ` ) ;
}
else {
let fieldValue = field . value ;
component . addChild ( new DataviewInlineRenderer ( fieldValue , text , el , codeblock , this . index , sourcePath , this . settings ) ) ;
}
}
}
} ) ;
}
/** Update plugin settings. */
updateSettings ( settings ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
Object . assign ( this . settings , settings ) ;
yield this . saveData ( this . settings ) ;
} ) ;
}
/** Call the given callback when the dataview API has initialized. */
withApi ( callback ) {
callback ( this . api ) ;
}
}
/** All of the dataview settings in a single, nice tab. */
class DataviewSettingsTab extends obsidian . PluginSettingTab {
constructor ( app , plugin ) {
super ( app , plugin ) ;
this . plugin = plugin ;
}
display ( ) {
this . containerEl . empty ( ) ;
this . containerEl . createEl ( "h2" , { text : "General Settings" } ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Enable JavaScript Queries" )
. setDesc ( "Enable or disable executing DataviewJS queries." )
. addToggle ( toggle => toggle
. setValue ( this . plugin . settings . enableDataviewJs )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return yield this . plugin . updateSettings ( { enableDataviewJs : value } ) ; } ) ) ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Enable Inline JavaScript Queries" )
. setDesc ( "Enable or disable executing inline DataviewJS queries. Requires that DataviewJS queries are enabled." )
. addToggle ( toggle => toggle
. setValue ( this . plugin . settings . enableInlineDataviewJs )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return yield this . plugin . updateSettings ( { enableInlineDataviewJs : value } ) ; } ) ) ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Enable Inline Field Highlighting" )
. setDesc ( "Enables or disables visual highlighting / pretty rendering for inline fields." )
. addToggle ( toggle => toggle
. setValue ( this . plugin . settings . prettyRenderInlineFields )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return yield this . plugin . updateSettings ( { prettyRenderInlineFields : value } ) ; } ) ) ) ;
this . containerEl . createEl ( "h2" , { text : "Codeblock Settings" } ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Inline Query Prefix" )
. setDesc ( "The prefix to inline queries (to mark them as Dataview queries). Defaults to '='." )
. addText ( text => text
. setPlaceholder ( "=" )
. setValue ( this . plugin . settings . inlineQueryPrefix )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return yield this . plugin . updateSettings ( { inlineQueryPrefix : value } ) ; } ) ) ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "JavaScript Inline Query Prefix" )
. setDesc ( "The prefix to JavaScript inline queries (to mark them as DataviewJS queries). Defaults to '$='." )
. addText ( text => text
. setPlaceholder ( "$=" )
. setValue ( this . plugin . settings . inlineJsQueryPrefix )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) { return yield this . plugin . updateSettings ( { inlineJsQueryPrefix : value } ) ; } ) ) ) ;
this . containerEl . createEl ( "h2" , { text : "View Settings" } ) ;
this . containerEl . createEl ( "h3" , { text : "General" } ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Warn on Empty Result" )
. setDesc ( "If set, queries which return 0 results will render a warning message." )
. addToggle ( toggle => toggle . setValue ( this . plugin . settings . warnOnEmptyResult ) . onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . plugin . updateSettings ( { warnOnEmptyResult : value } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Render Null As" )
. setDesc ( "What null/non-existent should show up as in tables, by default. This supports Markdown notation." )
. addText ( text => text
. setPlaceholder ( "-" )
. setValue ( this . plugin . settings . renderNullAs )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . plugin . updateSettings ( { renderNullAs : value } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Refresh Interval" )
. setDesc ( "How frequently views are updated (in milliseconds) in preview mode when files are changing." )
. addText ( text => text
. setPlaceholder ( "500" )
. setValue ( "" + this . plugin . settings . refreshInterval )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let parsed = parseInt ( value ) ;
if ( isNaN ( parsed ) )
return ;
parsed = parsed < 100 ? 100 : parsed ;
yield this . plugin . updateSettings ( { refreshInterval : parsed } ) ;
} ) ) ) ;
let dformat = new obsidian . Setting ( this . containerEl )
. setName ( "Date Format" )
. setDesc ( "The default date format (see Luxon date format options)." +
" Currently: " +
DateTime _1 . now ( ) . toFormat ( this . plugin . settings . defaultDateFormat , { locale : currentLocale ( ) } ) )
. addText ( text => text
. setPlaceholder ( DEFAULT _QUERY _SETTINGS . defaultDateFormat )
. setValue ( this . plugin . settings . defaultDateFormat )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
dformat . setDesc ( "The default date format (see Luxon date format options)." +
" Currently: " +
DateTime _1 . now ( ) . toFormat ( value , { locale : currentLocale ( ) } ) ) ;
yield this . plugin . updateSettings ( { defaultDateFormat : value } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
let dtformat = new obsidian . Setting ( this . containerEl )
. setName ( "Date + Time Format" )
. setDesc ( "The default date and time format (see Luxon date format options)." +
" Currently: " +
DateTime _1 . now ( ) . toFormat ( this . plugin . settings . defaultDateTimeFormat , { locale : currentLocale ( ) } ) )
. addText ( text => text
. setPlaceholder ( DEFAULT _QUERY _SETTINGS . defaultDateTimeFormat )
. setValue ( this . plugin . settings . defaultDateTimeFormat )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
dtformat . setDesc ( "The default date and time format (see Luxon date format options)." +
" Currently: " +
DateTime _1 . now ( ) . toFormat ( value , { locale : currentLocale ( ) } ) ) ;
yield this . plugin . updateSettings ( { defaultDateTimeFormat : value } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
this . containerEl . createEl ( "h3" , { text : "Table Settings" } ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Primary Column Name" )
. setDesc ( "The name of the default ID column in tables; this is the auto-generated first column that links to the source file." )
. addText ( text => text
. setPlaceholder ( "File" )
. setValue ( this . plugin . settings . tableIdColumnName )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . plugin . updateSettings ( { tableIdColumnName : value } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Grouped Column Name" )
. setDesc ( "The name of the default ID column in tables, when the table is on grouped data; this is the auto-generated first column" +
"that links to the source file/group." )
. addText ( text => text
. setPlaceholder ( "Group" )
. setValue ( this . plugin . settings . tableGroupColumnName )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . plugin . updateSettings ( { tableGroupColumnName : value } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
this . containerEl . createEl ( "h3" , { text : "Task Settings" } ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Task Link Type" )
. setDesc ( "'Start' and 'End' place a symbol link in their respective location; 'None' disables linking." )
. addDropdown ( dropdown => dropdown
. addOption ( "start" , "Start" )
. addOption ( "end" , "End" )
. addOption ( "none" , "None" )
. setValue ( this . plugin . settings . taskLinkLocation )
. onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . plugin . updateSettings ( { taskLinkLocation : value } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
new obsidian . Setting ( this . containerEl )
. setName ( "Render Task Links As" )
. setDesc ( "Text used when linking from a task to its source note in the 'Start' and 'End' link types." )
. addText ( text => text . setValue ( this . plugin . settings . taskLinkText ) . onChange ( ( value ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . plugin . updateSettings ( { taskLinkText : value . trim ( ) } ) ;
this . plugin . index . touch ( ) ;
} ) ) ) ;
}
}
/** Renders a list dataview for the given query. */
class DataviewListRenderer extends obsidian . MarkdownRenderChild {
constructor ( query , container , index , origin , settings ) {
super ( container ) ;
this . query = query ;
this . container = container ;
this . index = index ;
this . origin = origin ;
this . settings = settings ;
}
onload ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . render ( ) ;
onIndexChange ( this . index , this . settings . refreshInterval , this , ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
this . container . innerHTML = "" ;
yield this . render ( ) ;
} ) ) ;
} ) ;
}
render ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let maybeResult = yield asyncTryOrPropogate ( ( ) => executeList ( this . query , this . index , this . origin , this . settings ) ) ;
if ( ! maybeResult . successful ) {
renderErrorPre ( this . container , "Dataview: " + maybeResult . error ) ;
return ;
}
else if ( maybeResult . value . data . length == 0 && this . settings . warnOnEmptyResult ) {
renderErrorPre ( this . container , "Dataview: Query returned 0 results." ) ;
return ;
}
let showId = this . query . header . showId ;
let showValue = ! ! this . query . header . format ;
let result = maybeResult . value ;
let rendered = [ ] ;
for ( let row of result . data ) {
if ( showValue && showId ) {
let span = document . createElement ( "span" ) ;
yield renderValue ( row . primary , span , this . origin , this , this . settings , false , "list" ) ;
span . appendText ( ": " ) ;
yield renderValue ( row . value || null , span , this . origin , this , this . settings , true , "list" ) ;
rendered . push ( span ) ;
}
else if ( showId ) {
rendered . push ( row . primary ) ;
}
else if ( showValue ) {
rendered . push ( row . value || null ) ;
}
}
yield renderList ( this . container , rendered , this , this . origin , this . settings ) ;
} ) ;
}
}
class DataviewTableRenderer extends obsidian . MarkdownRenderChild {
constructor ( query , container , index , origin , settings ) {
super ( container ) ;
this . query = query ;
this . container = container ;
this . index = index ;
this . origin = origin ;
this . settings = settings ;
}
onload ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . render ( ) ;
onIndexChange ( this . index , this . settings . refreshInterval , this , ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
this . container . innerHTML = "" ;
yield this . render ( ) ;
} ) ) ;
} ) ;
}
render ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let maybeResult = yield asyncTryOrPropogate ( ( ) => executeTable ( this . query , this . index , this . origin , this . settings ) ) ;
if ( ! maybeResult . successful ) {
renderErrorPre ( this . container , "Dataview: " + maybeResult . error ) ;
return ;
}
let result = maybeResult . value ;
if ( this . query . header . showId ) {
let dataWithNames = [ ] ;
for ( let entry of result . data ) {
dataWithNames . push ( [ entry . id ] . concat ( entry . values ) ) ;
}
let name = result . idMeaning . type === "group"
? this . settings . tableGroupColumnName
: this . settings . tableIdColumnName ;
yield renderTable ( this . container , [ name ] . concat ( result . names ) , dataWithNames , this , this . origin , this . settings ) ;
}
else {
yield renderTable ( this . container , result . names , result . data . map ( v => v . values ) , this , this . origin , this . settings ) ;
}
// Render after the empty table, so the table header still renders.
if ( result . data . length == 0 && this . settings . warnOnEmptyResult ) {
renderErrorPre ( this . container , "Dataview: Query returned 0 results." ) ;
}
} ) ;
}
}
class DataviewTaskRenderer extends obsidian . MarkdownRenderChild {
constructor ( query , container , index , origin , vault , settings ) {
super ( container ) ;
this . query = query ;
this . container = container ;
this . index = index ;
this . origin = origin ;
this . vault = vault ;
this . settings = settings ;
}
onload ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . render ( ) ;
onIndexChange ( this . index , this . settings . refreshInterval , this , ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( this . taskBindings )
this . removeChild ( this . taskBindings ) ;
this . container . innerHTML = "" ;
yield this . render ( ) ;
} ) ) ;
} ) ;
}
render ( ) {
var _a ;
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let result = yield asyncTryOrPropogate ( ( ) => executeTask ( this . query , this . origin , this . index , this . settings ) ) ;
if ( ! result . successful ) {
renderErrorPre ( this . container , "Dataview: " + result . error ) ;
}
else {
// If there is no grouping going on, group by the file path by default.
let tasks = result . value . tasks ;
if ( tasks . type == "base" ) {
let byFile = new Map ( ) ;
for ( let task of tasks . value ) {
if ( ! byFile . has ( task . path ) )
byFile . set ( task . path , [ ] ) ;
( _a = byFile . get ( task . path ) ) === null || _a === void 0 ? void 0 : _a . push ( task ) ;
}
tasks = Groupings . grouped ( Array . from ( byFile . entries ( ) ) . map ( ( [ path , tasks ] ) => {
return { key : Link . file ( path ) , value : Groupings . base ( tasks ) } ;
} ) ) ;
}
this . taskBindings = new obsidian . Component ( ) ;
this . addChild ( this . taskBindings ) ;
yield renderTasks ( this . container , tasks , this . origin , this . taskBindings , this . vault , this . settings ) ;
}
} ) ;
}
}
/** Renders inline query results. */
class DataviewInlineRenderer extends obsidian . MarkdownRenderChild {
constructor ( field , fieldText , container , target , index , origin , settings ) {
super ( container ) ;
this . field = field ;
this . fieldText = fieldText ;
this . container = container ;
this . target = target ;
this . index = index ;
this . origin = origin ;
this . settings = settings ;
}
onload ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . render ( ) ;
onIndexChange ( this . index , this . settings . refreshInterval , this , ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
var _a ;
( _a = this . errorbox ) === null || _a === void 0 ? void 0 : _a . remove ( ) ;
yield this . render ( ) ;
} ) ) ;
} ) ;
}
render ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let result = tryOrPropogate ( ( ) => executeInline ( this . field , this . origin , this . index , this . settings ) ) ;
if ( ! result . successful ) {
this . errorbox = this . container . createEl ( "div" ) ;
renderErrorPre ( this . errorbox , "Dataview (for inline query '" + this . fieldText + "'): " + result . error ) ;
}
else {
let temp = document . createElement ( "span" ) ;
yield renderValue ( result . value , temp , this . origin , this , this . settings , false ) ;
this . target . replaceWith ( temp ) ;
}
} ) ;
}
}
class DataviewJSRenderer extends obsidian . MarkdownRenderChild {
constructor ( script , container , app , index , origin , settings ) {
super ( container ) ;
this . script = script ;
this . container = container ;
this . app = app ;
this . index = index ;
this . origin = origin ;
this . settings = settings ;
}
onload ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . render ( ) ;
onIndexChange ( this . index , this . settings . refreshInterval , this , ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
this . container . innerHTML = "" ;
yield this . render ( ) ;
} ) ) ;
} ) ;
}
render ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( ! this . settings . enableDataviewJs ) {
this . containerEl . innerHTML = "" ;
renderErrorPre ( this . container , "Dataview JS queries are disabled. You can enable them in the Dataview settings." ) ;
return ;
}
// Assume that the code is javascript, and try to eval it.
try {
yield asyncEvalInContext ( DataviewJSRenderer . PREAMBLE + this . script , makeApiContext ( this . index , this , this . app , this . settings , this . container , this . origin ) ) ;
}
catch ( e ) {
this . containerEl . innerHTML = "" ;
renderErrorPre ( this . container , "Evaluation Error: " + e . stack ) ;
}
} ) ;
}
}
DataviewJSRenderer . PREAMBLE = "const dataview = this;const dv = this;" ;
/** Inline JS renderer accessible using '=$' by default. */
class DataviewInlineJSRenderer extends obsidian . MarkdownRenderChild {
constructor ( script , container , target , app , index , origin , settings ) {
super ( container ) ;
this . script = script ;
this . container = container ;
this . target = target ;
this . app = app ;
this . index = index ;
this . origin = origin ;
this . settings = settings ;
}
onload ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
yield this . render ( ) ;
onIndexChange ( this . index , this . settings . refreshInterval , this , ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
var _a ;
( _a = this . errorbox ) === null || _a === void 0 ? void 0 : _a . remove ( ) ;
yield this . render ( ) ;
} ) ) ;
} ) ;
}
render ( ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( ! this . settings . enableDataviewJs || ! this . settings . enableInlineDataviewJs ) {
let temp = document . createElement ( "span" ) ;
temp . innerText = "(disabled; enable in settings)" ;
this . target . replaceWith ( temp ) ;
this . target = temp ;
return ;
}
// Assume that the code is javascript, and try to eval it.
try {
let temp = document . createElement ( "span" ) ;
let result = yield asyncEvalInContext ( DataviewInlineJSRenderer . PREAMBLE + this . script , makeApiContext ( this . index , this , this . app , this . settings , temp , this . origin ) ) ;
this . target . replaceWith ( temp ) ;
this . target = temp ;
if ( result === undefined )
return ;
renderValue ( result , temp , this . origin , this , this . settings , false ) ;
}
catch ( e ) {
this . errorbox = this . container . createEl ( "div" ) ;
renderErrorPre ( this . errorbox , "Dataview (for inline JS query '" + this . script + "'): " + e ) ;
}
} ) ;
}
}
DataviewInlineJSRenderer . PREAMBLE = "const dataview = this;const dv=this;" ;
/** Adds a simple handler which runs the given action on any index update. */
function onIndexChange ( index , interval , component , action ) {
let lastReload = index . revision ;
component . registerInterval ( window . setInterval ( ( ) => {
// If the index revision has changed recently, then queue a reload.
if ( lastReload != index . revision ) {
action ( ) ;
lastReload = index . revision ;
}
} , interval ) ) ;
}
/** Replaces raw textual inline fields in text containers with pretty HTML equivalents. */
function replaceInlineFields ( ctx , container , originFile , settings ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let inlineFields = extractInlineFields ( container . innerHTML ) ;
if ( inlineFields . length == 0 )
return undefined ;
let component = new obsidian . MarkdownRenderChild ( container ) ;
ctx . addChild ( component ) ;
let result = container . innerHTML ;
for ( let x = inlineFields . length - 1 ; x >= 0 ; x -- ) {
let field = inlineFields [ x ] ;
let renderContainer = document . createElement ( "span" ) ;
renderContainer . addClasses ( [ "dataview" , "inline-field" ] ) ;
// Block inline fields render the key, parenthesis ones do not.
if ( field . wrapping == "[" ) {
renderContainer . createSpan ( { text : field . key , cls : [ "dataview" , "inline-field-key" ] } ) ;
let valueContainer = renderContainer . createSpan ( { cls : [ "dataview" , "inline-field-value" ] } ) ;
yield renderValue ( parseInlineValue ( field . value ) , valueContainer , originFile , component , settings , false ) ;
}
else {
let valueContainer = renderContainer . createSpan ( { cls : [ "dataview" , "inline-field-standalone-value" ] } ) ;
yield renderValue ( parseInlineValue ( field . value ) , valueContainer , originFile , component , settings , false ) ;
}
result = result . slice ( 0 , field . start ) + renderContainer . outerHTML + result . slice ( field . end ) ;
}
container . innerHTML = result ;
return component ;
} ) ;
}
module . exports = DataviewPlugin ;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsiLi4vbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIi4uL25vZGVfbW9kdWxlcy9sdXhvbi9idWlsZC9janMtYnJvd3Nlci9sdXhvbi5qcyIsIi4uL3NyYy9zZXR0aW5ncy50cyIsIi4uL3NyYy9hcGkvcmVzdWx0LnRzIiwiLi4vbm9kZV9tb2R1bGVzL3BhcnNpbW1vbi9idWlsZC9wYXJzaW1tb24udW1kLm1pbi5qcyIsIi4uL25vZGVfbW9kdWxlcy9lbW9qaS1yZWdleC9pbmRleC5qcyIsIi4uL3NyYy91dGlsL25vcm1hbGl6ZS50cyIsIi4uL3NyYy9kYXRhL3ZhbHVlLnRzIiwiLi4vc3JjL2FwaS9kYXRhLWFycmF5LnRzIiwiLi4vc3JjL3V0aWwvbG9jYWxlLnRzIiwiLi4vc3JjL3VpL3JlbmRlci50cyIsIi4uL3NyYy9leHByZXNzaW9uL2ZpZWxkLnRzIiwiLi4vc3JjL2RhdGEvc291cmNlLnRzIiwiLi4vc3JjL2V4cHJlc3Npb24vcGFyc2UudHMiLCIuLi9zcmMvZGF0YS9wYXJzZS9pbmxpbmUtZmllbGQudHMiLCIuLi9zcmMvZGF0YS9tZXRhZGF0YS50cyIsIi4uL3NyYy9kYXRhL3BhcnNlL21hcmtkb3duLnRzIiwiLi4vbm9kZV9tb2R1bGVzL3BhcGFwYXJzZS9wYXBhcGFyc2UubWluLmpzIiwiLi4vc3JjL2RhdGEvcGFyc2UvY3N2LnRzIiwiLi4vc3JjL2RhdGEvdHJhbnNmZXJhYmxlLnRzIiwiLi4vc3JjL2RhdGEvaW1wb3J0L2ltcG9ydC1tYW5hZ2VyLnRzIiwiLi4vc3JjL2RhdGEvaW5kZXgudHMiLCIuLi9zcmMvdWkvdGFza3MudHMiLCIuLi9zcmMvcXVlcnkvcXVlcnkudHMiLCIuLi9zcmMvcXVlcnkvcGFyc2UudHMiLCIuLi9zcmMvZXhwcmVzc2lvbi9iaW5hcnlvcC50cyIsIi4uL3NyYy9leHByZXNzaW9uL2Z1bmN0aW9ucy50cyIsIi4uL3NyYy9leHByZXNzaW9uL2NvbnRleHQudHMiLCIuLi9zcmMvZGF0YS9yZXNvbHZlci50cyIsIi4uL3NyYy9xdWVyeS9lbmdpbmUudHMiLCIuLi9zcmMvYXBpL3BsdWdpbi1hcGkudHMiLCIuLi9zcmMvYXBpL2lubGluZS1hcGkudHMiLCIuLi9zcmMvbWFpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6bnVsbCwibmFtZXMiOlsidGhpcyIsIkRhdGVUaW1lIiwiUC5hbHQiLCJQLnJlZ2V4IiwiUC53aGl0ZXNwYWNlIiwiUC5hbnkiLCJEdXJhdGlvbiIsIk1hcmtkb3duUmVuZGVyZXIiLCJQLnNlcU1hcCIsIlAuc2VxIiwiUC5vcHRXaGl0ZXNwYWNlIiwiUC5jdXN0b20iLCJQLmNyZWF0ZUxhbmd1YWdlIiwiUC5yZWdleHAiLCJQLnN0cmluZyIsIlAubm9uZU9mIiwiUC5zdWNjZWVkIiwiUC5mYWlsIiwiZ2V0QWxsVGFncyIsInBhcnNlRnJvbnRNYXR0ZXJUYWdzIiwicGFyc2VGcm9udE1hdHRlckFsaWFzZXMiLCJQYXBhLnBhcnNlIiwiRGF0YXZpZXdJbXBvcnRXb3JrZXIiLCJURmlsZSIsIkNvbXBvbmVudCIsIlAuc2VwQnkiLCJQbHVnaW4iLCJQbHVnaW5TZXR0aW5nVGFiIiwiU2V0dGluZyIsIk1hcmtkb3duUmVuZGVyQ2hpbGQiLCJUYXNrcy5yZW5kZXJUYXNrcyJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF1REE7QUFDTyxTQUFTLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUU7QUFDN0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEtBQUssWUFBWSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTyxFQUFFLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDaEgsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxVQUFVLE9BQU8sRUFBRSxNQUFNLEVBQUU7QUFDL0QsUUFBUSxTQUFTLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ25HLFFBQVEsU0FBUyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ3RHLFFBQVEsU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQyxFQUFFO0FBQ3RILFFBQVEsSUFBSSxDQUFDLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFVBQVUsSUFBSSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzlFLEtBQUssQ0FBQyxDQUFDO0FBQ1A7Ozs7OztBQzNFQSxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQU8sRUFBRSxZQUFZLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUM5RDtBQUNBLFNBQVMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtBQUMxQyxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3pDLElBQUksSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlCLElBQUksVUFBVSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsVUFBVSxJQUFJLEtBQUssQ0FBQztBQUMzRCxJQUFJLFVBQVUsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0FBQ25DLElBQUksSUFBSSxPQUFPLElBQUksVUFBVSxFQUFFLFVBQVUsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQzFELElBQUksTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM5RCx