@iebh/tera-fy 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +9 -4
  2. package/api.md +445 -431
  3. package/dist/terafy.js +2 -2
  4. package/dist/terafy.js.map +4 -4
  5. package/docs/assets/anchor.js +350 -0
  6. package/docs/assets/bass-addons.css +12 -0
  7. package/docs/assets/bass.css +544 -0
  8. package/docs/assets/fonts/EOT/SourceCodePro-Bold.eot +0 -0
  9. package/docs/assets/fonts/EOT/SourceCodePro-Regular.eot +0 -0
  10. package/docs/assets/fonts/LICENSE.txt +93 -0
  11. package/docs/assets/fonts/OTF/SourceCodePro-Bold.otf +0 -0
  12. package/docs/assets/fonts/OTF/SourceCodePro-Regular.otf +0 -0
  13. package/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf +0 -0
  14. package/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf +0 -0
  15. package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff +0 -0
  16. package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff +0 -0
  17. package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff +0 -0
  18. package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff +0 -0
  19. package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 +0 -0
  20. package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 +0 -0
  21. package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 +0 -0
  22. package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 +0 -0
  23. package/docs/assets/fonts/source-code-pro.css +23 -0
  24. package/docs/assets/github.css +123 -0
  25. package/docs/assets/site.js +168 -0
  26. package/docs/assets/split.css +15 -0
  27. package/docs/assets/split.js +782 -0
  28. package/docs/assets/style.css +147 -0
  29. package/docs/index.html +3636 -0
  30. package/{index.html → docs/playground.html} +48 -12
  31. package/documentation.yml +12 -0
  32. package/lib/terafy.client.js +230 -6
  33. package/lib/terafy.server.js +192 -10
  34. package/package.json +7 -6
  35. package/plugins/vue2.js +173 -0
  36. package/plugins/{vue.js → vue3.js} +20 -11
