@asciidoctor/core 4.0.0-alpha.2 → 4.0.0-alpha.4

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.
@@ -1,4 +1,4 @@
1
- var version = "4.0.0-alpha.2";
1
+ var version = "4.0.0-alpha.4";
2
2
  const packageJson = {
3
3
  version: version};
4
4
 
@@ -1507,6 +1507,65 @@ function resolveSeverity(severity) {
1507
1507
  return severity ?? Severity.UNKNOWN
1508
1508
  }
1509
1509
 
1510
+ // ── Per-execution logger context ─────────────────────────────────────────────
1511
+
1512
+ // Holds an AsyncLocalStorage instance once it is lazily initialised.
1513
+ // Allows per-execution logger isolation without mutating the global singleton,
1514
+ // making concurrent test execution (e.g. Deno's node:test) safe.
1515
+ let _loggerStore = null;
1516
+
1517
+ // Promise singleton — ensures AsyncLocalStorage is initialised at most once.
1518
+ let _loggerStorePromise = null;
1519
+
1520
+ /**
1521
+ * Lazily initialise an AsyncLocalStorage for per-execution logger context.
1522
+ * Falls back to null in environments that do not support node:async_hooks (e.g. browsers).
1523
+ * @returns {Promise<import('node:async_hooks').AsyncLocalStorage|null>}
1524
+ */
1525
+ async function _ensureLoggerStore() {
1526
+ if (_loggerStorePromise === null) {
1527
+ _loggerStorePromise = import('node:async_hooks')
1528
+ .then(({ AsyncLocalStorage }) => {
1529
+ const store = new AsyncLocalStorage();
1530
+ _loggerStore = store;
1531
+ return store
1532
+ })
1533
+ .catch(() => null);
1534
+ }
1535
+ return _loggerStorePromise
1536
+ }
1537
+
1538
+ /** @internal — returns the logger bound to the current async context, or null */
1539
+ function getContextLogger() {
1540
+ return _loggerStore?.getStore() ?? null
1541
+ }
1542
+
1543
+ /**
1544
+ * Run fn() within an async-local logger context so that all log calls via
1545
+ * `this.logger` (from applyLogging) automatically route to the provided logger
1546
+ * for the duration of the async execution chain.
1547
+ *
1548
+ * Falls back to global mutation in environments without node:async_hooks (e.g. browsers).
1549
+ *
1550
+ * @param {Logger|MemoryLogger|NullLogger} logger - The logger to activate.
1551
+ * @param {() => any} fn - The function to execute within the logger context.
1552
+ * @returns {Promise<any>}
1553
+ */
1554
+ async function withLogger(logger, fn) {
1555
+ const store = await _ensureLoggerStore();
1556
+ if (store) {
1557
+ return store.run(logger, fn)
1558
+ }
1559
+ // Fallback for environments without node:async_hooks (browsers).
1560
+ const prev = LoggerManager.logger;
1561
+ if (logger !== prev) LoggerManager.logger = logger;
1562
+ try {
1563
+ return await fn()
1564
+ } finally {
1565
+ if (logger !== prev) LoggerManager.logger = prev;
1566
+ }
1567
+ }
1568
+
1510
1569
  // ── Logger ────────────────────────────────────────────────────────────────────
1511
1570
 
1512
1571
  /** Standard logger that writes formatted messages to stderr or a custom pipe. */
