@cyberismo/backend 0.0.14 → 0.0.15

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/dist/domain/calculations/index.js +1 -53
  2. package/dist/domain/calculations/index.js.map +1 -1
  3. package/dist/domain/calculations/schema.js +0 -7
  4. package/dist/domain/calculations/schema.js.map +1 -1
  5. package/dist/domain/calculations/service.js +0 -5
  6. package/dist/domain/calculations/service.js.map +1 -1
  7. package/dist/domain/cards/index.js +2 -2
  8. package/dist/domain/cards/index.js.map +1 -1
  9. package/dist/domain/cards/lib.js +1 -11
  10. package/dist/domain/cards/lib.js.map +1 -1
  11. package/dist/domain/cards/service.js +2 -6
  12. package/dist/domain/cards/service.js.map +1 -1
  13. package/dist/domain/resources/index.js +2 -20
  14. package/dist/domain/resources/index.js.map +1 -1
  15. package/dist/domain/resources/schema.js +12 -1
  16. package/dist/domain/resources/schema.js.map +1 -1
  17. package/dist/domain/resources/service.js +14 -34
  18. package/dist/domain/resources/service.js.map +1 -1
  19. package/dist/index.js +3 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/public/THIRD-PARTY.txt +112 -112
  22. package/dist/public/assets/index-DnK7MBer.css +1 -0
  23. package/dist/public/assets/{index-OjHhVGiV.js → index-Dtn1rQ-9.js} +81741 -73825
  24. package/dist/public/index.html +2 -2
  25. package/package.json +6 -6
  26. package/src/domain/calculations/index.ts +1 -68
  27. package/src/domain/calculations/schema.ts +0 -9
  28. package/src/domain/calculations/service.ts +0 -11
  29. package/src/domain/cards/index.ts +2 -2
  30. package/src/domain/cards/lib.ts +2 -19
  31. package/src/domain/cards/service.ts +2 -13
  32. package/src/domain/resources/index.ts +3 -41
  33. package/src/domain/resources/schema.ts +13 -1
  34. package/src/domain/resources/service.ts +25 -64
  35. package/src/index.ts +3 -4
  36. package/dist/public/assets/index-DA46eVkH.css +0 -1
@@ -11,8 +11,8 @@
11
11
  name="msapplication-TileImage"
12
12
  content="/cropped-favicon-270x270.png"
13
13
  />