package/api.md CHANGED
@@ -1,586 +1,600 @@
1
- ## Classes
2
-
3
- <dl>
4
- <dt><a href="#TeraFy">TeraFy</a></dt>
5
- <dd></dd>
6
- <dt><a href="#TeraFyServer">TeraFyServer</a></dt>
7
- <dd></dd>
8
- <dt><a href="#User">User</a></dt>
9
- <dd></dd>
10
- <dt><a href="#Project">Project</a></dt>
11
- <dd></dd>
12
- <dt><a href="#TeraFyPlugin">TeraFyPlugin</a></dt>
13
- <dd></dd>
14
- <dt><a href="#TeraFyPluginVue">TeraFyPluginVue</a></dt>
15
- <dd></dd>
16
- </dl>
17
-
18
- ## Functions
19
-
20
- <dl>
21
- <dt><a href="#send">send(message)</a> ⇒ <code>Promise.&lt;*&gt;</code></dt>
22
- <dd><p>Send a message + wait for a response object</p>
23
- </dd>
24
- <dt><a href="#sendRaw">sendRaw(message)</a></dt>
25
- <dd><p>Send raw message content to the server
26
- This function does not return or wait for a reply - use <code>send()</code> for that</p>
27
- </dd>
28
- <dt><a href="#rpc">rpc(method)</a> ⇒ <code>Promise.&lt;*&gt;</code></dt>
29
- <dd><p>Call an RPC function in the server instance</p>
30
- </dd>
31
- <dt><a href="#acceptMessage">acceptMessage(Raw)</a></dt>
32
- <dd><p>Accept an incoming message</p>
33
- </dd>
34
- <dt><a href="#toggleDevMode">toggleDevMode([devModeEnabled])</a> ⇒ <code><a href="#TeraFy">TeraFy</a></code></dt>
35
- <dd><p>Set or toggle devMode</p>
36
- </dd>
37
- <dt><a href="#init">init()</a></dt>
38
- <dd><p>Initalize the TERA client singleton</p>
39
- </dd>
40
- <dt><a href="#injectMain">injectMain()</a></dt>
41
- <dd><p>Find an existing active TERA server OR initalize one</p>
42
- </dd>
43
- <dt><a href="#injectStylesheet">injectStylesheet()</a></dt>
44
- <dd><p>Inject a local stylesheet to handle TERA server functionality</p>
45
- </dd>
46
- <dt><a href="#injectMethods">injectMethods()</a></dt>
47
- <dd><p>Inject all server methods defined in <code>methods</code> as local functions wrapped in the <code>rpc</code> function</p>
48
- </dd>
49
- <dt><a href="#debug">debug()</a></dt>
50
- <dd><p>Debugging output function
51
- This function will only act if <code>settings.devMode</code> is truthy</p>
52
- </dd>
53
- <dt><a href="#set">set(key, value)</a> ⇒ <code><a href="#TeraFy">TeraFy</a></code></dt>
54
- <dd><p>Set or merge settings
55
- This function also routes &#39;special&#39; keys like <code>devMode</code> to their internal handlers</p>
56
- </dd>
57
- <dt><a href="#use">use(The, [options])</a> ⇒ <code><a href="#TeraFy">TeraFy</a></code></dt>
58
- <dd><p>Include a TeraFy client plugin</p>
59
- </dd>
60
- <dt><a href="#toggleFocus">toggleFocus([isFocused])</a> ⇒ <code><a href="#TeraFy">TeraFy</a></code></dt>
61
- <dd><p>Fit the nested TERA server to a full-screen
62
- This is usually because the server component wants to perform some user activity like calling $prompt</p>
63
- </dd>
64
- <dt><a href="#createContext">createContext(e)</a> ⇒ <code>Object</code></dt>
65
- <dd><p>Create a context based on a shallow copy of this instance + additional functionality for the incoming MessageEvent
66
- This is used by acceptMessage to provide a means to reply / send messages to the originator</p>
67
- </dd>
68
- <dt><a href="#senderRpc">senderRpc(method)</a> ⇒ <code>Promise.&lt;*&gt;</code></dt>
69
- <dd><p>Request an RPC call from the original sender of a mesasge
70
- This function only works if the context was sub-classed via <code>createContext()</code></p>
71
- </dd>
72
- <dt><a href="#handshake">handshake()</a> ⇒ <code>Promise.&lt;Object&gt;</code></dt>
73
- <dd><p>Return basic server information as a form of validation</p>
74
- </dd>
75
- <dt><a href="#send">send(message)</a> ⇒ <code>Promise.&lt;*&gt;</code></dt>
76
- <dd><p>Send a message + wait for a response object</p>
77
- </dd>
78
- <dt><a href="#sendRaw">sendRaw(message)</a></dt>
79
- <dd><p>Send raw message content to the client</p>
80
- </dd>
81
- <dt><a href="#acceptMessage">acceptMessage(Raw)</a></dt>
82
- <dd><p>Accept a message from the parent event listener</p>
83
- </dd>
84
- <dt><a href="#requestFocus">requestFocus(cb)</a> ⇒ <code>Promise.&lt;*&gt;</code></dt>
85
- <dd><p>Wrapper function which runs a callback after the frontend UI has obtained focus
86
- This is to fix the issue where the front-end needs to switch between a regular webpage and a focused TERA iFrame wrapper
87
- Any use of $prompt or other UI calls should be wrapped here</p>
88
- </dd>
89
- <dt><a href="#getUser">getUser()</a> ⇒ <code><a href="#User">Promise.&lt;User&gt;</a></code></dt>
90
- <dd><p>Fetch the current session user</p>
91
- </dd>
92
- <dt><a href="#getProject">getProject()</a> ⇒ <code>Promise.&lt;(Project|null)&gt;</code></dt>
93
- <dd><p>Get the currently active project, if any</p>
94
- </dd>
95
- <dt><a href="#getProjects">getProjects()</a> ⇒ <code>Promise.&lt;Array.&lt;Project&gt;&gt;</code></dt>
96
- <dd><p>Get a list of projects the current session user has access to</p>
97
- </dd>
98
- <dt><a href="#setActiveProject">setActiveProject(project)</a></dt>
99
- <dd><p>Set the currently active project within TERA</p>
100
- </dd>
101
- <dt><a href="#requireProject">requireProject([options])</a> ⇒ <code><a href="#Project">Promise.&lt;Project&gt;</a></code></dt>
102
- <dd><p>Ask the user to select a project from those available - if one isn&#39;t already active
103
- Note that this function will percist in asking the uesr even if they try to cancel</p>
104
- </dd>
105
- <dt><a href="#selectProject">selectProject([options])</a> ⇒ <code><a href="#Project">Promise.&lt;Project&gt;</a></code></dt>
106
- <dd><p>Prompt the user to select a project from those available</p>
107
- </dd>
108
- <dt><a href="#getProjectState">getProjectState([options], Paths)</a> ⇒ <code>Promise.&lt;Object&gt;</code></dt>
109
- <dd><p>Return the current, full snapshot state of the active project</p>
110
- </dd>
111
- <dt><a href="#applyProjectStatePatch">applyProjectStatePatch()</a></dt>
112
- <dd><p>Apply a computed <code>just-diff</code> patch to the current project state</p>
113
- </dd>
114
- <dt><a href="#getProjectLibrary">getProjectLibrary([options])</a> ⇒ <code>Promise.&lt;Array.&lt;RefLibRef&gt;&gt;</code></dt>
115
- <dd><p>Fetch the active projects citation library</p>
116
- </dd>
117
- <dt><a href="#setProjectLibrary">setProjectLibrary(Collection, [options])</a> ⇒ <code>Promise</code></dt>
118
- <dd><p>Save back a projects citation library</p>
119
- </dd>
120
- <dt><a href="#init">init()</a></dt>
121
- <dd><p>Initialize the browser listener</p>
122
- </dd>
123
- <dt><a href="#debug">debug()</a></dt>
124
- <dd><p>Debugging output function
125
- This function will only act if <code>settings.devMode</code> is truthy</p>
126
- </dd>
127
- <dt><a href="#init">init()</a></dt>
128
- <dd><p>Optional function to be included when the main TeraFyClient is initalized</p>
129
- </dd>
130
- <dt><a href="#bindProjectState">bindProjectState([options], Paths)</a> ⇒ <code>Promies.&lt;Reactive.&lt;Object&gt;&gt;</code></dt>
131
- <dd><p>Return a Vue reactive object that can be read/written which whose changes will transparently be written back to the TERA server instance</p>
132
- </dd>
133
- </dl>
134
-
135
- <a name="TeraFy"></a>
1
+ <!-- Generated by documentation.js. Update this documentation by updating the source code. -->
2
+
3
+ ### Table of Contents
4
+
5
+ * [TeraFy][1]
6
+ * [settings][2]
7
+ * [Properties][3]
8
+ * [dom][4]
9
+ * [Properties][5]
10
+ * [methods][6]
11
+ * [plugins][7]
12
+ * [send][8]
13
+ * [Parameters][9]
14
+ * [sendRaw][10]
15
+ * [Parameters][11]
16
+ * [rpc][12]
17
+ * [Parameters][13]
18
+ * [acceptMessage][14]
19
+ * [Parameters][15]
20
+ * [acceptPostboxes][16]
21
+ * [createProjectStatePatch][17]
22
+ * [Parameters][18]
23
+ * [applyProjectStatePatchLocal][19]
24
+ * [Parameters][20]
25
+ * [init][21]
26
+ * [Parameters][22]
27
+ * [detectMode][23]
28
+ * [injectComms][24]
29
+ * [injectStylesheet][25]
30
+ * [injectMethods][26]
31
+ * [debug][27]
32
+ * [Parameters][28]
33
+ * [set][29]
34
+ * [Parameters][30]
35
+ * [use][31]
36
+ * [Parameters][32]
37
+ * [mixin][33]
38
+ * [Parameters][34]
39
+ * [toggleDevMode][35]
40
+ * [Parameters][36]
41
+ * [toggleFocus][37]
42
+ * [Parameters][38]
43
+ * [handshake][39]
44
+ * [Properties][40]
45
+ * [User][41]
46
+ * [Properties][42]
47
+ * [getUser][43]
48
+ * [Project][44]
49
+ * [getProject][45]
50
+ * [getProjects][46]
51
+ * [setActiveProject][47]
52
+ * [Parameters][48]
53
+ * [requireProject][49]
54
+ * [Parameters][50]
55
+ * [selectProject][51]
56
+ * [Parameters][52]
57
+ * [getProjectState][53]
58
+ * [Parameters][54]
59
+ * [applyProjectStatePatch][55]
60
+ * [Parameters][56]
61
+ * [subscribeProjectState][57]
62
+ * [ProjectFile][58]
63
+ * [Properties][59]
64
+ * [getProjectFiles][60]
65
+ * [Parameters][61]
66
+ * [getProjectLibrary][62]
67
+ * [Parameters][63]
68
+ * [setProjectLibrary][64]
69
+ * [Parameters][65]
136
70
 