@@ -1815,8 +1874,9 @@ class MemoryLogger {
1815
1874
  // ── NullLogger ────────────────────────────────────────────────────────────────
1816
1875
 
1817
1876
  /** Logger that discards all messages but still tracks the maximum severity. */
1818
- class NullLogger {
1877
+ class NullLogger extends Logger {
1819
1878
  constructor() {
1879
+ super();
1820
1880
  this.level = Severity.UNKNOWN;
1821
1881
  this._maxSeverity = null;
1822
1882
  }
@@ -1961,12 +2021,12 @@ const LoggerManager = (() => {
1961
2021
  function applyLogging(proto) {
1962
2022
  Object.defineProperty(proto, 'logger', {
1963
2023
  get() {
1964
- return LoggerManager.logger
2024
+ return _loggerStore?.getStore() ?? LoggerManager.logger
1965
2025
  },
1966
2026
  configurable: true,
1967
2027
  });
1968
2028
 
1969
- proto.getLogger = () => LoggerManager.logger;
2029
+ proto.getLogger = () => _loggerStore?.getStore() ?? LoggerManager.logger;
1970
2030
 
1971
2031
  proto.messageWithContext = (text, context = {}) =>
1972
2032
  Logger.AutoFormattingMessage.attach({ text, ...context });
@@ -2013,7 +2073,16 @@ const rstrip = (line) => line.replace(/[ \t\r\n\f\v]+$/, '');
2013
2073
  */
2014
2074
  function prepareSourceArray(data, trimEnd = true) {
2015
2075
  if (!data.length) return []
2016
- if (data[0].startsWith(BOM)) data[0] = data[0].slice(1);
2076
+ if (data[0].startsWith(BOM)) {
2077
+ data[0] = data[0].slice(1);
2078
+ } else if (
2079
+ data[0].charCodeAt(0) === 0xef &&
2080
+ data[0].charCodeAt(1) === 0xbb &&
2081
+ data[0].charCodeAt(2) === 0xbf
2082
+ ) {
2083
+ // Strip UTF-8 BOM encoded as three raw characters ( / \xEF\xBB\xBF) if not already decoded to U+FEFF
2084
+ data[0] = data[0].slice(3);
2085
+ }
2017
2086
  // Strip trailing \r to normalize Windows CRLF line endings (lines were split on \n, leaving \r).
2018
2087
  return trimEnd
2019
2088
  ? data.map(rstrip)
@@ -2033,7 +2102,16 @@ function prepareSourceArray(data, trimEnd = true) {
2033
2102
  */
2034
2103
  function prepareSourceString(data, trimEnd = true) {
2035
2104
  if (!data) return []
2036
- if (data.startsWith(BOM)) data = data.slice(1);
2105
+ if (data.startsWith(BOM)) {
2106
+ data = data.slice(1);
2107
+ } else if (
2108
+ data.charCodeAt(0) === 0xef &&
2109
+ data.charCodeAt(1) === 0xbb &&
2110
+ data.charCodeAt(2) === 0xbf
2111
+ ) {
2112
+ // Strip UTF-8 BOM encoded as three raw characters ( / \xEF\xBB\xBF) if not already decoded to U+FEFF
2113
+ data = data.slice(3);
2114
+ }
2037
2115
  // Normalize Windows CRLF to LF so that split('\n') does not leave trailing \r on each line.
2038
2116
  if (data.includes('\r'))
2039
2117
  data = data.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
@@ -2329,6 +2407,146 @@ function nextval(current) {
2329
2407
  return current
2330
2408
  }
2331
2409
 
2410
+ // HTTP cache system for URI fetching.
2411
+ //
2412
+ // Provides a pluggable caching layer for all HTTP(S) fetches performed during
2413
+ // document conversion (includes, images, readContents). Mirrors the behaviour
2414
+ // of Ruby's open-uri/cached mechanism activated by the `cache-uri` attribute.
2415
+ //
2416
+ // When `cache-uri` is set on the document:
2417
+ // - If a cache has been registered via HttpCacheManager.setCache(), it is used.
2418
+ // - Otherwise an ephemeral MemoryHttpCache is created for the duration of the
2419
+ // conversion (keyed by Document instance via a WeakMap, GC'd with the doc).
2420
+ //
2421
+ // To implement a custom cache, extend HttpCache and override read(uri).
2422
+
2423
+ /**
2424
+ * Base HTTP cache class.
2425
+ *
2426
+ * The default implementation delegates directly to fetch() with no caching.
2427
+ * Subclasses override read() to add caching behaviour.
2428
+ */
2429
+ class HttpCache {
2430
+ /**
2431
+ * Fetch content from a URI, optionally from a cache.
2432
+ * @param {string} uri
2433
+ * @returns {Promise<Response>}
2434
+ */
2435
+ async read(uri) {
2436
+ return fetch(uri)
2437
+ }
2438
+ }
2439
+
2440
+ /**
2441
+ * In-memory HTTP cache.
2442
+ *
2443
+ * Stores successful responses as ArrayBuffers keyed by URI. On a cache hit
2444
+ * a synthetic Response is reconstructed from the stored data without touching
2445
+ * the network. Non-OK responses (4xx, 5xx) are never cached.
2446
+ *
2447
+ * Safe as an ephemeral per-conversion cache or as a longer-lived process-level
2448
+ * cache when registered via HttpCacheManager.setCache().
2449
+ */
2450
+ class MemoryHttpCache extends HttpCache {
2451
+ /** @type {Map<string, {buffer: ArrayBuffer, status: number, statusText: string, headers: Record<string,string>}>} */
2452
+ #cache = new Map()
2453
+
2454
+ async read(uri) {
2455
+ const entry = this.#cache.get(uri);
2456
+ if (entry) {
2457
+ return new Response(entry.buffer.slice(0), {
2458
+ status: entry.status,
2459
+ statusText: entry.statusText,
2460
+ headers: entry.headers,
2461
+ })
2462
+ }
2463
+ const response = await fetch(uri);
2464
+ if (response.ok) {
2465
+ const buffer = await response.arrayBuffer();
2466
+ const headers = Object.fromEntries(response.headers.entries());
2467
+ this.#cache.set(uri, {
2468
+ buffer,
2469
+ status: response.status,
2470
+ statusText: response.statusText,
2471
+ headers,
2472
+ });
2473
+ return new Response(buffer.slice(0), {
2474
+ status: response.status,
2475
+ statusText: response.statusText,
2476
+ headers,
2477
+ })
2478
+ }
2479
+ return response
2480
+ }
2481
+ }
2482
+
2483
+ /** @type {WeakMap<object, MemoryHttpCache>} */
2484
+ const _ephemeralCaches = new WeakMap();
2485
+
2486
+ /**
2487
+ * Singleton manager for the HTTP cache.
2488
+ *
2489
+ * Register a process-level cache:
2490
+ * HttpCacheManager.setCache(new MemoryHttpCache())
2491
+ * HttpCacheManager.setCache(new MyFileSystemCache('./cache'))
2492
+ * HttpCacheManager.setCache(null) // revert to default ephemeral behaviour
2493
+ *
2494
+ * When no cache is registered and `cache-uri` is set, an ephemeral
2495
+ * MemoryHttpCache is created per Document instance.
2496
+ */
2497
+ const HttpCacheManager = {
2498
+ /** @type {HttpCache|null} */
2499
+ _cache: null,
2500
+
2501
+ /**
2502
+ * Register a cache to use for all conversions.
2503
+ * Pass null to unregister and revert to the ephemeral default.
2504
+ * @param {HttpCache|null} cache
2505
+ */
2506
+ setCache(cache) {
2507
+ this._cache = cache;
2508
+ },
2509
+
2510
+ /**
2511
+ * Return the registered process-level cache, or null if none is registered.
2512
+ * @returns {HttpCache|null}
2513
+ */
2514
+ getCache() {
2515
+ return this._cache
2516
+ },
2517
+
2518
+ /**
2519
+ * Return the cache to use for a specific document conversion.
2520
+ *
2521
+ * Returns the registered cache if one exists; otherwise creates (or reuses)
2522
+ * an ephemeral MemoryHttpCache scoped to the document's lifetime via a WeakMap.
2523
+ * @param {object} doc - the current Document instance
2524
+ * @returns {HttpCache}
2525
+ */
2526
+ getCacheForDocument(doc) {
2527
+ if (this._cache) return this._cache
2528
+ let cache = _ephemeralCaches.get(doc);
2529
+ if (!cache) {
2530
+ cache = new MemoryHttpCache();
2531
+ _ephemeralCaches.set(doc, cache);
2532
+ }
2533
+ return cache
2534
+ },
2535
+ };
2536
+
2537
+ /**
2538
+ * Fetch a URI, routing through the HTTP cache when `cache-uri` is set on the document.
2539
+ * @param {string} uri
2540
+ * @param {object} doc - the current Document instance
2541
+ * @returns {Promise<Response>}
2542
+ */
2543
+ function fetchUri(uri, doc) {
2544
+ if (doc.hasAttribute('cache-uri')) {
2545
+ return HttpCacheManager.getCacheForDocument(doc).read(uri)
2546
+ }
2547
+ return fetch(uri)
2548
+ }
2549
+
2332
2550
  // ESM conversion of abstract_node.rb
2333
2551
  //
2334
2552
  // Ruby-to-JavaScript notes:
@@ -2808,10 +3026,7 @@ class AbstractNode {
2808
3026
  (targetImage = this.normalizeWebPath(targetImage, imagesBase, false)))
2809
3027
  ) {
2810
3028
  return doc.hasAttribute('allow-uri-read')
2811
- ? this.generateDataUriFromUri(
2812
- targetImage,
2813
- doc.hasAttribute('cache-uri')
2814
- )
3029
+ ? this.generateDataUriFromUri(targetImage)
2815
3030
  : targetImage
2816
3031
  }
2817
3032
  return this.generateDataUri(targetImage, assetDirKey)
@@ -2864,10 +3079,7 @@ class AbstractNode {
2864
3079
  )
2865
3080
  : this.normalizeSystemPath(targetImage);
2866
3081
  if (isUriish(imagePath)) {
2867
- return await this.generateDataUriFromUri(
2868
- imagePath,
2869
- this.document.hasAttribute('cache-uri')
2870
- )
3082
+ return await this.generateDataUriFromUri(imagePath)
2871
3083
  }
2872
3084
  if (await isReadable(imagePath)) {
2873
3085
  const data = await _fsp$1.readFile(imagePath);
@@ -2887,12 +3099,12 @@ class AbstractNode {
2887
3099
  * imageUri, the caller must await the returned Promise.
2888
3100
  *
2889
3101
  * @param {string} imageUri - The URI from which to read the image data (http/https/ftp).
2890
- * @param {boolean} [cacheUri=false] - A Boolean to control caching (not yet supported in JS).
2891
3102
  * @returns {Promise<string>} a Promise resolving to a String data URI.
2892
3103
  */
2893
- async generateDataUriFromUri(imageUri, cacheUri = false) {
3104
+ async generateDataUriFromUri(imageUri) {
2894
3105
  try {
2895
- const response = await fetch(imageUri);
3106
+ const doc = this.document;
3107
+ const response = await fetchUri(imageUri, doc);
2896
3108
  if (response.ok) {
2897
3109
  const mimetype = (
2898
3110
  response.headers.get('content-type') || 'application/octet-stream'
@@ -3063,7 +3275,7 @@ class AbstractNode {
3063
3275
  ) {
3064
3276
  if (doc.hasAttribute('allow-uri-read')) {
3065
3277
  try {
3066
- const response = await fetch(resolvedTarget);
3278
+ const response = await fetchUri(resolvedTarget, doc);
3067
3279
  const text = await response.text();
3068
3280
  contents = opts.normalize ? prepareSourceString(text).join(LF$1) : text;
3069
3281
  } catch {
@@ -3088,7 +3300,7 @@ class AbstractNode {
3088
3300
  });
3089
3301
  }
3090
3302
 
3091
- if (contents && opts.warnIfEmpty && contents.length === 0) {
3303
+ if (contents != null && opts.warnIfEmpty && contents.length === 0) {
3092
3304
  this.logger.warn(`contents of ${label} is empty: ${resolvedTarget}`);
3093
3305
  }
3094
3306
  return contents
@@ -4842,14 +5054,6 @@ class PathResolver {
4842
5054
  : path
4843
5055
  }
4844
5056
 
4845
- /**
4846
- * @param {string} path
4847
- * @returns {string}
4848
- */
4849
- posixfy(path) {
4850
- return this.posixify(path)
4851
- }
4852
-
4853
5057
  /**
4854
5058
  * Expand the path by resolving parent references (..) and removing self references (.).
4855
5059
  * @param {string} path
@@ -5150,14 +5354,27 @@ function _platformSeparator() {
5150
5354
  * @internal
5151
5355
  */
5152
5356
  function _expandPath$1(p) {
5153
- if (typeof process !== 'undefined') {
5154
- // Lazy import to avoid top-level await
5155
- try {
5156
- const path = require('node:path');
5157
- return path.resolve(p).replace(/\\/g, '/')
5158
- } catch {}
5357
+ if (typeof process === 'undefined') return p
5358
+ const cwd = process.cwd().replace(/\\/g, '/');
5359
+ const full = `${cwd}/${p.replace(/\\/g, '/')}`;
5360
+ let root, rest;
5361
+ if (full.startsWith('//')) {
5362
+ root = '//';
5363
+ rest = full.slice(2);
5364
+ } else if (full.startsWith('/')) {
5365
+ root = '/';
5366
+ rest = full.slice(1);
5367
+ } else {
5368
+ const slash = full.indexOf('/');
5369
+ root = full.slice(0, slash + 1);
5370
+ rest = full.slice(slash + 1);
5371
+ }
5372
+ const resolved = [];
5373
+ for (const seg of rest.split('/')) {
5374
+ if (seg === '..') resolved.pop();
5375
+ else if (seg && seg !== '.') resolved.push(seg);
5159
5376
  }
5160
- return p
5377
+ return root + resolved.join('/')
5161
5378
  }
5162
5379
 
5163
5380
  /**
@@ -5965,7 +6182,7 @@ const SyntaxHighlighter = new DefaultFactory();
5965
6182
  //
5966
6183
  // This logic is specific to Asciidoctor.js and has no equivalent in the upstream Ruby asciidoctor
5967
6184
  // implementation. It handles the case where the document is loaded in a browser environment
5968
- // (XMLHttpRequest / Fetch IO module) where paths can be file:// or http(s):// URIs.
6185
+ // where paths can be file:// or http(s):// URIs.
5969
6186
  //
5970
6187
  // The key behavioural differences from the standard file-system resolver:
5971
6188
  // - Relative targets are resolved by string concatenation against a URI context dir,
@@ -6014,7 +6231,7 @@ function _linkReplacement(reader, target, attrlist) {
6014
6231
  * 1. target starts with file:// → inc_path = relpath = target
6015
6232
  * 2. target is a URI → must descend from baseDir or allow-uri-read; else → link
6016
6233
  * 3. target is an absolute OS path → prepend file:// (or file:///)
6017
- * 4. baseDir == '.' → inc_path = relpath = target (resolved by XMLHttpRequest/fetch)
6234
+ * 4. baseDir == '.' → inc_path = relpath = target (resolved by fetch)
6018
6235
  * 5. baseDir starts with file:// OR baseDir is not a URI → inc_path = baseDir/target; relpath = target
6019
6236
  * 6. baseDir is an absolute URL → inc_path = baseDir/target; relpath = target
6020
6237
  *
@@ -6736,7 +6953,7 @@ class Reader {
6736
6953
  return this.source()
6737
6954
  }
6738
6955
  getLogger() {
6739
- return LoggerManager.logger
6956
+ return this._document?.logger ?? LoggerManager.logger
6740
6957
  }
6741
6958
  createLogMessage(text, context = {}) {
6742
6959
  return Logger.AutoFormattingMessage.attach({ text, ...context })
@@ -7384,7 +7601,7 @@ class PreprocessorReader extends Reader {
7384
7601
  if (targetType === 'uri') {
7385
7602
  let uriContent;
7386
7603
  try {
7387
- const response = await fetch(incPath);
7604
+ const response = await fetchUri(incPath, this._document);
7388
7605
  if (!response.ok)
7389
7606
  throw new Error(`HTTP ${response.status} ${response.statusText}`)
7390
7607
  uriContent = await response.text();
@@ -9561,6 +9778,22 @@ class AttributeList {
9561
9778
  }
9562
9779
  }
9563
9780
 
9781
+ // Symbol key used to store attribute entries on a block-attributes object without
9782
+ // polluting the public attributes (invisible to Object.keys / for-in / JSON.stringify).
9783
+ // Spread ({ ...attrs }) copies Symbol-keyed properties, so the entry survives the
9784
+ // shallow clone made in AbstractNode's constructor.
9785
+ const ATTR_ENTRIES_KEY = Symbol('attribute_entries');
9786
+
9787
+ /**
9788
+ * Return the attribute entries stored for the given block attributes object,
9789
+ * or undefined if none have been saved.
9790
+ * @param {Object} blockAttributes
9791
+ * @returns {AttributeEntry[]|undefined}
9792
+ */
9793
+ function getAttributeEntries(blockAttributes) {
9794
+ return blockAttributes[ATTR_ENTRIES_KEY]
9795
+ }
9796
+
9564
9797
  class AttributeEntry {
9565
9798
  constructor(name, value, negate = null) {
9566
9799
  this.name = name;
@@ -9569,7 +9802,7 @@ class AttributeEntry {
9569
9802
  }
9570
9803
 
9571
9804
  saveTo(blockAttributes) {
9572
- (blockAttributes.attribute_entries ??= []).push(this);
9805
+ (blockAttributes[ATTR_ENTRIES_KEY] ??= []).push(this);
9573
9806
  return this
9574
9807
  }
9575
9808
  }
@@ -11044,7 +11277,7 @@ class Parser {
11044
11277
  const Rdr = Reader;
11045
11278
  const result = await extension.processMethod(
11046
11279
  parent,
11047
- blockReader ?? new Rdr(lines),
11280
+ blockReader ?? new Rdr(lines, null, { document: parent.document }),
11048
11281
  { ...attributes }
11049
11282
  );
11050
11283
  if (!result || result === parent) return null
@@ -13166,6 +13399,94 @@ function _uniform(str, chr, len) {
13166
13399
  // references; they will be resolved when those modules implement the methods.
13167
13400
 
13168
13401
 
13402
+ // Type-only imports for JSDoc
13403
+ /**
13404
+ * @typedef {import('./document.js').Document} Document
13405
+ * @typedef {import('./abstract_block.js').AbstractBlock} AbstractBlock
13406
+ */
13407
+
13408
+ // ── DSL interface types ───────────────────────────────────────────────────────
13409
+
13410
+ /**
13411
+ * DSL interface for configuring a {@link Processor} instance.
13412
+ * Applied to a processor instance via `Object.assign(instance, DslMixin)`.
13413
+ *
13414
+ * The `process` property behaves as a setter when called with a single Function
13415
+ * argument (stores the process block), or as a passthrough caller otherwise.
13416
+ *
13417
+ * @typedef {object} ProcessorDslInterface
13418
+ * @property {(key: string, value: unknown) => void} option - Set a config option.
13419
+ * @property {(fn: (...args: unknown[]) => unknown) => void} process - Register the process function.
13420
+ * @property {() => boolean} processBlockGiven - Returns true if a process function has been registered.
13421
+ */
13422
+
13423
+ /**
13424
+ * DSL interface for document processors (Preprocessor, TreeProcessor, Postprocessor, DocinfoProcessor).
13425
+ *
13426
+ * @typedef {ProcessorDslInterface & { prefer(): void; prepend(): void }} DocumentProcessorDslInterface
13427
+ */
13428
+
13429
+ /**
13430
+ * DSL interface for syntax processors (BlockProcessor, BlockMacroProcessor, InlineMacroProcessor).
13431
+ *
13432
+ * @typedef {ProcessorDslInterface & {
13433
+ * named(value: string): void;
13434
+ * contentModel(value: string): void;
13435
+ * parseContentAs(value: string): void;
13436
+ * positionalAttributes(...value: string[]): void;
13437
+ * namePositionalAttributes(...value: string[]): void;
13438
+ * positionalAttrs(...value: string[]): void;
13439
+ * defaultAttributes(value: Record<string, string>): void;
13440
+ * defaultAttrs(value: Record<string, string>): void;
13441
+ * resolveAttributes(...args: unknown[]): void;
13442
+ * resolvesAttributes(...args: unknown[]): void;
13443
+ * }} SyntaxProcessorDslInterface
13444
+ */
13445
+
13446
+ /**
13447
+ * DSL interface for include processors.
13448
+ *
13449
+ * @typedef {DocumentProcessorDslInterface & {
13450
+ * handles(fn: (doc: Document, target: string) => boolean): void;
13451
+ * }} IncludeProcessorDslInterface
13452
+ */
13453
+
13454
+ /**
13455
+ * DSL interface for docinfo processors.
13456
+ *
13457
+ * @typedef {DocumentProcessorDslInterface & {
13458
+ * atLocation(value: string): void;
13459
+ * }} DocinfoProcessorDslInterface
13460
+ */
13461
+
13462
+ /**
13463
+ * DSL interface for block processors.
13464
+ *
13465
+ * @typedef {SyntaxProcessorDslInterface & {
13466
+ * contexts(...value: (string | string[])[]): void;
13467
+ * onContexts(...value: (string | string[])[]): void;
13468
+ * onContext(...value: (string | string[])[]): void;
13469
+ * bindTo(...value: (string | string[])[]): void;
13470
+ * }} BlockProcessorDslInterface
13471
+ */
13472
+
13473
+ /**
13474
+ * DSL interface for macro processors (block and inline macros).
13475
+ *
13476
+ * @typedef {SyntaxProcessorDslInterface} MacroProcessorDslInterface
13477
+ */
13478
+
13479
+ /**
13480
+ * DSL interface for inline macro processors.
13481
+ *
13482
+ * @typedef {MacroProcessorDslInterface & {
13483
+ * format(value: string): void;
13484
+ * matchFormat(value: string): void;
13485
+ * usingFormat(value: string): void;
13486
+ * match(value: RegExp): void;
13487
+ * }} InlineMacroProcessorDslInterface
13488
+ */
13489
+
13169
13490
  // ── DSL Mixins ────────────────────────────────────────────────────────────────
13170
13491
 
13171
13492
  /**
@@ -13761,7 +14082,12 @@ class Processor {
13761
14082
  * Extensions.register(function () { this.preprocessor(CommentStripPreprocessor) })
13762
14083
  */
13763
14084
  class Preprocessor extends Processor {
13764
- process(_document, _reader) {
14085
+ /**
14086
+ * @param {Document} document - The document being parsed.
14087
+ * @param {Reader} reader - The reader positioned at the beginning of the source.
14088
+ * @returns {Reader|undefined} The same or a substitute Reader, or undefined to use the original.
14089
+ */
14090
+ process(document, reader) {
13765
14091
  throw new Error(
13766
14092
  `${this.constructor.name} must implement the process method`
13767
14093
  )
@@ -13786,7 +14112,11 @@ Preprocessor.DSL = DocumentProcessorDsl;
13786
14112
  * Extensions.register(function () { this.treeProcessor(ShoutTreeProcessor) })
13787
14113
  */
13788
14114
  class TreeProcessor extends Processor {
13789
- process(_document) {
14115
+ /**
14116
+ * @param {Document} document - The parsed document.
14117
+ * @returns {void}
14118
+ */
14119
+ process(document) {
13790
14120
  throw new Error(
13791
14121
  `${this.constructor.name} must implement the process method`
13792
14122
  )
@@ -13812,7 +14142,12 @@ TreeProcessor.DSL = DocumentProcessorDsl;
13812
14142
  * Extensions.register(function () { this.postprocessor(FooterPostprocessor) })
13813
14143
  */
13814
14144
  class Postprocessor extends Processor {
13815
- process(_document, _output) {
14145
+ /**
14146
+ * @param {Document} document - The converted document.
14147
+ * @param {string} output - The converted output string.
14148
+ * @returns {string} The (possibly modified) output string.
14149
+ */
14150
+ process(document, output) {
13816
14151
  throw new Error(
13817
14152
  `${this.constructor.name} must implement the process method`
13818
14153
  )
@@ -13826,13 +14161,25 @@ Postprocessor.DSL = DocumentProcessorDsl;
13826
14161
  * Implementations must extend IncludeProcessor.
13827
14162
  */
13828
14163
  class IncludeProcessor extends Processor {
13829
- process(_document, _reader, _target, _attributes) {
14164
+ /**
14165
+ * @param {Document} document - The document being parsed.
14166
+ * @param {Reader} reader - The reader for the including document.
14167
+ * @param {string} target - The target of the include directive.
14168
+ * @param {Record<string, string>} attributes - The parsed include attributes.
14169
+ * @returns {void}
14170
+ */
14171
+ process(document, reader, target, attributes) {
13830
14172
  throw new Error(
13831
14173
  `${this.constructor.name} must implement the process method`
13832
14174
  )
13833
14175
  }
13834
14176
 
13835
- handles(_doc, _target) {
14177
+ /**
14178
+ * @param {Document} doc - The document being parsed.
14179
+ * @param {string} target - The target of the include directive.
14180
+ * @returns {boolean} true if this processor handles the given target.
14181
+ */
14182
+ handles(doc, target) {
13836
14183
  return true
13837
14184
  }
13838
14185
  }
@@ -13850,7 +14197,11 @@ class DocinfoProcessor extends Processor {
13850
14197
  this.config.location ??= 'head';
13851
14198
  }
13852
14199
 
13853
- process(_document) {
14200
+ /**
14201
+ * @param {Document} document - The document being converted.
14202
+ * @returns {string} The docinfo content to inject into the document.
14203
+ */
14204
+ process(document) {
13854
14205
  throw new Error(
13855
14206
  `${this.constructor.name} must implement the process method`
13856
14207
  )
@@ -13906,7 +14257,13 @@ class BlockProcessor extends Processor {
13906
14257
  this.config.content_model ??= 'compound';
13907
14258
  }
13908
14259
 
13909
- process(_parent, _reader, _attributes) {
14260
+ /**
14261
+ * @param {AbstractBlock} parent - The enclosing block.
14262
+ * @param {Reader} reader - The reader positioned at the block content.
14263
+ * @param {Record<string, unknown>} attributes - The parsed block attributes.
14264
+ * @returns {Block|void} A block node, or void to let the parser handle it.
14265
+ */
14266
+ process(parent, reader, attributes) {
13910
14267
  throw new Error(
13911
14268
  `${this.constructor.name} must implement the process method`
13912
14269
  )
@@ -13924,7 +14281,13 @@ class MacroProcessor extends Processor {
13924
14281
  this.config.content_model ??= 'attributes';
13925
14282
  }
13926
14283
 
13927
- process(_parent, _target, _attributes) {
14284
+ /**
14285
+ * @param {AbstractBlock} parent - The enclosing block.
14286
+ * @param {string} target - The macro target (text between `name:` and `[`).
14287
+ * @param {Record<string, unknown>} attributes - The parsed macro attributes.
14288
+ * @returns {Block|Inline|void}
14289
+ */
14290
+ process(parent, target, attributes) {
13928
14291
  throw new Error(
13929
14292
  `${this.constructor.name} must implement the process method`
13930
14293
  )
@@ -13970,6 +14333,16 @@ class BlockMacroProcessor extends MacroProcessor {
13970
14333
  set name(value) {
13971
14334
  this._name = value;
13972
14335
  }
14336
+
14337
+ /**
14338
+ * @param {AbstractBlock} parent - The enclosing block.
14339
+ * @param {string} target - The macro target.
14340
+ * @param {Record<string, unknown>} attributes - The parsed macro attributes.
14341
+ * @returns {Block} A block node created with one of the `createBlock` helpers.
14342
+ */
14343
+ process(parent, target, attributes) {
14344
+ return super.process(parent, target, attributes)
14345
+ }
13973
14346
  }
13974
14347
  BlockMacroProcessor.DSL = MacroProcessorDsl;
13975
14348
 
@@ -14013,6 +14386,16 @@ class InlineMacroProcessor extends MacroProcessor {
14013
14386
  ))
14014
14387
  }
14015
14388
 
14389
+ /**
14390
+ * @param {AbstractBlock} parent - The enclosing block.
14391
+ * @param {string} target - The macro target.
14392
+ * @param {Record<string, unknown>} attributes - The parsed macro attributes.
14393
+ * @returns {Inline} An Inline node created with `this.createInline(...)`.
14394
+ */
14395
+ process(parent, target, attributes) {
14396
+ return super.process(parent, target, attributes)
14397
+ }
14398
+
14016
14399
  resolveRegexp(name, format) {
14017
14400
  if (!MacroNameRx.test(name)) {
14018
14401
  throw new Error(`invalid name for inline macro: ${name}`)
@@ -14376,6 +14759,15 @@ class Registry {
14376
14759
  return !!this._block_extensions
14377
14760
  }
14378
14761
 
14762
+ /**
14763
+ * Retrieve all BlockProcessor Extension proxy objects.
14764
+ *
14765
+ * @returns {ProcessorExtension[]}
14766
+ */
14767
+ blocks() {
14768
+ return this._block_extensions ? Object.values(this._block_extensions) : []
14769
+ }
14770
+
14379
14771
  /**
14380
14772
  * Check whether a BlockProcessor is registered for the given name and context.
14381
14773
  *
@@ -14422,6 +14814,17 @@ class Registry {
14422
14814
  return !!this._block_macro_extensions
14423
14815
  }
14424
14816
 
14817
+ /**
14818
+ * Retrieve all BlockMacroProcessor Extension proxy objects.
14819
+ *
14820
+ * @returns {ProcessorExtension[]}
14821
+ */
14822
+ blockMacros() {
14823
+ return this._block_macro_extensions
14824
+ ? Object.values(this._block_macro_extensions)
14825
+ : []
14826
+ }
14827
+
14425
14828
  /**
14426
14829
  * Check whether a BlockMacroProcessor is registered for the given name.
14427
14830
  *
@@ -14527,6 +14930,85 @@ class Registry {
14527
14930
  return extension
14528
14931
  }
14529
14932
 
14933
+ // ── JavaScript-style accessors ───────────────────────────────────────────────
14934
+
14935
+ /** @returns {object} the plain Object that maps names to groups for this registry. */
14936
+ getGroups() {
14937
+ return this.groups
14938
+ }
14939
+
14940
+ /** Alias for {@link preprocessors}. */
14941
+ getPreprocessors() {
14942
+ return this.preprocessors()
14943
+ }
14944
+
14945
+ /** Alias for {@link treeProcessors}. */
14946
+ getTreeProcessors() {
14947
+ return this.treeProcessors()
14948
+ }
14949
+
14950
+ /** Alias for {@link includeProcessors}. */
14951
+ getIncludeProcessors() {
14952
+ return this.includeProcessors()
14953
+ }
14954
+
14955
+ /** Alias for {@link postprocessors}. */
14956
+ getPostprocessors() {
14957
+ return this.postprocessors()
14958
+ }
14959
+
14960
+ /**
14961
+ * Alias for {@link docinfoProcessors}.
14962
+ *
14963
+ * @param {string|null} [location=null]
14964
+ */
14965
+ getDocinfoProcessors(location = null) {
14966
+ return this.docinfoProcessors(location)
14967
+ }
14968
+
14969
+ /** Alias for {@link blocks}. */
14970
+ getBlocks() {
14971
+ return this.blocks()
14972
+ }
14973
+
14974
+ /** Alias for {@link blockMacros}. */
14975
+ getBlockMacros() {
14976
+ return this.blockMacros()
14977
+ }
14978
+
14979
+ /** Alias for {@link inlineMacros}. */
14980
+ getInlineMacros() {
14981
+ return this.inlineMacros()
14982
+ }
14983
+
14984
+ /**
14985
+ * Alias for {@link registeredForInlineMacro}.
14986
+ *
14987
+ * @param {string} name
14988
+ */
14989
+ getInlineMacroFor(name) {
14990
+ return this.registeredForInlineMacro(name)
14991
+ }
14992
+
14993
+ /**
14994
+ * Alias for {@link registeredForBlock}.
14995
+ *
14996
+ * @param {string} name
14997
+ * @param {string} context
14998
+ */
14999
+ getBlockFor(name, context) {
15000
+ return this.registeredForBlock(name, context)
15001
+ }
15002
+
15003
+ /**
15004
+ * Alias for {@link registeredForBlockMacro}.
15005
+ *
15006
+ * @param {string} name
15007
+ */
15008
+ getBlockMacroFor(name) {
15009
+ return this.registeredForBlockMacro(name)
15010
+ }
15011
+
14530
15012
  // ── Private helpers ──────────────────────────────────────────────────────────
14531
15013
 
14532
15014
  /** @internal */
@@ -14752,6 +15234,15 @@ const Extensions = {
14752
15234
  return _groups
14753
15235
  },
14754
15236
 
15237
+ /**
15238
+ * Alias for {@link groups}.
15239
+ *
15240
+ * @returns {object}
15241
+ */
15242
+ getGroups() {
15243
+ return this.groups()
15244
+ },
15245
+
14755
15246
  /**
14756
15247
  * Create a new Registry, optionally pre-populated with a named block.
14757
15248
  *
@@ -15979,8 +16470,9 @@ class Document extends AbstractBlock {
15979
16470
  * @param {Object} blockAttributes
15980
16471
  */
15981
16472
  playbackAttributes(blockAttributes) {
15982
- if (!('attribute_entries' in blockAttributes)) return
15983
- for (const entry of blockAttributes.attribute_entries) {
16473
+ const entries = getAttributeEntries(blockAttributes);
16474
+ if (!entries) return
16475
+ for (const entry of entries) {
15984
16476
  if (entry.negate) {
15985
16477
  delete this.attributes[entry.name];
15986
16478
  if (entry.name === 'compat-mode') this.compatMode = false;
@@ -16709,6 +17201,12 @@ class Document extends AbstractBlock {
16709
17201
  * Handles titles (AbstractBlock), list item text, table cell text, and reftexts.
16710
17202
  */
16711
17203
  async _resolveAllTexts(block) {
17204
+ // The header section lives outside document.blocks; pre-compute its title here so
17205
+ // that doc.doctitle() returns the fully-substituted title (with replacements applied,
17206
+ // e.g. ' → &#8217;) rather than the header-subs-only fallback.
17207
+ if (block === this && this.header) {
17208
+ await this.header.precomputeTitle?.();
17209
+ }
16712
17210
  // Skip title pre-computation for blocks with an explicit empty id ([id=]).
16713
17211
  // In Ruby, apply_title_subs is lazy: it is never called during parsing for such
16714
17212
  // blocks because section.title is never accessed. An explicit empty id is
@@ -16792,7 +17290,7 @@ class Document extends AbstractBlock {
16792
17290
  * @internal
16793
17291
  */
16794
17292
  _clearPlaybackAttributes(attributes) {
16795
- delete attributes.attribute_entries;
17293
+ delete attributes[ATTR_ENTRIES_KEY];
16796
17294
  }
16797
17295
 
16798
17296
  /**
@@ -17132,11 +17630,10 @@ class Document extends AbstractBlock {
17132
17630
  // ── Helpers ───────────────────────────────────────────────────────────────────
17133
17631
 
17134
17632
  function _expandPath(p) {
17135
- try {
17136
- return require('node:path').resolve(p)
17137
- } catch {
17138
- return p
17139
- }
17633
+ const resolver = new PathResolver();
17634
+ const posixed = p.replace(/\\/g, '/');
17635
+ if (resolver.absolutePath(posixed)) return resolver.expandPath(posixed)
17636
+ return resolver.expandPath(`${resolver.workingDir}/${posixed}`)
17140
17637
  }
17141
17638
 
17142
17639
  function _cwd() {
@@ -19520,17 +20017,23 @@ async function load$1(input, options = {}) {
19520
20017
  // Shallow-copy options so we don't mutate the caller's object.
19521
20018
  options = Object.assign({}, options);
19522
20019
 
19523
- const timings = options.timings ?? null;
19524
- if (timings) timings.start('read');
19525
-
19526
20020
  // ── Logger override ───────────────────────────────────────────────────────
20021
+ // When a logger option is supplied, run the conversion in an async-local
20022
+ // context so the logger is scoped to this call only — no global mutation,
20023
+ // which makes concurrent callers (e.g. parallel Deno tests) safe.
19527
20024
  if ('logger' in options) {
19528
- const logger = options.logger;
19529
- if (logger !== LoggerManager.logger) {
19530
- LoggerManager.logger = logger ?? new NullLogger();
19531
- }
20025
+ const newLogger = options.logger ?? new NullLogger();
20026
+ delete options.logger;
20027
+ return withLogger(newLogger, () => _doLoad(input, options, newLogger))
19532
20028
  }
19533
20029
 
20030
+ return _doLoad(input, options)
20031
+ }
20032
+
20033
+ async function _doLoad(input, options, explicitLogger = null) {
20034
+ const timings = options.timings ?? null;
20035
+ if (timings) timings.start('read');
20036
+
19534
20037
  // ── Attributes normalisation ──────────────────────────────────────────────
19535
20038
  let attrs = options.attributes;
19536
20039
  if (!attrs) {
@@ -19562,11 +20065,9 @@ async function load$1(input, options = {}) {
19562
20065
  attrs.docname = basename(inputPath, docfilesuffix);
19563
20066
  }
19564
20067
  source = await _readStream(input);
19565
- } else if (
19566
- typeof input === 'object' &&
19567
- input?.constructor?.name === 'Buffer'
19568
- ) {
19569
- source = input.toString('utf8');
20068
+ } else if (input instanceof Uint8Array) {
20069
+ // Covers both Node.js Buffer (a Uint8Array subclass) and browser Uint8Array shims.
20070
+ source = new TextDecoder('utf-8').decode(input);
19570
20071
  } else if (typeof input === 'string') {
19571
20072
  source = input;
19572
20073
  } else if (Array.isArray(input)) {
@@ -19629,6 +20130,19 @@ async function load$1(input, options = {}) {
19629
20130
  }
19630
20131
 
19631
20132
  if (timings) timings.record('parse');
20133
+
20134
+ // Persist the logger on the Document instance so that doc.convert()
20135
+ // (called by convert.js after the async-local context ends) still routes
20136
+ // logging through the caller-supplied logger.
20137
+ // ALS provides it in Node.js/Deno; the explicit parameter covers browser fallback.
20138
+ const contextLogger = getContextLogger() ?? explicitLogger;
20139
+ if (contextLogger) {
20140
+ Object.defineProperty(doc, 'logger', {
20141
+ get: () => contextLogger,
20142
+ configurable: true,
20143
+ });
20144
+ }
20145
+
19632
20146
  return doc
19633
20147
  }
19634
20148
 
@@ -19704,6 +20218,54 @@ async function _requirePath$1() {
19704
20218
  return import('node:path')
19705
20219
  }
19706
20220
 
20221
+ // Auto-generated from data/asciidoctor-default.css — run 'npm run build:data' to update
20222
+ const defaultStylesheetData = "/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */\n/* Uncomment the following line when using as a custom stylesheet */\n/* @import \"https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700\"; */\nhtml{font-family:sans-serif;-webkit-text-size-adjust:100%}\na{background:none}\na:focus{outline:thin dotted}\na:active,a:hover{outline:0}\nh1{font-size:2em;margin:.67em 0}\nb,strong{font-weight:bold}\nabbr{font-size:.9em}\nabbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}\ndfn{font-style:italic}\nhr{height:0}\nmark{background:#ff0;color:#000}\ncode,kbd,pre,samp{font-family:monospace;font-size:1em}\npre{white-space:pre-wrap}\nq{quotes:\"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\"}\nsmall{font-size:80%}\nsub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}\nsup{top:-.5em}\nsub{bottom:-.25em}\nimg{border:0}\nsvg:not(:root){overflow:hidden}\nfigure{margin:0}\naudio,video{display:inline-block}\naudio:not([controls]){display:none;height:0}\nfieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}\nlegend{border:0;padding:0}\nbutton,input,select,textarea{font-family:inherit;font-size:100%;margin:0}\nbutton,input{line-height:normal}\nbutton,select{text-transform:none}\nbutton,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}\nbutton[disabled],html input[disabled]{cursor:default}\ninput[type=checkbox],input[type=radio]{padding:0}\nbutton::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}\ntextarea{overflow:auto;vertical-align:top}\ntable{border-collapse:collapse;border-spacing:0}\n*,::before,::after{box-sizing:border-box}\nhtml,body{font-size:100%}\nbody{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:\"Noto Serif\",\"DejaVu Serif\",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}\na:hover{cursor:pointer}\nimg,object,embed{max-width:100%;height:auto}\nobject,embed{height:100%}\nimg{-ms-interpolation-mode:bicubic}\n.left{float:left!important}\n.right{float:right!important}\n.text-left{text-align:left!important}\n.text-right{text-align:right!important}\n.text-center{text-align:center!important}\n.text-justify{text-align:justify!important}\n.hide{display:none}\nimg,object,svg{display:inline-block;vertical-align:middle}\ntextarea{height:auto;min-height:50px}\nselect{width:100%}\n.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}\ndiv,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}\na{color:#2156a5;text-decoration:underline;line-height:inherit}\na:hover,a:focus{color:#1d4b8f}\na img{border:0}\np{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}\np aside{font-size:.875em;line-height:1.35;font-style:italic}\nh1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}\nh1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}\nh1{font-size:2.125em}\nh2{font-size:1.6875em}\nh3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}\nh4,h5{font-size:1.125em}\nh6{font-size:1em}\nhr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}\nem,i{font-style:italic;line-height:inherit}\nstrong,b{font-weight:bold;line-height:inherit}\nsmall{font-size:60%;line-height:inherit}\ncode{font-family:\"Droid Sans Mono\",\"DejaVu Sans Mono\",monospace;font-weight:400;color:rgba(0,0,0,.9)}\nul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}\nul,ol{margin-left:1.5em}\nul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}\nul.circle{list-style-type:circle}\nul.disc{list-style-type:disc}\nul.square{list-style-type:square}\nul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}\nol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}\ndl dt{margin-bottom:.3125em;font-weight:bold}\ndl dd{margin-bottom:1.25em}\nblockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}\nblockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}\n@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}\n h1{font-size:2.75em}\n h2{font-size:2.3125em}\n h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}\n h4{font-size:1.4375em}}\ntable{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}\ntable thead,table tfoot{background:#f7f8f7}\ntable thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}\ntable tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}\ntable tr.even,table tr.alt{background:#f8f8f7}\ntable thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}\nh1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}\nh1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}\n.center{margin-left:auto;margin-right:auto}\n.stretch{width:100%}\n.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:\" \";display:table}\n.clearfix::after,.float-group::after{clear:both}\n:not(pre).nobreak{word-wrap:normal}\n:not(pre).nowrap{white-space:nowrap}\n:not(pre).pre-wrap{white-space:pre-wrap}\n:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}\npre{color:rgba(0,0,0,.9);font-family:\"Droid Sans Mono\",\"DejaVu Sans Mono\",monospace;line-height:1.45;text-rendering:optimizeSpeed}\npre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}\npre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}\nem em{font-style:normal}\nstrong strong{font-weight:400}\n.keyseq{color:rgba(51,51,51,.8)}\nkbd{font-family:\"Droid Sans Mono\",\"DejaVu Sans Mono\",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}\n.keyseq kbd:first-child{margin-left:0}\n.keyseq kbd:last-child{margin-right:0}\n.menuseq,.menuref{color:#000}\n.menuseq b:not(.caret),.menuref{font-weight:inherit}\n.menuseq{word-spacing:-.02em}\n.menuseq b.caret{font-size:1.25em;line-height:.8}\n.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}\nb.button::before,b.button::after{position:relative;top:-1px;font-weight:400}\nb.button::before{content:\"[\";padding:0 3px 0 2px}\nb.button::after{content:\"]\";padding:0 2px 0 3px}\np a>code:hover{color:rgba(0,0,0,.9)}\n#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}\n#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:\" \";display:table}\n#header::after,#content::after,#footnotes::after,#footer::after{clear:both}\n#content{margin-top:1.25em}\n#content::before{content:none}\n#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}\n#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}\n#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}\n#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}\n#header .details span:first-child{margin-left:-.125em}\n#header .details span.email a{color:rgba(0,0,0,.85)}\n#header .details br{display:none}\n#header .details br+span::before{content:\"\\00a0\\2013\\00a0\"}\n#header .details br+span.author::before{content:\"\\00a0\\22c5\\00a0\";color:rgba(0,0,0,.85)}\n#header .details br+span#revremark::before{content:\"\\00a0|\\00a0\"}\n#header #revnumber{text-transform:capitalize}\n#header #revnumber::after{content:\"\\00a0\"}\n#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}\n#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}\n#toc>ul{margin-left:.125em}\n#toc ul.sectlevel0>li>a{font-style:italic}\n#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}\n#toc ul{font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;list-style-type:none}\n#toc li{line-height:1.3334;margin-top:.3334em}\n#toc a{text-decoration:none}\n#toc a:active{text-decoration:underline}\n#toctitle{color:#7a2518;font-size:1.2em}\n@media screen and (min-width:768px){#toctitle{font-size:1.375em}\n body.toc2{padding-left:15em;padding-right:0}\n body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}\n #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}\n #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}\n #toc.toc2>ul{font-size:.9em;margin-bottom:0}\n #toc.toc2 ul ul{margin-left:0;padding-left:1em}\n #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}\n body.toc2.toc-right{padding-left:0;padding-right:15em}\n body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}\n@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}\n #toc.toc2{width:20em}\n #toc.toc2 #toctitle{font-size:1.375em}\n #toc.toc2>ul{font-size:.95em}\n #toc.toc2 ul ul{padding-left:1.25em}\n body.toc2.toc-right{padding-left:0;padding-right:20em}}\n#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}\n#content #toc>:first-child{margin-top:0}\n#content #toc>:last-child{margin-bottom:0}\n#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}\n#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}\n#content{margin-bottom:.625em}\n.sect1{padding-bottom:.625em}\n@media screen and (min-width:768px){#content{margin-bottom:1.25em}\n .sect1{padding-bottom:1.25em}}\n.sect1:last-child{padding-bottom:0}\n.sect1+.sect1{border-top:1px solid #e7e7e9}\n#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}\n#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:\"\\00A7\";font-size:.85em;display:block;padding-top:.1em}\n#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}\n#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}\n#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}\ndetails,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}\ndetails{margin-left:1.25rem}\ndetails>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}\ndetails>summary::-webkit-details-marker{display:none}\ndetails>summary::before{content:\"\";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}\ndetails[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}\ndetails>summary::after{content:\"\";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}\n.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:\"Noto Serif\",\"DejaVu Serif\",serif;font-size:1rem;font-style:italic}\ntable.tableblock.fit-content>caption.title{white-space:nowrap;width:0}\n.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}\n.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}\n.admonitionblock>table td.icon{text-align:center;width:80px}\n.admonitionblock>table td.icon img{max-width:none}\n.admonitionblock>table td.icon .title{font-weight:bold;font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;text-transform:uppercase}\n.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}\n.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}\n.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}\n.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}\n.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}\n.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}\n.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}\n.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}\n@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}\n@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}\n.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^=\"highlight \"]{background:#f7f7f8}\n.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}\n.listingblock>.content{position:relative}\n.listingblock pre>code{display:block}\n.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}\n.listingblock:hover code[data-lang]::before{display:block}\n.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}\n.listingblock.terminal pre .command:not([data-prompt])::before{content:\"$\"}\n.listingblock pre.highlightjs{padding:0}\n.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}\n.listingblock pre.prettyprint{border-width:0}\n.prettyprint{background:#f7f7f8}\npre.prettyprint .linenums{line-height:1.45;margin-left:2em}\npre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}\npre.prettyprint li code[data-lang]::before{opacity:1}\npre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}\ntable.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}\ntable.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}\ntable.linenotable td.code{padding-left:.75em}\ntable.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}\npre.pygments span.linenos{display:inline-block;margin-right:.75em}\n.quoteblock{margin:0 1em 1.25em 1.5em;display:table}\n.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}\n.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}\n.quoteblock blockquote{margin:0;padding:0;border:0}\n.quoteblock blockquote::before{content:\"\\201c\";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}\n.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}\n.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}\n.verseblock{margin:0 1em 1.25em}\n.verseblock pre{font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}\n.verseblock pre strong{font-weight:400}\n.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}\n.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}\n.quoteblock .attribution br,.verseblock .attribution br{display:none}\n.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}\n.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}\n.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}\n.quoteblock.abstract{margin:0 1em 1.25em;display:block}\n.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}\n.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}\n.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}\n.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}\n.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}\np.tableblock:last-child{margin-bottom:0}\ntd.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}\ntd.tableblock>.content>:last-child{margin-bottom:-1.25em}\ntable.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}\ntable.grid-all>*>tr>*{border-width:1px}\ntable.grid-cols>*>tr>*{border-width:0 1px}\ntable.grid-rows>*>tr>*{border-width:1px 0}\ntable.frame-all{border-width:1px}\ntable.frame-ends{border-width:1px 0}\ntable.frame-sides{border-width:0 1px}\ntable.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}\ntable.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}\ntable.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}\ntable.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}\ntable.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}\nth.halign-left,td.halign-left{text-align:left}\nth.halign-right,td.halign-right{text-align:right}\nth.halign-center,td.halign-center{text-align:center}\nth.valign-top,td.valign-top{vertical-align:top}\nth.valign-bottom,td.valign-bottom{vertical-align:bottom}\nth.valign-middle,td.valign-middle{vertical-align:middle}\ntable thead th,table tfoot th{font-weight:bold}\ntbody tr th{background:#f7f8f7}\ntbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}\np.tableblock>code:only-child{background:none;padding:0}\np.tableblock{font-size:1em}\nol{margin-left:1.75em}\nul li ol{margin-left:1.5em}\ndl dd{margin-left:1.125em}\ndl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}\nli p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}\nul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}\nul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}\nul.unstyled,ol.unstyled{margin-left:0}\nli>p:empty:only-child::before{content:\"\";display:inline-block}\nul.checklist>li>p:first-child{margin-left:-1em}\nul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}\nul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}\nul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}\nul.inline>li{margin-left:1.25em}\n.unstyled dl dt{font-weight:400;font-style:normal}\nol.arabic{list-style-type:decimal}\nol.decimal{list-style-type:decimal-leading-zero}\nol.loweralpha{list-style-type:lower-alpha}\nol.upperalpha{list-style-type:upper-alpha}\nol.lowerroman{list-style-type:lower-roman}\nol.upperroman{list-style-type:upper-roman}\nol.lowergreek{list-style-type:lower-greek}\n.hdlist>table,.colist>table{border:0;background:none}\n.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}\ntd.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}\ntd.hdlist1{font-weight:bold;padding-bottom:1.25em}\ntd.hdlist2{word-wrap:anywhere}\n.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}\n.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}\n.colist td:not([class]):first-child img{max-width:none}\n.colist td:not([class]):last-child{padding:.25em 0}\n.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}\n.imageblock.left{margin:.25em .625em 1.25em 0}\n.imageblock.right{margin:.25em 0 1.25em .625em}\n.imageblock>.title{margin-bottom:0}\n.imageblock.thumb,.imageblock.th{border-width:6px}\n.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}\n.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}\n.image.left{margin-right:.625em}\n.image.right{margin-left:.625em}\na.image{text-decoration:none;display:inline-block}\na.image object{pointer-events:none}\nsup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}\nsup.footnote a,sup.footnoteref a{text-decoration:none}\nsup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}\n#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}\n#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}\n#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}\n#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}\n#footnotes .footnote:last-of-type{margin-bottom:0}\n#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}\ndiv.unbreakable{page-break-inside:avoid}\n.big{font-size:larger}\n.small{font-size:smaller}\n.underline{text-decoration:underline}\n.overline{text-decoration:overline}\n.line-through{text-decoration:line-through}\n.aqua{color:#00bfbf}\n.aqua-background{background:#00fafa}\n.black{color:#000}\n.black-background{background:#000}\n.blue{color:#0000bf}\n.blue-background{background:#0000fa}\n.fuchsia{color:#bf00bf}\n.fuchsia-background{background:#fa00fa}\n.gray{color:#606060}\n.gray-background{background:#7d7d7d}\n.green{color:#006000}\n.green-background{background:#007d00}\n.lime{color:#00bf00}\n.lime-background{background:#00fa00}\n.maroon{color:#600000}\n.maroon-background{background:#7d0000}\n.navy{color:#000060}\n.navy-background{background:#00007d}\n.olive{color:#606000}\n.olive-background{background:#7d7d00}\n.purple{color:#600060}\n.purple-background{background:#7d007d}\n.red{color:#bf0000}\n.red-background{background:#fa0000}\n.silver{color:#909090}\n.silver-background{background:#bcbcbc}\n.teal{color:#006060}\n.teal-background{background:#007d7d}\n.white{color:#bfbfbf}\n.white-background{background:#fafafa}\n.yellow{color:#bfbf00}\n.yellow-background{background:#fafa00}\nspan.icon>.fa{cursor:default}\na span.icon>.fa{cursor:inherit}\n.admonitionblock td.icon [class^=\"fa icon-\"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}\n.admonitionblock td.icon .icon-note::before{content:\"\\f05a\";color:#19407c}\n.admonitionblock td.icon .icon-tip::before{content:\"\\f0eb\";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}\n.admonitionblock td.icon .icon-warning::before{content:\"\\f071\";color:#bf6900}\n.admonitionblock td.icon .icon-caution::before{content:\"\\f06d\";color:#bf3400}\n.admonitionblock td.icon .icon-important::before{content:\"\\f06a\";color:#bf0000}\n.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;font-style:normal;font-weight:bold}\n.conum[data-value] *{color:#fff!important}\n.conum[data-value]+b{display:none}\n.conum[data-value]::after{content:attr(data-value)}\npre .conum[data-value]{position:relative;top:-.125em}\nb.conum *{color:inherit!important}\n.conum:not([data-value]):empty{display:none}\ndt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}\nh1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}\np strong,td.content strong,div.footnote strong{letter-spacing:-.005em}\np,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}\np{margin-bottom:1.25rem}\n.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}\n.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}\n.print-only{display:none!important}\n@page{margin:1.25cm .75cm}\n@media print{*{box-shadow:none!important;text-shadow:none!important}\n html{font-size:80%}\n a{color:inherit!important;text-decoration:underline!important}\n a.bare,a[href^=\"#\"],a[href^=\"mailto:\"]{text-decoration:none!important}\n a[href^=\"http:\"]:not(.bare)::after,a[href^=\"https:\"]:not(.bare)::after{content:\"(\" attr(href) \")\";display:inline-block;font-size:.875em;padding-left:.25em}\n abbr[title]{border-bottom:1px dotted}\n abbr[title]::after{content:\" (\" attr(title) \")\"}\n pre,blockquote,tr,img,object,svg{page-break-inside:avoid}\n thead{display:table-header-group}\n svg{max-width:100%}\n p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}\n h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}\n #header,#content,#footnotes,#footer{max-width:none}\n #toc,.sidebarblock,.exampleblock>.content{background:none!important}\n #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}\n body.book #header{text-align:center}\n body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}\n body.book #header .details{border:0!important;display:block;padding:0!important}\n body.book #header .details span:first-child{margin-left:0!important}\n body.book #header .details br{display:block}\n body.book #header .details br+span::before{content:none!important}\n body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}\n body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}\n .listingblock code[data-lang]::before{display:block}\n #footer{padding:0 .9375em}\n .hide-on-print{display:none!important}\n .print-only{display:block!important}\n .hide-for-print{display:none!important}\n .show-for-print{display:inherit!important}}\n@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}\n .sect1{padding:0!important}\n .sect1+.sect1{border:0}\n #footer{background:none}\n #footer-text{color:rgba(0,0,0,.6);font-size:.9em}}\n@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}";
20223
+
20224
+ // ESM port of lib/asciidoctor/stylesheets.rb
20225
+ //
20226
+ // Ruby-to-JavaScript notes:
20227
+ // - Singleton: Ruby @__instance__ = new → module-level instance exported as Stylesheets.instance
20228
+ // - primary_stylesheet_data memoisation: Ruby ||= → the CSS is a static import; no lazy load needed
20229
+ // - File.read(...).rstrip → CSS is inlined at build time in src/data/stylesheet-data.js
20230
+ // - STYLESHEETS_DIR = File.join(DATA_DIR, 'stylesheets') → not needed; CSS is a JS module
20231
+ // - coderay / pygments methods → omitted (SyntaxHighlighter.for not needed here)
20232
+
20233
+
20234
+ class StylesheetsClass {
20235
+ static DEFAULT_STYLESHEET_NAME = 'asciidoctor.css'
20236
+
20237
+ get primaryStylesheetName() {
20238
+ return StylesheetsClass.DEFAULT_STYLESHEET_NAME
20239
+ }
20240
+
20241
+ async primaryStylesheetData() {
20242
+ return defaultStylesheetData
20243
+ }
20244
+
20245
+ async embedPrimaryStylesheet() {
20246
+ return `<style>\n${defaultStylesheetData}\n</style>`
20247
+ }
20248
+
20249
+ async writePrimaryStylesheet(stylesoutdir) {
20250
+ try {
20251
+ const { writeFile } = await import('node:fs/promises');
20252
+ const { join } = await import('node:path');
20253
+ await writeFile(
20254
+ join(stylesoutdir, StylesheetsClass.DEFAULT_STYLESHEET_NAME),
20255
+ defaultStylesheetData,
20256
+ 'utf8'
20257
+ );
20258
+ return true
20259
+ } catch {
20260
+ return false
20261
+ }
20262
+ }
20263
+ }
20264
+
20265
+ const Stylesheets = {
20266
+ instance: new StylesheetsClass(),
20267
+ };
20268
+
19707
20269
  // ESM conversion of convert.rb
19708
20270
  //
19709
20271
  // Ruby-to-JavaScript notes:
@@ -19717,7 +20279,7 @@ async function _requirePath$1() {
19717
20279
  // - Ruby File.write → async writeFile() via node:fs/promises.
19718
20280
  // - Ruby Helpers.mkdir_p → mkdirP() from helpers.js.
19719
20281
  // - Ruby Helpers.uriish? → isUriish() from helpers.js.
19720
- // - Ruby Stylesheets.instance.write_primary_stylesheet → not yet ported to JS; skipped.
20282
+ // - Ruby Stylesheets.instance.write_primary_stylesheet → Stylesheets.instance.writePrimaryStylesheet() in stylesheets.js; returns false in browser environments.
19721
20283
  // - Ruby doc.syntax_highlighter → doc.syntaxHighlighter.
19722
20284
  // - Ruby syntax_hl.write_stylesheet? doc → syntaxHl.writeStylesheet(doc).
19723
20285
  // - Ruby syntax_hl.write_stylesheet doc, dir → syntaxHl.writeStylesheetToDisk(doc, dir).
@@ -19917,7 +20479,7 @@ async function convert(input, options = {}) {
19917
20479
  let copyAsciidoctorStylesheet = false;
19918
20480
  let copyUserStylesheet = false;
19919
20481
  const stylesheet = doc.getAttribute('stylesheet');
19920
- if (stylesheet) {
20482
+ if (stylesheet != null) {
19921
20483
  if (DEFAULT_STYLESHEET_KEYS.has(stylesheet)) {
19922
20484
  copyAsciidoctorStylesheet = true;
19923
20485
  } else if (!isUriish(stylesheet)) {
@@ -19948,7 +20510,15 @@ async function convert(input, options = {}) {
19948
20510
  }
19949
20511
  }
19950
20512
 
19951
- if (copyAsciidoctorStylesheet) ; else if (copyUserStylesheet) {
20513
+ if (copyAsciidoctorStylesheet) {
20514
+ if (
20515
+ !(await Stylesheets.instance.writePrimaryStylesheet(stylesoutdir))
20516
+ ) {
20517
+ doc.logger.info(
20518
+ 'skipping default stylesheet copy: filesystem writes are not supported in this environment'
20519
+ );
20520
+ }
20521
+ } else if (copyUserStylesheet) {
19952
20522
  let stylesheetSrc = doc.getAttribute('copycss');
19953
20523
  if (stylesheetSrc === '' || stylesheetSrc === true) {
19954
20524
  stylesheetSrc = doc.normalizeSystemPath(stylesheet);
@@ -20115,39 +20685,6 @@ class Timings {
20115
20685
  }
20116
20686
  }
20117
20687
 
20118
- // Auto-generated from data/asciidoctor-default.css — run 'npm run build:data' to update
20119
- const defaultStylesheetData = "/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */\n/* Uncomment the following line when using as a custom stylesheet */\n/* @import \"https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700\"; */\nhtml{font-family:sans-serif;-webkit-text-size-adjust:100%}\na{background:none}\na:focus{outline:thin dotted}\na:active,a:hover{outline:0}\nh1{font-size:2em;margin:.67em 0}\nb,strong{font-weight:bold}\nabbr{font-size:.9em}\nabbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}\ndfn{font-style:italic}\nhr{height:0}\nmark{background:#ff0;color:#000}\ncode,kbd,pre,samp{font-family:monospace;font-size:1em}\npre{white-space:pre-wrap}\nq{quotes:\"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\"}\nsmall{font-size:80%}\nsub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}\nsup{top:-.5em}\nsub{bottom:-.25em}\nimg{border:0}\nsvg:not(:root){overflow:hidden}\nfigure{margin:0}\naudio,video{display:inline-block}\naudio:not([controls]){display:none;height:0}\nfieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}\nlegend{border:0;padding:0}\nbutton,input,select,textarea{font-family:inherit;font-size:100%;margin:0}\nbutton,input{line-height:normal}\nbutton,select{text-transform:none}\nbutton,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}\nbutton[disabled],html input[disabled]{cursor:default}\ninput[type=checkbox],input[type=radio]{padding:0}\nbutton::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}\ntextarea{overflow:auto;vertical-align:top}\ntable{border-collapse:collapse;border-spacing:0}\n*,::before,::after{box-sizing:border-box}\nhtml,body{font-size:100%}\nbody{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:\"Noto Serif\",\"DejaVu Serif\",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}\na:hover{cursor:pointer}\nimg,object,embed{max-width:100%;height:auto}\nobject,embed{height:100%}\nimg{-ms-interpolation-mode:bicubic}\n.left{float:left!important}\n.right{float:right!important}\n.text-left{text-align:left!important}\n.text-right{text-align:right!important}\n.text-center{text-align:center!important}\n.text-justify{text-align:justify!important}\n.hide{display:none}\nimg,object,svg{display:inline-block;vertical-align:middle}\ntextarea{height:auto;min-height:50px}\nselect{width:100%}\n.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}\ndiv,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}\na{color:#2156a5;text-decoration:underline;line-height:inherit}\na:hover,a:focus{color:#1d4b8f}\na img{border:0}\np{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}\np aside{font-size:.875em;line-height:1.35;font-style:italic}\nh1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}\nh1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}\nh1{font-size:2.125em}\nh2{font-size:1.6875em}\nh3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}\nh4,h5{font-size:1.125em}\nh6{font-size:1em}\nhr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}\nem,i{font-style:italic;line-height:inherit}\nstrong,b{font-weight:bold;line-height:inherit}\nsmall{font-size:60%;line-height:inherit}\ncode{font-family:\"Droid Sans Mono\",\"DejaVu Sans Mono\",monospace;font-weight:400;color:rgba(0,0,0,.9)}\nul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}\nul,ol{margin-left:1.5em}\nul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}\nul.circle{list-style-type:circle}\nul.disc{list-style-type:disc}\nul.square{list-style-type:square}\nul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}\nol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}\ndl dt{margin-bottom:.3125em;font-weight:bold}\ndl dd{margin-bottom:1.25em}\nblockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}\nblockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}\n@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}\n h1{font-size:2.75em}\n h2{font-size:2.3125em}\n h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}\n h4{font-size:1.4375em}}\ntable{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}\ntable thead,table tfoot{background:#f7f8f7}\ntable thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}\ntable tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}\ntable tr.even,table tr.alt{background:#f8f8f7}\ntable thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}\nh1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}\nh1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}\n.center{margin-left:auto;margin-right:auto}\n.stretch{width:100%}\n.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:\" \";display:table}\n.clearfix::after,.float-group::after{clear:both}\n:not(pre).nobreak{word-wrap:normal}\n:not(pre).nowrap{white-space:nowrap}\n:not(pre).pre-wrap{white-space:pre-wrap}\n:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}\npre{color:rgba(0,0,0,.9);font-family:\"Droid Sans Mono\",\"DejaVu Sans Mono\",monospace;line-height:1.45;text-rendering:optimizeSpeed}\npre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}\npre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}\nem em{font-style:normal}\nstrong strong{font-weight:400}\n.keyseq{color:rgba(51,51,51,.8)}\nkbd{font-family:\"Droid Sans Mono\",\"DejaVu Sans Mono\",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}\n.keyseq kbd:first-child{margin-left:0}\n.keyseq kbd:last-child{margin-right:0}\n.menuseq,.menuref{color:#000}\n.menuseq b:not(.caret),.menuref{font-weight:inherit}\n.menuseq{word-spacing:-.02em}\n.menuseq b.caret{font-size:1.25em;line-height:.8}\n.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}\nb.button::before,b.button::after{position:relative;top:-1px;font-weight:400}\nb.button::before{content:\"[\";padding:0 3px 0 2px}\nb.button::after{content:\"]\";padding:0 2px 0 3px}\np a>code:hover{color:rgba(0,0,0,.9)}\n#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}\n#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:\" \";display:table}\n#header::after,#content::after,#footnotes::after,#footer::after{clear:both}\n#content{margin-top:1.25em}\n#content::before{content:none}\n#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}\n#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}\n#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}\n#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}\n#header .details span:first-child{margin-left:-.125em}\n#header .details span.email a{color:rgba(0,0,0,.85)}\n#header .details br{display:none}\n#header .details br+span::before{content:\"\\00a0\\2013\\00a0\"}\n#header .details br+span.author::before{content:\"\\00a0\\22c5\\00a0\";color:rgba(0,0,0,.85)}\n#header .details br+span#revremark::before{content:\"\\00a0|\\00a0\"}\n#header #revnumber{text-transform:capitalize}\n#header #revnumber::after{content:\"\\00a0\"}\n#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}\n#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}\n#toc>ul{margin-left:.125em}\n#toc ul.sectlevel0>li>a{font-style:italic}\n#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}\n#toc ul{font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;list-style-type:none}\n#toc li{line-height:1.3334;margin-top:.3334em}\n#toc a{text-decoration:none}\n#toc a:active{text-decoration:underline}\n#toctitle{color:#7a2518;font-size:1.2em}\n@media screen and (min-width:768px){#toctitle{font-size:1.375em}\n body.toc2{padding-left:15em;padding-right:0}\n body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}\n #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}\n #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}\n #toc.toc2>ul{font-size:.9em;margin-bottom:0}\n #toc.toc2 ul ul{margin-left:0;padding-left:1em}\n #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}\n body.toc2.toc-right{padding-left:0;padding-right:15em}\n body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}\n@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}\n #toc.toc2{width:20em}\n #toc.toc2 #toctitle{font-size:1.375em}\n #toc.toc2>ul{font-size:.95em}\n #toc.toc2 ul ul{padding-left:1.25em}\n body.toc2.toc-right{padding-left:0;padding-right:20em}}\n#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}\n#content #toc>:first-child{margin-top:0}\n#content #toc>:last-child{margin-bottom:0}\n#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}\n#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}\n#content{margin-bottom:.625em}\n.sect1{padding-bottom:.625em}\n@media screen and (min-width:768px){#content{margin-bottom:1.25em}\n .sect1{padding-bottom:1.25em}}\n.sect1:last-child{padding-bottom:0}\n.sect1+.sect1{border-top:1px solid #e7e7e9}\n#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}\n#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:\"\\00A7\";font-size:.85em;display:block;padding-top:.1em}\n#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}\n#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}\n#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}\ndetails,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}\ndetails{margin-left:1.25rem}\ndetails>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}\ndetails>summary::-webkit-details-marker{display:none}\ndetails>summary::before{content:\"\";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}\ndetails[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}\ndetails>summary::after{content:\"\";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}\n.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:\"Noto Serif\",\"DejaVu Serif\",serif;font-size:1rem;font-style:italic}\ntable.tableblock.fit-content>caption.title{white-space:nowrap;width:0}\n.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}\n.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}\n.admonitionblock>table td.icon{text-align:center;width:80px}\n.admonitionblock>table td.icon img{max-width:none}\n.admonitionblock>table td.icon .title{font-weight:bold;font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;text-transform:uppercase}\n.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}\n.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}\n.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}\n.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}\n.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}\n.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}\n.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}\n.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}\n@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}\n@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}\n.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^=\"highlight \"]{background:#f7f7f8}\n.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}\n.listingblock>.content{position:relative}\n.listingblock pre>code{display:block}\n.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}\n.listingblock:hover code[data-lang]::before{display:block}\n.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}\n.listingblock.terminal pre .command:not([data-prompt])::before{content:\"$\"}\n.listingblock pre.highlightjs{padding:0}\n.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}\n.listingblock pre.prettyprint{border-width:0}\n.prettyprint{background:#f7f7f8}\npre.prettyprint .linenums{line-height:1.45;margin-left:2em}\npre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}\npre.prettyprint li code[data-lang]::before{opacity:1}\npre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}\ntable.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}\ntable.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}\ntable.linenotable td.code{padding-left:.75em}\ntable.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}\npre.pygments span.linenos{display:inline-block;margin-right:.75em}\n.quoteblock{margin:0 1em 1.25em 1.5em;display:table}\n.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}\n.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}\n.quoteblock blockquote{margin:0;padding:0;border:0}\n.quoteblock blockquote::before{content:\"\\201c\";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}\n.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}\n.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}\n.verseblock{margin:0 1em 1.25em}\n.verseblock pre{font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}\n.verseblock pre strong{font-weight:400}\n.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}\n.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}\n.quoteblock .attribution br,.verseblock .attribution br{display:none}\n.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}\n.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}\n.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}\n.quoteblock.abstract{margin:0 1em 1.25em;display:block}\n.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}\n.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}\n.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}\n.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}\n.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}\np.tableblock:last-child{margin-bottom:0}\ntd.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}\ntd.tableblock>.content>:last-child{margin-bottom:-1.25em}\ntable.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}\ntable.grid-all>*>tr>*{border-width:1px}\ntable.grid-cols>*>tr>*{border-width:0 1px}\ntable.grid-rows>*>tr>*{border-width:1px 0}\ntable.frame-all{border-width:1px}\ntable.frame-ends{border-width:1px 0}\ntable.frame-sides{border-width:0 1px}\ntable.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}\ntable.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}\ntable.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}\ntable.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}\ntable.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}\nth.halign-left,td.halign-left{text-align:left}\nth.halign-right,td.halign-right{text-align:right}\nth.halign-center,td.halign-center{text-align:center}\nth.valign-top,td.valign-top{vertical-align:top}\nth.valign-bottom,td.valign-bottom{vertical-align:bottom}\nth.valign-middle,td.valign-middle{vertical-align:middle}\ntable thead th,table tfoot th{font-weight:bold}\ntbody tr th{background:#f7f8f7}\ntbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}\np.tableblock>code:only-child{background:none;padding:0}\np.tableblock{font-size:1em}\nol{margin-left:1.75em}\nul li ol{margin-left:1.5em}\ndl dd{margin-left:1.125em}\ndl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}\nli p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}\nul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}\nul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}\nul.unstyled,ol.unstyled{margin-left:0}\nli>p:empty:only-child::before{content:\"\";display:inline-block}\nul.checklist>li>p:first-child{margin-left:-1em}\nul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}\nul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}\nul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}\nul.inline>li{margin-left:1.25em}\n.unstyled dl dt{font-weight:400;font-style:normal}\nol.arabic{list-style-type:decimal}\nol.decimal{list-style-type:decimal-leading-zero}\nol.loweralpha{list-style-type:lower-alpha}\nol.upperalpha{list-style-type:upper-alpha}\nol.lowerroman{list-style-type:lower-roman}\nol.upperroman{list-style-type:upper-roman}\nol.lowergreek{list-style-type:lower-greek}\n.hdlist>table,.colist>table{border:0;background:none}\n.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}\ntd.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}\ntd.hdlist1{font-weight:bold;padding-bottom:1.25em}\ntd.hdlist2{word-wrap:anywhere}\n.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}\n.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}\n.colist td:not([class]):first-child img{max-width:none}\n.colist td:not([class]):last-child{padding:.25em 0}\n.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}\n.imageblock.left{margin:.25em .625em 1.25em 0}\n.imageblock.right{margin:.25em 0 1.25em .625em}\n.imageblock>.title{margin-bottom:0}\n.imageblock.thumb,.imageblock.th{border-width:6px}\n.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}\n.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}\n.image.left{margin-right:.625em}\n.image.right{margin-left:.625em}\na.image{text-decoration:none;display:inline-block}\na.image object{pointer-events:none}\nsup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}\nsup.footnote a,sup.footnoteref a{text-decoration:none}\nsup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}\n#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}\n#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}\n#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}\n#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}\n#footnotes .footnote:last-of-type{margin-bottom:0}\n#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}\ndiv.unbreakable{page-break-inside:avoid}\n.big{font-size:larger}\n.small{font-size:smaller}\n.underline{text-decoration:underline}\n.overline{text-decoration:overline}\n.line-through{text-decoration:line-through}\n.aqua{color:#00bfbf}\n.aqua-background{background:#00fafa}\n.black{color:#000}\n.black-background{background:#000}\n.blue{color:#0000bf}\n.blue-background{background:#0000fa}\n.fuchsia{color:#bf00bf}\n.fuchsia-background{background:#fa00fa}\n.gray{color:#606060}\n.gray-background{background:#7d7d7d}\n.green{color:#006000}\n.green-background{background:#007d00}\n.lime{color:#00bf00}\n.lime-background{background:#00fa00}\n.maroon{color:#600000}\n.maroon-background{background:#7d0000}\n.navy{color:#000060}\n.navy-background{background:#00007d}\n.olive{color:#606000}\n.olive-background{background:#7d7d00}\n.purple{color:#600060}\n.purple-background{background:#7d007d}\n.red{color:#bf0000}\n.red-background{background:#fa0000}\n.silver{color:#909090}\n.silver-background{background:#bcbcbc}\n.teal{color:#006060}\n.teal-background{background:#007d7d}\n.white{color:#bfbfbf}\n.white-background{background:#fafafa}\n.yellow{color:#bfbf00}\n.yellow-background{background:#fafa00}\nspan.icon>.fa{cursor:default}\na span.icon>.fa{cursor:inherit}\n.admonitionblock td.icon [class^=\"fa icon-\"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}\n.admonitionblock td.icon .icon-note::before{content:\"\\f05a\";color:#19407c}\n.admonitionblock td.icon .icon-tip::before{content:\"\\f0eb\";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}\n.admonitionblock td.icon .icon-warning::before{content:\"\\f071\";color:#bf6900}\n.admonitionblock td.icon .icon-caution::before{content:\"\\f06d\";color:#bf3400}\n.admonitionblock td.icon .icon-important::before{content:\"\\f06a\";color:#bf0000}\n.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:\"Open Sans\",\"DejaVu Sans\",sans-serif;font-style:normal;font-weight:bold}\n.conum[data-value] *{color:#fff!important}\n.conum[data-value]+b{display:none}\n.conum[data-value]::after{content:attr(data-value)}\npre .conum[data-value]{position:relative;top:-.125em}\nb.conum *{color:inherit!important}\n.conum:not([data-value]):empty{display:none}\ndt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}\nh1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}\np strong,td.content strong,div.footnote strong{letter-spacing:-.005em}\np,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}\np{margin-bottom:1.25rem}\n.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}\n.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}\n.print-only{display:none!important}\n@page{margin:1.25cm .75cm}\n@media print{*{box-shadow:none!important;text-shadow:none!important}\n html{font-size:80%}\n a{color:inherit!important;text-decoration:underline!important}\n a.bare,a[href^=\"#\"],a[href^=\"mailto:\"]{text-decoration:none!important}\n a[href^=\"http:\"]:not(.bare)::after,a[href^=\"https:\"]:not(.bare)::after{content:\"(\" attr(href) \")\";display:inline-block;font-size:.875em;padding-left:.25em}\n abbr[title]{border-bottom:1px dotted}\n abbr[title]::after{content:\" (\" attr(title) \")\"}\n pre,blockquote,tr,img,object,svg{page-break-inside:avoid}\n thead{display:table-header-group}\n svg{max-width:100%}\n p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}\n h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}\n #header,#content,#footnotes,#footer{max-width:none}\n #toc,.sidebarblock,.exampleblock>.content{background:none!important}\n #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}\n body.book #header{text-align:center}\n body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}\n body.book #header .details{border:0!important;display:block;padding:0!important}\n body.book #header .details span:first-child{margin-left:0!important}\n body.book #header .details br{display:block}\n body.book #header .details br+span::before{content:none!important}\n body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}\n body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}\n .listingblock code[data-lang]::before{display:block}\n #footer{padding:0 .9375em}\n .hide-on-print{display:none!important}\n .print-only{display:block!important}\n .hide-for-print{display:none!important}\n .show-for-print{display:inherit!important}}\n@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}\n .sect1{padding:0!important}\n .sect1+.sect1{border:0}\n #footer{background:none}\n #footer-text{color:rgba(0,0,0,.6);font-size:.9em}}\n@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}";
20120
-
20121
- // ESM port of lib/asciidoctor/stylesheets.rb
20122
- //
20123
- // Ruby-to-JavaScript notes:
20124
- // - Singleton: Ruby @__instance__ = new → module-level instance exported as Stylesheets.instance
20125
- // - primary_stylesheet_data memoisation: Ruby ||= → the CSS is a static import; no lazy load needed
20126
- // - File.read(...).rstrip → CSS is inlined at build time in src/data/stylesheet-data.js
20127
- // - STYLESHEETS_DIR = File.join(DATA_DIR, 'stylesheets') → not needed; CSS is a JS module
20128
- // - coderay / pygments methods → omitted (SyntaxHighlighter.for not needed here)
20129
-
20130
-
20131
- class StylesheetsClass {
20132
- static DEFAULT_STYLESHEET_NAME = 'asciidoctor.css'
20133
-
20134
- get primaryStylesheetName() {
20135
- return StylesheetsClass.DEFAULT_STYLESHEET_NAME
20136
- }
20137
-
20138
- async primaryStylesheetData() {
20139
- return defaultStylesheetData
20140
- }
20141
-
20142
- async embedPrimaryStylesheet() {
20143
- return `<style>\n${defaultStylesheetData}\n</style>`
20144
- }
20145
- }
20146
-
20147
- const Stylesheets = {
20148
- instance: new StylesheetsClass(),
20149
- };
20150
-
20151
20688
  // ESM port of converter/html5.rb
20152
20689
  //
20153
20690
  // Ruby-to-JavaScript notes:
@@ -21902,32 +22439,13 @@ Your browser does not support the video tag.
21902
22439
 
21903
22440
  // NOTE expose readSvgContents for Bespoke converter
21904
22441
  async readSvgContents(node, target) {
21905
- const imagesdir = node.document.getAttribute('imagesdir');
21906
- let resolvedPath;
21907
- let svg;
21908
- if (isUriish(target) || (imagesdir && isUriish(imagesdir))) {
21909
- svg = await node.readContents(target, {
21910
- start: imagesdir,
21911
- normalize: true,
21912
- warnOnFailure: true,
21913
- label: 'SVG',
21914
- });
21915
- resolvedPath = target;
21916
- } else {
21917
- resolvedPath = node.normalizeSystemPath(target, imagesdir, null, {
21918
- targetName: 'image',
21919
- });
21920
- svg = await node.readAsset(resolvedPath, {
21921
- normalize: true,
21922
- warnOnFailure: true,
21923
- label: 'SVG',
21924
- });
21925
- }
21926
- if (svg == null) return null // file not found/readable; warning already emitted
21927
- if (!svg) {
21928
- node.logger.warn(`contents of SVG is empty: ${resolvedPath}`);
21929
- return null
21930
- }
22442
+ let svg = await node.readContents(target, {
22443
+ start: node.document.getAttribute('imagesdir'),
22444
+ normalize: true,
22445
+ label: 'SVG',
22446
+ warnIfEmpty: true,
22447
+ });
22448
+ if (!svg) return null
21931
22449
  if (!svg.startsWith('<svg')) svg = svg.replace(SvgPreambleRx, '');
21932
22450
  // Fix incomplete SVG start tag (missing closing >) by inserting > before the first child element.
21933
22451
  // This handles cases like: <svg width="500"\n<circle .../> where the > is missing.
@@ -24153,4 +24671,4 @@ const manpage = /*#__PURE__*/Object.freeze({
24153
24671
  default: ManPageConverter
24154
24672
  });
24155
24673
 
24156
- export { AbstractBlock, AbstractNode, Author, Block, BlockMacroProcessor, BlockProcessor, ContentModel, Converter as ConverterFactory, Cursor, DefaultFactory$1 as DefaultConverterFactory, DefaultFactory as DefaultSyntaxHighlighterFactory, DocinfoProcessor, Document, DocumentTitle, Extensions, Footnote, Html5Converter, ImageReference, IncludeProcessor, Inline, InlineMacroProcessor, List, ListItem, Logger, LoggerManager, MemoryLogger, NullLogger, Postprocessor, Preprocessor, Processor, ProcessorExtension, Reader, Registry, RevisionInfo, SafeMode, Section, SyntaxHighlighter, SyntaxHighlighterBase, Timings, TreeProcessor, convert, getCoreVersion, getVersion, load };
24674
+ export { AbstractBlock, AbstractNode, Author, Block, BlockMacroProcessor, BlockProcessor, ContentModel, ConverterBase, CustomFactory$1 as ConverterCustomFactory, Converter as ConverterFactory, Cursor, DefaultFactory$1 as DefaultConverterFactory, DefaultFactory as DefaultSyntaxHighlighterFactory, DocinfoProcessor, Document, DocumentTitle, Extensions, Footnote, Html5Converter, HttpCache, HttpCacheManager, ImageReference, IncludeProcessor, Inline, InlineMacroProcessor, List, ListItem, Logger, LoggerManager, MemoryHttpCache, MemoryLogger, NullLogger, Postprocessor, Preprocessor, Processor, ProcessorExtension, Reader, Registry, RevisionInfo, SafeMode, Section, SyntaxHighlighter, SyntaxHighlighterBase, Timings, TreeProcessor, convert, deriveBackendTraits, getCoreVersion, getVersion, load };