2023-03-02 21:47:11 +00:00
'use strict' ;
var obsidian = require ( 'obsidian' ) ;
2023-04-03 20:35:26 +00:00
var state = require ( '@codemirror/state' ) ;
2023-03-02 21:47:11 +00:00
var view = require ( '@codemirror/view' ) ;
2023-08-21 17:47:20 +00:00
var language = require ( '@codemirror/language' ) ;
2023-03-02 21:47:11 +00:00
function noop ( ) { }
function run ( fn ) {
return fn ( ) ;
}
function blank _object ( ) {
return Object . create ( null ) ;
}
function run _all ( fns ) {
fns . forEach ( run ) ;
}
function is _function ( thing ) {
return typeof thing === 'function' ;
}
function safe _not _equal ( a , b ) {
return a != a ? b == b : a !== b || ( ( a && typeof a === 'object' ) || typeof a === 'function' ) ;
}
function is _empty ( obj ) {
return Object . keys ( obj ) . length === 0 ;
}
function append ( target , node ) {
target . appendChild ( node ) ;
}
function insert ( target , node , anchor ) {
target . insertBefore ( node , anchor || null ) ;
}
function detach ( node ) {
if ( node . parentNode ) {
node . parentNode . removeChild ( node ) ;
}
}
function destroy _each ( iterations , detaching ) {
for ( let i = 0 ; i < iterations . length ; i += 1 ) {
if ( iterations [ i ] )
iterations [ i ] . d ( detaching ) ;
}
}
function element ( name ) {
return document . createElement ( name ) ;
}
function text ( data ) {
return document . createTextNode ( data ) ;
}
function space ( ) {
return text ( ' ' ) ;
}
function listen ( node , event , handler , options ) {
node . addEventListener ( event , handler , options ) ;
return ( ) => node . removeEventListener ( event , handler , options ) ;
}
function attr ( node , attribute , value ) {
if ( value == null )
node . removeAttribute ( attribute ) ;
else if ( node . getAttribute ( attribute ) !== value )
node . setAttribute ( attribute , value ) ;
}
function children ( element ) {
return Array . from ( element . childNodes ) ;
}
function set _data ( text , data ) {
data = '' + data ;
2023-08-21 17:47:20 +00:00
if ( text . data === data )
return ;
text . data = data ;
2023-03-02 21:47:11 +00:00
}
2023-04-03 20:35:26 +00:00
function select _option ( select , value , mounting ) {
2023-03-02 21:47:11 +00:00
for ( let i = 0 ; i < select . options . length ; i += 1 ) {
const option = select . options [ i ] ;
if ( option . _ _value === value ) {
option . selected = true ;
return ;
}
}
2023-04-03 20:35:26 +00:00
if ( ! mounting || value !== undefined ) {
select . selectedIndex = - 1 ; // no option should be selected
}
2023-03-02 21:47:11 +00:00
}
let current _component ;
function set _current _component ( component ) {
current _component = component ;
}
const dirty _components = [ ] ;
const binding _callbacks = [ ] ;
2023-04-03 20:35:26 +00:00
let render _callbacks = [ ] ;
2023-03-02 21:47:11 +00:00
const flush _callbacks = [ ] ;
2023-04-03 20:35:26 +00:00
const resolved _promise = /* @__PURE__ */ Promise . resolve ( ) ;
2023-03-02 21:47:11 +00:00
let update _scheduled = false ;
function schedule _update ( ) {
if ( ! update _scheduled ) {
update _scheduled = true ;
resolved _promise . then ( flush ) ;
}
}
function add _render _callback ( fn ) {
render _callbacks . push ( fn ) ;
}
// flush() calls callbacks in this order:
// 1. All beforeUpdate callbacks, in order: parents before children
// 2. All bind:this callbacks, in reverse order: children before parents.
// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
// for afterUpdates called during the initial onMount, which are called in
// reverse order: children before parents.
// Since callbacks might update component values, which could trigger another
// call to flush(), the following steps guard against this:
// 1. During beforeUpdate, any updated components will be added to the
// dirty_components array and will cause a reentrant call to flush(). Because
// the flush index is kept outside the function, the reentrant call will pick
// up where the earlier call left off and go through all dirty components. The
// current_component value is saved and restored so that the reentrant call will
// not interfere with the "parent" flush() call.
// 2. bind:this callbacks cannot trigger new flush() calls.
// 3. During afterUpdate, any updated components will NOT have their afterUpdate
// callback called a second time; the seen_callbacks set, outside the flush()
// function, guarantees this behavior.
const seen _callbacks = new Set ( ) ;
let flushidx = 0 ; // Do *not* move this inside the flush() function
function flush ( ) {
// Do not reenter flush while dirty components are updated, as this can
// result in an infinite loop. Instead, let the inner flush handle it.
// Reentrancy is ok afterwards for bindings etc.
if ( flushidx !== 0 ) {
return ;
}
const saved _component = current _component ;
do {
// first, call beforeUpdate functions
// and update components
try {
while ( flushidx < dirty _components . length ) {
const component = dirty _components [ flushidx ] ;
flushidx ++ ;
set _current _component ( component ) ;
update ( component . $$ ) ;
}
}
catch ( e ) {
// reset dirty state to not end up in a deadlocked state and then rethrow
dirty _components . length = 0 ;
flushidx = 0 ;
throw e ;
}
set _current _component ( null ) ;
dirty _components . length = 0 ;
flushidx = 0 ;
while ( binding _callbacks . length )
binding _callbacks . pop ( ) ( ) ;
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
for ( let i = 0 ; i < render _callbacks . length ; i += 1 ) {
const callback = render _callbacks [ i ] ;
if ( ! seen _callbacks . has ( callback ) ) {
// ...so guard against infinite loops
seen _callbacks . add ( callback ) ;
callback ( ) ;
}
}
render _callbacks . length = 0 ;
} while ( dirty _components . length ) ;
while ( flush _callbacks . length ) {
flush _callbacks . pop ( ) ( ) ;
}
update _scheduled = false ;
seen _callbacks . clear ( ) ;
set _current _component ( saved _component ) ;
}
function update ( $$ ) {
if ( $$ . fragment !== null ) {
$$ . update ( ) ;
run _all ( $$ . before _update ) ;
const dirty = $$ . dirty ;
$$ . dirty = [ - 1 ] ;
$$ . fragment && $$ . fragment . p ( $$ . ctx , dirty ) ;
$$ . after _update . forEach ( add _render _callback ) ;
}
}
2023-04-03 20:35:26 +00:00
/ * *
* Useful for example to execute remaining ` afterUpdate ` callbacks before executing ` destroy ` .
* /
function flush _render _callbacks ( fns ) {
const filtered = [ ] ;
const targets = [ ] ;
render _callbacks . forEach ( ( c ) => fns . indexOf ( c ) === - 1 ? filtered . push ( c ) : targets . push ( c ) ) ;
targets . forEach ( ( c ) => c ( ) ) ;
render _callbacks = filtered ;
}
2023-03-02 21:47:11 +00:00
const outroing = new Set ( ) ;
function transition _in ( block , local ) {
if ( block && block . i ) {
outroing . delete ( block ) ;
block . i ( local ) ;
}
}
function mount _component ( component , target , anchor , customElement ) {
const { fragment , after _update } = component . $$ ;
fragment && fragment . m ( target , anchor ) ;
if ( ! customElement ) {
// onMount happens before the initial afterUpdate
add _render _callback ( ( ) => {
const new _on _destroy = component . $$ . on _mount . map ( run ) . filter ( is _function ) ;
// if the component was destroyed immediately
// it will update the `$$.on_destroy` reference to `null`.
// the destructured on_destroy may still reference to the old array
if ( component . $$ . on _destroy ) {
component . $$ . on _destroy . push ( ... new _on _destroy ) ;
}
else {
// Edge case - component was destroyed immediately,
// most likely as a result of a binding initialising
run _all ( new _on _destroy ) ;
}
component . $$ . on _mount = [ ] ;
} ) ;
}
after _update . forEach ( add _render _callback ) ;
}
function destroy _component ( component , detaching ) {
const $$ = component . $$ ;
if ( $$ . fragment !== null ) {
2023-04-03 20:35:26 +00:00
flush _render _callbacks ( $$ . after _update ) ;
2023-03-02 21:47:11 +00:00
run _all ( $$ . on _destroy ) ;
$$ . fragment && $$ . fragment . d ( detaching ) ;
// TODO null out other refs, including component.$$ (but need to
// preserve final state?)
$$ . on _destroy = $$ . fragment = null ;
$$ . ctx = [ ] ;
}
}
function make _dirty ( component , i ) {
if ( component . $$ . dirty [ 0 ] === - 1 ) {
dirty _components . push ( component ) ;
schedule _update ( ) ;
component . $$ . dirty . fill ( 0 ) ;
}
component . $$ . dirty [ ( i / 31 ) | 0 ] |= ( 1 << ( i % 31 ) ) ;
}
function init ( component , options , instance , create _fragment , not _equal , props , append _styles , dirty = [ - 1 ] ) {
const parent _component = current _component ;
set _current _component ( component ) ;
const $$ = component . $$ = {
fragment : null ,
ctx : [ ] ,
// state
props ,
update : noop ,
not _equal ,
bound : blank _object ( ) ,
// lifecycle
on _mount : [ ] ,
on _destroy : [ ] ,
on _disconnect : [ ] ,
before _update : [ ] ,
after _update : [ ] ,
context : new Map ( options . context || ( parent _component ? parent _component . $$ . context : [ ] ) ) ,
// everything else
callbacks : blank _object ( ) ,
dirty ,
skip _bound : false ,
root : options . target || parent _component . $$ . root
} ;
append _styles && append _styles ( $$ . root ) ;
let ready = false ;
$$ . ctx = instance
? instance ( component , options . props || { } , ( i , ret , ... rest ) => {
const value = rest . length ? rest [ 0 ] : ret ;
if ( $$ . ctx && not _equal ( $$ . ctx [ i ] , $$ . ctx [ i ] = value ) ) {
if ( ! $$ . skip _bound && $$ . bound [ i ] )
$$ . bound [ i ] ( value ) ;
if ( ready )
make _dirty ( component , i ) ;
}
return ret ;
} )
: [ ] ;
$$ . update ( ) ;
ready = true ;
run _all ( $$ . before _update ) ;
// `false` as a special case of no DOM component
$$ . fragment = create _fragment ? create _fragment ( $$ . ctx ) : false ;
if ( options . target ) {
if ( options . hydrate ) {
const nodes = children ( options . target ) ;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$ . fragment && $$ . fragment . l ( nodes ) ;
nodes . forEach ( detach ) ;
}
else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$ . fragment && $$ . fragment . c ( ) ;
}
if ( options . intro )
transition _in ( component . $$ . fragment ) ;
mount _component ( component , options . target , options . anchor , options . customElement ) ;
flush ( ) ;
}
set _current _component ( parent _component ) ;
}
/ * *
* Base class for Svelte components . Used when dev = false .
* /
class SvelteComponent {
$destroy ( ) {
destroy _component ( this , 1 ) ;
this . $destroy = noop ;
}
$on ( type , callback ) {
if ( ! is _function ( callback ) ) {
return noop ;
}
const callbacks = ( this . $$ . callbacks [ type ] || ( this . $$ . callbacks [ type ] = [ ] ) ) ;
callbacks . push ( callback ) ;
return ( ) => {
const index = callbacks . indexOf ( callback ) ;
if ( index !== - 1 )
callbacks . splice ( index , 1 ) ;
} ;
}
$set ( $$props ) {
if ( this . $$set && ! is _empty ( $$props ) ) {
this . $$ . skip _bound = true ;
this . $$set ( $$props ) ;
this . $$ . skip _bound = false ;
}
}
}
var MetricCounter ;
( function ( MetricCounter ) {
MetricCounter [ MetricCounter [ "words" ] = 0 ] = "words" ;
MetricCounter [ MetricCounter [ "characters" ] = 1 ] = "characters" ;
MetricCounter [ MetricCounter [ "sentences" ] = 2 ] = "sentences" ;
2023-04-03 20:35:26 +00:00
MetricCounter [ MetricCounter [ "footnotes" ] = 3 ] = "footnotes" ;
MetricCounter [ MetricCounter [ "citations" ] = 4 ] = "citations" ;
MetricCounter [ MetricCounter [ "pages" ] = 5 ] = "pages" ;
MetricCounter [ MetricCounter [ "files" ] = 6 ] = "files" ;
2023-03-02 21:47:11 +00:00
} ) ( MetricCounter || ( MetricCounter = { } ) ) ;
var MetricType ;
( function ( MetricType ) {
MetricType [ MetricType [ "file" ] = 0 ] = "file" ;
MetricType [ MetricType [ "daily" ] = 1 ] = "daily" ;
MetricType [ MetricType [ "total" ] = 2 ] = "total" ;
MetricType [ MetricType [ "folder" ] = 3 ] = "folder" ;
} ) ( MetricType || ( MetricType = { } ) ) ;
const BLANK _SB _ITEM = {
prefix : "" ,
suffix : "" ,
metric : {
type : null ,
counter : null ,
} ,
} ;
const DEFAULT _SETTINGS = {
statusBar : [
{
prefix : "" ,
suffix : " words" ,
metric : {
type : MetricType . file ,
counter : MetricCounter . words ,
} ,
} ,
{
prefix : " " ,
suffix : " characters" ,
metric : {
type : MetricType . file ,
counter : MetricCounter . characters ,
} ,
} ,
] ,
altBar : [
{
prefix : "" ,
suffix : " files" ,
metric : {
type : MetricType . total ,
counter : MetricCounter . files ,
} ,
} ,
] ,
countComments : false ,
collectStats : false ,
2023-08-21 17:47:20 +00:00
displaySectionCounts : false ,
2023-04-03 20:35:26 +00:00
pageWords : 300 ,
2023-03-02 21:47:11 +00:00
} ;
2023-08-21 17:47:20 +00:00
/* src/settings/StatusBarSettings.svelte generated by Svelte v3.59.2 */
2023-03-02 21:47:11 +00:00
function get _each _context ( ctx , list , i ) {
const child _ctx = ctx . slice ( ) ;
child _ctx [ 25 ] = list [ i ] ;
child _ctx [ 26 ] = list ;
child _ctx [ 27 ] = i ;
return child _ctx ;
}
function get _each _context _1 ( ctx , list , i ) {
const child _ctx = ctx . slice ( ) ;
child _ctx [ 25 ] = list [ i ] ;
child _ctx [ 28 ] = list ;
child _ctx [ 27 ] = i ;
return child _ctx ;
}
2023-04-03 20:35:26 +00:00
// (140:10) {#if i !== 0}
2023-03-02 21:47:11 +00:00
function create _if _block _3 ( ctx ) {
let button ;
let mounted ;
let dispose ;
function click _handler _2 ( ) {
return /*click_handler_2*/ ctx [ 8 ] ( /*i*/ ctx [ 27 ] ) ;
}
return {
c ( ) {
button = element ( "button" ) ;
button . textContent = "↑" ;
attr ( button , "aria-label" , "Move Status Bar Item Up" ) ;
} ,
m ( target , anchor ) {
insert ( target , button , anchor ) ;
if ( ! mounted ) {
dispose = listen ( button , "click" , click _handler _2 ) ;
mounted = true ;
}
} ,
p ( new _ctx , dirty ) {
ctx = new _ctx ;
} ,
d ( detaching ) {
if ( detaching ) detach ( button ) ;
mounted = false ;
dispose ( ) ;
}
} ;
}
2023-04-03 20:35:26 +00:00
// (151:10) {#if i !== statusItems.length - 1}
2023-03-02 21:47:11 +00:00
function create _if _block _2 ( ctx ) {
let button ;
let mounted ;
let dispose ;
function click _handler _3 ( ) {
return /*click_handler_3*/ ctx [ 9 ] ( /*i*/ ctx [ 27 ] ) ;
}
return {
c ( ) {
button = element ( "button" ) ;
button . textContent = "↓" ;
attr ( button , "aria-label" , "Move Status Bar Item Down" ) ;
} ,
m ( target , anchor ) {
insert ( target , button , anchor ) ;
if ( ! mounted ) {
dispose = listen ( button , "click" , click _handler _3 ) ;
mounted = true ;
}
} ,
p ( new _ctx , dirty ) {
ctx = new _ctx ;
} ,
d ( detaching ) {
if ( detaching ) detach ( button ) ;
mounted = false ;
dispose ( ) ;
}
} ;
}
2023-04-03 20:35:26 +00:00
// (133:2) {#each statusItems as item, i}
2023-03-02 21:47:11 +00:00
function create _each _block _1 ( ctx ) {
let details ;
let summary ;
let span0 ;
let t0 _value = /*metricToString*/ ctx [ 3 ] ( /*item*/ ctx [ 25 ] . metric ) + "" ;
let t0 ;
let t1 ;
let span1 ;
let t2 ;
let t3 ;
let button ;
let t5 ;
let div4 ;
let div2 ;
let t9 ;
let div3 ;
let select0 ;
let option0 ;
let option1 ;
let t11 ;
let option2 ;
let t12 ;
let option3 ;
let t13 ;
let option4 ;
let t14 ;
2023-04-03 20:35:26 +00:00
let option5 ;
2023-03-02 21:47:11 +00:00
let t15 ;
2023-04-03 20:35:26 +00:00
let option6 ;
let t16 ;
let option7 ;
let t17 ;
let select0 _value _value ;
let t18 ;
2023-03-02 21:47:11 +00:00
let div9 ;
let div7 ;
2023-04-03 20:35:26 +00:00
let t22 ;
2023-03-02 21:47:11 +00:00
let div8 ;
let select1 ;
let option8 ;
2023-04-03 20:35:26 +00:00
let option9 ;
2023-03-02 21:47:11 +00:00
let t24 ;
2023-04-03 20:35:26 +00:00
let option10 ;
let t25 ;
let option11 ;
let t26 ;
let select1 _value _value ;
let t27 ;
2023-03-02 21:47:11 +00:00
let div14 ;
let div12 ;
2023-04-03 20:35:26 +00:00
let t31 ;
2023-03-02 21:47:11 +00:00
let div13 ;
let input0 ;
let input0 _value _value ;
2023-04-03 20:35:26 +00:00
let t32 ;
2023-03-02 21:47:11 +00:00
let div19 ;
let div17 ;
2023-04-03 20:35:26 +00:00
let t36 ;
2023-03-02 21:47:11 +00:00
let div18 ;
let input1 ;
let input1 _value _value ;
let mounted ;
let dispose ;
let if _block0 = /*i*/ ctx [ 27 ] !== 0 && create _if _block _3 ( ctx ) ;
let if _block1 = /*i*/ ctx [ 27 ] !== /*statusItems*/ ctx [ 1 ] . length - 1 && create _if _block _2 ( ctx ) ;
function click _handler _4 ( ) {
return /*click_handler_4*/ ctx [ 10 ] ( /*i*/ ctx [ 27 ] ) ;
}
function change _handler ( ... args ) {
return /*change_handler*/ ctx [ 11 ] ( /*item*/ ctx [ 25 ] , /*each_value_1*/ ctx [ 28 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
function change _handler _1 ( ... args ) {
return /*change_handler_1*/ ctx [ 12 ] ( /*item*/ ctx [ 25 ] , /*each_value_1*/ ctx [ 28 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
function change _handler _2 ( ... args ) {
return /*change_handler_2*/ ctx [ 13 ] ( /*item*/ ctx [ 25 ] , /*each_value_1*/ ctx [ 28 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
function change _handler _3 ( ... args ) {
return /*change_handler_3*/ ctx [ 14 ] ( /*item*/ ctx [ 25 ] , /*each_value_1*/ ctx [ 28 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
return {
c ( ) {
details = element ( "details" ) ;
summary = element ( "summary" ) ;
span0 = element ( "span" ) ;
t0 = text ( t0 _value ) ;
t1 = space ( ) ;
span1 = element ( "span" ) ;
if ( if _block0 ) if _block0 . c ( ) ;
t2 = space ( ) ;
if ( if _block1 ) if _block1 . c ( ) ;
t3 = space ( ) ;
button = element ( "button" ) ;
button . textContent = "X" ;
t5 = space ( ) ;
div4 = element ( "div" ) ;
div2 = element ( "div" ) ;
div2 . innerHTML = ` <div class="setting-item-name">Metric Counter</div>
< div class = "setting-item-description" > Select the counter to display , e . g . words , characters . < / d i v > ` ;
t9 = space ( ) ;
div3 = element ( "div" ) ;
select0 = element ( "select" ) ;
option0 = element ( "option" ) ;
option0 . textContent = "Select Option" ;
option1 = element ( "option" ) ;
t11 = text ( "Words" ) ;
option2 = element ( "option" ) ;
t12 = text ( "Characters" ) ;
option3 = element ( "option" ) ;
t13 = text ( "Sentences" ) ;
option4 = element ( "option" ) ;
2023-04-03 20:35:26 +00:00
t14 = text ( "Footnotes" ) ;
option5 = element ( "option" ) ;
t15 = text ( "Citations" ) ;
option6 = element ( "option" ) ;
t16 = text ( "Pages" ) ;
option7 = element ( "option" ) ;
t17 = text ( "Files" ) ;
t18 = space ( ) ;
2023-03-02 21:47:11 +00:00
div9 = element ( "div" ) ;
div7 = element ( "div" ) ;
div7 . innerHTML = ` <div class="setting-item-name">Metric Type</div>
< div class = "setting-item-description" > Select the type of metric that you want displayed . < / d i v > ` ;
2023-04-03 20:35:26 +00:00
t22 = space ( ) ;
2023-03-02 21:47:11 +00:00
div8 = element ( "div" ) ;
select1 = element ( "select" ) ;
option8 = element ( "option" ) ;
2023-04-03 20:35:26 +00:00
option8 . textContent = "Select Option" ;
option9 = element ( "option" ) ;
t24 = text ( "Current Note" ) ;
option10 = element ( "option" ) ;
t25 = text ( "Daily Metric" ) ;
option11 = element ( "option" ) ;
t26 = text ( "Total in Vault" ) ;
t27 = space ( ) ;
2023-03-02 21:47:11 +00:00
div14 = element ( "div" ) ;
div12 = element ( "div" ) ;
div12 . innerHTML = ` <div class="setting-item-name">Prefix Text</div>
< div class = "setting-item-description" > This is the text that is placed before the count . < / d i v > ` ;
2023-04-03 20:35:26 +00:00
t31 = space ( ) ;
2023-03-02 21:47:11 +00:00
div13 = element ( "div" ) ;
input0 = element ( "input" ) ;
2023-04-03 20:35:26 +00:00
t32 = space ( ) ;
2023-03-02 21:47:11 +00:00
div19 = element ( "div" ) ;
div17 = element ( "div" ) ;
div17 . innerHTML = ` <div class="setting-item-name">Suffix Text</div>
< div class = "setting-item-description" > This is the text that is placed after the count . < / d i v > ` ;
2023-04-03 20:35:26 +00:00
t36 = space ( ) ;
2023-03-02 21:47:11 +00:00
div18 = element ( "div" ) ;
input1 = element ( "input" ) ;
attr ( span0 , "class" , "bwc-sb-item-text" ) ;
attr ( button , "aria-label" , "Remove Status Bar Item" ) ;
attr ( span1 , "class" , "bwc-sb-buttons" ) ;
attr ( div2 , "class" , "setting-item-info" ) ;
option0 . _ _value = "" ;
option0 . value = option0 . _ _value ;
option1 . _ _value = MetricCounter . words ;
option1 . value = option1 . _ _value ;
option2 . _ _value = MetricCounter . characters ;
option2 . value = option2 . _ _value ;
option3 . _ _value = MetricCounter . sentences ;
option3 . value = option3 . _ _value ;
2023-04-03 20:35:26 +00:00
option4 . _ _value = MetricCounter . footnotes ;
2023-03-02 21:47:11 +00:00
option4 . value = option4 . _ _value ;
2023-04-03 20:35:26 +00:00
option5 . _ _value = MetricCounter . citations ;
option5 . value = option5 . _ _value ;
option6 . _ _value = MetricCounter . pages ;
option6 . value = option6 . _ _value ;
option7 . _ _value = MetricCounter . files ;
option7 . value = option7 . _ _value ;
2023-03-02 21:47:11 +00:00
attr ( select0 , "class" , "dropdown" ) ;
attr ( div3 , "class" , "setting-item-control" ) ;
attr ( div4 , "class" , "setting-item" ) ;
attr ( div7 , "class" , "setting-item-info" ) ;
2023-04-03 20:35:26 +00:00
option8 . _ _value = "" ;
2023-03-02 21:47:11 +00:00
option8 . value = option8 . _ _value ;
2023-04-03 20:35:26 +00:00
option9 . _ _value = MetricType . file ;
option9 . value = option9 . _ _value ;
option10 . _ _value = MetricType . daily ;
option10 . value = option10 . _ _value ;
option11 . _ _value = MetricType . total ;
option11 . value = option11 . _ _value ;
2023-03-02 21:47:11 +00:00
attr ( select1 , "class" , "dropdown" ) ;
attr ( div8 , "class" , "setting-item-control" ) ;
attr ( div9 , "class" , "setting-item" ) ;
attr ( div12 , "class" , "setting-item-info" ) ;
attr ( input0 , "type" , "text" ) ;
attr ( input0 , "name" , "prefix" ) ;
input0 . value = input0 _value _value = /*item*/ ctx [ 25 ] . prefix ;
attr ( div13 , "class" , "setting-item-control" ) ;
attr ( div14 , "class" , "setting-item" ) ;
attr ( div17 , "class" , "setting-item-info" ) ;
attr ( input1 , "type" , "text" ) ;
attr ( input1 , "name" , "suffix" ) ;
input1 . value = input1 _value _value = /*item*/ ctx [ 25 ] . suffix ;
attr ( div18 , "class" , "setting-item-control" ) ;
attr ( div19 , "class" , "setting-item" ) ;
attr ( details , "class" , "bwc-sb-item-setting" ) ;
} ,
m ( target , anchor ) {
insert ( target , details , anchor ) ;
append ( details , summary ) ;
append ( summary , span0 ) ;
append ( span0 , t0 ) ;
append ( summary , t1 ) ;
append ( summary , span1 ) ;
if ( if _block0 ) if _block0 . m ( span1 , null ) ;
append ( span1 , t2 ) ;
if ( if _block1 ) if _block1 . m ( span1 , null ) ;
append ( span1 , t3 ) ;
append ( span1 , button ) ;
append ( details , t5 ) ;
append ( details , div4 ) ;
append ( div4 , div2 ) ;
append ( div4 , t9 ) ;
append ( div4 , div3 ) ;
append ( div3 , select0 ) ;
append ( select0 , option0 ) ;
append ( select0 , option1 ) ;
append ( option1 , t11 ) ;
append ( select0 , option2 ) ;
append ( option2 , t12 ) ;
append ( select0 , option3 ) ;
append ( option3 , t13 ) ;
append ( select0 , option4 ) ;
append ( option4 , t14 ) ;
2023-04-03 20:35:26 +00:00
append ( select0 , option5 ) ;
append ( option5 , t15 ) ;
append ( select0 , option6 ) ;
append ( option6 , t16 ) ;
append ( select0 , option7 ) ;
append ( option7 , t17 ) ;
2023-03-02 21:47:11 +00:00
select _option ( select0 , /*item*/ ctx [ 25 ] . metric . counter ) ;
2023-04-03 20:35:26 +00:00
append ( details , t18 ) ;
2023-03-02 21:47:11 +00:00
append ( details , div9 ) ;
append ( div9 , div7 ) ;
2023-04-03 20:35:26 +00:00
append ( div9 , t22 ) ;
2023-03-02 21:47:11 +00:00
append ( div9 , div8 ) ;
append ( div8 , select1 ) ;
append ( select1 , option8 ) ;
2023-04-03 20:35:26 +00:00
append ( select1 , option9 ) ;
append ( option9 , t24 ) ;
append ( select1 , option10 ) ;
append ( option10 , t25 ) ;
append ( select1 , option11 ) ;
append ( option11 , t26 ) ;
2023-03-02 21:47:11 +00:00
select _option ( select1 , /*item*/ ctx [ 25 ] . metric . type ) ;
2023-04-03 20:35:26 +00:00
append ( details , t27 ) ;
2023-03-02 21:47:11 +00:00
append ( details , div14 ) ;
append ( div14 , div12 ) ;
2023-04-03 20:35:26 +00:00
append ( div14 , t31 ) ;
2023-03-02 21:47:11 +00:00
append ( div14 , div13 ) ;
append ( div13 , input0 ) ;
2023-04-03 20:35:26 +00:00
append ( details , t32 ) ;
2023-03-02 21:47:11 +00:00
append ( details , div19 ) ;
append ( div19 , div17 ) ;
2023-04-03 20:35:26 +00:00
append ( div19 , t36 ) ;
2023-03-02 21:47:11 +00:00
append ( div19 , div18 ) ;
append ( div18 , input1 ) ;
if ( ! mounted ) {
dispose = [
listen ( button , "click" , click _handler _4 ) ,
listen ( select0 , "change" , change _handler ) ,
listen ( select1 , "change" , change _handler _1 ) ,
listen ( input0 , "change" , change _handler _2 ) ,
listen ( input1 , "change" , change _handler _3 )
] ;
mounted = true ;
}
} ,
p ( new _ctx , dirty ) {
ctx = new _ctx ;
if ( dirty & /*statusItems*/ 2 && t0 _value !== ( t0 _value = /*metricToString*/ ctx [ 3 ] ( /*item*/ ctx [ 25 ] . metric ) + "" ) ) set _data ( t0 , t0 _value ) ;
if ( /*i*/ ctx [ 27 ] !== 0 ) if _block0 . p ( ctx , dirty ) ;
if ( /*i*/ ctx [ 27 ] !== /*statusItems*/ ctx [ 1 ] . length - 1 ) {
if ( if _block1 ) {
if _block1 . p ( ctx , dirty ) ;
} else {
if _block1 = create _if _block _2 ( ctx ) ;
if _block1 . c ( ) ;
if _block1 . m ( span1 , t3 ) ;
}
} else if ( if _block1 ) {
if _block1 . d ( 1 ) ;
if _block1 = null ;
}
if ( dirty & /*statusItems, MetricCounter*/ 2 && select0 _value _value !== ( select0 _value _value = /*item*/ ctx [ 25 ] . metric . counter ) ) {
select _option ( select0 , /*item*/ ctx [ 25 ] . metric . counter ) ;
}
if ( dirty & /*statusItems, MetricCounter*/ 2 && select1 _value _value !== ( select1 _value _value = /*item*/ ctx [ 25 ] . metric . type ) ) {
select _option ( select1 , /*item*/ ctx [ 25 ] . metric . type ) ;
}
if ( dirty & /*statusItems, MetricCounter*/ 2 && input0 _value _value !== ( input0 _value _value = /*item*/ ctx [ 25 ] . prefix ) && input0 . value !== input0 _value _value ) {
input0 . value = input0 _value _value ;
}
if ( dirty & /*statusItems, MetricCounter*/ 2 && input1 _value _value !== ( input1 _value _value = /*item*/ ctx [ 25 ] . suffix ) && input1 . value !== input1 _value _value ) {
input1 . value = input1 _value _value ;
}
} ,
d ( detaching ) {
if ( detaching ) detach ( details ) ;
if ( if _block0 ) if _block0 . d ( ) ;
if ( if _block1 ) if _block1 . d ( ) ;
mounted = false ;
run _all ( dispose ) ;
}
} ;
}
2023-04-03 20:35:26 +00:00
// (310:10) {#if i !== 0}
2023-03-02 21:47:11 +00:00
function create _if _block _1 ( ctx ) {
let button ;
let mounted ;
let dispose ;
function click _handler _7 ( ) {
return /*click_handler_7*/ ctx [ 17 ] ( /*i*/ ctx [ 27 ] ) ;
}
return {
c ( ) {
button = element ( "button" ) ;
button . textContent = "↑" ;
attr ( button , "aria-label" , "Move Status Bar Item Up" ) ;
} ,
m ( target , anchor ) {
insert ( target , button , anchor ) ;
if ( ! mounted ) {
dispose = listen ( button , "click" , click _handler _7 ) ;
mounted = true ;
}
} ,
p ( new _ctx , dirty ) {
ctx = new _ctx ;
} ,
d ( detaching ) {
if ( detaching ) detach ( button ) ;
mounted = false ;
dispose ( ) ;
}
} ;
}
2023-04-03 20:35:26 +00:00
// (321:10) {#if i !== altSItems.length - 1}
2023-03-02 21:47:11 +00:00
function create _if _block ( ctx ) {
let button ;
let mounted ;
let dispose ;
function click _handler _8 ( ) {
return /*click_handler_8*/ ctx [ 18 ] ( /*i*/ ctx [ 27 ] ) ;
}
return {
c ( ) {
button = element ( "button" ) ;
button . textContent = "↓" ;
attr ( button , "aria-label" , "Move Status Bar Item Down" ) ;
} ,
m ( target , anchor ) {
insert ( target , button , anchor ) ;
if ( ! mounted ) {
dispose = listen ( button , "click" , click _handler _8 ) ;
mounted = true ;
}
} ,
p ( new _ctx , dirty ) {
ctx = new _ctx ;
} ,
d ( detaching ) {
if ( detaching ) detach ( button ) ;
mounted = false ;
dispose ( ) ;
}
} ;
}
2023-04-03 20:35:26 +00:00
// (303:2) {#each altSItems as item, i}
2023-03-02 21:47:11 +00:00
function create _each _block ( ctx ) {
let details ;
let summary ;
let span0 ;
let t0 _value = /*metricToString*/ ctx [ 3 ] ( /*item*/ ctx [ 25 ] . metric ) + "" ;
let t0 ;
let t1 ;
let span1 ;
let t2 ;
let t3 ;
let button ;
let t5 ;
let div4 ;
let div2 ;
let t9 ;
let div3 ;
let select0 ;
let option0 ;
let option1 ;
let t11 ;
let option2 ;
let t12 ;
let option3 ;
let t13 ;
let option4 ;
let t14 ;
2023-04-03 20:35:26 +00:00
let option5 ;
2023-03-02 21:47:11 +00:00
let t15 ;
2023-04-03 20:35:26 +00:00
let option6 ;
let t16 ;
let option7 ;
let t17 ;
let select0 _value _value ;
let t18 ;
2023-03-02 21:47:11 +00:00
let div9 ;
let div7 ;
2023-04-03 20:35:26 +00:00
let t22 ;
2023-03-02 21:47:11 +00:00
let div8 ;
let select1 ;
let option8 ;
2023-04-03 20:35:26 +00:00
let option9 ;
2023-03-02 21:47:11 +00:00
let t24 ;
2023-04-03 20:35:26 +00:00
let option10 ;
let t25 ;
let option11 ;
let t26 ;
let select1 _value _value ;
let t27 ;
2023-03-02 21:47:11 +00:00
let div14 ;
let div12 ;
2023-04-03 20:35:26 +00:00
let t31 ;
2023-03-02 21:47:11 +00:00
let div13 ;
let input0 ;
let input0 _value _value ;
2023-04-03 20:35:26 +00:00
let t32 ;
2023-03-02 21:47:11 +00:00
let div19 ;
let div17 ;
2023-04-03 20:35:26 +00:00
let t36 ;
2023-03-02 21:47:11 +00:00
let div18 ;
let input1 ;
let input1 _value _value ;
2023-04-03 20:35:26 +00:00
let t37 ;
2023-03-02 21:47:11 +00:00
let mounted ;
let dispose ;
let if _block0 = /*i*/ ctx [ 27 ] !== 0 && create _if _block _1 ( ctx ) ;
let if _block1 = /*i*/ ctx [ 27 ] !== /*altSItems*/ ctx [ 2 ] . length - 1 && create _if _block ( ctx ) ;
function click _handler _9 ( ) {
return /*click_handler_9*/ ctx [ 19 ] ( /*i*/ ctx [ 27 ] ) ;
}
function change _handler _4 ( ... args ) {
return /*change_handler_4*/ ctx [ 20 ] ( /*item*/ ctx [ 25 ] , /*each_value*/ ctx [ 26 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
function change _handler _5 ( ... args ) {
return /*change_handler_5*/ ctx [ 21 ] ( /*item*/ ctx [ 25 ] , /*each_value*/ ctx [ 26 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
function change _handler _6 ( ... args ) {
return /*change_handler_6*/ ctx [ 22 ] ( /*item*/ ctx [ 25 ] , /*each_value*/ ctx [ 26 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
function change _handler _7 ( ... args ) {
return /*change_handler_7*/ ctx [ 23 ] ( /*item*/ ctx [ 25 ] , /*each_value*/ ctx [ 26 ] , /*i*/ ctx [ 27 ] , ... args ) ;
}
return {
c ( ) {
details = element ( "details" ) ;
summary = element ( "summary" ) ;
span0 = element ( "span" ) ;
t0 = text ( t0 _value ) ;
t1 = space ( ) ;
span1 = element ( "span" ) ;
if ( if _block0 ) if _block0 . c ( ) ;
t2 = space ( ) ;
if ( if _block1 ) if _block1 . c ( ) ;
t3 = space ( ) ;
button = element ( "button" ) ;
button . textContent = "X" ;
t5 = space ( ) ;
div4 = element ( "div" ) ;
div2 = element ( "div" ) ;
div2 . innerHTML = ` <div class="setting-item-name">Metric Counter</div>
< div class = "setting-item-description" > Select the counter to display , e . g . words , characters . < / d i v > ` ;
t9 = space ( ) ;
div3 = element ( "div" ) ;
select0 = element ( "select" ) ;
option0 = element ( "option" ) ;
option0 . textContent = "Select Option" ;
option1 = element ( "option" ) ;
t11 = text ( "Words" ) ;
option2 = element ( "option" ) ;
t12 = text ( "Characters" ) ;
option3 = element ( "option" ) ;
t13 = text ( "Sentences" ) ;
option4 = element ( "option" ) ;
2023-04-03 20:35:26 +00:00
t14 = text ( "Footnotes" ) ;
option5 = element ( "option" ) ;
t15 = text ( "Citations" ) ;
option6 = element ( "option" ) ;
t16 = text ( "Pages" ) ;
option7 = element ( "option" ) ;
t17 = text ( "Files" ) ;
t18 = space ( ) ;
2023-03-02 21:47:11 +00:00
div9 = element ( "div" ) ;
div7 = element ( "div" ) ;
div7 . innerHTML = ` <div class="setting-item-name">Metric Type</div>
< div class = "setting-item-description" > Select the type of metric that you want displayed . < / d i v > ` ;
2023-04-03 20:35:26 +00:00
t22 = space ( ) ;
2023-03-02 21:47:11 +00:00
div8 = element ( "div" ) ;
select1 = element ( "select" ) ;
option8 = element ( "option" ) ;
2023-04-03 20:35:26 +00:00
option8 . textContent = "Select Option" ;
option9 = element ( "option" ) ;
t24 = text ( "Current Note" ) ;
option10 = element ( "option" ) ;
t25 = text ( "Daily Metric" ) ;
option11 = element ( "option" ) ;
t26 = text ( "Total in Vault" ) ;
t27 = space ( ) ;
2023-03-02 21:47:11 +00:00
div14 = element ( "div" ) ;
div12 = element ( "div" ) ;
div12 . innerHTML = ` <div class="setting-item-name">Prefix Text</div>
< div class = "setting-item-description" > This is the text that is placed before the count . < / d i v > ` ;
2023-04-03 20:35:26 +00:00
t31 = space ( ) ;
2023-03-02 21:47:11 +00:00
div13 = element ( "div" ) ;
input0 = element ( "input" ) ;
2023-04-03 20:35:26 +00:00
t32 = space ( ) ;
2023-03-02 21:47:11 +00:00
div19 = element ( "div" ) ;
div17 = element ( "div" ) ;
div17 . innerHTML = ` <div class="setting-item-name">Suffix Text</div>
< div class = "setting-item-description" > This is the text that is placed after the count . < / d i v > ` ;
2023-04-03 20:35:26 +00:00
t36 = space ( ) ;
2023-03-02 21:47:11 +00:00
div18 = element ( "div" ) ;
input1 = element ( "input" ) ;
2023-04-03 20:35:26 +00:00
t37 = space ( ) ;
2023-03-02 21:47:11 +00:00
attr ( span0 , "class" , "bwc-sb-item-text" ) ;
attr ( button , "aria-label" , "Remove Status Bar Item" ) ;
attr ( span1 , "class" , "bwc-sb-buttons" ) ;
attr ( div2 , "class" , "setting-item-info" ) ;
option0 . _ _value = "" ;
option0 . value = option0 . _ _value ;
option1 . _ _value = MetricCounter . words ;
option1 . value = option1 . _ _value ;
option2 . _ _value = MetricCounter . characters ;
option2 . value = option2 . _ _value ;
option3 . _ _value = MetricCounter . sentences ;
option3 . value = option3 . _ _value ;
2023-04-03 20:35:26 +00:00
option4 . _ _value = MetricCounter . footnotes ;
2023-03-02 21:47:11 +00:00
option4 . value = option4 . _ _value ;
2023-04-03 20:35:26 +00:00
option5 . _ _value = MetricCounter . citations ;
option5 . value = option5 . _ _value ;
option6 . _ _value = MetricCounter . pages ;
option6 . value = option6 . _ _value ;
option7 . _ _value = MetricCounter . files ;
option7 . value = option7 . _ _value ;
2023-03-02 21:47:11 +00:00
attr ( select0 , "class" , "dropdown" ) ;
attr ( div3 , "class" , "setting-item-control" ) ;
attr ( div4 , "class" , "setting-item" ) ;
attr ( div7 , "class" , "setting-item-info" ) ;
2023-04-03 20:35:26 +00:00
option8 . _ _value = "" ;
2023-03-02 21:47:11 +00:00
option8 . value = option8 . _ _value ;
2023-04-03 20:35:26 +00:00
option9 . _ _value = MetricType . file ;
option9 . value = option9 . _ _value ;
option10 . _ _value = MetricType . daily ;
option10 . value = option10 . _ _value ;
option11 . _ _value = MetricType . total ;
option11 . value = option11 . _ _value ;
2023-03-02 21:47:11 +00:00
attr ( select1 , "class" , "dropdown" ) ;
attr ( div8 , "class" , "setting-item-control" ) ;
attr ( div9 , "class" , "setting-item" ) ;
attr ( div12 , "class" , "setting-item-info" ) ;
attr ( input0 , "type" , "text" ) ;
attr ( input0 , "name" , "prefix" ) ;
input0 . value = input0 _value _value = /*item*/ ctx [ 25 ] . prefix ;
attr ( div13 , "class" , "setting-item-control" ) ;
attr ( div14 , "class" , "setting-item" ) ;
attr ( div17 , "class" , "setting-item-info" ) ;
attr ( input1 , "type" , "text" ) ;
attr ( input1 , "name" , "suffix" ) ;
input1 . value = input1 _value _value = /*item*/ ctx [ 25 ] . suffix ;
attr ( div18 , "class" , "setting-item-control" ) ;
attr ( div19 , "class" , "setting-item" ) ;
attr ( details , "class" , "bwc-sb-item-setting" ) ;
} ,
m ( target , anchor ) {
insert ( target , details , anchor ) ;
append ( details , summary ) ;
append ( summary , span0 ) ;
append ( span0 , t0 ) ;
append ( summary , t1 ) ;
append ( summary , span1 ) ;
if ( if _block0 ) if _block0 . m ( span1 , null ) ;
append ( span1 , t2 ) ;
if ( if _block1 ) if _block1 . m ( span1 , null ) ;
append ( span1 , t3 ) ;
append ( span1 , button ) ;
append ( details , t5 ) ;
append ( details , div4 ) ;
append ( div4 , div2 ) ;
append ( div4 , t9 ) ;
append ( div4 , div3 ) ;
append ( div3 , select0 ) ;
append ( select0 , option0 ) ;
append ( select0 , option1 ) ;
append ( option1 , t11 ) ;
append ( select0 , option2 ) ;
append ( option2 , t12 ) ;
append ( select0 , option3 ) ;
append ( option3 , t13 ) ;
append ( select0 , option4 ) ;
append ( option4 , t14 ) ;
2023-04-03 20:35:26 +00:00
append ( select0 , option5 ) ;
append ( option5 , t15 ) ;
append ( select0 , option6 ) ;
append ( option6 , t16 ) ;
append ( select0 , option7 ) ;
append ( option7 , t17 ) ;
2023-03-02 21:47:11 +00:00
select _option ( select0 , /*item*/ ctx [ 25 ] . metric . counter ) ;
2023-04-03 20:35:26 +00:00
append ( details , t18 ) ;
2023-03-02 21:47:11 +00:00
append ( details , div9 ) ;
append ( div9 , div7 ) ;
2023-04-03 20:35:26 +00:00
append ( div9 , t22 ) ;
2023-03-02 21:47:11 +00:00
append ( div9 , div8 ) ;
append ( div8 , select1 ) ;
append ( select1 , option8 ) ;
2023-04-03 20:35:26 +00:00
append ( select1 , option9 ) ;
append ( option9 , t24 ) ;
append ( select1 , option10 ) ;
append ( option10 , t25 ) ;
append ( select1 , option11 ) ;
append ( option11 , t26 ) ;
2023-03-02 21:47:11 +00:00
select _option ( select1 , /*item*/ ctx [ 25 ] . metric . type ) ;
2023-04-03 20:35:26 +00:00
append ( details , t27 ) ;
2023-03-02 21:47:11 +00:00
append ( details , div14 ) ;
append ( div14 , div12 ) ;
2023-04-03 20:35:26 +00:00
append ( div14 , t31 ) ;
2023-03-02 21:47:11 +00:00
append ( div14 , div13 ) ;
append ( div13 , input0 ) ;
2023-04-03 20:35:26 +00:00
append ( details , t32 ) ;
2023-03-02 21:47:11 +00:00
append ( details , div19 ) ;
append ( div19 , div17 ) ;
2023-04-03 20:35:26 +00:00
append ( div19 , t36 ) ;
2023-03-02 21:47:11 +00:00
append ( div19 , div18 ) ;
append ( div18 , input1 ) ;
2023-04-03 20:35:26 +00:00
append ( details , t37 ) ;
2023-03-02 21:47:11 +00:00
if ( ! mounted ) {
dispose = [
listen ( button , "click" , click _handler _9 ) ,
listen ( select0 , "change" , change _handler _4 ) ,
listen ( select1 , "change" , change _handler _5 ) ,
listen ( input0 , "change" , change _handler _6 ) ,
listen ( input1 , "change" , change _handler _7 )
] ;
mounted = true ;
}
} ,
p ( new _ctx , dirty ) {
ctx = new _ctx ;
if ( dirty & /*altSItems*/ 4 && t0 _value !== ( t0 _value = /*metricToString*/ ctx [ 3 ] ( /*item*/ ctx [ 25 ] . metric ) + "" ) ) set _data ( t0 , t0 _value ) ;
if ( /*i*/ ctx [ 27 ] !== 0 ) if _block0 . p ( ctx , dirty ) ;
if ( /*i*/ ctx [ 27 ] !== /*altSItems*/ ctx [ 2 ] . length - 1 ) {
if ( if _block1 ) {
if _block1 . p ( ctx , dirty ) ;
} else {
if _block1 = create _if _block ( ctx ) ;
if _block1 . c ( ) ;
if _block1 . m ( span1 , t3 ) ;
}
} else if ( if _block1 ) {
if _block1 . d ( 1 ) ;
if _block1 = null ;
}
if ( dirty & /*altSItems, MetricCounter*/ 4 && select0 _value _value !== ( select0 _value _value = /*item*/ ctx [ 25 ] . metric . counter ) ) {
select _option ( select0 , /*item*/ ctx [ 25 ] . metric . counter ) ;
}
if ( dirty & /*altSItems, MetricCounter*/ 4 && select1 _value _value !== ( select1 _value _value = /*item*/ ctx [ 25 ] . metric . type ) ) {
select _option ( select1 , /*item*/ ctx [ 25 ] . metric . type ) ;
}
if ( dirty & /*altSItems, MetricCounter*/ 4 && input0 _value _value !== ( input0 _value _value = /*item*/ ctx [ 25 ] . prefix ) && input0 . value !== input0 _value _value ) {
input0 . value = input0 _value _value ;
}
if ( dirty & /*altSItems, MetricCounter*/ 4 && input1 _value _value !== ( input1 _value _value = /*item*/ ctx [ 25 ] . suffix ) && input1 . value !== input1 _value _value ) {
input1 . value = input1 _value _value ;
}
} ,
d ( detaching ) {
if ( detaching ) detach ( details ) ;
if ( if _block0 ) if _block0 . d ( ) ;
if ( if _block1 ) if _block1 . d ( ) ;
mounted = false ;
run _all ( dispose ) ;
}
} ;
}
function create _fragment ( ctx ) {
let div6 ;
let h40 ;
let t1 ;
let p0 ;
let t3 ;
let div2 ;
let button0 ;
let t5 ;
let button1 ;
let t7 ;
let t8 ;
let h41 ;
let t10 ;
let p1 ;
let t12 ;
let div5 ;
let button2 ;
let t14 ;
let button3 ;
let t16 ;
let mounted ;
let dispose ;
let each _value _1 = /*statusItems*/ ctx [ 1 ] ;
let each _blocks _1 = [ ] ;
for ( let i = 0 ; i < each _value _1 . length ; i += 1 ) {
each _blocks _1 [ i ] = create _each _block _1 ( get _each _context _1 ( ctx , each _value _1 , i ) ) ;
}
let each _value = /*altSItems*/ ctx [ 2 ] ;
let each _blocks = [ ] ;
for ( let i = 0 ; i < each _value . length ; i += 1 ) {
each _blocks [ i ] = create _each _block ( get _each _context ( ctx , each _value , i ) ) ;
}
return {
c ( ) {
div6 = element ( "div" ) ;
h40 = element ( "h4" ) ;
h40 . textContent = "Markdown Status Bar" ;
t1 = space ( ) ;
p0 = element ( "p" ) ;
p0 . textContent = "Here you can customize what statistics are displayed on the status bar when editing a markdown note." ;
t3 = space ( ) ;
div2 = element ( "div" ) ;
button0 = element ( "button" ) ;
button0 . innerHTML = ` <div class="icon">Add Item</div> ` ;
t5 = space ( ) ;
button1 = element ( "button" ) ;
button1 . innerHTML = ` <div class="icon">Reset</div> ` ;
t7 = space ( ) ;
for ( let i = 0 ; i < each _blocks _1 . length ; i += 1 ) {
each _blocks _1 [ i ] . c ( ) ;
}
t8 = space ( ) ;
h41 = element ( "h4" ) ;
h41 . textContent = "Alternative Status Bar" ;
t10 = space ( ) ;
p1 = element ( "p" ) ;
p1 . textContent = "Here you can customize what statistics are displayed on the status bar when not editing a markdown file." ;
t12 = space ( ) ;
div5 = element ( "div" ) ;
button2 = element ( "button" ) ;
button2 . innerHTML = ` <div class="icon">Add Item</div> ` ;
t14 = space ( ) ;
button3 = element ( "button" ) ;
button3 . innerHTML = ` <div class="icon">Reset</div> ` ;
t16 = space ( ) ;
for ( let i = 0 ; i < each _blocks . length ; i += 1 ) {
each _blocks [ i ] . c ( ) ;
}
attr ( button0 , "aria-label" , "Add New Status Bar Item" ) ;
attr ( button1 , "aria-label" , "Reset Status Bar to Default" ) ;
attr ( div2 , "class" , "bwc-sb-buttons" ) ;
attr ( button2 , "aria-label" , "Add New Status Bar Item" ) ;
attr ( button3 , "aria-label" , "Reset Status Bar to Default" ) ;
attr ( div5 , "class" , "bwc-sb-buttons" ) ;
} ,
m ( target , anchor ) {
insert ( target , div6 , anchor ) ;
append ( div6 , h40 ) ;
append ( div6 , t1 ) ;
append ( div6 , p0 ) ;
append ( div6 , t3 ) ;
append ( div6 , div2 ) ;
append ( div2 , button0 ) ;
append ( div2 , t5 ) ;
append ( div2 , button1 ) ;
append ( div6 , t7 ) ;
for ( let i = 0 ; i < each _blocks _1 . length ; i += 1 ) {
2023-04-03 20:35:26 +00:00
if ( each _blocks _1 [ i ] ) {
each _blocks _1 [ i ] . m ( div6 , null ) ;
}
2023-03-02 21:47:11 +00:00
}
append ( div6 , t8 ) ;
append ( div6 , h41 ) ;
append ( div6 , t10 ) ;
append ( div6 , p1 ) ;
append ( div6 , t12 ) ;
append ( div6 , div5 ) ;
append ( div5 , button2 ) ;
append ( div5 , t14 ) ;
append ( div5 , button3 ) ;
append ( div6 , t16 ) ;
for ( let i = 0 ; i < each _blocks . length ; i += 1 ) {
2023-04-03 20:35:26 +00:00
if ( each _blocks [ i ] ) {
each _blocks [ i ] . m ( div6 , null ) ;
}
2023-03-02 21:47:11 +00:00
}
if ( ! mounted ) {
dispose = [
listen ( button0 , "click" , /*click_handler*/ ctx [ 6 ] ) ,
listen ( button1 , "click" , /*click_handler_1*/ ctx [ 7 ] ) ,
listen ( button2 , "click" , /*click_handler_5*/ ctx [ 15 ] ) ,
listen ( button3 , "click" , /*click_handler_6*/ ctx [ 16 ] )
] ;
mounted = true ;
}
} ,
p ( ctx , [ dirty ] ) {
if ( dirty & /*statusItems, update, plugin, MetricType, MetricCounter, swapStatusBarItems, metricToString*/ 27 ) {
each _value _1 = /*statusItems*/ ctx [ 1 ] ;
let i ;
for ( i = 0 ; i < each _value _1 . length ; i += 1 ) {
const child _ctx = get _each _context _1 ( ctx , each _value _1 , i ) ;
if ( each _blocks _1 [ i ] ) {
each _blocks _1 [ i ] . p ( child _ctx , dirty ) ;
} else {
each _blocks _1 [ i ] = create _each _block _1 ( child _ctx ) ;
each _blocks _1 [ i ] . c ( ) ;
each _blocks _1 [ i ] . m ( div6 , t8 ) ;
}
}
for ( ; i < each _blocks _1 . length ; i += 1 ) {
each _blocks _1 [ i ] . d ( 1 ) ;
}
each _blocks _1 . length = each _value _1 . length ;
}
if ( dirty & /*altSItems, updateAlt, plugin, MetricType, MetricCounter, swapStatusBarItems, metricToString*/ 45 ) {
each _value = /*altSItems*/ ctx [ 2 ] ;
let i ;
for ( i = 0 ; i < each _value . length ; i += 1 ) {
const child _ctx = get _each _context ( ctx , each _value , i ) ;
if ( each _blocks [ i ] ) {
each _blocks [ i ] . p ( child _ctx , dirty ) ;
} else {
each _blocks [ i ] = create _each _block ( child _ctx ) ;
each _blocks [ i ] . c ( ) ;
each _blocks [ i ] . m ( div6 , null ) ;
}
}
for ( ; i < each _blocks . length ; i += 1 ) {
each _blocks [ i ] . d ( 1 ) ;
}
each _blocks . length = each _value . length ;
}
} ,
i : noop ,
o : noop ,
d ( detaching ) {
if ( detaching ) detach ( div6 ) ;
destroy _each ( each _blocks _1 , detaching ) ;
destroy _each ( each _blocks , detaching ) ;
mounted = false ;
run _all ( dispose ) ;
}
} ;
}
function swapStatusBarItems ( i , j , arr ) {
const max = arr . length - 1 ;
if ( i < 0 || i > max || j < 0 || j > max ) return arr ;
const tmp = arr [ i ] ;
arr [ i ] = arr [ j ] ;
arr [ j ] = tmp ;
return arr ;
}
function instance ( $$self , $$props , $$invalidate ) {
let { plugin } = $$props ;
let statusItems = [ ... plugin . settings . statusBar ] ;
let altSItems = [ ... plugin . settings . altBar ] ;
function metricToString ( metric ) {
if ( metric . type === MetricType . file ) {
switch ( metric . counter ) {
case MetricCounter . words :
return "Words in Note" ;
case MetricCounter . characters :
return "Chars in Note" ;
case MetricCounter . sentences :
return "Sentences in Note" ;
2023-04-03 20:35:26 +00:00
case MetricCounter . footnotes :
return "Footnotes in Note" ;
case MetricCounter . citations :
return "Citations in Note" ;
case MetricCounter . pages :
return "Pages in Note" ;
2023-03-02 21:47:11 +00:00
case MetricCounter . files :
return "Total Notes" ;
}
} else if ( metric . type === MetricType . daily ) {
switch ( metric . counter ) {
case MetricCounter . words :
return "Daily Words" ;
case MetricCounter . characters :
return "Daily Chars" ;
case MetricCounter . sentences :
return "Daily Sentences" ;
2023-04-03 20:35:26 +00:00
case MetricCounter . footnotes :
return "Daily Footnotes" ;
case MetricCounter . citations :
return "Daily Citations" ;
case MetricCounter . pages :
return "Daily Pages" ;
2023-03-02 21:47:11 +00:00
case MetricCounter . files :
return "Total Notes" ;
}
} else if ( metric . type === MetricType . total ) {
switch ( metric . counter ) {
case MetricCounter . words :
return "Total Words" ;
case MetricCounter . characters :
return "Total Chars" ;
case MetricCounter . sentences :
return "Total Sentences" ;
2023-04-03 20:35:26 +00:00
case MetricCounter . footnotes :
return "Total Footnotes" ;
case MetricCounter . citations :
return "Total Citations" ;
case MetricCounter . pages :
return "Total Pages" ;
2023-03-02 21:47:11 +00:00
case MetricCounter . files :
return "Total Notes" ;
}
} else {
return "Select Options" ;
}
}
async function update ( statusItems ) {
$$invalidate (
0 ,
plugin . settings . statusBar = statusItems . filter ( item => {
if ( metricToString ( item . metric ) !== "Select Options" ) {
return item ;
}
} ) ,
plugin
) ;
await plugin . saveSettings ( ) ;
}
async function updateAlt ( altSItems ) {
$$invalidate (
0 ,
plugin . settings . altBar = altSItems . filter ( item => {
if ( metricToString ( item . metric ) !== "Select Options" ) {
return item ;
}
} ) ,
plugin
) ;
await plugin . saveSettings ( ) ;
}
const click _handler = async ( ) => $$invalidate ( 1 , statusItems = [ ... statusItems , JSON . parse ( JSON . stringify ( BLANK _SB _ITEM ) ) ] ) ;
const click _handler _1 = async ( ) => {
$$invalidate ( 1 , statusItems = [
{
prefix : "" ,
suffix : " words" ,
metric : {
type : MetricType . file ,
counter : MetricCounter . words
}
} ,
{
prefix : " " ,
suffix : " characters" ,
metric : {
type : MetricType . file ,
counter : MetricCounter . characters
}
}
] ) ;
await update ( statusItems ) ;
} ;
const click _handler _2 = async i => {
$$invalidate ( 1 , statusItems = swapStatusBarItems ( i , i - 1 , statusItems ) ) ;
await update ( statusItems ) ;
} ;
const click _handler _3 = async i => {
$$invalidate ( 1 , statusItems = swapStatusBarItems ( i , i + 1 , statusItems ) ) ;
await update ( statusItems ) ;
} ;
const click _handler _4 = async i => {
$$invalidate ( 1 , statusItems = statusItems . filter ( ( item , j ) => i !== j ) ) ;
await update ( statusItems ) ;
} ;
const change _handler = async ( item , each _value _1 , i , e ) => {
const { value } = e . target ;
$$invalidate ( 1 , each _value _1 [ i ] . metric . counter = MetricCounter [ MetricCounter [ value ] ] , statusItems ) ;
await update ( statusItems ) ;
await plugin . saveSettings ( ) ;
} ;
const change _handler _1 = async ( item , each _value _1 , i , e ) => {
const { value } = e . target ;
$$invalidate ( 1 , each _value _1 [ i ] . metric . type = MetricType [ MetricType [ value ] ] , statusItems ) ;
await update ( statusItems ) ;
await plugin . saveSettings ( ) ;
} ;
const change _handler _2 = async ( item , each _value _1 , i , e ) => {
const { value } = e . target ;
$$invalidate ( 1 , each _value _1 [ i ] . prefix = value , statusItems ) ;
await update ( statusItems ) ;
await plugin . saveSettings ( ) ;
} ;
const change _handler _3 = async ( item , each _value _1 , i , e ) => {
const { value } = e . target ;
$$invalidate ( 1 , each _value _1 [ i ] . suffix = value , statusItems ) ;
await update ( statusItems ) ;
await plugin . saveSettings ( ) ;
} ;
const click _handler _5 = async ( ) => $$invalidate ( 2 , altSItems = [ ... altSItems , JSON . parse ( JSON . stringify ( BLANK _SB _ITEM ) ) ] ) ;
const click _handler _6 = async ( ) => {
$$invalidate ( 2 , altSItems = [
{
prefix : "" ,
suffix : " files" ,
metric : {
type : MetricType . total ,
counter : MetricCounter . files
}
}
] ) ;
await update ( statusItems ) ;
} ;
const click _handler _7 = async i => {
$$invalidate ( 2 , altSItems = swapStatusBarItems ( i , i - 1 , altSItems ) ) ;
await updateAlt ( altSItems ) ;
} ;
const click _handler _8 = async i => {
$$invalidate ( 2 , altSItems = swapStatusBarItems ( i , i + 1 , altSItems ) ) ;
await updateAlt ( altSItems ) ;
} ;
const click _handler _9 = async i => {
$$invalidate ( 2 , altSItems = altSItems . filter ( ( item , j ) => i !== j ) ) ;
await updateAlt ( altSItems ) ;
} ;
const change _handler _4 = async ( item , each _value , i , e ) => {
const { value } = e . target ;
$$invalidate ( 2 , each _value [ i ] . metric . counter = MetricCounter [ MetricCounter [ value ] ] , altSItems ) ;
await updateAlt ( altSItems ) ;
await plugin . saveSettings ( ) ;
} ;
const change _handler _5 = async ( item , each _value , i , e ) => {
const { value } = e . target ;
$$invalidate ( 2 , each _value [ i ] . metric . type = MetricType [ MetricType [ value ] ] , altSItems ) ;
await updateAlt ( altSItems ) ;
await plugin . saveSettings ( ) ;
} ;
const change _handler _6 = async ( item , each _value , i , e ) => {
const { value } = e . target ;
$$invalidate ( 2 , each _value [ i ] . prefix = value , altSItems ) ;
await updateAlt ( altSItems ) ;
await plugin . saveSettings ( ) ;
} ;
const change _handler _7 = async ( item , each _value , i , e ) => {
const { value } = e . target ;
$$invalidate ( 2 , each _value [ i ] . suffix = value , altSItems ) ;
await updateAlt ( altSItems ) ;
await plugin . saveSettings ( ) ;
} ;
$$self . $$set = $$props => {
if ( 'plugin' in $$props ) $$invalidate ( 0 , plugin = $$props . plugin ) ;
} ;
return [
plugin ,
statusItems ,
altSItems ,
metricToString ,
update ,
updateAlt ,
click _handler ,
click _handler _1 ,
click _handler _2 ,
click _handler _3 ,
click _handler _4 ,
change _handler ,
change _handler _1 ,
change _handler _2 ,
change _handler _3 ,
click _handler _5 ,
click _handler _6 ,
click _handler _7 ,
click _handler _8 ,
click _handler _9 ,
change _handler _4 ,
change _handler _5 ,
change _handler _6 ,
change _handler _7
] ;
}
class StatusBarSettings extends SvelteComponent {
constructor ( options ) {
super ( ) ;
init ( this , options , instance , create _fragment , safe _not _equal , { plugin : 0 } ) ;
}
}
function addStatusBarSettings ( plugin , containerEl ) {
const statusItemsEl = containerEl . createEl ( "div" ) ;
new StatusBarSettings ( {
target : statusItemsEl ,
props : { plugin } ,
} ) ;
}
class BetterWordCountSettingsTab extends obsidian . PluginSettingTab {
constructor ( app , plugin ) {
super ( app , plugin ) ;
this . plugin = plugin ;
}
display ( ) {
let { containerEl } = this ;
containerEl . empty ( ) ;
containerEl . createEl ( "h3" , { text : "Better Word Count Settings" } ) ;
// General Settings
containerEl . createEl ( "h4" , { text : "General Settings" } ) ;
new obsidian . Setting ( containerEl )
. setName ( "Collect Statistics" )
. setDesc ( "Reload Required for change to take effect. Turn on to start collecting daily statistics of your writing. Stored in the vault-stats.json file in the .obsidian of your vault. This is required for counts of the day as well as total counts." )
. addToggle ( ( cb ) => {
cb . setValue ( this . plugin . settings . collectStats ) ;
cb . onChange ( async ( value ) => {
this . plugin . settings . collectStats = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
new obsidian . Setting ( containerEl )
. setName ( "Don't Count Comments" )
. setDesc ( "Turn on if you don't want markdown comments to be counted." )
. addToggle ( ( cb ) => {
cb . setValue ( this . plugin . settings . countComments ) ;
cb . onChange ( async ( value ) => {
this . plugin . settings . countComments = value ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
2023-08-21 17:47:20 +00:00
new obsidian . Setting ( containerEl )
. setName ( "Display Section Word Count" )
. setDesc ( "Turn on if you want to display section word counts next to headings." )
. addToggle ( ( cb ) => {
cb . setValue ( this . plugin . settings . displaySectionCounts ) ;
cb . onChange ( async ( value ) => {
this . plugin . settings . displaySectionCounts = value ;
this . plugin . onDisplaySectionCountsChange ( ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
2023-04-03 20:35:26 +00:00
new obsidian . Setting ( containerEl )
. setName ( "Page Word Count" )
. setDesc ( "Set how many words count as one \"page\"" )
. addText ( ( text ) => {
text . inputEl . type = "number" ;
text . setPlaceholder ( "300" ) ;
text . setValue ( this . plugin . settings . pageWords . toString ( ) ) ;
text . onChange ( async ( value ) => {
this . plugin . settings . pageWords = parseInt ( value ) ;
await this . plugin . saveSettings ( ) ;
} ) ;
} ) ;
2023-03-02 21:47:11 +00:00
// Status Bar Settings
addStatusBarSettings ( this . plugin , containerEl ) ;
}
}
const STATS _FILE = ".obsidian/vault-stats.json" ;
2023-04-03 20:35:26 +00:00
const MATCH _HTML _COMMENT = new RegExp ( "<!--[\\s\\S]*?(?:-->)?" +
"<!---+>?" +
"|<!(?![dD][oO][cC][tT][yY][pP][eE]|\\[CDATA\\[)[^>]*>?" +
"|<[?][^>]*>?" , "g" ) ;
2023-08-21 17:47:20 +00:00
const MATCH _COMMENT = new RegExp ( "%%[\\s\\S]*?(?!%%)[\\s\\S]+?%%" , "g" ) ;
2023-03-02 21:47:11 +00:00
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : { } ;
function createCommonjsModule ( fn , basedir , module ) {
return module = {
path : basedir ,
exports : { } ,
require : function ( path , base ) {
return commonjsRequire ( path , ( base === undefined || base === null ) ? module . path : base ) ;
}
} , fn ( module , module . exports ) , module . exports ;
}
function commonjsRequire ( ) {
throw new Error ( 'Dynamic requires are not currently supported by @rollup/plugin-commonjs' ) ;
}
var moment = createCommonjsModule ( function ( module , exports ) {
( function ( global , factory ) {
module . exports = factory ( ) ;
} ( commonjsGlobal , ( function ( ) {
var hookCallback ;
function hooks ( ) {
return hookCallback . apply ( null , arguments ) ;
}
// This is done to register the method called with moment()
// without creating circular dependencies.
function setHookCallback ( callback ) {
hookCallback = callback ;
}
function isArray ( input ) {
return (
input instanceof Array ||
Object . prototype . toString . call ( input ) === '[object Array]'
) ;
}
function isObject ( input ) {
// IE8 will treat undefined and null as object if it wasn't for
// input != null
return (
input != null &&
Object . prototype . toString . call ( input ) === '[object Object]'
) ;
}
function hasOwnProp ( a , b ) {
return Object . prototype . hasOwnProperty . call ( a , b ) ;
}
function isObjectEmpty ( obj ) {
if ( Object . getOwnPropertyNames ) {
return Object . getOwnPropertyNames ( obj ) . length === 0 ;
} else {
var k ;
for ( k in obj ) {
if ( hasOwnProp ( obj , k ) ) {
return false ;
}
}
return true ;
}
}
function isUndefined ( input ) {
return input === void 0 ;
}
function isNumber ( input ) {
return (
typeof input === 'number' ||
Object . prototype . toString . call ( input ) === '[object Number]'
) ;
}
function isDate ( input ) {
return (
input instanceof Date ||
Object . prototype . toString . call ( input ) === '[object Date]'
) ;
}
function map ( arr , fn ) {
var res = [ ] ,
i ,
arrLen = arr . length ;
for ( i = 0 ; i < arrLen ; ++ i ) {
res . push ( fn ( arr [ i ] , i ) ) ;
}
return res ;
}
function extend ( a , b ) {
for ( var i in b ) {
if ( hasOwnProp ( b , i ) ) {
a [ i ] = b [ i ] ;
}
}
if ( hasOwnProp ( b , 'toString' ) ) {
a . toString = b . toString ;
}
if ( hasOwnProp ( b , 'valueOf' ) ) {
a . valueOf = b . valueOf ;
}
return a ;
}
function createUTC ( input , format , locale , strict ) {
return createLocalOrUTC ( input , format , locale , strict , true ) . utc ( ) ;
}
function defaultParsingFlags ( ) {
// We need to deep clone this object.
return {
empty : false ,
unusedTokens : [ ] ,
unusedInput : [ ] ,
overflow : - 2 ,
charsLeftOver : 0 ,
nullInput : false ,
invalidEra : null ,
invalidMonth : null ,
invalidFormat : false ,
userInvalidated : false ,
iso : false ,
parsedDateParts : [ ] ,
era : null ,
meridiem : null ,
rfc2822 : false ,
weekdayMismatch : false ,
} ;
}
function getParsingFlags ( m ) {
if ( m . _pf == null ) {
m . _pf = defaultParsingFlags ( ) ;
}
return m . _pf ;
}
var some ;
if ( Array . prototype . some ) {
some = Array . prototype . some ;
} else {
some = function ( fun ) {
var t = Object ( this ) ,
len = t . length >>> 0 ,
i ;
for ( i = 0 ; i < len ; i ++ ) {
if ( i in t && fun . call ( this , t [ i ] , i , t ) ) {
return true ;
}
}
return false ;
} ;
}
function isValid ( m ) {
if ( m . _isValid == null ) {
var flags = getParsingFlags ( m ) ,
parsedParts = some . call ( flags . parsedDateParts , function ( i ) {
return i != null ;
} ) ,
isNowValid =
! isNaN ( m . _d . getTime ( ) ) &&
flags . overflow < 0 &&
! flags . empty &&
! flags . invalidEra &&
! flags . invalidMonth &&
! flags . invalidWeekday &&
! flags . weekdayMismatch &&
! flags . nullInput &&
! flags . invalidFormat &&
! flags . userInvalidated &&
( ! flags . meridiem || ( flags . meridiem && parsedParts ) ) ;
if ( m . _strict ) {
isNowValid =
isNowValid &&
flags . charsLeftOver === 0 &&
flags . unusedTokens . length === 0 &&
flags . bigHour === undefined ;
}
if ( Object . isFrozen == null || ! Object . isFrozen ( m ) ) {
m . _isValid = isNowValid ;
} else {
return isNowValid ;
}
}
return m . _isValid ;
}
function createInvalid ( flags ) {
var m = createUTC ( NaN ) ;
if ( flags != null ) {
extend ( getParsingFlags ( m ) , flags ) ;
} else {
getParsingFlags ( m ) . userInvalidated = true ;
}
return m ;
}
// Plugins that add properties should also add the key here (null value),
// so we can properly clone ourselves.
var momentProperties = ( hooks . momentProperties = [ ] ) ,
updateInProgress = false ;
function copyConfig ( to , from ) {
var i ,
prop ,
val ,
momentPropertiesLen = momentProperties . length ;
if ( ! isUndefined ( from . _isAMomentObject ) ) {
to . _isAMomentObject = from . _isAMomentObject ;
}
if ( ! isUndefined ( from . _i ) ) {
to . _i = from . _i ;
}
if ( ! isUndefined ( from . _f ) ) {
to . _f = from . _f ;
}
if ( ! isUndefined ( from . _l ) ) {
to . _l = from . _l ;
}
if ( ! isUndefined ( from . _strict ) ) {
to . _strict = from . _strict ;
}
if ( ! isUndefined ( from . _tzm ) ) {
to . _tzm = from . _tzm ;
}
if ( ! isUndefined ( from . _isUTC ) ) {
to . _isUTC = from . _isUTC ;
}
if ( ! isUndefined ( from . _offset ) ) {
to . _offset = from . _offset ;
}
if ( ! isUndefined ( from . _pf ) ) {
to . _pf = getParsingFlags ( from ) ;
}
if ( ! isUndefined ( from . _locale ) ) {
to . _locale = from . _locale ;
}
if ( momentPropertiesLen > 0 ) {
for ( i = 0 ; i < momentPropertiesLen ; i ++ ) {
prop = momentProperties [ i ] ;
val = from [ prop ] ;
if ( ! isUndefined ( val ) ) {
to [ prop ] = val ;
}
}
}
return to ;
}
// Moment prototype object
function Moment ( config ) {
copyConfig ( this , config ) ;
this . _d = new Date ( config . _d != null ? config . _d . getTime ( ) : NaN ) ;
if ( ! this . isValid ( ) ) {
this . _d = new Date ( NaN ) ;
}
// Prevent infinite loop in case updateOffset creates new moment
// objects.
if ( updateInProgress === false ) {
updateInProgress = true ;
hooks . updateOffset ( this ) ;
updateInProgress = false ;
}
}
function isMoment ( obj ) {
return (
obj instanceof Moment || ( obj != null && obj . _isAMomentObject != null )
) ;
}
function warn ( msg ) {
if (
hooks . suppressDeprecationWarnings === false &&
typeof console !== 'undefined' &&
console . warn
) {
console . warn ( 'Deprecation warning: ' + msg ) ;
}
}
function deprecate ( msg , fn ) {
var firstTime = true ;
return extend ( function ( ) {
if ( hooks . deprecationHandler != null ) {
hooks . deprecationHandler ( null , msg ) ;
}
if ( firstTime ) {
var args = [ ] ,
arg ,
i ,
key ,
argLen = arguments . length ;
for ( i = 0 ; i < argLen ; i ++ ) {
arg = '' ;
if ( typeof arguments [ i ] === 'object' ) {
arg += '\n[' + i + '] ' ;
for ( key in arguments [ 0 ] ) {
if ( hasOwnProp ( arguments [ 0 ] , key ) ) {
arg += key + ': ' + arguments [ 0 ] [ key ] + ', ' ;
}
}
arg = arg . slice ( 0 , - 2 ) ; // Remove trailing comma and space
} else {
arg = arguments [ i ] ;
}
args . push ( arg ) ;
}
warn (
msg +
'\nArguments: ' +
Array . prototype . slice . call ( args ) . join ( '' ) +
'\n' +
new Error ( ) . stack
) ;
firstTime = false ;
}
return fn . apply ( this , arguments ) ;
} , fn ) ;
}
var deprecations = { } ;
function deprecateSimple ( name , msg ) {
if ( hooks . deprecationHandler != null ) {
hooks . deprecationHandler ( name , msg ) ;
}
if ( ! deprecations [ name ] ) {
warn ( msg ) ;
deprecations [ name ] = true ;
}
}
hooks . suppressDeprecationWarnings = false ;
hooks . deprecationHandler = null ;
function isFunction ( input ) {
return (
( typeof Function !== 'undefined' && input instanceof Function ) ||
Object . prototype . toString . call ( input ) === '[object Function]'
) ;
}
function set ( config ) {
var prop , i ;
for ( i in config ) {
if ( hasOwnProp ( config , i ) ) {
prop = config [ i ] ;
if ( isFunction ( prop ) ) {
this [ i ] = prop ;
} else {
this [ '_' + i ] = prop ;
}
}
}
this . _config = config ;
// Lenient ordinal parsing accepts just a number in addition to
// number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
// TODO: Remove "ordinalParse" fallback in next major release.
this . _dayOfMonthOrdinalParseLenient = new RegExp (
( this . _dayOfMonthOrdinalParse . source || this . _ordinalParse . source ) +
'|' +
/\d{1,2}/ . source
) ;
}
function mergeConfigs ( parentConfig , childConfig ) {
var res = extend ( { } , parentConfig ) ,
prop ;
for ( prop in childConfig ) {
if ( hasOwnProp ( childConfig , prop ) ) {
if ( isObject ( parentConfig [ prop ] ) && isObject ( childConfig [ prop ] ) ) {
res [ prop ] = { } ;
extend ( res [ prop ] , parentConfig [ prop ] ) ;
extend ( res [ prop ] , childConfig [ prop ] ) ;
} else if ( childConfig [ prop ] != null ) {
res [ prop ] = childConfig [ prop ] ;
} else {
delete res [ prop ] ;
}
}
}
for ( prop in parentConfig ) {
if (
hasOwnProp ( parentConfig , prop ) &&
! hasOwnProp ( childConfig , prop ) &&
isObject ( parentConfig [ prop ] )
) {
// make sure changes to properties don't modify parent config
res [ prop ] = extend ( { } , res [ prop ] ) ;
}
}
return res ;
}
function Locale ( config ) {
if ( config != null ) {
this . set ( config ) ;
}
}
var keys ;
if ( Object . keys ) {
keys = Object . keys ;
} else {
keys = function ( obj ) {
var i ,
res = [ ] ;
for ( i in obj ) {
if ( hasOwnProp ( obj , i ) ) {
res . push ( i ) ;
}
}
return res ;
} ;
}
var defaultCalendar = {
sameDay : '[Today at] LT' ,
nextDay : '[Tomorrow at] LT' ,
nextWeek : 'dddd [at] LT' ,
lastDay : '[Yesterday at] LT' ,
lastWeek : '[Last] dddd [at] LT' ,
sameElse : 'L' ,
} ;
function calendar ( key , mom , now ) {
var output = this . _calendar [ key ] || this . _calendar [ 'sameElse' ] ;
return isFunction ( output ) ? output . call ( mom , now ) : output ;
}
function zeroFill ( number , targetLength , forceSign ) {
var absNumber = '' + Math . abs ( number ) ,
zerosToFill = targetLength - absNumber . length ,
sign = number >= 0 ;
return (
( sign ? ( forceSign ? '+' : '' ) : '-' ) +
Math . pow ( 10 , Math . max ( 0 , zerosToFill ) ) . toString ( ) . substr ( 1 ) +
absNumber
) ;
}
var formattingTokens =
/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g ,
localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g ,
formatFunctions = { } ,
formatTokenFunctions = { } ;
// token: 'M'
// padded: ['MM', 2]
// ordinal: 'Mo'
// callback: function () { this.month() + 1 }
function addFormatToken ( token , padded , ordinal , callback ) {
var func = callback ;
if ( typeof callback === 'string' ) {
func = function ( ) {
return this [ callback ] ( ) ;
} ;
}
if ( token ) {
formatTokenFunctions [ token ] = func ;
}
if ( padded ) {
formatTokenFunctions [ padded [ 0 ] ] = function ( ) {
return zeroFill ( func . apply ( this , arguments ) , padded [ 1 ] , padded [ 2 ] ) ;
} ;
}
if ( ordinal ) {
formatTokenFunctions [ ordinal ] = function ( ) {
return this . localeData ( ) . ordinal (
func . apply ( this , arguments ) ,
token
) ;
} ;
}
}
function removeFormattingTokens ( input ) {
if ( input . match ( /\[[\s\S]/ ) ) {
return input . replace ( /^\[|\]$/g , '' ) ;
}
return input . replace ( /\\/g , '' ) ;
}
function makeFormatFunction ( format ) {
var array = format . match ( formattingTokens ) ,
i ,
length ;
for ( i = 0 , length = array . length ; i < length ; i ++ ) {
if ( formatTokenFunctions [ array [ i ] ] ) {
array [ i ] = formatTokenFunctions [ array [ i ] ] ;
} else {
array [ i ] = removeFormattingTokens ( array [ i ] ) ;
}
}
return function ( mom ) {
var output = '' ,
i ;
for ( i = 0 ; i < length ; i ++ ) {
output += isFunction ( array [ i ] )
? array [ i ] . call ( mom , format )
: array [ i ] ;
}
return output ;
} ;
}
// format date using native date object
function formatMoment ( m , format ) {
if ( ! m . isValid ( ) ) {
return m . localeData ( ) . invalidDate ( ) ;
}
format = expandFormat ( format , m . localeData ( ) ) ;
formatFunctions [ format ] =
formatFunctions [ format ] || makeFormatFunction ( format ) ;
return formatFunctions [ format ] ( m ) ;
}
function expandFormat ( format , locale ) {
var i = 5 ;
function replaceLongDateFormatTokens ( input ) {
return locale . longDateFormat ( input ) || input ;
}
localFormattingTokens . lastIndex = 0 ;
while ( i >= 0 && localFormattingTokens . test ( format ) ) {
format = format . replace (
localFormattingTokens ,
replaceLongDateFormatTokens
) ;
localFormattingTokens . lastIndex = 0 ;
i -= 1 ;
}
return format ;
}
var defaultLongDateFormat = {
LTS : 'h:mm:ss A' ,
LT : 'h:mm A' ,
L : 'MM/DD/YYYY' ,
LL : 'MMMM D, YYYY' ,
LLL : 'MMMM D, YYYY h:mm A' ,
LLLL : 'dddd, MMMM D, YYYY h:mm A' ,
} ;
function longDateFormat ( key ) {
var format = this . _longDateFormat [ key ] ,
formatUpper = this . _longDateFormat [ key . toUpperCase ( ) ] ;
if ( format || ! formatUpper ) {
return format ;
}
this . _longDateFormat [ key ] = formatUpper
. match ( formattingTokens )
. map ( function ( tok ) {
if (
tok === 'MMMM' ||
tok === 'MM' ||
tok === 'DD' ||
tok === 'dddd'
) {
return tok . slice ( 1 ) ;
}
return tok ;
} )
. join ( '' ) ;
return this . _longDateFormat [ key ] ;
}
var defaultInvalidDate = 'Invalid date' ;
function invalidDate ( ) {
return this . _invalidDate ;
}
var defaultOrdinal = '%d' ,
defaultDayOfMonthOrdinalParse = /\d{1,2}/ ;
function ordinal ( number ) {
return this . _ordinal . replace ( '%d' , number ) ;
}
var defaultRelativeTime = {
future : 'in %s' ,
past : '%s ago' ,
s : 'a few seconds' ,
ss : '%d seconds' ,
m : 'a minute' ,
mm : '%d minutes' ,
h : 'an hour' ,
hh : '%d hours' ,
d : 'a day' ,
dd : '%d days' ,
w : 'a week' ,
ww : '%d weeks' ,
M : 'a month' ,
MM : '%d months' ,
y : 'a year' ,
yy : '%d years' ,
} ;
function relativeTime ( number , withoutSuffix , string , isFuture ) {
var output = this . _relativeTime [ string ] ;
return isFunction ( output )
? output ( number , withoutSuffix , string , isFuture )
: output . replace ( /%d/i , number ) ;
}
function pastFuture ( diff , output ) {
var format = this . _relativeTime [ diff > 0 ? 'future' : 'past' ] ;
return isFunction ( format ) ? format ( output ) : format . replace ( /%s/i , output ) ;
}
var aliases = { } ;
function addUnitAlias ( unit , shorthand ) {
var lowerCase = unit . toLowerCase ( ) ;
aliases [ lowerCase ] = aliases [ lowerCase + 's' ] = aliases [ shorthand ] = unit ;
}
function normalizeUnits ( units ) {
return typeof units === 'string'
? aliases [ units ] || aliases [ units . toLowerCase ( ) ]
: undefined ;
}
function normalizeObjectUnits ( inputObject ) {
var normalizedInput = { } ,
normalizedProp ,
prop ;
for ( prop in inputObject ) {
if ( hasOwnProp ( inputObject , prop ) ) {
normalizedProp = normalizeUnits ( prop ) ;
if ( normalizedProp ) {
normalizedInput [ normalizedProp ] = inputObject [ prop ] ;
}
}
}
return normalizedInput ;
}
var priorities = { } ;
function addUnitPriority ( unit , priority ) {
priorities [ unit ] = priority ;
}
function getPrioritizedUnits ( unitsObj ) {
var units = [ ] ,
u ;
for ( u in unitsObj ) {
if ( hasOwnProp ( unitsObj , u ) ) {
units . push ( { unit : u , priority : priorities [ u ] } ) ;
}
}
units . sort ( function ( a , b ) {
return a . priority - b . priority ;
} ) ;
return units ;
}
function isLeapYear ( year ) {
return ( year % 4 === 0 && year % 100 !== 0 ) || year % 400 === 0 ;
}
function absFloor ( number ) {
if ( number < 0 ) {
// -0 -> 0
return Math . ceil ( number ) || 0 ;
} else {
return Math . floor ( number ) ;
}
}
function toInt ( argumentForCoercion ) {
var coercedNumber = + argumentForCoercion ,
value = 0 ;
if ( coercedNumber !== 0 && isFinite ( coercedNumber ) ) {
value = absFloor ( coercedNumber ) ;
}
return value ;
}
function makeGetSet ( unit , keepTime ) {
return function ( value ) {
if ( value != null ) {
set$1 ( this , unit , value ) ;
hooks . updateOffset ( this , keepTime ) ;
return this ;
} else {
return get ( this , unit ) ;
}
} ;
}
function get ( mom , unit ) {
return mom . isValid ( )
? mom . _d [ 'get' + ( mom . _isUTC ? 'UTC' : '' ) + unit ] ( )
: NaN ;
}
function set$1 ( mom , unit , value ) {
if ( mom . isValid ( ) && ! isNaN ( value ) ) {
if (
unit === 'FullYear' &&
isLeapYear ( mom . year ( ) ) &&
mom . month ( ) === 1 &&
mom . date ( ) === 29
) {
value = toInt ( value ) ;
mom . _d [ 'set' + ( mom . _isUTC ? 'UTC' : '' ) + unit ] (
value ,
mom . month ( ) ,
daysInMonth ( value , mom . month ( ) )
) ;
} else {
mom . _d [ 'set' + ( mom . _isUTC ? 'UTC' : '' ) + unit ] ( value ) ;
}
}
}
// MOMENTS
function stringGet ( units ) {
units = normalizeUnits ( units ) ;
if ( isFunction ( this [ units ] ) ) {
return this [ units ] ( ) ;
}
return this ;
}
function stringSet ( units , value ) {
if ( typeof units === 'object' ) {
units = normalizeObjectUnits ( units ) ;
var prioritized = getPrioritizedUnits ( units ) ,
i ,
prioritizedLen = prioritized . length ;
for ( i = 0 ; i < prioritizedLen ; i ++ ) {
this [ prioritized [ i ] . unit ] ( units [ prioritized [ i ] . unit ] ) ;
}
} else {
units = normalizeUnits ( units ) ;
if ( isFunction ( this [ units ] ) ) {
return this [ units ] ( value ) ;
}
}
return this ;
}
var match1 = /\d/ , // 0 - 9
match2 = /\d\d/ , // 00 - 99
match3 = /\d{3}/ , // 000 - 999
match4 = /\d{4}/ , // 0000 - 9999
match6 = /[+-]?\d{6}/ , // -999999 - 999999
match1to2 = /\d\d?/ , // 0 - 99
match3to4 = /\d\d\d\d?/ , // 999 - 9999
match5to6 = /\d\d\d\d\d\d?/ , // 99999 - 999999
match1to3 = /\d{1,3}/ , // 0 - 999
match1to4 = /\d{1,4}/ , // 0 - 9999
match1to6 = /[+-]?\d{1,6}/ , // -999999 - 999999
matchUnsigned = /\d+/ , // 0 - inf
matchSigned = /[+-]?\d+/ , // -inf - inf
matchOffset = /Z|[+-]\d\d:?\d\d/gi , // +00:00 -00:00 +0000 -0000 or Z
matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi , // +00 -00 +00:00 -00:00 +0000 -0000 or Z
matchTimestamp = /[+-]?\d+(\.\d{1,3})?/ , // 123456789 123456789.123
// any word (or two) characters or numbers including two/three word month in arabic.
// includes scottish gaelic two word and hyphenated months
matchWord =
/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i ,
regexes ;
regexes = { } ;
function addRegexToken ( token , regex , strictRegex ) {
regexes [ token ] = isFunction ( regex )
? regex
: function ( isStrict , localeData ) {
return isStrict && strictRegex ? strictRegex : regex ;
} ;
}
function getParseRegexForToken ( token , config ) {
if ( ! hasOwnProp ( regexes , token ) ) {
return new RegExp ( unescapeFormat ( token ) ) ;
}
return regexes [ token ] ( config . _strict , config . _locale ) ;
}
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function unescapeFormat ( s ) {
return regexEscape (
s
. replace ( '\\' , '' )
. replace (
/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g ,
function ( matched , p1 , p2 , p3 , p4 ) {
return p1 || p2 || p3 || p4 ;
}
)
) ;
}
function regexEscape ( s ) {
return s . replace ( /[-\/\\^$*+?.()|[\]{}]/g , '\\$&' ) ;
}
var tokens = { } ;
function addParseToken ( token , callback ) {
var i ,
func = callback ,
tokenLen ;
if ( typeof token === 'string' ) {
token = [ token ] ;
}
if ( isNumber ( callback ) ) {
func = function ( input , array ) {
array [ callback ] = toInt ( input ) ;
} ;
}
tokenLen = token . length ;
for ( i = 0 ; i < tokenLen ; i ++ ) {
tokens [ token [ i ] ] = func ;
}
}
function addWeekParseToken ( token , callback ) {
addParseToken ( token , function ( input , array , config , token ) {
config . _w = config . _w || { } ;
callback ( input , config . _w , config , token ) ;
} ) ;
}
function addTimeToArrayFromToken ( token , input , config ) {
if ( input != null && hasOwnProp ( tokens , token ) ) {
tokens [ token ] ( input , config . _a , config , token ) ;
}
}
var YEAR = 0 ,
MONTH = 1 ,
DATE = 2 ,
HOUR = 3 ,
MINUTE = 4 ,
SECOND = 5 ,
MILLISECOND = 6 ,
WEEK = 7 ,
WEEKDAY = 8 ;
function mod ( n , x ) {
return ( ( n % x ) + x ) % x ;
}
var indexOf ;
if ( Array . prototype . indexOf ) {
indexOf = Array . prototype . indexOf ;
} else {
indexOf = function ( o ) {
// I know
var i ;
for ( i = 0 ; i < this . length ; ++ i ) {
if ( this [ i ] === o ) {
return i ;
}
}
return - 1 ;
} ;
}
function daysInMonth ( year , month ) {
if ( isNaN ( year ) || isNaN ( month ) ) {
return NaN ;
}
var modMonth = mod ( month , 12 ) ;
year += ( month - modMonth ) / 12 ;
return modMonth === 1
? isLeapYear ( year )
? 29
: 28
: 31 - ( ( modMonth % 7 ) % 2 ) ;
}
// FORMATTING
addFormatToken ( 'M' , [ 'MM' , 2 ] , 'Mo' , function ( ) {
return this . month ( ) + 1 ;
} ) ;
addFormatToken ( 'MMM' , 0 , 0 , function ( format ) {
return this . localeData ( ) . monthsShort ( this , format ) ;
} ) ;
addFormatToken ( 'MMMM' , 0 , 0 , function ( format ) {
return this . localeData ( ) . months ( this , format ) ;
} ) ;
// ALIASES
addUnitAlias ( 'month' , 'M' ) ;
// PRIORITY
addUnitPriority ( 'month' , 8 ) ;
// PARSING
addRegexToken ( 'M' , match1to2 ) ;
addRegexToken ( 'MM' , match1to2 , match2 ) ;
addRegexToken ( 'MMM' , function ( isStrict , locale ) {
return locale . monthsShortRegex ( isStrict ) ;
} ) ;
addRegexToken ( 'MMMM' , function ( isStrict , locale ) {
return locale . monthsRegex ( isStrict ) ;
} ) ;
addParseToken ( [ 'M' , 'MM' ] , function ( input , array ) {
array [ MONTH ] = toInt ( input ) - 1 ;
} ) ;
addParseToken ( [ 'MMM' , 'MMMM' ] , function ( input , array , config , token ) {
var month = config . _locale . monthsParse ( input , token , config . _strict ) ;
// if we didn't find a month name, mark the date as invalid.
if ( month != null ) {
array [ MONTH ] = month ;
} else {
getParsingFlags ( config ) . invalidMonth = input ;
}
} ) ;
// LOCALES
var defaultLocaleMonths =
'January_February_March_April_May_June_July_August_September_October_November_December' . split (
'_'
) ,
defaultLocaleMonthsShort =
'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec' . split ( '_' ) ,
MONTHS _IN _FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/ ,
defaultMonthsShortRegex = matchWord ,
defaultMonthsRegex = matchWord ;
function localeMonths ( m , format ) {
if ( ! m ) {
return isArray ( this . _months )
? this . _months
: this . _months [ 'standalone' ] ;
}
return isArray ( this . _months )
? this . _months [ m . month ( ) ]
: this . _months [
( this . _months . isFormat || MONTHS _IN _FORMAT ) . test ( format )
? 'format'
: 'standalone'
] [ m . month ( ) ] ;
}
function localeMonthsShort ( m , format ) {
if ( ! m ) {
return isArray ( this . _monthsShort )
? this . _monthsShort
: this . _monthsShort [ 'standalone' ] ;
}
return isArray ( this . _monthsShort )
? this . _monthsShort [ m . month ( ) ]
: this . _monthsShort [
MONTHS _IN _FORMAT . test ( format ) ? 'format' : 'standalone'
] [ m . month ( ) ] ;
}
function handleStrictParse ( monthName , format , strict ) {
var i ,
ii ,
mom ,
llc = monthName . toLocaleLowerCase ( ) ;
if ( ! this . _monthsParse ) {
// this is not used
this . _monthsParse = [ ] ;
this . _longMonthsParse = [ ] ;
this . _shortMonthsParse = [ ] ;
for ( i = 0 ; i < 12 ; ++ i ) {
mom = createUTC ( [ 2000 , i ] ) ;
this . _shortMonthsParse [ i ] = this . monthsShort (
mom ,
''
) . toLocaleLowerCase ( ) ;
this . _longMonthsParse [ i ] = this . months ( mom , '' ) . toLocaleLowerCase ( ) ;
}
}
if ( strict ) {
if ( format === 'MMM' ) {
ii = indexOf . call ( this . _shortMonthsParse , llc ) ;
return ii !== - 1 ? ii : null ;
} else {
ii = indexOf . call ( this . _longMonthsParse , llc ) ;
return ii !== - 1 ? ii : null ;
}
} else {
if ( format === 'MMM' ) {
ii = indexOf . call ( this . _shortMonthsParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _longMonthsParse , llc ) ;
return ii !== - 1 ? ii : null ;
} else {
ii = indexOf . call ( this . _longMonthsParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _shortMonthsParse , llc ) ;
return ii !== - 1 ? ii : null ;
}
}
}
function localeMonthsParse ( monthName , format , strict ) {
var i , mom , regex ;
if ( this . _monthsParseExact ) {
return handleStrictParse . call ( this , monthName , format , strict ) ;
}
if ( ! this . _monthsParse ) {
this . _monthsParse = [ ] ;
this . _longMonthsParse = [ ] ;
this . _shortMonthsParse = [ ] ;
}
// TODO: add sorting
// Sorting makes sure if one month (or abbr) is a prefix of another
// see sorting in computeMonthsParse
for ( i = 0 ; i < 12 ; i ++ ) {
// make the regex if we don't have it already
mom = createUTC ( [ 2000 , i ] ) ;
if ( strict && ! this . _longMonthsParse [ i ] ) {
this . _longMonthsParse [ i ] = new RegExp (
'^' + this . months ( mom , '' ) . replace ( '.' , '' ) + '$' ,
'i'
) ;
this . _shortMonthsParse [ i ] = new RegExp (
'^' + this . monthsShort ( mom , '' ) . replace ( '.' , '' ) + '$' ,
'i'
) ;
}
if ( ! strict && ! this . _monthsParse [ i ] ) {
regex =
'^' + this . months ( mom , '' ) + '|^' + this . monthsShort ( mom , '' ) ;
this . _monthsParse [ i ] = new RegExp ( regex . replace ( '.' , '' ) , 'i' ) ;
}
// test the regex
if (
strict &&
format === 'MMMM' &&
this . _longMonthsParse [ i ] . test ( monthName )
) {
return i ;
} else if (
strict &&
format === 'MMM' &&
this . _shortMonthsParse [ i ] . test ( monthName )
) {
return i ;
} else if ( ! strict && this . _monthsParse [ i ] . test ( monthName ) ) {
return i ;
}
}
}
// MOMENTS
function setMonth ( mom , value ) {
var dayOfMonth ;
if ( ! mom . isValid ( ) ) {
// No op
return mom ;
}
if ( typeof value === 'string' ) {
if ( /^\d+$/ . test ( value ) ) {
value = toInt ( value ) ;
} else {
value = mom . localeData ( ) . monthsParse ( value ) ;
// TODO: Another silent failure?
if ( ! isNumber ( value ) ) {
return mom ;
}
}
}
dayOfMonth = Math . min ( mom . date ( ) , daysInMonth ( mom . year ( ) , value ) ) ;
mom . _d [ 'set' + ( mom . _isUTC ? 'UTC' : '' ) + 'Month' ] ( value , dayOfMonth ) ;
return mom ;
}
function getSetMonth ( value ) {
if ( value != null ) {
setMonth ( this , value ) ;
hooks . updateOffset ( this , true ) ;
return this ;
} else {
return get ( this , 'Month' ) ;
}
}
function getDaysInMonth ( ) {
return daysInMonth ( this . year ( ) , this . month ( ) ) ;
}
function monthsShortRegex ( isStrict ) {
if ( this . _monthsParseExact ) {
if ( ! hasOwnProp ( this , '_monthsRegex' ) ) {
computeMonthsParse . call ( this ) ;
}
if ( isStrict ) {
return this . _monthsShortStrictRegex ;
} else {
return this . _monthsShortRegex ;
}
} else {
if ( ! hasOwnProp ( this , '_monthsShortRegex' ) ) {
this . _monthsShortRegex = defaultMonthsShortRegex ;
}
return this . _monthsShortStrictRegex && isStrict
? this . _monthsShortStrictRegex
: this . _monthsShortRegex ;
}
}
function monthsRegex ( isStrict ) {
if ( this . _monthsParseExact ) {
if ( ! hasOwnProp ( this , '_monthsRegex' ) ) {
computeMonthsParse . call ( this ) ;
}
if ( isStrict ) {
return this . _monthsStrictRegex ;
} else {
return this . _monthsRegex ;
}
} else {
if ( ! hasOwnProp ( this , '_monthsRegex' ) ) {
this . _monthsRegex = defaultMonthsRegex ;
}
return this . _monthsStrictRegex && isStrict
? this . _monthsStrictRegex
: this . _monthsRegex ;
}
}
function computeMonthsParse ( ) {
function cmpLenRev ( a , b ) {
return b . length - a . length ;
}
var shortPieces = [ ] ,
longPieces = [ ] ,
mixedPieces = [ ] ,
i ,
mom ;
for ( i = 0 ; i < 12 ; i ++ ) {
// make the regex if we don't have it already
mom = createUTC ( [ 2000 , i ] ) ;
shortPieces . push ( this . monthsShort ( mom , '' ) ) ;
longPieces . push ( this . months ( mom , '' ) ) ;
mixedPieces . push ( this . months ( mom , '' ) ) ;
mixedPieces . push ( this . monthsShort ( mom , '' ) ) ;
}
// Sorting makes sure if one month (or abbr) is a prefix of another it
// will match the longer piece.
shortPieces . sort ( cmpLenRev ) ;
longPieces . sort ( cmpLenRev ) ;
mixedPieces . sort ( cmpLenRev ) ;
for ( i = 0 ; i < 12 ; i ++ ) {
shortPieces [ i ] = regexEscape ( shortPieces [ i ] ) ;
longPieces [ i ] = regexEscape ( longPieces [ i ] ) ;
}
for ( i = 0 ; i < 24 ; i ++ ) {
mixedPieces [ i ] = regexEscape ( mixedPieces [ i ] ) ;
}
this . _monthsRegex = new RegExp ( '^(' + mixedPieces . join ( '|' ) + ')' , 'i' ) ;
this . _monthsShortRegex = this . _monthsRegex ;
this . _monthsStrictRegex = new RegExp (
'^(' + longPieces . join ( '|' ) + ')' ,
'i'
) ;
this . _monthsShortStrictRegex = new RegExp (
'^(' + shortPieces . join ( '|' ) + ')' ,
'i'
) ;
}
// FORMATTING
addFormatToken ( 'Y' , 0 , 0 , function ( ) {
var y = this . year ( ) ;
return y <= 9999 ? zeroFill ( y , 4 ) : '+' + y ;
} ) ;
addFormatToken ( 0 , [ 'YY' , 2 ] , 0 , function ( ) {
return this . year ( ) % 100 ;
} ) ;
addFormatToken ( 0 , [ 'YYYY' , 4 ] , 0 , 'year' ) ;
addFormatToken ( 0 , [ 'YYYYY' , 5 ] , 0 , 'year' ) ;
addFormatToken ( 0 , [ 'YYYYYY' , 6 , true ] , 0 , 'year' ) ;
// ALIASES
addUnitAlias ( 'year' , 'y' ) ;
// PRIORITIES
addUnitPriority ( 'year' , 1 ) ;
// PARSING
addRegexToken ( 'Y' , matchSigned ) ;
addRegexToken ( 'YY' , match1to2 , match2 ) ;
addRegexToken ( 'YYYY' , match1to4 , match4 ) ;
addRegexToken ( 'YYYYY' , match1to6 , match6 ) ;
addRegexToken ( 'YYYYYY' , match1to6 , match6 ) ;
addParseToken ( [ 'YYYYY' , 'YYYYYY' ] , YEAR ) ;
addParseToken ( 'YYYY' , function ( input , array ) {
array [ YEAR ] =
input . length === 2 ? hooks . parseTwoDigitYear ( input ) : toInt ( input ) ;
} ) ;
addParseToken ( 'YY' , function ( input , array ) {
array [ YEAR ] = hooks . parseTwoDigitYear ( input ) ;
} ) ;
addParseToken ( 'Y' , function ( input , array ) {
array [ YEAR ] = parseInt ( input , 10 ) ;
} ) ;
// HELPERS
function daysInYear ( year ) {
return isLeapYear ( year ) ? 366 : 365 ;
}
// HOOKS
hooks . parseTwoDigitYear = function ( input ) {
return toInt ( input ) + ( toInt ( input ) > 68 ? 1900 : 2000 ) ;
} ;
// MOMENTS
var getSetYear = makeGetSet ( 'FullYear' , true ) ;
function getIsLeapYear ( ) {
return isLeapYear ( this . year ( ) ) ;
}
function createDate ( y , m , d , h , M , s , ms ) {
// can't just apply() to create a date:
// https://stackoverflow.com/q/181348
var date ;
// the date constructor remaps years 0-99 to 1900-1999
if ( y < 100 && y >= 0 ) {
// preserve leap years using a full 400 year cycle, then reset
date = new Date ( y + 400 , m , d , h , M , s , ms ) ;
if ( isFinite ( date . getFullYear ( ) ) ) {
date . setFullYear ( y ) ;
}
} else {
date = new Date ( y , m , d , h , M , s , ms ) ;
}
return date ;
}
function createUTCDate ( y ) {
var date , args ;
// the Date.UTC function remaps years 0-99 to 1900-1999
if ( y < 100 && y >= 0 ) {
args = Array . prototype . slice . call ( arguments ) ;
// preserve leap years using a full 400 year cycle, then reset
args [ 0 ] = y + 400 ;
date = new Date ( Date . UTC . apply ( null , args ) ) ;
if ( isFinite ( date . getUTCFullYear ( ) ) ) {
date . setUTCFullYear ( y ) ;
}
} else {
date = new Date ( Date . UTC . apply ( null , arguments ) ) ;
}
return date ;
}
// start-of-first-week - start-of-year
function firstWeekOffset ( year , dow , doy ) {
var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
fwd = 7 + dow - doy ,
// first-week day local weekday -- which local weekday is fwd
fwdlw = ( 7 + createUTCDate ( year , 0 , fwd ) . getUTCDay ( ) - dow ) % 7 ;
return - fwdlw + fwd - 1 ;
}
// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks ( year , week , weekday , dow , doy ) {
var localWeekday = ( 7 + weekday - dow ) % 7 ,
weekOffset = firstWeekOffset ( year , dow , doy ) ,
dayOfYear = 1 + 7 * ( week - 1 ) + localWeekday + weekOffset ,
resYear ,
resDayOfYear ;
if ( dayOfYear <= 0 ) {
resYear = year - 1 ;
resDayOfYear = daysInYear ( resYear ) + dayOfYear ;
} else if ( dayOfYear > daysInYear ( year ) ) {
resYear = year + 1 ;
resDayOfYear = dayOfYear - daysInYear ( year ) ;
} else {
resYear = year ;
resDayOfYear = dayOfYear ;
}
return {
year : resYear ,
dayOfYear : resDayOfYear ,
} ;
}
function weekOfYear ( mom , dow , doy ) {
var weekOffset = firstWeekOffset ( mom . year ( ) , dow , doy ) ,
week = Math . floor ( ( mom . dayOfYear ( ) - weekOffset - 1 ) / 7 ) + 1 ,
resWeek ,
resYear ;
if ( week < 1 ) {
resYear = mom . year ( ) - 1 ;
resWeek = week + weeksInYear ( resYear , dow , doy ) ;
} else if ( week > weeksInYear ( mom . year ( ) , dow , doy ) ) {
resWeek = week - weeksInYear ( mom . year ( ) , dow , doy ) ;
resYear = mom . year ( ) + 1 ;
} else {
resYear = mom . year ( ) ;
resWeek = week ;
}
return {
week : resWeek ,
year : resYear ,
} ;
}
function weeksInYear ( year , dow , doy ) {
var weekOffset = firstWeekOffset ( year , dow , doy ) ,
weekOffsetNext = firstWeekOffset ( year + 1 , dow , doy ) ;
return ( daysInYear ( year ) - weekOffset + weekOffsetNext ) / 7 ;
}
// FORMATTING
addFormatToken ( 'w' , [ 'ww' , 2 ] , 'wo' , 'week' ) ;
addFormatToken ( 'W' , [ 'WW' , 2 ] , 'Wo' , 'isoWeek' ) ;
// ALIASES
addUnitAlias ( 'week' , 'w' ) ;
addUnitAlias ( 'isoWeek' , 'W' ) ;
// PRIORITIES
addUnitPriority ( 'week' , 5 ) ;
addUnitPriority ( 'isoWeek' , 5 ) ;
// PARSING
addRegexToken ( 'w' , match1to2 ) ;
addRegexToken ( 'ww' , match1to2 , match2 ) ;
addRegexToken ( 'W' , match1to2 ) ;
addRegexToken ( 'WW' , match1to2 , match2 ) ;
addWeekParseToken (
[ 'w' , 'ww' , 'W' , 'WW' ] ,
function ( input , week , config , token ) {
week [ token . substr ( 0 , 1 ) ] = toInt ( input ) ;
}
) ;
// HELPERS
// LOCALES
function localeWeek ( mom ) {
return weekOfYear ( mom , this . _week . dow , this . _week . doy ) . week ;
}
var defaultLocaleWeek = {
dow : 0 , // Sunday is the first day of the week.
doy : 6 , // The week that contains Jan 6th is the first week of the year.
} ;
function localeFirstDayOfWeek ( ) {
return this . _week . dow ;
}
function localeFirstDayOfYear ( ) {
return this . _week . doy ;
}
// MOMENTS
function getSetWeek ( input ) {
var week = this . localeData ( ) . week ( this ) ;
return input == null ? week : this . add ( ( input - week ) * 7 , 'd' ) ;
}
function getSetISOWeek ( input ) {
var week = weekOfYear ( this , 1 , 4 ) . week ;
return input == null ? week : this . add ( ( input - week ) * 7 , 'd' ) ;
}
// FORMATTING
addFormatToken ( 'd' , 0 , 'do' , 'day' ) ;
addFormatToken ( 'dd' , 0 , 0 , function ( format ) {
return this . localeData ( ) . weekdaysMin ( this , format ) ;
} ) ;
addFormatToken ( 'ddd' , 0 , 0 , function ( format ) {
return this . localeData ( ) . weekdaysShort ( this , format ) ;
} ) ;
addFormatToken ( 'dddd' , 0 , 0 , function ( format ) {
return this . localeData ( ) . weekdays ( this , format ) ;
} ) ;
addFormatToken ( 'e' , 0 , 0 , 'weekday' ) ;
addFormatToken ( 'E' , 0 , 0 , 'isoWeekday' ) ;
// ALIASES
addUnitAlias ( 'day' , 'd' ) ;
addUnitAlias ( 'weekday' , 'e' ) ;
addUnitAlias ( 'isoWeekday' , 'E' ) ;
// PRIORITY
addUnitPriority ( 'day' , 11 ) ;
addUnitPriority ( 'weekday' , 11 ) ;
addUnitPriority ( 'isoWeekday' , 11 ) ;
// PARSING
addRegexToken ( 'd' , match1to2 ) ;
addRegexToken ( 'e' , match1to2 ) ;
addRegexToken ( 'E' , match1to2 ) ;
addRegexToken ( 'dd' , function ( isStrict , locale ) {
return locale . weekdaysMinRegex ( isStrict ) ;
} ) ;
addRegexToken ( 'ddd' , function ( isStrict , locale ) {
return locale . weekdaysShortRegex ( isStrict ) ;
} ) ;
addRegexToken ( 'dddd' , function ( isStrict , locale ) {
return locale . weekdaysRegex ( isStrict ) ;
} ) ;
addWeekParseToken ( [ 'dd' , 'ddd' , 'dddd' ] , function ( input , week , config , token ) {
var weekday = config . _locale . weekdaysParse ( input , token , config . _strict ) ;
// if we didn't get a weekday name, mark the date as invalid
if ( weekday != null ) {
week . d = weekday ;
} else {
getParsingFlags ( config ) . invalidWeekday = input ;
}
} ) ;
addWeekParseToken ( [ 'd' , 'e' , 'E' ] , function ( input , week , config , token ) {
week [ token ] = toInt ( input ) ;
} ) ;
// HELPERS
function parseWeekday ( input , locale ) {
if ( typeof input !== 'string' ) {
return input ;
}
if ( ! isNaN ( input ) ) {
return parseInt ( input , 10 ) ;
}
input = locale . weekdaysParse ( input ) ;
if ( typeof input === 'number' ) {
return input ;
}
return null ;
}
function parseIsoWeekday ( input , locale ) {
if ( typeof input === 'string' ) {
return locale . weekdaysParse ( input ) % 7 || 7 ;
}
return isNaN ( input ) ? null : input ;
}
// LOCALES
function shiftWeekdays ( ws , n ) {
return ws . slice ( n , 7 ) . concat ( ws . slice ( 0 , n ) ) ;
}
var defaultLocaleWeekdays =
'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday' . split ( '_' ) ,
defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat' . split ( '_' ) ,
defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa' . split ( '_' ) ,
defaultWeekdaysRegex = matchWord ,
defaultWeekdaysShortRegex = matchWord ,
defaultWeekdaysMinRegex = matchWord ;
function localeWeekdays ( m , format ) {
var weekdays = isArray ( this . _weekdays )
? this . _weekdays
: this . _weekdays [
m && m !== true && this . _weekdays . isFormat . test ( format )
? 'format'
: 'standalone'
] ;
return m === true
? shiftWeekdays ( weekdays , this . _week . dow )
: m
? weekdays [ m . day ( ) ]
: weekdays ;
}
function localeWeekdaysShort ( m ) {
return m === true
? shiftWeekdays ( this . _weekdaysShort , this . _week . dow )
: m
? this . _weekdaysShort [ m . day ( ) ]
: this . _weekdaysShort ;
}
function localeWeekdaysMin ( m ) {
return m === true
? shiftWeekdays ( this . _weekdaysMin , this . _week . dow )
: m
? this . _weekdaysMin [ m . day ( ) ]
: this . _weekdaysMin ;
}
function handleStrictParse$1 ( weekdayName , format , strict ) {
var i ,
ii ,
mom ,
llc = weekdayName . toLocaleLowerCase ( ) ;
if ( ! this . _weekdaysParse ) {
this . _weekdaysParse = [ ] ;
this . _shortWeekdaysParse = [ ] ;
this . _minWeekdaysParse = [ ] ;
for ( i = 0 ; i < 7 ; ++ i ) {
mom = createUTC ( [ 2000 , 1 ] ) . day ( i ) ;
this . _minWeekdaysParse [ i ] = this . weekdaysMin (
mom ,
''
) . toLocaleLowerCase ( ) ;
this . _shortWeekdaysParse [ i ] = this . weekdaysShort (
mom ,
''
) . toLocaleLowerCase ( ) ;
this . _weekdaysParse [ i ] = this . weekdays ( mom , '' ) . toLocaleLowerCase ( ) ;
}
}
if ( strict ) {
if ( format === 'dddd' ) {
ii = indexOf . call ( this . _weekdaysParse , llc ) ;
return ii !== - 1 ? ii : null ;
} else if ( format === 'ddd' ) {
ii = indexOf . call ( this . _shortWeekdaysParse , llc ) ;
return ii !== - 1 ? ii : null ;
} else {
ii = indexOf . call ( this . _minWeekdaysParse , llc ) ;
return ii !== - 1 ? ii : null ;
}
} else {
if ( format === 'dddd' ) {
ii = indexOf . call ( this . _weekdaysParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _shortWeekdaysParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _minWeekdaysParse , llc ) ;
return ii !== - 1 ? ii : null ;
} else if ( format === 'ddd' ) {
ii = indexOf . call ( this . _shortWeekdaysParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _weekdaysParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _minWeekdaysParse , llc ) ;
return ii !== - 1 ? ii : null ;
} else {
ii = indexOf . call ( this . _minWeekdaysParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _weekdaysParse , llc ) ;
if ( ii !== - 1 ) {
return ii ;
}
ii = indexOf . call ( this . _shortWeekdaysParse , llc ) ;
return ii !== - 1 ? ii : null ;
}
}
}
function localeWeekdaysParse ( weekdayName , format , strict ) {
var i , mom , regex ;
if ( this . _weekdaysParseExact ) {
return handleStrictParse$1 . call ( this , weekdayName , format , strict ) ;
}
if ( ! this . _weekdaysParse ) {
this . _weekdaysParse = [ ] ;
this . _minWeekdaysParse = [ ] ;
this . _shortWeekdaysParse = [ ] ;
this . _fullWeekdaysParse = [ ] ;
}
for ( i = 0 ; i < 7 ; i ++ ) {
// make the regex if we don't have it already
mom = createUTC ( [ 2000 , 1 ] ) . day ( i ) ;
if ( strict && ! this . _fullWeekdaysParse [ i ] ) {
this . _fullWeekdaysParse [ i ] = new RegExp (
'^' + this . weekdays ( mom , '' ) . replace ( '.' , '\\.?' ) + '$' ,
'i'
) ;
this . _shortWeekdaysParse [ i ] = new RegExp (
'^' + this . weekdaysShort ( mom , '' ) . replace ( '.' , '\\.?' ) + '$' ,
'i'
) ;
this . _minWeekdaysParse [ i ] = new RegExp (
'^' + this . weekdaysMin ( mom , '' ) . replace ( '.' , '\\.?' ) + '$' ,
'i'
) ;
}
if ( ! this . _weekdaysParse [ i ] ) {
regex =
'^' +
this . weekdays ( mom , '' ) +
'|^' +
this . weekdaysShort ( mom , '' ) +
'|^' +
this . weekdaysMin ( mom , '' ) ;
this . _weekdaysParse [ i ] = new RegExp ( regex . replace ( '.' , '' ) , 'i' ) ;
}
// test the regex
if (
strict &&
format === 'dddd' &&
this . _fullWeekdaysParse [ i ] . test ( weekdayName )
) {
return i ;
} else if (
strict &&
format === 'ddd' &&
this . _shortWeekdaysParse [ i ] . test ( weekdayName )
) {
return i ;
} else if (
strict &&
format === 'dd' &&
this . _minWeekdaysParse [ i ] . test ( weekdayName )
) {
return i ;
} else if ( ! strict && this . _weekdaysParse [ i ] . test ( weekdayName ) ) {
return i ;
}
}
}
// MOMENTS
function getSetDayOfWeek ( input ) {
if ( ! this . isValid ( ) ) {
return input != null ? this : NaN ;
}
var day = this . _isUTC ? this . _d . getUTCDay ( ) : this . _d . getDay ( ) ;
if ( input != null ) {
input = parseWeekday ( input , this . localeData ( ) ) ;
return this . add ( input - day , 'd' ) ;
} else {
return day ;
}
}
function getSetLocaleDayOfWeek ( input ) {
if ( ! this . isValid ( ) ) {
return input != null ? this : NaN ;
}
var weekday = ( this . day ( ) + 7 - this . localeData ( ) . _week . dow ) % 7 ;
return input == null ? weekday : this . add ( input - weekday , 'd' ) ;
}
function getSetISODayOfWeek ( input ) {
if ( ! this . isValid ( ) ) {
return input != null ? this : NaN ;
}
// behaves the same as moment#day except
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
// as a setter, sunday should belong to the previous week.
if ( input != null ) {
var weekday = parseIsoWeekday ( input , this . localeData ( ) ) ;
return this . day ( this . day ( ) % 7 ? weekday : weekday - 7 ) ;
} else {
return this . day ( ) || 7 ;
}
}
function weekdaysRegex ( isStrict ) {
if ( this . _weekdaysParseExact ) {
if ( ! hasOwnProp ( this , '_weekdaysRegex' ) ) {
computeWeekdaysParse . call ( this ) ;
}
if ( isStrict ) {
return this . _weekdaysStrictRegex ;
} else {
return this . _weekdaysRegex ;
}
} else {
if ( ! hasOwnProp ( this , '_weekdaysRegex' ) ) {
this . _weekdaysRegex = defaultWeekdaysRegex ;
}
return this . _weekdaysStrictRegex && isStrict
? this . _weekdaysStrictRegex
: this . _weekdaysRegex ;
}
}
function weekdaysShortRegex ( isStrict ) {
if ( this . _weekdaysParseExact ) {
if ( ! hasOwnProp ( this , '_weekdaysRegex' ) ) {
computeWeekdaysParse . call ( this ) ;
}
if ( isStrict ) {
return this . _weekdaysShortStrictRegex ;
} else {
return this . _weekdaysShortRegex ;
}
} else {
if ( ! hasOwnProp ( this , '_weekdaysShortRegex' ) ) {
this . _weekdaysShortRegex = defaultWeekdaysShortRegex ;
}
return this . _weekdaysShortStrictRegex && isStrict
? this . _weekdaysShortStrictRegex
: this . _weekdaysShortRegex ;
}
}
function weekdaysMinRegex ( isStrict ) {
if ( this . _weekdaysParseExact ) {
if ( ! hasOwnProp ( this , '_weekdaysRegex' ) ) {
computeWeekdaysParse . call ( this ) ;
}
if ( isStrict ) {
return this . _weekdaysMinStrictRegex ;
} else {
return this . _weekdaysMinRegex ;
}
} else {
if ( ! hasOwnProp ( this , '_weekdaysMinRegex' ) ) {
this . _weekdaysMinRegex = defaultWeekdaysMinRegex ;
}
return this . _weekdaysMinStrictRegex && isStrict
? this . _weekdaysMinStrictRegex
: this . _weekdaysMinRegex ;
}
}
function computeWeekdaysParse ( ) {
function cmpLenRev ( a , b ) {
return b . length - a . length ;
}
var minPieces = [ ] ,
shortPieces = [ ] ,
longPieces = [ ] ,
mixedPieces = [ ] ,
i ,
mom ,
minp ,
shortp ,
longp ;
for ( i = 0 ; i < 7 ; i ++ ) {
// make the regex if we don't have it already
mom = createUTC ( [ 2000 , 1 ] ) . day ( i ) ;
minp = regexEscape ( this . weekdaysMin ( mom , '' ) ) ;
shortp = regexEscape ( this . weekdaysShort ( mom , '' ) ) ;
longp = regexEscape ( this . weekdays ( mom , '' ) ) ;
minPieces . push ( minp ) ;
shortPieces . push ( shortp ) ;
longPieces . push ( longp ) ;
mixedPieces . push ( minp ) ;
mixedPieces . push ( shortp ) ;
mixedPieces . push ( longp ) ;
}
// Sorting makes sure if one weekday (or abbr) is a prefix of another it
// will match the longer piece.
minPieces . sort ( cmpLenRev ) ;
shortPieces . sort ( cmpLenRev ) ;
longPieces . sort ( cmpLenRev ) ;
mixedPieces . sort ( cmpLenRev ) ;
this . _weekdaysRegex = new RegExp ( '^(' + mixedPieces . join ( '|' ) + ')' , 'i' ) ;
this . _weekdaysShortRegex = this . _weekdaysRegex ;
this . _weekdaysMinRegex = this . _weekdaysRegex ;
this . _weekdaysStrictRegex = new RegExp (
'^(' + longPieces . join ( '|' ) + ')' ,
'i'
) ;
this . _weekdaysShortStrictRegex = new RegExp (
'^(' + shortPieces . join ( '|' ) + ')' ,
'i'
) ;
this . _weekdaysMinStrictRegex = new RegExp (
'^(' + minPieces . join ( '|' ) + ')' ,
'i'
) ;
}
// FORMATTING
function hFormat ( ) {
return this . hours ( ) % 12 || 12 ;
}
function kFormat ( ) {
return this . hours ( ) || 24 ;
}
addFormatToken ( 'H' , [ 'HH' , 2 ] , 0 , 'hour' ) ;
addFormatToken ( 'h' , [ 'hh' , 2 ] , 0 , hFormat ) ;
addFormatToken ( 'k' , [ 'kk' , 2 ] , 0 , kFormat ) ;
addFormatToken ( 'hmm' , 0 , 0 , function ( ) {
return '' + hFormat . apply ( this ) + zeroFill ( this . minutes ( ) , 2 ) ;
} ) ;
addFormatToken ( 'hmmss' , 0 , 0 , function ( ) {
return (
'' +
hFormat . apply ( this ) +
zeroFill ( this . minutes ( ) , 2 ) +
zeroFill ( this . seconds ( ) , 2 )
) ;
} ) ;
addFormatToken ( 'Hmm' , 0 , 0 , function ( ) {
return '' + this . hours ( ) + zeroFill ( this . minutes ( ) , 2 ) ;
} ) ;
addFormatToken ( 'Hmmss' , 0 , 0 , function ( ) {
return (
'' +
this . hours ( ) +
zeroFill ( this . minutes ( ) , 2 ) +
zeroFill ( this . seconds ( ) , 2 )
) ;
} ) ;
function meridiem ( token , lowercase ) {
addFormatToken ( token , 0 , 0 , function ( ) {
return this . localeData ( ) . meridiem (
this . hours ( ) ,
this . minutes ( ) ,
lowercase
) ;
} ) ;
}
meridiem ( 'a' , true ) ;
meridiem ( 'A' , false ) ;
// ALIASES
addUnitAlias ( 'hour' , 'h' ) ;
// PRIORITY
addUnitPriority ( 'hour' , 13 ) ;
// PARSING
function matchMeridiem ( isStrict , locale ) {
return locale . _meridiemParse ;
}
addRegexToken ( 'a' , matchMeridiem ) ;
addRegexToken ( 'A' , matchMeridiem ) ;
addRegexToken ( 'H' , match1to2 ) ;
addRegexToken ( 'h' , match1to2 ) ;
addRegexToken ( 'k' , match1to2 ) ;
addRegexToken ( 'HH' , match1to2 , match2 ) ;
addRegexToken ( 'hh' , match1to2 , match2 ) ;
addRegexToken ( 'kk' , match1to2 , match2 ) ;
addRegexToken ( 'hmm' , match3to4 ) ;
addRegexToken ( 'hmmss' , match5to6 ) ;
addRegexToken ( 'Hmm' , match3to4 ) ;
addRegexToken ( 'Hmmss' , match5to6 ) ;
addParseToken ( [ 'H' , 'HH' ] , HOUR ) ;
addParseToken ( [ 'k' , 'kk' ] , function ( input , array , config ) {
var kInput = toInt ( input ) ;
array [ HOUR ] = kInput === 24 ? 0 : kInput ;
} ) ;
addParseToken ( [ 'a' , 'A' ] , function ( input , array , config ) {
config . _isPm = config . _locale . isPM ( input ) ;
config . _meridiem = input ;
} ) ;
addParseToken ( [ 'h' , 'hh' ] , function ( input , array , config ) {
array [ HOUR ] = toInt ( input ) ;
getParsingFlags ( config ) . bigHour = true ;
} ) ;
addParseToken ( 'hmm' , function ( input , array , config ) {
var pos = input . length - 2 ;
array [ HOUR ] = toInt ( input . substr ( 0 , pos ) ) ;
array [ MINUTE ] = toInt ( input . substr ( pos ) ) ;
getParsingFlags ( config ) . bigHour = true ;
} ) ;
addParseToken ( 'hmmss' , function ( input , array , config ) {
var pos1 = input . length - 4 ,
pos2 = input . length - 2 ;
array [ HOUR ] = toInt ( input . substr ( 0 , pos1 ) ) ;
array [ MINUTE ] = toInt ( input . substr ( pos1 , 2 ) ) ;
array [ SECOND ] = toInt ( input . substr ( pos2 ) ) ;
getParsingFlags ( config ) . bigHour = true ;
} ) ;
addParseToken ( 'Hmm' , function ( input , array , config ) {
var pos = input . length - 2 ;
array [ HOUR ] = toInt ( input . substr ( 0 , pos ) ) ;
array [ MINUTE ] = toInt ( input . substr ( pos ) ) ;
} ) ;
addParseToken ( 'Hmmss' , function ( input , array , config ) {
var pos1 = input . length - 4 ,
pos2 = input . length - 2 ;
array [ HOUR ] = toInt ( input . substr ( 0 , pos1 ) ) ;
array [ MINUTE ] = toInt ( input . substr ( pos1 , 2 ) ) ;
array [ SECOND ] = toInt ( input . substr ( pos2 ) ) ;
} ) ;
// LOCALES
function localeIsPM ( input ) {
// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
// Using charAt should be more compatible.
return ( input + '' ) . toLowerCase ( ) . charAt ( 0 ) === 'p' ;
}
var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i ,
// Setting the hour should keep the time, because the user explicitly
// specified which hour they want. So trying to maintain the same hour (in
// a new timezone) makes sense. Adding/subtracting hours does not follow
// this rule.
getSetHour = makeGetSet ( 'Hours' , true ) ;
function localeMeridiem ( hours , minutes , isLower ) {
if ( hours > 11 ) {
return isLower ? 'pm' : 'PM' ;
} else {
return isLower ? 'am' : 'AM' ;
}
}
var baseConfig = {
calendar : defaultCalendar ,
longDateFormat : defaultLongDateFormat ,
invalidDate : defaultInvalidDate ,
ordinal : defaultOrdinal ,
dayOfMonthOrdinalParse : defaultDayOfMonthOrdinalParse ,
relativeTime : defaultRelativeTime ,
months : defaultLocaleMonths ,
monthsShort : defaultLocaleMonthsShort ,
week : defaultLocaleWeek ,
weekdays : defaultLocaleWeekdays ,
weekdaysMin : defaultLocaleWeekdaysMin ,
weekdaysShort : defaultLocaleWeekdaysShort ,
meridiemParse : defaultLocaleMeridiemParse ,
} ;
// internal storage for locale config files
var locales = { } ,
localeFamilies = { } ,
globalLocale ;
function commonPrefix ( arr1 , arr2 ) {
var i ,
minl = Math . min ( arr1 . length , arr2 . length ) ;
for ( i = 0 ; i < minl ; i += 1 ) {
if ( arr1 [ i ] !== arr2 [ i ] ) {
return i ;
}
}
return minl ;
}
function normalizeLocale ( key ) {
return key ? key . toLowerCase ( ) . replace ( '_' , '-' ) : key ;
}
// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale ( names ) {
var i = 0 ,
j ,
next ,
locale ,
split ;
while ( i < names . length ) {
split = normalizeLocale ( names [ i ] ) . split ( '-' ) ;
j = split . length ;
next = normalizeLocale ( names [ i + 1 ] ) ;
next = next ? next . split ( '-' ) : null ;
while ( j > 0 ) {
locale = loadLocale ( split . slice ( 0 , j ) . join ( '-' ) ) ;
if ( locale ) {
return locale ;
}
if (
next &&
next . length >= j &&
commonPrefix ( split , next ) >= j - 1
) {
//the next array item is better than a shallower substring of this one
break ;
}
j -- ;
}
i ++ ;
}
return globalLocale ;
}
function isLocaleNameSane ( name ) {
// Prevent names that look like filesystem paths, i.e contain '/' or '\'
return name . match ( '^[^/\\\\]*$' ) != null ;
}
function loadLocale ( name ) {
var oldLocale = null ,
aliasedRequire ;
// TODO: Find a better way to register and load all the locales in Node
if (
locales [ name ] === undefined &&
'object' !== 'undefined' &&
module &&
module . exports &&
isLocaleNameSane ( name )
) {
try {
oldLocale = globalLocale . _abbr ;
aliasedRequire = commonjsRequire ;
aliasedRequire ( './locale/' + name ) ;
getSetGlobalLocale ( oldLocale ) ;
} catch ( e ) {
// mark as not found to avoid repeating expensive file require call causing high CPU
// when trying to find en-US, en_US, en-us for every format call
locales [ name ] = null ; // null means not found
}
}
return locales [ name ] ;
}
// This function will load locale and then set the global locale. If
// no arguments are passed in, it will simply return the current global
// locale key.
function getSetGlobalLocale ( key , values ) {
var data ;
if ( key ) {
if ( isUndefined ( values ) ) {
data = getLocale ( key ) ;
} else {
data = defineLocale ( key , values ) ;
}
if ( data ) {
// moment.duration._locale = moment._locale = data;
globalLocale = data ;
} else {
if ( typeof console !== 'undefined' && console . warn ) {
//warn user if arguments are passed but the locale could not be set
console . warn (
'Locale ' + key + ' not found. Did you forget to load it?'
) ;
}
}
}
return globalLocale . _abbr ;
}
function defineLocale ( name , config ) {
if ( config !== null ) {
var locale ,
parentConfig = baseConfig ;
config . abbr = name ;
if ( locales [ name ] != null ) {
deprecateSimple (
'defineLocaleOverride' ,
'use moment.updateLocale(localeName, config) to change ' +
'an existing locale. moment.defineLocale(localeName, ' +
'config) should only be used for creating a new locale ' +
'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
) ;
parentConfig = locales [ name ] . _config ;
} else if ( config . parentLocale != null ) {
if ( locales [ config . parentLocale ] != null ) {
parentConfig = locales [ config . parentLocale ] . _config ;
} else {
locale = loadLocale ( config . parentLocale ) ;
if ( locale != null ) {
parentConfig = locale . _config ;
} else {
if ( ! localeFamilies [ config . parentLocale ] ) {
localeFamilies [ config . parentLocale ] = [ ] ;
}
localeFamilies [ config . parentLocale ] . push ( {
name : name ,
config : config ,
} ) ;
return null ;
}
}
}
locales [ name ] = new Locale ( mergeConfigs ( parentConfig , config ) ) ;
if ( localeFamilies [ name ] ) {
localeFamilies [ name ] . forEach ( function ( x ) {
defineLocale ( x . name , x . config ) ;
} ) ;
}
// backwards compat for now: also set the locale
// make sure we set the locale AFTER all child locales have been
// created, so we won't end up with the child locale set.
getSetGlobalLocale ( name ) ;
return locales [ name ] ;
} else {
// useful for testing
delete locales [ name ] ;
return null ;
}
}
function updateLocale ( name , config ) {
if ( config != null ) {
var locale ,
tmpLocale ,
parentConfig = baseConfig ;
if ( locales [ name ] != null && locales [ name ] . parentLocale != null ) {
// Update existing child locale in-place to avoid memory-leaks
locales [ name ] . set ( mergeConfigs ( locales [ name ] . _config , config ) ) ;
} else {
// MERGE
tmpLocale = loadLocale ( name ) ;
if ( tmpLocale != null ) {
parentConfig = tmpLocale . _config ;
}
config = mergeConfigs ( parentConfig , config ) ;
if ( tmpLocale == null ) {
// updateLocale is called for creating a new locale
// Set abbr so it will have a name (getters return
// undefined otherwise).
config . abbr = name ;
}
locale = new Locale ( config ) ;
locale . parentLocale = locales [ name ] ;
locales [ name ] = locale ;
}
// backwards compat for now: also set the locale
getSetGlobalLocale ( name ) ;
} else {
// pass null for config to unupdate, useful for tests
if ( locales [ name ] != null ) {
if ( locales [ name ] . parentLocale != null ) {
locales [ name ] = locales [ name ] . parentLocale ;
if ( name === getSetGlobalLocale ( ) ) {
getSetGlobalLocale ( name ) ;
}
} else if ( locales [ name ] != null ) {
delete locales [ name ] ;
}
}
}
return locales [ name ] ;
}
// returns locale data
function getLocale ( key ) {
var locale ;
if ( key && key . _locale && key . _locale . _abbr ) {
key = key . _locale . _abbr ;
}
if ( ! key ) {
return globalLocale ;
}
if ( ! isArray ( key ) ) {
//short-circuit everything else
locale = loadLocale ( key ) ;
if ( locale ) {
return locale ;
}
key = [ key ] ;
}
return chooseLocale ( key ) ;
}
function listLocales ( ) {
return keys ( locales ) ;
}
function checkOverflow ( m ) {
var overflow ,
a = m . _a ;
if ( a && getParsingFlags ( m ) . overflow === - 2 ) {
overflow =
a [ MONTH ] < 0 || a [ MONTH ] > 11
? MONTH
: a [ DATE ] < 1 || a [ DATE ] > daysInMonth ( a [ YEAR ] , a [ MONTH ] )
? DATE
: a [ HOUR ] < 0 ||
a [ HOUR ] > 24 ||
( a [ HOUR ] === 24 &&
( a [ MINUTE ] !== 0 ||
a [ SECOND ] !== 0 ||
a [ MILLISECOND ] !== 0 ) )
? HOUR
: a [ MINUTE ] < 0 || a [ MINUTE ] > 59
? MINUTE
: a [ SECOND ] < 0 || a [ SECOND ] > 59
? SECOND
: a [ MILLISECOND ] < 0 || a [ MILLISECOND ] > 999
? MILLISECOND
: - 1 ;
if (
getParsingFlags ( m ) . _overflowDayOfYear &&
( overflow < YEAR || overflow > DATE )
) {
overflow = DATE ;
}
if ( getParsingFlags ( m ) . _overflowWeeks && overflow === - 1 ) {
overflow = WEEK ;
}
if ( getParsingFlags ( m ) . _overflowWeekday && overflow === - 1 ) {
overflow = WEEKDAY ;
}
getParsingFlags ( m ) . overflow = overflow ;
}
return m ;
}
// iso 8601 regex
// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
var extendedIsoRegex =
/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/ ,
basicIsoRegex =
/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/ ,
tzRegex = /Z|[+-]\d\d(?::?\d\d)?/ ,
isoDates = [
[ 'YYYYYY-MM-DD' , /[+-]\d{6}-\d\d-\d\d/ ] ,
[ 'YYYY-MM-DD' , /\d{4}-\d\d-\d\d/ ] ,
[ 'GGGG-[W]WW-E' , /\d{4}-W\d\d-\d/ ] ,
[ 'GGGG-[W]WW' , /\d{4}-W\d\d/ , false ] ,
[ 'YYYY-DDD' , /\d{4}-\d{3}/ ] ,
[ 'YYYY-MM' , /\d{4}-\d\d/ , false ] ,
[ 'YYYYYYMMDD' , /[+-]\d{10}/ ] ,
[ 'YYYYMMDD' , /\d{8}/ ] ,
[ 'GGGG[W]WWE' , /\d{4}W\d{3}/ ] ,
[ 'GGGG[W]WW' , /\d{4}W\d{2}/ , false ] ,
[ 'YYYYDDD' , /\d{7}/ ] ,
[ 'YYYYMM' , /\d{6}/ , false ] ,
[ 'YYYY' , /\d{4}/ , false ] ,
] ,
// iso time formats and regexes
isoTimes = [
[ 'HH:mm:ss.SSSS' , /\d\d:\d\d:\d\d\.\d+/ ] ,
[ 'HH:mm:ss,SSSS' , /\d\d:\d\d:\d\d,\d+/ ] ,
[ 'HH:mm:ss' , /\d\d:\d\d:\d\d/ ] ,
[ 'HH:mm' , /\d\d:\d\d/ ] ,
[ 'HHmmss.SSSS' , /\d\d\d\d\d\d\.\d+/ ] ,
[ 'HHmmss,SSSS' , /\d\d\d\d\d\d,\d+/ ] ,
[ 'HHmmss' , /\d\d\d\d\d\d/ ] ,
[ 'HHmm' , /\d\d\d\d/ ] ,
[ 'HH' , /\d\d/ ] ,
] ,
aspNetJsonRegex = /^\/?Date\((-?\d+)/i ,
// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
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{4}))$/ ,
obsOffsets = {
UT : 0 ,
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 ,
} ;
// date from iso format
function configFromISO ( config ) {
var i ,
l ,
string = config . _i ,
match = extendedIsoRegex . exec ( string ) || basicIsoRegex . exec ( string ) ,
allowTime ,
dateFormat ,
timeFormat ,
tzFormat ,
isoDatesLen = isoDates . length ,
isoTimesLen = isoTimes . length ;
if ( match ) {
getParsingFlags ( config ) . iso = true ;
for ( i = 0 , l = isoDatesLen ; i < l ; i ++ ) {
if ( isoDates [ i ] [ 1 ] . exec ( match [ 1 ] ) ) {
dateFormat = isoDates [ i ] [ 0 ] ;
allowTime = isoDates [ i ] [ 2 ] !== false ;
break ;
}
}
if ( dateFormat == null ) {
config . _isValid = false ;
return ;
}
if ( match [ 3 ] ) {
for ( i = 0 , l = isoTimesLen ; i < l ; i ++ ) {
if ( isoTimes [ i ] [ 1 ] . exec ( match [ 3 ] ) ) {
// match[2] should be 'T' or space
timeFormat = ( match [ 2 ] || ' ' ) + isoTimes [ i ] [ 0 ] ;
break ;
}
}
if ( timeFormat == null ) {
config . _isValid = false ;
return ;
}
}
if ( ! allowTime && timeFormat != null ) {
config . _isValid = false ;
return ;
}
if ( match [ 4 ] ) {
if ( tzRegex . exec ( match [ 4 ] ) ) {
tzFormat = 'Z' ;
} else {
config . _isValid = false ;
return ;
}
}
config . _f = dateFormat + ( timeFormat || '' ) + ( tzFormat || '' ) ;
configFromStringAndFormat ( config ) ;
} else {
config . _isValid = false ;
}
}
function extractFromRFC2822Strings (
yearStr ,
monthStr ,
dayStr ,
hourStr ,
minuteStr ,
secondStr
) {
var result = [
untruncateYear ( yearStr ) ,
defaultLocaleMonthsShort . indexOf ( monthStr ) ,
parseInt ( dayStr , 10 ) ,
parseInt ( hourStr , 10 ) ,
parseInt ( minuteStr , 10 ) ,
] ;
if ( secondStr ) {
result . push ( parseInt ( secondStr , 10 ) ) ;
}
return result ;
}
function untruncateYear ( yearStr ) {
var year = parseInt ( yearStr , 10 ) ;
if ( year <= 49 ) {
return 2000 + year ;
} else if ( year <= 999 ) {
return 1900 + year ;
}
return year ;
}
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 , ' ' )
. replace ( /^\s\s*/ , '' )
. replace ( /\s\s*$/ , '' ) ;
}
function checkWeekday ( weekdayStr , parsedInput , config ) {
if ( weekdayStr ) {
// TODO: Replace the vanilla JS Date object with an independent day-of-week check.
var weekdayProvided = defaultLocaleWeekdaysShort . indexOf ( weekdayStr ) ,
weekdayActual = new Date (
parsedInput [ 0 ] ,
parsedInput [ 1 ] ,
parsedInput [ 2 ]
) . getDay ( ) ;
if ( weekdayProvided !== weekdayActual ) {
getParsingFlags ( config ) . weekdayMismatch = true ;
config . _isValid = false ;
return false ;
}
}
return true ;
}
function calculateOffset ( obsOffset , militaryOffset , numOffset ) {
if ( obsOffset ) {
return obsOffsets [ obsOffset ] ;
} else if ( militaryOffset ) {
// the only allowed military tz is Z
return 0 ;
} else {
var hm = parseInt ( numOffset , 10 ) ,
m = hm % 100 ,
h = ( hm - m ) / 100 ;
return h * 60 + m ;
}
}
// date and time from ref 2822 format
function configFromRFC2822 ( config ) {
var match = rfc2822 . exec ( preprocessRFC2822 ( config . _i ) ) ,
parsedArray ;
if ( match ) {
parsedArray = extractFromRFC2822Strings (
match [ 4 ] ,
match [ 3 ] ,
match [ 2 ] ,
match [ 5 ] ,
match [ 6 ] ,
match [ 7 ]
) ;
if ( ! checkWeekday ( match [ 1 ] , parsedArray , config ) ) {
return ;
}
config . _a = parsedArray ;
config . _tzm = calculateOffset ( match [ 8 ] , match [ 9 ] , match [ 10 ] ) ;
config . _d = createUTCDate . apply ( null , config . _a ) ;
config . _d . setUTCMinutes ( config . _d . getUTCMinutes ( ) - config . _tzm ) ;
getParsingFlags ( config ) . rfc2822 = true ;
} else {
config . _isValid = false ;
}
}
// date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
function configFromString ( config ) {
var matched = aspNetJsonRegex . exec ( config . _i ) ;
if ( matched !== null ) {
config . _d = new Date ( + matched [ 1 ] ) ;
return ;
}
configFromISO ( config ) ;
if ( config . _isValid === false ) {
delete config . _isValid ;
} else {
return ;
}
configFromRFC2822 ( config ) ;
if ( config . _isValid === false ) {
delete config . _isValid ;
} else {
return ;
}
if ( config . _strict ) {
config . _isValid = false ;
} else {
// Final attempt, use Input Fallback
hooks . createFromInputFallback ( config ) ;
}
}
hooks . createFromInputFallback = deprecate (
'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.' ,
function ( config ) {
config . _d = new Date ( config . _i + ( config . _useUTC ? ' UTC' : '' ) ) ;
}
) ;
// Pick the first defined of two or three arguments.
function defaults ( a , b , c ) {
if ( a != null ) {
return a ;
}
if ( b != null ) {
return b ;
}
return c ;
}
function currentDateArray ( config ) {
// hooks is actually the exported moment object
var nowValue = new Date ( hooks . now ( ) ) ;
if ( config . _useUTC ) {
return [
nowValue . getUTCFullYear ( ) ,
nowValue . getUTCMonth ( ) ,
nowValue . getUTCDate ( ) ,
] ;
}
return [ nowValue . getFullYear ( ) , nowValue . getMonth ( ) , nowValue . getDate ( ) ] ;
}
// convert an array to a date.
// the array should mirror the parameters below
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
function configFromArray ( config ) {
var i ,
date ,
input = [ ] ,
currentDate ,
expectedWeekday ,
yearToUse ;
if ( config . _d ) {
return ;
}
currentDate = currentDateArray ( config ) ;
//compute day of the year from weeks and weekdays
if ( config . _w && config . _a [ DATE ] == null && config . _a [ MONTH ] == null ) {
dayOfYearFromWeekInfo ( config ) ;
}
//if the day of the year is set, figure out what it is
if ( config . _dayOfYear != null ) {
yearToUse = defaults ( config . _a [ YEAR ] , currentDate [ YEAR ] ) ;
if (
config . _dayOfYear > daysInYear ( yearToUse ) ||
config . _dayOfYear === 0
) {
getParsingFlags ( config ) . _overflowDayOfYear = true ;
}
date = createUTCDate ( yearToUse , 0 , config . _dayOfYear ) ;
config . _a [ MONTH ] = date . getUTCMonth ( ) ;
config . _a [ DATE ] = date . getUTCDate ( ) ;
}
// Default to current date.
// * if no year, month, day of month are given, default to today
// * if day of month is given, default month and year
// * if month is given, default only year
// * if year is given, don't default anything
for ( i = 0 ; i < 3 && config . _a [ i ] == null ; ++ i ) {
config . _a [ i ] = input [ i ] = currentDate [ i ] ;
}
// Zero out whatever was not defaulted, including time
for ( ; i < 7 ; i ++ ) {
config . _a [ i ] = input [ i ] =
config . _a [ i ] == null ? ( i === 2 ? 1 : 0 ) : config . _a [ i ] ;
}
// Check for 24:00:00.000
if (
config . _a [ HOUR ] === 24 &&
config . _a [ MINUTE ] === 0 &&
config . _a [ SECOND ] === 0 &&
config . _a [ MILLISECOND ] === 0
) {
config . _nextDay = true ;
config . _a [ HOUR ] = 0 ;
}
config . _d = ( config . _useUTC ? createUTCDate : createDate ) . apply (
null ,
input
) ;
expectedWeekday = config . _useUTC
? config . _d . getUTCDay ( )
: config . _d . getDay ( ) ;
// Apply timezone offset from input. The actual utcOffset can be changed
// with parseZone.
if ( config . _tzm != null ) {
config . _d . setUTCMinutes ( config . _d . getUTCMinutes ( ) - config . _tzm ) ;
}
if ( config . _nextDay ) {
config . _a [ HOUR ] = 24 ;
}
// check for mismatching day of week
if (
config . _w &&
typeof config . _w . d !== 'undefined' &&
config . _w . d !== expectedWeekday
) {
getParsingFlags ( config ) . weekdayMismatch = true ;
}
}
function dayOfYearFromWeekInfo ( config ) {
var w , weekYear , week , weekday , dow , doy , temp , weekdayOverflow , curWeek ;
w = config . _w ;
if ( w . GG != null || w . W != null || w . E != null ) {
dow = 1 ;
doy = 4 ;
// TODO: We need to take the current isoWeekYear, but that depends on
// how we interpret now (local, utc, fixed offset). So create
// a now version of current config (take local/utc/offset flags, and
// create now).
weekYear = defaults (
w . GG ,
config . _a [ YEAR ] ,
weekOfYear ( createLocal ( ) , 1 , 4 ) . year
) ;
week = defaults ( w . W , 1 ) ;
weekday = defaults ( w . E , 1 ) ;
if ( weekday < 1 || weekday > 7 ) {
weekdayOverflow = true ;
}
} else {
dow = config . _locale . _week . dow ;
doy = config . _locale . _week . doy ;
curWeek = weekOfYear ( createLocal ( ) , dow , doy ) ;
weekYear = defaults ( w . gg , config . _a [ YEAR ] , curWeek . year ) ;
// Default to current week.
week = defaults ( w . w , curWeek . week ) ;
if ( w . d != null ) {
// weekday -- low day numbers are considered next week
weekday = w . d ;
if ( weekday < 0 || weekday > 6 ) {
weekdayOverflow = true ;
}
} else if ( w . e != null ) {
// local weekday -- counting starts from beginning of week
weekday = w . e + dow ;
if ( w . e < 0 || w . e > 6 ) {
weekdayOverflow = true ;
}
} else {
// default to beginning of week
weekday = dow ;
}
}
if ( week < 1 || week > weeksInYear ( weekYear , dow , doy ) ) {
getParsingFlags ( config ) . _overflowWeeks = true ;
} else if ( weekdayOverflow != null ) {
getParsingFlags ( config ) . _overflowWeekday = true ;
} else {
temp = dayOfYearFromWeeks ( weekYear , week , weekday , dow , doy ) ;
config . _a [ YEAR ] = temp . year ;
config . _dayOfYear = temp . dayOfYear ;
}
}
// constant that refers to the ISO standard
hooks . ISO _8601 = function ( ) { } ;
// constant that refers to the RFC 2822 form
hooks . RFC _2822 = function ( ) { } ;
// date from string and format string
function configFromStringAndFormat ( config ) {
// TODO: Move this to another part of the creation flow to prevent circular deps
if ( config . _f === hooks . ISO _8601 ) {
configFromISO ( config ) ;
return ;
}
if ( config . _f === hooks . RFC _2822 ) {
configFromRFC2822 ( config ) ;
return ;
}
config . _a = [ ] ;
getParsingFlags ( config ) . empty = true ;
// This array is used to make a Date, either with `new Date` or `Date.UTC`
var string = '' + config . _i ,
i ,
parsedInput ,
tokens ,
token ,
skipped ,
stringLength = string . length ,
totalParsedInputLength = 0 ,
era ,
tokenLen ;
tokens =
expandFormat ( config . _f , config . _locale ) . match ( formattingTokens ) || [ ] ;
tokenLen = tokens . length ;
for ( i = 0 ; i < tokenLen ; i ++ ) {
token = tokens [ i ] ;
parsedInput = ( string . match ( getParseRegexForToken ( token , config ) ) ||
[ ] ) [ 0 ] ;
if ( parsedInput ) {
skipped = string . substr ( 0 , string . indexOf ( parsedInput ) ) ;
if ( skipped . length > 0 ) {
getParsingFlags ( config ) . unusedInput . push ( skipped ) ;
}
string = string . slice (
string . indexOf ( parsedInput ) + parsedInput . length
) ;
totalParsedInputLength += parsedInput . length ;
}
// don't parse if it's not a known token
if ( formatTokenFunctions [ token ] ) {
if ( parsedInput ) {
getParsingFlags ( config ) . empty = false ;
} else {
getParsingFlags ( config ) . unusedTokens . push ( token ) ;
}
addTimeToArrayFromToken ( token , parsedInput , config ) ;
} else if ( config . _strict && ! parsedInput ) {
getParsingFlags ( config ) . unusedTokens . push ( token ) ;
}
}
// add remaining unparsed input length to the string
getParsingFlags ( config ) . charsLeftOver =
stringLength - totalParsedInputLength ;
if ( string . length > 0 ) {
getParsingFlags ( config ) . unusedInput . push ( string ) ;
}
// clear _12h flag if hour is <= 12
if (
config . _a [ HOUR ] <= 12 &&
getParsingFlags ( config ) . bigHour === true &&
config . _a [ HOUR ] > 0
) {
getParsingFlags ( config ) . bigHour = undefined ;
}
getParsingFlags ( config ) . parsedDateParts = config . _a . slice ( 0 ) ;
getParsingFlags ( config ) . meridiem = config . _meridiem ;
// handle meridiem
config . _a [ HOUR ] = meridiemFixWrap (
config . _locale ,
config . _a [ HOUR ] ,
config . _meridiem
) ;
// handle era
era = getParsingFlags ( config ) . era ;
if ( era !== null ) {
config . _a [ YEAR ] = config . _locale . erasConvertYear ( era , config . _a [ YEAR ] ) ;
}
configFromArray ( config ) ;
checkOverflow ( config ) ;
}
function meridiemFixWrap ( locale , hour , meridiem ) {
var isPm ;
if ( meridiem == null ) {
// nothing to do
return hour ;
}
if ( locale . meridiemHour != null ) {
return locale . meridiemHour ( hour , meridiem ) ;
} else if ( locale . isPM != null ) {
// Fallback
isPm = locale . isPM ( meridiem ) ;
if ( isPm && hour < 12 ) {
hour += 12 ;
}
if ( ! isPm && hour === 12 ) {
hour = 0 ;
}
return hour ;
} else {
// this is not supposed to happen
return hour ;
}
}
// date from string and array of format strings
function configFromStringAndArray ( config ) {
var tempConfig ,
bestMoment ,
scoreToBeat ,
i ,
currentScore ,
validFormatFound ,
bestFormatIsValid = false ,
configfLen = config . _f . length ;
if ( configfLen === 0 ) {
getParsingFlags ( config ) . invalidFormat = true ;
config . _d = new Date ( NaN ) ;
return ;
}
for ( i = 0 ; i < configfLen ; i ++ ) {
currentScore = 0 ;
validFormatFound = false ;
tempConfig = copyConfig ( { } , config ) ;
if ( config . _useUTC != null ) {
tempConfig . _useUTC = config . _useUTC ;
}
tempConfig . _f = config . _f [ i ] ;
configFromStringAndFormat ( tempConfig ) ;
if ( isValid ( tempConfig ) ) {
validFormatFound = true ;
}
// if there is any input that was not parsed add a penalty for that format
currentScore += getParsingFlags ( tempConfig ) . charsLeftOver ;
//or tokens
currentScore += getParsingFlags ( tempConfig ) . unusedTokens . length * 10 ;
getParsingFlags ( tempConfig ) . score = currentScore ;
if ( ! bestFormatIsValid ) {
if (
scoreToBeat == null ||
currentScore < scoreToBeat ||
validFormatFound
) {
scoreToBeat = currentScore ;
bestMoment = tempConfig ;
if ( validFormatFound ) {
bestFormatIsValid = true ;
}
}
} else {
if ( currentScore < scoreToBeat ) {
scoreToBeat = currentScore ;
bestMoment = tempConfig ;
}
}
}
extend ( config , bestMoment || tempConfig ) ;
}
function configFromObject ( config ) {
if ( config . _d ) {
return ;
}
var i = normalizeObjectUnits ( config . _i ) ,
dayOrDate = i . day === undefined ? i . date : i . day ;
config . _a = map (
[ i . year , i . month , dayOrDate , i . hour , i . minute , i . second , i . millisecond ] ,
function ( obj ) {
return obj && parseInt ( obj , 10 ) ;
}
) ;
configFromArray ( config ) ;
}
function createFromConfig ( config ) {
var res = new Moment ( checkOverflow ( prepareConfig ( config ) ) ) ;
if ( res . _nextDay ) {
// Adding is smart enough around DST
res . add ( 1 , 'd' ) ;
res . _nextDay = undefined ;
}
return res ;
}
function prepareConfig ( config ) {
var input = config . _i ,
format = config . _f ;
config . _locale = config . _locale || getLocale ( config . _l ) ;
if ( input === null || ( format === undefined && input === '' ) ) {
return createInvalid ( { nullInput : true } ) ;
}
if ( typeof input === 'string' ) {
config . _i = input = config . _locale . preparse ( input ) ;
}
if ( isMoment ( input ) ) {
return new Moment ( checkOverflow ( input ) ) ;
} else if ( isDate ( input ) ) {
config . _d = input ;
} else if ( isArray ( format ) ) {
configFromStringAndArray ( config ) ;
} else if ( format ) {
configFromStringAndFormat ( config ) ;
} else {
configFromInput ( config ) ;
}
if ( ! isValid ( config ) ) {
config . _d = null ;
}
return config ;
}
function configFromInput ( config ) {
var input = config . _i ;
if ( isUndefined ( input ) ) {
config . _d = new Date ( hooks . now ( ) ) ;
} else if ( isDate ( input ) ) {
config . _d = new Date ( input . valueOf ( ) ) ;
} else if ( typeof input === 'string' ) {
configFromString ( config ) ;
} else if ( isArray ( input ) ) {
config . _a = map ( input . slice ( 0 ) , function ( obj ) {
return parseInt ( obj , 10 ) ;
} ) ;
configFromArray ( config ) ;
} else if ( isObject ( input ) ) {
configFromObject ( config ) ;
} else if ( isNumber ( input ) ) {
// from milliseconds
config . _d = new Date ( input ) ;
} else {
hooks . createFromInputFallback ( config ) ;
}
}
function createLocalOrUTC ( input , format , locale , strict , isUTC ) {
var c = { } ;
if ( format === true || format === false ) {
strict = format ;
format = undefined ;
}
if ( locale === true || locale === false ) {
strict = locale ;
locale = undefined ;
}
if (
( isObject ( input ) && isObjectEmpty ( input ) ) ||
( isArray ( input ) && input . length === 0 )
) {
input = undefined ;
}
// object construction must be done this way.
// https://github.com/moment/moment/issues/1423
c . _isAMomentObject = true ;
c . _useUTC = c . _isUTC = isUTC ;
c . _l = locale ;
c . _i = input ;
c . _f = format ;
c . _strict = strict ;
return createFromConfig ( c ) ;
}
function createLocal ( input , format , locale , strict ) {
return createLocalOrUTC ( input , format , locale , strict , false ) ;
}
var prototypeMin = deprecate (
'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/' ,
function ( ) {
var other = createLocal . apply ( null , arguments ) ;
if ( this . isValid ( ) && other . isValid ( ) ) {
return other < this ? this : other ;
} else {
return createInvalid ( ) ;
}
}
) ,
prototypeMax = deprecate (
'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/' ,
function ( ) {
var other = createLocal . apply ( null , arguments ) ;
if ( this . isValid ( ) && other . isValid ( ) ) {
return other > this ? this : other ;
} else {
return createInvalid ( ) ;
}
}
) ;
// Pick a moment m from moments so that m[fn](other) is true for all
// other. This relies on the function fn to be transitive.
//
// moments should either be an array of moment objects or an array, whose
// first element is an array of moment objects.
function pickBy ( fn , moments ) {
var res , i ;
if ( moments . length === 1 && isArray ( moments [ 0 ] ) ) {
moments = moments [ 0 ] ;
}
if ( ! moments . length ) {
return createLocal ( ) ;
}
res = moments [ 0 ] ;
for ( i = 1 ; i < moments . length ; ++ i ) {
if ( ! moments [ i ] . isValid ( ) || moments [ i ] [ fn ] ( res ) ) {
res = moments [ i ] ;
}
}
return res ;
}
// TODO: Use [].sort instead?
function min ( ) {
var args = [ ] . slice . call ( arguments , 0 ) ;
return pickBy ( 'isBefore' , args ) ;
}
function max ( ) {
var args = [ ] . slice . call ( arguments , 0 ) ;
return pickBy ( 'isAfter' , args ) ;
}
var now = function ( ) {
return Date . now ? Date . now ( ) : + new Date ( ) ;
} ;
var ordering = [
'year' ,
'quarter' ,
'month' ,
'week' ,
'day' ,
'hour' ,
'minute' ,
'second' ,
'millisecond' ,
] ;
function isDurationValid ( m ) {
var key ,
unitHasDecimal = false ,
i ,
orderLen = ordering . length ;
for ( key in m ) {
if (
hasOwnProp ( m , key ) &&
! (
indexOf . call ( ordering , key ) !== - 1 &&
( m [ key ] == null || ! isNaN ( m [ key ] ) )
)
) {
return false ;
}
}
for ( i = 0 ; i < orderLen ; ++ i ) {
if ( m [ ordering [ i ] ] ) {
if ( unitHasDecimal ) {
return false ; // only allow non-integers for smallest unit
}
if ( parseFloat ( m [ ordering [ i ] ] ) !== toInt ( m [ ordering [ i ] ] ) ) {
unitHasDecimal = true ;
}
}
}
return true ;
}
function isValid$1 ( ) {
return this . _isValid ;
}
function createInvalid$1 ( ) {
return createDuration ( NaN ) ;
}
function Duration ( duration ) {
var normalizedInput = normalizeObjectUnits ( duration ) ,
years = normalizedInput . year || 0 ,
quarters = normalizedInput . quarter || 0 ,
months = normalizedInput . month || 0 ,
weeks = normalizedInput . week || normalizedInput . isoWeek || 0 ,
days = normalizedInput . day || 0 ,
hours = normalizedInput . hour || 0 ,
minutes = normalizedInput . minute || 0 ,
seconds = normalizedInput . second || 0 ,
milliseconds = normalizedInput . millisecond || 0 ;
this . _isValid = isDurationValid ( normalizedInput ) ;
// representation for dateAddRemove
this . _milliseconds =
+ milliseconds +
seconds * 1e3 + // 1000
minutes * 6e4 + // 1000 * 60
hours * 1000 * 60 * 60 ; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
// Because of dateAddRemove treats 24 hours as different from a
// day when working around DST, we need to store them separately
this . _days = + days + weeks * 7 ;
// It is impossible to translate months into days without knowing
// which months you are are talking about, so we have to store
// it separately.
this . _months = + months + quarters * 3 + years * 12 ;
this . _data = { } ;
this . _locale = getLocale ( ) ;
this . _bubble ( ) ;
}
function isDuration ( obj ) {
return obj instanceof Duration ;
}
function absRound ( number ) {
if ( number < 0 ) {
return Math . round ( - 1 * number ) * - 1 ;
} else {
return Math . round ( number ) ;
}
}
// compare two arrays, return the number of differences
function compareArrays ( array1 , array2 , dontConvert ) {
var len = Math . min ( array1 . length , array2 . length ) ,
lengthDiff = Math . abs ( array1 . length - array2 . length ) ,
diffs = 0 ,
i ;
for ( i = 0 ; i < len ; i ++ ) {
if (
( dontConvert && array1 [ i ] !== array2 [ i ] ) ||
( ! dontConvert && toInt ( array1 [ i ] ) !== toInt ( array2 [ i ] ) )
) {
diffs ++ ;
}
}
return diffs + lengthDiff ;
}
// FORMATTING
function offset ( token , separator ) {
addFormatToken ( token , 0 , 0 , function ( ) {
var offset = this . utcOffset ( ) ,
sign = '+' ;
if ( offset < 0 ) {
offset = - offset ;
sign = '-' ;
}
return (
sign +
zeroFill ( ~ ~ ( offset / 60 ) , 2 ) +
separator +
zeroFill ( ~ ~ offset % 60 , 2 )
) ;
} ) ;
}
offset ( 'Z' , ':' ) ;
offset ( 'ZZ' , '' ) ;
// PARSING
addRegexToken ( 'Z' , matchShortOffset ) ;
addRegexToken ( 'ZZ' , matchShortOffset ) ;
addParseToken ( [ 'Z' , 'ZZ' ] , function ( input , array , config ) {
config . _useUTC = true ;
config . _tzm = offsetFromString ( matchShortOffset , input ) ;
} ) ;
// HELPERS
// timezone chunker
// '+10:00' > ['10', '00']
// '-1530' > ['-15', '30']
var chunkOffset = /([\+\-]|\d\d)/gi ;
function offsetFromString ( matcher , string ) {
var matches = ( string || '' ) . match ( matcher ) ,
chunk ,
parts ,
minutes ;
if ( matches === null ) {
return null ;
}
chunk = matches [ matches . length - 1 ] || [ ] ;
parts = ( chunk + '' ) . match ( chunkOffset ) || [ '-' , 0 , 0 ] ;
minutes = + ( parts [ 1 ] * 60 ) + toInt ( parts [ 2 ] ) ;
return minutes === 0 ? 0 : parts [ 0 ] === '+' ? minutes : - minutes ;
}
// Return a moment from input, that is local/utc/zone equivalent to model.
function cloneWithOffset ( input , model ) {
var res , diff ;
if ( model . _isUTC ) {
res = model . clone ( ) ;
diff =
( isMoment ( input ) || isDate ( input )
? input . valueOf ( )
: createLocal ( input ) . valueOf ( ) ) - res . valueOf ( ) ;
// Use low-level api, because this fn is low-level api.
res . _d . setTime ( res . _d . valueOf ( ) + diff ) ;
hooks . updateOffset ( res , false ) ;
return res ;
} else {
return createLocal ( input ) . local ( ) ;
}
}
function getDateOffset ( m ) {
// On Firefox.24 Date#getTimezoneOffset returns a floating point.
// https://github.com/moment/moment/pull/1871
return - Math . round ( m . _d . getTimezoneOffset ( ) ) ;
}
// HOOKS
// This function will be called whenever a moment is mutated.
// It is intended to keep the offset in sync with the timezone.
hooks . updateOffset = function ( ) { } ;
// MOMENTS
// keepLocalTime = true means only change the timezone, without
// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
// +0200, so we adjust the time as needed, to be valid.
//
// Keeping the time actually adds/subtracts (one hour)
// from the actual represented time. That is why we call updateOffset
// a second time. In case it wants us to change the offset again
// _changeInProgress == true case, then we have to adjust, because
// there is no such time in the given timezone.
function getSetOffset ( input , keepLocalTime , keepMinutes ) {
var offset = this . _offset || 0 ,
localAdjust ;
if ( ! this . isValid ( ) ) {
return input != null ? this : NaN ;
}
if ( input != null ) {
if ( typeof input === 'string' ) {
input = offsetFromString ( matchShortOffset , input ) ;
if ( input === null ) {
return this ;
}
} else if ( Math . abs ( input ) < 16 && ! keepMinutes ) {
input = input * 60 ;
}
if ( ! this . _isUTC && keepLocalTime ) {
localAdjust = getDateOffset ( this ) ;
}
this . _offset = input ;
this . _isUTC = true ;
if ( localAdjust != null ) {
this . add ( localAdjust , 'm' ) ;
}
if ( offset !== input ) {
if ( ! keepLocalTime || this . _changeInProgress ) {
addSubtract (
this ,
createDuration ( input - offset , 'm' ) ,
1 ,
false
) ;
} else if ( ! this . _changeInProgress ) {
this . _changeInProgress = true ;
hooks . updateOffset ( this , true ) ;
this . _changeInProgress = null ;
}
}
return this ;
} else {
return this . _isUTC ? offset : getDateOffset ( this ) ;
}
}
function getSetZone ( input , keepLocalTime ) {
if ( input != null ) {
if ( typeof input !== 'string' ) {
input = - input ;
}
this . utcOffset ( input , keepLocalTime ) ;
return this ;
} else {
return - this . utcOffset ( ) ;
}
}
function setOffsetToUTC ( keepLocalTime ) {
return this . utcOffset ( 0 , keepLocalTime ) ;
}
function setOffsetToLocal ( keepLocalTime ) {
if ( this . _isUTC ) {
this . utcOffset ( 0 , keepLocalTime ) ;
this . _isUTC = false ;
if ( keepLocalTime ) {
this . subtract ( getDateOffset ( this ) , 'm' ) ;
}
}
return this ;
}
function setOffsetToParsedOffset ( ) {
if ( this . _tzm != null ) {
this . utcOffset ( this . _tzm , false , true ) ;
} else if ( typeof this . _i === 'string' ) {
var tZone = offsetFromString ( matchOffset , this . _i ) ;
if ( tZone != null ) {
this . utcOffset ( tZone ) ;
} else {
this . utcOffset ( 0 , true ) ;
}
}
return this ;
}
function hasAlignedHourOffset ( input ) {
if ( ! this . isValid ( ) ) {
return false ;
}
input = input ? createLocal ( input ) . utcOffset ( ) : 0 ;
return ( this . utcOffset ( ) - input ) % 60 === 0 ;
}
function isDaylightSavingTime ( ) {
return (
this . utcOffset ( ) > this . clone ( ) . month ( 0 ) . utcOffset ( ) ||
this . utcOffset ( ) > this . clone ( ) . month ( 5 ) . utcOffset ( )
) ;
}
function isDaylightSavingTimeShifted ( ) {
if ( ! isUndefined ( this . _isDSTShifted ) ) {
return this . _isDSTShifted ;
}
var c = { } ,
other ;
copyConfig ( c , this ) ;
c = prepareConfig ( c ) ;
if ( c . _a ) {
other = c . _isUTC ? createUTC ( c . _a ) : createLocal ( c . _a ) ;
this . _isDSTShifted =
this . isValid ( ) && compareArrays ( c . _a , other . toArray ( ) ) > 0 ;
} else {
this . _isDSTShifted = false ;
}
return this . _isDSTShifted ;
}
function isLocal ( ) {
return this . isValid ( ) ? ! this . _isUTC : false ;
}
function isUtcOffset ( ) {
return this . isValid ( ) ? this . _isUTC : false ;
}
function isUtc ( ) {
return this . isValid ( ) ? this . _isUTC && this . _offset === 0 : false ;
}
// ASP.NET json date format regex
var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/ ,
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
// and further modified to allow for strings containing both week and day
isoRegex =
/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/ ;
function createDuration ( input , key ) {
var duration = input ,
// matching against regexp is expensive, do it on demand
match = null ,
sign ,
ret ,
diffRes ;
if ( isDuration ( input ) ) {
duration = {
ms : input . _milliseconds ,
d : input . _days ,
M : input . _months ,
} ;
} else if ( isNumber ( input ) || ! isNaN ( + input ) ) {
duration = { } ;
if ( key ) {
duration [ key ] = + input ;
} else {
duration . milliseconds = + input ;
}
} else if ( ( match = aspNetRegex . exec ( input ) ) ) {
sign = match [ 1 ] === '-' ? - 1 : 1 ;
duration = {
y : 0 ,
d : toInt ( match [ DATE ] ) * sign ,
h : toInt ( match [ HOUR ] ) * sign ,
m : toInt ( match [ MINUTE ] ) * sign ,
s : toInt ( match [ SECOND ] ) * sign ,
ms : toInt ( absRound ( match [ MILLISECOND ] * 1000 ) ) * sign , // the millisecond decimal point is included in the match
} ;
} else if ( ( match = isoRegex . exec ( input ) ) ) {
sign = match [ 1 ] === '-' ? - 1 : 1 ;
duration = {
y : parseIso ( match [ 2 ] , sign ) ,
M : parseIso ( match [ 3 ] , sign ) ,
w : parseIso ( match [ 4 ] , sign ) ,
d : parseIso ( match [ 5 ] , sign ) ,
h : parseIso ( match [ 6 ] , sign ) ,
m : parseIso ( match [ 7 ] , sign ) ,
s : parseIso ( match [ 8 ] , sign ) ,
} ;
} else if ( duration == null ) {
// checks for null or undefined
duration = { } ;
} else if (
typeof duration === 'object' &&
( 'from' in duration || 'to' in duration )
) {
diffRes = momentsDifference (
createLocal ( duration . from ) ,
createLocal ( duration . to )
) ;
duration = { } ;
duration . ms = diffRes . milliseconds ;
duration . M = diffRes . months ;
}
ret = new Duration ( duration ) ;
if ( isDuration ( input ) && hasOwnProp ( input , '_locale' ) ) {
ret . _locale = input . _locale ;
}
if ( isDuration ( input ) && hasOwnProp ( input , '_isValid' ) ) {
ret . _isValid = input . _isValid ;
}
return ret ;
}
createDuration . fn = Duration . prototype ;
createDuration . invalid = createInvalid$1 ;
function parseIso ( inp , sign ) {
// We'd normally use ~~inp for this, but unfortunately it also
// converts floats to ints.
// inp may be undefined, so careful calling replace on it.
var res = inp && parseFloat ( inp . replace ( ',' , '.' ) ) ;
// apply sign while we're at it
return ( isNaN ( res ) ? 0 : res ) * sign ;
}
function positiveMomentsDifference ( base , other ) {
var res = { } ;
res . months =
other . month ( ) - base . month ( ) + ( other . year ( ) - base . year ( ) ) * 12 ;
if ( base . clone ( ) . add ( res . months , 'M' ) . isAfter ( other ) ) {
-- res . months ;
}
res . milliseconds = + other - + base . clone ( ) . add ( res . months , 'M' ) ;
return res ;
}
function momentsDifference ( base , other ) {
var res ;
if ( ! ( base . isValid ( ) && other . isValid ( ) ) ) {
return { milliseconds : 0 , months : 0 } ;
}
other = cloneWithOffset ( other , base ) ;
if ( base . isBefore ( other ) ) {
res = positiveMomentsDifference ( base , other ) ;
} else {
res = positiveMomentsDifference ( other , base ) ;
res . milliseconds = - res . milliseconds ;
res . months = - res . months ;
}
return res ;
}
// TODO: remove 'name' arg after deprecation is removed
function createAdder ( direction , name ) {
return function ( val , period ) {
var dur , tmp ;
//invert the arguments, but complain about it
if ( period !== null && ! isNaN ( + period ) ) {
deprecateSimple (
name ,
'moment().' +
name +
'(period, number) is deprecated. Please use moment().' +
name +
'(number, period). ' +
'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
) ;
tmp = val ;
val = period ;
period = tmp ;
}
dur = createDuration ( val , period ) ;
addSubtract ( this , dur , direction ) ;
return this ;
} ;
}
function addSubtract ( mom , duration , isAdding , updateOffset ) {
var milliseconds = duration . _milliseconds ,
days = absRound ( duration . _days ) ,
months = absRound ( duration . _months ) ;
if ( ! mom . isValid ( ) ) {
// No op
return ;
}
updateOffset = updateOffset == null ? true : updateOffset ;
if ( months ) {
setMonth ( mom , get ( mom , 'Month' ) + months * isAdding ) ;
}
if ( days ) {
set$1 ( mom , 'Date' , get ( mom , 'Date' ) + days * isAdding ) ;
}
if ( milliseconds ) {
mom . _d . setTime ( mom . _d . valueOf ( ) + milliseconds * isAdding ) ;
}
if ( updateOffset ) {
hooks . updateOffset ( mom , days || months ) ;
}
}
var add = createAdder ( 1 , 'add' ) ,
subtract = createAdder ( - 1 , 'subtract' ) ;
function isString ( input ) {
return typeof input === 'string' || input instanceof String ;
}
// type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
function isMomentInput ( input ) {
return (
isMoment ( input ) ||
isDate ( input ) ||
isString ( input ) ||
isNumber ( input ) ||
isNumberOrStringArray ( input ) ||
isMomentInputObject ( input ) ||
input === null ||
input === undefined
) ;
}
function isMomentInputObject ( input ) {
var objectTest = isObject ( input ) && ! isObjectEmpty ( input ) ,
propertyTest = false ,
properties = [
'years' ,
'year' ,
'y' ,
'months' ,
'month' ,
'M' ,
'days' ,
'day' ,
'd' ,
'dates' ,
'date' ,
'D' ,
'hours' ,
'hour' ,
'h' ,
'minutes' ,
'minute' ,
'm' ,
'seconds' ,
'second' ,
's' ,
'milliseconds' ,
'millisecond' ,
'ms' ,
] ,
i ,
property ,
propertyLen = properties . length ;
for ( i = 0 ; i < propertyLen ; i += 1 ) {
property = properties [ i ] ;
propertyTest = propertyTest || hasOwnProp ( input , property ) ;
}
return objectTest && propertyTest ;
}
function isNumberOrStringArray ( input ) {
var arrayTest = isArray ( input ) ,
dataTypeTest = false ;
if ( arrayTest ) {
dataTypeTest =
input . filter ( function ( item ) {
return ! isNumber ( item ) && isString ( input ) ;
} ) . length === 0 ;
}
return arrayTest && dataTypeTest ;
}
function isCalendarSpec ( input ) {
var objectTest = isObject ( input ) && ! isObjectEmpty ( input ) ,
propertyTest = false ,
properties = [
'sameDay' ,
'nextDay' ,
'lastDay' ,
'nextWeek' ,
'lastWeek' ,
'sameElse' ,
] ,
i ,
property ;
for ( i = 0 ; i < properties . length ; i += 1 ) {
property = properties [ i ] ;
propertyTest = propertyTest || hasOwnProp ( input , property ) ;
}
return objectTest && propertyTest ;
}
function getCalendarFormat ( myMoment , now ) {
var diff = myMoment . diff ( now , 'days' , true ) ;
return diff < - 6
? 'sameElse'
: diff < - 1
? 'lastWeek'
: diff < 0
? 'lastDay'
: diff < 1
? 'sameDay'
: diff < 2
? 'nextDay'
: diff < 7
? 'nextWeek'
: 'sameElse' ;
}
function calendar$1 ( time , formats ) {
// Support for single parameter, formats only overload to the calendar function
if ( arguments . length === 1 ) {
if ( ! arguments [ 0 ] ) {
time = undefined ;
formats = undefined ;
} else if ( isMomentInput ( arguments [ 0 ] ) ) {
time = arguments [ 0 ] ;
formats = undefined ;
} else if ( isCalendarSpec ( arguments [ 0 ] ) ) {
formats = arguments [ 0 ] ;
time = undefined ;
}
}
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're local/utc/offset or not.
var now = time || createLocal ( ) ,
sod = cloneWithOffset ( now , this ) . startOf ( 'day' ) ,
format = hooks . calendarFormat ( this , sod ) || 'sameElse' ,
output =
formats &&
( isFunction ( formats [ format ] )
? formats [ format ] . call ( this , now )
: formats [ format ] ) ;
return this . format (
output || this . localeData ( ) . calendar ( format , this , createLocal ( now ) )
) ;
}
function clone ( ) {
return new Moment ( this ) ;
}
function isAfter ( input , units ) {
var localInput = isMoment ( input ) ? input : createLocal ( input ) ;
if ( ! ( this . isValid ( ) && localInput . isValid ( ) ) ) {
return false ;
}
units = normalizeUnits ( units ) || 'millisecond' ;
if ( units === 'millisecond' ) {
return this . valueOf ( ) > localInput . valueOf ( ) ;
} else {
return localInput . valueOf ( ) < this . clone ( ) . startOf ( units ) . valueOf ( ) ;
}
}
function isBefore ( input , units ) {
var localInput = isMoment ( input ) ? input : createLocal ( input ) ;
if ( ! ( this . isValid ( ) && localInput . isValid ( ) ) ) {
return false ;
}
units = normalizeUnits ( units ) || 'millisecond' ;
if ( units === 'millisecond' ) {
return this . valueOf ( ) < localInput . valueOf ( ) ;
} else {
return this . clone ( ) . endOf ( units ) . valueOf ( ) < localInput . valueOf ( ) ;
}
}
function isBetween ( from , to , units , inclusivity ) {
var localFrom = isMoment ( from ) ? from : createLocal ( from ) ,
localTo = isMoment ( to ) ? to : createLocal ( to ) ;
if ( ! ( this . isValid ( ) && localFrom . isValid ( ) && localTo . isValid ( ) ) ) {
return false ;
}
inclusivity = inclusivity || '()' ;
return (
( inclusivity [ 0 ] === '('
? this . isAfter ( localFrom , units )
: ! this . isBefore ( localFrom , units ) ) &&
( inclusivity [ 1 ] === ')'
? this . isBefore ( localTo , units )
: ! this . isAfter ( localTo , units ) )
) ;
}
function isSame ( input , units ) {
var localInput = isMoment ( input ) ? input : createLocal ( input ) ,
inputMs ;
if ( ! ( this . isValid ( ) && localInput . isValid ( ) ) ) {
return false ;
}
units = normalizeUnits ( units ) || 'millisecond' ;
if ( units === 'millisecond' ) {
return this . valueOf ( ) === localInput . valueOf ( ) ;
} else {
inputMs = localInput . valueOf ( ) ;
return (
this . clone ( ) . startOf ( units ) . valueOf ( ) <= inputMs &&
inputMs <= this . clone ( ) . endOf ( units ) . valueOf ( )
) ;
}
}
function isSameOrAfter ( input , units ) {
return this . isSame ( input , units ) || this . isAfter ( input , units ) ;
}
function isSameOrBefore ( input , units ) {
return this . isSame ( input , units ) || this . isBefore ( input , units ) ;
}
function diff ( input , units , asFloat ) {
var that , zoneDelta , output ;
if ( ! this . isValid ( ) ) {
return NaN ;
}
that = cloneWithOffset ( input , this ) ;
if ( ! that . isValid ( ) ) {
return NaN ;
}
zoneDelta = ( that . utcOffset ( ) - this . utcOffset ( ) ) * 6e4 ;
units = normalizeUnits ( units ) ;
switch ( units ) {
case 'year' :
output = monthDiff ( this , that ) / 12 ;
break ;
case 'month' :
output = monthDiff ( this , that ) ;
break ;
case 'quarter' :
output = monthDiff ( this , that ) / 3 ;
break ;
case 'second' :
output = ( this - that ) / 1e3 ;
break ; // 1000
case 'minute' :
output = ( this - that ) / 6e4 ;
break ; // 1000 * 60
case 'hour' :
output = ( this - that ) / 36e5 ;
break ; // 1000 * 60 * 60
case 'day' :
output = ( this - that - zoneDelta ) / 864e5 ;
break ; // 1000 * 60 * 60 * 24, negate dst
case 'week' :
output = ( this - that - zoneDelta ) / 6048e5 ;
break ; // 1000 * 60 * 60 * 24 * 7, negate dst
default :
output = this - that ;
}
return asFloat ? output : absFloor ( output ) ;
}
function monthDiff ( a , b ) {
if ( a . date ( ) < b . date ( ) ) {
// end-of-month calculations work correct when the start month has more
// days than the end month.
return - monthDiff ( b , a ) ;
}
// difference in months
var wholeMonthDiff = ( b . year ( ) - a . year ( ) ) * 12 + ( b . month ( ) - a . month ( ) ) ,
// b is in (anchor - 1 month, anchor + 1 month)
anchor = a . clone ( ) . add ( wholeMonthDiff , 'months' ) ,
anchor2 ,
adjust ;
if ( b - anchor < 0 ) {
anchor2 = a . clone ( ) . add ( wholeMonthDiff - 1 , 'months' ) ;
// linear across the month
adjust = ( b - anchor ) / ( anchor - anchor2 ) ;
} else {
anchor2 = a . clone ( ) . add ( wholeMonthDiff + 1 , 'months' ) ;
// linear across the month
adjust = ( b - anchor ) / ( anchor2 - anchor ) ;
}
//check for negative zero, return zero if negative zero
return - ( wholeMonthDiff + adjust ) || 0 ;
}
hooks . defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ' ;
hooks . defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]' ;
function toString ( ) {
return this . clone ( ) . locale ( 'en' ) . format ( 'ddd MMM DD YYYY HH:mm:ss [GMT]ZZ' ) ;
}
function toISOString ( keepOffset ) {
if ( ! this . isValid ( ) ) {
return null ;
}
var utc = keepOffset !== true ,
m = utc ? this . clone ( ) . utc ( ) : this ;
if ( m . year ( ) < 0 || m . year ( ) > 9999 ) {
return formatMoment (
m ,
utc
? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
: 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
) ;
}
if ( isFunction ( Date . prototype . toISOString ) ) {
// native implementation is ~50x faster, use it when we can
if ( utc ) {
return this . toDate ( ) . toISOString ( ) ;
} else {
return new Date ( this . valueOf ( ) + this . utcOffset ( ) * 60 * 1000 )
. toISOString ( )
. replace ( 'Z' , formatMoment ( m , 'Z' ) ) ;
}
}
return formatMoment (
m ,
utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
) ;
}
/ * *
* Return a human readable representation of a moment that can
* also be evaluated to get a new moment which is the same
*
* @ link https : //nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
* /
function inspect ( ) {
if ( ! this . isValid ( ) ) {
return 'moment.invalid(/* ' + this . _i + ' */)' ;
}
var func = 'moment' ,
zone = '' ,
prefix ,
year ,
datetime ,
suffix ;
if ( ! this . isLocal ( ) ) {
func = this . utcOffset ( ) === 0 ? 'moment.utc' : 'moment.parseZone' ;
zone = 'Z' ;
}
prefix = '[' + func + '("]' ;
year = 0 <= this . year ( ) && this . year ( ) <= 9999 ? 'YYYY' : 'YYYYYY' ;
datetime = '-MM-DD[T]HH:mm:ss.SSS' ;
suffix = zone + '[")]' ;
return this . format ( prefix + year + datetime + suffix ) ;
}
function format ( inputString ) {
if ( ! inputString ) {
inputString = this . isUtc ( )
? hooks . defaultFormatUtc
: hooks . defaultFormat ;
}
var output = formatMoment ( this , inputString ) ;
return this . localeData ( ) . postformat ( output ) ;
}
function from ( time , withoutSuffix ) {
if (
this . isValid ( ) &&
( ( isMoment ( time ) && time . isValid ( ) ) || createLocal ( time ) . isValid ( ) )
) {
return createDuration ( { to : this , from : time } )
. locale ( this . locale ( ) )
. humanize ( ! withoutSuffix ) ;
} else {
return this . localeData ( ) . invalidDate ( ) ;
}
}
function fromNow ( withoutSuffix ) {
return this . from ( createLocal ( ) , withoutSuffix ) ;
}
function to ( time , withoutSuffix ) {
if (
this . isValid ( ) &&
( ( isMoment ( time ) && time . isValid ( ) ) || createLocal ( time ) . isValid ( ) )
) {
return createDuration ( { from : this , to : time } )
. locale ( this . locale ( ) )
. humanize ( ! withoutSuffix ) ;
} else {
return this . localeData ( ) . invalidDate ( ) ;
}
}
function toNow ( withoutSuffix ) {
return this . to ( createLocal ( ) , withoutSuffix ) ;
}
// If passed a locale key, it will set the locale for this
// instance. Otherwise, it will return the locale configuration
// variables for this instance.
function locale ( key ) {
var newLocaleData ;
if ( key === undefined ) {
return this . _locale . _abbr ;
} else {
newLocaleData = getLocale ( key ) ;
if ( newLocaleData != null ) {
this . _locale = newLocaleData ;
}
return this ;
}
}
var lang = deprecate (
'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.' ,
function ( key ) {
if ( key === undefined ) {
return this . localeData ( ) ;
} else {
return this . locale ( key ) ;
}
}
) ;
function localeData ( ) {
return this . _locale ;
}
var MS _PER _SECOND = 1000 ,
MS _PER _MINUTE = 60 * MS _PER _SECOND ,
MS _PER _HOUR = 60 * MS _PER _MINUTE ,
MS _PER _400 _YEARS = ( 365 * 400 + 97 ) * 24 * MS _PER _HOUR ;
// actual modulo - handles negative numbers (for dates before 1970):
function mod$1 ( dividend , divisor ) {
return ( ( dividend % divisor ) + divisor ) % divisor ;
}
function localStartOfDate ( y , m , d ) {
// the date constructor remaps years 0-99 to 1900-1999
if ( y < 100 && y >= 0 ) {
// preserve leap years using a full 400 year cycle, then reset
return new Date ( y + 400 , m , d ) - MS _PER _400 _YEARS ;
} else {
return new Date ( y , m , d ) . valueOf ( ) ;
}
}
function utcStartOfDate ( y , m , d ) {
// Date.UTC remaps years 0-99 to 1900-1999
if ( y < 100 && y >= 0 ) {
// preserve leap years using a full 400 year cycle, then reset
return Date . UTC ( y + 400 , m , d ) - MS _PER _400 _YEARS ;
} else {
return Date . UTC ( y , m , d ) ;
}
}
function startOf ( units ) {
var time , startOfDate ;
units = normalizeUnits ( units ) ;
if ( units === undefined || units === 'millisecond' || ! this . isValid ( ) ) {
return this ;
}
startOfDate = this . _isUTC ? utcStartOfDate : localStartOfDate ;
switch ( units ) {
case 'year' :
time = startOfDate ( this . year ( ) , 0 , 1 ) ;
break ;
case 'quarter' :
time = startOfDate (
this . year ( ) ,
this . month ( ) - ( this . month ( ) % 3 ) ,
1
) ;
break ;
case 'month' :
time = startOfDate ( this . year ( ) , this . month ( ) , 1 ) ;
break ;
case 'week' :
time = startOfDate (
this . year ( ) ,
this . month ( ) ,
this . date ( ) - this . weekday ( )
) ;
break ;
case 'isoWeek' :
time = startOfDate (
this . year ( ) ,
this . month ( ) ,
this . date ( ) - ( this . isoWeekday ( ) - 1 )
) ;
break ;
case 'day' :
case 'date' :
time = startOfDate ( this . year ( ) , this . month ( ) , this . date ( ) ) ;
break ;
case 'hour' :
time = this . _d . valueOf ( ) ;
time -= mod$1 (
time + ( this . _isUTC ? 0 : this . utcOffset ( ) * MS _PER _MINUTE ) ,
MS _PER _HOUR
) ;
break ;
case 'minute' :
time = this . _d . valueOf ( ) ;
time -= mod$1 ( time , MS _PER _MINUTE ) ;
break ;
case 'second' :
time = this . _d . valueOf ( ) ;
time -= mod$1 ( time , MS _PER _SECOND ) ;
break ;
}
this . _d . setTime ( time ) ;
hooks . updateOffset ( this , true ) ;
return this ;
}
function endOf ( units ) {
var time , startOfDate ;
units = normalizeUnits ( units ) ;
if ( units === undefined || units === 'millisecond' || ! this . isValid ( ) ) {
return this ;
}
startOfDate = this . _isUTC ? utcStartOfDate : localStartOfDate ;
switch ( units ) {
case 'year' :
time = startOfDate ( this . year ( ) + 1 , 0 , 1 ) - 1 ;
break ;
case 'quarter' :
time =
startOfDate (
this . year ( ) ,
this . month ( ) - ( this . month ( ) % 3 ) + 3 ,
1
) - 1 ;
break ;
case 'month' :
time = startOfDate ( this . year ( ) , this . month ( ) + 1 , 1 ) - 1 ;
break ;
case 'week' :
time =
startOfDate (
this . year ( ) ,
this . month ( ) ,
this . date ( ) - this . weekday ( ) + 7
) - 1 ;
break ;
case 'isoWeek' :
time =
startOfDate (
this . year ( ) ,
this . month ( ) ,
this . date ( ) - ( this . isoWeekday ( ) - 1 ) + 7
) - 1 ;
break ;
case 'day' :
case 'date' :
time = startOfDate ( this . year ( ) , this . month ( ) , this . date ( ) + 1 ) - 1 ;
break ;
case 'hour' :
time = this . _d . valueOf ( ) ;
time +=
MS _PER _HOUR -
mod$1 (
time + ( this . _isUTC ? 0 : this . utcOffset ( ) * MS _PER _MINUTE ) ,
MS _PER _HOUR
) -
1 ;
break ;
case 'minute' :
time = this . _d . valueOf ( ) ;
time += MS _PER _MINUTE - mod$1 ( time , MS _PER _MINUTE ) - 1 ;
break ;
case 'second' :
time = this . _d . valueOf ( ) ;
time += MS _PER _SECOND - mod$1 ( time , MS _PER _SECOND ) - 1 ;
break ;
}
this . _d . setTime ( time ) ;
hooks . updateOffset ( this , true ) ;
return this ;
}
function valueOf ( ) {
return this . _d . valueOf ( ) - ( this . _offset || 0 ) * 60000 ;
}
function unix ( ) {
return Math . floor ( this . valueOf ( ) / 1000 ) ;
}
function toDate ( ) {
return new Date ( this . valueOf ( ) ) ;
}
function toArray ( ) {
var m = this ;
return [
m . year ( ) ,
m . month ( ) ,
m . date ( ) ,
m . hour ( ) ,
m . minute ( ) ,
m . second ( ) ,
m . millisecond ( ) ,
] ;
}
function toObject ( ) {
var m = this ;
return {
years : m . year ( ) ,
months : m . month ( ) ,
date : m . date ( ) ,
hours : m . hours ( ) ,
minutes : m . minutes ( ) ,
seconds : m . seconds ( ) ,
milliseconds : m . milliseconds ( ) ,
} ;
}
function toJSON ( ) {
// new Date(NaN).toJSON() === null
return this . isValid ( ) ? this . toISOString ( ) : null ;
}
function isValid$2 ( ) {
return isValid ( this ) ;
}
function parsingFlags ( ) {
return extend ( { } , getParsingFlags ( this ) ) ;
}
function invalidAt ( ) {
return getParsingFlags ( this ) . overflow ;
}
function creationData ( ) {
return {
input : this . _i ,
format : this . _f ,
locale : this . _locale ,
isUTC : this . _isUTC ,
strict : this . _strict ,
} ;
}
addFormatToken ( 'N' , 0 , 0 , 'eraAbbr' ) ;
addFormatToken ( 'NN' , 0 , 0 , 'eraAbbr' ) ;
addFormatToken ( 'NNN' , 0 , 0 , 'eraAbbr' ) ;
addFormatToken ( 'NNNN' , 0 , 0 , 'eraName' ) ;
addFormatToken ( 'NNNNN' , 0 , 0 , 'eraNarrow' ) ;
addFormatToken ( 'y' , [ 'y' , 1 ] , 'yo' , 'eraYear' ) ;
addFormatToken ( 'y' , [ 'yy' , 2 ] , 0 , 'eraYear' ) ;
addFormatToken ( 'y' , [ 'yyy' , 3 ] , 0 , 'eraYear' ) ;
addFormatToken ( 'y' , [ 'yyyy' , 4 ] , 0 , 'eraYear' ) ;
addRegexToken ( 'N' , matchEraAbbr ) ;
addRegexToken ( 'NN' , matchEraAbbr ) ;
addRegexToken ( 'NNN' , matchEraAbbr ) ;
addRegexToken ( 'NNNN' , matchEraName ) ;
addRegexToken ( 'NNNNN' , matchEraNarrow ) ;
addParseToken (
[ 'N' , 'NN' , 'NNN' , 'NNNN' , 'NNNNN' ] ,
function ( input , array , config , token ) {
var era = config . _locale . erasParse ( input , token , config . _strict ) ;
if ( era ) {
getParsingFlags ( config ) . era = era ;
} else {
getParsingFlags ( config ) . invalidEra = input ;
}
}
) ;
addRegexToken ( 'y' , matchUnsigned ) ;
addRegexToken ( 'yy' , matchUnsigned ) ;
addRegexToken ( 'yyy' , matchUnsigned ) ;
addRegexToken ( 'yyyy' , matchUnsigned ) ;
addRegexToken ( 'yo' , matchEraYearOrdinal ) ;
addParseToken ( [ 'y' , 'yy' , 'yyy' , 'yyyy' ] , YEAR ) ;
addParseToken ( [ 'yo' ] , function ( input , array , config , token ) {
var match ;
if ( config . _locale . _eraYearOrdinalRegex ) {
match = input . match ( config . _locale . _eraYearOrdinalRegex ) ;
}
if ( config . _locale . eraYearOrdinalParse ) {
array [ YEAR ] = config . _locale . eraYearOrdinalParse ( input , match ) ;
} else {
array [ YEAR ] = parseInt ( input , 10 ) ;
}
} ) ;
function localeEras ( m , format ) {
var i ,
l ,
date ,
eras = this . _eras || getLocale ( 'en' ) . _eras ;
for ( i = 0 , l = eras . length ; i < l ; ++ i ) {
switch ( typeof eras [ i ] . since ) {
case 'string' :
// truncate time
date = hooks ( eras [ i ] . since ) . startOf ( 'day' ) ;
eras [ i ] . since = date . valueOf ( ) ;
break ;
}
switch ( typeof eras [ i ] . until ) {
case 'undefined' :
eras [ i ] . until = + Infinity ;
break ;
case 'string' :
// truncate time
date = hooks ( eras [ i ] . until ) . startOf ( 'day' ) . valueOf ( ) ;
eras [ i ] . until = date . valueOf ( ) ;
break ;
}
}
return eras ;
}
function localeErasParse ( eraName , format , strict ) {
var i ,
l ,
eras = this . eras ( ) ,
name ,
abbr ,
narrow ;
eraName = eraName . toUpperCase ( ) ;
for ( i = 0 , l = eras . length ; i < l ; ++ i ) {
name = eras [ i ] . name . toUpperCase ( ) ;
abbr = eras [ i ] . abbr . toUpperCase ( ) ;
narrow = eras [ i ] . narrow . toUpperCase ( ) ;
if ( strict ) {
switch ( format ) {
case 'N' :
case 'NN' :
case 'NNN' :
if ( abbr === eraName ) {
return eras [ i ] ;
}
break ;
case 'NNNN' :
if ( name === eraName ) {
return eras [ i ] ;
}
break ;
case 'NNNNN' :
if ( narrow === eraName ) {
return eras [ i ] ;
}
break ;
}
} else if ( [ name , abbr , narrow ] . indexOf ( eraName ) >= 0 ) {
return eras [ i ] ;
}
}
}
function localeErasConvertYear ( era , year ) {
var dir = era . since <= era . until ? + 1 : - 1 ;
if ( year === undefined ) {
return hooks ( era . since ) . year ( ) ;
} else {
return hooks ( era . since ) . year ( ) + ( year - era . offset ) * dir ;
}
}
function getEraName ( ) {
var i ,
l ,
val ,
eras = this . localeData ( ) . eras ( ) ;
for ( i = 0 , l = eras . length ; i < l ; ++ i ) {
// truncate time
val = this . clone ( ) . startOf ( 'day' ) . valueOf ( ) ;
if ( eras [ i ] . since <= val && val <= eras [ i ] . until ) {
return eras [ i ] . name ;
}
if ( eras [ i ] . until <= val && val <= eras [ i ] . since ) {
return eras [ i ] . name ;
}
}
return '' ;
}
function getEraNarrow ( ) {
var i ,
l ,
val ,
eras = this . localeData ( ) . eras ( ) ;
for ( i = 0 , l = eras . length ; i < l ; ++ i ) {
// truncate time
val = this . clone ( ) . startOf ( 'day' ) . valueOf ( ) ;
if ( eras [ i ] . since <= val && val <= eras [ i ] . until ) {
return eras [ i ] . narrow ;
}
if ( eras [ i ] . until <= val && val <= eras [ i ] . since ) {
return eras [ i ] . narrow ;
}
}
return '' ;
}
function getEraAbbr ( ) {
var i ,
l ,
val ,
eras = this . localeData ( ) . eras ( ) ;
for ( i = 0 , l = eras . length ; i < l ; ++ i ) {
// truncate time
val = this . clone ( ) . startOf ( 'day' ) . valueOf ( ) ;
if ( eras [ i ] . since <= val && val <= eras [ i ] . until ) {
return eras [ i ] . abbr ;
}
if ( eras [ i ] . until <= val && val <= eras [ i ] . since ) {
return eras [ i ] . abbr ;
}
}
return '' ;
}
function getEraYear ( ) {
var i ,
l ,
dir ,
val ,
eras = this . localeData ( ) . eras ( ) ;
for ( i = 0 , l = eras . length ; i < l ; ++ i ) {
dir = eras [ i ] . since <= eras [ i ] . until ? + 1 : - 1 ;
// truncate time
val = this . clone ( ) . startOf ( 'day' ) . valueOf ( ) ;
if (
( eras [ i ] . since <= val && val <= eras [ i ] . until ) ||
( eras [ i ] . until <= val && val <= eras [ i ] . since )
) {
return (
( this . year ( ) - hooks ( eras [ i ] . since ) . year ( ) ) * dir +
eras [ i ] . offset
) ;
}
}
return this . year ( ) ;
}
function erasNameRegex ( isStrict ) {
if ( ! hasOwnProp ( this , '_erasNameRegex' ) ) {
computeErasParse . call ( this ) ;
}
return isStrict ? this . _erasNameRegex : this . _erasRegex ;
}
function erasAbbrRegex ( isStrict ) {
if ( ! hasOwnProp ( this , '_erasAbbrRegex' ) ) {
computeErasParse . call ( this ) ;
}
return isStrict ? this . _erasAbbrRegex : this . _erasRegex ;
}
function erasNarrowRegex ( isStrict ) {
if ( ! hasOwnProp ( this , '_erasNarrowRegex' ) ) {
computeErasParse . call ( this ) ;
}
return isStrict ? this . _erasNarrowRegex : this . _erasRegex ;
}
function matchEraAbbr ( isStrict , locale ) {
return locale . erasAbbrRegex ( isStrict ) ;
}
function matchEraName ( isStrict , locale ) {
return locale . erasNameRegex ( isStrict ) ;
}
function matchEraNarrow ( isStrict , locale ) {
return locale . erasNarrowRegex ( isStrict ) ;
}
function matchEraYearOrdinal ( isStrict , locale ) {
return locale . _eraYearOrdinalRegex || matchUnsigned ;
}
function computeErasParse ( ) {
var abbrPieces = [ ] ,
namePieces = [ ] ,
narrowPieces = [ ] ,
mixedPieces = [ ] ,
i ,
l ,
eras = this . eras ( ) ;
for ( i = 0 , l = eras . length ; i < l ; ++ i ) {
namePieces . push ( regexEscape ( eras [ i ] . name ) ) ;
abbrPieces . push ( regexEscape ( eras [ i ] . abbr ) ) ;
narrowPieces . push ( regexEscape ( eras [ i ] . narrow ) ) ;
mixedPieces . push ( regexEscape ( eras [ i ] . name ) ) ;
mixedPieces . push ( regexEscape ( eras [ i ] . abbr ) ) ;
mixedPieces . push ( regexEscape ( eras [ i ] . narrow ) ) ;
}
this . _erasRegex = new RegExp ( '^(' + mixedPieces . join ( '|' ) + ')' , 'i' ) ;
this . _erasNameRegex = new RegExp ( '^(' + namePieces . join ( '|' ) + ')' , 'i' ) ;
this . _erasAbbrRegex = new RegExp ( '^(' + abbrPieces . join ( '|' ) + ')' , 'i' ) ;
this . _erasNarrowRegex = new RegExp (
'^(' + narrowPieces . join ( '|' ) + ')' ,
'i'
) ;
}
// FORMATTING
addFormatToken ( 0 , [ 'gg' , 2 ] , 0 , function ( ) {
return this . weekYear ( ) % 100 ;
} ) ;
addFormatToken ( 0 , [ 'GG' , 2 ] , 0 , function ( ) {
return this . isoWeekYear ( ) % 100 ;
} ) ;
function addWeekYearFormatToken ( token , getter ) {
addFormatToken ( 0 , [ token , token . length ] , 0 , getter ) ;
}
addWeekYearFormatToken ( 'gggg' , 'weekYear' ) ;
addWeekYearFormatToken ( 'ggggg' , 'weekYear' ) ;
addWeekYearFormatToken ( 'GGGG' , 'isoWeekYear' ) ;
addWeekYearFormatToken ( 'GGGGG' , 'isoWeekYear' ) ;
// ALIASES
addUnitAlias ( 'weekYear' , 'gg' ) ;
addUnitAlias ( 'isoWeekYear' , 'GG' ) ;
// PRIORITY
addUnitPriority ( 'weekYear' , 1 ) ;
addUnitPriority ( 'isoWeekYear' , 1 ) ;
// PARSING
addRegexToken ( 'G' , matchSigned ) ;
addRegexToken ( 'g' , matchSigned ) ;
addRegexToken ( 'GG' , match1to2 , match2 ) ;
addRegexToken ( 'gg' , match1to2 , match2 ) ;
addRegexToken ( 'GGGG' , match1to4 , match4 ) ;
addRegexToken ( 'gggg' , match1to4 , match4 ) ;
addRegexToken ( 'GGGGG' , match1to6 , match6 ) ;
addRegexToken ( 'ggggg' , match1to6 , match6 ) ;
addWeekParseToken (
[ 'gggg' , 'ggggg' , 'GGGG' , 'GGGGG' ] ,
function ( input , week , config , token ) {
week [ token . substr ( 0 , 2 ) ] = toInt ( input ) ;
}
) ;
addWeekParseToken ( [ 'gg' , 'GG' ] , function ( input , week , config , token ) {
week [ token ] = hooks . parseTwoDigitYear ( input ) ;
} ) ;
// MOMENTS
function getSetWeekYear ( input ) {
return getSetWeekYearHelper . call (
this ,
input ,
this . week ( ) ,
this . weekday ( ) ,
this . localeData ( ) . _week . dow ,
this . localeData ( ) . _week . doy
) ;
}
function getSetISOWeekYear ( input ) {
return getSetWeekYearHelper . call (
this ,
input ,
this . isoWeek ( ) ,
this . isoWeekday ( ) ,
1 ,
4
) ;
}
function getISOWeeksInYear ( ) {
return weeksInYear ( this . year ( ) , 1 , 4 ) ;
}
function getISOWeeksInISOWeekYear ( ) {
return weeksInYear ( this . isoWeekYear ( ) , 1 , 4 ) ;
}
function getWeeksInYear ( ) {
var weekInfo = this . localeData ( ) . _week ;
return weeksInYear ( this . year ( ) , weekInfo . dow , weekInfo . doy ) ;
}
function getWeeksInWeekYear ( ) {
var weekInfo = this . localeData ( ) . _week ;
return weeksInYear ( this . weekYear ( ) , weekInfo . dow , weekInfo . doy ) ;
}
function getSetWeekYearHelper ( input , week , weekday , dow , doy ) {
var weeksTarget ;
if ( input == null ) {
return weekOfYear ( this , dow , doy ) . year ;
} else {
weeksTarget = weeksInYear ( input , dow , doy ) ;
if ( week > weeksTarget ) {
week = weeksTarget ;
}
return setWeekAll . call ( this , input , week , weekday , dow , doy ) ;
}
}
function setWeekAll ( weekYear , week , weekday , dow , doy ) {
var dayOfYearData = dayOfYearFromWeeks ( weekYear , week , weekday , dow , doy ) ,
date = createUTCDate ( dayOfYearData . year , 0 , dayOfYearData . dayOfYear ) ;
this . year ( date . getUTCFullYear ( ) ) ;
this . month ( date . getUTCMonth ( ) ) ;
this . date ( date . getUTCDate ( ) ) ;
return this ;
}
// FORMATTING
addFormatToken ( 'Q' , 0 , 'Qo' , 'quarter' ) ;
// ALIASES
addUnitAlias ( 'quarter' , 'Q' ) ;
// PRIORITY
addUnitPriority ( 'quarter' , 7 ) ;
// PARSING
addRegexToken ( 'Q' , match1 ) ;
addParseToken ( 'Q' , function ( input , array ) {
array [ MONTH ] = ( toInt ( input ) - 1 ) * 3 ;
} ) ;
// MOMENTS
function getSetQuarter ( input ) {
return input == null
? Math . ceil ( ( this . month ( ) + 1 ) / 3 )
: this . month ( ( input - 1 ) * 3 + ( this . month ( ) % 3 ) ) ;
}
// FORMATTING
addFormatToken ( 'D' , [ 'DD' , 2 ] , 'Do' , 'date' ) ;
// ALIASES
addUnitAlias ( 'date' , 'D' ) ;
// PRIORITY
addUnitPriority ( 'date' , 9 ) ;
// PARSING
addRegexToken ( 'D' , match1to2 ) ;
addRegexToken ( 'DD' , match1to2 , match2 ) ;
addRegexToken ( 'Do' , function ( isStrict , locale ) {
// TODO: Remove "ordinalParse" fallback in next major release.
return isStrict
? locale . _dayOfMonthOrdinalParse || locale . _ordinalParse
: locale . _dayOfMonthOrdinalParseLenient ;
} ) ;
addParseToken ( [ 'D' , 'DD' ] , DATE ) ;
addParseToken ( 'Do' , function ( input , array ) {
array [ DATE ] = toInt ( input . match ( match1to2 ) [ 0 ] ) ;
} ) ;
// MOMENTS
var getSetDayOfMonth = makeGetSet ( 'Date' , true ) ;
// FORMATTING
addFormatToken ( 'DDD' , [ 'DDDD' , 3 ] , 'DDDo' , 'dayOfYear' ) ;
// ALIASES
addUnitAlias ( 'dayOfYear' , 'DDD' ) ;
// PRIORITY
addUnitPriority ( 'dayOfYear' , 4 ) ;
// PARSING
addRegexToken ( 'DDD' , match1to3 ) ;
addRegexToken ( 'DDDD' , match3 ) ;
addParseToken ( [ 'DDD' , 'DDDD' ] , function ( input , array , config ) {
config . _dayOfYear = toInt ( input ) ;
} ) ;
// HELPERS
// MOMENTS
function getSetDayOfYear ( input ) {
var dayOfYear =
Math . round (
( this . clone ( ) . startOf ( 'day' ) - this . clone ( ) . startOf ( 'year' ) ) / 864e5
) + 1 ;
return input == null ? dayOfYear : this . add ( input - dayOfYear , 'd' ) ;
}
// FORMATTING
addFormatToken ( 'm' , [ 'mm' , 2 ] , 0 , 'minute' ) ;
// ALIASES
addUnitAlias ( 'minute' , 'm' ) ;
// PRIORITY
addUnitPriority ( 'minute' , 14 ) ;
// PARSING
addRegexToken ( 'm' , match1to2 ) ;
addRegexToken ( 'mm' , match1to2 , match2 ) ;
addParseToken ( [ 'm' , 'mm' ] , MINUTE ) ;
// MOMENTS
var getSetMinute = makeGetSet ( 'Minutes' , false ) ;
// FORMATTING
addFormatToken ( 's' , [ 'ss' , 2 ] , 0 , 'second' ) ;
// ALIASES
addUnitAlias ( 'second' , 's' ) ;
// PRIORITY
addUnitPriority ( 'second' , 15 ) ;
// PARSING
addRegexToken ( 's' , match1to2 ) ;
addRegexToken ( 'ss' , match1to2 , match2 ) ;
addParseToken ( [ 's' , 'ss' ] , SECOND ) ;
// MOMENTS
var getSetSecond = makeGetSet ( 'Seconds' , false ) ;
// FORMATTING
addFormatToken ( 'S' , 0 , 0 , function ( ) {
return ~ ~ ( this . millisecond ( ) / 100 ) ;
} ) ;
addFormatToken ( 0 , [ 'SS' , 2 ] , 0 , function ( ) {
return ~ ~ ( this . millisecond ( ) / 10 ) ;
} ) ;
addFormatToken ( 0 , [ 'SSS' , 3 ] , 0 , 'millisecond' ) ;
addFormatToken ( 0 , [ 'SSSS' , 4 ] , 0 , function ( ) {
return this . millisecond ( ) * 10 ;
} ) ;
addFormatToken ( 0 , [ 'SSSSS' , 5 ] , 0 , function ( ) {
return this . millisecond ( ) * 100 ;
} ) ;
addFormatToken ( 0 , [ 'SSSSSS' , 6 ] , 0 , function ( ) {
return this . millisecond ( ) * 1000 ;
} ) ;
addFormatToken ( 0 , [ 'SSSSSSS' , 7 ] , 0 , function ( ) {
return this . millisecond ( ) * 10000 ;
} ) ;
addFormatToken ( 0 , [ 'SSSSSSSS' , 8 ] , 0 , function ( ) {
return this . millisecond ( ) * 100000 ;
} ) ;
addFormatToken ( 0 , [ 'SSSSSSSSS' , 9 ] , 0 , function ( ) {
return this . millisecond ( ) * 1000000 ;
} ) ;
// ALIASES
addUnitAlias ( 'millisecond' , 'ms' ) ;
// PRIORITY
addUnitPriority ( 'millisecond' , 16 ) ;
// PARSING
addRegexToken ( 'S' , match1to3 , match1 ) ;
addRegexToken ( 'SS' , match1to3 , match2 ) ;
addRegexToken ( 'SSS' , match1to3 , match3 ) ;
var token , getSetMillisecond ;
for ( token = 'SSSS' ; token . length <= 9 ; token += 'S' ) {
addRegexToken ( token , matchUnsigned ) ;
}
function parseMs ( input , array ) {
array [ MILLISECOND ] = toInt ( ( '0.' + input ) * 1000 ) ;
}
for ( token = 'S' ; token . length <= 9 ; token += 'S' ) {
addParseToken ( token , parseMs ) ;
}
getSetMillisecond = makeGetSet ( 'Milliseconds' , false ) ;
// FORMATTING
addFormatToken ( 'z' , 0 , 0 , 'zoneAbbr' ) ;
addFormatToken ( 'zz' , 0 , 0 , 'zoneName' ) ;
// MOMENTS
function getZoneAbbr ( ) {
return this . _isUTC ? 'UTC' : '' ;
}
function getZoneName ( ) {
return this . _isUTC ? 'Coordinated Universal Time' : '' ;
}
var proto = Moment . prototype ;
proto . add = add ;
proto . calendar = calendar$1 ;
proto . clone = clone ;
proto . diff = diff ;
proto . endOf = endOf ;
proto . format = format ;
proto . from = from ;
proto . fromNow = fromNow ;
proto . to = to ;
proto . toNow = toNow ;
proto . get = stringGet ;
proto . invalidAt = invalidAt ;
proto . isAfter = isAfter ;
proto . isBefore = isBefore ;
proto . isBetween = isBetween ;
proto . isSame = isSame ;
proto . isSameOrAfter = isSameOrAfter ;
proto . isSameOrBefore = isSameOrBefore ;
proto . isValid = isValid$2 ;
proto . lang = lang ;
proto . locale = locale ;
proto . localeData = localeData ;
proto . max = prototypeMax ;
proto . min = prototypeMin ;
proto . parsingFlags = parsingFlags ;
proto . set = stringSet ;
proto . startOf = startOf ;
proto . subtract = subtract ;
proto . toArray = toArray ;
proto . toObject = toObject ;
proto . toDate = toDate ;
proto . toISOString = toISOString ;
proto . inspect = inspect ;
if ( typeof Symbol !== 'undefined' && Symbol . for != null ) {
proto [ Symbol . for ( 'nodejs.util.inspect.custom' ) ] = function ( ) {
return 'Moment<' + this . format ( ) + '>' ;
} ;
}
proto . toJSON = toJSON ;
proto . toString = toString ;
proto . unix = unix ;
proto . valueOf = valueOf ;
proto . creationData = creationData ;
proto . eraName = getEraName ;
proto . eraNarrow = getEraNarrow ;
proto . eraAbbr = getEraAbbr ;
proto . eraYear = getEraYear ;
proto . year = getSetYear ;
proto . isLeapYear = getIsLeapYear ;
proto . weekYear = getSetWeekYear ;
proto . isoWeekYear = getSetISOWeekYear ;
proto . quarter = proto . quarters = getSetQuarter ;
proto . month = getSetMonth ;
proto . daysInMonth = getDaysInMonth ;
proto . week = proto . weeks = getSetWeek ;
proto . isoWeek = proto . isoWeeks = getSetISOWeek ;
proto . weeksInYear = getWeeksInYear ;
proto . weeksInWeekYear = getWeeksInWeekYear ;
proto . isoWeeksInYear = getISOWeeksInYear ;
proto . isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear ;
proto . date = getSetDayOfMonth ;
proto . day = proto . days = getSetDayOfWeek ;
proto . weekday = getSetLocaleDayOfWeek ;
proto . isoWeekday = getSetISODayOfWeek ;
proto . dayOfYear = getSetDayOfYear ;
proto . hour = proto . hours = getSetHour ;
proto . minute = proto . minutes = getSetMinute ;
proto . second = proto . seconds = getSetSecond ;
proto . millisecond = proto . milliseconds = getSetMillisecond ;
proto . utcOffset = getSetOffset ;
proto . utc = setOffsetToUTC ;
proto . local = setOffsetToLocal ;
proto . parseZone = setOffsetToParsedOffset ;
proto . hasAlignedHourOffset = hasAlignedHourOffset ;
proto . isDST = isDaylightSavingTime ;
proto . isLocal = isLocal ;
proto . isUtcOffset = isUtcOffset ;
proto . isUtc = isUtc ;
proto . isUTC = isUtc ;
proto . zoneAbbr = getZoneAbbr ;
proto . zoneName = getZoneName ;
proto . dates = deprecate (
'dates accessor is deprecated. Use date instead.' ,
getSetDayOfMonth
) ;
proto . months = deprecate (
'months accessor is deprecated. Use month instead' ,
getSetMonth
) ;
proto . years = deprecate (
'years accessor is deprecated. Use year instead' ,
getSetYear
) ;
proto . zone = deprecate (
'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/' ,
getSetZone
) ;
proto . isDSTShifted = deprecate (
'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information' ,
isDaylightSavingTimeShifted
) ;
function createUnix ( input ) {
return createLocal ( input * 1000 ) ;
}
function createInZone ( ) {
return createLocal . apply ( null , arguments ) . parseZone ( ) ;
}
function preParsePostFormat ( string ) {
return string ;
}
var proto$1 = Locale . prototype ;
proto$1 . calendar = calendar ;
proto$1 . longDateFormat = longDateFormat ;
proto$1 . invalidDate = invalidDate ;
proto$1 . ordinal = ordinal ;
proto$1 . preparse = preParsePostFormat ;
proto$1 . postformat = preParsePostFormat ;
proto$1 . relativeTime = relativeTime ;
proto$1 . pastFuture = pastFuture ;
proto$1 . set = set ;
proto$1 . eras = localeEras ;
proto$1 . erasParse = localeErasParse ;
proto$1 . erasConvertYear = localeErasConvertYear ;
proto$1 . erasAbbrRegex = erasAbbrRegex ;
proto$1 . erasNameRegex = erasNameRegex ;
proto$1 . erasNarrowRegex = erasNarrowRegex ;
proto$1 . months = localeMonths ;
proto$1 . monthsShort = localeMonthsShort ;
proto$1 . monthsParse = localeMonthsParse ;
proto$1 . monthsRegex = monthsRegex ;
proto$1 . monthsShortRegex = monthsShortRegex ;
proto$1 . week = localeWeek ;
proto$1 . firstDayOfYear = localeFirstDayOfYear ;
proto$1 . firstDayOfWeek = localeFirstDayOfWeek ;
proto$1 . weekdays = localeWeekdays ;
proto$1 . weekdaysMin = localeWeekdaysMin ;
proto$1 . weekdaysShort = localeWeekdaysShort ;
proto$1 . weekdaysParse = localeWeekdaysParse ;
proto$1 . weekdaysRegex = weekdaysRegex ;
proto$1 . weekdaysShortRegex = weekdaysShortRegex ;
proto$1 . weekdaysMinRegex = weekdaysMinRegex ;
proto$1 . isPM = localeIsPM ;
proto$1 . meridiem = localeMeridiem ;
function get$1 ( format , index , field , setter ) {
var locale = getLocale ( ) ,
utc = createUTC ( ) . set ( setter , index ) ;
return locale [ field ] ( utc , format ) ;
}
function listMonthsImpl ( format , index , field ) {
if ( isNumber ( format ) ) {
index = format ;
format = undefined ;
}
format = format || '' ;
if ( index != null ) {
return get$1 ( format , index , field , 'month' ) ;
}
var i ,
out = [ ] ;
for ( i = 0 ; i < 12 ; i ++ ) {
out [ i ] = get$1 ( format , i , field , 'month' ) ;
}
return out ;
}
// ()
// (5)
// (fmt, 5)
// (fmt)
// (true)
// (true, 5)
// (true, fmt, 5)
// (true, fmt)
function listWeekdaysImpl ( localeSorted , format , index , field ) {
if ( typeof localeSorted === 'boolean' ) {
if ( isNumber ( format ) ) {
index = format ;
format = undefined ;
}
format = format || '' ;
} else {
format = localeSorted ;
index = format ;
localeSorted = false ;
if ( isNumber ( format ) ) {
index = format ;
format = undefined ;
}
format = format || '' ;
}
var locale = getLocale ( ) ,
shift = localeSorted ? locale . _week . dow : 0 ,
i ,
out = [ ] ;
if ( index != null ) {
return get$1 ( format , ( index + shift ) % 7 , field , 'day' ) ;
}
for ( i = 0 ; i < 7 ; i ++ ) {
out [ i ] = get$1 ( format , ( i + shift ) % 7 , field , 'day' ) ;
}
return out ;
}
function listMonths ( format , index ) {
return listMonthsImpl ( format , index , 'months' ) ;
}
function listMonthsShort ( format , index ) {
return listMonthsImpl ( format , index , 'monthsShort' ) ;
}
function listWeekdays ( localeSorted , format , index ) {
return listWeekdaysImpl ( localeSorted , format , index , 'weekdays' ) ;
}
function listWeekdaysShort ( localeSorted , format , index ) {
return listWeekdaysImpl ( localeSorted , format , index , 'weekdaysShort' ) ;
}
function listWeekdaysMin ( localeSorted , format , index ) {
return listWeekdaysImpl ( localeSorted , format , index , 'weekdaysMin' ) ;
}
getSetGlobalLocale ( 'en' , {
eras : [
{
since : '0001-01-01' ,
until : + Infinity ,
offset : 1 ,
name : 'Anno Domini' ,
narrow : 'AD' ,
abbr : 'AD' ,
} ,
{
since : '0000-12-31' ,
until : - Infinity ,
offset : 1 ,
name : 'Before Christ' ,
narrow : 'BC' ,
abbr : 'BC' ,
} ,
] ,
dayOfMonthOrdinalParse : /\d{1,2}(th|st|nd|rd)/ ,
ordinal : function ( number ) {
var b = number % 10 ,
output =
toInt ( ( number % 100 ) / 10 ) === 1
? 'th'
: b === 1
? 'st'
: b === 2
? 'nd'
: b === 3
? 'rd'
: 'th' ;
return number + output ;
} ,
} ) ;
// Side effect imports
hooks . lang = deprecate (
'moment.lang is deprecated. Use moment.locale instead.' ,
getSetGlobalLocale
) ;
hooks . langData = deprecate (
'moment.langData is deprecated. Use moment.localeData instead.' ,
getLocale
) ;
var mathAbs = Math . abs ;
function abs ( ) {
var data = this . _data ;
this . _milliseconds = mathAbs ( this . _milliseconds ) ;
this . _days = mathAbs ( this . _days ) ;
this . _months = mathAbs ( this . _months ) ;
data . milliseconds = mathAbs ( data . milliseconds ) ;
data . seconds = mathAbs ( data . seconds ) ;
data . minutes = mathAbs ( data . minutes ) ;
data . hours = mathAbs ( data . hours ) ;
data . months = mathAbs ( data . months ) ;
data . years = mathAbs ( data . years ) ;
return this ;
}
function addSubtract$1 ( duration , input , value , direction ) {
var other = createDuration ( input , value ) ;
duration . _milliseconds += direction * other . _milliseconds ;
duration . _days += direction * other . _days ;
duration . _months += direction * other . _months ;
return duration . _bubble ( ) ;
}
// supports only 2.0-style add(1, 's') or add(duration)
function add$1 ( input , value ) {
return addSubtract$1 ( this , input , value , 1 ) ;
}
// supports only 2.0-style subtract(1, 's') or subtract(duration)
function subtract$1 ( input , value ) {
return addSubtract$1 ( this , input , value , - 1 ) ;
}
function absCeil ( number ) {
if ( number < 0 ) {
return Math . floor ( number ) ;
} else {
return Math . ceil ( number ) ;
}
}
function bubble ( ) {
var milliseconds = this . _milliseconds ,
days = this . _days ,
months = this . _months ,
data = this . _data ,
seconds ,
minutes ,
hours ,
years ,
monthsFromDays ;
// if we have a mix of positive and negative values, bubble down first
// check: https://github.com/moment/moment/issues/2166
if (
! (
( milliseconds >= 0 && days >= 0 && months >= 0 ) ||
( milliseconds <= 0 && days <= 0 && months <= 0 )
)
) {
milliseconds += absCeil ( monthsToDays ( months ) + days ) * 864e5 ;
days = 0 ;
months = 0 ;
}
// The following code bubbles up values, see the tests for
// examples of what that means.
data . milliseconds = milliseconds % 1000 ;
seconds = absFloor ( milliseconds / 1000 ) ;
data . seconds = seconds % 60 ;
minutes = absFloor ( seconds / 60 ) ;
data . minutes = minutes % 60 ;
hours = absFloor ( minutes / 60 ) ;
data . hours = hours % 24 ;
days += absFloor ( hours / 24 ) ;
// convert days to months
monthsFromDays = absFloor ( daysToMonths ( days ) ) ;
months += monthsFromDays ;
days -= absCeil ( monthsToDays ( monthsFromDays ) ) ;
// 12 months -> 1 year
years = absFloor ( months / 12 ) ;
months %= 12 ;
data . days = days ;
data . months = months ;
data . years = years ;
return this ;
}
function daysToMonths ( days ) {
// 400 years have 146097 days (taking into account leap year rules)
// 400 years have 12 months === 4800
return ( days * 4800 ) / 146097 ;
}
function monthsToDays ( months ) {
// the reverse of daysToMonths
return ( months * 146097 ) / 4800 ;
}
function as ( units ) {
if ( ! this . isValid ( ) ) {
return NaN ;
}
var days ,
months ,
milliseconds = this . _milliseconds ;
units = normalizeUnits ( units ) ;
if ( units === 'month' || units === 'quarter' || units === 'year' ) {
days = this . _days + milliseconds / 864e5 ;
months = this . _months + daysToMonths ( days ) ;
switch ( units ) {
case 'month' :
return months ;
case 'quarter' :
return months / 3 ;
case 'year' :
return months / 12 ;
}
} else {
// handle milliseconds separately because of floating point math errors (issue #1867)
days = this . _days + Math . round ( monthsToDays ( this . _months ) ) ;
switch ( units ) {
case 'week' :
return days / 7 + milliseconds / 6048e5 ;
case 'day' :
return days + milliseconds / 864e5 ;
case 'hour' :
return days * 24 + milliseconds / 36e5 ;
case 'minute' :
return days * 1440 + milliseconds / 6e4 ;
case 'second' :
return days * 86400 + milliseconds / 1000 ;
// Math.floor prevents floating point math errors here
case 'millisecond' :
return Math . floor ( days * 864e5 ) + milliseconds ;
default :
throw new Error ( 'Unknown unit ' + units ) ;
}
}
}
// TODO: Use this.as('ms')?
function valueOf$1 ( ) {
if ( ! this . isValid ( ) ) {
return NaN ;
}
return (
this . _milliseconds +
this . _days * 864e5 +
( this . _months % 12 ) * 2592e6 +
toInt ( this . _months / 12 ) * 31536e6
) ;
}
function makeAs ( alias ) {
return function ( ) {
return this . as ( alias ) ;
} ;
}
var asMilliseconds = makeAs ( 'ms' ) ,
asSeconds = makeAs ( 's' ) ,
asMinutes = makeAs ( 'm' ) ,
asHours = makeAs ( 'h' ) ,
asDays = makeAs ( 'd' ) ,
asWeeks = makeAs ( 'w' ) ,
asMonths = makeAs ( 'M' ) ,
asQuarters = makeAs ( 'Q' ) ,
asYears = makeAs ( 'y' ) ;
function clone$1 ( ) {
return createDuration ( this ) ;
}
function get$2 ( units ) {
units = normalizeUnits ( units ) ;
return this . isValid ( ) ? this [ units + 's' ] ( ) : NaN ;
}
function makeGetter ( name ) {
return function ( ) {
return this . isValid ( ) ? this . _data [ name ] : NaN ;
} ;
}
var milliseconds = makeGetter ( 'milliseconds' ) ,
seconds = makeGetter ( 'seconds' ) ,
minutes = makeGetter ( 'minutes' ) ,
hours = makeGetter ( 'hours' ) ,
days = makeGetter ( 'days' ) ,
months = makeGetter ( 'months' ) ,
years = makeGetter ( 'years' ) ;
function weeks ( ) {
return absFloor ( this . days ( ) / 7 ) ;
}
var round = Math . round ,
thresholds = {
ss : 44 , // a few seconds to seconds
s : 45 , // seconds to minute
m : 45 , // minutes to hour
h : 22 , // hours to day
d : 26 , // days to month/week
w : null , // weeks to month
M : 11 , // months to year
} ;
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
function substituteTimeAgo ( string , number , withoutSuffix , isFuture , locale ) {
return locale . relativeTime ( number || 1 , ! ! withoutSuffix , string , isFuture ) ;
}
function relativeTime$1 ( posNegDuration , withoutSuffix , thresholds , locale ) {
var duration = createDuration ( posNegDuration ) . abs ( ) ,
seconds = round ( duration . as ( 's' ) ) ,
minutes = round ( duration . as ( 'm' ) ) ,
hours = round ( duration . as ( 'h' ) ) ,
days = round ( duration . as ( 'd' ) ) ,
months = round ( duration . as ( 'M' ) ) ,
weeks = round ( duration . as ( 'w' ) ) ,
years = round ( duration . as ( 'y' ) ) ,
a =
( seconds <= thresholds . ss && [ 's' , seconds ] ) ||
( seconds < thresholds . s && [ 'ss' , seconds ] ) ||
( minutes <= 1 && [ 'm' ] ) ||
( minutes < thresholds . m && [ 'mm' , minutes ] ) ||
( hours <= 1 && [ 'h' ] ) ||
( hours < thresholds . h && [ 'hh' , hours ] ) ||
( days <= 1 && [ 'd' ] ) ||
( days < thresholds . d && [ 'dd' , days ] ) ;
if ( thresholds . w != null ) {
a =
a ||
( weeks <= 1 && [ 'w' ] ) ||
( weeks < thresholds . w && [ 'ww' , weeks ] ) ;
}
a = a ||
( months <= 1 && [ 'M' ] ) ||
( months < thresholds . M && [ 'MM' , months ] ) ||
( years <= 1 && [ 'y' ] ) || [ 'yy' , years ] ;
a [ 2 ] = withoutSuffix ;
a [ 3 ] = + posNegDuration > 0 ;
a [ 4 ] = locale ;
return substituteTimeAgo . apply ( null , a ) ;
}
// This function allows you to set the rounding function for relative time strings
function getSetRelativeTimeRounding ( roundingFunction ) {
if ( roundingFunction === undefined ) {
return round ;
}
if ( typeof roundingFunction === 'function' ) {
round = roundingFunction ;
return true ;
}
return false ;
}
// This function allows you to set a threshold for relative time strings
function getSetRelativeTimeThreshold ( threshold , limit ) {
if ( thresholds [ threshold ] === undefined ) {
return false ;
}
if ( limit === undefined ) {
return thresholds [ threshold ] ;
}
thresholds [ threshold ] = limit ;
if ( threshold === 's' ) {
thresholds . ss = limit - 1 ;
}
return true ;
}
function humanize ( argWithSuffix , argThresholds ) {
if ( ! this . isValid ( ) ) {
return this . localeData ( ) . invalidDate ( ) ;
}
var withSuffix = false ,
th = thresholds ,
locale ,
output ;
if ( typeof argWithSuffix === 'object' ) {
argThresholds = argWithSuffix ;
argWithSuffix = false ;
}
if ( typeof argWithSuffix === 'boolean' ) {
withSuffix = argWithSuffix ;
}
if ( typeof argThresholds === 'object' ) {
th = Object . assign ( { } , thresholds , argThresholds ) ;
if ( argThresholds . s != null && argThresholds . ss == null ) {
th . ss = argThresholds . s - 1 ;
}
}
locale = this . localeData ( ) ;
output = relativeTime$1 ( this , ! withSuffix , th , locale ) ;
if ( withSuffix ) {
output = locale . pastFuture ( + this , output ) ;
}
return locale . postformat ( output ) ;
}
var abs$1 = Math . abs ;
function sign ( x ) {
return ( x > 0 ) - ( x < 0 ) || + x ;
}
function toISOString$1 ( ) {
// for ISO strings we do not use the normal bubbling rules:
// * milliseconds bubble up until they become hours
// * days do not bubble at all
// * months bubble up until they become years
// This is because there is no context-free conversion between hours and days
// (think of clock changes)
// and also not between days and months (28-31 days per month)
if ( ! this . isValid ( ) ) {
return this . localeData ( ) . invalidDate ( ) ;
}
var seconds = abs$1 ( this . _milliseconds ) / 1000 ,
days = abs$1 ( this . _days ) ,
months = abs$1 ( this . _months ) ,
minutes ,
hours ,
years ,
s ,
total = this . asSeconds ( ) ,
totalSign ,
ymSign ,
daysSign ,
hmsSign ;
if ( ! total ) {
// this is the same as C#'s (Noda) and python (isodate)...
// but not other JS (goog.date)
return 'P0D' ;
}
// 3600 seconds -> 60 minutes -> 1 hour
minutes = absFloor ( seconds / 60 ) ;
hours = absFloor ( minutes / 60 ) ;
seconds %= 60 ;
minutes %= 60 ;
// 12 months -> 1 year
years = absFloor ( months / 12 ) ;
months %= 12 ;
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
s = seconds ? seconds . toFixed ( 3 ) . replace ( /\.?0+$/ , '' ) : '' ;
totalSign = total < 0 ? '-' : '' ;
ymSign = sign ( this . _months ) !== sign ( total ) ? '-' : '' ;
daysSign = sign ( this . _days ) !== sign ( total ) ? '-' : '' ;
hmsSign = sign ( this . _milliseconds ) !== sign ( total ) ? '-' : '' ;
return (
totalSign +
'P' +
( years ? ymSign + years + 'Y' : '' ) +
( months ? ymSign + months + 'M' : '' ) +
( days ? daysSign + days + 'D' : '' ) +
( hours || minutes || seconds ? 'T' : '' ) +
( hours ? hmsSign + hours + 'H' : '' ) +
( minutes ? hmsSign + minutes + 'M' : '' ) +
( seconds ? hmsSign + s + 'S' : '' )
) ;
}
var proto$2 = Duration . prototype ;
proto$2 . isValid = isValid$1 ;
proto$2 . abs = abs ;
proto$2 . add = add$1 ;
proto$2 . subtract = subtract$1 ;
proto$2 . as = as ;
proto$2 . asMilliseconds = asMilliseconds ;
proto$2 . asSeconds = asSeconds ;
proto$2 . asMinutes = asMinutes ;
proto$2 . asHours = asHours ;
proto$2 . asDays = asDays ;
proto$2 . asWeeks = asWeeks ;
proto$2 . asMonths = asMonths ;
proto$2 . asQuarters = asQuarters ;
proto$2 . asYears = asYears ;
proto$2 . valueOf = valueOf$1 ;
proto$2 . _bubble = bubble ;
proto$2 . clone = clone$1 ;
proto$2 . get = get$2 ;
proto$2 . milliseconds = milliseconds ;
proto$2 . seconds = seconds ;
proto$2 . minutes = minutes ;
proto$2 . hours = hours ;
proto$2 . days = days ;
proto$2 . weeks = weeks ;
proto$2 . months = months ;
proto$2 . years = years ;
proto$2 . humanize = humanize ;
proto$2 . toISOString = toISOString$1 ;
proto$2 . toString = toISOString$1 ;
proto$2 . toJSON = toISOString$1 ;
proto$2 . locale = locale ;
proto$2 . localeData = localeData ;
proto$2 . toIsoString = deprecate (
'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)' ,
toISOString$1
) ;
proto$2 . lang = lang ;
// FORMATTING
addFormatToken ( 'X' , 0 , 0 , 'unix' ) ;
addFormatToken ( 'x' , 0 , 0 , 'valueOf' ) ;
// PARSING
addRegexToken ( 'x' , matchSigned ) ;
addRegexToken ( 'X' , matchTimestamp ) ;
addParseToken ( 'X' , function ( input , array , config ) {
config . _d = new Date ( parseFloat ( input ) * 1000 ) ;
} ) ;
addParseToken ( 'x' , function ( input , array , config ) {
config . _d = new Date ( toInt ( input ) ) ;
} ) ;
//! moment.js
hooks . version = '2.29.4' ;
setHookCallback ( createLocal ) ;
hooks . fn = proto ;
hooks . min = min ;
hooks . max = max ;
hooks . now = now ;
hooks . utc = createUTC ;
hooks . unix = createUnix ;
hooks . months = listMonths ;
hooks . isDate = isDate ;
hooks . locale = getSetGlobalLocale ;
hooks . invalid = createInvalid ;
hooks . duration = createDuration ;
hooks . isMoment = isMoment ;
hooks . weekdays = listWeekdays ;
hooks . parseZone = createInZone ;
hooks . localeData = getLocale ;
hooks . isDuration = isDuration ;
hooks . monthsShort = listMonthsShort ;
hooks . weekdaysMin = listWeekdaysMin ;
hooks . defineLocale = defineLocale ;
hooks . updateLocale = updateLocale ;
hooks . locales = listLocales ;
hooks . weekdaysShort = listWeekdaysShort ;
hooks . normalizeUnits = normalizeUnits ;
hooks . relativeTimeRounding = getSetRelativeTimeRounding ;
hooks . relativeTimeThreshold = getSetRelativeTimeThreshold ;
hooks . calendarFormat = getCalendarFormat ;
hooks . prototype = proto ;
// currently HTML5 input type only supports 24-hour formats
hooks . HTML5 _FMT = {
DATETIME _LOCAL : 'YYYY-MM-DDTHH:mm' , // <input type="datetime-local" />
DATETIME _LOCAL _SECONDS : 'YYYY-MM-DDTHH:mm:ss' , // <input type="datetime-local" step="1" />
DATETIME _LOCAL _MS : 'YYYY-MM-DDTHH:mm:ss.SSS' , // <input type="datetime-local" step="0.001" />
DATE : 'YYYY-MM-DD' , // <input type="date" />
TIME : 'HH:mm' , // <input type="time" />
TIME _SECONDS : 'HH:mm:ss' , // <input type="time" step="1" />
TIME _MS : 'HH:mm:ss.SSS' , // <input type="time" step="0.001" />
WEEK : 'GGGG-[W]WW' , // <input type="week" />
MONTH : 'YYYY-MM' , // <input type="month" />
} ;
return hooks ;
} ) ) ) ;
} ) ;
function getWordCount ( text ) {
const spaceDelimitedChars = / ' ’ A - Z a - z \ u 0 0 A A \ u 0 0 B 5 \ u 0 0 B A \ u 0 0 C 0 - \ u 0 0 D 6 \ u 0 0 D 8 - \ u 0 0 F 6 \ u 0 0 F 8 - \ u 0 2 C 1 \ u 0 2 C 6 - \ u 0 2 D 1 \ u 0 2 E 0 - \ u 0 2 E 4 \ u 0 2 E C \ u 0 2 E E \ u 0 3 7 0 - \ u 0 3 7 4 \ u 0 3 7 6 \ u 0 3 7 7 \ u 0 3 7 A - \ u 0 3 7 D \ u 0 3 7 F \ u 0 3 8 6 \ u 0 3 8 8 - \ u 0 3 8 A \ u 0 3 8 C \ u 0 3 8 E - \ u 0 3 A 1 \ u 0 3 A 3 - \ u 0 3 F 5 \ u 0 3 F 7 - \ u 0 4 8 1 \ u 0 4 8 A - \ u 0 5 2 F \ u 0 5 3 1 - \ u 0 5 5 6 \ u 0 5 5 9 \ u 0 5 6 1 - \ u 0 5 8 7 \ u 0 5 D 0 - \ u 0 5 E A \ u 0 5 F 0 - \ u 0 5 F 2 \ u 0 6 2 0 - \ u 0 6 4 A \ u 0 6 6 E \ u 0 6 6 F \ u 0 6 7 1 - \ u 0 6 D 3 \ u 0 6 D 5 \ u 0 6 E 5 \ u 0 6 E 6 \ u 0 6 E E \ u 0 6 E F \ u 0 6 F A - \ u 0 6 F C \ u 0 6 F F \ u 0 7 1 0 \ u 0 7 1 2 - \ u 0 7 2 F \ u 0 7 4 D - \ u 0 7 A 5 \ u 0 7 B 1 \ u 0 7 C A - \ u 0 7 E A \ u 0 7 F 4 \ u 0 7 F 5 \ u 0 7 F A \ u 0 8 0 0 - \ u 0 8 1 5 \ u 0 8 1 A \ u 0 8 2 4 \ u 0 8 2 8 \ u 0 8 4 0 - \ u 0 8 5 8 \ u 0 8 A 0 - \ u 0 8 B 4 \ u 0 9 0 4 - \ u 0 9 3 9 \ u 0 9 3 D \ u 0 9 5 0 \ u 0 9 5 8 - \ u 0 9 6 1 \ u 0 9 7 1 - \ u 0 9 8 0 \ u 0 9 8 5 - \ u 0 9 8 C \ u 0 9 8 F \ u 0 9 9 0 \ u 0 9 9 3 - \ u 0 9 A 8 \ u 0 9 A A - \ u 0 9 B 0 \ u 0 9 B 2 \ u 0 9 B 6 - \ u 0 9 B 9 \ u 0 9 B D \ u 0 9 C E \ u 0 9 D C \ u 0 9 D D \ u 0 9 D F - \ u 0 9 E 1 \ u 0 9 F 0 \ u 0 9 F 1 \ u 0 A 0 5 - \ u 0 A 0 A \ u 0 A 0 F \ u 0 A 1 0 \ u 0 A 1 3 - \ u 0 A 2 8 \ u 0 A 2 A - \ u 0 A 3 0 \ u 0 A 3 2 \ u 0 A 3 3 \ u 0 A 3 5 \ u 0 A 3 6 \ u 0 A 3 8 \ u 0 A 3 9 \ u 0 A 5 9 - \ u 0 A 5 C \ u 0 A 5 E \ u 0 A 7 2 - \ u 0 A 7 4 \ u 0 A 8 5 - \ u 0 A 8 D \ u 0 A 8 F - \ u 0 A 9 1 \ u 0 A 9 3 - \ u 0 A A 8 \ u 0 A A A - \ u 0 A B 0 \ u 0 A B 2 \ u 0 A B 3 \ u 0 A B 5 - \ u 0 A B 9 \ u 0 A B D \ u 0 A D 0 \ u 0 A E 0 \ u 0 A E 1 \ u 0 A F 9 \ u 0 B 0 5 - \ u 0 B 0 C \ u 0 B 0 F \ u 0 B 1 0 \ u 0 B 1 3 - \ u 0 B 2 8 \ u 0 B 2 A - \ u 0 B 3 0 \ u 0 B 3 2 \ u 0 B 3 3 \ u 0 B 3 5 - \ u 0 B 3 9 \ u 0 B 3 D \ u 0 B 5 C \ u 0 B 5 D \ u 0 B 5 F - \ u 0 B 6 1 \ u 0 B 7 1 \ u 0 B 8 3 \ u 0 B 8 5 - \ u 0 B 8 A \ u 0 B 8 E - \ u 0 B 9 0 \ u 0 B 9 2 - \ u 0 B 9 5 \ u 0 B 9 9 \ u 0 B 9 A \ u 0 B 9 C \ u 0 B 9 E \ u 0 B 9 F \ u 0 B A 3 \ u 0 B A 4 \ u 0 B A 8 - \ u 0 B A A \ u 0 B A E - \ u 0 B B 9 \ u 0 B D 0 \ u 0 C 0 5 - \ u 0 C 0 C \ u 0 C 0 E - \ u 0 C 1 0 \ u 0 C 1 2 - \ u 0 C 2 8 \ u 0 C 2 A - \ u 0 C 3 9 \ u 0 C 3 D \ u 0 C 5 8 - \ u 0 C 5 A \ u 0 C 6 0 \ u 0 C 6 1 \ u 0 C 8 5 - \ u 0 C 8 C \ u 0 C 8 E - \ u 0 C 9 0 \ u 0 C 9 2 - \ u 0 C A 8 \ u 0 C A A - \ u 0 C B 3 \ u 0 C B 5 - \ u 0 C B 9 \ u 0 C B D \ u 0 C D E \ u 0 C E 0 \ u 0 C E 1 \ u 0 C F 1 \ u 0 C F 2 \ u 0 D 0 5 - \ u 0 D 0 C \ u 0 D 0 E - \ u 0 D 1 0 \ u 0 D 1 2 - \ u 0 D 3 A \ u 0 D 3 D \ u 0 D 4 E \ u 0 D 5 F - \ u 0 D 6 1 \ u 0 D 7 A - \ u 0 D 7 F \ u 0 D 8 5 - \ u 0 D 9 6 \ u 0 D 9 A - \ u 0 D B 1 \ u 0 D B 3 - \ u 0 D B B \ u 0 D B D \ u 0 D C 0 - \ u 0 D C 6 \ u 0 E 0 1 - \ u 0 E 3 0 \ u 0 E 3 2 \ u 0 E 3 3 \ u 0 E 4 0 - \ u 0 E 4 6 \ u 0 E 8 1 \ u 0 E 8 2 \ u 0 E 8 4 \ u 0 E 8 7 \ u 0 E 8 8 \ u 0 E 8 A \ u 0 E 8 D \ u 0 E 9 4 - \ u 0 E 9 7 \ u 0 E 9 9 - \ u 0 E 9 F \ u 0 E A 1 - \ u 0 E A 3 \ u 0 E A 5 \ u 0 E A 7 \ u 0 E A A \ u 0 E A B \ u 0 E A D - \ u 0 E B 0 \ u 0 E B 2 \ u 0 E B 3 \ u 0 E B D \ u 0 E C 0 - \ u 0 E C 4 \ u 0 E C 6 \ u 0 E D C - \ u 0 E D F \ u 0 F 0 0 \ u 0 F 4 0 - \ u 0 F 4 7 \ u 0 F 4 9 - \ u 0 F 6 C \ u 0 F 8 8 - \ u 0 F 8 C \ u 1 0 0 0 - \ u 1 0 2 A \ u 1 0 3 F \ u 1 0 5 0 - \ u 1 0 5 5 \ u 1 0 5 A - \ u 1 0 5 D \ u 1 0 6 1 \ u 1 0 6 5 \ u 1 0 6 6 \ u 1 0 6 E - \ u 1 0 7 0 \ u 1 0 7 5 - \ u 1 0 8 1 \ u 1 0 8 E \ u 1 0 A 0 - \ u 1 0 C 5 \ u 1 0 C 7 \ u 1 0 C D \ u 1 0 D 0 - \ u 1 0 F A \ u 1 0 F C - \ u 1 2 4 8 \ u 1 2 4 A - \ u 1 2 4 D \ u 1 2 5 0 - \ u 1 2 5 6 \ u 1 2 5 8 \ u 1 2 5 A - \ u 1 2 5 D \ u 1 2 6 0 - \ u 1 2 8 8 \ u 1 2 8 A - \ u 1 2 8 D \ u 1 2 9 0 - \ u 1 2 B 0 \ u 1 2 B 2 - \ u 1 2 B 5 \ u 1 2 B 8 - \ u 1 2 B E \ u 1 2 C 0 \ u 1 2 C 2 - \ u 1 2 C 5 \ u 1 2 C 8 - \ u 1 2 D 6 \ u 1 2 D 8 - \ u 1 3 1 0 \ u 1 3 1 2 - \ u 1 3 1 5 \ u 1 3 1 8 - \ u 1 3 5 A \ u 1 3 8 0 - \ u 1 3 8 F \ u 1 3 A 0 - \ u 1 3 F 5 \ u 1 3 F 8 - \ u 1 3 F D \ u 1 4 0 1 - \ u 1 6 6 C \ u 1 6 6 F - \ u 1 6 7 F \ u 1 6 8 1 - \ u 1 6 9 A \ u 1 6 A 0 - \ u 1 6 E A \ u 1 6 F 1 - \ u 1 6 F 8 \ u 1 7 0 0 - \ u 1 7 0 C \ u 1 7 0 E - \ u 1 7 1 1 \ u 1 7 2 0 - \ u 1 7 3 1 \ u 1 7 4 0 - \ u 1 7 5 1 \ u 1 7 6 0 - \ u 1 7 6 C \ u 1 7 6 E - \ u 1 7 7 0 \ u 1 7 8 0 - \ u 1 7 B 3 \ u 1 7 D 7 \ u 1 7 D C \ u 1 8 2 0 - \ u 1 8 7 7 \ u 1 8 8 0 - \ u 1 8 A 8 \ u 1 8 A A \ u 1 8 B 0 - \ u 1 8 F 5 \ u 1 9 0 0 - \ u 1 9 1 E \ u 1 9 5 0 - \ u 1 9 6 D \ u 1 9 7 0 - \ u 1 9 7 4 \ u 1 9 8 0 - \ u 1 9 A B \ u 1 9 B 0 - \ u 1 9 C 9 \ u 1 A 0 0 - \ u 1 A 1 6 \ u 1 A 2 0 - \ u 1 A 5 4 \ u 1 A A 7 \ u 1 B 0 5 - \ u 1 B 3 3 \ u 1 B 4 5 - \ u 1 B 4 B \ u 1 B 8 3 - \ u 1 B A 0 \ u 1 B A E \ u 1 B A F \ u 1 B B A - \ u 1 B E 5 \ u 1 C 0 0 - \ u 1 C 2 3 \ u 1 C 4 D - \ u 1 C 4 F \ u 1 C 5 A - \ u 1 C 7 D \ u 1 C E 9 - \ u 1 C E C \ u 1 C E E - \ u 1 C F 1 \ u 1 C F 5 \ u 1 C F 6 \ u 1 D 0 0 - \ u 1 D B F \ u 1 E 0 0 - \ u 1 F 1 5 \ u 1 F 1 8 - \ u 1 F 1 D \ u 1 F 2 0 - \ u 1 F 4 5 \ u 1 F 4 8 - \ u 1 F 4 D \ u 1 F 5 0 - \ u 1 F 5 7 \ u 1 F 5 9 \ u 1 F 5 B \ u 1 F 5 D \ u 1 F 5 F - \ u 1 F 7 D \ u 1 F 8 0 - \ u 1 F B 4 \ u 1 F B 6 - \ u 1 F B C \ u 1 F B E \ u 1 F C 2 - \ u 1 F C 4 \ u 1 F C 6 - \ u 1 F C C \ u 1 F D 0 - \ u 1 F D 3 \ u 1 F D 6 - \ u 1 F D B \ u 1 F E 0 - \ u 1 F E C \ u 1 F F 2 - \ u 1 F F 4 \ u 1 F F 6 - \ u 1 F F C \ u 2 0 7 1 \ u 2 0 7 F \ u 2 0 9 0 - \ u 2 0 9 C \ u 2 1 0 2 \ u 2 1 0 7 \ u 2 1 0 A - \ u 2 1 1 3 \ u 2 1 1 5 \ u 2 1 1 9 - \ u 2 1 1 D \ u 2 1 2 4 \ u 2 1 2 6 \ u 2 1 2 8 \ u 2 1 2 A - \ u 2 1 2 D \ u 2 1 2 F - \ u 2 1 3 9 \ u 2 1 3 C - \ u 2 1 3 F \ u 2 1 4 5 - \ u 2 1 4 9 \ u 2 1 4 E \ u 2 1 8 3 \ u 2 1 8 4 \ u 2 C 0 0 - \ u 2 C 2 E \ u 2 C 3 0 - \ u 2 C 5 E \ u 2 C 6 0 - \ u 2 C E 4 \ u 2 C E B - \ u 2 C E E \ u 2 C F 2 \ u 2 C F 3 \ u 2 D 0 0 - \ u 2 D 2 5 \ u 2 D 2 7 \ u 2 D 2 D \ u 2 D 3 0 - \ u 2 D 6 7 \ u 2 D 6 F \ u 2 D 8 0 - \ u 2 D 9 6 \ u 2 D A 0 - \ u 2 D A 6 \ u 2 D A 8 - \ u 2 D A E \ u 2 D B 0 - \ u 2 D B 6 \ u 2 D B 8 - \ u 2 D B E \ u 2 D C 0 - \ u 2 D C 6 \ u 2 D C 8 - \ u 2 D C E \ u 2 D D 0 - \ u 2 D D 6 \ u 2 D D 8 - \ u 2 D D E \ u 2 E 2 F \ u 3 0 0 5 \ u 3 0 0 6 \ u 3 0 3 1 - \ u 3 0 3 5 \ u 3 0 3 B \ u 3 0 3 C \ u 3 1 0 5 - \ u 3 1 2 D \ u 3 1 3 1 - \ u 3 1 8 E \ u 3 1 A 0 - \ u 3 1 B A \ u 3 1 F 0 - \ u 3 1 F F \ u 3 4 0 0 - \ u 4 D B 5 \ u A 0 0 0 - \ u A 4 8 C \ u A 4 D 0 - \ u A 4 F D \ u A 5 0 0 - \ u A 6 0 C \ u A 6 1 0 - \ u A 6 1 F \ u A 6 2 A \ u A 6 2 B \ u A 6 4 0 - \ u A 6 6 E \ u A 6 7 F - \ u A 6 9 D \ u A 6 A 0 - \ u A 6 E 5 \ u A 7 1 7 - \ u A 7 1 F \ u A 7 2 2 - \ u A 7 8 8 \ u A 7 8 B - \ u A 7 A D \ u A 7 B 0 - \ u A 7 B 7 \ u A 7 F 7 - \ u A 8 0 1 \ u A 8 0 3 - \ u A 8 0 5 \ u A 8 0 7 - \ u A 8 0 A \ u A 8 0 C - \ u A 8 2 2 \ u A 8 4 0 - \ u A 8 7 3 \ u A 8 8 2 - \ u A 8 B 3 \ u A 8 F 2 - \ u A 8 F 7 \ u A 8 F B \ u A 8 F D \ u A 9 0 A - \ u A 9 2 5 \ u A 9 3 0 - \ u A 9 4 6 \ u A 9 6 0 - \ u A 9 7 C \ u A 9 8 4 - \ u A 9 B 2 \ u A 9 C F \ u A 9 E 0 - \ u A 9 E 4 \ u A 9 E 6 - \ u A 9 E F \ u A 9 F A - \ u A 9 F E \ u A A 0 0 - \ u A A 2 8 \ u A A 4 0 - \ u A A 4 2 \ u A A 4 4 - \ u A A 4 B \ u A A 6 0 - \ u A A 7 6 \ u A A 7 A \ u A A 7 E - \ u A A A F \ u A A B 1 \ u A A B 5 \ u A A B 6 \ u A A B 9 - \ u A A B D \ u A A C 0 \ u A A C 2 \ u A A D B - \ u A A D D \ u A A E 0 - \ u A A E A \ u A A F 2 - \ u A A F 4 \ u A B 0 1 - \ u A B 0 6 \ u A B 0 9 - \ u A B 0 E \ u A B 1 1 - \ u A B 1 6 \ u A B 2 0 - \ u A B 2 6 \ u A B 2 8 - \ u A B 2 E \ u A B 3 0 - \ u A B 5 A \ u A B 5 C - \ u A B 6 5 \ u A B 7 0 - \ u A B E 2 \ u A C 0 0 - \ u D 7 A 3 \ u D 7 B 0 - \ u D 7 C 6 \ u D 7 C B - \ u D 7 F B \ u F 9 0 0 - \ u F A 6 D \ u F A 7 0 - \ u F A D 9 \ u F B 0 0 - \ u F B 0 6 \ u F B 1 3 - \ u F B 1 7 \ u F B 1 D \ u F B 1 F - \ u F B 2 8 \ u F B 2 A - \ u F B 3 6 \ u F B 3 8 - \ u F B 3 C \ u F B 3 E \ u F B 4 0 \ u F B 4 1 \ u F B 4 3 \ u F B 4 4 \ u F B 4 6 - \ u F B B 1 \ u F B D 3 - \ u F D 3 D \ u F D 5 0 - \ u F D 8 F \ u F D 9 2 - \ u F D
. source ;
const nonSpaceDelimitedWords = /\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u4E00-\u9FD5/ . source ;
const nonSpaceDelimitedWordsOther = /[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u4E00-\u9FD5]{1}/
. source ;
const pattern = new RegExp ( [
` (?:[0-9]+(?:(?:,| \\ .)[0-9]+)*|[ \\ - ${ spaceDelimitedChars } ])+ ` ,
nonSpaceDelimitedWords ,
nonSpaceDelimitedWordsOther ,
] . join ( "|" ) , "g" ) ;
return ( text . match ( pattern ) || [ ] ) . length ;
}
function getCharacterCount ( text ) {
return text . length ;
}
2023-04-03 20:35:26 +00:00
function getFootnoteCount ( text ) {
const regularFn = text . match ( /\[\^\S+](?!:)/g ) ;
const inlineFn = text . match ( /\^\[[^^].+?]/g ) ;
let overallFn = 0 ;
if ( regularFn )
overallFn += regularFn . length ;
if ( inlineFn )
overallFn += inlineFn . length ;
return overallFn ;
}
function getCitationCount ( text ) {
const pandocCitations = text . match ( /@[A-Za-z0-9-]+[,;\]](?!\()/gi ) ;
if ( ! pandocCitations )
return 0 ;
const uniqueCitations = [ ... new Set ( pandocCitations ) ] . length ;
return uniqueCitations ;
}
2023-03-02 21:47:11 +00:00
function getSentenceCount ( text ) {
const sentences = ( ( text || "" ) . match ( /[^.!?\s][^.!?]*(?:[.!?](?!['"]?\s|$)[^.!?]*)*[.!?]?['"]?(?=\s|$)/gm ) || [ ] ) . length ;
return sentences ;
}
2023-04-03 20:35:26 +00:00
function getPageCount ( text , pageWords ) {
return parseFloat ( ( getWordCount ( text ) / pageWords ) . toFixed ( 1 ) ) ;
}
function cleanComments ( text ) {
return text . replace ( MATCH _COMMENT , "" ) . replace ( MATCH _HTML _COMMENT , "" ) ;
}
2023-03-02 21:47:11 +00:00
class StatsManager {
2023-04-03 20:35:26 +00:00
constructor ( vault , workspace , plugin ) {
2023-03-02 21:47:11 +00:00
this . vault = vault ;
this . workspace = workspace ;
2023-04-03 20:35:26 +00:00
this . plugin = plugin ;
2023-03-02 21:47:11 +00:00
this . debounceChange = obsidian . debounce ( ( text ) => this . change ( text ) , 50 , false ) ;
this . vault . on ( "rename" , ( new _name , old _path ) => {
if ( this . vaultStats . modifiedFiles . hasOwnProperty ( old _path ) ) {
const content = this . vaultStats . modifiedFiles [ old _path ] ;
delete this . vaultStats . modifiedFiles [ old _path ] ;
this . vaultStats . modifiedFiles [ new _name . path ] = content ;
}
} ) ;
this . vault . on ( "delete" , ( deleted _file ) => {
if ( this . vaultStats . modifiedFiles . hasOwnProperty ( deleted _file . path ) ) {
delete this . vaultStats . modifiedFiles [ deleted _file . path ] ;
}
} ) ;
this . vault . adapter . exists ( STATS _FILE ) . then ( async ( exists ) => {
if ( ! exists ) {
const vaultSt = {
history : { } ,
modifiedFiles : { } ,
} ;
await this . vault . adapter . write ( STATS _FILE , JSON . stringify ( vaultSt ) ) ;
this . vaultStats = JSON . parse ( await this . vault . adapter . read ( STATS _FILE ) ) ;
}
else {
this . vaultStats = JSON . parse ( await this . vault . adapter . read ( STATS _FILE ) ) ;
if ( ! this . vaultStats . hasOwnProperty ( "history" ) ) {
const vaultSt = {
history : { } ,
modifiedFiles : { } ,
} ;
await this . vault . adapter . write ( STATS _FILE , JSON . stringify ( vaultSt ) ) ;
}
this . vaultStats = JSON . parse ( await this . vault . adapter . read ( STATS _FILE ) ) ;
}
await this . updateToday ( ) ;
} ) ;
}
async update ( ) {
this . vault . adapter . write ( STATS _FILE , JSON . stringify ( this . vaultStats ) ) ;
}
async updateToday ( ) {
if ( this . vaultStats . history . hasOwnProperty ( moment ( ) . format ( "YYYY-MM-DD" ) ) ) {
this . today = moment ( ) . format ( "YYYY-MM-DD" ) ;
return ;
}
this . today = moment ( ) . format ( "YYYY-MM-DD" ) ;
const totalWords = await this . calcTotalWords ( ) ;
const totalCharacters = await this . calcTotalCharacters ( ) ;
const totalSentences = await this . calcTotalSentences ( ) ;
2023-04-03 20:35:26 +00:00
const totalFootnotes = await this . calcTotalFootnotes ( ) ;
const totalCitations = await this . calcTotalCitations ( ) ;
const totalPages = await this . calcTotalPages ( ) ;
2023-03-02 21:47:11 +00:00
const newDay = {
words : 0 ,
characters : 0 ,
sentences : 0 ,
2023-04-03 20:35:26 +00:00
pages : 0 ,
2023-03-02 21:47:11 +00:00
files : 0 ,
2023-04-03 20:35:26 +00:00
footnotes : 0 ,
citations : 0 ,
2023-03-02 21:47:11 +00:00
totalWords : totalWords ,
totalCharacters : totalCharacters ,
totalSentences : totalSentences ,
2023-04-03 20:35:26 +00:00
totalFootnotes : totalFootnotes ,
totalCitations : totalCitations ,
totalPages : totalPages ,
2023-03-02 21:47:11 +00:00
} ;
this . vaultStats . modifiedFiles = { } ;
this . vaultStats . history [ this . today ] = newDay ;
await this . update ( ) ;
}
async change ( text ) {
2023-04-03 20:35:26 +00:00
if ( this . plugin . settings . countComments ) {
text = cleanComments ( text ) ;
}
2023-03-02 21:47:11 +00:00
const fileName = this . workspace . getActiveFile ( ) . path ;
const currentWords = getWordCount ( text ) ;
const currentCharacters = getCharacterCount ( text ) ;
const currentSentences = getSentenceCount ( text ) ;
2023-04-03 20:35:26 +00:00
const currentCitations = getCitationCount ( text ) ;
const currentFootnotes = getFootnoteCount ( text ) ;
const currentPages = getPageCount ( text , this . plugin . settings . pageWords ) ;
2023-03-02 21:47:11 +00:00
if ( this . vaultStats . history . hasOwnProperty ( this . today ) &&
this . today === moment ( ) . format ( "YYYY-MM-DD" ) ) {
let modFiles = this . vaultStats . modifiedFiles ;
if ( modFiles . hasOwnProperty ( fileName ) ) {
this . vaultStats . history [ this . today ] . totalWords +=
currentWords - modFiles [ fileName ] . words . current ;
this . vaultStats . history [ this . today ] . totalCharacters +=
currentCharacters - modFiles [ fileName ] . characters . current ;
this . vaultStats . history [ this . today ] . totalSentences +=
currentSentences - modFiles [ fileName ] . sentences . current ;
2023-04-03 20:35:26 +00:00
this . vaultStats . history [ this . today ] . totalFootnotes +=
currentSentences - modFiles [ fileName ] . footnotes . current ;
this . vaultStats . history [ this . today ] . totalCitations +=
currentSentences - modFiles [ fileName ] . citations . current ;
this . vaultStats . history [ this . today ] . totalPages +=
currentPages - modFiles [ fileName ] . pages . current ;
2023-03-02 21:47:11 +00:00
modFiles [ fileName ] . words . current = currentWords ;
modFiles [ fileName ] . characters . current = currentCharacters ;
modFiles [ fileName ] . sentences . current = currentSentences ;
2023-04-03 20:35:26 +00:00
modFiles [ fileName ] . footnotes . current = currentFootnotes ;
modFiles [ fileName ] . citations . current = currentCitations ;
modFiles [ fileName ] . pages . current = currentPages ;
2023-03-02 21:47:11 +00:00
}
else {
modFiles [ fileName ] = {
words : {
initial : currentWords ,
current : currentWords ,
} ,
characters : {
initial : currentCharacters ,
current : currentCharacters ,
} ,
sentences : {
initial : currentSentences ,
current : currentSentences ,
} ,
2023-04-03 20:35:26 +00:00
footnotes : {
initial : currentFootnotes ,
current : currentFootnotes ,
} ,
citations : {
initial : currentCitations ,
current : currentCitations ,
} ,
pages : {
initial : currentPages ,
current : currentPages ,
} ,
2023-03-02 21:47:11 +00:00
} ;
}
const words = Object . values ( modFiles )
. map ( ( counts ) => Math . max ( 0 , counts . words . current - counts . words . initial ) )
. reduce ( ( a , b ) => a + b , 0 ) ;
const characters = Object . values ( modFiles )
. map ( ( counts ) => Math . max ( 0 , counts . characters . current - counts . characters . initial ) )
. reduce ( ( a , b ) => a + b , 0 ) ;
const sentences = Object . values ( modFiles )
. map ( ( counts ) => Math . max ( 0 , counts . sentences . current - counts . sentences . initial ) )
. reduce ( ( a , b ) => a + b , 0 ) ;
2023-04-03 20:35:26 +00:00
const footnotes = Object . values ( modFiles )
. map ( ( counts ) => Math . max ( 0 , counts . footnotes . current - counts . footnotes . initial ) )
. reduce ( ( a , b ) => a + b , 0 ) ;
const citations = Object . values ( modFiles )
. map ( ( counts ) => Math . max ( 0 , counts . citations . current - counts . citations . initial ) ) . reduce ( ( a , b ) => a + b , 0 ) ;
const pages = Object . values ( modFiles )
. map ( ( counts ) => Math . max ( 0 , counts . pages . current - counts . pages . initial ) )
. reduce ( ( a , b ) => a + b , 0 ) ;
2023-03-02 21:47:11 +00:00
this . vaultStats . history [ this . today ] . words = words ;
this . vaultStats . history [ this . today ] . characters = characters ;
this . vaultStats . history [ this . today ] . sentences = sentences ;
2023-04-03 20:35:26 +00:00
this . vaultStats . history [ this . today ] . footnotes = footnotes ;
this . vaultStats . history [ this . today ] . citations = citations ;
this . vaultStats . history [ this . today ] . pages = pages ;
2023-03-02 21:47:11 +00:00
this . vaultStats . history [ this . today ] . files = this . getTotalFiles ( ) ;
await this . update ( ) ;
}
else {
this . updateToday ( ) ;
}
}
async recalcTotals ( ) {
if ( ! this . vaultStats )
return ;
if ( this . vaultStats . history . hasOwnProperty ( this . today ) &&
this . today === moment ( ) . format ( "YYYY-MM-DD" ) ) {
const todayHist = this . vaultStats . history [ this . today ] ;
todayHist . totalWords = await this . calcTotalWords ( ) ;
todayHist . totalCharacters = await this . calcTotalCharacters ( ) ;
todayHist . totalSentences = await this . calcTotalSentences ( ) ;
2023-04-03 20:35:26 +00:00
todayHist . totalFootnotes = await this . calcTotalFootnotes ( ) ;
todayHist . totalCitations = await this . calcTotalCitations ( ) ;
todayHist . totalPages = await this . calcTotalPages ( ) ;
2023-03-02 21:47:11 +00:00
this . update ( ) ;
}
else {
this . updateToday ( ) ;
}
}
async calcTotalWords ( ) {
let words = 0 ;
const files = this . vault . getFiles ( ) ;
for ( const i in files ) {
const file = files [ i ] ;
if ( file . extension === "md" ) {
words += getWordCount ( await this . vault . cachedRead ( file ) ) ;
}
}
return words ;
}
async calcTotalCharacters ( ) {
let characters = 0 ;
const files = this . vault . getFiles ( ) ;
for ( const i in files ) {
const file = files [ i ] ;
if ( file . extension === "md" ) {
characters += getCharacterCount ( await this . vault . cachedRead ( file ) ) ;
}
}
return characters ;
}
async calcTotalSentences ( ) {
let sentence = 0 ;
const files = this . vault . getFiles ( ) ;
for ( const i in files ) {
const file = files [ i ] ;
if ( file . extension === "md" ) {
sentence += getSentenceCount ( await this . vault . cachedRead ( file ) ) ;
}
}
return sentence ;
}
2023-04-03 20:35:26 +00:00
async calcTotalPages ( ) {
let pages = 0 ;
const files = this . vault . getFiles ( ) ;
for ( const i in files ) {
const file = files [ i ] ;
if ( file . extension === "md" ) {
pages += getPageCount ( await this . vault . cachedRead ( file ) , this . plugin . settings . pageWords ) ;
}
}
return pages ;
}
async calcTotalFootnotes ( ) {
let footnotes = 0 ;
const files = this . vault . getFiles ( ) ;
for ( const i in files ) {
const file = files [ i ] ;
if ( file . extension === "md" ) {
footnotes += getFootnoteCount ( await this . vault . cachedRead ( file ) ) ;
}
}
return footnotes ;
}
async calcTotalCitations ( ) {
let citations = 0 ;
const files = this . vault . getFiles ( ) ;
for ( const i in files ) {
const file = files [ i ] ;
if ( file . extension === "md" ) {
citations += getCitationCount ( await this . vault . cachedRead ( file ) ) ;
}
}
return citations ;
}
2023-03-02 21:47:11 +00:00
getDailyWords ( ) {
return this . vaultStats . history [ this . today ] . words ;
}
getDailyCharacters ( ) {
return this . vaultStats . history [ this . today ] . characters ;
}
getDailySentences ( ) {
return this . vaultStats . history [ this . today ] . sentences ;
}
2023-04-03 20:35:26 +00:00
getDailyFootnotes ( ) {
return this . vaultStats . history [ this . today ] . footnotes ;
}
getDailyCitations ( ) {
return this . vaultStats . history [ this . today ] . citations ;
}
getDailyPages ( ) {
return this . vaultStats . history [ this . today ] . pages ;
}
2023-03-02 21:47:11 +00:00
getTotalFiles ( ) {
return this . vault . getMarkdownFiles ( ) . length ;
}
async getTotalWords ( ) {
if ( ! this . vaultStats )
return await this . calcTotalWords ( ) ;
return this . vaultStats . history [ this . today ] . totalWords ;
}
async getTotalCharacters ( ) {
if ( ! this . vaultStats )
return await this . calcTotalCharacters ( ) ;
return this . vaultStats . history [ this . today ] . totalCharacters ;
}
async getTotalSentences ( ) {
if ( ! this . vaultStats )
return await this . calcTotalSentences ( ) ;
return this . vaultStats . history [ this . today ] . totalSentences ;
}
2023-04-03 20:35:26 +00:00
async getTotalFootnotes ( ) {
if ( ! this . vaultStats )
return await this . calcTotalFootnotes ( ) ;
return this . vaultStats . history [ this . today ] . totalFootnotes ;
}
async getTotalCitations ( ) {
if ( ! this . vaultStats )
return await this . calcTotalCitations ( ) ;
return this . vaultStats . history [ this . today ] . totalCitations ;
}
async getTotalPages ( ) {
if ( ! this . vaultStats )
return await this . calcTotalPages ( ) ;
return this . vaultStats . history [ this . today ] . totalPages ;
}
2023-03-02 21:47:11 +00:00
}
class StatusBar {
constructor ( statusBarEl , plugin ) {
this . statusBarEl = statusBarEl ;
this . plugin = plugin ;
this . debounceStatusBarUpdate = obsidian . debounce ( ( text ) => this . updateStatusBar ( text ) , 20 , false ) ;
this . statusBarEl . classList . add ( "mod-clickable" ) ;
2023-04-03 20:35:26 +00:00
this . statusBarEl . setAttribute ( "aria-label" , "!!!" ) ;
2023-03-02 21:47:11 +00:00
this . statusBarEl . setAttribute ( "aria-label-position" , "top" ) ;
this . statusBarEl . addEventListener ( "click" , ( ev ) => this . onClick ( ev ) ) ;
}
onClick ( ev ) {
}
displayText ( text ) {
this . statusBarEl . setText ( text ) ;
}
async updateStatusBar ( text ) {
const sb = this . plugin . settings . statusBar ;
let display = "" ;
2023-08-21 17:47:20 +00:00
if ( this . plugin . settings . countComments ) {
2023-04-03 20:35:26 +00:00
text = cleanComments ( text ) ;
}
2023-03-02 21:47:11 +00:00
for ( let i = 0 ; i < sb . length ; i ++ ) {
const sbItem = sb [ i ] ;
display = display + sbItem . prefix ;
const metric = sbItem . metric ;
if ( metric . counter === MetricCounter . words ) {
switch ( metric . type ) {
case MetricType . file :
display = display + getWordCount ( text ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyWords ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalWords ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . characters ) {
switch ( metric . type ) {
case MetricType . file :
display = display + getCharacterCount ( text ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyCharacters ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalCharacters ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . sentences ) {
switch ( metric . type ) {
case MetricType . file :
display = display + getSentenceCount ( text ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailySentences ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalSentences ( )
: 0 ) ) ;
break ;
}
}
2023-04-03 20:35:26 +00:00
else if ( metric . counter === MetricCounter . footnotes ) {
switch ( metric . type ) {
case MetricType . file :
display = display + getFootnoteCount ( text ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyFootnotes ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFootnotes ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . citations ) {
switch ( metric . type ) {
case MetricType . file :
display = display + getCitationCount ( text ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyCitations ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalCitations ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . pages ) {
switch ( metric . type ) {
case MetricType . file :
display = display + getPageCount ( text , this . plugin . settings . pageWords ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyPages ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalPages ( )
: 0 ) ) ;
break ;
}
}
2023-03-02 21:47:11 +00:00
else if ( metric . counter === MetricCounter . files ) {
switch ( metric . type ) {
case MetricType . file :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFiles ( )
: 0 ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFiles ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFiles ( )
: 0 ) ;
break ;
}
}
display = display + sbItem . suffix ;
}
this . displayText ( display ) ;
}
async updateAltBar ( ) {
const ab = this . plugin . settings . altBar ;
let display = "" ;
for ( let i = 0 ; i < ab . length ; i ++ ) {
const sbItem = ab [ i ] ;
display = display + sbItem . prefix ;
const metric = sbItem . metric ;
if ( metric . counter === MetricCounter . words ) {
switch ( metric . type ) {
case MetricType . file :
display = display + 0 ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyWords ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalWords ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . characters ) {
switch ( metric . type ) {
case MetricType . file :
display = display + 0 ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyCharacters ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalCharacters ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . sentences ) {
switch ( metric . type ) {
case MetricType . file :
display = display + 0 ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailySentences ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalSentences ( )
: 0 ) ) ;
break ;
}
}
2023-04-03 20:35:26 +00:00
else if ( metric . counter === MetricCounter . footnotes ) {
switch ( metric . type ) {
case MetricType . file :
display = display + 0 ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyFootnotes ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFootnotes ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . citations ) {
switch ( metric . type ) {
case MetricType . file :
display = display + 0 ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyCitations ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalCitations ( )
: 0 ) ) ;
break ;
}
}
else if ( metric . counter === MetricCounter . pages ) {
switch ( metric . type ) {
case MetricType . file :
display = display + 0 ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getDailyPages ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( await ( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalPages ( )
: 0 ) ) ;
break ;
}
}
2023-03-02 21:47:11 +00:00
else if ( metric . counter === MetricCounter . files ) {
switch ( metric . type ) {
case MetricType . file :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFiles ( )
: 0 ) ;
break ;
case MetricType . daily :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFiles ( )
: 0 ) ;
break ;
case MetricType . total :
display =
display +
( this . plugin . settings . collectStats
? this . plugin . statsManager . getTotalFiles ( )
: 0 ) ;
break ;
}
}
display = display + sbItem . suffix ;
}
this . displayText ( display ) ;
}
}
2023-08-21 17:47:20 +00:00
const pluginField = state . StateField . define ( {
create ( ) {
return null ;
} ,
update ( state ) {
return state ;
} ,
} ) ;
class StatusBarEditorPlugin {
2023-03-02 21:47:11 +00:00
constructor ( view ) {
this . view = view ;
}
update ( update ) {
const tr = update . transactions [ 0 ] ;
2023-04-03 20:35:26 +00:00
if ( ! tr ) {
2023-03-02 21:47:11 +00:00
return ;
2023-04-03 20:35:26 +00:00
}
2023-08-21 17:47:20 +00:00
const plugin = update . view . state . field ( pluginField ) ;
2023-04-03 20:35:26 +00:00
// When selecting text with Shift+Home the userEventType is undefined.
// This is probably a bug in codemirror, for the time being doing an explict check
// for the type allows us to update the stats for the selection.
const userEventTypeUndefined = tr . annotation ( state . Transaction . userEvent ) === undefined ;
if ( ( tr . isUserEvent ( "select" ) || userEventTypeUndefined ) &&
2023-03-02 21:47:11 +00:00
tr . newSelection . ranges [ 0 ] . from !== tr . newSelection . ranges [ 0 ] . to ) {
let text = "" ;
const selection = tr . newSelection . main ;
const textIter = tr . newDoc . iterRange ( selection . from , selection . to ) ;
while ( ! textIter . done ) {
text = text + textIter . next ( ) . value ;
}
2023-08-21 17:47:20 +00:00
plugin . statusBar . debounceStatusBarUpdate ( text ) ;
2023-03-02 21:47:11 +00:00
}
else if ( tr . isUserEvent ( "input" ) ||
tr . isUserEvent ( "delete" ) ||
tr . isUserEvent ( "move" ) ||
tr . isUserEvent ( "undo" ) ||
tr . isUserEvent ( "redo" ) ||
tr . isUserEvent ( "select" ) ) {
const textIter = tr . newDoc . iter ( ) ;
let text = "" ;
while ( ! textIter . done ) {
text = text + textIter . next ( ) . value ;
}
2023-08-21 17:47:20 +00:00
if ( tr . docChanged && plugin . statsManager ) {
plugin . statsManager . debounceChange ( text ) ;
2023-03-02 21:47:11 +00:00
}
2023-08-21 17:47:20 +00:00
plugin . statusBar . debounceStatusBarUpdate ( text ) ;
2023-03-02 21:47:11 +00:00
}
}
destroy ( ) { }
}
2023-08-21 17:47:20 +00:00
const statusBarEditorPlugin = view . ViewPlugin . fromClass ( StatusBarEditorPlugin ) ;
class SectionWidget extends view . WidgetType {
constructor ( data ) {
super ( ) ;
this . data = data ;
}
eq ( widget ) {
const { pos , self , total } = this . data ;
return pos === widget . data . pos && self === widget . data . self && total === widget . data . total ;
}
getDisplayText ( ) {
const { self , total } = this . data ;
if ( self && self !== total ) {
return ` ${ self } / ${ total } ` ;
}
return total . toString ( ) ;
}
toDOM ( ) {
return createSpan ( { cls : "bwc-section-count" , text : this . getDisplayText ( ) } ) ;
}
}
class SectionWordCountEditorPlugin {
constructor ( view$1 ) {
this . lineCounts = [ ] ;
const plugin = view$1 . state . field ( pluginField ) ;
if ( ! plugin . settings . displaySectionCounts ) {
this . decorations = view . Decoration . none ;
return ;
}
this . calculateLineCounts ( view$1 . state , plugin ) ;
this . decorations = this . mkDeco ( view$1 ) ;
}
calculateLineCounts ( state$1 , plugin ) {
const stripComments = plugin . settings . countComments ;
let docStr = state$1 . doc . toString ( ) ;
if ( stripComments ) {
// Strip out comments, but preserve new lines for accurate positioning data
const preserveNl = ( match , offset , str ) => {
let output = '' ;
for ( let i = offset , len = offset + match . length ; i < len ; i ++ ) {
if ( /[\r\n]/ . test ( str [ i ] ) ) {
output += str [ i ] ;
}
}
return output ;
} ;
docStr = docStr . replace ( MATCH _COMMENT , preserveNl ) . replace ( MATCH _HTML _COMMENT , preserveNl ) ;
}
const lines = docStr . split ( state$1 . facet ( state . EditorState . lineSeparator ) || /\r\n?|\n/ ) ;
for ( let i = 0 , len = lines . length ; i < len ; i ++ ) {
let line = lines [ i ] ;
this . lineCounts . push ( getWordCount ( line ) ) ;
}
}
update ( update ) {
const plugin = update . view . state . field ( pluginField ) ;
const { displaySectionCounts , countComments : stripComments } = plugin . settings ;
let didSettingsChange = false ;
if ( this . lineCounts . length && ! displaySectionCounts ) {
this . lineCounts = [ ] ;
this . decorations = view . Decoration . none ;
return ;
}
else if ( ! this . lineCounts . length && displaySectionCounts ) {
didSettingsChange = true ;
this . calculateLineCounts ( update . startState , plugin ) ;
}
if ( update . docChanged ) {
const startDoc = update . startState . doc ;
let tempDoc = startDoc ;
let editStartLine = Infinity ;
let editEndLine = - Infinity ;
update . changes . iterChanges ( ( fromA , toA , fromB , toB , text ) => {
const from = fromB ;
const to = fromB + ( toA - fromA ) ;
const nextTo = from + text . length ;
const fromLine = tempDoc . lineAt ( from ) ;
const toLine = tempDoc . lineAt ( to ) ;
tempDoc = tempDoc . replace ( fromB , fromB + ( toA - fromA ) , text ) ;
const nextFromLine = tempDoc . lineAt ( from ) ;
const nextToLine = tempDoc . lineAt ( nextTo ) ;
const lines = [ ] ;
for ( let i = nextFromLine . number ; i <= nextToLine . number ; i ++ ) {
lines . push ( getWordCount ( tempDoc . line ( i ) . text ) ) ;
}
const spliceStart = fromLine . number - 1 ;
const spliceLen = toLine . number - fromLine . number + 1 ;
editStartLine = Math . min ( editStartLine , spliceStart ) ;
editEndLine = Math . max ( editEndLine , spliceStart + ( nextToLine . number - nextFromLine . number + 1 ) ) ;
this . lineCounts . splice ( spliceStart , spliceLen , ... lines ) ;
} ) ;
// Filter out any counts associated with comments in the lines that were edited
if ( stripComments ) {
const tree = language . syntaxTree ( update . state ) ;
for ( let i = editStartLine ; i < editEndLine ; i ++ ) {
const line = update . state . doc . line ( i + 1 ) ;
let newLine = '' ;
let pos = 0 ;
let foundComment = false ;
tree . iterate ( {
enter ( node ) {
if ( node . name && /comment/ . test ( node . name ) ) {
foundComment = true ;
newLine += line . text . substring ( pos , node . from - line . from ) ;
pos = node . to - line . from ;
}
} ,
from : line . from ,
to : line . to ,
} ) ;
if ( foundComment ) {
newLine += line . text . substring ( pos ) ;
this . lineCounts [ i ] = getWordCount ( newLine ) ;
}
}
}
}
if ( update . docChanged || update . viewportChanged || didSettingsChange ) {
this . decorations = this . mkDeco ( update . view ) ;
}
}
mkDeco ( view$1 ) {
const plugin = view$1 . state . field ( pluginField ) ;
const b = new state . RangeSetBuilder ( ) ;
if ( ! plugin . settings . displaySectionCounts )
return b . finish ( ) ;
const getHeaderLevel = ( line ) => {
const match = line . text . match ( /^(#+)[ \t]/ ) ;
return match ? match [ 1 ] . length : null ;
} ;
if ( ! view$1 . visibleRanges . length )
return b . finish ( ) ;
// Start processing from the beginning of the first visible range
const { from } = view$1 . visibleRanges [ 0 ] ;
const doc = view$1 . state . doc ;
const lineStart = doc . lineAt ( from ) ;
const lineCount = doc . lines ;
const sectionCounts = [ ] ;
const nested = [ ] ;
for ( let i = lineStart . number ; i <= lineCount ; i ++ ) {
let line ;
if ( i === lineStart . number )
line = lineStart ;
else
line = doc . line ( i ) ;
const level = getHeaderLevel ( line ) ;
const prevHeading = nested . last ( ) ;
if ( level ) {
if ( ! prevHeading || level > prevHeading . level ) {
// The first heading or moving to a higher level eg. ## -> ###
nested . push ( {
line : i ,
level ,
self : 0 ,
total : 0 ,
pos : line . to ,
} ) ;
}
else if ( prevHeading . level === level ) {
// Same level as the previous heading
const nestedHeading = nested . pop ( ) ;
sectionCounts . push ( nestedHeading ) ;
nested . push ( {
line : i ,
level ,
self : 0 ,
total : 0 ,
pos : line . to ,
} ) ;
}
else if ( prevHeading . level > level ) {
// Traversing to lower level heading (eg. ### -> ##)
for ( let j = nested . length - 1 ; j >= 0 ; j -- ) {
const nestedHeading = nested [ j ] ;
if ( level < nestedHeading . level ) {
// Continue traversing to lower level heading
const nestedHeading = nested . pop ( ) ;
sectionCounts . push ( nestedHeading ) ;
if ( j === 0 ) {
nested . push ( {
line : i ,
level ,
self : 0 ,
total : 0 ,
pos : line . to ,
} ) ;
}
continue ;
}
if ( level === nestedHeading . level ) {
// Stop because we found an equal level heading
const nestedHeading = nested . pop ( ) ;
sectionCounts . push ( nestedHeading ) ;
nested . push ( {
line : i ,
level ,
self : 0 ,
total : 0 ,
pos : line . to ,
} ) ;
break ;
}
if ( level > nestedHeading . level ) {
// Stop because we found an higher level heading
nested . push ( {
line : i ,
level ,
self : 0 ,
total : 0 ,
pos : line . to ,
} ) ;
break ;
}
}
}
}
else if ( nested . length ) {
// Not in a heading, so add the word count of the line to the headings containing this line
const count = this . lineCounts [ i - 1 ] ;
for ( const heading of nested ) {
if ( heading === prevHeading ) {
heading . self += count ;
}
heading . total += count ;
}
}
}
if ( nested . length )
sectionCounts . push ( ... nested ) ;
sectionCounts . sort ( ( a , b ) => a . line - b . line ) ;
for ( const data of sectionCounts ) {
b . add ( data . pos , data . pos , view . Decoration . widget ( {
side : 1 ,
widget : new SectionWidget ( data ) ,
} ) ) ;
}
return b . finish ( ) ;
}
}
const settingsChanged = state . StateEffect . define ( ) ;
const sectionWordCountEditorPlugin = view . ViewPlugin . fromClass ( SectionWordCountEditorPlugin , {
decorations : ( v ) => v . decorations ,
} ) ;
2023-03-02 21:47:11 +00:00
class BetterWordCount extends obsidian . Plugin {
async onunload ( ) {
this . statsManager = null ;
this . statusBar = null ;
}
async onload ( ) {
// Settings Store
// this.register(
// settingsStore.subscribe((value) => {
// this.settings = value;
// })
// );
// Handle Settings
this . settings = Object . assign ( DEFAULT _SETTINGS , await this . loadData ( ) ) ;
this . addSettingTab ( new BetterWordCountSettingsTab ( this . app , this ) ) ;
// Handle Statistics
if ( this . settings . collectStats ) {
2023-04-03 20:35:26 +00:00
this . statsManager = new StatsManager ( this . app . vault , this . app . workspace , this ) ;
2023-03-02 21:47:11 +00:00
}
// Handle Status Bar
let statusBarEl = this . addStatusBarItem ( ) ;
this . statusBar = new StatusBar ( statusBarEl , this ) ;
2023-08-21 17:47:20 +00:00
// Handle the Editor Plugins
this . registerEditorExtension ( [ pluginField . init ( ( ) => this ) , statusBarEditorPlugin , sectionWordCountEditorPlugin ] ) ;
2023-03-02 21:47:11 +00:00
this . registerEvent ( this . app . workspace . on ( "active-leaf-change" , async ( leaf ) => {
if ( leaf . view . getViewType ( ) !== "markdown" ) {
this . statusBar . updateAltBar ( ) ;
}
if ( ! this . settings . collectStats )
return ;
await this . statsManager . recalcTotals ( ) ;
} ) ) ;
this . registerEvent ( this . app . vault . on ( "delete" , async ( ) => {
if ( ! this . settings . collectStats )
return ;
await this . statsManager . recalcTotals ( ) ;
} ) ) ;
}
async saveSettings ( ) {
await this . saveData ( this . settings ) ;
}
2023-08-21 17:47:20 +00:00
onDisplaySectionCountsChange ( ) {
this . app . workspace . getLeavesOfType ( "markdown" ) . forEach ( ( leaf ) => {
if ( ( leaf === null || leaf === void 0 ? void 0 : leaf . view ) instanceof obsidian . MarkdownView ) {
const cm = leaf . view . editor . cm ;
if ( cm . dispatch ) {
cm . dispatch ( {
effects : [ settingsChanged . of ( ) ] ,
} ) ;
}
}
} ) ;
}
2023-03-02 21:47:11 +00:00
}
module . exports = BetterWordCount ;
2023-08-21 17:47:20 +00:00
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsiLi4vbm9kZV9tb2R1bGVzL3N2ZWx0ZS9pbnRlcm5hbC9pbmRleC5tanMiLCIuLi9zcmMvc2V0dGluZ3MvU2V0dGluZ3MudHMiLCIuLi9zcmMvc2V0dGluZ3MvU3RhdHVzQmFyU2V0dGluZ3Muc3ZlbHRlIiwiLi4vc3JjL3NldHRpbmdzL1N0YXR1c0JhclNldHRpbmdzLnRzIiwiLi4vc3JjL3NldHRpbmdzL1NldHRpbmdzVGFiLnRzIiwiLi4vc3JjL2NvbnN0YW50cy50cyIsIi4uL25vZGVfbW9kdWxlcy9tb21lbnQvbW9tZW50LmpzIiwiLi4vc3JjL3V0aWxzL1N0YXRVdGlscy50cyIsIi4uL3NyYy9zdGF0cy9TdGF0c01hbmFnZXIudHMiLCIuLi9zcmMvc3RhdHVzL1N0YXR1c0Jhci50cyIsIi4uL3NyYy9lZGl0b3IvRWRpdG9yUGx1Z2luLnRzIiwiLi4vc3JjL21haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gbm9vcCgpIHsgfVxuY29uc3QgaWRlbnRpdHkgPSB4ID0+IHg7XG5mdW5jdGlvbiBhc3NpZ24odGFyLCBzcmMpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgZm9yIChjb25zdCBrIGluIHNyYylcbiAgICAgICAgdGFyW2tdID0gc3JjW2tdO1xuICAgIHJldHVybiB0YXI7XG59XG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3RoZW4vaXMtcHJvbWlzZS9ibG9iL21hc3Rlci9pbmRleC5qc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgTUlUIExpY2Vuc2UgaHR0cHM6Ly9naXRodWIuY29tL3RoZW4vaXMtcHJvbWlzZS9ibG9iL21hc3Rlci9MSUNFTlNFXG5mdW5jdGlvbiBpc19wcm9taXNlKHZhbHVlKSB7XG4gICAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSAmJiB0eXBlb2YgdmFsdWUudGhlbiA9PT0gJ2Z1bmN0aW9uJztcbn1cbmZ1bmN0aW9uIGFkZF9sb2NhdGlvbihlbGVtZW50LCBmaWxlLCBsaW5lLCBjb2x1bW4sIGNoYXIpIHtcbiAgICBlbGVtZW50Ll9fc3ZlbHRlX21ldGEgPSB7XG4gICAgICAgIGxvYzogeyBmaWxlLCBsaW5lLCBjb2x1bW4sIGNoYXIgfVxuICAgIH07XG59XG5mdW5jdGlvbiBydW4oZm4pIHtcbiAgICByZXR1cm4gZm4oKTtcbn1cbmZ1bmN0aW9uIGJsYW5rX29iamVjdCgpIHtcbiAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZShudWxsKTtcbn1cbmZ1bmN0aW9uIHJ1bl9hbGwoZm5zKSB7XG4gICAgZm5zLmZvckVhY2gocnVuKTtcbn1cbmZ1bmN0aW9uIGlzX2Z1bmN0aW9uKHRoaW5nKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmZ1bmN0aW9uIHNhZmVfbm90X2VxdWFsKGEsIGIpIHtcbiAgICByZXR1cm4gYSAhPSBhID8gYiA9PSBiIDogYSAhPT0gYiB8fCAoKGEgJiYgdHlwZW9mIGEgPT09ICdvYmplY3QnKSB8fCB0eXBlb2YgYSA9PT0gJ2Z1bmN0aW9uJyk7XG59XG5sZXQgc3JjX3VybF9lcXVhbF9hbmNob3I7XG5mdW5jdGlvbiBzcmNfdXJsX2VxdWFsKGVsZW1lbnRfc3JjLCB1cmwpIHtcbiAgICBpZiAoIXNyY191cmxfZXF1YWxfYW5jaG9yKSB7XG4gICAgICAgIHNyY191cmxfZXF1YWxfYW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgIH1cbiAgICBzcmNfdXJsX2VxdWFsX2FuY2hvci5ocmVmID0gdXJsO1xuICAgIHJldHVybiBlbGVtZW50X3NyYyA9PT0gc3JjX3VybF9lcXVhbF9hbmNob3IuaHJlZjtcbn1cbmZ1bmN0aW9uIG5vdF9lcXVhbChhLCBiKSB7XG4gICAgcmV0dXJuIGEgIT0gYSA/IGIgPT0gYiA6IGEgIT09IGI7XG59XG5mdW5jdGlvbiBpc19lbXB0eShvYmopIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5sZW5ndGggPT09IDA7XG59XG5mdW5jdGlvbiB2YWxpZGF0ZV9zdG9yZShzdG9yZSwgbmFtZSkge1xuICAgIGlmIChzdG9yZSAhPSBudWxsICYmIHR5cGVvZiBzdG9yZS5zdWJzY3JpYmUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAnJHtuYW1lfScgaXMgbm90IGEgc3RvcmUgd2l0aCBhICdzdWJzY3JpYmUnIG1ldGhvZGApO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHN1YnNjcmliZShzdG9yZSwgLi4uY2FsbGJhY2tzKSB7XG4gICAgaWYgKHN0b3JlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG5vb3A7XG4gICAgfVxuICAgIGNvbnN0IHVuc3ViID0gc3RvcmUuc3Vic2NyaWJlKC4uLmNhbGxiYWNrcyk7XG4gICAgcmV0dXJuIHVuc3ViLnVuc3Vic2NyaWJlID8gKCkgPT4gdW5zdWIudW5zdWJzY3JpYmUoKSA6IHVuc3ViO1xufVxuZnVuY3Rpb24gZ2V0X3N0b3JlX3ZhbHVlKHN0b3JlKSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIHN1YnNjcmliZShzdG9yZSwgXyA9PiB2YWx1ZSA9IF8pKCk7XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuZnVuY3Rpb24gY29tcG9uZW50X3N1YnNjcmliZShjb21wb25lbnQsIHN0b3JlLCBjYWxsYmFjaykge1xuICAgIGNvbXBvbmVudC4kJC5vbl9kZXN0cm95LnB1c2goc3Vic2NyaWJlKHN0b3JlLCBjYWxsYmFjaykpO1xufVxuZnVuY3Rpb24gY3JlYXRlX3Nsb3QoZGVmaW5pdGlvbiwgY3R4LCAkJHNjb3BlLCBmbikge1xuICAgIGlmIChkZWZpbml0aW9uKSB7XG4gICAgICAgIGNvbnN0IHNsb3RfY3R4ID0gZ2V0X3Nsb3RfY29udGV4dChkZWZpbml0aW9uLCBjdHgsICQkc2NvcGUsIGZuKTtcbiAgICAgICAgcmV0dXJuIGRlZmluaXRpb25bMF0oc2xvdF9jdHgpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldF9zbG90X2NvbnRleHQoZGVmaW5pdGlvbiwgY3R4LCAkJHNjb3BlLCBmbikge1xuICAgIHJldHVybiBkZWZpbml0aW9uWzFdICYmIGZuXG4gICAgICAgID8gYXNzaWduKCQkc2NvcGUuY3R4LnNsaWNlKCksIGRlZmluaXRpb25bMV0oZm4oY3R4KSkpXG4gICAgICAgIDogJCRzY29wZS5jdHg7XG59XG5mdW5jdGlvbiBnZXRfc2xvdF9jaGFuZ2VzKGRlZmluaXRpb24sICQkc2NvcGUsIGRpcnR5LCBmbikge1xuICAgIGlmIChkZWZpbml0aW9uWzJdICYmIGZuKSB7XG4gICAgICAgIGNvbnN0IGxldHMgPSBkZWZpbml0aW9uWzJdKGZuKGRpcnR5KSk