137
71
  ## TeraFy
138
- **Kind**: global class
139
- <a name="new_TeraFy_new"></a>
140
72
 
141
- ### new TeraFy()
142
73
  Main Tera-Fy Client (class singleton) to be used in a frontend browser
143
74
 
144
- <a name="TeraFyServer"></a>
75
+ ### settings
145
76
 
146
- ## TeraFyServer
147
- **Kind**: global class
148
- <a name="new_TeraFyServer_new"></a>
77
+ Various settings to configure behaviour
149
78
 
150
- ### new TeraFyServer()
151
- Server-side functions available to the Tera-Fy client library
79
+ Type: [Object][66]
152
80
 
153
- <a name="User"></a>
81
+ #### Properties
154
82
 
155
- ## User
156
- **Kind**: global class
157
- **Properties**
83
+ * `devMode` **[Boolean][67]** Operate in devMode - i.e. force outer refresh when encountering an existing TeraFy instance
84
+ * `How` **(`"detect"` | `"parent"` | `"child"`)** to communicate with TERA. 'parent' assumes that the parent of the current document is TERA, 'child' spawns an iFrame and uses TERA there, 'detect' tries parent and fallsback to 'child'
85
+ * `modeTimeout` **[Number][68]** How long entities have in 'detect' mode to identify themselves
86
+ * `siteUrl` **[String][69]** The TERA URL to connect to
87
+ * `restrictOrigin` **[String][69]** URL to restrict communications to
158
88
 
159
- | Name | Type | Description |
160
- | --- | --- | --- |
161
- | id | <code>String</code> | Unique identifier of the user |
162
- | email | <code>String</code> | The email address of the current user |
163
- | name | <code>String</code> | The provided full name of the user |
164
- | isSubscribed | <code>Boolean</code> | Whether the active user has a TERA subscription |
89
+ ### dom
165
90
 
166
- <a name="new_User_new"></a>
91
+ DOMElements for this TeraFy instance
167
92
 
168
- ### new User()
169
- User / active session within TERA
93
+ Type: [Object][66]
170
94
 
171
- <a name="Project"></a>
95
+ #### Properties
172
96
 
173
- ## Project
174
- **Kind**: global class
175
- **Properties**
97
+ * `el` **DOMElement** The main tera-fy div wrapper
98
+ * `iframe` **DOMElement** The internal iFrame element
99
+ * `stylesheet` **DOMElement** The corresponding stylesheet
176
100
 
177
- | Name | Type | Description |
178
- | --- | --- | --- |
179
- | id | <code>String</code> | The Unique ID of the project |
180
- | name | <code>String</code> | The name of the project |
181
- | created | <code>String</code> | The creation date of the project as an ISO string |
182
- | isOwner | <code>Boolean</code> | Whether the current session user is the owner of the project |
101
+ ### methods
183
102
 
184
- <a name="new_Project_new"></a>
185
-
186
- ### new Project()
187
- Project entry within TERA
103
+ List of function stubs mapped here from the server
104
+ This array is forms the reference of `TeraFy.METHOD()` objects to provide locally which will be mapped via `TeraFy.rpc(METHOD, ...args)`
188
105
 
189
- <a name="TeraFyPlugin"></a>
106
+ Type: [Array][70]<[String][69]>
190
107
 
191
- ## TeraFyPlugin
192
- **Kind**: global class
193
- <a name="new_TeraFyPlugin_new"></a>
108
+ ### plugins
194
109
 
195
- ### new TeraFyPlugin()
196
- Base TeraFy plugin interface
197
- This is included as a documentation exanple only
110
+ Loaded plugins via Use()
198
111
 
199
- <a name="TeraFyPluginVue"></a>
112
+ Type: [Array][70]\<TeraFyPlugin>
200
113
 
201
- ## TeraFyPluginVue
202
- **Kind**: global class
203
- <a name="new_TeraFyPluginVue_new"></a>
114
+ ### send
204
115
 
205
- ### new TeraFyPluginVue()
206
- Vue observables plugin
207
- Provides the `bindProjectState()` function for Vue based projects
208
-
209
- This function is expected to be included via the `terafy.use(MODULE, OPTIONS)` syntax rather than directly
210
-
211
- <a name="send"></a>
212
-
213
- ## send(message) ⇒ <code>Promise.&lt;\*&gt;</code>
214
116
  Send a message + wait for a response object
215
117
 
216
- **Kind**: global function
217
- **Returns**: <code>Promise.&lt;\*&gt;</code> - A promise which resolves when the operation has completed with the remote reply
118
+ #### Parameters
119
+
120
+ * `message` **[Object][66]** Message object to send
218
121
 
219
- | Param | Type | Description |
220
- | --- | --- | --- |
221
- | message | <code>Object</code> | Message object to send |
122
+ Returns **[Promise][71]\<any>** A promise which resolves when the operation has completed with the remote reply
222
123
 
223
- <a name="sendRaw"></a>
124
+ ### sendRaw
224
125
 
225
- ## sendRaw(message)
226
126
  Send raw message content to the server
227
127
  This function does not return or wait for a reply - use `send()` for that
228
128
 
229
- **Kind**: global function
129
+ #### Parameters
230
130
 
231
- | Param | Type | Description |
232
- | --- | --- | --- |
233
- | message | <code>Object</code> | Message object to send |
131
+ * `message` **[Object][66]** Message object to send
234
132
 
235
- <a name="rpc"></a>
133
+ ### rpc
236
134
 
237
- ## rpc(method) ⇒ <code>Promise.&lt;\*&gt;</code>
238
135
  Call an RPC function in the server instance