14
- <script type="module" crossorigin src="/assets/index-OjHhVGiV.js"></script>
15
- <link rel="stylesheet" crossorigin href="/assets/index-DA46eVkH.css">
14
+ <script type="module" crossorigin src="/assets/index-Dtn1rQ-9.js"></script>
15
+ <link rel="stylesheet" crossorigin href="/assets/index-DnK7MBer.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyberismo/backend",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "Express backend for Cyberismo",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [],
@@ -9,13 +9,13 @@
9
9
  "dependencies": {
10
10
  "@asciidoctor/core": "^3.0.4",
11
11
  "@hono/node-server": "^1.19.2",
12
- "@hono/zod-validator": "^0.7.2",
12
+ "@hono/zod-validator": "^0.7.4",
13
13
  "@types/mime-types": "^3.0.1",
14
- "dotenv": "^17.2.2",
15
- "hono": "^4.9.7",
14
+ "dotenv": "^17.2.3",
15
+ "hono": "^4.10.3",
16
16
  "mime-types": "^3.0.1",
17
- "zod": "^4.1.8",
18
- "@cyberismo/data-handler": "0.0.14"
17
+ "zod": "^4.1.12",
18
+ "@cyberismo/data-handler": "0.0.15"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@cyberismo/app": "0.0.2"
@@ -13,11 +13,7 @@
13
13
 
14
14
  import { Hono } from 'hono';
15
15
  import * as calculationService from './service.js';
16
- import {
17
- createCalculationSchema,
18
- updateCalculationParamsSchema,
19
- updateCalculationBodySchema,
20
- } from './schema.js';
16
+ import { createCalculationSchema } from './schema.js';
21
17
  import { zValidator } from '../../middleware/zvalidator.js';
22
18
 
23
19
  const router = new Hono();
@@ -56,66 +52,3 @@ router.post('/', zValidator('json', createCalculationSchema), async (c) => {
56
52
  });
57
53
 
58
54
  export default router;
59
- /**
60
- * @swagger
61
- * /api/calculations/{prefix}/{identifier}:
62
- * put:
63
- * summary: Update a calculation content
64
- * description: Updates the content of a calculation file
65
- * parameters:
66
- * - in: path
67
- * name: prefix
68
- * required: true
69
- * schema:
70
- * type: string
71
- * description: Prefix of the calculation
72
- * - in: path
73
- * name: type
74
- * required: true
75
- * schema:
76
- * type: string
77
- * description: Resource type (must be 'calculations')
78
- * - in: path
79
- * name: identifier
80
- * required: true
81
- * schema:
82
- * type: string
83
- * description: Identifier of the calculation
84
- * requestBody:
85
- * required: true
86
- * content:
87
- * application/json:
88
- * schema:
89
- * type: object
90
- * properties:
91
- * content:
92
- * type: string
93
- * description: New content for the calculation
94
- * responses:
95
- * 200:
96
- * description: Calculation updated successfully
97
- * 400:
98
- * description: Invalid request
99
- * 404:
100
- * description: Calculation not found
101
- * 500:
102
- * description: Server error
103
- */
104
- router.put(
105
- '/:prefix/:type/:identifier',
106
- zValidator('param', updateCalculationParamsSchema),
107
- zValidator('json', updateCalculationBodySchema),
108
- async (c) => {
109
- const commands = c.get('commands');
110
- const { prefix, identifier } = c.req.valid('param');
111
- const { content } = c.req.valid('json');
112
-
113
- await calculationService.updateCalculation(
114
- commands,
115
- prefix,
116
- identifier,
117
- content,
118
- );
119
- return c.json({ message: 'Calculation updated successfully' });
120
- },
121
- );
@@ -12,16 +12,7 @@
12
12
  */
13
13
 
14
14
  import { z } from 'zod';
15
- import { resourceParamsSchema } from '../../common/validationSchemas.js';
16
15
 
17
16
  export const createCalculationSchema = z.object({
18
17
  fileName: z.string().min(1),
19
18
  });
20
-
21
- export const updateCalculationBodySchema = z.object({
22
- content: z.string(),
23
- });
24
-
25
- export const updateCalculationParamsSchema = resourceParamsSchema.extend({
26
- type: z.literal('calculations'),
27
- });
@@ -12,7 +12,6 @@
12
12
  */
13
13
 
14
14
  import type { CommandManager } from '@cyberismo/data-handler';
15
- import { resourceName } from '@cyberismo/data-handler';
16
15
 
17
16
  export async function createCalculation(
18
17
  commands: CommandManager,
@@ -20,13 +19,3 @@ export async function createCalculation(
20
19
  ) {
21
20
  await commands.createCmd.createCalculation(fileName);
22
21
  }
23
-
24
- export async function updateCalculation(
25
- commands: CommandManager,
26
- prefix: string,
27
- identifier: string,
28
- content: string,
29
- ) {
30
- const name = resourceName(`${prefix}/calculations/${identifier}`, true);
31
- await commands.editCmd.editCalculation(name, content);
32
- }
@@ -589,7 +589,7 @@ router.get(
589
589
  const commands = c.get('commands');
590
590
  return await cardService.getAllAttachments(commands);
591
591
  }),
592
- async (c) => {
592
+ (c) => {
593
593
  const commands = c.get('commands');
594
594
  const { key, attachment } = c.req.param();
595
595
  const filename = decodeURI(attachment);
@@ -599,7 +599,7 @@ router.get(
599
599
  }
600
600
 
601
601
  try {
602
- const attachmentResponse = await cardService.getAttachment(
602
+ const attachmentResponse = cardService.getAttachment(
603
603
  commands,
604
604
  key,
605
605
  filename,
@@ -12,11 +12,7 @@
12
12
  */
13
13
 
14
14
  import Processor from '@asciidoctor/core';
15
- import {
16
- type Card,
17
- CardLocation,
18
- type ProjectFetchCardDetails,
19
- } from '@cyberismo/data-handler/interfaces/project-interfaces';
15
+ import type { Card } from '@cyberismo/data-handler/interfaces/project-interfaces';
20
16
  import { type CommandManager, evaluateMacros } from '@cyberismo/data-handler';
21
17
  import { getCardQueryResult } from '../../export.js';
22
18
 
@@ -31,22 +27,9 @@ export async function getCardDetails(
31
27
  key: string,
32
28
  staticMode?: boolean,
33
29
  ): Promise<result> {
34
- const fetchCardDetails: ProjectFetchCardDetails = {
35
- attachments: true,
36
- children: false,
37
- content: true,
38
- contentType: 'adoc',
39
- metadata: false,
40
- parent: false,
41
- location: CardLocation.all,
42
- };
43
-
44
30
  let cardDetailsResponse: Card | undefined;
45
31
  try {
46
- cardDetailsResponse = await commands.showCmd.showCardDetails(
47
- fetchCardDetails,
48
- key,
49
- );
32
+ cardDetailsResponse = commands.showCmd.showCardDetails(key);
50
33
  } catch {
51
34
  return { status: 400, message: `Card ${key} not found from project` };
52
35
  }
@@ -213,23 +213,12 @@ export async function removeLink(
213
213
  return { message: 'Link removed successfully' };
214
214
  }
215
215
 
216
- export async function getAttachment(
216
+ export function getAttachment(
217
217
  commands: CommandManager,
218
218
  key: string,
219
219
  filename: string,
220
220
  ) {
221
- const attachmentResponse = await commands.showCmd.showAttachment(
222
- key,
223
- filename,
224
- );
225
-
226
- if (!attachmentResponse) {
227
- throw new Error(
228
- `No attachment found from card ${key} and filename ${filename}`,
229
- );
230
- }
231
-
232
- return attachmentResponse;
221
+ return commands.showCmd.showAttachment(key, filename);
233
222
  }
234
223
 
235
224
  export async function getAllCards(commands: CommandManager) {
@@ -13,10 +13,7 @@
13
13
 
14
14
  import { Hono } from 'hono';
15
15
  import * as resourceService from './service.js';
16
- import type {
17
- ResourceFileContentResponse,
18
- ResourceValidationResponse,
19
- } from '../../types.js';
16
+ import type { ResourceValidationResponse } from '../../types.js';
20
17
  import { resourceParamsSchema } from '../../common/validationSchemas.js';
21
18
  import { zValidator } from '../../middleware/zvalidator.js';
22
19
  import {
@@ -118,41 +115,6 @@ router.get(
118
115
  },
119
116
  );
120
117
 
121
- router.get('/:module/:type/:resource/:file', async (c) => {
122
- const commands = c.get('commands');
123
- const { module, type, resource, file } = c.req.param();
124
- const content = await resourceService.getFileContent(
125
- commands,
126
- module,
127
- type,
128
- resource,
129
- file,
130
- );
131
- const response: ResourceFileContentResponse = { content };
132
- return c.json(response);
133
- });
134
-
135
- router.put('/:module/:type/:resource/:file', async (c) => {
136
- const commands = c.get('commands');
137
- const { module, type, resource, file } = c.req.param();
138
- const changedContent = await c.req.json();
139
- if (
140
- changedContent.content === undefined ||
141
- typeof changedContent.content !== 'string'
142
- ) {
143
- return c.json({ error: 'Content is required' }, 400);
144
- }
145
- await resourceService.updateFile(
146
- commands,
147
- module,
148
- type,
149
- resource,
150
- file,
151
- changedContent.content,
152
- );
153
- return c.json({ content: changedContent.content });
154
- });
155
-
156
118
  router.delete(
157
119
  '/:prefix/:type/:identifier',
158
120
  zValidator('param', resourceParamsSchema),
@@ -173,12 +135,12 @@ router.post(
173
135
  async (c) => {
174
136
  const commands = c.get('commands');
175
137
  const resourceParams = c.req.valid('param');
176
- const { key, operation } = c.req.valid('json');
138
+ const { updateKey, operation } = c.req.valid('json');
177
139
 
178
140
  await resourceService.updateResourceWithOperation(
179
141
  commands,
180
142
  resourceParams,
181
- { key, operation },
143
+ { updateKey, operation },
182
144
  );
183
145
  return c.json({ message: 'Updated' });
184
146
  },
@@ -18,9 +18,21 @@ export type ValidateResourceParams = z.infer<
18
18
  typeof validateResourceParamsSchema
19
19
  >;
20
20
 
21
+ const updateKey = z.union([
22
+ z.object({
23
+ key: z.literal('content'),
24
+ subKey: z.string(),
25
+ }),
26
+ z.object({
27
+ key: z.string().refine((k) => k !== 'content', {
28
+ message: 'key cannot be "content" here',
29
+ }),
30
+ }),
31
+ ]);
32
+
21
33
  // Body schema for update operation-based resource update
22
34
  export const updateOperationBodySchema = z.object({
23
- key: z.string(),
35
+ updateKey,
24
36
  operation: z.discriminatedUnion('name', [
25
37
  z.object({
26
38
  name: z.literal('add'),
@@ -14,6 +14,7 @@
14
14
  import type { ResourceContent } from '@cyberismo/data-handler/interfaces/resource-interfaces';
15
15
  import type {
16
16
  Card,
17
+ CardWithChildrenCards,
17
18
  ResourceFolderType,
18
19
  RemovableResourceTypes,
19
20
  } from '@cyberismo/data-handler/interfaces/project-interfaces';
@@ -158,18 +159,26 @@ async function createResourceNode(
158
159
  };
159
160
 
160
161
  // Add file children for folder resources
161
- if (isResourceFolderType(resourceType) && resourceType !== 'templates') {
162
+ if (
163
+ isResourceFolderType(resourceType) &&
164
+ resourceType !== 'templates' &&
165
+ 'content' in resourceData!
166
+ ) {
162
167
  try {
163
- const fileNames = await commands.showCmd.showFileNames(
164
- resourceName(name),
168
+ const fileNodes = Object.entries(resourceData.content).map(
169
+ ([fileName, content]) => ({
170
+ id: `${resourceType}-${name}-${fileName}`,
171
+ type: 'file',
172
+ name: `${name}/${fileName}`,
173
+ resourceName: name,
174
+ fileName,
175
+ displayName: fileName,
176
+ data: {
177
+ content,
178
+ },
179
+ readOnly: resourceName(name).prefix !== projectPrefix,
180
+ }),
165
181
  );
166
- const fileNodes = fileNames.map((fileName: string) => ({
167
- id: `${resourceType}-${name}-${fileName}`,
168
- type: 'file',
169
- name: `${name}/${fileName}`,
170
- displayName: fileName,
171
- readOnly: resourceName(name).prefix !== projectPrefix,
172
- }));
173
182
 
174
183
  node.children = children ? [...children, ...fileNodes] : fileNodes;
175
184
  } catch (error) {
@@ -184,12 +193,12 @@ async function createResourceNode(
184
193
 
185
194
  // Helper function to recursively create card nodes with children
186
195
  function createCardNode(
187
- card: Card,
196
+ card: CardWithChildrenCards,
188
197
  module: string,
189
198
  projectPrefix: string,
190
199
  ): unknown {
191
200
  // Destructure to separate children from other card data
192
- const { children, ...cardData } = card;
201
+ const { childrenCards, ...cardData } = card;
193
202
 
194
203
  const cardNode: {
195
204
  id: string;
@@ -208,8 +217,8 @@ function createCardNode(
208
217
  };
209
218
 
210
219
  // Recursively process children if they exist
211
- if (children && children.length > 0) {
212
- cardNode.children = children.map((child) =>
220
+ if (childrenCards && childrenCards.length > 0) {
221
+ cardNode.children = childrenCards.map((child) =>
213
222
  createCardNode(child, module, projectPrefix),
214
223
  );
215
224
  }
@@ -368,54 +377,6 @@ export async function deleteResource(
368
377
  );
369
378
  }
370
379
 
371
- /**
372
- * Get the content of a file in a resource.
373
- * @param commands Command manager.
374
- * @param module Name of the module.
375
- * @param type Name of the type.
376
- * @param resource Name of the resource.
377
- * @param fileName Name of the file.
378
- * @returns The content of the file.
379
- */
380
- export async function getFileContent(
381
- commands: CommandManager,
382
- module: string,
383
- type: string,
384
- resource: string,
385
- fileName: string,
386
- ) {
387
- // TODO: Use resource APIs to fetch resource content; showFile will be removed
388
- return commands.showCmd.showFile(
389
- resourceName(`${module}/${type}/${resource}`),
390
- fileName,
391
- );
392
- }
393
-
394
- /**
395
- * Update a file of a folder resource. Cannot be used to create a new file.
396
- * @param commands Command manager.
397
- * @param module Name of the module.
398
- * @param type Name of the type.
399
- * @param resource Name of the resource.
400
- * @param fileName Name of the file.
401
- * @param changedContent The new content for the file.
402
- * @returns The updated file content.
403
- */
404
- export async function updateFile(
405
- commands: CommandManager,
406
- module: string,
407
- type: string,
408
- resource: string,
409
- fileName: string,
410
- changedContent: string,
411
- ) {
412
- return commands.editCmd.editResourceContent(
413
- resourceName(`${module}/${type}/${resource}`),
414
- fileName,
415
- changedContent,
416
- );
417
- }
418
-
419
380
  /**
420
381
  * Validate a single resource.
421
382
  * @param commands Command manager.
@@ -445,10 +406,10 @@ export async function updateResourceWithOperation(
445
406
  resource: ResourceParams,
446
407
  body: UpdateOperationBody,
447
408
  ) {
448
- const { key, operation } = body;
409
+ const { updateKey, operation } = body;
449
410
  await commands.updateCmd.applyResourceOperation(
450
411
  resourceNameToString(resource),
451
- key,
412
+ updateKey,
452
413
  operation,
453
414
  );
454
415
  }
package/src/index.ts CHANGED
@@ -41,7 +41,7 @@ export async function previewSite(dir: string, findPort: boolean = true) {
41
41
  if (findPort) {
42
42
  port = await findFreePort(port, DEFAULT_MAX_PORT);
43
43
  }
44
- await startApp(app, port);
44
+ startApp(app, port);
45
45
  }
46
46
 
47
47
  /**
@@ -59,11 +59,10 @@ export async function startServer(
59
59
  port = await findFreePort(port, DEFAULT_MAX_PORT);
60
60
  }
61
61
  const app = createApp(projectPath);
62
- await startApp(app, port);
62
+ startApp(app, port);
63
63
  }
64
64
 
65
- async function startApp(app: Hono, port: number) {
66
- // Start server
65
+ function startApp(app: Hono, port: number) {
67
66
  serve(
68
67
  {
69
68
  fetch: app.fetch,
@@ -1 +0,0 @@
1
- @media (max-width: 800px){.breadcrumbs{display:none}}[role=treeitem][aria-selected=false]:hover{.treenode{background-color:#dedede}}[role=treeitem][aria-selected=true]{outline:none}.resizeHandle{width:2px}.resizeHandle:hover,.resizeHandle:active{background-color:#0b6bcb}.cyberismo-svg-wrapper svg{max-height:100vh}.doc .MuiButton-root{margin-top:12px}.doc table.tableblock{border-collapse:collapse}.doc{color:#333;font-size:inherit;-ms-hyphens:auto;hyphens:auto;line-height:1.6;margin:0;padding:0}@media screen and (min-width: 1024px){.doc{-webkit-box-flex:1;-ms-flex:auto;flex:auto;font-size:.94444rem;margin:0;min-width:0}}.doc h1,.doc h2,.doc h3,.doc h4,.doc h5,.doc h6{color:#191919;font-weight:400;-ms-hyphens:none;hyphens:none;line-height:1.3;margin:1rem 0 0}.doc>h1.page:first-child{font-size:2rem;margin:1.5rem 0}@media screen and (min-width: 769px){.doc>h1.page:first-child{margin-top:2.5rem}}.doc>h1.page:first-child+aside.toc.embedded{margin-top:-.5rem}.doc>h2#name+.sectionbody{margin-top:1rem}#preamble+.sect1,.doc .sect1+.sect1{margin-top:2rem}.doc h1.sect0{background:#f0f0f0;font-size:1.8em;margin:1.5rem -1rem 0;padding:.5rem 1rem}.doc h2:not(.discrete){border-bottom:1px solid #e1e1e1;margin-left:-1rem;margin-right:-1rem;padding:.4rem 1rem .1rem}.doc h3:not(.discrete),.doc h4:not(.discrete){font-weight:600}.doc h1 .anchor,.doc h2 .anchor,.doc h3 .anchor,.doc h4 .anchor,.doc h5 .anchor,.doc h6 .anchor{position:absolute;text-decoration:none;width:1.75ex;margin-left:-1.5ex;visibility:hidden;font-size:.8em;font-weight:400;padding-top:.05em}.doc h1 .anchor:before,.doc h2 .anchor:before,.doc h3 .anchor:before,.doc h4 .anchor:before,.doc h5 .anchor:before,.doc h6 .anchor:before{content:"§"}.doc h1:hover .anchor,.doc h2:hover .anchor,.doc h3:hover .anchor,.doc h4:hover .anchor,.doc h5:hover .anchor,.doc h6:hover .anchor{visibility:visible}.doc dl,.doc p{margin:0}.doc a{color:#1565c0}.doc a:hover{color:#104d92}.doc a.bare{-ms-hyphens:none;hyphens:none}.doc a.unresolved{color:#d32f2f}.doc i.fa{-ms-hyphens:none;hyphens:none;font-style:normal}.doc .colist>table code,.doc p code,.doc thead code{color:#222;background:#fafafa;border-radius:.25em;font-size:.95em;padding:.125em .25em}.doc code,.doc pre{-ms-hyphens:none;hyphens:none}.doc pre{font-size:.88889rem;line-height:1.5;margin:0}.doc blockquote{margin:0}.doc .paragraph.lead>p{font-size:1rem}.doc .right{float:right}.doc .left{float:left}.doc .float-gap.right{margin:0 1rem 1rem 0}.doc .float-gap.left{margin:0 0 1rem 1rem}.doc .float-group:after{content:"";display:table;clear:both}.doc .text-left{text-align:left}.doc .text-center{text-align:center}.doc .text-right{text-align:right}.doc .text-justify{text-align:justify}.doc .stretch{width:100%}.doc .big{font-size:larger}.doc .small{font-size:smaller}.doc .underline{text-decoration:underline}.doc .line-through{text-decoration:line-through}.doc .dlist,.doc .exampleblock,.doc .hdlist,.doc .imageblock,.doc .listingblock,.doc .literalblock,.doc .olist,.doc .paragraph,.doc .partintro,.doc .quoteblock,.doc .sidebarblock,.doc .tabs,.doc .ulist,.doc .verseblock,.doc .videoblock,.doc details,.doc hr{margin:1rem 0 0}.doc .tablecontainer,.doc .tablecontainer+*,.doc :not(.tablecontainer)>table.tableblock,.doc :not(.tablecontainer)>table.tableblock+*,.doc>table.tableblock,.doc>table.tableblock+*{margin-top:1.5rem}.doc table.tableblock{font-size:.83333rem}.doc p.tableblock+p.tableblock{margin-top:.5rem}.doc table.tableblock pre{font-size:inherit}.doc td.tableblock>.content{word-wrap:anywhere}.doc td.tableblock>.content>:first-child{margin-top:0}.doc table.tableblock td{padding:.5rem}.doc table.tableblock th{padding:.5rem;background:#fbfcfe}.doc table.tableblock,.doc table.tableblock>*>tr>*{border:0 solid #e1e1e1}.doc table.grid-all>*>tr>*{border-width:1px}.doc table.grid-cols>*>tr>*{border-width:0 1px}.doc table.grid-rows>*>tr>*{border-width:1px 0}.doc table.grid-all>thead th,.doc table.grid-rows>thead th{border-bottom-width:2.5px}.doc table.frame-all{border-width:1px}.doc table.frame-ends{border-width:1px 0}.doc table.frame-sides{border-width:0 1px}.doc table.frame-none>colgroup+*>:first-child>*,.doc table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}.doc table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}.doc table.frame-ends>*>tr>:first-child,.doc table.frame-none>*>tr>:first-child{border-left-width:0}.doc table.frame-ends>*>tr>:last-child,.doc table.frame-none>*>tr>:last-child{border-right-width:0}.doc table.stripes-all>tbody>tr,.doc table.stripes-even>tbody>tr:nth-of-type(2n),.doc table.stripes-hover>tbody>tr:hover,.doc table.stripes-odd>tbody>tr:nth-of-type(odd){background:#fafafa}.doc table.tableblock>tfoot{background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#fff));background:linear-gradient(180deg,#f0f0f0 0,#fff)}.doc .halign-left{text-align:left}.doc .halign-right{text-align:right}.doc .halign-center{text-align:center}.doc .valign-top{vertical-align:top}.doc .valign-bottom{vertical-align:bottom}.doc .valign-middle{vertical-align:middle}.doc .admonitionblock{margin:1.4rem 0 0}.doc .admonitionblock p,.doc .admonitionblock td.content{font-size:.88889rem}.doc .admonitionblock td.content>.title+*,.doc .admonitionblock td.content>:not(.title):first-child{margin-top:0}.doc .admonitionblock td.content pre{font-size:.83333rem}.doc .admonitionblock>table{table-layout:fixed;position:relative;width:100%}.doc .admonitionblock td.content{padding:1rem 1rem .75rem;background:#fafafa;width:100%;word-wrap:anywhere}.doc .admonitionblock td.icon{font-size:.83333rem;left:0;line-height:1;padding:0;position:absolute;top:0;-webkit-transform:translate(-.5rem,-50%);transform:translate(-.5rem,-50%)}.doc .admonitionblock td.icon i{-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-radius:.45rem;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-filter:initial;filter:none;height:1.25rem;padding:0 .5rem;vertical-align:initial;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.doc .admonitionblock td.icon i:after{content:attr(title);font-weight:600;font-style:normal;text-transform:uppercase}.doc .admonitionblock td.icon i.icon-caution{background-color:#a0439c;color:#fff}.doc .admonitionblock td.icon i.icon-important{background-color:#d32f2f;color:#fff}.doc .admonitionblock td.icon i.icon-note{background-color:#217ee7;color:#fff}.doc .admonitionblock td.icon i.icon-tip{background-color:#41af46;color:#fff}.doc .admonitionblock td.icon i.icon-warning{background-color:#e18114;color:#fff}.doc .imageblock,.doc .videoblock{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.doc .imageblock .content{-ms-flex-item-align:stretch;align-self:stretch;text-align:center}.doc .imageblock.text-left,.doc .videoblock.text-left{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.doc .imageblock.text-left .content{text-align:left}.doc .imageblock.text-right,.doc .videoblock.text-right{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.doc .imageblock.text-right .content{text-align:right}.doc .image>img,.doc .image>object,.doc .image>svg,.doc .imageblock img,.doc .imageblock object,.doc .imageblock svg{display:inline-block;max-height:75vh;max-width:100%;vertical-align:middle}.doc .image:not(.left):not(.right)>img{margin-top:-.2em}.doc .videoblock iframe,.doc .videoblock video{max-width:100%;vertical-align:middle}#preamble .abstract blockquote{background:#f0f0f0;border-left:5px solid #e1e1e1;color:#4a4a4a;font-size:.88889rem;padding:.75em 1em}.doc .quoteblock,.doc .verseblock{background:#fafafa;border-left:5px solid #5d5d5d;color:#5d5d5d}.doc .quoteblock{padding:.25rem 2rem 1.25rem}.doc .quoteblock .attribution{color:#8e8e8e;font-size:.83333rem;margin-top:.75rem}.doc .quoteblock blockquote{margin-top:1rem}.doc .quoteblock .paragraph{font-style:italic}.doc .quoteblock cite{padding-left:1em}.doc .verseblock{font-size:1.15em;padding:1rem 2rem}.doc .verseblock pre{font-family:inherit;font-size:inherit}.doc ol,.doc ul{margin:0;padding:0 0 0 2rem}.doc ol.none,.doc ol.unnumbered,.doc ol.unstyled,.doc ul.checklist,.doc ul.no-bullet,.doc ul.none,.doc ul.unstyled{list-style-type:none}.doc ol.unnumbered,.doc ul.no-bullet{padding-left:1.25rem}.doc ol.unstyled,.doc ul.unstyled{padding-left:0}.doc ul.circle{list-style-type:circle}.doc ul.disc{list-style-type:disc}.doc ul.square{list-style-type:square}.doc ul.circle ul:not([class]),.doc ul.disc ul:not([class]),.doc ul.square ul:not([class]){list-style:inherit}.doc ol.arabic{list-style-type:decimal}.doc ol.decimal{list-style-type:decimal-leading-zero}.doc ol.loweralpha{list-style-type:lower-alpha}.doc ol.upperalpha{list-style-type:upper-alpha}.doc ol.lowerroman{list-style-type:lower-roman}.doc ol.upperroman{list-style-type:upper-roman}.doc ol.lowergreek{list-style-type:lower-greek}.doc ul.checklist{padding-left:1.75rem}.doc ul.checklist p>i.fa-check-square-o:first-child,.doc ul.checklist p>i.fa-square-o:first-child{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:1.25rem;margin-left:-1.25rem}.doc ul.checklist i.fa-check-square-o:before{content:"✓"}.doc ul.checklist i.fa-square-o:before{content:"❏"}.doc .dlist .dlist,.doc .dlist .olist,.doc .dlist .ulist,.doc .olist .dlist,.doc .olist .olist,.doc .olist .ulist,.doc .olist li+li,.doc .ulist .dlist,.doc .ulist .olist,.doc .ulist .ulist,.doc .ulist li+li{margin-top:.5rem}.doc .admonitionblock .listingblock,.doc .olist .listingblock,.doc .ulist .listingblock{padding:0}.doc .admonitionblock .title,.doc .exampleblock .title,.doc .imageblock .title,.doc .listingblock .title,.doc .literalblock .title,.doc .openblock .title,.doc .videoblock .title,.doc table.tableblock caption{color:#5d5d5d;font-size:.88889rem;font-style:italic;font-weight:600;-ms-hyphens:none;hyphens:none;letter-spacing:.01em;padding-bottom:.075rem}.doc table.tableblock caption{text-align:left}.doc .olist .title,.doc .ulist .title{font-style:italic;font-weight:600;margin-bottom:.25rem}.doc .imageblock .title,.doc .videoblock .title{margin-top:.5rem;padding-bottom:0}.doc details{margin-left:1rem}.doc details>summary{display:block;position:relative;line-height:1.6;margin-bottom:.5rem}.doc details>summary::-webkit-details-marker{display:none}.doc details>summary:before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1rem;-webkit-transform:translateX(15%);transform:translate(15%)}.doc details[open]>summary:before{border-color:currentColor transparent transparent;border-width:.5rem .3rem 0;-webkit-transform:translateY(15%);transform:translateY(15%)}.doc details>summary:after{content:"";width:1rem;height:1em;position:absolute;top:.3em;left:-1rem}.doc details.result{margin-top:.25rem}.doc details.result>summary{color:#5d5d5d;font-style:italic;margin-bottom:0}.doc details.result>.content{margin-left:-1rem}.doc .exampleblock>.content,.doc details.result>.content{background:#fff;border:.25rem solid #5d5d5d;border-radius:.5rem;padding:.75rem}.doc .exampleblock>.content:after,.doc details.result>.content:after{content:"";display:table;clear:both}.doc .exampleblock>.content>:first-child,.doc details>.content>:first-child{margin-top:0}.doc .sidebarblock{background:#e1e1e1;border-radius:.75rem;padding:.75rem 1.5rem}.doc .sidebarblock>.content>.title{font-size:1.25rem;font-weight:600;line-height:1.3;margin-bottom:.5rem;text-align:center}.doc .sidebarblock>.content>.title+*,.doc .sidebarblock>.content>:not(.title):first-child{margin-top:0}.doc .listingblock.wrap pre,.doc table.tableblock pre{white-space:pre-wrap}.doc .listingblock pre:not(.highlight),.doc .literalblock pre,.doc pre.highlight>code{background:#fafafa;-webkit-box-shadow:inset 0 0 1.75px #e1e1e1;box-shadow:inset 0 0 1.75px #e1e1e1;display:block;overflow-x:auto;padding:.875em}.doc .listingblock>.content{position:relative}.doc .source-toolbox{display:-webkit-box;display:-ms-flexbox;display:flex;visibility:hidden;position:absolute;top:.25rem;right:.5rem;color:gray;font-family:Roboto,sans-serif;font-size:.72222rem;line-height:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;z-index:1}.doc .listingblock:hover .source-toolbox{visibility:visible}.doc .source-toolbox .source-lang{text-transform:uppercase;letter-spacing:.075em}.doc .source-toolbox>:not(:last-child):after{content:"|";letter-spacing:0;padding:0 1ch}.doc .source-toolbox .copy-button{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:none;border:none;color:inherit;outline:none;padding:0;font-size:inherit;line-height:inherit;width:1em;height:1em}.doc .source-toolbox .copy-icon{-webkit-box-flex:0;-ms-flex:none;flex:none;width:inherit;height:inherit}.doc .source-toolbox img.copy-icon{-webkit-filter:invert(50.2%);filter:invert(50.2%)}.doc .source-toolbox svg.copy-icon{fill:currentColor}.doc .source-toolbox .copy-toast{-webkit-box-flex:0;-ms-flex:none;flex:none;position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-top:1em;background-color:#333;border-radius:.25em;padding:.5em;color:#fff;cursor:auto;opacity:0;-webkit-transition:opacity .5s ease .5s;transition:opacity .5s ease .5s}.doc .source-toolbox .copy-toast:after{content:"";position:absolute;top:0;width:1em;height:1em;border:.55em solid transparent;border-left-color:#333;-webkit-transform:rotate(-90deg) translateX(50%) translateY(50%);transform:rotate(-90deg) translate(50%) translateY(50%);-webkit-transform-origin:left;transform-origin:left}.doc .source-toolbox .copy-button.clicked .copy-toast{opacity:1;-webkit-transition:none;transition:none}.doc .language-console .hljs-meta{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.doc .dlist dt{font-style:italic}.doc .dlist dd{margin:0 0 0 1.5rem}.doc .dlist dd+dt,.doc .dlist dd>p:first-child{margin-top:.5rem}.doc td.hdlist1,.doc td.hdlist2{padding:.5rem 0 0;vertical-align:top}.doc tr:first-child>.hdlist1,.doc tr:first-child>.hdlist2{padding-top:0}.doc td.hdlist1{font-weight:600;padding-right:.25rem}.doc td.hdlist2{padding-left:.25rem}.doc .colist{font-size:.88889rem;margin:.25rem 0 -.25rem}.doc .colist>table>tbody>tr>:first-child,.doc .colist>table>tr>:first-child{padding:.25em .5rem 0;vertical-align:top}.doc .colist>table>tbody>tr>:last-child,.doc .colist>table>tr>:last-child{padding:.25rem 0}.doc .conum[data-value]{border:1px solid;border-radius:100%;display:inline-block;font-family:Roboto,sans-serif;font-size:.75rem;font-style:normal;line-height:1.2;text-align:center;width:1.25em;height:1.25em;letter-spacing:-.25ex;text-indent:-.25ex}.doc .conum[data-value]:after{content:attr(data-value)}.doc .conum[data-value]+b{display:none}.doc hr{border:solid #e1e1e1;border-width:2px 0 0;height:0}.doc b.button{white-space:nowrap}.doc b.button:before{content:"[";padding-right:.25em}.doc b.button:after{content:"]";padding-left:.25em}.doc kbd{display:inline-block;font-size:.66667rem;background:#fafafa;border:1px solid #c1c1c1;border-radius:.25em;-webkit-box-shadow:0 1px 0 #c1c1c1,0 0 0 .1em #fff inset;box-shadow:0 1px #c1c1c1,inset 0 0 0 .1em #fff;padding:.25em .5em;vertical-align:text-bottom;white-space:nowrap}.doc .keyseq,.doc kbd{line-height:1}.doc .keyseq{font-size:.88889rem}.doc .keyseq kbd{margin:0 .125em}.doc .keyseq kbd:first-child{margin-left:0}.doc .keyseq kbd:last-child{margin-right:0}.doc .menuseq,.doc .path{-ms-hyphens:none;hyphens:none}.doc .menuseq i.caret:before{content:"›";font-size:1.1em;font-weight:600;line-height:.90909}.doc :not(pre).nowrap{white-space:nowrap}.doc .nobreak{-ms-hyphens:none;hyphens:none;word-wrap:normal}.doc :not(pre).pre-wrap{white-space:pre-wrap}#footnotes{font-size:.85em;line-height:1.5;margin:2rem -.5rem 0}.doc td.tableblock>.content #footnotes{margin:2rem 0 0}#footnotes hr{border-top-width:1px;margin-top:0;width:20%}#footnotes .footnote{margin:.5em 0 0 1em}#footnotes .footnote+.footnote{margin-top:.25em}#footnotes .footnote>a:first-of-type{display:inline-block;margin-left:-2em;text-align:right;width:1.5em}.toc-menu{color:#5d5d5d}.toc.sidebar .toc-menu{margin-right:.75rem;position:sticky;top:6rem}.toc .toc-menu h3{color:#333;font-size:.88889rem;font-weight:600;line-height:1.3;margin:0 -.5px;padding-bottom:.25rem}.toc.sidebar .toc-menu h3{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:2.5rem;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.toc .toc-menu ul{font-size:.83333rem;line-height:1.2;list-style:none;margin:0;padding:0}.toc.sidebar .toc-menu ul{max-height:calc(100vh - 8.5rem);overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:none}@supports (scrollbar-width: none){.toc.sidebar .toc-menu ul{scrollbar-width:none}}.toc .toc-menu ul::-webkit-scrollbar{width:0;height:0}@media screen and (min-width: 1024px){.toc .toc-menu h3{font-size:.83333rem}.toc .toc-menu ul{font-size:.75rem}}.toc .toc-menu li{margin:0}.toc .toc-menu li[data-level="2"] a{padding-left:1.25rem}.toc .toc-menu li[data-level="3"] a{padding-left:2rem}.toc .toc-menu a{color:inherit;border-left:2px solid #e1e1e1;display:inline-block;padding:.25rem 0 .25rem .5rem;text-decoration:none}.sidebar.toc .toc-menu a{display:block;outline:none}.toc .toc-menu a:hover{color:#1565c0}.toc .toc-menu a.is-active{border-left-color:#2a7ee4;color:#2a7ee4}.sidebar.toc .toc-menu a:focus{background:#fafafa}.toc .toc-menu .is-hidden-toc{display:none!important}.contentSidebar{min-width:160px}.doc .videoblock .content{position:relative;width:100%;max-width:100%}.doc .videoblock .content:before{content:"";display:block;padding-top:56.25%}.doc .videoblock .content>iframe,.doc .videoblock .content>video{position:absolute;inset:0;width:100%!important;height:100%!important;border:0;background:#000;display:block}