239
136
 
240
- **Kind**: global function
241
- **Returns**: <code>Promise.&lt;\*&gt;</code> - The resolved output of the server function
137
+ #### Parameters
242
138
 
243
- | Param | Type | Description |
244
- | --- | --- | --- |
245
- | method | <code>String</code> | The method name to call |
246
- | [...] | <code>\*</code> | Optional arguments to pass to the function |
139
+ * `method` **[String][69]** The method name to call
140
+ * `args` **...any**&#x20;
247
141
 
248
- <a name="acceptMessage"></a>
142
+ Returns **[Promise][71]\<any>** The resolved output of the server function
143
+
144
+ ### acceptMessage
249
145
 
250
- ## acceptMessage(Raw)
251
146
  Accept an incoming message
252
147
 
253
- **Kind**: global function
148
+ #### Parameters
254
149
 
255
- | Param | Type | Description |
256
- | --- | --- | --- |
257
- | Raw | <code>MessageEvent</code> | message event to process |
150
+ * `rawMessage` &#x20;
151
+ * `Raw` **[MessageEvent][72]** message event to process
258
152
 
259
- <a name="toggleDevMode"></a>
153
+ ### acceptPostboxes
260
154
 
261
- ## toggleDevMode([devModeEnabled]) [<code>TeraFy</code>](#TeraFy)
262
- Set or toggle devMode
155
+ Listening postboxes, these correspond to outgoing message IDs that expect a response
156
+
157
+ ### createProjectStatePatch
158
+
159
+ Create + transmit a new project state patch base on the current and previous states
160
+ The transmitted patch follows the [JSPatch][73] standard
161
+ This function accepts an entire projectState instance, computes the delta and transmits that to the server for merging
162
+
163
+ #### Parameters
164
+
165
+ * `newState` **[Object][66]** The local projectState to accept
166
+ * `oldState` **[Object][66]** The previous projectState to examine against
167
+
168
+ Returns **[Promise][71]** A promise which will resolve when the operation has completed
169
+
170
+ ### applyProjectStatePatchLocal
171
+
172
+ Client function which accepts a patch from the server and applies it to local project state
173
+ The patch should follow the [JSPatch][73] standard
174
+ This function is expected to be sub-classed by a plugin
263
175
 
264
- **Kind**: global function
265
- **Returns**: [<code>TeraFy</code>](#TeraFy) - This chainable terafy instance
176
+ #### Parameters
266
177
 
267
- | Param | Type | Default | Description |
268
- | --- | --- | --- | --- |
269
- | [devModeEnabled] | <code>String</code> \| <code>Boolean</code> | <code>&#x27;toggle&#x27;</code> | Optional boolean to force dev mode |
178
+ * `patch` **[Array][70]** A JSPatch patch to apply
270
179
 
271
- <a name="init"></a>
180
+ Returns **[Promise][71]** A promise which will resolve when the operation has completed
181
+
182
+ ### init
272
183
 
273
- ## init()
274
184
  Initalize the TERA client singleton
185
+ This function can only be called once and will return the existing init() worker Promise if its called againt
186
+
187
+ #### Parameters
188
+
189
+ * `options` **[Object][66]?** Additional options to merge into `settings` via `set`
190
+
191
+ Returns **[Promise][71]<[TeraFy][1]>** An eventual promise which will resovle with this terafy instance
192
+
193
+ ### detectMode
275
194
 
276
- **Kind**: global function
277
- <a name="injectMain"></a>
195
+ Populate `settings.mode`
196
+ Try to communicate with a parent frame, if none assume we need to fallback to child mode
197
+
198
+ Returns **[Promise][71]<[String][69]>** A promise which will resolve with the detected mode to use
199
+
200
+ ### injectComms
278
201
 
279
- ## injectMain()
280
202
  Find an existing active TERA server OR initalize one
281
203
 
282
- **Kind**: global function
283
- <a name="injectStylesheet"></a>
204
+ Returns **[Promise][71]** A promise which will resolve when the loading has completed and we have found a parent TERA instance or initiallized a child
205
+
206
+ ### injectStylesheet
284
207
 
285
- ## injectStylesheet()
286
208
  Inject a local stylesheet to handle TERA server functionality
287
209
 
288
- **Kind**: global function
289
- <a name="injectMethods"></a>
210
+ ### injectMethods
290
211
 
291
- ## injectMethods()
292
212
  Inject all server methods defined in `methods` as local functions wrapped in the `rpc` function
293
213
 
294
- **Kind**: global function
295
- <a name="debug"></a>
214
+ ### debug
296
215
 
297
- ## debug()
298
216
  Debugging output function
299
217
  This function will only act if `settings.devMode` is truthy
300
218
 
301
- **Kind**: global function
219
+ #### Parameters
302
220
 
303
- | Param | Type | Description |
304
- | --- | --- | --- |
305
- | [msg...] | <code>String</code> | Output to show |
221
+ * `msg` **...any**&#x20;
222
+ * `status` **(`"VERBOSE"` | `"INFO"` | `"LOG"` | `"WARN"` | `"ERROR"`)?** Optional prefixing level to mark the message as. 'WARN' and 'ERROR' will always show reguardless of devMode being enabled
306
223
 
307
- <a name="set"></a>
224
+ ### set
308
225
 
309
- ## set(key, value) ⇒ [<code>TeraFy</code>](#TeraFy)
310
226
  Set or merge settings
311
227
  This function also routes 'special' keys like `devMode` to their internal handlers
312
228
 
313
- **Kind**: global function
314
- **Returns**: [<code>TeraFy</code>](#TeraFy) - This chainable terafy instance
229
+ #### Parameters
315
230
 
316
- | Param | Type | Description |
317
- | --- | --- | --- |
318
- | key | <code>String</code> \| <code>Object</code> | Either a single setting key to set or an object to merge |
319
- | value | <code>\*</code> | The value to set if `key` is a string |
231
+ * `key` **([String][69] | [Object][66])** Either a single setting key to set or an object to merge
232
+ * `value` **any** The value to set if `key` is a string
320
233
 
321
- <a name="use"></a>
234
+ Returns **[TeraFy][1]** This chainable terafy instance
322
235
 
323
- ## use(The, [options]) ⇒ [<code>TeraFy</code>](#TeraFy)
324
- Include a TeraFy client plugin
236
+ ### use
325
237
 
326
- **Kind**: global function
327
- **Returns**: [<code>TeraFy</code>](#TeraFy) - This chainable terafy instance
328
-
329
- | Param | Type | Description |
330
- | --- | --- | --- |
331
- | The | <code>Object</code> | module function to include. Invoked as `(teraClient:TeraFy, options:Object)` |
332
- | [options] | <code>Object</code> | Additional options to mutate behaviour |
333
-
334
- <a name="toggleFocus"></a>
335
-
336
- ## toggleFocus([isFocused]) ⇒ [<code>TeraFy</code>](#TeraFy)
337
- Fit the nested TERA server to a full-screen
338
- This is usually because the server component wants to perform some user activity like calling $prompt
339
-
340
- **Kind**: global function
341
- **Returns**: [<code>TeraFy</code>](#TeraFy) - This chainable terafy instance
342
-
343
- | Param | Type | Default | Description |
344
- | --- | --- | --- | --- |
345
- | [isFocused] | <code>String</code> \| <code>Boolean</code> | <code>&#x27;toggle&#x27;</code> | Whether to fullscreen the embedded component |
238
+ Include a TeraFy client plugin
346
239
 
347
- <a name="createContext"></a>
240
+ #### Parameters
348
241
 
349
- ## createContext(e) ⇒ <code>Object</code>
350
- Create a context based on a shallow copy of this instance + additional functionality for the incoming MessageEvent
351
- This is used by acceptMessage to provide a means to reply / send messages to the originator
242
+ * `mod` &#x20;
243
+ * `options` **[Object][66]?** Additional options to mutate behaviour
244
+ * `The` **[Object][66]** module function to include. Invoked as `(teraClient:TeraFy, options:Object)`
352
245
 
353
- **Kind**: global function
354
- **Returns**: <code>Object</code> - A context, which is this instance extended with additional properties
246
+ Returns **[TeraFy][1]** This chainable terafy instance
355
247
 
356
- | Param | Type | Description |
357
- | --- | --- | --- |
358
- | e | <code>MessageEvent</code> | Original message event to base the new context on |
248
+ ### mixin
359
249
 
360
- <a name="senderRpc"></a>
250
+ Internal function used by use() to merge an external declared singleton against this object
361
251
 
362
- ## senderRpc(method) ⇒ <code>Promise.&lt;\*&gt;</code>
363
- Request an RPC call from the original sender of a mesasge
364
- This function only works if the context was sub-classed via `createContext()`
252
+ #### Parameters
365
253
 
366
- **Kind**: global function
367
- **Returns**: <code>Promise.&lt;\*&gt;</code> - The resolved output of the server function
254
+ * `target` **[Object][66]** Initalied class instance to extend
255
+ * `source` **[Object][66]** Initalized source object to extend from
368
256
 
369
- | Param | Type | Description |
370
- | --- | --- | --- |
371
- | method | <code>String</code> | The method name to call |
372
- | [...] | <code>\*</code> | Optional arguments to pass to the function |
257
+ ### toggleDevMode
373
258
 
374
- <a name="handshake"></a>
259
+ Set or toggle devMode
375
260
 
376
- ## handshake() ⇒ <code>Promise.&lt;Object&gt;</code>
377
- Return basic server information as a form of validation
261
+ #### Parameters
378
262
 
379
- **Kind**: global function
380
- **Returns**: <code>Promise.&lt;Object&gt;</code> - Basic promise result
381
- **Properties**
263
+ * `devModeEnabled` **([String][69] | [Boolean][67])** Optional boolean to force dev mode (optional, default `'toggle'`)
382
264
 
383
- | Name | Type | Description |
384
- | --- | --- | --- |
385
- | date | <code>Date</code> | Server date |
265
+ Returns **[TeraFy][1]** This chainable terafy instance
386
266
 
387
- <a name="send"></a>
267
+ ### toggleFocus
388
268
 
389
- ## send(message) <code>Promise.&lt;\*&gt;</code>
390
- Send a message + wait for a response object
269
+ Fit the nested TERA server to a full-screen
270
+ This is usually because the server component wants to perform some user activity like calling $prompt
391
271
 
392
- **Kind**: global function
393
- **Returns**: <code>Promise.&lt;\*&gt;</code> - A promise which resolves when the operation has completed with the remote reply
272
+ #### Parameters
394
273
 
395
- | Param | Type | Description |
396
- | --- | --- | --- |
397
- | message | <code>Object</code> | Message object to send |
274
+ * `isFocused` **([String][69] | [Boolean][67])** Whether to fullscreen the embedded component (optional, default `'toggle'`)
398
275
 
399
- <a name="sendRaw"></a>
276
+ ## handshake
400
277
 
401
- ## sendRaw(message)
402
- Send raw message content to the client
278
+ Return basic server information as a form of validation
403
279
 
404
- **Kind**: global function
280
+ ### Properties
405
281
 
406
- | Param | Type | Description |
407
- | --- | --- | --- |
408
- | message | <code>Object</code> | Message object to send |
282
+ * `date` **[Date][74]** Server date
409
283
 
410
- <a name="acceptMessage"></a>
284
+ Returns **[Promise][71]<[Object][66]>** Basic promise result
411
285
 
412
- ## acceptMessage(Raw)
413
- Accept a message from the parent event listener
286
+ ## User
414
287
 
415
- **Kind**: global function
288
+ User / active session within TERA
416
289
 
417
- | Param | Type | Description |
418
- | --- | --- | --- |
419
- | Raw | <code>MessageEvent</code> | message event to process |
290
+ ### Properties
420
291
 
421
- <a name="requestFocus"></a>
292
+ * `id` **[String][69]** Unique identifier of the user
293
+ * `email` **[String][69]** The email address of the current user
294
+ * `name` **[String][69]** The provided full name of the user
295
+ * `isSubscribed` **[Boolean][67]** Whether the active user has a TERA subscription
422
296
 
423
- ## requestFocus(cb) ⇒ <code>Promise.&lt;\*&gt;</code>
424
- Wrapper function which runs a callback after the frontend UI has obtained focus
425
- This is to fix the issue where the front-end needs to switch between a regular webpage and a focused TERA iFrame wrapper
426
- Any use of $prompt or other UI calls should be wrapped here
297
+ ## getUser
427
298
 
428
- **Kind**: global function
429
- **Returns**: <code>Promise.&lt;\*&gt;</code> - A promise which resolves with the resulting inner callback payload
299
+ Fetch the current session user
430
300
 
431
- | Param | Type | Description |
432
- | --- | --- | --- |
433
- | cb | <code>function</code> | Async function to run in focused mode |
301
+ Returns **[Promise][71]<[User][41]>** The current logged in user or null if none
434
302
 
435
- <a name="getUser"></a>
303
+ ## Project
436
304
 
437
- ## getUser() [<code>Promise.&lt;User&gt;</code>](#User)
438
- Fetch the current session user
305
+ Project entry within TERA
439
306
 
440
- **Kind**: global function
441
- **Returns**: [<code>Promise.&lt;User&gt;</code>](#User) - The current logged in user or null if none
442
- <a name="getProject"></a>
307
+ ## getProject
443
308
 
444
- ## getProject() ⇒ <code>Promise.&lt;(Project\|null)&gt;</code>
445
309
  Get the currently active project, if any
446
310
 
447
- **Kind**: global function
448
- **Returns**: <code>Promise.&lt;(Project\|null)&gt;</code> - The currently active project, if any
449
- <a name="getProjects"></a>
311
+ Returns **[Promise][71]<([Project][44] | null)>** The currently active project, if any
312
+
313
+ ## getProjects
450
314
 
451
- ## getProjects() ⇒ <code>Promise.&lt;Array.&lt;Project&gt;&gt;</code>
452
315
  Get a list of projects the current session user has access to
453
316
 
454
- **Kind**: global function
455
- **Returns**: <code>Promise.&lt;Array.&lt;Project&gt;&gt;</code> - Collection of projects the user has access to
456
- <a name="setActiveProject"></a>
317
+ Returns **[Promise][71]<[Array][70]<[Project][44]>>** Collection of projects the user has access to
318
+
319
+ ## setActiveProject
457
320
 
458
- ## setActiveProject(project)
459
321
  Set the currently active project within TERA
460
322
 
461
- **Kind**: global function
323
+ ### Parameters
462
324
 
463
- | Param | Type | Description |
464
- | --- | --- | --- |
465
- | project | <code>Object</code> \| <code>String</code> | The project to set as active - either the full Project object or its ID |
325
+ * `project` **([Object][66] | [String][69])** The project to set as active - either the full Project object or its ID
466
326
 
467
- <a name="requireProject"></a>
327
+ ## requireProject
468
328
 
469
- ## requireProject([options]) ⇒ [<code>Promise.&lt;Project&gt;</code>](#Project)
470
329
  Ask the user to select a project from those available - if one isn't already active
471
330
  Note that this function will percist in asking the uesr even if they try to cancel
472
331
 
473
- **Kind**: global function
474
- **Returns**: [<code>Promise.&lt;Project&gt;</code>](#Project) - The active project
332
+ ### Parameters
475
333
 
476
- | Param | Type | Default | Description |
477
- | --- | --- | --- | --- |
478
- | [options] | <code>Object</code> | | Additional options to mutate behaviour |
479
- | [options.autoSetActiveProject] | <code>Boolean</code> | <code>true</code> | After selecting a project set that project as active in TERA |
480
- | [options.title] | <code>String</code> | <code>&quot;Select a project to work with&quot;</code> | The title of the dialog to display |
481
- | [options.noSelectTitle] | <code>String</code> | <code>&#x27;Select project&#x27;</code> | Dialog title when warning the user they need to select something |
482
- | [options.noSelectBody] | <code>String</code> | <code>&#x27;A project needs to be selected to continue&#x27;</code> | Dialog body when warning the user they need to select something |
334
+ * `options` **[Object][66]?** Additional options to mutate behaviour
483
335
 
484
- <a name="selectProject"></a>
336
+ * `options.autoSetActiveProject` **[Boolean][67]** After selecting a project set that project as active in TERA (optional, default `true`)
337
+ * `options.title` **[String][69]** The title of the dialog to display (optional, default `"Select a project to work with"`)
338
+ * `options.noSelectTitle` **[String][69]** Dialog title when warning the user they need to select something (optional, default `'Select project'`)
339
+ * `options.noSelectBody` **[String][69]** Dialog body when warning the user they need to select something (optional, default `'A project needs to be selected to continue'`)
340
+
341
+ Returns **[Promise][71]<[Project][44]>** The active project
342
+
343
+ ## selectProject
485
344
 
486
- ## selectProject([options]) ⇒ [<code>Promise.&lt;Project&gt;</code>](#Project)
487
345
  Prompt the user to select a project from those available
488
346
 
489
- **Kind**: global function
490
- **Returns**: [<code>Promise.&lt;Project&gt;</code>](#Project) - The active project
347
+ ### Parameters
348
+
349
+ * `options` **[Object][66]?** Additional options to mutate behaviour
350
+
351
+ * `options.title` **[String][69]** The title of the dialog to display (optional, default `"Select a project to work with"`)
352
+ * `options.allowCancel` **[Boolean][67]** Advertise cancelling the operation, the dialog can still be cancelled by closing it (optional, default `true`)
353
+ * `options.setActive` **[Boolean][67]** Also set the project as active when selected (optional, default `false`)
491
354
 
492
- | Param | Type | Default | Description |
493
- | --- | --- | --- | --- |
494
- | [options] | <code>Object</code> | | Additional options to mutate behaviour |
495
- | [options.title] | <code>String</code> | <code>&quot;Select a project to work with&quot;</code> | The title of the dialog to display |
496
- | [options.allowCancel] | <code>Boolean</code> | <code>true</code> | Advertise cancelling the operation, the dialog can still be cancelled by closing it |
355
+ Returns **[Promise][71]<[Project][44]>** The active project
497
356
 
498
- <a name="getProjectState"></a>
357
+ ## getProjectState
499
358
 
500
- ## getProjectState([options], Paths) ⇒ <code>Promise.&lt;Object&gt;</code>
501
359
  Return the current, full snapshot state of the active project
502
360
 
503
- **Kind**: global function
504
- **Returns**: <code>Promise.&lt;Object&gt;</code> - The current project state snapshot
361
+ ### Parameters
505
362
 
506
- | Param | Type | Default | Description |
507
- | --- | --- | --- | --- |
508
- | [options] | <code>Object</code> | | Additional options to mutate behaviour |
509
- | [options.autoRequire] | <code>Boolean</code> | <code>true</code> | Run `requireProject()` automatically before continuing |
510
- | Paths | <code>Array.&lt;String&gt;</code> | | to subscribe to e.g. ['/users/'], |
363
+ * `options` **[Object][66]?** Additional options to mutate behaviour
511
364
 
512
- <a name="applyProjectStatePatch"></a>
365
+ * `options.autoRequire` **[Boolean][67]** Run `requireProject()` automatically before continuing (optional, default `true`)
366
+ * `Paths` **[Array][70]<[String][69]>** to subscribe to e.g. \['/users/'],
367
+
368
+ Returns **[Promise][71]<[Object][66]>** The current project state snapshot
369
+
370
+ ## applyProjectStatePatch
513
371
 
514
- ## applyProjectStatePatch()
515
372
  Apply a computed `just-diff` patch to the current project state
516
373
 
517
- **Kind**: global function
518
- <a name="getProjectLibrary"></a>
374
+ ### Parameters
375
+
376
+ * `Patch` **[Object][66]** to apply
377
+
378
+ Returns **[Promise][71]** A promise which resolves when the operation has completed
379
+
380
+ ## subscribeProjectState
381
+
382
+ Subscribe to project state changes
383
+ This will dispatch an RPC call to the source object `applyProjectStatePatchLocal()` function with the patch
384
+ If the above call fails the subscriber is assumed as dead and unsubscribed from the polling list
385
+
386
+ Returns **[Promise][71]<[Function][75]>** A promise which resolves when a subscription has been created, call the resulting function to unsubscribe
387
+
388
+ ## ProjectFile
389
+
390
+ Data structure for a project file
391
+
392
+ ### Properties
393
+
394
+ * `id` **[String][69]** A UUID string representing the unique ID of the file
395
+ * `name` **[String][69]** Relative name path (can contain prefix directories) for the human readable file name
396
+ * `parsedName` **[Object][66]** An object representing meta file parts of a file name
397
+
398
+ * `parsedName.basename` **[String][69]** The filename + extention (i.e. everything without directory name)
399
+ * `parsedName.filename` **[String][69]** The file portion of the name (basename without the extension)
400
+ * `parsedName.ext` **[String][69]** The extension portion of the name (always lower case)
401
+ * `parsedName.dirName` **[String][69]** The directory path portion of the name
402
+ * `created` **[Date][74]** A date representing when the file was created
403
+ * `modified` **[Date][74]** A date representing when the file was created
404
+ * `accessed` **[Date][74]** A date representing when the file was last accessed
405
+ * `size` **[Number][68]** Size, in bytes, of the file
406
+ * `mime` **[String][69]** The associated mime type for the file
407
+
408
+ ## getProjectFiles
409
+
410
+ Fetch the files associated with a given project
411
+
412
+ ### Parameters
413
+
414
+ * `options` **[Object][66]** Options which mutate behaviour
415
+
416
+ * `options.autoRequire` **[Boolean][67]** Run `requireProject()` automatically before continuing (optional, default `true`)
417
+ * `options.meta` **[Boolean][67]** Pull meta information for each file entity (optional, default `true`)
418
+
419
+ Returns **[Promise][71]<[ProjectFile][58]>** A collection of project files for the given project
420
+
421
+ ## getProjectLibrary
519
422
 
520
- ## getProjectLibrary([options]) ⇒ <code>Promise.&lt;Array.&lt;RefLibRef&gt;&gt;</code>
521
423
  Fetch the active projects citation library
522
424
 
523
- **Kind**: global function
524
- **Returns**: <code>Promise.&lt;Array.&lt;RefLibRef&gt;&gt;</code> - Collection of references for the selected library
425
+ ### Parameters
426
+
427
+ * `path` **[String][69]?** Optional file path to use, if omitted the contents of `options` are used to guess at a suitable file
428
+ * `options` **[Object][66]?** Additional options to mutate behaviour
525
429
 
526
- | Param | Type | Default | Description |
527
- | --- | --- | --- | --- |
528
- | [options] | <code>Object</code> | | Additional options to mutate behaviour |
529
- | [options.autoRequire] | <code>Boolean</code> | <code>true</code> | Run `requireProject()` automatically before continuing |
530
- | [options.multiple] | <code>Boolean</code> | <code>false</code> | Allow selection of multiple libraries |
531
- | [options.hint] | <code>String</code> \| <code>Array.&lt;String&gt;</code> | | Hints to identify the library to select in array order of preference. Generally corresponds to the previous stage - e.g. 'deduped', 'review1', 'review2', 'dedisputed' |
430
+ * `options.autoRequire` **[Boolean][67]** Run `requireProject()` automatically before continuing (optional, default `true`)
431
+ * `options.multiple` **[Boolean][67]** Allow selection of multiple libraries (optional, default `false`)
432
+ * `options.filter` **[Function][75]?** Optional async file filter, called each time as `(File:ProjectFile)`
433
+ * `options.find` **[Function][75]?** Optional async final stage file filter to reduce all candidates down to one subject file
434
+ * `options.hint` **([String][69] | [Array][70]<[String][69]>)?** Hints to identify the library to select in array order of preference. Generally corresponds to the previous stage - e.g. 'deduped', 'review1', 'review2', 'dedisputed'
532
435
 
533
- <a name="setProjectLibrary"></a>
436
+ Returns **[Promise][71]<[Array][70]<[ProjectFile][58]>>** Collection of references for the selected library matching the given hint + filter, this could be a zero length array
437
+
438
+ ## setProjectLibrary
534
439
 
535
- ## setProjectLibrary(Collection, [options]) ⇒ <code>Promise</code>
536
440
  Save back a projects citation library
537
441
 
538
- **Kind**: global function
539
- **Returns**: <code>Promise</code> - A promise which resolves when the save operation has completed
442
+ ### Parameters
540
443
 
541
- | Param | Type | Default | Description |
542
- | --- | --- | --- | --- |
543
- | Collection | <code>Array.&lt;RefLibRef&gt;</code> | | of references for the selected library |
544
- | [options] | <code>Object</code> | | Additional options to mutate behaviour |
545
- | [options.autoRequire] | <code>Boolean</code> | <code>true</code> | Run `requireProject()` automatically before continuing |
546
- | [options.hint] | <code>String</code> | | Hint to store against the library. Generally corresponds to the current operation being performed - e.g. 'deduped' |
444
+ * `Collection` **[Array][70]\<RefLibRef>** of references for the selected library
445
+ * `options` **[Object][66]?** Additional options to mutate behaviour
547
446
 
548
- <a name="init"></a>
447
+ * `options.autoRequire` **[Boolean][67]** Run `requireProject()` automatically before continuing (optional, default `true`)
448
+ * `options.hint` **[String][69]?** Hint to store against the library. Generally corresponds to the current operation being performed - e.g. 'deduped'
549
449
 
550
- ## init()
551
- Initialize the browser listener
450
+ Returns **[Promise][71]** A promise which resolves when the save operation has completed
552
451
 
553
- **Kind**: global function
554
- <a name="debug"></a>
452
+ [1]: #terafy
555
453
 
556
- ## debug()
557
- Debugging output function
558
- This function will only act if `settings.devMode` is truthy
454
+ [2]: #settings
455
+
456
+ [3]: #properties
457
+
458
+ [4]: #dom
459
+
460
+ [5]: #properties-1
461
+
462
+ [6]: #methods
463
+
464
+ [7]: #plugins
465
+
466
+ [8]: #send
467
+
468
+ [9]: #parameters
469
+
470
+ [10]: #sendraw
471
+
472
+ [11]: #parameters-1
473
+
474
+ [12]: #rpc
475
+
476
+ [13]: #parameters-2
477
+
478
+ [14]: #acceptmessage
479
+
480
+ [15]: #parameters-3
481
+
482
+ [16]: #acceptpostboxes
483
+
484
+ [17]: #createprojectstatepatch
485
+
486
+ [18]: #parameters-4
487
+
488
+ [19]: #applyprojectstatepatchlocal
489
+
490
+ [20]: #parameters-5
491
+
492
+ [21]: #init
493
+
494
+ [22]: #parameters-6
495
+
496
+ [23]: #detectmode
497
+
498
+ [24]: #injectcomms
499
+
500
+ [25]: #injectstylesheet
501
+
502
+ [26]: #injectmethods
503
+
504
+ [27]: #debug
505
+
506
+ [28]: #parameters-7
507
+
508
+ [29]: #set
509
+
510
+ [30]: #parameters-8
511
+
512
+ [31]: #use
513
+
514
+ [32]: #parameters-9
515
+
516
+ [33]: #mixin
517
+
518
+ [34]: #parameters-10
519
+
520
+ [35]: #toggledevmode
521
+
522
+ [36]: #parameters-11
523
+
524
+ [37]: #togglefocus
525
+
526
+ [38]: #parameters-12
527
+
528
+ [39]: #handshake
529
+
530
+ [40]: #properties-2
531
+
532
+ [41]: #user
533
+
534
+ [42]: #properties-3
535
+
536
+ [43]: #getuser
537
+
538
+ [44]: #project
539
+
540
+ [45]: #getproject
541
+
542
+ [46]: #getprojects
543
+
544
+ [47]: #setactiveproject
545
+
546
+ [48]: #parameters-13
547
+
548
+ [49]: #requireproject
549
+
550
+ [50]: #parameters-14
551
+
552
+ [51]: #selectproject
553
+
554
+ [52]: #parameters-15
555
+
556
+ [53]: #getprojectstate
557
+
558
+ [54]: #parameters-16
559
+
560
+ [55]: #applyprojectstatepatch
561
+
562
+ [56]: #parameters-17
563
+
564
+ [57]: #subscribeprojectstate
565
+
566
+ [58]: #projectfile
567
+
568
+ [59]: #properties-4
569
+
570
+ [60]: #getprojectfiles
571
+
572
+ [61]: #parameters-18
573
+
574
+ [62]: #getprojectlibrary
575
+
576
+ [63]: #parameters-19
577
+
578
+ [64]: #setprojectlibrary
579
+
580
+ [65]: #parameters-20
581
+
582
+ [66]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
559
583
 
560
- **Kind**: global function
584
+ [67]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
561
585
 
562
- | Param | Type | Description |
563
- | --- | --- | --- |
564
- | [msg...] | <code>String</code> | Output to show |
586
+ [68]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
565
587
 
566
- <a name="init"></a>
588
+ [69]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
567
589
 
568
- ## init()
569
- Optional function to be included when the main TeraFyClient is initalized
590
+ [70]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
570
591
 
571
- **Kind**: global function
572
- <a name="bindProjectState"></a>
592
+ [71]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
573
593
 
574
- ## bindProjectState([options], Paths) ⇒ <code>Promies.&lt;Reactive.&lt;Object&gt;&gt;</code>
575
- Return a Vue reactive object that can be read/written which whose changes will transparently be written back to the TERA server instance
594
+ [72]: https://developer.mozilla.org/docs/Web/API/MessageEvent
576
595
 
577
- **Kind**: global function
578
- **Returns**: <code>Promies.&lt;Reactive.&lt;Object&gt;&gt;</code> - A reactive object representing the project state
596
+ [73]: http://jsonpatch.com
579
597
 
580
- | Param | Type | Default | Description |
581
- | --- | --- | --- | --- |
582
- | [options] | <code>Object</code> | | Additional options to mutate behaviour |
583
- | [options.autoRequire] | <code>Boolean</code> | <code>true</code> | Run `requireProject()` automatically before continuing |
584
- | [options.write] | <code>Boolean</code> | <code>true</code> | Allow local reactivity to writes - send these to the server |
585
- | Paths | <code>Array.&lt;String&gt;</code> | | to subscribe to e.g. ['/users/'], |
598
+ [74]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date
586
599
 
600
+ [75]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function