From d2786baa20999a666555c4369abf54f4428086af Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 27 Oct 2025 12:28:55 -0700 Subject: [PATCH 1/5] contribute package:jot to dart-lang/labs --- pkgs/jot/.gitattributes | 1 + pkgs/jot/.gitignore | 13 + pkgs/jot/CHANGELOG.md | 3 + pkgs/jot/README.md | 59 + pkgs/jot/analysis_options.yaml | 10 + pkgs/jot/bin/jot.dart | 100 + pkgs/jot/lib/api.dart | 1011 +++ pkgs/jot/lib/jot.dart | 286 + pkgs/jot/lib/resources/dart.png | Bin 0 -> 1767 bytes pkgs/jot/lib/resources/index.html | 134 + pkgs/jot/lib/resources/script.js | 6821 +++++++++++++++++ pkgs/jot/lib/resources/script.sig | 1 + pkgs/jot/lib/resources/styles-dark.css | 3125 ++++++++ pkgs/jot/lib/resources/styles-light.css | 3052 ++++++++ pkgs/jot/lib/resources/styles.css | 320 + pkgs/jot/lib/resources/toggle-dark.svg | 6 + pkgs/jot/lib/resources/toggle-light.svg | 6 + pkgs/jot/lib/src/analysis.dart | 143 + pkgs/jot/lib/src/display.dart | 591 ++ pkgs/jot/lib/src/formatting.dart | 96 + pkgs/jot/lib/src/generate.dart | 588 ++ pkgs/jot/lib/src/html.dart | 129 + pkgs/jot/lib/src/index.dart | 110 + pkgs/jot/lib/src/llm_summary.dart | 515 ++ pkgs/jot/lib/src/markdown.dart | 112 + pkgs/jot/lib/src/render.dart | 283 + pkgs/jot/lib/src/server.dart | 21 + pkgs/jot/lib/src/utils.dart | 224 + pkgs/jot/lib/workspace.dart | 427 ++ pkgs/jot/pubspec.yaml | 36 + pkgs/jot/test/fixtures/demo/doc/api/demo.md | 244 + pkgs/jot/test/fixtures/demo/doc/api/index.md | 9 + .../test/fixtures/demo/doc/api/modifiers_a.md | 45 + .../test/fixtures/demo/doc/api/modifiers_b.md | 41 + pkgs/jot/test/fixtures/demo/lib/demo.dart | 369 + .../test/fixtures/demo/lib/modifiers_a.dart | 40 + .../test/fixtures/demo/lib/modifiers_b.dart | 66 + pkgs/jot/test/fixtures/demo/pubspec.yaml | 8 + pkgs/jot/test/fixtures/server/lib/a.dart | 9 + pkgs/jot/test/fixtures/server/lib/b.dart | 5 + pkgs/jot/test/fixtures/server/pubspec.yaml | 7 + pkgs/jot/test/index_test.dart | 77 + pkgs/jot/test/llm_summary_test.dart | 84 + pkgs/jot/test/render_test.dart | 289 + pkgs/jot/test/server_test.dart | 66 + pkgs/jot/test/support.dart | 220 + pkgs/jot/third_party/docusaurus/LICENSE | 21 + pkgs/jot/third_party/docusaurus/README.md | 9 + pkgs/jot/todo.md | 95 + pkgs/jot/tool/build_web.dart | 119 + pkgs/jot/tool/create_dart_sdk.dart | 330 + pkgs/jot/tool/create_flutter_sdk.dart | 141 + pkgs/jot/web/dom.dart | 94 + pkgs/jot/web/interop.dart | 18 + pkgs/jot/web/main.dart | 427 ++ pkgs/jot/web/search.dart | 552 ++ pkgs/jot/web/utils.dart | 72 + 57 files changed, 21680 insertions(+) create mode 100644 pkgs/jot/.gitattributes create mode 100644 pkgs/jot/.gitignore create mode 100644 pkgs/jot/CHANGELOG.md create mode 100644 pkgs/jot/README.md create mode 100644 pkgs/jot/analysis_options.yaml create mode 100644 pkgs/jot/bin/jot.dart create mode 100644 pkgs/jot/lib/api.dart create mode 100644 pkgs/jot/lib/jot.dart create mode 100644 pkgs/jot/lib/resources/dart.png create mode 100644 pkgs/jot/lib/resources/index.html create mode 100644 pkgs/jot/lib/resources/script.js create mode 100644 pkgs/jot/lib/resources/script.sig create mode 100644 pkgs/jot/lib/resources/styles-dark.css create mode 100644 pkgs/jot/lib/resources/styles-light.css create mode 100644 pkgs/jot/lib/resources/styles.css create mode 100644 pkgs/jot/lib/resources/toggle-dark.svg create mode 100644 pkgs/jot/lib/resources/toggle-light.svg create mode 100644 pkgs/jot/lib/src/analysis.dart create mode 100644 pkgs/jot/lib/src/display.dart create mode 100644 pkgs/jot/lib/src/formatting.dart create mode 100644 pkgs/jot/lib/src/generate.dart create mode 100644 pkgs/jot/lib/src/html.dart create mode 100644 pkgs/jot/lib/src/index.dart create mode 100644 pkgs/jot/lib/src/llm_summary.dart create mode 100644 pkgs/jot/lib/src/markdown.dart create mode 100644 pkgs/jot/lib/src/render.dart create mode 100644 pkgs/jot/lib/src/server.dart create mode 100644 pkgs/jot/lib/src/utils.dart create mode 100644 pkgs/jot/lib/workspace.dart create mode 100644 pkgs/jot/pubspec.yaml create mode 100644 pkgs/jot/test/fixtures/demo/doc/api/demo.md create mode 100644 pkgs/jot/test/fixtures/demo/doc/api/index.md create mode 100644 pkgs/jot/test/fixtures/demo/doc/api/modifiers_a.md create mode 100644 pkgs/jot/test/fixtures/demo/doc/api/modifiers_b.md create mode 100644 pkgs/jot/test/fixtures/demo/lib/demo.dart create mode 100644 pkgs/jot/test/fixtures/demo/lib/modifiers_a.dart create mode 100644 pkgs/jot/test/fixtures/demo/lib/modifiers_b.dart create mode 100644 pkgs/jot/test/fixtures/demo/pubspec.yaml create mode 100644 pkgs/jot/test/fixtures/server/lib/a.dart create mode 100644 pkgs/jot/test/fixtures/server/lib/b.dart create mode 100644 pkgs/jot/test/fixtures/server/pubspec.yaml create mode 100644 pkgs/jot/test/index_test.dart create mode 100644 pkgs/jot/test/llm_summary_test.dart create mode 100644 pkgs/jot/test/render_test.dart create mode 100644 pkgs/jot/test/server_test.dart create mode 100644 pkgs/jot/test/support.dart create mode 100644 pkgs/jot/third_party/docusaurus/LICENSE create mode 100644 pkgs/jot/third_party/docusaurus/README.md create mode 100644 pkgs/jot/todo.md create mode 100644 pkgs/jot/tool/build_web.dart create mode 100644 pkgs/jot/tool/create_dart_sdk.dart create mode 100644 pkgs/jot/tool/create_flutter_sdk.dart create mode 100644 pkgs/jot/web/dom.dart create mode 100644 pkgs/jot/web/interop.dart create mode 100644 pkgs/jot/web/main.dart create mode 100644 pkgs/jot/web/search.dart create mode 100644 pkgs/jot/web/utils.dart diff --git a/pkgs/jot/.gitattributes b/pkgs/jot/.gitattributes new file mode 100644 index 00000000..8e75ec95 --- /dev/null +++ b/pkgs/jot/.gitattributes @@ -0,0 +1 @@ +lib/resources/script.js -diff linguist-generated=true diff --git a/pkgs/jot/.gitignore b/pkgs/jot/.gitignore new file mode 100644 index 00000000..f8b2ae9a --- /dev/null +++ b/pkgs/jot/.gitignore @@ -0,0 +1,13 @@ +# https://dart.dev/guides/libraries/private-files + +.dart_tool/ +pubspec.lock + +doc/api/ +doc/sdk/ + +lib/resources/script.js.deps +lib/resources/script.js.map + +test/fixtures/demo/doc/api/_resources/ +test/fixtures/demo/doc/api/**/*.html diff --git a/pkgs/jot/CHANGELOG.md b/pkgs/jot/CHANGELOG.md new file mode 100644 index 00000000..c869571f --- /dev/null +++ b/pkgs/jot/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0-dev + +- initial version diff --git a/pkgs/jot/README.md b/pkgs/jot/README.md new file mode 100644 index 00000000..5db38341 --- /dev/null +++ b/pkgs/jot/README.md @@ -0,0 +1,59 @@ +[![package:jot](https://github.com/dart-lang/labs/actions/workflows/native_synchronization.yml/badge.svg)](https://github.com/dart-lang/labs/actions/workflows/jot.yml) + +An experimental documentation generator for Dart. + +## What's this? + +An experimental documentation generator for Dart; the main design features are: + +- fast generation +- output one page per library and per class (instead of a page per symbol) +- output rendered in a SPA web app +- few configuration options for the CLI tool +- designed to be used as a library for sophisticated use cases (documenting the + Dart SDK, the Flutter SDK, ...) + +## Status: experimental + +**NOTE**: This package is currently experimental and published under the +[labs.dart.dev](https://dart.dev/dart-team-packages) pub publisher in order to +solicit feedback. + +For packages in the labs.dart.dev publisher we generally plan to either graduate +the package into a supported publisher (dart.dev, tools.dart.dev) after a period +of feedback and iteration, or discontinue the package. These packages have a +much higher expected rate of API and breaking changes. + +Your feedback is valuable and will help us evolve this package. For general +feedback, suggestions, and comments, please file an issue in the +[bug tracker](https://github.com/dart-lang/labs/issues). + +## Command-line usage + +``` +Generate API documentation for Dart projects. + +usage: dart bin/jot.dart [] + +-h, --help Print this command help. +-o, --output Configure the output directory. + (defaults to "doc/api") + --[no-]markdown Include LLM-friendly markdown summaries of the API. + (defaults to on) + --serve= Serve live docs from the documented package. + This serves on localhost and is useful for previewing docs while working on them. +``` + +## Markdown API summaries + +Markdown summaries of the package's libraries are emitted into doc/api. +These are designed for use by agents and LLMs. They are a token dense +representation of the API; for example, for most symbols, the first markdown +sentence of the symbol is used (instead of the full dartdoc text). In a future +version, code examples in the documentation will be preserved as these are +valuable to LLMs. + +## Infima and Docusaurus + +The CSS page layout for this API generator are sourced from the +[Docusaurus](https://docusaurus.io/) project. diff --git a/pkgs/jot/analysis_options.yaml b/pkgs/jot/analysis_options.yaml new file mode 100644 index 00000000..91b821f6 --- /dev/null +++ b/pkgs/jot/analysis_options.yaml @@ -0,0 +1,10 @@ +include: package:dart_flutter_team_lints/analysis_options.yaml + +analyzer: + errors: + sort_pub_dependencies: ignore + unreachable_from_main: ignore + +linter: + rules: + - unawaited_futures diff --git a/pkgs/jot/bin/jot.dart b/pkgs/jot/bin/jot.dart new file mode 100644 index 00000000..3d449e06 --- /dev/null +++ b/pkgs/jot/bin/jot.dart @@ -0,0 +1,100 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:jot/jot.dart'; +import 'package:path/path.dart' as p; + +void main(List args) async { + var parser = createArgsParser(); + ArgResults results; + + try { + results = parser.parse(args); + } catch (e) { + printUsage(parser, e); + exit(64); + } + + var help = results['help'] as bool; + if (help) { + printUsage(parser); + exit(0); + } + + var rest = results.rest; + var inDir = rest.isEmpty ? Directory.current : Directory(rest.first); + if (!inDir.existsSync()) { + stderr.writeln("error: '${inDir.path}' does not exist."); + exit(1); + } + + Directory outDir; + if (results.wasParsed('output')) { + outDir = Directory(results['output'] as String); + } else { + outDir = Directory(p.join(inDir.path, results['output'] as String)); + } + + int? servePort; + if (results.wasParsed('serve')) { + servePort = int.tryParse(results['serve'] as String); + } + + final markdown = results['markdown'] as bool; + + var jot = Jot(inDir: inDir, outDir: outDir, markdown: markdown); + + if (servePort == null) { + await jot.generate(); + } else { + await jot.serve(servePort); + } +} + +ArgParser createArgsParser() { + return ArgParser() + ..addFlag( + 'help', + abbr: 'h', + negatable: false, + help: 'Print this command help.', + ) + ..addOption( + 'output', + abbr: 'o', + defaultsTo: 'doc/api', + help: 'Configure the output directory.', + ) + ..addFlag( + 'markdown', + aliases: ['md', 'llm'], + negatable: true, + defaultsTo: true, + help: 'Include LLM-friendly markdown summaries of the API.', + ) + ..addOption( + 'serve', + valueHelp: 'port', + help: + 'Serve live docs from the documented package.\nThis serves on ' + 'localhost and is useful for previewing docs while working on them.', + ); +} + +void printUsage(ArgParser parser, [Object? error]) { + if (error != null) { + print(error); + } else { + print('Generate API documentation for Dart projects.'); + } + + print(''); + + print('usage: dart bin/jot.dart []'); + print(''); + print(parser.usage); +} diff --git a/pkgs/jot/lib/api.dart b/pkgs/jot/lib/api.dart new file mode 100644 index 00000000..20dc11c0 --- /dev/null +++ b/pkgs/jot/lib/api.dart @@ -0,0 +1,1011 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:collection'; + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/scope.dart'; +// ignore: implementation_imports +import 'package:analyzer/src/dart/element/scope.dart'; +import 'package:path/path.dart' as p; + +import 'src/index.dart'; +import 'src/markdown.dart'; +import 'src/utils.dart'; +import 'workspace.dart'; + +class Api { + final List packages = []; + final Resolver resolver = Resolver(); + final Map elementItemMap = {}; + + late final Index index; + + Api(); + + LibraryItemContainer addLibrary( + LibraryElement element, + String packageName, + String libraryPath, + ) { + var package = packages.firstWhere( + (p) => p.name == packageName, + orElse: () { + var package = Package(packageName); + packages.add(package); + return package; + }, + ); + + var library = LibraryItemContainer(package, element, libraryPath); + package.libraries.add(library); + return library; + } + + void finish() { + // populate the element item map + for (var package in packages) { + for (var library in package.libraries) { + _buildElementItemMap(library); + } + } + + // handle situations where elements are exported from multiple libraries + _processDuplicates(); + + // perform calculations; super, children, ... + elementItemMap.values.forEach(_calculateFor); + + index = Index(); + + for (var package in packages) { + var packageIndex = index.add(package.name, 'package'); + + for (var library in package.libraries) { + var libraryIndex = packageIndex.add( + library.name, + 'library', + ref: resolve(library.element), + docs: docSummary(library), + ); + + for (var child in library.allChildrenSorted) { + if (child is Items) { + var childIndex = libraryIndex.add( + child.name, + child.type.displayName, + ref: resolve(child.element), + docs: docSummary(child), + ); + for (var c in child.allChildrenSorted) { + childIndex.add( + c.name, + c.type.displayName, + id: c.anchorId, + docs: docSummary(c), + ); + } + } else { + libraryIndex.add( + child.name, + child.type.displayName, + id: child.anchorId, + docs: docSummary(child), + ); + } + } + } + } + } + + void _buildElementItemMap(Item item) { + if (elementItemMap[item.element] == null) { + elementItemMap[item.element] = item; + } + + if (item is Items) { + item.allChildren.forEach(_buildElementItemMap); + } + } + + /// Indicate that the given item is the cannonical location from which to + /// reference its associated Element. + void _makeCanonical(Item item) { + elementItemMap[item.element] = item; + if (item is Items) { + item.allChildren.forEach(_makeCanonical); + } + } + + void _calculateFor(Item item) { + if (item.element is InterfaceElement) { + var element = item.element as InterfaceElement; + + var superItem = itemForElement(element.supertype?.element); + superItem?._addRelationship(item, RelationshipKind.$subclasses); + + for (var $interface in element.interfaces) { + var interfaceItem = itemForElement($interface.element); + interfaceItem?._addRelationship(item, RelationshipKind.$implements); + } + + for (var $mixin in element.mixins) { + var interfaceItem = itemForElement($mixin.element); + interfaceItem?._addRelationship(item, RelationshipKind.$mixes); + } + } else if (item.element is ExtensionElement) { + var element = item.element as ExtensionElement; + + var extendedElement = element.extendedType.element; + var extendedItem = itemForElement(extendedElement); + extendedItem?._addRelationship(item, RelationshipKind.$extended); + } + } + + Item? itemForElement(Element? element) { + return elementItemMap[element]; + } + + void addResolution(Item item, WorkspaceFile file) { + resolver.addResolution(item, file); + } + + String? resolve(Element? element, {WorkspaceFile? from}) { + return resolver.resolve(element, from: from); + } + + String hrefOrSpan(String text, Element element, {WorkspaceFile? from}) { + return resolver.hrefOrSpan(text, element, from: from); + } + + void _processDuplicates() { + // todo: decide whether elements should be de-duped globally or just + // de-duped per package + + // todo: instead of having one unique element definition location globally, + // have a main one, but allow per-lib scopes to have an override + + // Note that we only care about de-duping for library members. + + // todo: we want to the container members to resolve to the same place as + // their parents + + final topLevelElementsToItems = >{}; + + // look for dups + for (var package in packages) { + for (var library in package.libraries) { + for (var item in library.allChildren) { + var element = item.element; + topLevelElementsToItems.putIfAbsent(element, () => []).add(item); + } + } + } + + // todo: create a relationship between an item and the library's its defined + // in + // todo: do we have multiple Item's for each unique Element? + // todo: where are Item's created, and do we de-dupe wrt Elements? + // var libraryElement = item.element.library; + // if (item.element is! LibraryElement && libraryElement != null) { + // item._addRelationship(item, RelationshipKind.$definedIn); + // } + + for (var entry in topLevelElementsToItems.entries.where( + (entry) => entry.value.length > 1, + )) { + _updateForDuplicates(entry.key, entry.value); + } + + resolver.initElementItemMap(elementItemMap); + } + + void _updateForDuplicates(Element element, List items) { + // Use cases: + + // definied in a public lib; exported from a 2nd public lib + // dups for [promiseToFuture(...)] defined in dart:js_util: + // promiseToFuture from dart:js_util + // promiseToFuture from dart:html + + // defined in a private lib, exported (independently) from two public libs + // dups for [abstract class BytesBuilder] defined in dart:_internal: + // BytesBuilder from dart:io + // BytesBuilder from dart:typed_data + + // defined in a private library + // exported from a public library + // exported from other public libraries from the first public library + // ex., flutter:widgets symbols (defined in private libs), exported as part + // of flutter:material + + // todo: we want to sort these dups via the length of their export chain + // 0: defined in a public lib + // 1: defined in a private lib, exported from a public one + // 2: exported from a public lib + // 3: ... + + // then, choose a 'best' Item + + // replace all the worst Items with forward refs to that bext one + + // have all Items equal to the best item add local package overrides to + // their local ref + + var exports = items.map((item) { + var parentLib = item.libraryParent; + var len = parentLib!._calcElementExportLength(element); + return _ElementExports(element, item, parentLib, len); + }).toList()..sort(); + + print( + 'dups for [$element] defined in ' + '${element.library?.librarySource.uri}:', + ); + for (var export in exports) { + print( + ' ${export.element.name} from ' + '${export.libraryContainer.name}: ${export.exportLength}', + ); + } + + // for non-canonical items: + // - convert to export + // - make sure the element map point to the cannonical versions + var canonical = exports.first; + _makeCanonical(canonical.item); + + print('[$element] => ${elementItemMap[element]!.debugPath}'); + + for (var export in exports) { + if (export.exportLength > canonical.exportLength) { + export.item._convertToExport( + exportedFrom: canonical.libraryContainer, + cannonicalItem: canonical.item, + ); + } + } + } +} + +class _ElementExports implements Comparable<_ElementExports> { + final Element element; + final Item item; + final LibraryItemContainer libraryContainer; + final int exportLength; + + _ElementExports( + this.element, + this.item, + this.libraryContainer, + this.exportLength, + ); + + @override + int compareTo(_ElementExports other) { + var diff = exportLength - other.exportLength; + if (diff != 0) return diff; + + return libraryContainer.name.compareTo(other.libraryContainer.name); + } +} + +class Package implements Comparable { + final String name; + final List libraries = []; + + String? version; + String? description; + + Package(this.name); + + bool get includeInUrls => name.contains(':'); + + @override + int compareTo(Package other) { + return name.compareTo(other.name); + } +} + +/// A tuple of a relationship kind (subclass, implementor, ...) and a set of +/// items. +typedef RelationshipMap = Map>; + +class Item { + Items? parent; + final Element element; + late final GroupType type = GroupType.typeFor(element); + final RelationshipMap relationships = SplayTreeMap(); + + String? nameOverride; + + Scope? _scopeCache; + + Item(this.parent, this.element); + + String get name { + if (nameOverride != null) return nameOverride!; + + var result = element.displayName; + if (result.isEmpty) { + // Assume this is a ctor. + return element.enclosingElement!.name!; + } else { + return result; + } + } + + LibraryItemContainer? get libraryParent { + Item? item = this; + while (item != null) { + if (item is LibraryItemContainer) return item; + item = item.parent; + } + return null; + } + + Scope get scope => _scopeCache ??= _calcScope(element)!; + + String get anchorId => stringToAnchorId(name); + + late String? docs = _calculateDocs(); + + bool get hasDocs => docs != null; + + ClassElement get asClass => element as ClassElement; + + MixinElement get asMixin => element as MixinElement; + + ExtensionElement get asExtension => element as ExtensionElement; + + // ignore: experimental_member_use + ExtensionTypeElement get asExtensionType => element as ExtensionTypeElement; + + EnumElement get asEnum => element as EnumElement; + + FieldElement get asField => element as FieldElement; + + TopLevelVariableElement get asTopLevelVariableElement => + element as TopLevelVariableElement; + + PropertyAccessorElement get asAccessor => element as PropertyAccessorElement; + + MethodElement get asMethod => element as MethodElement; + + FunctionElement get asFunction => element as FunctionElement; + + ConstructorElement get asConstructor => element as ConstructorElement; + + TypeAliasElement get asTypeAlias => element as TypeAliasElement; + + bool get isStatic { + if (element is ClassMemberElement) { + return (element as ClassMemberElement).isStatic; + } else if (element is ExecutableElement) { + return (element as ExecutableElement).isStatic; + } + throw StateError('element not a class member: $element'); + } + + String get debugPath => parent == null ? name : '${parent!.debugPath}/$name'; + + void _addRelationship(Item item, RelationshipKind kind) { + relationships.putIfAbsent(kind, () => []).add(item); + } + + String? _calculateDocs() { + var result = element.documentationComment; + if (result == null) { + var enclosing = element.enclosingElement; + if (enclosing is InterfaceElement) { + if (element.kind == ElementKind.METHOD) { + result = _lookupMethodDocs(element as MethodElement); + } else if (element.kind == ElementKind.GETTER) { + result = _lookupGetterDocs(element as PropertyAccessorElement); + } else if (element.kind == ElementKind.SETTER) { + result = _lookupSetterDocs(element as PropertyAccessorElement); + } + } + } + + return result == null ? null : stripDartdoc(result); + } + + String? _lookupMethodDocs(MethodElement element) { + var enclosing = element.enclosingElement as InterfaceElement; + var superMethod = enclosing.thisType.lookUpMethod2( + element.name, + element.library, + inherited: true, + ); + return superMethod == null + ? null + : (superMethod.documentationComment ?? _lookupMethodDocs(superMethod)); + } + + String? _lookupGetterDocs(PropertyAccessorElement element) { + var enclosing = element.enclosingElement as InterfaceElement; + var accessor = enclosing.thisType.lookUpGetter2( + element.name, + element.library, + inherited: true, + ); + return accessor == null + ? null + : (accessor.documentationComment ?? _lookupGetterDocs(accessor)); + } + + String? _lookupSetterDocs(PropertyAccessorElement element) { + var enclosing = element.enclosingElement as InterfaceElement; + var accessor = enclosing.thisType.lookUpSetter2( + element.name, + element.library, + inherited: true, + ); + return accessor == null + ? null + : (accessor.documentationComment ?? _lookupSetterDocs(accessor)); + } + + MarkdownLinkResolver markdownLinkResolver(Resolver resolver) { + return (String ref) { + var result = resolver.resolveDocReference( + ref, + context: this, + fromFile: resolver.fileFor(element), + ); + + // todo: log this? + // if (result == null) { + // print(' unresolved: [$ref] from ${element.displayName}'); + // } + + return result; + }; + } + + List get annotations { + return element.metadata.where((annotation) { + var meta = annotation.element; + if (meta == null) return false; + + // `meta` is a PropertyAccessorElement or a ConstructorElement. + + // Filter pragma annotations - these are directions to tools, not first + // class properties of the source code. + if (meta is PropertyAccessorElement) { + if (meta.name == 'pragma') return false; + } else if (meta is ConstructorElement) { + if (meta.enclosingElement.name == 'pragma') return false; + } + + return true; + }).toList(); + } + + static Scope? _calcScope(Element element) { + // todo: more of these scopes could be cached / looked up by Item + + if (element is CompilationUnitElement) { + return _calcScope(element.enclosingElement); + } + + if (element is LibraryElement) { + return element.scope; + } else if (element is ExtensionElement) { + return ExtensionScope(_calcScope(element.enclosingElement)!, element); + } else if (element is InterfaceElement) { + return InterfaceScope(_calcScope(element.enclosingElement)!, element); + } else if (element is MethodElement) { + return FormalParameterScope( + _calcScope(element.enclosingElement)!, + element.parameters, + ); + } else if (element is FunctionElement) { + return FormalParameterScope( + _calcScope(element.enclosingElement)!, + element.parameters, + ); + } else if (element is ConstructorElement) { + return ConstructorInitializerScope( + _calcScope(element.enclosingElement)!, + element, + ); + } else if (element is PropertyAccessorElement) { + return LocalScope(_calcScope(element.enclosingElement)!)..add(element); + } else if (element is FieldElement) { + return LocalScope(_calcScope(element.enclosingElement)!)..add(element); + } else if (element is TypeAliasElement) { + return _calcScope(element.enclosingElement); + } else { + print('scope not found for ${element.runtimeType}'); + return null; + } + } + + /// Indicate that this Item should not be considered to be defined in the + /// current library, but documented as an export. + /// + /// The item should be a direct child of a library. + void _convertToExport({ + required LibraryItemContainer exportedFrom, + required Item cannonicalItem, + }) { + var library = parent as LibraryItemContainer; + + // todo: there are more dangling references here to clean up + + // remove from children + library.groups[type]!.items.remove(this); + if (library.groups[type]!.items.isEmpty) { + library.groups.remove(type); + } + + // add to an exports list + library.exports.add(ExportedItem(cannonicalItem, exportedFrom)); + } +} + +class ExportedItem { + final Item item; + final LibraryItemContainer exportedFrom; + + ExportedItem(this.item, this.exportedFrom); +} + +abstract class Items extends Item { + final Map groups = SplayTreeMap(); + + Items(super.parent, super.element); + + T addChild(T item) { + var groupType = GroupType.typeFor(item.element); + if (groupType != GroupType.skip) { + groups.putIfAbsent(groupType, () => Group(groupType)).items.add(item); + } + return item; + } + + Iterable get allChildren { + return groups.entries.expand((entry) => entry.value.items); + } + + List get allChildrenSorted { + var items = allChildren.toList(); + items.sort((a, b) => adjustedLexicalCompare(a.name, b.name)); + return items; + } + + void sort() { + for (var entry in groups.entries) { + // have enums retain their declaration order + if (entry.key == GroupType.enumValue) continue; + + entry.value.sort(); + } + } + + static Map> itemsByGroup(List items) { + var result = SplayTreeMap>(); + for (var item in items) { + result.putIfAbsent(item.type, () => []).add(item); + } + for (var entry in result.entries) { + entry.value.sort((a, b) => adjustedLexicalCompare(a.name, b.name)); + } + return result; + } +} + +class InterfaceElementItems extends Items { + InterfaceElementItems(super.parent, InterfaceElement super.element); + + @override + InterfaceElement get element => super.element as InterfaceElement; +} + +class ExtensionElementItems extends Items { + ExtensionElementItems(super.parent, super.element); + + @override + ExtensionElement get element => super.element as ExtensionElement; +} + +class LibraryItemContainer extends Items + implements Comparable { + final Package? package; + + /// The list of items that are part of this library's public API, but that + /// are considered exports (primarily defined elsewhere). + final List exports = []; + + LibraryItemContainer(this.package, LibraryElement element, String name) + : super(null, element) { + nameOverride = name; + + var exportNamespace = element.exportNamespace; + var elements = exportNamespace.definedNames.values + .where((element) => element.isPublic) + .toList(); + elements.sort((a, b) => adjustedLexicalCompare(a.name ?? '', b.name ?? '')); + + for (var e in elements) { + if (e is InterfaceElement) { + var interfaceElement = e; + + var interfaceElementChildren = addChild( + InterfaceElementItems(this, interfaceElement), + ); + + for (var child in interfaceElement.children.where((c) => c.isPublic)) { + if (child.isSynthetic) continue; + + interfaceElementChildren.addChild( + Item(interfaceElementChildren, child), + ); + } + + interfaceElementChildren.sort(); + } else if (e is ExtensionElement) { + var extensionElement = e; + + var extensionElementChildren = addChild( + ExtensionElementItems(this, extensionElement), + ); + + for (var child in extensionElement.children.where((c) => c.isPublic)) { + if (child.isSynthetic) continue; + + extensionElementChildren.addChild( + Item(extensionElementChildren, child), + ); + } + + extensionElementChildren.sort(); + } else { + addChild(Item(this, e)); + } + } + } + + String get urlName => package != null && package!.includeInUrls + ? '${package!.name}/$name' + : name; + + @override + LibraryElement get element => super.element as LibraryElement; + + Map> get exportsByLibrary { + var results = SplayTreeMap>(); + + for (var export in exports) { + results.putIfAbsent(export.exportedFrom, () => []).add(export.item); + } + + return results; + } + + /// For a given element defined in this library or exported from it, calculate + /// how many library exports exist betwen this library and the library where + /// the element is actually defined. + /// + /// For example, if the element is defined in this library, the export length + /// would be 0. + /// + /// For an element defined in a private library exported from this library, + /// the export length would be 1. Higer numbers indicate a longer export path. + int _calcElementExportLength(Element e) { + // todo: implement this using directive export info + + if (e.library == element) return 0; + + return 1; + } + + @override + int compareTo(LibraryItemContainer other) { + return name.compareTo(other.name); + } +} + +class Group implements Comparable { + final GroupType type; + final List items = []; + + Group(this.type); + + String get name => type.title; + + String get anchorId => stringToAnchorId('_$name'); + + bool get containerType => type.containerType; + + void sort() { + items.sort((a, b) => adjustedLexicalCompare(a.name, b.name)); + } + + @override + int compareTo(Group other) { + return type.index - other.type.index; + } +} + +enum GroupType implements Comparable { + // TODO: why is there not an ElementKind.MIXIN? + + // class members + constructor('Constructors', 'constructor', {ElementKind.CONSTRUCTOR}), + enumValue('Values', 'enum value', {}), + field('Fields', 'field', {ElementKind.FIELD}), + accessor('Accessors', 'accessor', {ElementKind.GETTER, ElementKind.SETTER}), + method('Methods', 'method', {ElementKind.METHOD}), + + // library members + topLevelVariable('Top Level Variables', 'top level variable', { + ElementKind.TOP_LEVEL_VARIABLE, + }), + function('Functions', 'function', {ElementKind.FUNCTION}), + functionTypeAlias('Function Type Aliases', 'function type alias', { + ElementKind.FUNCTION_TYPE_ALIAS, + }), + typeAlias('Type Aliases', 'type alias', {ElementKind.TYPE_ALIAS}), + + // container items + $enum('Enums', 'enum', {ElementKind.ENUM}, containerType: true), + $mixin('Mixins', 'mixin', {}, containerType: true), + $class('Classes', 'class', {ElementKind.CLASS}, containerType: true), + $extension('Extensions', 'extension', { + ElementKind.EXTENSION, + }, containerType: true), + $extensionType('Extension Types', 'extension type', { + ElementKind.EXTENSION_TYPE, + }, containerType: true), + // todo: implement + // $record('Records', 'record', {ElementKind.RECORD}, containerType: true), + + // catch-all + skip('Skip', 'skip', { + ElementKind.DYNAMIC, + ElementKind.NEVER, + ElementKind.TYPE_PARAMETER, + }), + other('Other', 'other', {}); + + final String title; + final Set elementKinds; + final bool containerType; + final String displayName; + + const GroupType( + this.title, + this.displayName, + this.elementKinds, { + this.containerType = false, + }); + + @override + int compareTo(GroupType other) { + return index - other.index; + } + + /// Return the [GroupType] for the given [element]. + static GroupType typeFor(Element element) { + final kind = element.kind; + if (element is FieldElement && element.isEnumConstant) { + return GroupType.enumValue; + } + if (element is MixinElement) return GroupType.$mixin; + for (var val in GroupType.values) { + if (val.elementKinds.contains(kind)) { + return val; + } + } + print('*** ${element.kind} ***'); + return GroupType.other; + } +} + +// todo: remove files if we remove an Item +class Resolver { + // libraries and classes to files + + final Map itemToFileMap = {}; + late final Map elementToItemMap; + + void addResolution(Item item, WorkspaceFile file) { + itemToFileMap[item] = file; + } + + void initElementItemMap(Map elementItemMap) { + elementToItemMap = elementItemMap; + } + + String? resolve(Element? element, {WorkspaceFile? from}) { + var item = elementToItemMap[element]; + var target = itemToFileMap[item]; + if (target == null) return null; + + if (from != null) { + // Replaced for performance reasons. + return target.path.pathRelative(fromDir: p.dirname(from.path)); + // return p.relative(target.path, from: p.dirname(from.path)); + } else { + return target.path; + } + } + + // todo: html encode 'text' + String hrefOrSpan(String text, Element element, {WorkspaceFile? from}) { + var ref = resolve(element, from: from); + + if (ref != null) { + return '$text'; + } else { + return '$text'; + } + } + + /// Returns a Uri if the reference is resolved. + String? resolveDocReference( + String reference, { + required Item context, + WorkspaceFile? fromFile, + }) { + // TODO: handle dotted references (Foo.bar, ...) + + var scope = context.scope; + var element = scope.lookup(reference).getter; + return resolve(element, from: fromFile); + } + + WorkspaceFile? fileFor(Element element) { + // See if this element cooresponds directly to a file. + var item = elementToItemMap[element]; + var file = itemToFileMap[item]; + if (file != null) return file; + + // Otherwise check its library or compilation element. + if (element.enclosingElement is CompilationUnitElement) { + var enclosingItem = elementToItemMap[element.library]; + file = itemToFileMap[enclosingItem]; + } else { + var enclosingItem = elementToItemMap[element.enclosingElement]; + file = itemToFileMap[enclosingItem]; + } + + return file; + } +} + +enum RelationshipKind implements Comparable { + $subclasses('Subclassed by'), + $implements('Implemented by'), + $mixes('Mixed into'), + $extended('Extended by'); + + final String title; + + const RelationshipKind(this.title); + + @override + int compareTo(RelationshipKind other) { + return index - other.index; + } +} + +/// A StringBuffer like class that allows you to write out Element references, +/// dart format the written text, and emit the result as html with the element +/// references converted to html links. +class LinkedText { + final Resolver resolver; + final WorkspaceFile fromFile; + + final List<_ElementSpan> _elementSpans = []; + + final StringBuffer _buf = StringBuffer(); + int _charIndex = 0; + + LinkedText(this.resolver, this.fromFile); + + void write(String str) { + for (var i = 0; i < str.length; i++) { + if (str[i].trim().isNotEmpty) { + _charIndex++; + } + } + _buf.write(str); + } + + void writeElement(String str, Element element) { + _elementSpans.add(_ElementSpan(element, _charIndex, str)); + _charIndex += str.length; + _buf.write(str); + } + + String emitHtml(String Function(String) formatHelper, [String suffix = '']) { + var fmt = formatHelper(_buf.toString()); + + var chunks = _chunks(fmt, _elementSpans, _spanStarts(fmt)).toList(); + + var html = chunks.map((chunk) { + if (chunk is String) { + return htmlEscape(chunk); + } else { + var span = chunk as _ElementSpan; + + var uri = resolver.resolve(span.element, from: fromFile); + if (uri == null) { + return htmlEscape(span.text); + } else { + return '${htmlEscape(span.text)}'; + } + } + }).join(); + + return '
$html$suffix
'; + } + + List _spanStarts(String fmt) { + var result = []; + + var spans = _elementSpans.iterator; + if (!spans.moveNext()) return result; + + var index = 0; + int i; + + for (i = 0; i < fmt.length; i++) { + if (fmt[i].trim().isEmpty) continue; + + if (index == spans.current.start) { + result.add(i); + if (!spans.moveNext()) return result; + } + + index++; + } + + return result; + } + + // A List of Strings and _ElementSpans. + Iterable _chunks( + String fmt, + List<_ElementSpan> spans, + List spanStarts, + ) sync* { + var fmtIndex = 0; + + for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + var spanStart = spanStarts[i]; + + if (fmtIndex < spanStart) { + yield fmt.substring(fmtIndex, spanStart); + fmtIndex = spanStart; + } + + yield span; + fmtIndex = spanStart + span.text.length; + } + + if (fmtIndex < fmt.length) { + yield fmt.substring(fmtIndex); + } + } + + @override + String toString() => _buf.toString(); +} + +class _ElementSpan { + final Element element; + final int start; + final String text; + + _ElementSpan(this.element, this.start, this.text); + + @override + String toString() => '[$text]'; +} diff --git a/pkgs/jot/lib/jot.dart b/pkgs/jot/lib/jot.dart new file mode 100644 index 00000000..27c656e5 --- /dev/null +++ b/pkgs/jot/lib/jot.dart @@ -0,0 +1,286 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// To create a new [Workspace], see [Workspace.fromPackage]. +library; + +import 'dart:io'; + +import 'package:cli_util/cli_logging.dart'; +import 'package:path/path.dart' as p; +import 'package:shelf/shelf.dart'; +import 'package:shelf/shelf_io.dart' as shelf_io; +import 'package:shelf_router/shelf_router.dart'; + +import 'api.dart'; +import 'src/analysis.dart'; +import 'src/generate.dart'; +import 'src/html.dart'; +import 'src/llm_summary.dart'; +import 'src/server.dart'; +import 'src/utils.dart'; +import 'workspace.dart'; + +class Jot { + final Directory inDir; + final Directory outDir; + + /// Create an LLM-friendly markdown summary of the API in doc/markdown. + final bool markdown; + + final Logger logger; + + late final Analyzer analyzer; + late final HtmlTemplate htmlTemplate; + + Jot({ + required this.inDir, + required this.outDir, + this.markdown = false, + Logger? logger, + }) : logger = logger ?? Logger.standard(); + + Future generate() async { + if (!outDir.existsSync()) { + outDir.createSync(recursive: true); + } + + var stats = Stats()..start(); + + htmlTemplate = await HtmlTemplate.createDefault(); + analyzer = Analyzer.packages( + includedPaths: [p.normalize(inDir.absolute.path)], + ); + + var progress = logger.progress('Resolving public libraries'); + var workspace = await _buildWorkspace(); + progress.finish(); + + // build model + workspace.api.finish(); + + // generate + logger.stdout(''); + logger.stdout('Generating docs...'); + + // generate docs + final generator = Generator( + workspace: workspace, + outDir: outDir, + logger: logger, + stats: stats, + ); + await generator.generate(); + + if (markdown) { + logger.stdout(''); + logger.stdout('Generating markdown summaries...'); + + final summaryOut = Directory(p.join(outDir.parent.path, 'api')) + ..createSync(); + final summaryGenerator = LLMSummary( + workspace: workspace, + outDir: summaryOut, + logger: logger, + stats: stats, + ); + summaryGenerator.generate(); + } + + stats.stop(); + + logger.stdout(''); + // "1,347 symbols, 82% have documentation, 4 libraries, 8MB of html, 0.3s" + logger.stdout( + 'Wrote docs to ${p.relative(outDir.path)} in ' + '${stats.elapsedSeconds}s (${stats.fileCount} files, ' + '${stats.sizeDesc}).', + ); + } + + Future serve(int port) async { + htmlTemplate = await HtmlTemplate.createDefault(); + analyzer = Analyzer.packages( + includedPaths: [p.normalize(inDir.absolute.path)], + ); + + var progress = logger.progress('Resolving public libraries'); + var workspace = await _buildWorkspace(); + progress.finish(); + + // build model + workspace.api.finish(); + + logger.stdout(''); + + var server = DocServer(jot: this, workspace: workspace); + await server.start(port); + return server; + } + + Future _buildWorkspace() async { + var workspace = Workspace.fromPackage(htmlTemplate, inDir); + var packageName = workspace.name.substring('package:'.length); + + final libDirPath = p.join(inDir.path, 'lib'); + + // TODO: build up the api and the workspace separately; we need a better + // picture of the API before we start assigning elements to pages + + await for (var resolvedLibrary in analyzer.resolvedPublicLibraries()) { + var libraryPath = resolvedLibrary.element.source.fullName; + + var dartLibraryPath = p.relative(libraryPath, from: libDirPath); + var htmlOutputPath = '${p.withoutExtension(dartLibraryPath)}.html'; + + var libraryContainer = workspace.addChild( + WorkspaceDirectory(workspace, dartLibraryPath), + ); + + var library = workspace.api.addLibrary( + resolvedLibrary.element, + workspace.name, + dartLibraryPath, + ); + + libraryContainer.mainFile = WorkspaceFile( + workspace, + dartLibraryPath, + htmlOutputPath, + libraryGenerator(library), + )..importScript = 'package:$packageName/$dartLibraryPath'; + + workspace.api.addResolution(library, libraryContainer.mainFile!); + + for (var itemContainer in library.allChildrenSorted.whereType()) { + var path = + '${p.withoutExtension(dartLibraryPath)}/${itemContainer.name}.html'; + var docFile = WorkspaceFile( + libraryContainer, + itemContainer.name, + path, + itemsGenerator(itemContainer), + ); + libraryContainer.addChild(docFile); + workspace.api.addResolution(itemContainer, docFile); + } + } + + workspace.api.packages.first.version = workspace.version; + workspace.api.packages.first.description = workspace.description; + + return workspace; + } +} + +class DocServer { + final Jot jot; + Workspace workspace; + late final HttpServer _server; + + DocServer({required this.jot, required this.workspace}); + + int get port => _server.port; + + Logger get logger => jot.logger; + + Response _notFound(Request request) { + return Response.notFound('404 - page not found: ${request.url.path}'); + } + + Future _contentHandler(Request request) async { + var filePath = request.url.path; + if (!filePath.endsWith('.html')) return _notFound(request); + + // Check for changed dart sources. + if (await jot.analyzer.reanalyzeChanges()) { + workspace = await jot._buildWorkspace(); + workspace.api.finish(); + } + + var file = workspace.getForPath(filePath); + if (file == null) { + return _notFound(request); + } else { + var pageContents = await file.generatePageContents(); + var fileContents = await workspace.generateWorkspacePage( + file, + pageContents, + ); + return Response.ok(fileContents, headers: headersFor(filePath)); + } + } + + Future _resourcesHandler(Request request) { + var path = request.url.path; + + return loadResourceDataAsBytes(path) + .then((data) { + return Response.ok(data, headers: headersFor(path)); + }) + .onError((error, _) { + return _notFound(request); + }); + } + + Handler _loggingHandler(Handler handler) { + final ansi = logger.ansi; + + return (Request request) async { + final timer = Stopwatch()..start(); + final response = await handler(request); + timer.stop(); + + final ms = timer.elapsedMilliseconds; + final size = ((response.contentLength ?? 0) + 512) ~/ 1024; + final code = response.statusCode; + final path = request.url.path; + + logger.stdout( + '${ansi.blue}${ms.toString().padLeft(3)}ms ' + '${size.toString().padLeft(3)}k${ansi.none} ' + '${ansi.green}${ansi.bullet}${ansi.none} $code $path', + ); + + return response; + }; + } + + Future start(int port) async { + var app = Router(notFoundHandler: _contentHandler); + app.get('/', (Request request) { + return Response.movedPermanently('index.html'); + }); + app.get('/favicon.ico', (Request request) async { + return Response.ok( + await loadResourceDataAsBytes('dart.png'), + headers: headersFor('dart.png'), + ); + }); + app.get('/_resources/index.json', (Request request) async { + return Response.ok( + workspace.api.index.toJson(), + headers: headersFor(request.url.path), + ); + }); + app.get('/_resources/nav.json', (Request request) async { + return Response.ok( + workspace.generateNavData(), + headers: headersFor(request.url.path), + ); + }); + app.mount('/_resources', Router(notFoundHandler: _resourcesHandler).call); + + _server = await shelf_io.serve( + _loggingHandler(app.call), + 'localhost', + port, + ); + logger.stdout( + 'Serving docs at http://${_server.address.host}:${_server.port}/.', + ); + } + + Future dispose() => _server.close(); +} diff --git a/pkgs/jot/lib/resources/dart.png b/pkgs/jot/lib/resources/dart.png new file mode 100644 index 0000000000000000000000000000000000000000..43d2ffa079ca147a221437817dbc694d66a2a302 GIT binary patch literal 1767 zcmVr1gM)#AhSs$=eK0WK)CF2vH5m*T78Vv7 zOqGGvxA(cvvG46mUuvh$T1!8DmE**HzxO9;TsuQliJN|J!pK@zgpAc6W;K`ZbSrnoP`wF$fl7_5*8Ivypwf=W;~ z;08%MQORYPC_tGHZSh$O#Av43|^d-UX&HM!T~7!)g1(@JfEf{VV=B< z1V2h$vz|_)(42Iv;nMQ6gnaC=x-iE)V9>bg95MTIge3HB2W~Qqm*!+BpztvG$qKPZI96W} zvtB&GrNG5*kOai6|CR7-+*88m$TiE!O#Aqvg{$I60STah90fcj;bJTAHe50;DvqB` zEg>!%3Dgd1>303*qUn95wS&WE(*hLuC37)V?aQjQ(>?on4V>`^}$4&P2qUwF63p3!p z6R>6i5YrB(Dm-K?OMsE#XJVfc&SVMlTc3)@NKU0J3269ELe@xN0Za64hocS>SoY(& zL%m;r$g#En;{)>X$|7Ng63+K0K^DLzXfDCDx@#YPVSI{DxIP(XJHy#-j`B3b#X_yixgMa&bn3s?yPcssC4`0@Pr z>UDqkrA2oMvH(^Il;ArzoKINx_2)YKwKcf{c=joHgRLFHM+xq^ZVMp3+9h+pM_8DNoMAB-dVobWmYAS9rt1as~o-UgNSX!>_*0eKDx64<-L zsr_Sf&ksWK5X_wO=HsvVW@R@4avN{~b`kO)Q2hp=EFi=-pa;L0N~k1s7QiKN5q3y| z{H02#@|Qmd>8SNrVChicf`ASZgo+R(>{|f;A|&P#WC45@h!O<2gp5n*5WLs|%h5Io z&-zA4k|2tpV}-BR_;rW=0{Hbbr8g2rC_$(INdgxkz-9uI;7AhAx(eXe)2I^YTj5fu z07-%@V%uQ+#@-^?#TPmIvVf-~Xcr}rfKnDf$id05c9_^NzK{etcv%3Kz^)CFfYM7u z0sTc>5&YuI)(f)z1qhX(H3Ggi0-)qG;MpQ%*z;uxJkb6E_~m7Pp-})}1w7y{P|87X zMF?8JdR00$fprxiY?Jv$f)^#)PoTa$P7;P^(nEroXQBYUjX$q968u%Jy_6(e-Iwpz z`wQ&juE(vPtb`I*EA&`h0mZHYjw%V!O;ZVLl+daK6k%2i_w{N+cwBf+b515f%gmO% z0;CNdCA9us9ZyP?@Hi6?I4mR~j0z_-S>8&HnB#ImfGojJKnEEBu4V8D90ETn>T?(4 zMG`tr=$)vA?}qayISJ<{js z)mqSPcf)OyC94E3VQ2vf2>>`6^tPFngqTYhz5-+c150@O0%QqqUjRvn1qp9gfGmM1 zUw{G;1RSy*Qj(CpFloi)@B(OKcajFkv|3YK_es*=t)6!)-Mumr002ov JPDHLkV1ksy9Tflo literal 0 HcmV?d00001 diff --git a/pkgs/jot/lib/resources/index.html b/pkgs/jot/lib/resources/index.html new file mode 100644 index 00000000..e0bde985 --- /dev/null +++ b/pkgs/jot/lib/resources/index.html @@ -0,0 +1,134 @@ + + + + + + + + + {{ page-title }} + + + + + + + + + + + + + +
+ + + + + + + +
+
+
+
+ +
+
+ + + +
+ + {{ page-content }} + +
+ +
+
+
+ +
+
+ + {{ toc }} + +
+
+
+ +
+ +
+
+ + + + + + + +
+ +
+ +
+
+ + + + diff --git a/pkgs/jot/lib/resources/script.js b/pkgs/jot/lib/resources/script.js new file mode 100644 index 00000000..1547fd79 --- /dev/null +++ b/pkgs/jot/lib/resources/script.js @@ -0,0 +1,6821 @@ +(function dartProgram(){function copyProperties(a,b){var s=Object.keys(a) +for(var r=0;r=0)return true +if(typeof version=="function"&&version.length==0){var q=version() +if(/^\d+\.\d+\.\d+\.\d+$/.test(q))return true}}catch(p){}return false}() +function inherit(a,b){a.prototype.constructor=a +a.prototype["$i"+a.name]=a +if(b!=null){if(z){Object.setPrototypeOf(a.prototype,b.prototype) +return}var s=Object.create(b.prototype) +copyProperties(a.prototype,s) +a.prototype=s}}function inheritMany(a,b){for(var s=0;s4294967295)throw A.f(A.az(a,0,4294967295,"length",null)) +return J.lR(new Array(a),b)}, +j2(a,b){if(a<0)throw A.f(A.dv("Length must be a non-negative integer: "+a,null)) +return A.t(new Array(a),b.h("O<0>"))}, +lR(a,b){var s=A.t(a,b.h("O<0>")) +s.$flags=1 +return s}, +lS(a,b){var s=t.e8 +return J.li(s.a(a),s.a(b))}, +jP(a){if(a<256)switch(a){case 9:case 10:case 11:case 12:case 13:case 32:case 133:case 160:return!0 +default:return!1}switch(a){case 5760:case 8192:case 8193:case 8194:case 8195:case 8196:case 8197:case 8198:case 8199:case 8200:case 8201:case 8202:case 8232:case 8233:case 8239:case 8287:case 12288:case 65279:return!0 +default:return!1}}, +lT(a,b){var s,r +for(s=a.length;b0;b=r){r=b-1 +if(!(r>>0===b&&b").B(c).h("cT<1,2>")) +return new A.bi(a,b.h("@<0>").B(c).h("bi<1,2>"))}, +jQ(a){return new A.bV("Field '"+a+"' has been assigned during initialization.")}, +lX(a){return new A.bV("Field '"+a+"' has not been initialized.")}, +lW(a){return new A.bV("Field '"+a+"' has already been initialized.")}, +iH(a){var s,r=a^48 +if(r<=9)return r +s=a|32 +if(97<=s&&s<=102)return s-87 +return-1}, +b6(a,b){a=a+b&536870911 +a=a+((a&524287)<<10)&536870911 +return a^a>>>6}, +j9(a){a=a+((a&67108863)<<3)&536870911 +a^=a>>>11 +return a+((a&16383)<<15)&536870911}, +fP(a,b,c){return a}, +jp(a){var s,r +for(s=$.ap.length,r=0;rc)A.bH(A.az(b,0,c,"start",null))}return new A.cK(a,b,c,d.h("cK<0>"))}, +lZ(a,b,c,d){if(t.b.b(a))return new A.cm(a,b,c.h("@<0>").B(d).h("cm<1,2>")) +return new A.aL(a,b,c.h("@<0>").B(d).h("aL<1,2>"))}, +j0(){return new A.c1("No element")}, +lP(){return new A.c1("Too many elements")}, +b7:function b7(){}, +cd:function cd(a,b){this.a=a +this.$ti=b}, +bi:function bi(a,b){this.a=a +this.$ti=b}, +cT:function cT(a,b){this.a=a +this.$ti=b}, +cQ:function cQ(){}, +aI:function aI(a,b){this.a=a +this.$ti=b}, +bV:function bV(a){this.a=a}, +hH:function hH(){}, +i:function i(){}, +T:function T(){}, +cK:function cK(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.$ti=d}, +P:function P(a,b,c){var _=this +_.a=a +_.b=b +_.c=0 +_.d=null +_.$ti=c}, +aL:function aL(a,b,c){this.a=a +this.b=b +this.$ti=c}, +cm:function cm(a,b,c){this.a=a +this.b=b +this.$ti=c}, +cw:function cw(a,b,c){var _=this +_.a=null +_.b=a +_.c=b +_.$ti=c}, +K:function K(a,b,c){this.a=a +this.b=b +this.$ti=c}, +aQ:function aQ(a,b,c){this.a=a +this.b=b +this.$ti=c}, +cO:function cO(a,b,c){this.a=a +this.b=b +this.$ti=c}, +a5:function a5(){}, +dj:function dj(){}, +lC(){throw A.f(A.G("Cannot modify constant Set"))}, +kU(a){var s=v.mangledGlobalNames[a] +if(s!=null)return s +return"minified:"+a}, +o7(a,b){var s +if(b!=null){s=b.x +if(s!=null)return s}return t.aU.b(a)}, +u(a){var s +if(typeof a=="string")return a +if(typeof a=="number"){if(a!==0)return""+a}else if(!0===a)return"true" +else if(!1===a)return"false" +else if(a==null)return"null" +s=J.bg(a) +return s}, +ek(a){var s,r=$.jU +if(r==null)r=$.jU=Symbol("identityHashCode") +s=a[r] +if(s==null){s=Math.random()*0x3fffffff|0 +a[r]=s}return s}, +jV(a,b){var s,r=/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i.exec(a) +if(r==null)return null +if(3>=r.length)return A.j(r,3) +s=r[3] +if(s!=null)return parseInt(a,10) +if(r[2]!=null)return parseInt(a,16) +return null}, +el(a){var s,r,q,p +if(a instanceof A.z)return A.a6(A.ao(a),null) +s=J.bD(a) +if(s===B.O||s===B.R||t.ak.b(a)){r=B.q(a) +if(r!=="Object"&&r!=="")return r +q=a.constructor +if(typeof q=="function"){p=q.name +if(typeof p=="string"&&p!=="Object"&&p!=="")return p}}return A.a6(A.ao(a),null)}, +m7(a){var s,r,q +if(typeof a=="number"||A.dn(a))return J.bg(a) +if(typeof a=="string")return JSON.stringify(a) +if(a instanceof A.aZ)return a.j(0) +s=$.ld() +for(r=0;r<1;++r){q=s[r].da(a) +if(q!=null)return q}return"Instance of '"+A.el(a)+"'"}, +m8(a,b,c){var s,r,q,p +if(c<=500&&b===0&&c===a.length)return String.fromCharCode.apply(null,a) +for(s=b,r="";s>>0,s&1023|56320)}}throw A.f(A.az(a,0,1114111,null,null))}, +bZ(a){if(a.date===void 0)a.date=new Date(a.a) +return a.date}, +m6(a){var s=A.bZ(a).getUTCFullYear()+0 +return s}, +m4(a){var s=A.bZ(a).getUTCMonth()+1 +return s}, +m0(a){var s=A.bZ(a).getUTCDate()+0 +return s}, +m1(a){var s=A.bZ(a).getUTCHours()+0 +return s}, +m3(a){var s=A.bZ(a).getUTCMinutes()+0 +return s}, +m5(a){var s=A.bZ(a).getUTCSeconds()+0 +return s}, +m2(a){var s=A.bZ(a).getUTCMilliseconds()+0 +return s}, +m_(a){var s=a.$thrownJsError +if(s==null)return null +return A.bE(s)}, +jX(a,b){var s +if(a.$thrownJsError==null){s=new Error() +A.N(a,s) +a.$thrownJsError=s +s.stack=b.j(0)}}, +o1(a){throw A.f(A.kJ(a))}, +j(a,b){if(a==null)J.bf(a) +throw A.f(A.iD(a,b))}, +iD(a,b){var s,r="index" +if(!A.kz(b))return new A.av(!0,b,r,null) +s=A.aS(J.bf(a)) +if(b<0||b>=s)return A.I(b,s,a,r) +return A.jY(b,r)}, +kJ(a){return new A.av(!0,a,null,null)}, +f(a){return A.N(a,new Error())}, +N(a,b){var s +if(a==null)a=new A.aO() +b.dartException=a +s=A.oh +if("defineProperty" in Object){Object.defineProperty(b,"message",{get:s}) +b.name=""}else b.toString=s +return b}, +oh(){return J.bg(this.dartException)}, +bH(a,b){throw A.N(a,b==null?new Error():b)}, +bI(a,b,c){var s +if(b==null)b=0 +if(c==null)c=0 +s=Error() +A.bH(A.nc(a,b,c),s)}, +nc(a,b,c){var s,r,q,p,o,n,m,l,k +if(typeof b=="string")s=b +else{r="[]=;add;removeWhere;retainWhere;removeRange;setRange;setInt8;setInt16;setInt32;setUint8;setUint16;setUint32;setFloat32;setFloat64".split(";") +q=r.length +p=b +if(p>q){c=p/q|0 +p%=q}s=r[p]}o=typeof c=="string"?c:"modify;remove from;add to".split(";")[c] +n=t.j.b(a)?"list":"ByteData" +m=a.$flags|0 +l="a " +if((m&4)!==0)k="constant " +else if((m&2)!==0){k="unmodifiable " +l="an "}else k=(m&1)!==0?"fixed-length ":"" +return new A.cN("'"+s+"': Cannot "+o+" "+l+k+n)}, +bd(a){throw A.f(A.bj(a))}, +aP(a){var s,r,q,p,o,n +a=A.oc(a.replace(String({}),"$receiver$")) +s=a.match(/\\\$[a-zA-Z]+\\\$/g) +if(s==null)s=A.t([],t.s) +r=s.indexOf("\\$arguments\\$") +q=s.indexOf("\\$argumentsExpr\\$") +p=s.indexOf("\\$expr\\$") +o=s.indexOf("\\$method\\$") +n=s.indexOf("\\$receiver\\$") +return new A.hQ(a.replace(new RegExp("\\\\\\$arguments\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$argumentsExpr\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$expr\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$method\\\\\\$","g"),"((?:x|[^x])*)").replace(new RegExp("\\\\\\$receiver\\\\\\$","g"),"((?:x|[^x])*)"),r,q,p,o,n)}, +hR(a){return function($expr$){var $argumentsExpr$="$arguments$" +try{$expr$.$method$($argumentsExpr$)}catch(s){return s.message}}(a)}, +k2(a){return function($expr$){try{$expr$.$method$}catch(s){return s.message}}(a)}, +j4(a,b){var s=b==null,r=s?null:b.method +return new A.dZ(a,r,s?null:b.receiver)}, +aU(a){var s +if(a==null)return new A.hm(a) +if(a instanceof A.co){s=a.a +return A.bc(a,s==null?A.c7(s):s)}if(typeof a!=="object")return a +if("dartException" in a)return A.bc(a,a.dartException) +return A.nN(a)}, +bc(a,b){if(t.Q.b(b))if(b.$thrownJsError==null)b.$thrownJsError=a +return b}, +nN(a){var s,r,q,p,o,n,m,l,k,j,i,h,g +if(!("message" in a))return a +s=a.message +if("number" in a&&typeof a.number=="number"){r=a.number +q=r&65535 +if((B.c.aO(r,16)&8191)===10)switch(q){case 438:return A.bc(a,A.j4(A.u(s)+" (Error "+q+")",null)) +case 445:case 5007:A.u(s) +return A.bc(a,new A.cD())}}if(a instanceof TypeError){p=$.l1() +o=$.l2() +n=$.l3() +m=$.l4() +l=$.l7() +k=$.l8() +j=$.l6() +$.l5() +i=$.la() +h=$.l9() +g=p.O(s) +if(g!=null)return A.bc(a,A.j4(A.B(s),g)) +else{g=o.O(s) +if(g!=null){g.method="call" +return A.bc(a,A.j4(A.B(s),g))}else if(n.O(s)!=null||m.O(s)!=null||l.O(s)!=null||k.O(s)!=null||j.O(s)!=null||m.O(s)!=null||i.O(s)!=null||h.O(s)!=null){A.B(s) +return A.bc(a,new A.cD())}}return A.bc(a,new A.eG(typeof s=="string"?s:""))}if(a instanceof RangeError){if(typeof s=="string"&&s.indexOf("call stack")!==-1)return new A.cH() +s=function(b){try{return String(b)}catch(f){}return null}(a) +return A.bc(a,new A.av(!1,null,null,typeof s=="string"?s.replace(/^RangeError:\s*/,""):s))}if(typeof InternalError=="function"&&a instanceof InternalError)if(typeof s=="string"&&s==="too much recursion")return new A.cH() +return a}, +bE(a){var s +if(a instanceof A.co)return a.b +if(a==null)return new A.d8(a) +s=a.$cachedTrace +if(s!=null)return s +s=new A.d8(a) +if(typeof a==="object")a.$cachedTrace=s +return s}, +kQ(a){if(a==null)return J.bK(a) +if(typeof a=="object")return A.ek(a) +return J.bK(a)}, +nU(a,b){var s,r,q,p=a.length +for(s=0;s=0}, +oc(a){if(/[[\]{}()*+?.\\^$|]/.test(a))return a.replace(/[[\]{}()*+?.\\^$|]/g,"\\$&") +return a}, +cf:function cf(){}, +ch:function ch(a,b,c){this.a=a +this.b=b +this.$ti=c}, +cX:function cX(a,b,c){var _=this +_.a=a +_.b=b +_.c=0 +_.d=null +_.$ti=c}, +cg:function cg(){}, +bN:function bN(a,b,c){this.a=a +this.b=b +this.$ti=c}, +cF:function cF(){}, +hQ:function hQ(a,b,c,d,e,f){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f}, +cD:function cD(){}, +dZ:function dZ(a,b,c){this.a=a +this.b=b +this.c=c}, +eG:function eG(a){this.a=a}, +hm:function hm(a){this.a=a}, +co:function co(a,b){this.a=a +this.b=b}, +d8:function d8(a){this.a=a +this.b=null}, +aZ:function aZ(){}, +dD:function dD(){}, +dE:function dE(){}, +ex:function ex(){}, +es:function es(){}, +bM:function bM(a,b){this.a=a +this.b=b}, +eo:function eo(a){this.a=a}, +bp:function bp(a){var _=this +_.a=0 +_.f=_.e=_.d=_.c=_.b=null +_.r=0 +_.$ti=a}, +hc:function hc(a,b){var _=this +_.a=a +_.b=b +_.d=_.c=null}, +bq:function bq(a,b){this.a=a +this.$ti=b}, +cu:function cu(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=null +_.$ti=d}, +iI:function iI(a){this.a=a}, +iJ:function iJ(a){this.a=a}, +iK:function iK(a){this.a=a}, +ct:function ct(a,b){var _=this +_.a=a +_.b=b +_.e=_.d=_.c=null}, +nd(a){return a}, +aT(a,b,c){if(a>>>0!==a||a>=c)throw A.f(A.iD(b,a))}, +aM:function aM(){}, +eb:function eb(){}, +Q:function Q(){}, +e5:function e5(){}, +V:function V(){}, +cx:function cx(){}, +cy:function cy(){}, +e6:function e6(){}, +e7:function e7(){}, +e8:function e8(){}, +e9:function e9(){}, +ea:function ea(){}, +ec:function ec(){}, +ed:function ed(){}, +cz:function cz(){}, +cA:function cA(){}, +d_:function d_(){}, +d0:function d0(){}, +d1:function d1(){}, +d2:function d2(){}, +j8(a,b){var s=b.c +return s==null?b.c=A.dd(a,"bo",[b.x]):s}, +jZ(a){var s=a.w +if(s===6||s===7)return A.jZ(a.x) +return s===11||s===12}, +ma(a){return a.as}, +iF(a){return A.is(v.typeUniverse,a,!1)}, +bz(a1,a2,a3,a4){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,a0=a2.w +switch(a0){case 5:case 1:case 2:case 3:case 4:return a2 +case 6:s=a2.x +r=A.bz(a1,s,a3,a4) +if(r===s)return a2 +return A.kg(a1,r,!0) +case 7:s=a2.x +r=A.bz(a1,s,a3,a4) +if(r===s)return a2 +return A.kf(a1,r,!0) +case 8:q=a2.y +p=A.c9(a1,q,a3,a4) +if(p===q)return a2 +return A.dd(a1,a2.x,p) +case 9:o=a2.x +n=A.bz(a1,o,a3,a4) +m=a2.y +l=A.c9(a1,m,a3,a4) +if(n===o&&l===m)return a2 +return A.je(a1,n,l) +case 10:k=a2.x +j=a2.y +i=A.c9(a1,j,a3,a4) +if(i===j)return a2 +return A.kh(a1,k,i) +case 11:h=a2.x +g=A.bz(a1,h,a3,a4) +f=a2.y +e=A.nK(a1,f,a3,a4) +if(g===h&&e===f)return a2 +return A.ke(a1,g,e) +case 12:d=a2.y +a4+=d.length +c=A.c9(a1,d,a3,a4) +o=a2.x +n=A.bz(a1,o,a3,a4) +if(c===d&&n===o)return a2 +return A.jf(a1,n,c,!0) +case 13:b=a2.x +if(b=0)p+=" "+r[q];++q}return p+"})"}, +kx(a3,a4,a5){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1=", ",a2=null +if(a5!=null){s=a5.length +if(a4==null)a4=A.t([],t.s) +else a2=a4.length +r=a4.length +for(q=s;q>0;--q)B.b.m(a4,"T"+(r+q)) +for(p=t.cK,o="<",n="",q=0;q=0))return A.j(a4,l) +o=o+n+a4[l] +k=a5[q] +j=k.w +if(!(j===2||j===3||j===4||j===5||k===p))o+=" extends "+A.a6(k,a4)}o+=">"}else o="" +p=a3.x +i=a3.y +h=i.a +g=h.length +f=i.b +e=f.length +d=i.c +c=d.length +b=A.a6(p,a4) +for(a="",a0="",q=0;q0){a+=a0+"[" +for(a0="",q=0;q0){a+=a0+"{" +for(a0="",q=0;q "+b}, +a6(a,b){var s,r,q,p,o,n,m,l=a.w +if(l===5)return"erased" +if(l===2)return"dynamic" +if(l===3)return"void" +if(l===1)return"Never" +if(l===4)return"any" +if(l===6){s=a.x +r=A.a6(s,b) +q=s.w +return(q===11||q===12?"("+r+")":r)+"?"}if(l===7)return"FutureOr<"+A.a6(a.x,b)+">" +if(l===8){p=A.nM(a.x) +o=a.y +return o.length>0?p+("<"+A.kF(o,b)+">"):p}if(l===10)return A.nC(a,b) +if(l===11)return A.kx(a,b,null) +if(l===12)return A.kx(a.x,b,a.y) +if(l===13){n=a.x +m=b.length +n=m-1-n +if(!(n>=0&&n0)p+="<"+A.dc(c)+">" +s=a.eC.get(p) +if(s!=null)return s +r=new A.aB(null,null) +r.w=8 +r.x=b +r.y=c +if(c.length>0)r.c=c[0] +r.as=p +q=A.b9(a,r) +a.eC.set(p,q) +return q}, +je(a,b,c){var s,r,q,p,o,n +if(b.w===9){s=b.x +r=b.y.concat(c)}else{r=c +s=b}q=s.as+(";<"+A.dc(r)+">") +p=a.eC.get(q) +if(p!=null)return p +o=new A.aB(null,null) +o.w=9 +o.x=s +o.y=r +o.as=q +n=A.b9(a,o) +a.eC.set(q,n) +return n}, +kh(a,b,c){var s,r,q="+"+(b+"("+A.dc(c)+")"),p=a.eC.get(q) +if(p!=null)return p +s=new A.aB(null,null) +s.w=10 +s.x=b +s.y=c +s.as=q +r=A.b9(a,s) +a.eC.set(q,r) +return r}, +ke(a,b,c){var s,r,q,p,o,n=b.as,m=c.a,l=m.length,k=c.b,j=k.length,i=c.c,h=i.length,g="("+A.dc(m) +if(j>0){s=l>0?",":"" +g+=s+"["+A.dc(k)+"]"}if(h>0){s=l>0?",":"" +g+=s+"{"+A.mK(i)+"}"}r=n+(g+")") +q=a.eC.get(r) +if(q!=null)return q +p=new A.aB(null,null) +p.w=11 +p.x=b +p.y=c +p.as=r +o=A.b9(a,p) +a.eC.set(r,o) +return o}, +jf(a,b,c,d){var s,r=b.as+("<"+A.dc(c)+">"),q=a.eC.get(r) +if(q!=null)return q +s=A.mM(a,b,c,r,d) +a.eC.set(r,s) +return s}, +mM(a,b,c,d,e){var s,r,q,p,o,n,m,l +if(e){s=c.length +r=A.iu(s) +for(q=0,p=0;p0){n=A.bz(a,b,r,0) +m=A.c9(a,c,r,0) +return A.jf(a,n,m,c!==m)}}l=new A.aB(null,null) +l.w=12 +l.x=b +l.y=c +l.as=d +return A.b9(a,l)}, +k9(a,b,c,d){return{u:a,e:b,r:c,s:[],p:0,n:d}}, +kb(a){var s,r,q,p,o,n,m,l=a.r,k=a.s +for(s=l.length,r=0;r=48&&q<=57)r=A.mD(r+1,q,l,k) +else if((((q|32)>>>0)-97&65535)<26||q===95||q===36||q===124)r=A.ka(a,r,l,k,!1) +else if(q===46)r=A.ka(a,r,l,k,!0) +else{++r +switch(q){case 44:break +case 58:k.push(!1) +break +case 33:k.push(!0) +break +case 59:k.push(A.bx(a.u,a.e,k.pop())) +break +case 94:k.push(A.mO(a.u,k.pop())) +break +case 35:k.push(A.de(a.u,5,"#")) +break +case 64:k.push(A.de(a.u,2,"@")) +break +case 126:k.push(A.de(a.u,3,"~")) +break +case 60:k.push(a.p) +a.p=k.length +break +case 62:A.mF(a,k) +break +case 38:A.mE(a,k) +break +case 63:p=a.u +k.push(A.kg(p,A.bx(p,a.e,k.pop()),a.n)) +break +case 47:p=a.u +k.push(A.kf(p,A.bx(p,a.e,k.pop()),a.n)) +break +case 40:k.push(-3) +k.push(a.p) +a.p=k.length +break +case 41:A.mC(a,k) +break +case 91:k.push(a.p) +a.p=k.length +break +case 93:o=k.splice(a.p) +A.kc(a.u,a.e,o) +a.p=k.pop() +k.push(o) +k.push(-1) +break +case 123:k.push(a.p) +a.p=k.length +break +case 125:o=k.splice(a.p) +A.mH(a.u,a.e,o) +a.p=k.pop() +k.push(o) +k.push(-2) +break +case 43:n=l.indexOf("(",r) +k.push(l.substring(r,n)) +k.push(-4) +k.push(a.p) +a.p=k.length +r=n+1 +break +default:throw"Bad character "+q}}}m=k.pop() +return A.bx(a.u,a.e,m)}, +mD(a,b,c,d){var s,r,q=b-48 +for(s=c.length;a=48&&r<=57))break +q=q*10+(r-48)}d.push(q) +return a}, +ka(a,b,c,d,e){var s,r,q,p,o,n,m=b+1 +for(s=c.length;m>>0)-97&65535)<26||r===95||r===36||r===124))q=r>=48&&r<=57 +else q=!0 +if(!q)break}}p=c.substring(b,m) +if(e){s=a.u +o=a.e +if(o.w===9)o=o.x +n=A.mT(s,o.x)[p] +if(n==null)A.bH('No "'+p+'" in "'+A.ma(o)+'"') +d.push(A.it(s,o,n))}else d.push(p) +return m}, +mF(a,b){var s,r=a.u,q=A.k8(a,b),p=b.pop() +if(typeof p=="string")b.push(A.dd(r,p,q)) +else{s=A.bx(r,a.e,p) +switch(s.w){case 11:b.push(A.jf(r,s,q,a.n)) +break +default:b.push(A.je(r,s,q)) +break}}}, +mC(a,b){var s,r,q,p=a.u,o=b.pop(),n=null,m=null +if(typeof o=="number")switch(o){case-1:n=b.pop() +break +case-2:m=b.pop() +break +default:b.push(o) +break}else b.push(o) +s=A.k8(a,b) +o=b.pop() +switch(o){case-3:o=b.pop() +if(n==null)n=p.sEA +if(m==null)m=p.sEA +r=A.bx(p,a.e,o) +q=new A.f_() +q.a=s +q.b=n +q.c=m +b.push(A.ke(p,r,q)) +return +case-4:b.push(A.kh(p,b.pop(),s)) +return +default:throw A.f(A.dx("Unexpected state under `()`: "+A.u(o)))}}, +mE(a,b){var s=b.pop() +if(0===s){b.push(A.de(a.u,1,"0&")) +return}if(1===s){b.push(A.de(a.u,4,"1&")) +return}throw A.f(A.dx("Unexpected extended operation "+A.u(s)))}, +k8(a,b){var s=b.splice(a.p) +A.kc(a.u,a.e,s) +a.p=b.pop() +return s}, +bx(a,b,c){if(typeof c=="string")return A.dd(a,c,a.sEA) +else if(typeof c=="number"){b.toString +return A.mG(a,b,c)}else return c}, +kc(a,b,c){var s,r=c.length +for(s=0;sn)return!1 +m=n-o +l=s.b +k=r.b +j=l.length +i=k.length +if(o+j=d)return!1 +a1=f[b] +b+=3 +if(a00?new Array(q):v.typeUniverse.sEA +for(o=0;o0?new Array(a):v.typeUniverse.sEA}, +aB:function aB(a,b){var _=this +_.a=a +_.b=b +_.r=_.f=_.d=_.c=null +_.w=0 +_.as=_.Q=_.z=_.y=_.x=null}, +f_:function f_(){this.c=this.b=this.a=null}, +ir:function ir(a){this.a=a}, +eX:function eX(){}, +c5:function c5(a){this.a=a}, +mu(){var s,r,q +if(self.scheduleImmediate!=null)return A.nP() +if(self.MutationObserver!=null&&self.document!=null){s={} +r=self.document.createElement("div") +q=self.document.createElement("span") +s.a=null +new self.MutationObserver(A.bB(new A.hY(s),1)).observe(r,{childList:true}) +return new A.hX(s,r,q)}else if(self.setImmediate!=null)return A.nQ() +return A.nR()}, +mv(a){self.scheduleImmediate(A.bB(new A.hZ(t.M.a(a)),0))}, +mw(a){self.setImmediate(A.bB(new A.i_(t.M.a(a)),0))}, +mx(a){A.ja(B.u,t.M.a(a))}, +ja(a,b){return A.mI(a.a/1000|0,b)}, +mI(a,b){var s=new A.ip() +s.cc(a,b) +return s}, +dr(a){return new A.cP(new A.M($.C,a.h("M<0>")),a.h("cP<0>"))}, +dm(a,b){a.$2(0,null) +b.b=!0 +return b.a}, +ba(a,b){A.na(a,b)}, +dl(a,b){b.an(0,a)}, +dk(a,b){b.aP(A.aU(a),A.bE(a))}, +na(a,b){var s,r,q=new A.ix(b),p=new A.iy(b) +if(a instanceof A.M)a.bs(q,p,t.z) +else{s=t.z +if(a instanceof A.M)a.b3(q,p,s) +else{r=new A.M($.C,t._) +r.a=8 +r.c=a +r.bs(q,p,s)}}}, +ds(a){var s=function(b,c){return function(d,e){while(true){try{b(d,e) +break}catch(r){e=r +d=c}}}}(a,1) +return $.C.bN(new A.iC(s),t.H,t.S,t.z)}, +iX(a){var s +if(t.Q.b(a)){s=a.ga6() +if(s!=null)return s}return B.i}, +nl(a,b){if($.C===B.d)return null +return null}, +nm(a,b){if($.C!==B.d)A.nl(a,b) +if(b==null)if(t.Q.b(a)){b=a.ga6() +if(b==null){A.jX(a,B.i) +b=B.i}}else b=B.i +else if(t.Q.b(a))A.jX(a,b) +return new A.aq(a,b)}, +jc(a,b,c){var s,r,q,p,o={},n=o.a=a +for(s=t._;r=n.a,(r&4)!==0;n=a){a=s.a(n.c) +o.a=a}if(n===b){s=A.mf() +b.aF(new A.aq(new A.av(!0,n,null,"Cannot complete a future with itself"),s)) +return}q=b.a&1 +s=n.a=r|q +if((s&24)===0){p=t.F.a(b.c) +b.a=b.a&1|4 +b.c=n +n.bn(p) +return}if(!c)if(b.c==null)n=(s&16)===0||q!==0 +else n=!1 +else n=!0 +if(n){p=b.a9() +b.ai(o.a) +A.bu(b,p) +return}b.a^=2 +A.fO(null,null,b.b,t.M.a(new A.i7(o,b)))}, +bu(a,b){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d={},c=d.a=a +for(s=t.n,r=t.F;;){q={} +p=c.a +o=(p&16)===0 +n=!o +if(b==null){if(n&&(p&1)===0){m=s.a(c.c) +A.iA(m.a,m.b)}return}q.a=b +l=b.a +for(c=b;l!=null;c=l,l=k){c.a=null +A.bu(d.a,c) +q.a=l +k=l.a}p=d.a +j=p.c +q.b=n +q.c=j +if(o){i=c.c +i=(i&1)!==0||(i&15)===8}else i=!0 +if(i){h=c.b.b +if(n){p=p.b===h +p=!(p||p)}else p=!1 +if(p){s.a(j) +A.iA(j.a,j.b) +return}g=$.C +if(g!==h)$.C=h +else g=null +c=c.c +if((c&15)===8)new A.ib(q,d,n).$0() +else if(o){if((c&1)!==0)new A.ia(q,j).$0()}else if((c&2)!==0)new A.i9(d,q).$0() +if(g!=null)$.C=g +c=q.c +if(c instanceof A.M){p=q.a.$ti +p=p.h("bo<2>").b(c)||!p.y[1].b(c)}else p=!1 +if(p){f=q.a.b +if((c.a&24)!==0){e=r.a(f.c) +f.c=null +b=f.al(e) +f.a=c.a&30|f.a&1 +f.c=c.c +d.a=c +continue}else A.jc(c,f,!0) +return}}f=q.a.b +e=r.a(f.c) +f.c=null +b=f.al(e) +c=q.b +p=q.c +if(!c){f.$ti.c.a(p) +f.a=8 +f.c=p}else{s.a(p) +f.a=f.a&1|16 +f.c=p}d.a=f +c=f}}, +kC(a,b){var s +if(t.W.b(a))return b.bN(a,t.z,t.K,t.l) +s=t.x +if(s.b(a))return s.a(a) +throw A.f(A.iW(a,"onError",u.c))}, +nA(){var s,r +for(s=$.c8;s!=null;s=$.c8){$.dq=null +r=s.b +$.c8=r +if(r==null)$.dp=null +s.a.$0()}}, +nI(){$.jk=!0 +try{A.nA()}finally{$.dq=null +$.jk=!1 +if($.c8!=null)$.js().$1(A.kK())}}, +kH(a){var s=new A.eL(a),r=$.dp +if(r==null){$.c8=$.dp=s +if(!$.jk)$.js().$1(A.kK())}else $.dp=r.b=s}, +nF(a){var s,r,q,p=$.c8 +if(p==null){A.kH(a) +$.dq=$.dp +return}s=new A.eL(a) +r=$.dq +if(r==null){s.b=p +$.c8=$.dq=s}else{q=r.b +s.b=q +$.dq=r.b=s +if(q==null)$.dp=s}}, +oU(a,b){A.fP(a,"stream",t.K) +return new A.fq(b.h("fq<0>"))}, +k1(a,b){var s=$.C +if(s===B.d)return A.ja(a,t.M.a(b)) +return A.ja(a,t.M.a(s.by(b)))}, +iA(a,b){A.nF(new A.iB(a,b))}, +kD(a,b,c,d,e){var s,r=$.C +if(r===c)return d.$0() +$.C=c +s=r +try{r=d.$0() +return r}finally{$.C=s}}, +kE(a,b,c,d,e,f,g){var s,r=$.C +if(r===c)return d.$1(e) +$.C=c +s=r +try{r=d.$1(e) +return r}finally{$.C=s}}, +nE(a,b,c,d,e,f,g,h,i){var s,r=$.C +if(r===c)return d.$2(e,f) +$.C=c +s=r +try{r=d.$2(e,f) +return r}finally{$.C=s}}, +fO(a,b,c,d){t.M.a(d) +if(B.d!==c){d=c.by(d) +d=d}A.kH(d)}, +hY:function hY(a){this.a=a}, +hX:function hX(a,b,c){this.a=a +this.b=b +this.c=c}, +hZ:function hZ(a){this.a=a}, +i_:function i_(a){this.a=a}, +ip:function ip(){}, +iq:function iq(a,b){this.a=a +this.b=b}, +cP:function cP(a,b){this.a=a +this.b=!1 +this.$ti=b}, +ix:function ix(a){this.a=a}, +iy:function iy(a){this.a=a}, +iC:function iC(a){this.a=a}, +aq:function aq(a,b){this.a=a +this.b=b}, +cR:function cR(){}, +bt:function bt(a,b){this.a=a +this.$ti=b}, +aR:function aR(a,b,c,d,e){var _=this +_.a=null +_.b=a +_.c=b +_.d=c +_.e=d +_.$ti=e}, +M:function M(a,b){var _=this +_.a=0 +_.b=a +_.c=null +_.$ti=b}, +i4:function i4(a,b){this.a=a +this.b=b}, +i8:function i8(a,b){this.a=a +this.b=b}, +i7:function i7(a,b){this.a=a +this.b=b}, +i6:function i6(a,b){this.a=a +this.b=b}, +i5:function i5(a,b){this.a=a +this.b=b}, +ib:function ib(a,b,c){this.a=a +this.b=b +this.c=c}, +ic:function ic(a,b){this.a=a +this.b=b}, +id:function id(a){this.a=a}, +ia:function ia(a,b){this.a=a +this.b=b}, +i9:function i9(a,b){this.a=a +this.b=b}, +eL:function eL(a){this.a=a +this.b=null}, +cJ:function cJ(){}, +hO:function hO(a,b){this.a=a +this.b=b}, +hP:function hP(a,b){this.a=a +this.b=b}, +fq:function fq(a){this.$ti=a}, +di:function di(){}, +iB:function iB(a,b){this.a=a +this.b=b}, +fj:function fj(){}, +ig:function ig(a,b){this.a=a +this.b=b}, +ih:function ih(a,b,c){this.a=a +this.b=b +this.c=c}, +jS(a,b,c){return b.h("@<0>").B(c).h("jR<1,2>").a(A.nU(a,new A.bp(b.h("@<0>").B(c).h("bp<1,2>"))))}, +hd(a,b){return new A.bp(a.h("@<0>").B(b).h("bp<1,2>"))}, +cv(a){return new A.cY(a.h("cY<0>"))}, +jd(){var s=Object.create(null) +s[""]=s +delete s[""] +return s}, +mB(a,b,c){var s=new A.bw(a,b,c.h("bw<0>")) +s.c=a.e +return s}, +jT(a,b){var s,r,q=A.cv(b) +for(s=a.length,r=0;r=$.ap.length)return A.j($.ap,-1) +$.ap.pop()}r=s.a +return r.charCodeAt(0)==0?r:r}, +cY:function cY(a){var _=this +_.a=0 +_.f=_.e=_.d=_.c=_.b=null +_.r=0 +_.$ti=a}, +f8:function f8(a){this.a=a +this.c=this.b=null}, +bw:function bw(a,b,c){var _=this +_.a=a +_.b=b +_.d=_.c=null +_.$ti=c}, +c:function c(){}, +w:function w(){}, +hf:function hf(a,b){this.a=a +this.b=b}, +Z:function Z(){}, +d3:function d3(){}, +nB(a,b){var s,r,q,p=null +try{p=JSON.parse(a)}catch(r){s=A.aU(r) +q=A.X(String(s),null,null) +throw A.f(q)}q=A.iz(p) +return q}, +iz(a){var s +if(a==null)return null +if(typeof a!="object")return a +if(!Array.isArray(a))return new A.f4(a,Object.create(null)) +for(s=0;s")) +for(s=a.gA(a);s.p();)B.b.m(r,c.a(s.gt(s))) +if(b)return r +r.$flags=1 +return r}, +br(a,b){var s,r +if(Array.isArray(a))return A.t(a.slice(0),b.h("O<0>")) +s=A.t([],b.h("O<0>")) +for(r=J.aV(a);r.p();)B.b.m(s,r.gt(r)) +return s}, +mi(a){var s +A.em(0,"start") +s=A.mj(a,0,null) +return s}, +mj(a,b,c){var s=a.length +if(b>=s)return"" +return A.m8(a,b,s)}, +m9(a){return new A.ct(a,A.lV(a,!1,!0,!1,!1,""))}, +k0(a,b,c){var s=J.aV(b) +if(!s.p())return a +if(c.length===0){do a+=A.u(s.gt(s)) +while(s.p())}else{a+=A.u(s.gt(s)) +while(s.p())a=a+c+A.u(s.gt(s))}return a}, +mf(){return A.bE(new Error())}, +lD(a){var s=Math.abs(a),r=a<0?"-":"" +if(s>=1000)return""+a +if(s>=100)return r+"0"+s +if(s>=10)return r+"00"+s +return r+"000"+s}, +jJ(a){if(a>=100)return""+a +if(a>=10)return"0"+a +return"00"+a}, +dM(a){if(a>=10)return""+a +return"0"+a}, +fY(a){if(typeof a=="number"||A.dn(a)||a==null)return J.bg(a) +if(typeof a=="string")return JSON.stringify(a) +return A.m7(a)}, +lH(a,b){A.fP(a,"error",t.K) +A.fP(b,"stackTrace",t.l) +A.lG(a,b)}, +dx(a){return new A.dw(a)}, +dv(a,b){return new A.av(!1,null,b,a)}, +iW(a,b,c){return new A.av(!0,a,b,c)}, +jY(a,b){return new A.cE(null,null,!0,a,b,"Value not in range")}, +az(a,b,c,d,e){return new A.cE(b,c,!0,a,d,"Invalid value")}, +hq(a,b,c){if(0>a||a>c)throw A.f(A.az(a,0,c,"start",null)) +if(b!=null){if(a>b||b>c)throw A.f(A.az(b,a,c,"end",null)) +return b}return c}, +em(a,b){if(a<0)throw A.f(A.az(a,0,null,b,null)) +return a}, +I(a,b,c,d){return new A.dU(b,!0,a,d,"Index out of range")}, +G(a){return new A.cN(a)}, +eF(a){return new A.eE(a)}, +cI(a){return new A.c1(a)}, +bj(a){return new A.dF(a)}, +X(a,b,c){return new A.aE(a,b,c)}, +lQ(a,b,c){var s,r +if(A.jp(a)){if(b==="("&&c===")")return"(...)" +return b+"..."+c}s=A.t([],t.s) +B.b.m($.ap,a) +try{A.nz(a,s)}finally{if(0>=$.ap.length)return A.j($.ap,-1) +$.ap.pop()}r=A.k0(b,t.hf.a(s),", ")+c +return r.charCodeAt(0)==0?r:r}, +j1(a,b,c){var s,r +if(A.jp(a))return b+"..."+c +s=new A.ae(b) +B.b.m($.ap,a) +try{r=s +r.a=A.k0(r.a,a,", ")}finally{if(0>=$.ap.length)return A.j($.ap,-1) +$.ap.pop()}s.a+=c +r=s.a +return r.charCodeAt(0)==0?r:r}, +nz(a,b){var s,r,q,p,o,n,m,l=a.gA(a),k=0,j=0 +for(;;){if(!(k<80||j<3))break +if(!l.p())return +s=A.u(l.gt(l)) +B.b.m(b,s) +k+=s.length+2;++j}if(!l.p()){if(j<=5)return +if(0>=b.length)return A.j(b,-1) +r=b.pop() +if(0>=b.length)return A.j(b,-1) +q=b.pop()}else{p=l.gt(l);++j +if(!l.p()){if(j<=4){B.b.m(b,A.u(p)) +return}r=A.u(p) +if(0>=b.length)return A.j(b,-1) +q=b.pop() +k+=r.length+2}else{o=l.gt(l);++j +for(;l.p();p=o,o=n){n=l.gt(l);++j +if(j>100){for(;;){if(!(k>75&&j>3))break +if(0>=b.length)return A.j(b,-1) +k-=b.pop().length+2;--j}B.b.m(b,"...") +return}}q=A.u(p) +r=A.u(o) +k+=r.length+q.length+4}}if(j>b.length+2){k+=5 +m="..."}else m=null +for(;;){if(!(k>80&&b.length>3))break +if(0>=b.length)return A.j(b,-1) +k-=b.pop().length+2 +if(m==null){k+=5 +m="..."}}if(m!=null)B.b.m(b,m) +B.b.m(b,q) +B.b.m(b,r)}, +j7(a,b,c,d){var s +if(B.h===c){s=B.e.gu(a) +b=B.e.gu(b) +return A.j9(A.b6(A.b6($.iR(),s),b))}if(B.h===d){s=B.e.gu(a) +b=B.e.gu(b) +c=J.bK(c) +return A.j9(A.b6(A.b6(A.b6($.iR(),s),b),c))}s=B.e.gu(a) +b=B.e.gu(b) +c=J.bK(c) +d=J.bK(d) +d=A.j9(A.b6(A.b6(A.b6(A.b6($.iR(),s),b),c),d)) +return d}, +iO(a){A.ob(a)}, +jb(a6,a7,a8){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1,a2,a3,a4,a5=null +a8=a6.length +s=a7+5 +if(a8>=s){r=a7+4 +if(!(r>>0 +if(n===0)return A.k3(a7>0||a8=14)B.b.l(m,7,a8) +l=m[1] +if(l>=a7)if(A.kG(a6,a7,l,20,m)===20)m[7]=l +k=m[2]+1 +j=m[3] +i=m[4] +h=m[5] +g=m[6] +if(gl+3)){r=j>a7 +d=0 +if(!(r&&j+1===i)){if(!B.a.G(a6,"\\",i))if(k>a7)q=B.a.G(a6,"\\",k-1)||B.a.G(a6,"\\",k-2) +else q=!1 +else q=!0 +if(!q){if(!(hi+2&&B.a.G(a6,"/..",h-3) +else q=!0 +if(!q)if(l===a7+4){if(B.a.G(a6,"file",a7)){if(k<=a7){if(!B.a.G(a6,"/",i)){c="file:///" +n=3}else{c="file://" +n=2}a6=c+B.a.n(a6,i,a8) +l-=a7 +s=n-a7 +h+=s +g+=s +a8=a6.length +a7=d +k=7 +j=7 +i=7}else if(i===h){s=a7===0 +s +if(s){a6=B.a.a4(a6,i,h,"/");++h;++g;++a8}else{a6=B.a.n(a6,a7,i)+"/"+B.a.n(a6,h,a8) +l-=a7 +k-=a7 +j-=a7 +i-=a7 +s=1-a7 +h+=s +g+=s +a8=a6.length +a7=d}}e="file"}else if(B.a.G(a6,"http",a7)){if(r&&j+3===i&&B.a.G(a6,"80",j+1)){s=a7===0 +s +if(s){a6=B.a.a4(a6,j,i,"") +i-=3 +h-=3 +g-=3 +a8-=3}else{a6=B.a.n(a6,a7,j)+B.a.n(a6,i,a8) +l-=a7 +k-=a7 +j-=a7 +s=3+a7 +i-=s +h-=s +g-=s +a8=a6.length +a7=d}}e="http"}}else if(l===s&&B.a.G(a6,"https",a7)){if(r&&j+4===i&&B.a.G(a6,"443",j+1)){s=a7===0 +s +if(s){a6=B.a.a4(a6,j,i,"") +i-=4 +h-=4 +g-=4 +a8-=3}else{a6=B.a.n(a6,a7,j)+B.a.n(a6,i,a8) +l-=a7 +k-=a7 +j-=a7 +s=4+a7 +i-=s +h-=s +g-=s +a8=a6.length +a7=d}}e="https"}f=!q}}}}if(f){if(a7>0||a8a7)e=A.n0(a6,a7,l) +else{if(l===a7)A.c6(a6,a7,"Invalid empty scheme") +e=""}b=a5 +if(k>a7){a=l+3 +a0=a=c)n=0 +else{if(!(q>=0&&q=0&&b=0&&r=97&&o<=102)continue +if(p===46){if(q-1===b)return new A.aE(n,a,q) +r=q +break}return new A.aE("Unexpected character",a,q-1)}if(r-1===b)return new A.aE(n,a,r) +return new A.aE("Missing '.' in IPvFuture address",a,r)}if(r===c)return new A.aE("Missing address in IPvFuture address, host, cursor",null,null) +for(;;){if(!(r>=0&&r=0&&a4=a5)j=0 +else{if(!(n=97&&f<=102)g=f-87 +else break $label0$0 +k=h}if(nm){if(j===46){if(k){if(p<=6){A.mq(a3,m,a5,s,p*2) +p+=2 +n=a5 +break}a2.$2(a1,m)}break}o=p*2 +e=B.c.aO(l,8) +if(!(o<16))return A.j(s,o) +s[o]=e;++o +if(!(o<16))return A.j(s,o) +s[o]=l&255;++p +if(j===58){if(p<8){++n +m=n +l=0 +k=!0 +continue}a2.$2(a1,n)}break}if(j===58){if(q<0){d=p+1;++n +q=p +p=d +m=n +continue}a2.$2("only one wildcard `::` is allowed",n)}if(q!==p-1)a2.$2("missing part",n) +break}if(n0){a=c*2 +a0=16-b*2 +B.x.c_(s,a0,16,s,a) +B.x.cQ(s,a,a0,0)}}return s}, +ki(a,b,c,d,e,f,g){return new A.df(a,b,c,d,e,f,g)}, +kj(a){if(a==="http")return 80 +if(a==="https")return 443 +return 0}, +c6(a,b,c){throw A.f(A.X(c,a,b))}, +mZ(a,b){var s=A.kj(b) +if(a===s)return null +return a}, +mX(a,b,c,d){var s,r,q,p,o,n,m,l,k +if(b===c)return"" +s=a.length +if(!(b>=0&&b=0&&r=b&&o=b&&s=0&&r=o){if(h==null)h=new A.ae("") +if(q=0&&r=n){if(p==null)p=new A.ae("") +if(q=k)return"%" +s=b+1 +if(!(s>=0&&s=0))return A.j(a,l) +q=a.charCodeAt(l) +p=A.iH(r) +o=A.iH(q) +if(p<0||o<0)return"%" +n=p*16+o +if(n<127){if(!(n>=0))return A.j(m,n) +l=(m.charCodeAt(n)&1)!==0}else l=!1 +if(l)return A.jW(c&&65<=n&&90>=n?(n|32)>>>0:n) +if(r>=97||q>=97)return B.a.n(a,b,b+3).toUpperCase() +return null}, +jg(a){var s,r,q,p,o,n,m,l,k="0123456789ABCDEF" +if(a<=127){s=new Uint8Array(3) +s[0]=37 +r=a>>>4 +if(!(r<16))return A.j(k,r) +s[1]=k.charCodeAt(r) +s[2]=k.charCodeAt(a&15)}else{if(a>2047)if(a>65535){q=240 +p=4}else{q=224 +p=3}else{q=192 +p=2}r=3*p +s=new Uint8Array(r) +for(o=0;--p,p>=0;q=128){n=B.c.cA(a,6*p)&63|q +if(!(o>>4 +if(!(l<16))return A.j(k,l) +if(!(m=0&&q=m)return A.j(s,-1) +s.pop() +if(s.length===0)B.b.m(s,"")}p=!0}else{p="."===n +if(!p)B.b.m(s,n)}}if(p)B.b.m(s,"") +return B.b.W(s,"/")}, +n4(a,b){var s,r,q,p,o,n +if(!A.km(a))return!b?A.kk(a):a +s=A.t([],t.s) +for(r=a.split("/"),q=r.length,p=!1,o=0;o=s.length)return A.j(s,-1) +s.pop()}else B.b.m(s,"..")}else{p="."===n +if(!p)B.b.m(s,n)}}r=s.length +if(r!==0)if(r===1){if(0>=r)return A.j(s,0) +r=s[0].length===0}else r=!1 +else r=!0 +if(r)return"./" +if(p||B.b.gaZ(s)==="..")B.b.m(s,"") +if(!b){if(0>=s.length)return A.j(s,0) +B.b.l(s,0,A.kk(s[0]))}return B.b.W(s,"/")}, +kk(a){var s,r,q,p=u.f,o=a.length +if(o>=2&&A.kl(a.charCodeAt(0)))for(s=1;sb)throw A.f(A.X(k,a,r)) +while(p!==44){B.b.m(j,r);++r +for(o=-1;r=0))return A.j(a,r) +p=a.charCodeAt(r) +if(p===61){if(o<0)o=r}else if(p===59||p===44)break}if(o>=0)B.b.m(j,o) +else{n=B.b.gaZ(j) +if(p!==44||r!==n+7||!B.a.G(a,"base64",n+1))throw A.f(A.X("Expecting '='",a,r)) +break}}B.b.m(j,r) +m=r+1 +if((j.length&1)===1)a=B.B.d0(0,a,m,s) +else{l=A.kn(a,m,s,256,!0,!1) +if(l!=null)a=B.a.a4(a,m,s,l)}return new A.hS(a,j,c)}, +kG(a,b,c,d,e){var s,r,q,p,o,n='\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe3\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x0e\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xea\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\n\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xeb\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xeb\xeb\xeb\x8b\xeb\xeb\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xeb\x83\xeb\xeb\x8b\xeb\x8b\xeb\xcd\x8b\xeb\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x92\x83\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\x8b\xeb\x8b\xeb\x8b\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xebD\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x12D\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\xe5\xe5\xe5\x05\xe5D\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe8\x8a\xe5\xe5\x05\xe5\x05\xe5\xcd\x05\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x8a\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05f\x05\xe5\x05\xe5\xac\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\xe5\xe5\xe5\x05\xe5D\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5\x8a\xe5\xe5\x05\xe5\x05\xe5\xcd\x05\xe5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x8a\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05f\x05\xe5\x05\xe5\xac\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7D\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\xe7\xe7\xe7\xe7\xe7\xe7\xcd\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\xe7\x07\x07\x07\x07\x07\x07\x07\x07\x07\xe7\xe7\xe7\xe7\xe7\xac\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7D\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\xe7\xe7\xe7\xe7\xe7\xe7\xcd\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\xe7\x8a\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\xe7\xe7\xe7\xe7\xe7\xac\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\x05\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x10\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x12\n\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\v\n\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xec\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\xec\xec\xec\f\xec\xec\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\xec\xec\xec\xec\f\xec\f\xec\xcd\f\xec\f\f\f\f\f\f\f\f\f\xec\f\f\f\f\f\f\f\f\f\f\xec\f\xec\f\xec\f\xed\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xed\xed\xed\r\xed\xed\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\xed\xed\xed\xed\r\xed\r\xed\xed\r\xed\r\r\r\r\r\r\r\r\r\xed\r\r\r\r\r\r\r\r\r\r\xed\r\xed\r\xed\r\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xea\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x0f\xea\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe1\xe1\x01\xe1\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xe1\xe9\xe1\xe1\x01\xe1\x01\xe1\xcd\x01\xe1\x01\x01\x01\x01\x01\x01\x01\x01\x01\t\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"\x01\xe1\x01\xe1\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x11\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xe9\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\v\t\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\x13\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xeb\xeb\v\xeb\xeb\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\v\xeb\xea\xeb\xeb\v\xeb\v\xeb\xcd\v\xeb\v\v\v\v\v\v\v\v\v\xea\v\v\v\v\v\v\v\v\v\v\xeb\v\xeb\v\xeb\xac\xf5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\xf5\x15\xf5\x15\x15\xf5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xf5\xf5\xf5\xf5\xf5\xf5' +for(s=a.length,r=b;r95)q=31 +p=d*96+q +if(!(p<2112))return A.j(n,p) +o=n.charCodeAt(p) +d=o&31 +B.b.l(e,o>>>5,r)}return d}, +b_:function b_(a,b,c){this.a=a +this.b=b +this.c=c}, +b0:function b0(a){this.a=a}, +E:function E(){}, +dw:function dw(a){this.a=a}, +aO:function aO(){}, +av:function av(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +cE:function cE(a,b,c,d,e,f){var _=this +_.e=a +_.f=b +_.a=c +_.b=d +_.c=e +_.d=f}, +dU:function dU(a,b,c,d,e){var _=this +_.f=a +_.a=b +_.b=c +_.c=d +_.d=e}, +cN:function cN(a){this.a=a}, +eE:function eE(a){this.a=a}, +c1:function c1(a){this.a=a}, +dF:function dF(a){this.a=a}, +eg:function eg(){}, +cH:function cH(){}, +i3:function i3(a){this.a=a}, +aE:function aE(a,b,c){this.a=a +this.b=b +this.c=c}, +e:function e(){}, +L:function L(){}, +z:function z(){}, +ft:function ft(){}, +ae:function ae(a){this.a=a}, +hT:function hT(a){this.a=a}, +df:function df(a,b,c,d,e,f,g){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f +_.r=g +_.y=_.w=$}, +hS:function hS(a,b,c){this.a=a +this.b=b +this.c=c}, +d5:function d5(a,b,c,d,e,f,g,h){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f +_.r=g +_.w=h +_.x=null}, +eR:function eR(a,b,c,d,e,f,g){var _=this +_.a=a +_.b=b +_.c=c +_.d=d +_.e=e +_.f=f +_.r=g +_.y=_.w=$}, +jC(){var s=document.createElement("a") +s.toString +return s}, +my(a,b){var s +for(s=J.aV(b);s.p();)a.appendChild(s.gt(s)).toString}, +lF(a,b,c){var s,r=document.body +r.toString +s=t.ac +return t.h.a(new A.aQ(new A.W(B.p.L(r,a,b,c)),s.h("S(c.E)").a(new A.fX()),s.h("aQ")).gX(0))}, +cn(a){var s,r,q="element tag unavailable" +try{s=a.tagName +s.toString +q=s}catch(r){}return q}, +i1(a,b,c){var s=a.classList +s.toString +if(c){s.add(b) +return!0}else{s.remove(b) +return!1}}, +cU(a,b){var s,r,q=a.classList +q.toString +for(s=b.length,r=0;r"))}, +k7(a){var s=A.jC(),r=t.d.a(window.location) +s=new A.bv(new A.fl(s,r)) +s.ca(a) +return s}, +mz(a,b,c,d){t.h.a(a) +A.B(b) +A.B(c) +t.cr.a(d) +return!0}, +mA(a,b,c,d){var s,r,q,p,o,n +t.h.a(a) +A.B(b) +A.B(c) +s=t.cr.a(d).a +r=s.a +B.l.sbG(r,c) +q=r.hostname +s=s.b +p=!1 +if(q==s.hostname){o=r.port +n=s.port +n.toString +if(o===n){p=r.protocol +s=s.protocol +s.toString +s=p===s}else s=p}else s=p +if(!s){s=!1 +if(q==="")if(r.port===""){s=r.protocol +s=s===":"||s===""}}else s=!0 +return s}, +kd(){var s=t.N,r=A.jT(B.w,s),q=A.t(["TEMPLATE"],t.s),p=t.dG.a(new A.io()) +s=new A.fx(r,A.cv(s),A.cv(s),A.cv(s),null) +s.cb(null,new A.K(B.w,p,t.dv),q,null) +return s}, +nO(a,b){var s=$.C +if(s===B.d)return a +return s.cH(a,b)}, +q:function q(){}, +dt:function dt(){}, +aW:function aW(){}, +du:function du(){}, +bL:function bL(){}, +aY:function aY(){}, +bh:function bh(){}, +aD:function aD(){}, +dI:function dI(){}, +y:function y(){}, +bk:function bk(){}, +fW:function fW(){}, +a4:function a4(){}, +ax:function ax(){}, +dJ:function dJ(){}, +dK:function dK(){}, +dL:function dL(){}, +ci:function ci(){}, +bl:function bl(){}, +dN:function dN(){}, +cj:function cj(){}, +ck:function ck(){}, +cl:function cl(){}, +dO:function dO(){}, +dP:function dP(){}, +eO:function eO(a,b){this.a=a +this.b=b}, +an:function an(a,b){this.a=a +this.$ti=b}, +r:function r(){}, +fX:function fX(){}, +l:function l(){}, +b:function b(){}, +a7:function a7(){}, +bO:function bO(){}, +dQ:function dQ(){}, +dS:function dS(){}, +a8:function a8(){}, +dT:function dT(){}, +b2:function b2(){}, +cp:function cp(){}, +bP:function bP(){}, +bQ:function bQ(){}, +aF:function aF(){}, +aK:function aK(){}, +bW:function bW(){}, +bX:function bX(){}, +e1:function e1(){}, +bY:function bY(){}, +e2:function e2(){}, +hg:function hg(a){this.a=a}, +e3:function e3(){}, +hh:function hh(a){this.a=a}, +a9:function a9(){}, +e4:function e4(){}, +ai:function ai(){}, +W:function W(a){this.a=a}, +o:function o(){}, +cB:function cB(){}, +aa:function aa(){}, +ei:function ei(){}, +aN:function aN(){}, +en:function en(){}, +hr:function hr(a){this.a=a}, +ep:function ep(){}, +ab:function ab(){}, +eq:function eq(){}, +cG:function cG(){}, +ac:function ac(){}, +er:function er(){}, +ad:function ad(){}, +et:function et(){}, +hN:function hN(a){this.a=a}, +a_:function a_(){}, +cL:function cL(){}, +ev:function ev(){}, +ew:function ew(){}, +c2:function c2(){}, +af:function af(){}, +a0:function a0(){}, +ey:function ey(){}, +ez:function ez(){}, +eA:function eA(){}, +ag:function ag(){}, +eB:function eB(){}, +eC:function eC(){}, +aG:function aG(){}, +cM:function cM(){}, +eJ:function eJ(){}, +eK:function eK(){}, +c3:function c3(){}, +c4:function c4(){}, +eP:function eP(){}, +cS:function cS(){}, +f0:function f0(){}, +cZ:function cZ(){}, +fo:function fo(){}, +fv:function fv(){}, +eM:function eM(){}, +i0:function i0(a){this.a=a}, +b8:function b8(a){this.a=a}, +eW:function eW(a){this.a=a}, +j_:function j_(a,b){this.a=a +this.$ti=b}, +cV:function cV(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.$ti=d}, +aH:function aH(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.$ti=d}, +cW:function cW(a,b,c,d,e){var _=this +_.b=a +_.c=b +_.d=c +_.e=d +_.$ti=e}, +i2:function i2(a){this.a=a}, +bv:function bv(a){this.a=a}, +p:function p(){}, +cC:function cC(a){this.a=a}, +hk:function hk(a){this.a=a}, +hj:function hj(a,b,c){this.a=a +this.b=b +this.c=c}, +d4:function d4(){}, +ii:function ii(){}, +ij:function ij(){}, +fx:function fx(a,b,c,d,e){var _=this +_.e=a +_.a=b +_.b=c +_.c=d +_.d=e}, +io:function io(){}, +fw:function fw(){}, +bm:function bm(a,b,c){var _=this +_.a=a +_.b=b +_.c=-1 +_.d=null +_.$ti=c}, +db:function db(){}, +fl:function fl(a,b){this.a=a +this.b=b}, +dh:function dh(a){this.a=a +this.b=0}, +iv:function iv(a){this.a=a}, +eQ:function eQ(){}, +eS:function eS(){}, +eT:function eT(){}, +eU:function eU(){}, +eV:function eV(){}, +eY:function eY(){}, +eZ:function eZ(){}, +f2:function f2(){}, +f3:function f3(){}, +f9:function f9(){}, +fa:function fa(){}, +fb:function fb(){}, +fc:function fc(){}, +fd:function fd(){}, +fe:function fe(){}, +fh:function fh(){}, +fi:function fi(){}, +fk:function fk(){}, +d6:function d6(){}, +d7:function d7(){}, +fm:function fm(){}, +fn:function fn(){}, +fp:function fp(){}, +fy:function fy(){}, +fz:function fz(){}, +d9:function d9(){}, +da:function da(){}, +fA:function fA(){}, +fB:function fB(){}, +fE:function fE(){}, +fF:function fF(){}, +fG:function fG(){}, +fH:function fH(){}, +fI:function fI(){}, +fJ:function fJ(){}, +fK:function fK(){}, +fL:function fL(){}, +fM:function fM(){}, +fN:function fN(){}, +kv(a){var s,r,q +if(a==null)return a +if(typeof a=="string"||typeof a=="number"||A.dn(a))return a +if(A.kN(a))return A.au(a) +s=Array.isArray(a) +s.toString +if(s){r=[] +q=0 +for(;;){s=a.length +s.toString +if(!(q")),r=new A.bt(s,b.h("bt<0>")) +a.then(A.bB(new A.iP(r,b),1),A.bB(new A.iQ(r),1)) +return s}, +iP:function iP(a,b){this.a=a +this.b=b}, +iQ:function iQ(a){this.a=a}, +hl:function hl(a){this.a=a}, +ah:function ah(){}, +e0:function e0(){}, +aj:function aj(){}, +ee:function ee(){}, +ej:function ej(){}, +c_:function c_(){}, +eu:function eu(){}, +dy:function dy(a){this.a=a}, +n:function n(){}, +al:function al(){}, +eD:function eD(){}, +f6:function f6(){}, +f7:function f7(){}, +ff:function ff(){}, +fg:function fg(){}, +fr:function fr(){}, +fs:function fs(){}, +fC:function fC(){}, +fD:function fD(){}, +dz:function dz(){}, +dA:function dA(){}, +fS:function fS(a){this.a=a}, +dB:function dB(){}, +aX:function aX(){}, +ef:function ef(){}, +eN:function eN(){}, +o9(){var s=A.nb(),r=$.jt().getAttribute("data-path") +r.toString +new A.h5(s,s+r,new A.hn()).P()}, +nb(){var s,r,q,p=t.d.a(window.location).href +p.toString +for(s=$.jt().getAttribute("data-path").split("/").length,r=p,q=0;q") +p=A.br(new A.K(r,o.h("as(c.E)").a(A.kP()),q),q.h("T.E"))}else p=null +return new A.as(A.B(s.k(a,"n")),A.by(s.k(a,"h")),A.by(s.k(a,"t")),p)}, +h5:function h5(a,b,c){var _=this +_.a=a +_.b=b +_.c=c +_.f=_.e=_.d=$}, +h7:function h7(a){this.a=a}, +h8:function h8(a){this.a=a}, +h9:function h9(a){this.a=a}, +ha:function ha(a,b){this.a=a +this.b=b}, +h6:function h6(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +hi:function hi(a){this.a=a}, +hL:function hL(a){this.a=a +this.b=$}, +hM:function hM(a){this.a=a}, +as:function as(a,b,c,d){var _=this +_.a=a +_.b=b +_.c=c +_.d=d}, +hI:function hI(a,b){this.a=a +this.b=b}, +hJ:function hJ(a,b){this.a=a +this.b=b}, +hK:function hK(a){this.a=a}, +hn:function hn(){}, +md(a,b){var s=new A.hB(a,b) +s.c9(a,b) +return s}, +mc(a,b,c){var s=new A.hs(a,b,c,A.t([],t.I),A.hd(t.m,t.dr)) +s.c8(a,b,c) +return s}, +nD(a,b,c){var s,r,q,p,o=null,n=B.a.a1(a,"."+b),m=n!==-1?n:0,l=B.a.a2(a,c,m) +if(l===-1)l=B.a.a2(a.toLowerCase(),c.toLowerCase(),m) +if(l===-1)l=B.a.a1(a.toLowerCase(),c.toLowerCase()) +s=t.k +if(l===-1)return A.t([A.bG(B.f,o,a)],s) +else{r=A.bG(B.f,o,B.a.n(a,0,l)) +q=l+c.length +p=B.a.n(a,l,q) +return A.t([r,A.bG(A.t(["match"],t.s),o,p),A.bG(B.f,o,B.a.S(a,q))],s)}}, +lK(a){var s=new A.h0(new A.bt(new A.M($.C,t._),t.fz)) +s.c6(a) +return s}, +jN(a,b,c){var s,r,q +if(b.gar()!=null)if(B.a.v(b.a.toLowerCase(),a)||B.a.v(b.gV(0).toLowerCase(),a))B.b.m(c,b) +if(b.gK(b).length!==0)for(s=b.gK(b),r=s.length,q=0;q").B(b).h("aI<1,2>"))}, +m(a,b){A.U(a).c.a(b) +a.$flags&1&&A.bI(a,29) +a.push(b)}, +bO(a,b){a.$flags&1&&A.bI(a,"removeAt",1) +if(b<0||b>=a.length)throw A.f(A.jY(b,null)) +return a.splice(b,1)[0]}, +b_(a,b,c){var s=A.U(a) +return new A.K(a,s.B(c).h("1(2)").a(b),s.h("@<1>").B(c).h("K<1,2>"))}, +W(a,b){var s,r=A.he(a.length,"",!1,t.N) +for(s=0;s=0&&b0)return a[0] +throw A.f(A.j0())}, +gaZ(a){var s=a.length +if(s>0)return a[s-1] +throw A.f(A.j0())}, +bx(a,b){var s,r +A.U(a).h("S(1)").a(b) +s=a.length +for(r=0;r0){a[0]=q +a[1]=r}return}p=0 +if(n.c.b(null))for(o=0;o0)this.cu(a,p)}, +c0(a){return this.c1(a,null)}, +cu(a,b){var s,r=a.length +for(;s=r-1,r>0;r=s)if(a[s]===null){a[s]=void 0;--b +if(b===0)break}}, +a1(a,b){var s,r=a.length +if(0>=r)return-1 +for(s=0;s"))}, +gu(a){return A.ek(a)}, +gi(a){return a.length}, +k(a,b){if(!(b>=0&&b=0&&b=p){r.d=null +return!1}r.d=q[s] +r.c=s+1 +return!0}, +$iY:1} +J.bS.prototype={ +N(a,b){var s +A.kt(b) +if(ab)return 1 +else if(a===b){if(a===0){s=this.gaY(b) +if(this.gaY(a)===s)return 0 +if(this.gaY(a))return-1 +return 1}return 0}else if(isNaN(a)){if(isNaN(b))return 0 +return 1}else return-1}, +gaY(a){return a===0?1/a<0:a<0}, +bP(a){if(a>0){if(a!==1/0)return Math.round(a)}else if(a>-1/0)return 0-Math.round(0-a) +throw A.f(A.G(""+a+".round()"))}, +j(a){if(a===0&&1/a<0)return"-0.0" +else return""+a}, +gu(a){var s,r,q,p,o=a|0 +if(a===o)return o&536870911 +s=Math.abs(a) +r=Math.log(s)/0.6931471805599453|0 +q=Math.pow(2,r) +p=s<1?s/q:q/s +return((p*9007199254740992|0)+(p*3542243181176521|0))*599197+r*1259&536870911}, +aB(a,b){var s=a%b +if(s===0)return 0 +if(s>0)return s +return s+b}, +bq(a,b){return(a|0)===a?a/b|0:this.cD(a,b)}, +cD(a,b){var s=a/b +if(s>=-2147483648&&s<=2147483647)return s|0 +if(s>0){if(s!==1/0)return Math.floor(s)}else if(s>-1/0)return Math.ceil(s) +throw A.f(A.G("Result of truncating division is "+A.u(s)+": "+A.u(a)+" ~/ "+b))}, +aO(a,b){var s +if(a>0)s=this.bp(a,b) +else{s=b>31?31:b +s=a>>s>>>0}return s}, +cA(a,b){if(0>b)throw A.f(A.kJ(b)) +return this.bp(a,b)}, +bp(a,b){return b>31?0:a>>>b}, +gD(a){return A.bC(t.q)}, +$ia3:1, +$ix:1, +$iH:1} +J.cr.prototype={ +gD(a){return A.bC(t.S)}, +$iA:1, +$ik:1} +J.dY.prototype={ +gD(a){return A.bC(t.i)}, +$iA:1} +J.b3.prototype={ +cP(a,b){var s=b.length,r=a.length +if(s>r)return!1 +return b===this.S(a,r-s)}, +a4(a,b,c,d){var s=A.hq(b,c,a.length) +return a.substring(0,b)+d+a.substring(s)}, +G(a,b,c){var s +if(c<0||c>a.length)throw A.f(A.az(c,0,a.length,null,null)) +s=c+b.length +if(s>a.length)return!1 +return b===a.substring(c,s)}, +C(a,b){return this.G(a,b,0)}, +n(a,b,c){return a.substring(b,A.hq(b,c,a.length))}, +S(a,b){return this.n(a,b,null)}, +d9(a){return a.toLowerCase()}, +aw(a){var s,r,q,p=a.trim(),o=p.length +if(o===0)return p +if(0>=o)return A.j(p,0) +if(p.charCodeAt(0)===133){s=J.lT(p,1) +if(s===o)return""}else s=0 +r=o-1 +if(!(r>=0))return A.j(p,r) +q=p.charCodeAt(r)===133?J.lU(p,r):o +if(s===0&&q===o)return p +return p.substring(s,q)}, +b7(a,b){var s,r +if(0>=b)return"" +if(b===1||a.length===0)return a +if(b!==b>>>0)throw A.f(B.I) +for(s=a,r="";;){if((b&1)===1)r=s+r +b=b>>>1 +if(b===0)break +s+=s}return r}, +d1(a,b,c){var s=b-a.length +if(s<=0)return a +return this.b7(c,s)+a}, +a2(a,b,c){var s +if(c<0||c>a.length)throw A.f(A.az(c,0,a.length,null,null)) +s=a.indexOf(b,c) +return s}, +a1(a,b){return this.a2(a,b,0)}, +cY(a,b){var s=a.length,r=b.length +if(s+r>s)s-=r +return a.lastIndexOf(b,s)}, +ao(a,b,c){var s=a.length +if(c>s)throw A.f(A.az(c,0,s,null,null)) +return A.oe(a,b,c)}, +v(a,b){return this.ao(a,b,0)}, +N(a,b){var s +A.B(b) +if(a===b)s=0 +else s=a>6}r=r+((r&67108863)<<3)&536870911 +r^=r>>11 +return r+((r&16383)<<15)&536870911}, +gD(a){return A.bC(t.N)}, +gi(a){return a.length}, +$iA:1, +$ia3:1, +$ihp:1, +$ih:1} +A.b7.prototype={ +gA(a){return new A.cd(J.aV(this.gY()),A.D(this).h("cd<1,2>"))}, +gi(a){return J.bf(this.gY())}, +gI(a){return J.ll(this.gY())}, +q(a,b){return A.D(this).y[1].a(J.iU(this.gY(),b))}, +j(a){return J.bg(this.gY())}} +A.cd.prototype={ +p(){return this.a.p()}, +gt(a){var s=this.a +return this.$ti.y[1].a(s.gt(s))}, +$iY:1} +A.bi.prototype={ +gY(){return this.a}} +A.cT.prototype={$ii:1} +A.cQ.prototype={ +k(a,b){return this.$ti.y[1].a(J.jw(this.a,b))}, +l(a,b,c){var s=this.$ti +J.lf(this.a,b,s.c.a(s.y[1].a(c)))}, +$ii:1, +$im:1} +A.aI.prototype={ +am(a,b){return new A.aI(this.a,this.$ti.h("@<1>").B(b).h("aI<1,2>"))}, +gY(){return this.a}} +A.bV.prototype={ +j(a){return"LateInitializationError: "+this.a}} +A.hH.prototype={} +A.i.prototype={} +A.T.prototype={ +gA(a){var s=this +return new A.P(s,s.gi(s),A.D(s).h("P"))}, +gI(a){return this.gi(this)===0}, +aA(a,b){return this.c3(0,A.D(this).h("S(T.E)").a(b))}} +A.cK.prototype={ +gcl(){var s=J.bf(this.a),r=this.c +if(r==null||r>s)return s +return r}, +gcB(){var s=J.bf(this.a),r=this.b +if(r>s)return s +return r}, +gi(a){var s,r=J.bf(this.a),q=this.b +if(q>=r)return 0 +s=this.c +if(s==null||s>=r)return r-q +return s-q}, +q(a,b){var s=this,r=s.gcB()+b +if(b<0||r>=s.gcl())throw A.f(A.I(b,s.gi(0),s,"index")) +return J.iU(s.a,r)}, +b5(a,b){var s,r,q,p=this,o=p.b,n=p.a,m=J.bb(n),l=m.gi(n),k=p.c +if(k!=null&&k=o){r.d=null +return!1}r.d=p.q(q,s);++r.c +return!0}, +$iY:1} +A.aL.prototype={ +gA(a){var s=this.a +return new A.cw(s.gA(s),this.b,A.D(this).h("cw<1,2>"))}, +gi(a){var s=this.a +return s.gi(s)}, +gI(a){var s=this.a +return s.gI(s)}, +q(a,b){var s=this.a +return this.b.$1(s.q(s,b))}} +A.cm.prototype={$ii:1} +A.cw.prototype={ +p(){var s=this,r=s.b +if(r.p()){s.a=s.c.$1(r.gt(r)) +return!0}s.a=null +return!1}, +gt(a){var s=this.a +return s==null?this.$ti.y[1].a(s):s}, +$iY:1} +A.K.prototype={ +gi(a){return J.bf(this.a)}, +q(a,b){return this.b.$1(J.iU(this.a,b))}} +A.aQ.prototype={ +gA(a){return new A.cO(J.aV(this.a),this.b,this.$ti.h("cO<1>"))}} +A.cO.prototype={ +p(){var s,r +for(s=this.a,r=this.b;s.p();)if(r.$1(s.gt(s)))return!0 +return!1}, +gt(a){var s=this.a +return s.gt(s)}, +$iY:1} +A.a5.prototype={} +A.dj.prototype={} +A.cf.prototype={ +j(a){return A.j5(this)}, +$iF:1} +A.ch.prototype={ +gi(a){return this.b.length}, +gco(){var s=this.$keys +if(s==null){s=Object.keys(this.a) +this.$keys=s}return s}, +J(a,b){if("__proto__"===b)return!1 +return this.a.hasOwnProperty(b)}, +k(a,b){if(!this.J(0,b))return null +return this.b[this.a[b]]}, +F(a,b){var s,r,q,p +this.$ti.h("~(1,2)").a(b) +s=this.gco() +r=this.b +for(q=s.length,p=0;p=s.b){s.d=null +return!1}s.d=s.a[r] +s.c=r+1 +return!0}, +$iY:1} +A.cg.prototype={ +m(a,b){A.D(this).c.a(b) +A.lC()}} +A.bN.prototype={ +gi(a){return this.b}, +gI(a){return this.b===0}, +gA(a){var s,r=this,q=r.$keys +if(q==null){q=Object.keys(r.a) +r.$keys=q}s=q +return new A.cX(s,s.length,r.$ti.h("cX<1>"))}, +v(a,b){if(typeof b!="string")return!1 +if("__proto__"===b)return!1 +return this.a.hasOwnProperty(b)}} +A.cF.prototype={} +A.hQ.prototype={ +O(a){var s,r,q=this,p=new RegExp(q.a).exec(a) +if(p==null)return null +s=Object.create(null) +r=q.b +if(r!==-1)s.arguments=p[r+1] +r=q.c +if(r!==-1)s.argumentsExpr=p[r+1] +r=q.d +if(r!==-1)s.expr=p[r+1] +r=q.e +if(r!==-1)s.method=p[r+1] +r=q.f +if(r!==-1)s.receiver=p[r+1] +return s}} +A.cD.prototype={ +j(a){return"Null check operator used on a null value"}} +A.dZ.prototype={ +j(a){var s,r=this,q="NoSuchMethodError: method not found: '",p=r.b +if(p==null)return"NoSuchMethodError: "+r.a +s=r.c +if(s==null)return q+p+"' ("+r.a+")" +return q+p+"' on '"+s+"' ("+r.a+")"}} +A.eG.prototype={ +j(a){var s=this.a +return s.length===0?"Error":"Error: "+s}} +A.hm.prototype={ +j(a){return"Throw of null ('"+(this.a===null?"null":"undefined")+"' from JavaScript)"}} +A.co.prototype={} +A.d8.prototype={ +j(a){var s,r=this.b +if(r!=null)return r +r=this.a +s=r!==null&&typeof r==="object"?r.stack:null +return this.b=s==null?"":s}, +$ib5:1} +A.aZ.prototype={ +j(a){var s=this.constructor,r=s==null?null:s.name +return"Closure '"+A.kU(r==null?"unknown":r)+"'"}, +$ibn:1, +gdc(){return this}, +$C:"$1", +$R:1, +$D:null} +A.dD.prototype={$C:"$0",$R:0} +A.dE.prototype={$C:"$2",$R:2} +A.ex.prototype={} +A.es.prototype={ +j(a){var s=this.$static_name +if(s==null)return"Closure of unknown static method" +return"Closure '"+A.kU(s)+"'"}} +A.bM.prototype={ +M(a,b){if(b==null)return!1 +if(this===b)return!0 +if(!(b instanceof A.bM))return!1 +return this.$_target===b.$_target&&this.a===b.a}, +gu(a){return(A.kQ(this.a)^A.ek(this.$_target))>>>0}, +j(a){return"Closure '"+this.$_name+"' of "+("Instance of '"+A.el(this.a)+"'")}} +A.eo.prototype={ +j(a){return"RuntimeError: "+this.a}} +A.bp.prototype={ +gi(a){return this.a}, +gH(a){return new A.bq(this,A.D(this).h("bq<1>"))}, +J(a,b){var s,r +if(typeof b=="string"){s=this.b +if(s==null)return!1 +return s[b]!=null}else{r=this.cW(b) +return r}}, +cW(a){var s=this.d +if(s==null)return!1 +return this.aW(s[this.aV(a)],a)>=0}, +k(a,b){var s,r,q,p,o=null +if(typeof b=="string"){s=this.b +if(s==null)return o +r=s[b] +q=r==null?o:r.b +return q}else if(typeof b=="number"&&(b&0x3fffffff)===b){p=this.c +if(p==null)return o +r=p[b] +q=r==null?o:r.b +return q}else return this.cX(b)}, +cX(a){var s,r,q=this.d +if(q==null)return null +s=q[this.aV(a)] +r=this.aW(s,a) +if(r<0)return null +return s[r].b}, +l(a,b,c){var s,r,q,p,o,n,m=this,l=A.D(m) +l.c.a(b) +l.y[1].a(c) +if(typeof b=="string"){s=m.b +m.bb(s==null?m.b=m.aM():s,b,c)}else if(typeof b=="number"&&(b&0x3fffffff)===b){r=m.c +m.bb(r==null?m.c=m.aM():r,b,c)}else{q=m.d +if(q==null)q=m.d=m.aM() +p=m.aV(b) +o=q[p] +if(o==null)q[p]=[m.aN(b,c)] +else{n=m.aW(o,b) +if(n>=0)o[n].b=c +else o.push(m.aN(b,c))}}}, +ab(a){var s=this +if(s.a>0){s.b=s.c=s.d=s.e=s.f=null +s.a=0 +s.bm()}}, +F(a,b){var s,r,q=this +A.D(q).h("~(1,2)").a(b) +s=q.e +r=q.r +while(s!=null){b.$2(s.a,s.b) +if(r!==q.r)throw A.f(A.bj(q)) +s=s.c}}, +bb(a,b,c){var s,r=A.D(this) +r.c.a(b) +r.y[1].a(c) +s=a[b] +if(s==null)a[b]=this.aN(b,c) +else s.b=c}, +bm(){this.r=this.r+1&1073741823}, +aN(a,b){var s=this,r=A.D(s),q=new A.hc(r.c.a(a),r.y[1].a(b)) +if(s.e==null)s.e=s.f=q +else{r=s.f +r.toString +q.d=r +s.f=r.c=q}++s.a +s.bm() +return q}, +aV(a){return J.bK(a)&1073741823}, +aW(a,b){var s,r +if(a==null)return-1 +s=a.length +for(r=0;r"]=s +delete s[""] +return s}, +$ijR:1} +A.hc.prototype={} +A.bq.prototype={ +gi(a){return this.a.a}, +gI(a){return this.a.a===0}, +gA(a){var s=this.a +return new A.cu(s,s.r,s.e,this.$ti.h("cu<1>"))}, +v(a,b){return this.a.J(0,b)}} +A.cu.prototype={ +gt(a){return this.d}, +p(){var s,r=this,q=r.a +if(r.b!==q.r)throw A.f(A.bj(q)) +s=r.c +if(s==null){r.d=null +return!1}else{r.d=s.a +r.c=s.c +return!0}}, +$iY:1} +A.iI.prototype={ +$1(a){return this.a(a)}, +$S:30} +A.iJ.prototype={ +$2(a,b){return this.a(a,b)}, +$S:18} +A.iK.prototype={ +$1(a){return this.a(A.B(a))}, +$S:38} +A.ct.prototype={ +j(a){return"RegExp/"+this.a+"/"+this.b.flags}, +$ihp:1} +A.aM.prototype={ +gD(a){return B.a1}, +$iA:1, +$iaM:1} +A.eb.prototype={$ik_:1} +A.Q.prototype={ +cn(a,b,c,d){var s=A.az(b,0,c,d,null) +throw A.f(s)}, +bf(a,b,c,d){if(b>>>0!==b||b>c)this.cn(a,b,c,d)}, +$iQ:1} +A.e5.prototype={ +gD(a){return B.a2}, +$iA:1} +A.V.prototype={ +gi(a){return a.length}, +$iv:1} +A.cx.prototype={ +k(a,b){A.aT(b,a,a.length) +return a[b]}, +l(a,b,c){A.kr(c) +a.$flags&2&&A.bI(a) +A.aT(b,a,a.length) +a[b]=c}, +$ii:1, +$ie:1, +$im:1} +A.cy.prototype={ +l(a,b,c){A.aS(c) +a.$flags&2&&A.bI(a) +A.aT(b,a,a.length) +a[b]=c}, +c_(a,b,c,d,e){var s,r,q +t.hb.a(d) +a.$flags&2&&A.bI(a,5) +s=a.length +this.bf(a,b,s,"start") +this.bf(a,c,s,"end") +if(b>c)A.bH(A.az(b,0,c,null,null)) +r=c-b +if(e<0)A.bH(A.dv(e,null)) +if(16-e").b(b))s.be(b) +else s.bi(b)}}, +aP(a,b){var s=this.a +if(this.b)s.aH(new A.aq(a,b)) +else s.aF(new A.aq(a,b))}, +$ifU:1} +A.ix.prototype={ +$1(a){return this.a.$2(0,a)}, +$S:5} +A.iy.prototype={ +$2(a,b){this.a.$2(1,new A.co(a,t.l.a(b)))}, +$S:26} +A.iC.prototype={ +$2(a,b){this.a(A.aS(a),b)}, +$S:15} +A.aq.prototype={ +j(a){return A.u(this.a)}, +$iE:1, +ga6(){return this.b}} +A.cR.prototype={ +aP(a,b){var s=this.a +if((s.a&30)!==0)throw A.f(A.cI("Future already completed")) +s.aF(A.nm(a,b))}, +bB(a){return this.aP(a,null)}, +$ifU:1} +A.bt.prototype={ +an(a,b){var s,r=this.$ti +r.h("1/?").a(b) +s=this.a +if((s.a&30)!==0)throw A.f(A.cI("Future already completed")) +s.bc(r.h("1/").a(b))}, +bA(a){return this.an(0,null)}} +A.aR.prototype={ +cZ(a){if((this.c&15)!==6)return!0 +return this.b.b.b2(t.al.a(this.d),a.a,t.y,t.K)}, +cU(a){var s,r=this,q=r.e,p=null,o=t.z,n=t.K,m=a.a,l=r.b.b +if(t.W.b(q))p=l.d6(q,m,a.b,o,n,t.l) +else p=l.b2(t.x.a(q),m,o,n) +try{o=r.$ti.h("2/").a(p) +return o}catch(s){if(t.eK.b(A.aU(s))){if((r.c&1)!==0)throw A.f(A.dv("The error handler of Future.then must return a value of the returned future's type","onError")) +throw A.f(A.dv("The error handler of Future.catchError must return a value of the future's type","onError"))}else throw s}}} +A.M.prototype={ +b3(a,b,c){var s,r,q,p=this.$ti +p.B(c).h("1/(2)").a(a) +s=$.C +if(s===B.d){if(b!=null&&!t.W.b(b)&&!t.x.b(b))throw A.f(A.iW(b,"onError",u.c))}else{c.h("@<0/>").B(p.c).h("1(2)").a(a) +if(b!=null)b=A.kC(b,s)}r=new A.M(s,c.h("M<0>")) +q=b==null?1:3 +this.ah(new A.aR(r,q,a,b,p.h("@<1>").B(c).h("aR<1,2>"))) +return r}, +bQ(a,b){return this.b3(a,null,b)}, +bs(a,b,c){var s,r=this.$ti +r.B(c).h("1/(2)").a(a) +s=new A.M($.C,c.h("M<0>")) +this.ah(new A.aR(s,19,a,b,r.h("@<1>").B(c).h("aR<1,2>"))) +return s}, +cz(a){this.a=this.a&1|16 +this.c=a}, +ai(a){this.a=a.a&30|this.a&1 +this.c=a.c}, +ah(a){var s,r=this,q=r.a +if(q<=3){a.a=t.F.a(r.c) +r.c=a}else{if((q&4)!==0){s=t._.a(r.c) +if((s.a&24)===0){s.ah(a) +return}r.ai(s)}A.fO(null,null,r.b,t.M.a(new A.i4(r,a)))}}, +bn(a){var s,r,q,p,o,n,m=this,l={} +l.a=a +if(a==null)return +s=m.a +if(s<=3){r=t.F.a(m.c) +m.c=a +if(r!=null){q=a.a +for(p=a;q!=null;p=q,q=o)o=q.a +p.a=r}}else{if((s&4)!==0){n=t._.a(m.c) +if((n.a&24)===0){n.bn(a) +return}m.ai(n)}l.a=m.al(a) +A.fO(null,null,m.b,t.M.a(new A.i8(l,m)))}}, +a9(){var s=t.F.a(this.c) +this.c=null +return this.al(s)}, +al(a){var s,r,q +for(s=a,r=null;s!=null;r=s,s=q){q=s.a +s.a=r}return r}, +bi(a){var s,r=this +r.$ti.c.a(a) +s=r.a9() +r.a=8 +r.c=a +A.bu(r,s)}, +ci(a){var s,r,q=this +if((a.a&16)!==0){s=q.b===a.b +s=!(s||s)}else s=!1 +if(s)return +r=q.a9() +q.ai(a) +A.bu(q,r)}, +aH(a){var s=this.a9() +this.cz(a) +A.bu(this,s)}, +bc(a){var s=this.$ti +s.h("1/").a(a) +if(s.h("bo<1>").b(a)){this.be(a) +return}this.cf(a)}, +cf(a){var s=this +s.$ti.c.a(a) +s.a^=2 +A.fO(null,null,s.b,t.M.a(new A.i6(s,a)))}, +be(a){A.jc(this.$ti.h("bo<1>").a(a),this,!1) +return}, +aF(a){this.a^=2 +A.fO(null,null,this.b,t.M.a(new A.i5(this,a)))}, +$ibo:1} +A.i4.prototype={ +$0(){A.bu(this.a,this.b)}, +$S:0} +A.i8.prototype={ +$0(){A.bu(this.b,this.a.a)}, +$S:0} +A.i7.prototype={ +$0(){A.jc(this.a.a,this.b,!0)}, +$S:0} +A.i6.prototype={ +$0(){this.a.bi(this.b)}, +$S:0} +A.i5.prototype={ +$0(){this.a.aH(this.b)}, +$S:0} +A.ib.prototype={ +$0(){var s,r,q,p,o,n,m,l,k=this,j=null +try{q=k.a.a +j=q.b.b.d5(t.fO.a(q.d),t.z)}catch(p){s=A.aU(p) +r=A.bE(p) +if(k.c&&t.n.a(k.b.a.c).a===s){q=k.a +q.c=t.n.a(k.b.a.c)}else{q=s +o=r +if(o==null)o=A.iX(q) +n=k.a +n.c=new A.aq(q,o) +q=n}q.b=!0 +return}if(j instanceof A.M&&(j.a&24)!==0){if((j.a&16)!==0){q=k.a +q.c=t.n.a(j.c) +q.b=!0}return}if(j instanceof A.M){m=k.b.a +l=new A.M(m.b,m.$ti) +j.b3(new A.ic(l,m),new A.id(l),t.H) +q=k.a +q.c=l +q.b=!1}}, +$S:0} +A.ic.prototype={ +$1(a){this.a.ci(this.b)}, +$S:4} +A.id.prototype={ +$2(a,b){A.c7(a) +t.l.a(b) +this.a.aH(new A.aq(a,b))}, +$S:16} +A.ia.prototype={ +$0(){var s,r,q,p,o,n,m,l +try{q=this.a +p=q.a +o=p.$ti +n=o.c +m=n.a(this.b) +q.c=p.b.b.b2(o.h("2/(1)").a(p.d),m,o.h("2/"),n)}catch(l){s=A.aU(l) +r=A.bE(l) +q=s +p=r +if(p==null)p=A.iX(q) +o=this.a +o.c=new A.aq(q,p) +o.b=!0}}, +$S:0} +A.i9.prototype={ +$0(){var s,r,q,p,o,n,m,l=this +try{s=t.n.a(l.a.a.c) +p=l.b +if(p.a.cZ(s)&&p.a.e!=null){p.c=p.a.cU(s) +p.b=!1}}catch(o){r=A.aU(o) +q=A.bE(o) +p=t.n.a(l.a.a.c) +if(p.a===r){n=l.b +n.c=p +p=n}else{p=r +n=q +if(n==null)n=A.iX(p) +m=l.b +m.c=new A.aq(p,n) +p=m}p.b=!0}}, +$S:0} +A.eL.prototype={} +A.cJ.prototype={ +gi(a){var s,r,q=this,p={},o=new A.M($.C,t.fJ) +p.a=0 +s=A.D(q) +r=s.h("~(1)?").a(new A.hO(p,q)) +t.bn.a(new A.hP(p,o)) +A.am(q.a,q.b,r,!1,s.c) +return o}} +A.hO.prototype={ +$1(a){A.D(this.b).c.a(a);++this.a.a}, +$S(){return A.D(this.b).h("~(1)")}} +A.hP.prototype={ +$0(){var s=this.b,r=s.$ti,q=r.h("1/").a(this.a.a),p=s.a9() +r.c.a(q) +s.a=8 +s.c=q +A.bu(s,p)}, +$S:0} +A.fq.prototype={} +A.di.prototype={$ik5:1} +A.iB.prototype={ +$0(){A.lH(this.a,this.b)}, +$S:0} +A.fj.prototype={ +d7(a){var s,r,q +t.M.a(a) +try{if(B.d===$.C){a.$0() +return}A.kD(null,null,this,a,t.H)}catch(q){s=A.aU(q) +r=A.bE(q) +A.iA(A.c7(s),t.l.a(r))}}, +d8(a,b,c){var s,r,q +c.h("~(0)").a(a) +c.a(b) +try{if(B.d===$.C){a.$1(b) +return}A.kE(null,null,this,a,b,t.H,c)}catch(q){s=A.aU(q) +r=A.bE(q) +A.iA(A.c7(s),t.l.a(r))}}, +by(a){return new A.ig(this,t.M.a(a))}, +cH(a,b){return new A.ih(this,b.h("~(0)").a(a),b)}, +d5(a,b){b.h("0()").a(a) +if($.C===B.d)return a.$0() +return A.kD(null,null,this,a,b)}, +b2(a,b,c,d){c.h("@<0>").B(d).h("1(2)").a(a) +d.a(b) +if($.C===B.d)return a.$1(b) +return A.kE(null,null,this,a,b,c,d)}, +d6(a,b,c,d,e,f){d.h("@<0>").B(e).B(f).h("1(2,3)").a(a) +e.a(b) +f.a(c) +if($.C===B.d)return a.$2(b,c) +return A.nE(null,null,this,a,b,c,d,e,f)}, +bN(a,b,c,d){return b.h("@<0>").B(c).B(d).h("1(2,3)").a(a)}} +A.ig.prototype={ +$0(){return this.a.d7(this.b)}, +$S:0} +A.ih.prototype={ +$1(a){var s=this.c +return this.a.d8(this.b,s.a(a),s)}, +$S(){return this.c.h("~(0)")}} +A.cY.prototype={ +gA(a){var s=this,r=new A.bw(s,s.r,A.D(s).h("bw<1>")) +r.c=s.e +return r}, +gi(a){return this.a}, +gI(a){return this.a===0}, +v(a,b){var s,r +if(typeof b=="string"&&b!=="__proto__"){s=this.b +if(s==null)return!1 +return t.g.a(s[b])!=null}else{r=this.ck(b) +return r}}, +ck(a){var s=this.d +if(s==null)return!1 +return this.aL(s[this.aI(a)],a)>=0}, +m(a,b){var s,r,q=this +A.D(q).c.a(b) +if(typeof b=="string"&&b!=="__proto__"){s=q.b +return q.bg(s==null?q.b=A.jd():s,b)}else if(typeof b=="number"&&(b&1073741823)===b){r=q.c +return q.bg(r==null?q.c=A.jd():r,b)}else return q.cd(0,b)}, +cd(a,b){var s,r,q,p=this +A.D(p).c.a(b) +s=p.d +if(s==null)s=p.d=A.jd() +r=p.aI(b) +q=s[r] +if(q==null)s[r]=[p.aG(b)] +else{if(p.aL(q,b)>=0)return!1 +q.push(p.aG(b))}return!0}, +d3(a,b){var s +if(b!=="__proto__")return this.cr(this.b,b) +else{s=this.cq(0,b) +return s}}, +cq(a,b){var s,r,q,p,o=this,n=o.d +if(n==null)return!1 +s=o.aI(b) +r=n[s] +q=o.aL(r,b) +if(q<0)return!1 +p=r.splice(q,1)[0] +if(0===r.length)delete n[s] +o.bt(p) +return!0}, +bg(a,b){A.D(this).c.a(b) +if(t.g.a(a[b])!=null)return!1 +a[b]=this.aG(b) +return!0}, +cr(a,b){var s +if(a==null)return!1 +s=t.g.a(a[b]) +if(s==null)return!1 +this.bt(s) +delete a[b] +return!0}, +bh(){this.r=this.r+1&1073741823}, +aG(a){var s,r=this,q=new A.f8(A.D(r).c.a(a)) +if(r.e==null)r.e=r.f=q +else{s=r.f +s.toString +q.c=s +r.f=s.b=q}++r.a +r.bh() +return q}, +bt(a){var s=this,r=a.c,q=a.b +if(r==null)s.e=q +else r.b=q +if(q==null)s.f=r +else q.c=r;--s.a +s.bh()}, +aI(a){return J.bK(a)&1073741823}, +aL(a,b){var s,r +if(a==null)return-1 +s=a.length +for(r=0;r"))}, +q(a,b){return this.k(a,b)}, +gI(a){return this.gi(a)===0}, +b_(a,b,c){var s=A.ao(a) +return new A.K(a,s.B(c).h("1(c.E)").a(b),s.h("@").B(c).h("K<1,2>"))}, +b5(a,b){var s,r,q,p,o=this +if(o.gI(a)){s=J.j2(0,A.ao(a).h("c.E")) +return s}r=o.k(a,0) +q=A.he(o.gi(a),r,!0,A.ao(a).h("c.E")) +for(p=1;p").B(b).h("aI<1,2>"))}, +cQ(a,b,c,d){var s +A.ao(a).h("c.E?").a(d) +A.hq(b,c,this.gi(a)) +for(s=b;s").a(b));s.p();)this.m(0,s.gt(s))}, +j(a){return A.j1(this,"{","}")}, +W(a,b){var s,r,q=this.gA(this) +if(!q.p())return"" +s=J.bg(q.gt(q)) +if(!q.p())return s +if(b.length===0){r=s +do r+=A.u(q.gt(q)) +while(q.p())}else{r=s +do r=r+b+A.u(q.gt(q)) +while(q.p())}return r.charCodeAt(0)==0?r:r}, +q(a,b){var s,r +A.em(b,"index") +s=this.gA(this) +for(r=b;s.p();){if(r===0)return s.gt(s);--r}throw A.f(A.I(b,b-r,this,"index"))}, +$ii:1, +$ie:1, +$iar:1} +A.d3.prototype={} +A.f4.prototype={ +k(a,b){var s,r=this.b +if(r==null)return this.c.k(0,b) +else if(typeof b!="string")return null +else{s=r[b] +return typeof s=="undefined"?this.cp(b):s}}, +gi(a){return this.b==null?this.c.a:this.aj().length}, +gH(a){var s +if(this.b==null){s=this.c +return new A.bq(s,A.D(s).h("bq<1>"))}return new A.f5(this)}, +J(a,b){if(this.b==null)return this.c.J(0,b) +return Object.prototype.hasOwnProperty.call(this.a,b)}, +F(a,b){var s,r,q,p,o=this +t.u.a(b) +if(o.b==null)return o.c.F(0,b) +s=o.aj() +for(r=0;r=0&&b"))}return s}, +v(a,b){return this.a.J(0,b)}} +A.dC.prototype={ +d0(a3,a4,a5,a6){var s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,a0="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a1="Invalid base64 encoding length ",a2=a4.length +a6=A.hq(a5,a6,a2) +s=$.lb() +for(r=s.length,q=a5,p=q,o=null,n=-1,m=-1,l=0;q=0&&e=0){if(!(d<64))return A.j(a0,d) +e=a0.charCodeAt(d) +if(e===j)continue +j=e}else{if(d===-1){if(n<0){g=o==null?null:o.a.length +if(g==null)g=0 +n=g+(q-p) +m=q}++l +if(j===61)continue}j=e}if(d!==-2){if(o==null){o=new A.ae("") +g=o}else g=o +g.a+=B.a.n(a4,p,q) +c=A.jW(j) +g.a+=c +p=k +continue}}throw A.f(A.X("Invalid base64 data",a4,q))}if(o!=null){a2=B.a.n(a4,p,a6) +a2=o.a+=a2 +r=a2.length +if(n>=0)A.jD(a4,m,a6,n,l,r) +else{b=B.c.aB(r-1,4)+1 +if(b===1)throw A.f(A.X(a1,a4,a6)) +while(b<4){a2+="=" +o.a=a2;++b}}a2=o.a +return B.a.a4(a4,a5,a6,a2.charCodeAt(0)==0?a2:a2)}a=a6-a5 +if(n>=0)A.jD(a4,m,a6,n,l,a) +else{b=B.c.aB(a,4) +if(b===1)throw A.f(A.X(a1,a4,a6)) +if(b>1)a4=B.a.a4(a4,a6,a6,b===2?"==":"=")}return a4}} +A.fT.prototype={} +A.ce.prototype={} +A.dG.prototype={} +A.e_.prototype={ +bD(a,b,c){var s=A.nB(b,this.gcN().a) +return s}, +gcN(){return B.S}} +A.hb.prototype={} +A.b_.prototype={ +M(a,b){var s +if(b==null)return!1 +s=!1 +if(b instanceof A.b_)if(this.a===b.a)s=this.b===b.b +return s}, +gu(a){return A.j7(this.a,this.b,B.h,B.h)}, +N(a,b){var s +t.dy.a(b) +s=B.c.N(this.a,b.a) +if(s!==0)return s +return B.c.N(this.b,b.b)}, +j(a){var s=this,r=A.lD(A.m6(s)),q=A.dM(A.m4(s)),p=A.dM(A.m0(s)),o=A.dM(A.m1(s)),n=A.dM(A.m3(s)),m=A.dM(A.m5(s)),l=A.jJ(A.m2(s)),k=s.b,j=k===0?"":A.jJ(k) +return r+"-"+q+"-"+p+" "+o+":"+n+":"+m+"."+l+j+"Z"}, +$ia3:1} +A.b0.prototype={ +M(a,b){if(b==null)return!1 +return b instanceof A.b0&&this.a===b.a}, +gu(a){return B.c.gu(this.a)}, +N(a,b){return B.c.N(this.a,t.fu.a(b).a)}, +j(a){var s,r,q,p=this.a,o=p%36e8,n=B.c.bq(o,6e7) +o%=6e7 +s=n<10?"0":"" +r=B.c.bq(o,1e6) +q=r<10?"0":"" +return""+(p/36e8|0)+":"+s+n+":"+q+r+"."+B.a.d1(B.c.j(o%1e6),6,"0")}, +$ia3:1} +A.E.prototype={ +ga6(){return A.m_(this)}} +A.dw.prototype={ +j(a){var s=this.a +if(s!=null)return"Assertion failed: "+A.fY(s) +return"Assertion failed"}} +A.aO.prototype={} +A.av.prototype={ +gaK(){return"Invalid argument"+(!this.a?"(s)":"")}, +gaJ(){return""}, +j(a){var s=this,r=s.c,q=r==null?"":" ("+r+")",p=s.d,o=p==null?"":": "+A.u(p),n=s.gaK()+q+o +if(!s.a)return n +return n+s.gaJ()+": "+A.fY(s.gaX())}, +gaX(){return this.b}} +A.cE.prototype={ +gaX(){return A.ku(this.b)}, +gaK(){return"RangeError"}, +gaJ(){var s,r=this.e,q=this.f +if(r==null)s=q!=null?": Not less than or equal to "+A.u(q):"" +else if(q==null)s=": Not greater than or equal to "+A.u(r) +else if(q>r)s=": Not in inclusive range "+A.u(r)+".."+A.u(q) +else s=qe.length +else s=!1 +if(s)f=null +if(f==null){if(e.length>78)e=B.a.n(e,0,75)+"..." +return g+"\n"+e}for(r=e.length,q=1,p=0,o=!1,n=0;n1?g+(" (at line "+q+", character "+(f-p+1)+")\n"):g+(" (at character "+(f+1)+")\n") +for(n=f;n=0))return A.j(e,n) +m=e.charCodeAt(n) +if(m===10||m===13){r=n +break}}l="" +if(r-p>78){k="..." +if(f-p<75){j=p+75 +i=p}else{if(r-f<75){i=r-75 +j=r +k=""}else{i=f-36 +j=f+36}l="..."}}else{j=r +i=p +k=""}return g+l+B.a.n(e,i,j)+k+"\n"+B.a.b7(" ",f-i+l.length)+"^\n"}else return f!=null?g+(" (at offset "+A.u(f)+")"):g}} +A.e.prototype={ +am(a,b){return A.lw(this,A.D(this).h("e.E"),b)}, +b_(a,b,c){var s=A.D(this) +return A.lZ(this,s.B(c).h("1(e.E)").a(b),s.h("e.E"),c)}, +aA(a,b){var s=A.D(this) +return new A.aQ(this,s.h("S(e.E)").a(b),s.h("aQ"))}, +gi(a){var s,r=this.gA(this) +for(s=0;r.p();)++s +return s}, +gI(a){return!this.gA(this).p()}, +gX(a){var s,r=this.gA(this) +if(!r.p())throw A.f(A.j0()) +s=r.gt(r) +if(r.p())throw A.f(A.lP()) +return s}, +q(a,b){var s,r +A.em(b,"index") +s=this.gA(this) +for(r=b;s.p();){if(r===0)return s.gt(s);--r}throw A.f(A.I(b,b-r,this,"index"))}, +j(a){return A.lQ(this,"(",")")}} +A.L.prototype={ +gu(a){return A.z.prototype.gu.call(this,0)}, +j(a){return"null"}} +A.z.prototype={$iz:1, +M(a,b){return this===b}, +gu(a){return A.ek(this)}, +j(a){return"Instance of '"+A.el(this)+"'"}, +gD(a){return A.nY(this)}, +toString(){return this.j(this)}} +A.ft.prototype={ +j(a){return""}, +$ib5:1} +A.ae.prototype={ +gi(a){return this.a.length}, +j(a){var s=this.a +return s.charCodeAt(0)==0?s:s}, +$imh:1} +A.hT.prototype={ +$2(a,b){throw A.f(A.X("Illegal IPv6 address, "+a,this.a,b))}, +$S:14} +A.df.prototype={ +gbr(){var s,r,q,p,o=this,n=o.w +if(n===$){s=o.a +r=s.length!==0?s+":":"" +q=o.c +p=q==null +if(!p||s==="file"){s=r+"//" +r=o.b +if(r.length!==0)s=s+r+"@" +if(!p)s+=q +r=o.d +if(r!=null)s=s+":"+A.u(r)}else s=r +s+=o.e +r=o.f +if(r!=null)s=s+"?"+r +r=o.r +if(r!=null)s=s+"#"+r +n=o.w=s.charCodeAt(0)==0?s:s}return n}, +gu(a){var s,r=this,q=r.y +if(q===$){s=B.a.gu(r.gbr()) +r.y!==$&&A.og() +r.y=s +q=s}return q}, +gbU(){return this.b}, +gaT(a){var s=this.c +if(s==null)return"" +if(B.a.C(s,"[")&&!B.a.G(s,"v",1))return B.a.n(s,1,s.length-1) +return s}, +gb1(a){var s=this.d +return s==null?A.kj(this.a):s}, +gbM(a){var s=this.f +return s==null?"":s}, +gaR(){var s=this.r +return s==null?"":s}, +au(){var s=this +if(s.r==null)return s +return A.ki(s.a,s.b,s.c,s.d,s.e,s.f,null)}, +gbE(){return this.c!=null}, +gbF(){return this.f!=null}, +gaS(){return this.r!=null}, +j(a){return this.gbr()}, +M(a,b){var s,r,q,p=this +if(b==null)return!1 +if(p===b)return!0 +s=!1 +if(t.dD.b(b))if(p.a===b.gb8())if(p.c!=null===b.gbE())if(p.b===b.gbU())if(p.gaT(0)===b.gaT(b))if(p.gb1(0)===b.gb1(b))if(p.e===b.gbL(b)){r=p.f +q=r==null +if(!q===b.gbF()){if(q)r="" +if(r===b.gbM(b)){r=p.r +q=r==null +if(!q===b.gaS()){s=q?"":r +s=s===b.gaR()}}}}return s}, +$ieH:1, +gb8(){return this.a}, +gbL(a){return this.e}} +A.hS.prototype={ +gbS(){var s,r,q,p,o=this,n=null,m=o.c +if(m==null){m=o.b +if(0>=m.length)return A.j(m,0) +s=o.a +m=m[0]+1 +r=B.a.a2(s,"?",m) +q=s.length +if(r>=0){p=A.dg(s,r+1,q,256,!1,!1) +q=r}else p=n +m=o.c=new A.eR("data","",n,n,A.dg(s,m,q,128,!1,!1),p,n)}return m}, +j(a){var s,r=this.b +if(0>=r.length)return A.j(r,0) +s=this.a +return r[0]===-1?"data:"+s:s}} +A.d5.prototype={ +gbE(){return this.c>0}, +gbF(){return this.fr?B.a.n(this.a,r,s-1):""}, +gaT(a){var s=this.c +return s>0?B.a.n(this.a,s,this.d):""}, +gb1(a){var s,r=this +if(r.c>0&&r.d+1=q.length)return s +return new A.d5(B.a.n(q,0,r),s.b,s.c,s.d,s.e,s.f,r,s.w)}, +gu(a){var s=this.x +return s==null?this.x=B.a.gu(this.a):s}, +M(a,b){if(b==null)return!1 +if(this===b)return!0 +return t.dD.b(b)&&this.a===b.j(0)}, +j(a){return this.a}, +$ieH:1} +A.eR.prototype={} +A.q.prototype={} +A.dt.prototype={ +gi(a){return a.length}} +A.aW.prototype={ +sbG(a,b){a.href=b}, +j(a){var s=String(a) +s.toString +return s}, +$iaW:1} +A.du.prototype={ +j(a){var s=String(a) +s.toString +return s}} +A.bL.prototype={$ibL:1} +A.aY.prototype={$iaY:1} +A.bh.prototype={$ibh:1} +A.aD.prototype={ +gi(a){return a.length}} +A.dI.prototype={ +gi(a){return a.length}} +A.y.prototype={$iy:1} +A.bk.prototype={ +bd(a,b){var s=$.kW(),r=s[b] +if(typeof r=="string")return r +r=this.cC(a,b) +s[b]=r +return r}, +cC(a,b){var s,r=b.replace(/^-ms-/,"ms-").replace(/-([\da-z])/ig,function(c,d){return d.toUpperCase()}) +r.toString +r=r in a +r.toString +if(r)return b +s=$.kY()+b +r=s in a +r.toString +if(r)return s +return b}, +bo(a,b,c,d){a.setProperty(b,c,d)}, +gi(a){var s=a.length +s.toString +return s}} +A.fW.prototype={} +A.a4.prototype={} +A.ax.prototype={} +A.dJ.prototype={ +gi(a){return a.length}} +A.dK.prototype={ +gi(a){return a.length}} +A.dL.prototype={ +gi(a){return a.length}} +A.ci.prototype={} +A.bl.prototype={} +A.dN.prototype={ +j(a){var s=String(a) +s.toString +return s}} +A.cj.prototype={ +cM(a,b){var s=a.createHTMLDocument(b) +s.toString +return s}} +A.ck.prototype={ +gi(a){var s=a.length +s.toString +return s}, +k(a,b){var s=a.length,r=b>>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.eU.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){A.B(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b=0&&b=0&&b"))}, +E(a,b){A.my(this.a,t.c.a(b))}, +ab(a){J.iS(this.a)}} +A.an.prototype={ +gi(a){return this.a.length}, +k(a,b){var s=this.a +if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.L.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.A.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.cI.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b1)throw A.f(A.cI("More than one element")) +s=s.firstChild +s.toString +return s}, +E(a,b){var s,r,q,p,o +t.eh.a(b) +if(b instanceof A.W){s=b.a +r=this.a +if(s!==r)for(q=s.childNodes.length,p=0;p=0&&b"))}, +gi(a){return this.a.childNodes.length}, +k(a,b){var s=this.a.childNodes +if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.A.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.he.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.fY.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.f7.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b"+A.u(b)+"",c,d) +r=document.createDocumentFragment() +r.toString +new A.W(r).E(0,new A.W(s)) +return r}} +A.ev.prototype={ +L(a,b,c,d){var s,r="createContextualFragment" in window.Range.prototype +r.toString +if(r)return this.aE(a,b,c,d) +r=document +s=r.createDocumentFragment() +s.toString +r=r.createElement("table") +r.toString +new A.W(s).E(0,new A.W(new A.W(new A.W(B.A.L(r,b,c,d)).gX(0)).gX(0))) +return s}} +A.ew.prototype={ +L(a,b,c,d){var s,r="createContextualFragment" in window.Range.prototype +r.toString +if(r)return this.aE(a,b,c,d) +r=document +s=r.createDocumentFragment() +s.toString +r=r.createElement("table") +r.toString +new A.W(s).E(0,new A.W(new A.W(B.A.L(r,b,c,d)).gX(0))) +return s}} +A.c2.prototype={ +aD(a,b,c){var s,r +this.sae(a,null) +s=a.content +s.toString +J.iS(s) +r=this.L(a,b,c,null) +a.content.appendChild(r).toString}, +$ic2:1} +A.af.prototype={$iaf:1} +A.a0.prototype={$ia0:1} +A.ey.prototype={ +gi(a){var s=a.length +s.toString +return s}, +k(a,b){var s=a.length,r=b>>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.c7.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.a0.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.aK.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.g5.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +return a[b]}, +l(a,b,c){t.bx.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.A.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.gf.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b>>0!==b||b>=s +r.toString +if(r)throw A.f(A.I(b,s,a,null)) +s=a[b] +s.toString +return s}, +l(a,b,c){t.cO.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){if(!(b>=0&&b"))}} +A.cC.prototype={ +Z(a){return B.b.bx(this.a,new A.hk(a))}, +T(a,b,c){return B.b.bx(this.a,new A.hj(a,b,c))}, +$iay:1} +A.hk.prototype={ +$1(a){return t.f6.a(a).Z(this.a)}, +$S:11} +A.hj.prototype={ +$1(a){return t.f6.a(a).T(this.a,this.b,this.c)}, +$S:11} +A.d4.prototype={ +cb(a,b,c,d){var s,r,q +this.a.E(0,c) +s=b.aA(0,new A.ii()) +r=b.aA(0,new A.ij()) +this.b.E(0,s) +q=this.c +q.E(0,B.f) +q.E(0,r)}, +Z(a){return this.a.v(0,A.cn(a))}, +T(a,b,c){var s,r=this,q=A.cn(a),p=r.c,o=q+"::"+b +if(p.v(0,o))return r.d.cF(c) +else{s="*::"+b +if(p.v(0,s))return r.d.cF(c) +else{p=r.b +if(p.v(0,o))return!0 +else if(p.v(0,s))return!0 +else if(p.v(0,q+"::*"))return!0 +else if(p.v(0,"*::*"))return!0}}return!1}, +$iay:1} +A.ii.prototype={ +$1(a){return!B.b.v(B.m,A.B(a))}, +$S:8} +A.ij.prototype={ +$1(a){return B.b.v(B.m,A.B(a))}, +$S:8} +A.fx.prototype={ +T(a,b,c){if(this.c5(a,b,c))return!0 +if(b==="template"&&c==="")return!0 +if(a.getAttribute("template")==="")return this.e.v(0,b) +return!1}} +A.io.prototype={ +$1(a){return"TEMPLATE::"+A.B(a)}, +$S:19} +A.fw.prototype={ +Z(a){var s +if(t.ew.b(a))return!1 +s=t.g7.b(a) +if(s&&A.cn(a)==="foreignObject")return!1 +if(s)return!0 +return!1}, +T(a,b,c){if(b==="is"||B.a.C(b,"on"))return!1 +return this.Z(a)}, +$iay:1} +A.bm.prototype={ +p(){var s=this,r=s.c+1,q=s.b +if(r") +return}if(!l.a.Z(a)){l.aa(a,b) +window.toString +s=A.u(b) +r=typeof console!="undefined" +r.toString +if(r)window.console.warn("Removing disallowed element <"+e+"> from "+s) +return}if(g!=null)if(!l.a.T(a,"is",g)){l.aa(a,b) +window.toString +s=typeof console!="undefined" +s.toString +if(s)window.console.warn("Removing disallowed type extension <"+e+' is="'+g+'">') +return}s=f.gH(0) +q=A.t(s.slice(0),A.U(s)) +for(p=f.gH(0).length-1,s=f.a,r="Removing disallowed attribute <"+e+" ";p>=0;--p){if(!(p') +s.removeAttribute(o)}}if(t.aW.b(a)){s=a.content +s.toString +l.aC(s)}}, +bW(a,b){var s=a.nodeType +s.toString +switch(s){case 1:this.cw(a,b) +break +case 8:case 11:case 3:case 4:break +default:this.aa(a,b)}}, +$ij6:1} +A.iv.prototype={ +$2(a,b){var s,r,q,p,o,n=this.a +n.bW(a,b) +s=a.lastChild +while(s!=null){r=null +try{r=s.previousSibling +if(r!=null&&r.nextSibling!==s){q=A.cI("Corrupt HTML") +throw A.f(q)}}catch(p){q=s;++n.b +o=q.parentNode +if(a!==o){if(o!=null)o.removeChild(q).toString}else a.removeChild(q).toString +s=null +r=a.lastChild}if(s!=null)this.$2(s,a) +s=r}}, +$S:20} +A.eQ.prototype={} +A.eS.prototype={} +A.eT.prototype={} +A.eU.prototype={} +A.eV.prototype={} +A.eY.prototype={} +A.eZ.prototype={} +A.f2.prototype={} +A.f3.prototype={} +A.f9.prototype={} +A.fa.prototype={} +A.fb.prototype={} +A.fc.prototype={} +A.fd.prototype={} +A.fe.prototype={} +A.fh.prototype={} +A.fi.prototype={} +A.fk.prototype={} +A.d6.prototype={} +A.d7.prototype={} +A.fm.prototype={} +A.fn.prototype={} +A.fp.prototype={} +A.fy.prototype={} +A.fz.prototype={} +A.d9.prototype={} +A.da.prototype={} +A.fA.prototype={} +A.fB.prototype={} +A.fE.prototype={} +A.fF.prototype={} +A.fG.prototype={} +A.fH.prototype={} +A.fI.prototype={} +A.fJ.prototype={} +A.fK.prototype={} +A.fL.prototype={} +A.fM.prototype={} +A.fN.prototype={} +A.ik.prototype={ +a_(a){var s,r=this.a,q=r.length +for(s=0;s864e13)A.bH(A.az(s,-864e13,864e13,"millisecondsSinceEpoch",null)) +A.fP(!0,"isUtc",t.y) +return new A.b_(s,0,!0)}s=a instanceof RegExp +s.toString +if(s)throw A.f(A.eF("structured clone of RegExp")) +s=typeof Promise!="undefined"&&a instanceof Promise +s.toString +if(s)return A.fQ(a,t.z) +if(A.kN(a)){r=j.a_(a) +s=j.b +if(!(r")),r.h("r(c.E)").a(new A.h_()),r.h("aL"))}, +l(a,b,c){var s,r +t.h.a(c) +s=this.gak() +r=s.a +J.lp(s.b.$1(r.q(r,b)),c)}, +E(a,b){var s,r +for(s=J.aV(t.c.a(b)),r=this.b.a;s.p();)r.appendChild(s.gt(s)).toString}, +ab(a){J.iS(this.b.a)}, +gi(a){var s=this.gak().a +return s.gi(s)}, +k(a,b){var s=this.gak(),r=s.a +return s.b.$1(r.q(r,b))}, +gA(a){var s=A.lY(this.gak(),!1,t.h) +return new J.aw(s,s.length,A.U(s).h("aw<1>"))}} +A.fZ.prototype={ +$1(a){return t.h.b(t.A.a(a))}, +$S:6} +A.h_.prototype={ +$1(a){return t.h.a(t.A.a(a))}, +$S:25} +A.iP.prototype={ +$1(a){return this.a.an(0,this.b.h("0/?").a(a))}, +$S:5} +A.iQ.prototype={ +$1(a){if(a==null)return this.a.bB(new A.hl(a===undefined)) +return this.a.bB(a)}, +$S:5} +A.hl.prototype={ +j(a){return"Promise was rejected with a value of `"+(this.a?"undefined":"null")+"`."}} +A.ah.prototype={$iah:1} +A.e0.prototype={ +gi(a){var s=a.length +s.toString +return s}, +k(a,b){var s=a.length +s.toString +s=b>>>0!==b||b>=s +s.toString +if(s)throw A.f(A.I(b,this.gi(a),a,null)) +s=a.getItem(b) +s.toString +return s}, +l(a,b,c){t.bG.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){return this.k(a,b)}, +$ii:1, +$ie:1, +$im:1} +A.aj.prototype={$iaj:1} +A.ee.prototype={ +gi(a){var s=a.length +s.toString +return s}, +k(a,b){var s=a.length +s.toString +s=b>>>0!==b||b>=s +s.toString +if(s)throw A.f(A.I(b,this.gi(a),a,null)) +s=a.getItem(b) +s.toString +return s}, +l(a,b,c){t.eq.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){return this.k(a,b)}, +$ii:1, +$ie:1, +$im:1} +A.ej.prototype={ +gi(a){return a.length}} +A.c_.prototype={$ic_:1} +A.eu.prototype={ +gi(a){var s=a.length +s.toString +return s}, +k(a,b){var s=a.length +s.toString +s=b>>>0!==b||b>=s +s.toString +if(s)throw A.f(A.I(b,this.gi(a),a,null)) +s=a.getItem(b) +s.toString +return s}, +l(a,b,c){A.B(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){return this.k(a,b)}, +$ii:1, +$ie:1, +$im:1} +A.dy.prototype={ +U(){var s,r,q,p,o=this.a.getAttribute("class"),n=A.cv(t.N) +if(o==null)return n +for(s=o.split(" "),r=s.length,q=0;q'+A.u(b)+"",c) +s=s.createDocumentFragment() +s.toString +p=new A.W(q).gX(0) +while(r=p.firstChild,r!=null)s.appendChild(r).toString +return s}, +gbH(a){return new A.aH(a,"click",!1,t.C)}, +gbI(a){return new A.aH(a,"mousedown",!1,t.C)}, +$in:1} +A.al.prototype={$ial:1} +A.eD.prototype={ +gi(a){var s=a.length +s.toString +return s}, +k(a,b){var s=a.length +s.toString +s=b>>>0!==b||b>=s +s.toString +if(s)throw A.f(A.I(b,this.gi(a),a,null)) +s=a.getItem(b) +s.toString +return s}, +l(a,b,c){t.cM.a(c) +throw A.f(A.G("Cannot assign element of immutable List."))}, +q(a,b){return this.k(a,b)}, +$ii:1, +$ie:1, +$im:1} +A.f6.prototype={} +A.f7.prototype={} +A.ff.prototype={} +A.fg.prototype={} +A.fr.prototype={} +A.fs.prototype={} +A.fC.prototype={} +A.fD.prototype={} +A.dz.prototype={ +gi(a){return a.length}} +A.dA.prototype={ +J(a,b){return A.au(a.get(b))!=null}, +k(a,b){return A.au(a.get(A.B(b)))}, +F(a,b){var s,r,q +t.u.a(b) +s=a.entries() +for(;;){r=s.next() +q=r.done +q.toString +if(q)return +q=r.value[0] +q.toString +b.$2(q,A.au(r.value[1]))}}, +gH(a){var s=A.t([],t.s) +this.F(a,new A.fS(s)) +return s}, +gi(a){var s=a.size +s.toString +return s}, +$iF:1} +A.fS.prototype={ +$2(a,b){return B.b.m(this.a,a)}, +$S:2} +A.dB.prototype={ +gi(a){return a.length}} +A.aX.prototype={} +A.ef.prototype={ +gi(a){return a.length}} +A.eN.prototype={} +A.h5.prototype={ +P(){var s=0,r=A.dr(t.H),q=this,p,o,n,m,l,k,j,i +var $async$P=A.ds(function(a,b){if(a===1)return A.dk(b,r) +for(;;)switch(s){case 0:l=t.h +k=document +j=J.iV(l.a(k.getElementById("color-mode-button"))) +i=j.$ti +A.am(j.a,j.b,i.h("~(1)?").a(new A.h7(q)),!1,i.c) +p=window.localStorage.getItem("theme") +if(p!=null)q.saf(p) +j=q.a +i=A.md(j,new A.h8(q)) +q.f!==$&&A.be() +q.f=i +i=window +i.toString +A.am(i,"popstate",t.eQ.a(new A.h9(q)),!1,t.gV) +A.bA(t.p,l,"T","querySelectorAll") +l=k.querySelectorAll("a[data-jot]") +l.toString +i=t.U +l=new A.an(l,i) +l=new A.P(l,l.gi(0),i.h("P")) +o=t.C +n=o.h("~(1)?") +o=o.c +i=i.h("c.E") +while(l.p()){m=l.d +if(m==null)m=i.a(m) +A.am(m,"click",n.a(new A.ha(q,m)),!1,o)}q.bu() +q.d!==$&&A.be() +q.d=new A.hi(j) +l=new A.hL(q) +k=t.B.a(k.querySelector("aside.docSidebarContainer")) +k.toString +l.b=k +q.e!==$&&A.be() +q.e=l +s=2 +return A.ba(l.P(),$async$P) +case 2:return A.dl(null,r)}}) +return A.dm($async$P,r)}, +gaf(){var s=document.documentElement.getAttribute("data-theme") +return s==null?"dark":s}, +saf(a){var s +if(this.gaf()===a)return +s=document +t.de.a(s.getElementById("theme-stylesheet")).href=this.a+"_resources/styles-"+a+".css" +s.documentElement.setAttribute("data-theme",a) +window.localStorage.setItem("theme",a)}, +a3(a,b,c){var s=0,r=A.dr(t.H),q,p=this,o,n,m,l,k,j,i +var $async$a3=A.ds(function(d,e){if(d===1)return A.dk(e,r) +for(;;)switch(s){case 0:if(c){o=window.history +o.toString +n=window.document.documentElement.scrollTop +n.toString +o.replaceState(new A.fu([],[]).R(B.e.bP(n)),"",null)}if(c){o=window.history +o.toString +o.pushState(new A.fu([],[]).R(null),"",a)}o=window +o.toString +i=t.e +s=3 +return A.ba(B.o.aQ(o,a),$async$a3) +case 3:m=i.a(e) +if(A.aS(m.status)===404){A.iO("error response: "+A.u(m)) +s=1 +break}s=4 +return A.ba(A.fQ(A.iw(m.text()),t.N),$async$a3) +case 4:l=e +o=new DOMParser().parseFromString(l,"text/html").getElementById("doc-main-child") +o.toString +n=$.ju() +J.lr(n,J.lm(o),B.J) +k=A.jb(a,0,null) +if(b!=null){o=window.document.documentElement +o.toString +o.scrollTop=B.c.bP(b)}else if(k.gaS()){j=n.querySelector("#"+k.gaR()) +if(j!=null)j.scrollIntoViewIfNeeded()}else{o=window.document.documentElement +o.toString +o.scrollTop=0}p.bu() +o=p.d +o===$&&A.a2() +o.az(k.au()) +o=p.e +o===$&&A.a2() +o.az(k.au()) +case 1:return A.dl(q,r)}}) +return A.dm($async$a3,r)}, +ad(a){return this.a3(a,null,!0)}, +bu(){var s,r,q,p,o,n=t.h,m=n.a(document.getElementById("doc-main-child")).getAttribute("data-path") +m.toString +s=$.bJ().b0(0,m) +r=$.ju() +A.bA(n,n,"T","querySelectorAll") +r=r.querySelectorAll("a[href]") +r.toString +n=t.R +r=new A.an(r,n) +r=new A.P(r,r.gi(0),n.h("P")) +n=n.h("c.E") +while(r.p()){q=r.d +if(q==null)q=n.a(q) +p=q.getAttribute("href") +p.toString +if(A.mt(p)==null)continue +q=J.iV(q) +o=q.$ti +A.am(q.a,q.b,o.h("~(1)?").a(new A.h6(this,p,m,s)),!1,o.c)}}} +A.h7.prototype={ +$1(a){var s +t.V.a(a) +s=this.a +s.saf(s.gaf()==="light"?"dark":"light")}, +$S:1} +A.h8.prototype={ +$1(a){var s=this.a +s.ad(s.a+a)}, +$S:41} +A.h9.prototype={ +$1(a){var s,r,q +t.gV.a(a) +s=t.d.a(window.location).href +s.toString +r=a.state +q=new A.hV([],[]) +q.c=!0 +this.a.a3(s,A.ks(q.R(r)),!1)}, +$S:40} +A.ha.prototype={ +$1(a){var s,r,q,p +t.V.a(a).preventDefault() +s=$.bJ() +r=this.a +q=s.b0(0,r.b) +p=this.b.getAttribute("href") +p.toString +r.ad(s.aq(0,s.ap(0,q,p)))}, +$S:1} +A.h6.prototype={ +$1(a){var s,r,q,p,o=this +t.V.a(a).preventDefault() +s=o.b +r=o.a +q=r.a +p=B.a.C(s,"#")?q+o.c+s:q+$.bJ().ap(0,o.d,s) +r.ad($.bJ().aq(0,p))}, +$S:1} +A.hi.prototype={ +az(a){var s,r,q,p,o,n,m,l,k,j,i="a[data-jot]",h="querySelectorAll",g="navbar__link--active",f=B.a.S(a.j(0),this.a.length) +if(B.a.C(f,"/"))f=B.a.S(f,1) +s=t.B.a(document.querySelector("nav")) +s.toString +r=t.p +q=t.h +A.bA(r,q,"T",h) +p=s.querySelectorAll(i) +p.toString +o=t.U +p=new A.an(p,o) +n=o.h("P") +p=new A.P(p,p.gi(0),n) +m=o.h("c.E") +l=!1 +while(p.p()){k=p.d +if(k==null)k=m.a(k) +j=k.getAttribute("href")===f +l=B.P.bV(l,j) +A.i1(k,g,j)}if(!l){A.bA(r,q,"T",h) +s=s.querySelectorAll(i) +s.toString +o=new A.an(s,o) +n=new A.P(o,o.gi(0),n) +while(n.p()){s=n.d +if(s==null)s=m.a(s) +if(s.getAttribute("href")==="index.html")A.i1(s,g,!0)}}}} +A.hL.prototype={ +P(){var s=0,r=A.dr(t.H),q=this,p,o,n,m,l +var $async$P=A.ds(function(a,b){if(a===1)return A.dk(b,r) +for(;;)switch(s){case 0:s=2 +return A.ba(q.a8(),$async$P) +case 2:p=t.h +o=document +o.toString +A.bA(p,p,"T","querySelectorAll") +o=o.querySelectorAll("button.menu__caret") +o.toString +p=t.R +o=new A.an(o,p) +o=new A.P(o,o.gi(0),p.h("P")) +p=p.h("c.E") +while(o.p()){n=o.d +if(n==null)n=p.a(n) +m=J.iV(n) +l=m.$ti +A.am(m.a,m.b,l.h("~(1)?").a(new A.hM(n)),!1,l.c)}return A.dl(null,r)}}) +return A.dm($async$P,r)}, +az(a){var s,r,q,p,o,n,m,l,k,j=this,i="querySelectorAll",h="li.theme-doc-sidebar-item-category",g=B.a.S(a.j(0),j.a.a.length) +if(B.a.C(g,"/"))g=B.a.S(g,1) +s=j.b +s===$&&A.a2() +r=t.h +A.bA(t.p,r,"T",i) +s=s.querySelectorAll("a[data-jot]") +s.toString +q=t.U +s=new A.an(s,q) +s=new A.P(s,s.gi(0),q.h("P")) +q=q.h("c.E") +p=null +while(s.p()){o=s.d +n=o==null?q.a(o):o +o=n.getAttribute("href")===g +if(o)p=n +A.i1(n,"menu__link--active",o)}if(p!=null){m=A.t([],t.k) +s=j.b +A.bA(r,r,"T",i) +s=s.querySelectorAll(h) +s.toString +q=t.R +s=new A.an(s,q) +o=q.h("P") +s=new A.P(s,s.gi(0),o) +l=q.h("c.E") +while(s.p()){k=s.d +if(k==null)k=l.a(k) +if(A.lE(k,p))B.b.m(m,k)}if(m.length!==0){s=j.b +A.bA(r,r,"T",i) +s=s.querySelectorAll(h) +s.toString +q=new A.an(s,q) +o=new A.P(q,q.gi(0),o) +while(o.p()){s=o.d +if(s==null)s=l.a(s) +J.jy(s).av(0,"menu__list-item--collapsed",!B.b.v(m,s))}}}}, +a8(){var s=0,r=A.dr(t.H),q,p=this,o,n,m,l,k,j,i,h,g,f,e +var $async$a8=A.ds(function(a,b){if(a===1)return A.dk(b,r) +for(;;)switch(s){case 0:h=window +h.toString +o=p.a +g=t.e +s=3 +return A.ba(B.o.aQ(h,o.a+"_resources/nav.json"),$async$a8) +case 3:n=g.a(b) +if(A.aS(n.status)===404){A.iO("error response: "+A.u(n)) +s=1 +break}g=J +f=t.j +e=B.t +s=4 +return A.ba(A.fQ(A.iw(n.text()),t.N),$async$a8) +case 4:h=g.iT(f.a(e.bD(0,b,null)),t.a) +m=h.$ti +l=m.h("K") +k=A.br(new A.K(h,m.h("as(c.E)").a(A.kP()),l),l.h("T.E")) +j=A.kT(B.U,A.t(["theme-doc-sidebar-menu","menu__list"],t.s)) +for(h=k.length,i=0;i")),t.h) +return A.iM(A.t([q,A.kT(s,r)],p),m)}}}, +j(a){return this.a+" ["+A.u(this.b)+"]"}} +A.hI.prototype={ +$1(a){var s,r,q +t.V.a(a).preventDefault() +s=this.b +r=$.bJ() +q=this.a.b +q.toString +s.ad(r.aq(0,r.ap(0,s.a,q)))}, +$S:1} +A.hJ.prototype={ +$1(a){var s,r,q +t.V.a(a).preventDefault() +s=this.b +r=$.bJ() +q=this.a.b +q.toString +s.ad(r.aq(0,r.ap(0,s.a,q)))}, +$S:1} +A.hK.prototype={ +$1(a){return t.d0.a(a).bC(0,this.a)}, +$S:29} +A.hn.prototype={} +A.hB.prototype={ +c9(a,b){var s,r,q,p=this,o=A.lK(p.a) +p.e!==$&&A.be() +p.e=o +o=document +s=t.gk.a(t.h.a(o.getElementById("search"))) +p.c!==$&&A.be() +p.c=s +r=t.B +q=r.a(o.querySelector("div.search-glass-pane")) +q.toString +r=r.a(o.querySelector("div.search-area")) +r.toString +r=A.mc(p.b,q,r) +p.d!==$&&A.be() +p.d=r +A.am(o,"keypress",t.eN.a(new A.hD(p)),!1,t.v) +o=t.aY +A.am(s,"keydown",o.h("~(1)?").a(new A.hE(p)),!1,o.c) +o=t.cl +A.am(s,"input",o.h("~(1)?").a(new A.hF(p)),!1,o.c) +o=t.C +A.am(s,"click",o.h("~(1)?").a(new A.hG(p)),!1,o.c)}, +ba(){var s=this.c +s===$&&A.a2() +s.focus() +s=s.value +if(B.a.aw(s==null?"":s).length!==0){s=this.d +s===$&&A.a2() +s.b9(0)}}, +cm(a){var s +a=B.a.aw(a) +s=this.d +if(a.length===0){s===$&&A.a2() +s.ac()}else{s===$&&A.a2() +s.b9(0) +s=this.e +s===$&&A.a2() +s.ag(0,a).bQ(new A.hC(this),t.P)}}} +A.hD.prototype={ +$1(a){t.v.a(a) +if(a.key==="/"){a.preventDefault() +this.a.ba()}}, +$S:13} +A.hE.prototype={ +$1(a){var s,r,q=this +t.v.a(a) +s=a.key +if(s==="Escape"){s=q.a +r=s.c +r===$&&A.a2() +r.blur() +s=s.d +s===$&&A.a2() +s.ac()}else if(s==="Enter"){a.preventDefault() +s=q.a.d +s===$&&A.a2() +r=s.f +if(r!=null)s.a.$1(r.gbT(0)) +s.ac()}else if(s==="ArrowDown"){s=q.a.d +s===$&&A.a2() +s.bX()}else if(s==="ArrowUp"){s=q.a.d +s===$&&A.a2() +s.bY()}}, +$S:13} +A.hF.prototype={ +$1(a){var s=this.a,r=s.c +r===$&&A.a2() +r=r.value +s.cm(r==null?"":r)}, +$S:10} +A.hG.prototype={ +$1(a){t.V.a(a) +this.a.ba()}, +$S:1} +A.hC.prototype={ +$1(a){var s +t.D.a(a) +s=this.a.d +s===$&&A.a2() +s.cO(a)}, +$S:31} +A.hs.prototype={ +c8(a,b,c){var s=J.jz(this.b),r=s.$ti +A.am(s.a,s.b,r.h("~(1)?").a(new A.hu(this)),!1,r.c) +r=J.jz(this.c) +s=r.$ti +A.am(r.a,r.b,s.h("~(1)?").a(new A.hv()),!1,s.c)}, +b9(a){var s=this.b.style,r=s.display +r.toString +if(r==="none"){s.display="block" +A.k1(B.u,new A.hz(this))}}, +bY(){var s,r,q,p,o,n=this,m=n.f +if(m==null)return +s=B.b.a1(n.d,m) +if(s===0)return +m=n.e +r=m.k(0,n.f).classList +r.contains("selected").toString +r.remove("selected") +q=n.d +p=s-1 +if(!(p>=0&&p=o.d.length)return +s=o.e +r=s.k(0,o.f).classList +r.contains("selected").toString +r.remove("selected") +q=o.d +if(!(n>=0&&n") +q=A.br(new A.K(k,s.h("J(1)").a(new A.hw()),r),r.h("T.E")) +p=q.length +if(p>100)q=A.mk(q,0,A.fP(100,"count",t.S),A.U(q).c).b4(0) +l.d=q +k=l.e +k.ab(0) +l.f=null +s=l.c +r=s.querySelector("ul") +r.toString +o=J.a1(r) +o.gK(r).ab(0) +n=A.U(q) +o.gK(r).E(0,new A.K(q,n.h("r(1)").a(new A.hx(l,a)),n.h("K<1,r>"))) +o=q.length===0?null:B.b.gcR(q) +l.f=o +o=k.k(0,o) +if(o!=null){m=o.classList +m.contains("selected").toString +m.add("selected")}r.scrollTop=0 +k=s.querySelector("div.search-footer") +k.toString +s=q.length +r=""+s +if(p!==s){s=p===1?"item":"items" +J.jB(k,"showing "+r+" of "+p+" "+s)}else{s=p===1?"item":"items" +J.jB(k,r+" "+s)}}, +cs(a,b){var s,r,q,p=null,o=t.s,n=A.t(["margin--sm","padding--sm"],o),m=A.br(A.nD(b.gV(0),b.a,a),t.h),l=b.cV(!0) +m.push(A.bG(A.t(["location"],o),p,l)) +m.push(A.bG(A.t(["type","badge"],o),p,b.b)) +m=A.jn(m,B.f) +o=A.t(["docs"],o) +l=t.k +s=A.t([],l) +r=b.c +q=r==null +if(q)s.push(A.bG(B.f," ",p)) +if(!q)s.push(A.bG(B.f,p,r)) +o=A.iM(A.t([m,A.jn(s,o)],l),n) +n=t.C +A.am(o,"mousedown",n.h("~(1)?").a(new A.ht(this,b)),!1,n.c) +return o}, +ac(){var s=this.b.style,r=s.display +r.toString +if(r!=="none"){B.j.bo(s,B.j.bd(s,"opacity"),"0.0","") +A.k1(B.M,new A.hy(this))}}} +A.hu.prototype={ +$1(a){t.V.a(a) +this.a.ac()}, +$S:1} +A.hv.prototype={ +$1(a){t.V.a(a).stopPropagation()}, +$S:1} +A.hz.prototype={ +$0(){var s=this.a.b.style +s.toString +B.j.bo(s,B.j.bd(s,"opacity"),"1.0","") +return"1.0"}, +$S:0} +A.hw.prototype={ +$1(a){return t.bA.a(a).b}, +$S:32} +A.hx.prototype={ +$1(a){var s,r +t.m.a(a) +s=this.a +r=s.cs(this.b.a,a) +s.e.l(0,a,r) +return r}, +$S:33} +A.ht.prototype={ +$1(a){var s +t.V.a(a).stopPropagation() +s=this.a +s.a.$1(this.b.gbT(0)) +s.ac()}, +$S:1} +A.hy.prototype={ +$0(){var s=this.a.b.style +s.display="none" +return"none"}, +$S:0} +A.h0.prototype={ +c6(a){var s=this.a7(a).bQ(new A.h2(this),t.P),r=new A.h3(this),q=s.$ti,p=$.C +if(p!==B.d)r=A.kC(r,p) +s.ah(new A.aR(new A.M(p,q),2,null,r,q.h("aR<1,1>")))}, +a7(a){var s=0,r=A.dr(t.w),q,p,o,n,m,l,k,j +var $async$a7=A.ds(function(b,c){if(b===1)return A.dk(c,r) +for(;;)switch(s){case 0:m=window +m.toString +l=t.e +s=3 +return A.ba(B.o.aQ(m,a+"_resources/index.json"),$async$a7) +case 3:p=l.a(c) +if(A.aS(p.status)===404){A.iO("error response: "+A.u(p)) +q=A.t([],t.I) +s=1 +break}l=J +k=t.j +j=B.t +s=4 +return A.ba(A.fQ(A.iw(p.text()),t.N),$async$a7) +case 4:o=l.iT(k.a(j.bD(0,c,null)),t.a) +m=o.$ti +n=m.h("K") +m=A.br(new A.K(o,m.h("J(c.E)").a(A.od()),n),n.h("T.E")) +q=m +s=1 +break +case 1:return A.dl(q,r)}}) +return A.dm($async$a7,r)}, +ag(a,b){var s=0,r=A.dr(t.D),q,p=this,o,n,m +var $async$ag=A.ds(function(c,d){if(c===1)return A.dk(d,r) +for(;;)switch(s){case 0:s=3 +return A.ba(p.b.a,$async$ag) +case 3:o=b.toLowerCase() +n=A.t([],t.I) +m=p.a +m===$&&A.a2() +m=J.aV(m) +while(m.p())A.jN(o,m.gt(m),n) +q=A.mb(b,n) +s=1 +break +case 1:return A.dl(q,r)}}) +return A.dm($async$ag,r)}} +A.h2.prototype={ +$1(a){var s +t.w.a(a) +s=this.a +s.a!==$&&A.be() +s.a=a +s.b.bA(0)}, +$S:34} +A.h3.prototype={ +$1(a){var s=this.a,r=t.w.a(A.t([],t.I)) +s.a!==$&&A.be() +s.a=r +A.iO("error reading index: "+A.u(a)) +s.b.bA(0)}, +$S:4} +A.J.prototype={ +gV(a){var s,r=this,q=r.b +if(q==="class")return r.a+" { \u2026 }" +else if(q==="function"||q==="constructor")return r.a+"()" +else if(q==="method")return r.gbl()+r.a+"()" +else{q=q==="field"||q==="accessor" +s=r.a +if(q)return r.gbl()+s +else return s}}, +gbK(){var s=this.d +while(s!=null){if(s.b==="package")return s.a +s=s.d}return null}, +gbT(a){var s,r=this +if(r.gaU(r)!=null)s=A.u(r.gar())+"#"+A.u(r.gaU(r)) +else{s=r.gar() +s.toString}return s}, +cV(a){var s,r,q +for(s=this;s!=null;){if(s.b==="library"){r=s.a +q=s.gbK() +return q==null?r:q+"/"+r}s=s.d}return null}, +gbl(){var s=this.d +if(s==null)return"" +if(s.b==="library")return"" +return s.a+"."}, +j(a){return this.b+" "+this.a}} +A.h1.prototype={ +$1(a){return A.jM(t.a.a(a))}, +$S:35} +A.dW.prototype={ +gaU(a){return null}, +gar(){return this.e}, +gK(a){return this.f}} +A.dV.prototype={ +gaU(a){var s=this.e +if(s==null){s=this.d +s=(s==null?null:s.e)!=null?this.a:null}return s}, +gar(){var s=this.d +return s==null?null:s.e}, +gK(a){return B.v}} +A.c0.prototype={ +c7(a,b){var s=this,r=A.U(b),q=r.h("K<1,ak>") +r=A.br(new A.K(b,r.h("ak(1)").a(new A.hA(s,s.a.toLowerCase())),q),q.h("T.E")) +B.b.c0(r) +t.f9.a(r) +s.b!==$&&A.be() +s.b=r}} +A.hA.prototype={ +$1(a){var s,r,q,p,o +t.m.a(a) +s=this.a.a +r=this.b +q=a.a +if(q===s)p=400 +else if(B.a.C(q,s))p=300 +else if(B.a.C(q.toLowerCase(),r))p=200 +else p=B.a.C(a.gV(0).toLowerCase(),r)?150:100 +s=a.b +if(s==="class"||s==="extension"||s==="enum")p+=10 +o=a.gbK() +if(B.a_.v(0,o))p+=5 +else if(B.a0.v(0,o))p-=5 +return new A.ak(p,a)}, +$S:36} +A.ak.prototype={ +N(a,b){var s,r,q +t.bA.a(b) +s=b.a-this.a +if(s!==0)return s +r=this.b +q=b.b +s=B.a.N(r.a,q.a) +if(s!==0)return s +s=r.gV(0).length-q.gV(0).length +if(s!==0)return s +return B.a.N(r.gV(0),q.gV(0))}, +j(a){return"["+this.a+" "+this.b.j(0)+"]"}, +$ia3:1} +A.ho.prototype={ +b0(a,b){if(B.a.v(b,"/"))return B.a.n(b,0,B.a.cY(b,"/")) +else return""}, +ap(a,b,c){if(B.a.cP(b,"/"))return b+c +else if(b.length!==0)return b+"/"+c +else return c}, +aq(a,b){var s,r,q +if(!B.a.v(b,".."))return b +s=A.t(b.split("/"),t.s) +for(r=0;q=s.length,r=0))return A.j(s,r) +if(s[r]===".."&&r>0&&s[r-1]!==".."){B.b.bO(s,r);--r +B.b.bO(s,r)}else ++r}return B.b.W(s,"/")}};(function aliases(){var s=J.bR.prototype +s.c2=s.j +s=J.b4.prototype +s.c4=s.j +s=A.e.prototype +s.c3=s.aA +s=A.r.prototype +s.aE=s.L +s=A.d4.prototype +s.c5=s.T})();(function installTearOffs(){var s=hunkHelpers._static_2,r=hunkHelpers._static_1,q=hunkHelpers._static_0,p=hunkHelpers.installStaticTearOff +s(J,"nn","lS",37) +r(A,"nP","mv",3) +r(A,"nQ","mw",3) +r(A,"nR","mx",3) +q(A,"kK","nI",0) +p(A,"o_",4,null,["$4"],["mz"],7,0) +p(A,"o0",4,null,["$4"],["mA"],7,0) +r(A,"kP","me",28) +r(A,"od","lL",27)})();(function inheritance(){var s=hunkHelpers.mixin,r=hunkHelpers.inherit,q=hunkHelpers.inheritMany +r(A.z,null) +q(A.z,[A.j3,J.bR,A.cF,J.aw,A.e,A.cd,A.E,A.hH,A.P,A.cw,A.cO,A.a5,A.cf,A.cX,A.Z,A.hQ,A.hm,A.co,A.d8,A.aZ,A.w,A.hc,A.cu,A.ct,A.aB,A.f_,A.ir,A.ip,A.cP,A.aq,A.cR,A.aR,A.M,A.eL,A.cJ,A.fq,A.di,A.f8,A.bw,A.c,A.ce,A.dG,A.b_,A.b0,A.eg,A.cH,A.i3,A.aE,A.L,A.ft,A.ae,A.df,A.hS,A.d5,A.fW,A.j_,A.cW,A.bv,A.p,A.cC,A.d4,A.fw,A.bm,A.db,A.fl,A.dh,A.ik,A.hU,A.hl,A.h5,A.hi,A.hL,A.as,A.hn,A.hB,A.hs,A.h0,A.J,A.c0,A.ak,A.ho]) +q(J.bR,[J.cq,J.cs,J.a,J.bT,J.bU,J.bS,J.b3]) +q(J.a,[J.b4,J.O,A.aM,A.Q,A.b,A.dt,A.aY,A.ax,A.y,A.eQ,A.a4,A.dL,A.dN,A.cj,A.eS,A.cl,A.eU,A.dP,A.l,A.eY,A.a8,A.dT,A.f2,A.bP,A.bX,A.e1,A.f9,A.fa,A.a9,A.fb,A.fd,A.aa,A.fh,A.fk,A.ac,A.fm,A.ad,A.fp,A.a_,A.fy,A.eA,A.ag,A.fA,A.eC,A.eJ,A.fE,A.fG,A.fI,A.fK,A.fM,A.ah,A.f6,A.aj,A.ff,A.ej,A.fr,A.al,A.fC,A.dz,A.eN]) +q(J.b4,[J.eh,J.bs,J.aJ]) +r(J.dX,A.cF) +r(J.h4,J.O) +q(J.bS,[J.cr,J.dY]) +q(A.e,[A.b7,A.i,A.aL,A.aQ]) +q(A.b7,[A.bi,A.dj]) +r(A.cT,A.bi) +r(A.cQ,A.dj) +r(A.aI,A.cQ) +q(A.E,[A.bV,A.aO,A.dZ,A.eG,A.eo,A.eX,A.dw,A.av,A.cN,A.eE,A.c1,A.dF]) +q(A.i,[A.T,A.bq]) +q(A.T,[A.cK,A.K,A.f5]) +r(A.cm,A.aL) +r(A.ch,A.cf) +q(A.Z,[A.cg,A.d3,A.dH]) +r(A.bN,A.cg) +r(A.cD,A.aO) +q(A.aZ,[A.dD,A.dE,A.ex,A.iI,A.iK,A.hY,A.hX,A.ix,A.ic,A.hO,A.ih,A.fX,A.i2,A.hk,A.hj,A.ii,A.ij,A.io,A.fV,A.fZ,A.h_,A.iP,A.iQ,A.h7,A.h8,A.h9,A.ha,A.h6,A.hM,A.hI,A.hJ,A.hK,A.hD,A.hE,A.hF,A.hG,A.hC,A.hu,A.hv,A.hw,A.hx,A.ht,A.h2,A.h3,A.h1,A.hA]) +q(A.ex,[A.es,A.bM]) +q(A.w,[A.bp,A.f4,A.eM]) +q(A.dE,[A.iJ,A.iy,A.iC,A.id,A.hf,A.hT,A.hg,A.hh,A.hr,A.hN,A.i0,A.iv,A.il,A.im,A.hW,A.fS]) +r(A.eb,A.aM) +q(A.Q,[A.e5,A.V]) +q(A.V,[A.d_,A.d1]) +r(A.d0,A.d_) +r(A.cx,A.d0) +r(A.d2,A.d1) +r(A.cy,A.d2) +q(A.cx,[A.e6,A.e7]) +q(A.cy,[A.e8,A.e9,A.ea,A.ec,A.ed,A.cz,A.cA]) +r(A.c5,A.eX) +q(A.dD,[A.hZ,A.i_,A.iq,A.i4,A.i8,A.i7,A.i6,A.i5,A.ib,A.ia,A.i9,A.hP,A.iB,A.ig,A.hz,A.hy]) +r(A.bt,A.cR) +r(A.fj,A.di) +r(A.cY,A.d3) +q(A.ce,[A.dC,A.e_]) +q(A.dG,[A.fT,A.hb]) +q(A.av,[A.cE,A.dU]) +r(A.eR,A.df) +q(A.b,[A.o,A.dQ,A.bY,A.ab,A.d6,A.af,A.a0,A.d9,A.eK,A.c3,A.dB,A.aX]) +q(A.o,[A.r,A.aD,A.bl,A.c4]) +q(A.r,[A.q,A.n]) +q(A.q,[A.aW,A.du,A.bL,A.bh,A.ci,A.dS,A.bQ,A.aK,A.bW,A.ep,A.cG,A.cL,A.ev,A.ew,A.c2,A.cM]) +r(A.dI,A.ax) +r(A.bk,A.eQ) +q(A.a4,[A.dJ,A.dK]) +r(A.eT,A.eS) +r(A.ck,A.eT) +r(A.eV,A.eU) +r(A.dO,A.eV) +q(A.c,[A.eO,A.an,A.W,A.dR]) +r(A.a7,A.aY) +r(A.eZ,A.eY) +r(A.bO,A.eZ) +r(A.f3,A.f2) +r(A.b2,A.f3) +r(A.cp,A.bl) +q(A.l,[A.aG,A.aN]) +q(A.aG,[A.aF,A.ai]) +r(A.e2,A.f9) +r(A.e3,A.fa) +r(A.fc,A.fb) +r(A.e4,A.fc) +r(A.fe,A.fd) +r(A.cB,A.fe) +r(A.fi,A.fh) +r(A.ei,A.fi) +r(A.en,A.fk) +r(A.d7,A.d6) +r(A.eq,A.d7) +r(A.fn,A.fm) +r(A.er,A.fn) +r(A.et,A.fp) +r(A.fz,A.fy) +r(A.ey,A.fz) +r(A.da,A.d9) +r(A.ez,A.da) +r(A.fB,A.fA) +r(A.eB,A.fB) +r(A.fF,A.fE) +r(A.eP,A.fF) +r(A.cS,A.cl) +r(A.fH,A.fG) +r(A.f0,A.fH) +r(A.fJ,A.fI) +r(A.cZ,A.fJ) +r(A.fL,A.fK) +r(A.fo,A.fL) +r(A.fN,A.fM) +r(A.fv,A.fN) +r(A.b8,A.eM) +q(A.dH,[A.eW,A.dy]) +r(A.cV,A.cJ) +r(A.aH,A.cV) +r(A.fx,A.d4) +r(A.fu,A.ik) +r(A.hV,A.hU) +r(A.f7,A.f6) +r(A.e0,A.f7) +r(A.fg,A.ff) +r(A.ee,A.fg) +r(A.c_,A.n) +r(A.fs,A.fr) +r(A.eu,A.fs) +r(A.fD,A.fC) +r(A.eD,A.fD) +r(A.dA,A.eN) +r(A.ef,A.aX) +q(A.J,[A.dW,A.dV]) +s(A.dj,A.c) +s(A.d_,A.c) +s(A.d0,A.a5) +s(A.d1,A.c) +s(A.d2,A.a5) +s(A.eQ,A.fW) +s(A.eS,A.c) +s(A.eT,A.p) +s(A.eU,A.c) +s(A.eV,A.p) +s(A.eY,A.c) +s(A.eZ,A.p) +s(A.f2,A.c) +s(A.f3,A.p) +s(A.f9,A.w) +s(A.fa,A.w) +s(A.fb,A.c) +s(A.fc,A.p) +s(A.fd,A.c) +s(A.fe,A.p) +s(A.fh,A.c) +s(A.fi,A.p) +s(A.fk,A.w) +s(A.d6,A.c) +s(A.d7,A.p) +s(A.fm,A.c) +s(A.fn,A.p) +s(A.fp,A.w) +s(A.fy,A.c) +s(A.fz,A.p) +s(A.d9,A.c) +s(A.da,A.p) +s(A.fA,A.c) +s(A.fB,A.p) +s(A.fE,A.c) +s(A.fF,A.p) +s(A.fG,A.c) +s(A.fH,A.p) +s(A.fI,A.c) +s(A.fJ,A.p) +s(A.fK,A.c) +s(A.fL,A.p) +s(A.fM,A.c) +s(A.fN,A.p) +s(A.f6,A.c) +s(A.f7,A.p) +s(A.ff,A.c) +s(A.fg,A.p) +s(A.fr,A.c) +s(A.fs,A.p) +s(A.fC,A.c) +s(A.fD,A.p) +s(A.eN,A.w)})() +var v={G:typeof self!="undefined"?self:globalThis,typeUniverse:{eC:new Map(),tR:{},eT:{},tPV:{},sEA:[]},mangledGlobalNames:{k:"int",x:"double",H:"num",h:"String",S:"bool",L:"Null",m:"List",z:"Object",F:"Map",d:"JSObject"},mangledNames:{},types:["~()","~(ai)","~(h,@)","~(~())","L(@)","~(@)","S(o)","S(r,h,h,bv)","S(h)","~(h,h)","~(l)","S(ay)","L()","~(aF)","0&(h,k?)","~(k,@)","L(z,b5)","~(z?,z?)","@(@,h)","h(h)","~(o,o?)","~(@,@)","L(@,@)","@(@,@)","S(ar)","r(o)","L(@,b5)","J(F)","as(F)","r(as)","@(@)","L(c0)","J(ak)","aK(J)","L(m)","J(@)","ak(J)","k(@,@)","@(h)","L(~())","~(aN)","~(h)"],interceptorsByTag:null,leafTags:null,arrayRti:Symbol("$ti")} +A.mQ(v.typeUniverse,JSON.parse('{"eh":"b4","bs":"b4","aJ":"b4","oK":"a","oL":"a","ol":"a","oj":"l","oH":"l","om":"aX","ok":"b","oP":"b","oS":"b","oi":"n","oI":"n","on":"q","oN":"q","oT":"o","oG":"o","p6":"bl","oQ":"ai","p5":"a0","or":"aG","oq":"aD","oV":"aD","oM":"r","oJ":"b2","os":"y","ov":"ax","oy":"a_","oz":"a4","ou":"a4","ow":"a4","oO":"aM","cq":{"S":[],"A":[]},"cs":{"L":[],"A":[]},"a":{"d":[]},"b4":{"a":[],"d":[]},"O":{"m":["1"],"a":[],"i":["1"],"d":[],"e":["1"]},"dX":{"cF":[]},"h4":{"O":["1"],"m":["1"],"a":[],"i":["1"],"d":[],"e":["1"]},"aw":{"Y":["1"]},"bS":{"x":[],"H":[],"a3":["H"]},"cr":{"x":[],"k":[],"H":[],"a3":["H"],"A":[]},"dY":{"x":[],"H":[],"a3":["H"],"A":[]},"b3":{"h":[],"a3":["h"],"hp":[],"A":[]},"b7":{"e":["2"]},"cd":{"Y":["2"]},"bi":{"b7":["1","2"],"e":["2"],"e.E":"2"},"cT":{"bi":["1","2"],"b7":["1","2"],"i":["2"],"e":["2"],"e.E":"2"},"cQ":{"c":["2"],"m":["2"],"b7":["1","2"],"i":["2"],"e":["2"]},"aI":{"cQ":["1","2"],"c":["2"],"m":["2"],"b7":["1","2"],"i":["2"],"e":["2"],"c.E":"2","e.E":"2"},"bV":{"E":[]},"i":{"e":["1"]},"T":{"i":["1"],"e":["1"]},"cK":{"T":["1"],"i":["1"],"e":["1"],"T.E":"1","e.E":"1"},"P":{"Y":["1"]},"aL":{"e":["2"],"e.E":"2"},"cm":{"aL":["1","2"],"i":["2"],"e":["2"],"e.E":"2"},"cw":{"Y":["2"]},"K":{"T":["2"],"i":["2"],"e":["2"],"T.E":"2","e.E":"2"},"aQ":{"e":["1"],"e.E":"1"},"cO":{"Y":["1"]},"cf":{"F":["1","2"]},"ch":{"cf":["1","2"],"F":["1","2"]},"cX":{"Y":["1"]},"cg":{"Z":["1"],"ar":["1"],"i":["1"],"e":["1"]},"bN":{"cg":["1"],"Z":["1"],"ar":["1"],"i":["1"],"e":["1"],"Z.E":"1"},"cD":{"aO":[],"E":[]},"dZ":{"E":[]},"eG":{"E":[]},"d8":{"b5":[]},"aZ":{"bn":[]},"dD":{"bn":[]},"dE":{"bn":[]},"ex":{"bn":[]},"es":{"bn":[]},"bM":{"bn":[]},"eo":{"E":[]},"bp":{"w":["1","2"],"jR":["1","2"],"F":["1","2"],"w.K":"1","w.V":"2"},"bq":{"i":["1"],"e":["1"],"e.E":"1"},"cu":{"Y":["1"]},"ct":{"hp":[]},"aM":{"a":[],"d":[],"A":[]},"eb":{"aM":[],"k_":[],"a":[],"d":[],"A":[]},"Q":{"a":[],"d":[]},"e5":{"Q":[],"a":[],"d":[],"A":[]},"V":{"Q":[],"v":["1"],"a":[],"d":[]},"cx":{"c":["x"],"V":["x"],"m":["x"],"Q":[],"v":["x"],"a":[],"i":["x"],"d":[],"e":["x"],"a5":["x"]},"cy":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"]},"e6":{"c":["x"],"V":["x"],"m":["x"],"Q":[],"v":["x"],"a":[],"i":["x"],"d":[],"e":["x"],"a5":["x"],"A":[],"c.E":"x"},"e7":{"c":["x"],"V":["x"],"m":["x"],"Q":[],"v":["x"],"a":[],"i":["x"],"d":[],"e":["x"],"a5":["x"],"A":[],"c.E":"x"},"e8":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"],"A":[],"c.E":"k"},"e9":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"],"A":[],"c.E":"k"},"ea":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"],"A":[],"c.E":"k"},"ec":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"],"A":[],"c.E":"k"},"ed":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"],"A":[],"c.E":"k"},"cz":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"],"A":[],"c.E":"k"},"cA":{"c":["k"],"V":["k"],"m":["k"],"Q":[],"v":["k"],"a":[],"i":["k"],"d":[],"e":["k"],"a5":["k"],"A":[],"c.E":"k"},"eX":{"E":[]},"c5":{"aO":[],"E":[]},"cP":{"fU":["1"]},"aq":{"E":[]},"cR":{"fU":["1"]},"bt":{"cR":["1"],"fU":["1"]},"M":{"bo":["1"]},"di":{"k5":[]},"fj":{"di":[],"k5":[]},"cY":{"Z":["1"],"ar":["1"],"i":["1"],"e":["1"],"Z.E":"1"},"bw":{"Y":["1"]},"c":{"m":["1"],"i":["1"],"e":["1"]},"w":{"F":["1","2"]},"Z":{"ar":["1"],"i":["1"],"e":["1"]},"d3":{"Z":["1"],"ar":["1"],"i":["1"],"e":["1"]},"f4":{"w":["h","@"],"F":["h","@"],"w.K":"h","w.V":"@"},"f5":{"T":["h"],"i":["h"],"e":["h"],"T.E":"h","e.E":"h"},"dC":{"ce":["m","h"]},"e_":{"ce":["z?","h"]},"b_":{"a3":["b_"]},"x":{"H":[],"a3":["H"]},"b0":{"a3":["b0"]},"k":{"H":[],"a3":["H"]},"m":{"i":["1"],"e":["1"]},"H":{"a3":["H"]},"ar":{"i":["1"],"e":["1"]},"h":{"a3":["h"],"hp":[]},"dw":{"E":[]},"aO":{"E":[]},"av":{"E":[]},"cE":{"E":[]},"dU":{"E":[]},"cN":{"E":[]},"eE":{"E":[]},"c1":{"E":[]},"dF":{"E":[]},"eg":{"E":[]},"cH":{"E":[]},"ft":{"b5":[]},"ae":{"mh":[]},"df":{"eH":[]},"d5":{"eH":[]},"eR":{"eH":[]},"aW":{"r":[],"o":[],"b":[],"a":[],"d":[]},"y":{"a":[],"d":[]},"r":{"o":[],"b":[],"a":[],"d":[]},"l":{"a":[],"d":[]},"a7":{"aY":[],"a":[],"d":[]},"a8":{"a":[],"d":[]},"aF":{"l":[],"a":[],"d":[]},"aK":{"r":[],"o":[],"b":[],"a":[],"d":[]},"bW":{"r":[],"o":[],"b":[],"a":[],"d":[]},"a9":{"a":[],"d":[]},"ai":{"l":[],"a":[],"d":[]},"o":{"b":[],"a":[],"d":[]},"aa":{"a":[],"d":[]},"aN":{"l":[],"a":[],"d":[]},"ab":{"b":[],"a":[],"d":[]},"ac":{"a":[],"d":[]},"ad":{"a":[],"d":[]},"a_":{"a":[],"d":[]},"af":{"b":[],"a":[],"d":[]},"a0":{"b":[],"a":[],"d":[]},"ag":{"a":[],"d":[]},"bv":{"ay":[]},"q":{"r":[],"o":[],"b":[],"a":[],"d":[]},"dt":{"a":[],"d":[]},"du":{"r":[],"o":[],"b":[],"a":[],"d":[]},"bL":{"r":[],"o":[],"b":[],"a":[],"d":[]},"aY":{"a":[],"d":[]},"bh":{"r":[],"o":[],"b":[],"a":[],"d":[]},"aD":{"o":[],"b":[],"a":[],"d":[]},"dI":{"a":[],"d":[]},"bk":{"a":[],"d":[]},"a4":{"a":[],"d":[]},"ax":{"a":[],"d":[]},"dJ":{"a":[],"d":[]},"dK":{"a":[],"d":[]},"dL":{"a":[],"d":[]},"ci":{"r":[],"o":[],"b":[],"a":[],"d":[]},"bl":{"o":[],"b":[],"a":[],"d":[]},"dN":{"a":[],"d":[]},"cj":{"a":[],"d":[]},"ck":{"c":["aA"],"p":["aA"],"m":["aA"],"v":["aA"],"a":[],"i":["aA"],"d":[],"e":["aA"],"p.E":"aA","c.E":"aA"},"cl":{"a":[],"aA":["H"],"d":[]},"dO":{"c":["h"],"p":["h"],"m":["h"],"v":["h"],"a":[],"i":["h"],"d":[],"e":["h"],"p.E":"h","c.E":"h"},"dP":{"a":[],"d":[]},"eO":{"c":["r"],"m":["r"],"i":["r"],"e":["r"],"c.E":"r"},"an":{"c":["1"],"m":["1"],"i":["1"],"e":["1"],"c.E":"1"},"b":{"a":[],"d":[]},"bO":{"c":["a7"],"p":["a7"],"m":["a7"],"v":["a7"],"a":[],"i":["a7"],"d":[],"e":["a7"],"p.E":"a7","c.E":"a7"},"dQ":{"b":[],"a":[],"d":[]},"dS":{"r":[],"o":[],"b":[],"a":[],"d":[]},"dT":{"a":[],"d":[]},"b2":{"c":["o"],"p":["o"],"m":["o"],"v":["o"],"a":[],"i":["o"],"d":[],"e":["o"],"p.E":"o","c.E":"o"},"cp":{"o":[],"b":[],"a":[],"d":[]},"bP":{"a":[],"d":[]},"bQ":{"r":[],"o":[],"b":[],"a":[],"d":[]},"bX":{"a":[],"d":[]},"e1":{"a":[],"d":[]},"bY":{"b":[],"a":[],"d":[]},"e2":{"a":[],"w":["h","@"],"d":[],"F":["h","@"],"w.K":"h","w.V":"@"},"e3":{"a":[],"w":["h","@"],"d":[],"F":["h","@"],"w.K":"h","w.V":"@"},"e4":{"c":["a9"],"p":["a9"],"m":["a9"],"v":["a9"],"a":[],"i":["a9"],"d":[],"e":["a9"],"p.E":"a9","c.E":"a9"},"W":{"c":["o"],"m":["o"],"i":["o"],"e":["o"],"c.E":"o"},"cB":{"c":["o"],"p":["o"],"m":["o"],"v":["o"],"a":[],"i":["o"],"d":[],"e":["o"],"p.E":"o","c.E":"o"},"ei":{"c":["aa"],"p":["aa"],"m":["aa"],"v":["aa"],"a":[],"i":["aa"],"d":[],"e":["aa"],"p.E":"aa","c.E":"aa"},"en":{"a":[],"w":["h","@"],"d":[],"F":["h","@"],"w.K":"h","w.V":"@"},"ep":{"r":[],"o":[],"b":[],"a":[],"d":[]},"eq":{"c":["ab"],"p":["ab"],"m":["ab"],"b":[],"v":["ab"],"a":[],"i":["ab"],"d":[],"e":["ab"],"p.E":"ab","c.E":"ab"},"cG":{"r":[],"o":[],"b":[],"a":[],"d":[]},"er":{"c":["ac"],"p":["ac"],"m":["ac"],"v":["ac"],"a":[],"i":["ac"],"d":[],"e":["ac"],"p.E":"ac","c.E":"ac"},"et":{"a":[],"w":["h","h"],"d":[],"F":["h","h"],"w.K":"h","w.V":"h"},"cL":{"r":[],"o":[],"b":[],"a":[],"d":[]},"ev":{"r":[],"o":[],"b":[],"a":[],"d":[]},"ew":{"r":[],"o":[],"b":[],"a":[],"d":[]},"c2":{"r":[],"o":[],"b":[],"a":[],"d":[]},"ey":{"c":["a0"],"p":["a0"],"m":["a0"],"v":["a0"],"a":[],"i":["a0"],"d":[],"e":["a0"],"p.E":"a0","c.E":"a0"},"ez":{"c":["af"],"p":["af"],"m":["af"],"b":[],"v":["af"],"a":[],"i":["af"],"d":[],"e":["af"],"p.E":"af","c.E":"af"},"eA":{"a":[],"d":[]},"eB":{"c":["ag"],"p":["ag"],"m":["ag"],"v":["ag"],"a":[],"i":["ag"],"d":[],"e":["ag"],"p.E":"ag","c.E":"ag"},"eC":{"a":[],"d":[]},"aG":{"l":[],"a":[],"d":[]},"cM":{"r":[],"o":[],"b":[],"a":[],"d":[]},"eJ":{"a":[],"d":[]},"eK":{"b":[],"a":[],"d":[]},"c3":{"b":[],"a":[],"d":[]},"c4":{"o":[],"b":[],"a":[],"d":[]},"eP":{"c":["y"],"p":["y"],"m":["y"],"v":["y"],"a":[],"i":["y"],"d":[],"e":["y"],"p.E":"y","c.E":"y"},"cS":{"a":[],"aA":["H"],"d":[]},"f0":{"c":["a8?"],"p":["a8?"],"m":["a8?"],"v":["a8?"],"a":[],"i":["a8?"],"d":[],"e":["a8?"],"p.E":"a8?","c.E":"a8?"},"cZ":{"c":["o"],"p":["o"],"m":["o"],"v":["o"],"a":[],"i":["o"],"d":[],"e":["o"],"p.E":"o","c.E":"o"},"fo":{"c":["ad"],"p":["ad"],"m":["ad"],"v":["ad"],"a":[],"i":["ad"],"d":[],"e":["ad"],"p.E":"ad","c.E":"ad"},"fv":{"c":["a_"],"p":["a_"],"m":["a_"],"v":["a_"],"a":[],"i":["a_"],"d":[],"e":["a_"],"p.E":"a_","c.E":"a_"},"eM":{"w":["h","h"],"F":["h","h"]},"b8":{"w":["h","h"],"F":["h","h"],"w.K":"h","w.V":"h"},"eW":{"Z":["h"],"ar":["h"],"i":["h"],"e":["h"],"Z.E":"h"},"cV":{"cJ":["1"]},"aH":{"cV":["1"],"cJ":["1"]},"cW":{"mg":["1"]},"cC":{"ay":[]},"d4":{"ay":[]},"fx":{"ay":[]},"fw":{"ay":[]},"bm":{"Y":["1"]},"db":{"j6":[]},"fl":{"mp":[]},"dh":{"j6":[]},"dH":{"Z":["h"],"ar":["h"],"i":["h"],"e":["h"]},"dR":{"c":["r"],"m":["r"],"i":["r"],"e":["r"],"c.E":"r"},"ah":{"a":[],"d":[]},"aj":{"a":[],"d":[]},"al":{"a":[],"d":[]},"e0":{"c":["ah"],"p":["ah"],"m":["ah"],"a":[],"i":["ah"],"d":[],"e":["ah"],"p.E":"ah","c.E":"ah"},"ee":{"c":["aj"],"p":["aj"],"m":["aj"],"a":[],"i":["aj"],"d":[],"e":["aj"],"p.E":"aj","c.E":"aj"},"ej":{"a":[],"d":[]},"c_":{"n":[],"r":[],"o":[],"b":[],"a":[],"d":[]},"eu":{"c":["h"],"p":["h"],"m":["h"],"a":[],"i":["h"],"d":[],"e":["h"],"p.E":"h","c.E":"h"},"dy":{"Z":["h"],"ar":["h"],"i":["h"],"e":["h"],"Z.E":"h"},"n":{"r":[],"o":[],"b":[],"a":[],"d":[]},"eD":{"c":["al"],"p":["al"],"m":["al"],"a":[],"i":["al"],"d":[],"e":["al"],"p.E":"al","c.E":"al"},"dz":{"a":[],"d":[]},"dA":{"a":[],"w":["h","@"],"d":[],"F":["h","@"],"w.K":"h","w.V":"@"},"dB":{"b":[],"a":[],"d":[]},"aX":{"b":[],"a":[],"d":[]},"ef":{"b":[],"a":[],"d":[]},"ak":{"a3":["ak"]},"dW":{"J":[]},"dV":{"J":[]},"lO":{"m":["k"],"i":["k"],"e":["k"]},"mo":{"m":["k"],"i":["k"],"e":["k"]},"mn":{"m":["k"],"i":["k"],"e":["k"]},"lM":{"m":["k"],"i":["k"],"e":["k"]},"ml":{"m":["k"],"i":["k"],"e":["k"]},"lN":{"m":["k"],"i":["k"],"e":["k"]},"mm":{"m":["k"],"i":["k"],"e":["k"]},"lI":{"m":["x"],"i":["x"],"e":["x"]},"lJ":{"m":["x"],"i":["x"],"e":["x"]}}')) +A.mP(v.typeUniverse,JSON.parse('{"dj":2,"V":1,"d3":1,"dG":2}')) +var u={f:"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u03f6\x00\u0404\u03f4 \u03f4\u03f6\u01f6\u01f6\u03f6\u03fc\u01f4\u03ff\u03ff\u0584\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u05d4\u01f4\x00\u01f4\x00\u0504\u05c4\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0400\x00\u0400\u0200\u03f7\u0200\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0200\u0200\u0200\u03f7\x00",c:"Error handler must accept one Object or one Object and a StackTrace as arguments, and return a value of the returned future's type"} +var t=(function rtii(){var s=A.iF +return{p:s("aW"),n:s("aq"),cR:s("bL"),fK:s("aY"),t:s("bh"),e8:s("a3<@>"),O:s("bN"),g5:s("y"),dy:s("b_"),fu:s("b0"),b:s("i<@>"),h:s("r"),Q:s("E"),E:s("l"),L:s("a7"),bX:s("bO"),Z:s("bn"),gb:s("bP"),m:s("J"),gk:s("bQ"),c:s("e"),eh:s("e"),X:s("e"),hf:s("e<@>"),hb:s("e"),k:s("O"),I:s("O"),r:s("O"),s:s("O"),gn:s("O<@>"),G:s("O"),T:s("cs"),o:s("d"),J:s("aJ"),aU:s("v<@>"),e:s("a"),v:s("aF"),dr:s("aK"),bG:s("ah"),de:s("bW"),am:s("m"),w:s("m"),f9:s("m"),j:s("m<@>"),d:s("bX"),ck:s("F"),a:s("F"),f:s("F<@,@>"),dv:s("K"),bK:s("bY"),cI:s("a9"),V:s("ai"),bZ:s("aM"),dE:s("Q"),A:s("o"),f6:s("ay"),P:s("L"),eq:s("aj"),K:s("z"),he:s("aa"),gV:s("aN"),gT:s("oR"),at:s("aA<@>"),eU:s("aA"),ew:s("c_"),bA:s("ak"),D:s("c0"),cq:s("ar"),cW:s("k_"),d0:s("as"),fY:s("ab"),f7:s("ac"),gf:s("ad"),l:s("b5"),N:s("h"),dG:s("h(h)"),cO:s("a_"),g7:s("n"),aW:s("c2"),a0:s("af"),c7:s("a0"),aK:s("ag"),cM:s("al"),dm:s("A"),eK:s("aO"),ak:s("bs"),dD:s("eH"),fz:s("bt<@>"),h9:s("c4"),ac:s("W"),cl:s("aH"),aY:s("aH"),C:s("aH"),U:s("an"),R:s("an"),_:s("M<@>"),fJ:s("M"),cr:s("bv"),y:s("S"),al:s("S(z)"),i:s("x"),z:s("@"),fO:s("@()"),x:s("@(z)"),W:s("@(z,b5)"),bU:s("@(ar)"),Y:s("@(@,@)"),S:s("k"),B:s("r?"),eH:s("bo?"),bx:s("a8?"),an:s("d?"),bM:s("m<@>?"),cK:s("z?"),dk:s("h?"),F:s("aR<@,@>?"),g:s("f8?"),fQ:s("S?"),cD:s("x?"),bw:s("@(l)?"),h6:s("k?"),cg:s("H?"),bn:s("~()?"),eN:s("~(aF)?"),eQ:s("~(aN)?"),q:s("H"),H:s("~"),M:s("~()"),eA:s("~(h,h)"),u:s("~(h,@)")}})();(function constants(){var s=hunkHelpers.makeConstList +B.l=A.aW.prototype +B.p=A.bh.prototype +B.j=A.bk.prototype +B.K=A.ci.prototype +B.L=A.cj.prototype +B.N=A.cp.prototype +B.O=J.bR.prototype +B.b=J.O.prototype +B.P=J.cq.prototype +B.c=J.cr.prototype +B.e=J.bS.prototype +B.a=J.b3.prototype +B.Q=J.aJ.prototype +B.R=J.a.prototype +B.T=A.aK.prototype +B.x=A.cA.prototype +B.y=J.eh.prototype +B.z=A.cG.prototype +B.A=A.cL.prototype +B.ad=A.cM.prototype +B.n=J.bs.prototype +B.o=A.c3.prototype +B.ae=new A.fT() +B.B=new A.dC() +B.q=function getTagFallback(o) { + var s = Object.prototype.toString.call(o); + return s.substring(8, s.length - 1); +} +B.C=function() { + var toStringFunction = Object.prototype.toString; + function getTag(o) { + var s = toStringFunction.call(o); + return s.substring(8, s.length - 1); + } + function getUnknownTag(object, tag) { + if (/^HTML[A-Z].*Element$/.test(tag)) { + var name = toStringFunction.call(object); + if (name == "[object Object]") return null; + return "HTMLElement"; + } + } + function getUnknownTagGenericBrowser(object, tag) { + if (object instanceof HTMLElement) return "HTMLElement"; + return getUnknownTag(object, tag); + } + function prototypeForTag(tag) { + if (typeof window == "undefined") return null; + if (typeof window[tag] == "undefined") return null; + var constructor = window[tag]; + if (typeof constructor != "function") return null; + return constructor.prototype; + } + function discriminator(tag) { return null; } + var isBrowser = typeof HTMLElement == "function"; + return { + getTag: getTag, + getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag, + prototypeForTag: prototypeForTag, + discriminator: discriminator }; +} +B.H=function(getTagFallback) { + return function(hooks) { + if (typeof navigator != "object") return hooks; + var userAgent = navigator.userAgent; + if (typeof userAgent != "string") return hooks; + if (userAgent.indexOf("DumpRenderTree") >= 0) return hooks; + if (userAgent.indexOf("Chrome") >= 0) { + function confirm(p) { + return typeof window == "object" && window[p] && window[p].name == p; + } + if (confirm("Window") && confirm("HTMLElement")) return hooks; + } + hooks.getTag = getTagFallback; + }; +} +B.D=function(hooks) { + if (typeof dartExperimentalFixupGetTag != "function") return hooks; + hooks.getTag = dartExperimentalFixupGetTag(hooks.getTag); +} +B.G=function(hooks) { + if (typeof navigator != "object") return hooks; + var userAgent = navigator.userAgent; + if (typeof userAgent != "string") return hooks; + if (userAgent.indexOf("Firefox") == -1) return hooks; + var getTag = hooks.getTag; + var quickMap = { + "BeforeUnloadEvent": "Event", + "DataTransfer": "Clipboard", + "GeoGeolocation": "Geolocation", + "Location": "!Location", + "WorkerMessageEvent": "MessageEvent", + "XMLDocument": "!Document"}; + function getTagFirefox(o) { + var tag = getTag(o); + return quickMap[tag] || tag; + } + hooks.getTag = getTagFirefox; +} +B.F=function(hooks) { + if (typeof navigator != "object") return hooks; + var userAgent = navigator.userAgent; + if (typeof userAgent != "string") return hooks; + if (userAgent.indexOf("Trident/") == -1) return hooks; + var getTag = hooks.getTag; + var quickMap = { + "BeforeUnloadEvent": "Event", + "DataTransfer": "Clipboard", + "HTMLDDElement": "HTMLElement", + "HTMLDTElement": "HTMLElement", + "HTMLPhraseElement": "HTMLElement", + "Position": "Geoposition" + }; + function getTagIE(o) { + var tag = getTag(o); + var newTag = quickMap[tag]; + if (newTag) return newTag; + if (tag == "Object") { + if (window.DataView && (o instanceof window.DataView)) return "DataView"; + } + return tag; + } + function prototypeForTagIE(tag) { + var constructor = window[tag]; + if (constructor == null) return null; + return constructor.prototype; + } + hooks.getTag = getTagIE; + hooks.prototypeForTag = prototypeForTagIE; +} +B.E=function(hooks) { + var getTag = hooks.getTag; + var prototypeForTag = hooks.prototypeForTag; + function getTagFixed(o) { + var tag = getTag(o); + if (tag == "Document") { + if (!!o.xmlVersion) return "!Document"; + return "!HTMLDocument"; + } + return tag; + } + function prototypeForTagFixed(tag) { + if (tag == "Document") return null; + return prototypeForTag(tag); + } + hooks.getTag = getTagFixed; + hooks.prototypeForTag = prototypeForTagFixed; +} +B.r=function(hooks) { return hooks; } + +B.t=new A.e_() +B.I=new A.eg() +B.h=new A.hH() +B.d=new A.fj() +B.i=new A.ft() +B.J=new A.db() +B.u=new A.b0(0) +B.M=new A.b0(2e5) +B.S=new A.hb(null) +B.U=s([],t.k) +B.v=s([],t.I) +B.f=s([],t.s) +B.w=s(["bind","if","ref","repeat","syntax"],t.s) +B.m=s(["A::href","AREA::href","BLOCKQUOTE::cite","BODY::background","COMMAND::icon","DEL::cite","FORM::action","IMG::src","INPUT::src","INS::cite","Q::cite","VIDEO::poster"],t.s) +B.V=s(["HEAD","AREA","BASE","BASEFONT","BR","COL","COLGROUP","EMBED","FRAME","FRAMESET","HR","IMAGE","IMG","INPUT","ISINDEX","LINK","META","PARAM","SOURCE","STYLE","TITLE","WBR"],t.s) +B.W=s(["*::class","*::dir","*::draggable","*::hidden","*::id","*::inert","*::itemprop","*::itemref","*::itemscope","*::lang","*::spellcheck","*::title","*::translate","A::accesskey","A::coords","A::hreflang","A::name","A::shape","A::tabindex","A::target","A::type","AREA::accesskey","AREA::alt","AREA::coords","AREA::nohref","AREA::shape","AREA::tabindex","AREA::target","AUDIO::controls","AUDIO::loop","AUDIO::mediagroup","AUDIO::muted","AUDIO::preload","BDO::dir","BODY::alink","BODY::bgcolor","BODY::link","BODY::text","BODY::vlink","BR::clear","BUTTON::accesskey","BUTTON::disabled","BUTTON::name","BUTTON::tabindex","BUTTON::type","BUTTON::value","CANVAS::height","CANVAS::width","CAPTION::align","COL::align","COL::char","COL::charoff","COL::span","COL::valign","COL::width","COLGROUP::align","COLGROUP::char","COLGROUP::charoff","COLGROUP::span","COLGROUP::valign","COLGROUP::width","COMMAND::checked","COMMAND::command","COMMAND::disabled","COMMAND::label","COMMAND::radiogroup","COMMAND::type","DATA::value","DEL::datetime","DETAILS::open","DIR::compact","DIV::align","DL::compact","FIELDSET::disabled","FONT::color","FONT::face","FONT::size","FORM::accept","FORM::autocomplete","FORM::enctype","FORM::method","FORM::name","FORM::novalidate","FORM::target","FRAME::name","H1::align","H2::align","H3::align","H4::align","H5::align","H6::align","HR::align","HR::noshade","HR::size","HR::width","HTML::version","IFRAME::align","IFRAME::frameborder","IFRAME::height","IFRAME::marginheight","IFRAME::marginwidth","IFRAME::width","IMG::align","IMG::alt","IMG::border","IMG::height","IMG::hspace","IMG::ismap","IMG::name","IMG::usemap","IMG::vspace","IMG::width","INPUT::accept","INPUT::accesskey","INPUT::align","INPUT::alt","INPUT::autocomplete","INPUT::autofocus","INPUT::checked","INPUT::disabled","INPUT::inputmode","INPUT::ismap","INPUT::list","INPUT::max","INPUT::maxlength","INPUT::min","INPUT::multiple","INPUT::name","INPUT::placeholder","INPUT::readonly","INPUT::required","INPUT::size","INPUT::step","INPUT::tabindex","INPUT::type","INPUT::usemap","INPUT::value","INS::datetime","KEYGEN::disabled","KEYGEN::keytype","KEYGEN::name","LABEL::accesskey","LABEL::for","LEGEND::accesskey","LEGEND::align","LI::type","LI::value","LINK::sizes","MAP::name","MENU::compact","MENU::label","MENU::type","METER::high","METER::low","METER::max","METER::min","METER::value","OBJECT::typemustmatch","OL::compact","OL::reversed","OL::start","OL::type","OPTGROUP::disabled","OPTGROUP::label","OPTION::disabled","OPTION::label","OPTION::selected","OPTION::value","OUTPUT::for","OUTPUT::name","P::align","PRE::width","PROGRESS::max","PROGRESS::min","PROGRESS::value","SELECT::autocomplete","SELECT::disabled","SELECT::multiple","SELECT::name","SELECT::required","SELECT::size","SELECT::tabindex","SOURCE::type","TABLE::align","TABLE::bgcolor","TABLE::border","TABLE::cellpadding","TABLE::cellspacing","TABLE::frame","TABLE::rules","TABLE::summary","TABLE::width","TBODY::align","TBODY::char","TBODY::charoff","TBODY::valign","TD::abbr","TD::align","TD::axis","TD::bgcolor","TD::char","TD::charoff","TD::colspan","TD::headers","TD::height","TD::nowrap","TD::rowspan","TD::scope","TD::valign","TD::width","TEXTAREA::accesskey","TEXTAREA::autocomplete","TEXTAREA::cols","TEXTAREA::disabled","TEXTAREA::inputmode","TEXTAREA::name","TEXTAREA::placeholder","TEXTAREA::readonly","TEXTAREA::required","TEXTAREA::rows","TEXTAREA::tabindex","TEXTAREA::wrap","TFOOT::align","TFOOT::char","TFOOT::charoff","TFOOT::valign","TH::abbr","TH::align","TH::axis","TH::bgcolor","TH::char","TH::charoff","TH::colspan","TH::headers","TH::height","TH::nowrap","TH::rowspan","TH::scope","TH::valign","TH::width","THEAD::align","THEAD::char","THEAD::charoff","THEAD::valign","TR::align","TR::bgcolor","TR::char","TR::charoff","TR::valign","TRACK::default","TRACK::kind","TRACK::label","TRACK::srclang","UL::compact","UL::type","VIDEO::controls","VIDEO::height","VIDEO::loop","VIDEO::mediagroup","VIDEO::muted","VIDEO::preload","VIDEO::width"],t.s) +B.Y={} +B.k=new A.ch(B.Y,[],A.iF("ch")) +B.Z={flutter:0} +B.a_=new A.bN(B.Z,1,t.O) +B.X={"dart:cli":0,"dart:html":1,"dart:indexed_db":2,"dart:mirrors":3,"dart:svg":4,"dart:web_audio":5,"dart:web_gl":6} +B.a0=new A.bN(B.X,7,t.O) +B.a1=A.aC("oo") +B.a2=A.aC("op") +B.a3=A.aC("lI") +B.a4=A.aC("lJ") +B.a5=A.aC("lM") +B.a6=A.aC("lN") +B.a7=A.aC("lO") +B.a8=A.aC("z") +B.a9=A.aC("ml") +B.aa=A.aC("mm") +B.ab=A.aC("mn") +B.ac=A.aC("mo")})();(function staticFields(){$.ie=null +$.ap=A.t([],A.iF("O")) +$.jU=null +$.jG=null +$.jF=null +$.kM=null +$.kI=null +$.kS=null +$.iE=null +$.iL=null +$.jo=null +$.c8=null +$.dp=null +$.dq=null +$.jk=!1 +$.C=B.d +$.b1=null +$.iZ=null +$.jL=null +$.jK=null +$.f1=A.hd(t.N,t.Z)})();(function lazyInitializers(){var s=hunkHelpers.lazyFinal +s($,"oA","kX",()=>A.nX("_$dart_dartClosure")) +s($,"pd","ld",()=>A.t([new J.dX()],A.iF("O"))) +s($,"oW","l1",()=>A.aP(A.hR({ +toString:function(){return"$receiver$"}}))) +s($,"oX","l2",()=>A.aP(A.hR({$method$:null, +toString:function(){return"$receiver$"}}))) +s($,"oY","l3",()=>A.aP(A.hR(null))) +s($,"oZ","l4",()=>A.aP(function(){var $argumentsExpr$="$arguments$" +try{null.$method$($argumentsExpr$)}catch(r){return r.message}}())) +s($,"p1","l7",()=>A.aP(A.hR(void 0))) +s($,"p2","l8",()=>A.aP(function(){var $argumentsExpr$="$arguments$" +try{(void 0).$method$($argumentsExpr$)}catch(r){return r.message}}())) +s($,"p0","l6",()=>A.aP(A.k2(null))) +s($,"p_","l5",()=>A.aP(function(){try{null.$method$}catch(r){return r.message}}())) +s($,"p4","la",()=>A.aP(A.k2(void 0))) +s($,"p3","l9",()=>A.aP(function(){try{(void 0).$method$}catch(r){return r.message}}())) +s($,"p7","js",()=>A.mu()) +s($,"p8","lb",()=>new Int8Array(A.nd(A.t([-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-2,-2,-2,-2,-2,62,-2,62,-2,63,52,53,54,55,56,57,58,59,60,61,-2,-2,-2,-1,-2,-2,-2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-2,-2,-2,-2,63,-2,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-2,-2,-2,-2,-2],t.G)))) +s($,"pc","iR",()=>A.kQ(B.a8)) +s($,"ox","kW",()=>({})) +s($,"p9","lc",()=>A.jT(["A","ABBR","ACRONYM","ADDRESS","AREA","ARTICLE","ASIDE","AUDIO","B","BDI","BDO","BIG","BLOCKQUOTE","BR","BUTTON","CANVAS","CAPTION","CENTER","CITE","CODE","COL","COLGROUP","COMMAND","DATA","DATALIST","DD","DEL","DETAILS","DFN","DIR","DIV","DL","DT","EM","FIELDSET","FIGCAPTION","FIGURE","FONT","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","I","IFRAME","IMG","INPUT","INS","KBD","LABEL","LEGEND","LI","MAP","MARK","MENU","METER","NAV","NOBR","OL","OPTGROUP","OPTION","OUTPUT","P","PRE","PROGRESS","Q","S","SAMP","SECTION","SELECT","SMALL","SOURCE","SPAN","STRIKE","STRONG","SUB","SUMMARY","SUP","TABLE","TBODY","TD","TEXTAREA","TFOOT","TH","THEAD","TIME","TR","TRACK","TT","U","UL","VAR","VIDEO","WBR"],t.N)) +s($,"ot","kV",()=>A.m9("^\\S+$")) +s($,"oE","jr",()=>B.a.ao(A.iY(),"Opera",0)) +s($,"oD","l_",()=>!$.jr()&&B.a.ao(A.iY(),"Trident/",0)) +s($,"oC","kZ",()=>B.a.ao(A.iY(),"Firefox",0)) +s($,"oB","kY",()=>"-"+$.l0()+"-") +s($,"oF","l0",()=>{if($.kZ())var r="moz" +else if($.l_())r="ms" +else r=$.jr()?"o":"webkit" +return r}) +s($,"pg","bJ",()=>new A.ho()) +s($,"pe","le",()=>A.jv("sidebar-nav",t.h)) +s($,"pb","ju",()=>A.jv("doc-main-container",t.h)) +s($,"pa","jt",()=>{var r=A.lt("body",t.h) +r.toString +return r})})();(function nativeSupport(){!function(){var s=function(a){var m={} +m[a]=1 +return Object.keys(hunkHelpers.convertToFastObject(m))[0]} +v.getIsolateTag=function(a){return s("___dart_"+a+v.isolateTag)} +var r="___dart_isolate_tags_" +var q=Object[r]||(Object[r]=Object.create(null)) +var p="_ZxYxX" +for(var o=0;;o++){var n=s(p+"_"+o+"_") +if(!(n in q)){q[n]=1 +v.isolateTag=n +break}}v.dispatchPropertyName=v.getIsolateTag("dispatch_record")}() +hunkHelpers.setOrUpdateInterceptorsByTag({WebGL:J.bR,AnimationEffectReadOnly:J.a,AnimationEffectTiming:J.a,AnimationEffectTimingReadOnly:J.a,AnimationTimeline:J.a,AnimationWorkletGlobalScope:J.a,AuthenticatorAssertionResponse:J.a,AuthenticatorAttestationResponse:J.a,AuthenticatorResponse:J.a,BackgroundFetchFetch:J.a,BackgroundFetchManager:J.a,BackgroundFetchSettledFetch:J.a,BarProp:J.a,BarcodeDetector:J.a,BluetoothRemoteGATTDescriptor:J.a,Body:J.a,BudgetState:J.a,CacheStorage:J.a,CanvasGradient:J.a,CanvasPattern:J.a,CanvasRenderingContext2D:J.a,Client:J.a,Clients:J.a,CookieStore:J.a,Coordinates:J.a,Credential:J.a,CredentialUserData:J.a,CredentialsContainer:J.a,Crypto:J.a,CryptoKey:J.a,CSS:J.a,CSSVariableReferenceValue:J.a,CustomElementRegistry:J.a,DataTransfer:J.a,DataTransferItem:J.a,DeprecatedStorageInfo:J.a,DeprecatedStorageQuota:J.a,DeprecationReport:J.a,DetectedBarcode:J.a,DetectedFace:J.a,DetectedText:J.a,DeviceAcceleration:J.a,DeviceRotationRate:J.a,DirectoryEntry:J.a,webkitFileSystemDirectoryEntry:J.a,FileSystemDirectoryEntry:J.a,DirectoryReader:J.a,WebKitDirectoryReader:J.a,webkitFileSystemDirectoryReader:J.a,FileSystemDirectoryReader:J.a,DocumentOrShadowRoot:J.a,DocumentTimeline:J.a,DOMError:J.a,Iterator:J.a,DOMMatrix:J.a,DOMMatrixReadOnly:J.a,DOMParser:J.a,DOMPoint:J.a,DOMPointReadOnly:J.a,DOMQuad:J.a,DOMStringMap:J.a,Entry:J.a,webkitFileSystemEntry:J.a,FileSystemEntry:J.a,External:J.a,FaceDetector:J.a,FederatedCredential:J.a,FileEntry:J.a,webkitFileSystemFileEntry:J.a,FileSystemFileEntry:J.a,DOMFileSystem:J.a,WebKitFileSystem:J.a,webkitFileSystem:J.a,FileSystem:J.a,FontFace:J.a,FontFaceSource:J.a,FormData:J.a,GamepadButton:J.a,GamepadPose:J.a,Geolocation:J.a,Position:J.a,GeolocationPosition:J.a,Headers:J.a,HTMLHyperlinkElementUtils:J.a,IdleDeadline:J.a,ImageBitmap:J.a,ImageBitmapRenderingContext:J.a,ImageCapture:J.a,InputDeviceCapabilities:J.a,IntersectionObserver:J.a,IntersectionObserverEntry:J.a,InterventionReport:J.a,KeyframeEffect:J.a,KeyframeEffectReadOnly:J.a,MediaCapabilities:J.a,MediaCapabilitiesInfo:J.a,MediaDeviceInfo:J.a,MediaError:J.a,MediaKeyStatusMap:J.a,MediaKeySystemAccess:J.a,MediaKeys:J.a,MediaKeysPolicy:J.a,MediaMetadata:J.a,MediaSession:J.a,MediaSettingsRange:J.a,MemoryInfo:J.a,MessageChannel:J.a,Metadata:J.a,MutationObserver:J.a,WebKitMutationObserver:J.a,MutationRecord:J.a,NavigationPreloadManager:J.a,Navigator:J.a,NavigatorAutomationInformation:J.a,NavigatorConcurrentHardware:J.a,NavigatorCookies:J.a,NavigatorUserMediaError:J.a,NodeFilter:J.a,NodeIterator:J.a,NonDocumentTypeChildNode:J.a,NonElementParentNode:J.a,NoncedElement:J.a,OffscreenCanvasRenderingContext2D:J.a,OverconstrainedError:J.a,PaintRenderingContext2D:J.a,PaintSize:J.a,PaintWorkletGlobalScope:J.a,PasswordCredential:J.a,Path2D:J.a,PaymentAddress:J.a,PaymentInstruments:J.a,PaymentManager:J.a,PaymentResponse:J.a,PerformanceEntry:J.a,PerformanceLongTaskTiming:J.a,PerformanceMark:J.a,PerformanceMeasure:J.a,PerformanceNavigation:J.a,PerformanceNavigationTiming:J.a,PerformanceObserver:J.a,PerformanceObserverEntryList:J.a,PerformancePaintTiming:J.a,PerformanceResourceTiming:J.a,PerformanceServerTiming:J.a,PerformanceTiming:J.a,Permissions:J.a,PhotoCapabilities:J.a,PositionError:J.a,GeolocationPositionError:J.a,Presentation:J.a,PresentationReceiver:J.a,PublicKeyCredential:J.a,PushManager:J.a,PushMessageData:J.a,PushSubscription:J.a,PushSubscriptionOptions:J.a,Range:J.a,RelatedApplication:J.a,ReportBody:J.a,ReportingObserver:J.a,ResizeObserver:J.a,ResizeObserverEntry:J.a,RTCCertificate:J.a,RTCIceCandidate:J.a,mozRTCIceCandidate:J.a,RTCLegacyStatsReport:J.a,RTCRtpContributingSource:J.a,RTCRtpReceiver:J.a,RTCRtpSender:J.a,RTCSessionDescription:J.a,mozRTCSessionDescription:J.a,RTCStatsResponse:J.a,Screen:J.a,ScrollState:J.a,ScrollTimeline:J.a,Selection:J.a,SpeechRecognitionAlternative:J.a,SpeechSynthesisVoice:J.a,StaticRange:J.a,StorageManager:J.a,StyleMedia:J.a,StylePropertyMap:J.a,StylePropertyMapReadonly:J.a,SyncManager:J.a,TaskAttributionTiming:J.a,TextDetector:J.a,TextMetrics:J.a,TrackDefault:J.a,TreeWalker:J.a,TrustedHTML:J.a,TrustedScriptURL:J.a,TrustedURL:J.a,UnderlyingSourceBase:J.a,URLSearchParams:J.a,VRCoordinateSystem:J.a,VRDisplayCapabilities:J.a,VREyeParameters:J.a,VRFrameData:J.a,VRFrameOfReference:J.a,VRPose:J.a,VRStageBounds:J.a,VRStageBoundsPoint:J.a,VRStageParameters:J.a,ValidityState:J.a,VideoPlaybackQuality:J.a,VideoTrack:J.a,VTTRegion:J.a,WindowClient:J.a,WorkletAnimation:J.a,WorkletGlobalScope:J.a,XPathEvaluator:J.a,XPathExpression:J.a,XPathNSResolver:J.a,XPathResult:J.a,XMLSerializer:J.a,XSLTProcessor:J.a,Bluetooth:J.a,BluetoothCharacteristicProperties:J.a,BluetoothRemoteGATTServer:J.a,BluetoothRemoteGATTService:J.a,BluetoothUUID:J.a,BudgetService:J.a,Cache:J.a,DOMFileSystemSync:J.a,DirectoryEntrySync:J.a,DirectoryReaderSync:J.a,EntrySync:J.a,FileEntrySync:J.a,FileReaderSync:J.a,FileWriterSync:J.a,HTMLAllCollection:J.a,Mojo:J.a,MojoHandle:J.a,MojoWatcher:J.a,NFC:J.a,PagePopupController:J.a,Report:J.a,Request:J.a,Response:J.a,SubtleCrypto:J.a,USBAlternateInterface:J.a,USBConfiguration:J.a,USBDevice:J.a,USBEndpoint:J.a,USBInTransferResult:J.a,USBInterface:J.a,USBIsochronousInTransferPacket:J.a,USBIsochronousInTransferResult:J.a,USBIsochronousOutTransferPacket:J.a,USBIsochronousOutTransferResult:J.a,USBOutTransferResult:J.a,WorkerLocation:J.a,WorkerNavigator:J.a,Worklet:J.a,IDBCursor:J.a,IDBCursorWithValue:J.a,IDBFactory:J.a,IDBIndex:J.a,IDBKeyRange:J.a,IDBObjectStore:J.a,IDBObservation:J.a,IDBObserver:J.a,IDBObserverChanges:J.a,SVGAngle:J.a,SVGAnimatedAngle:J.a,SVGAnimatedBoolean:J.a,SVGAnimatedEnumeration:J.a,SVGAnimatedInteger:J.a,SVGAnimatedLength:J.a,SVGAnimatedLengthList:J.a,SVGAnimatedNumber:J.a,SVGAnimatedNumberList:J.a,SVGAnimatedPreserveAspectRatio:J.a,SVGAnimatedRect:J.a,SVGAnimatedString:J.a,SVGAnimatedTransformList:J.a,SVGMatrix:J.a,SVGPoint:J.a,SVGPreserveAspectRatio:J.a,SVGRect:J.a,SVGUnitTypes:J.a,AudioListener:J.a,AudioParam:J.a,AudioTrack:J.a,AudioWorkletGlobalScope:J.a,AudioWorkletProcessor:J.a,PeriodicWave:J.a,WebGLActiveInfo:J.a,ANGLEInstancedArrays:J.a,ANGLE_instanced_arrays:J.a,WebGLBuffer:J.a,WebGLCanvas:J.a,WebGLColorBufferFloat:J.a,WebGLCompressedTextureASTC:J.a,WebGLCompressedTextureATC:J.a,WEBGL_compressed_texture_atc:J.a,WebGLCompressedTextureETC1:J.a,WEBGL_compressed_texture_etc1:J.a,WebGLCompressedTextureETC:J.a,WebGLCompressedTexturePVRTC:J.a,WEBGL_compressed_texture_pvrtc:J.a,WebGLCompressedTextureS3TC:J.a,WEBGL_compressed_texture_s3tc:J.a,WebGLCompressedTextureS3TCsRGB:J.a,WebGLDebugRendererInfo:J.a,WEBGL_debug_renderer_info:J.a,WebGLDebugShaders:J.a,WEBGL_debug_shaders:J.a,WebGLDepthTexture:J.a,WEBGL_depth_texture:J.a,WebGLDrawBuffers:J.a,WEBGL_draw_buffers:J.a,EXTsRGB:J.a,EXT_sRGB:J.a,EXTBlendMinMax:J.a,EXT_blend_minmax:J.a,EXTColorBufferFloat:J.a,EXTColorBufferHalfFloat:J.a,EXTDisjointTimerQuery:J.a,EXTDisjointTimerQueryWebGL2:J.a,EXTFragDepth:J.a,EXT_frag_depth:J.a,EXTShaderTextureLOD:J.a,EXT_shader_texture_lod:J.a,EXTTextureFilterAnisotropic:J.a,EXT_texture_filter_anisotropic:J.a,WebGLFramebuffer:J.a,WebGLGetBufferSubDataAsync:J.a,WebGLLoseContext:J.a,WebGLExtensionLoseContext:J.a,WEBGL_lose_context:J.a,OESElementIndexUint:J.a,OES_element_index_uint:J.a,OESStandardDerivatives:J.a,OES_standard_derivatives:J.a,OESTextureFloat:J.a,OES_texture_float:J.a,OESTextureFloatLinear:J.a,OES_texture_float_linear:J.a,OESTextureHalfFloat:J.a,OES_texture_half_float:J.a,OESTextureHalfFloatLinear:J.a,OES_texture_half_float_linear:J.a,OESVertexArrayObject:J.a,OES_vertex_array_object:J.a,WebGLProgram:J.a,WebGLQuery:J.a,WebGLRenderbuffer:J.a,WebGLRenderingContext:J.a,WebGL2RenderingContext:J.a,WebGLSampler:J.a,WebGLShader:J.a,WebGLShaderPrecisionFormat:J.a,WebGLSync:J.a,WebGLTexture:J.a,WebGLTimerQueryEXT:J.a,WebGLTransformFeedback:J.a,WebGLUniformLocation:J.a,WebGLVertexArrayObject:J.a,WebGLVertexArrayObjectOES:J.a,WebGL2RenderingContextBase:J.a,ArrayBuffer:A.aM,SharedArrayBuffer:A.eb,ArrayBufferView:A.Q,DataView:A.e5,Float32Array:A.e6,Float64Array:A.e7,Int16Array:A.e8,Int32Array:A.e9,Int8Array:A.ea,Uint16Array:A.ec,Uint32Array:A.ed,Uint8ClampedArray:A.cz,CanvasPixelArray:A.cz,Uint8Array:A.cA,HTMLAudioElement:A.q,HTMLBRElement:A.q,HTMLButtonElement:A.q,HTMLCanvasElement:A.q,HTMLContentElement:A.q,HTMLDListElement:A.q,HTMLDataElement:A.q,HTMLDataListElement:A.q,HTMLDetailsElement:A.q,HTMLDialogElement:A.q,HTMLEmbedElement:A.q,HTMLFieldSetElement:A.q,HTMLHRElement:A.q,HTMLHeadElement:A.q,HTMLHeadingElement:A.q,HTMLHtmlElement:A.q,HTMLIFrameElement:A.q,HTMLImageElement:A.q,HTMLLabelElement:A.q,HTMLLegendElement:A.q,HTMLMapElement:A.q,HTMLMediaElement:A.q,HTMLMenuElement:A.q,HTMLMetaElement:A.q,HTMLMeterElement:A.q,HTMLModElement:A.q,HTMLOListElement:A.q,HTMLObjectElement:A.q,HTMLOptGroupElement:A.q,HTMLOptionElement:A.q,HTMLOutputElement:A.q,HTMLParagraphElement:A.q,HTMLParamElement:A.q,HTMLPictureElement:A.q,HTMLPreElement:A.q,HTMLProgressElement:A.q,HTMLQuoteElement:A.q,HTMLScriptElement:A.q,HTMLShadowElement:A.q,HTMLSlotElement:A.q,HTMLSourceElement:A.q,HTMLStyleElement:A.q,HTMLTableCaptionElement:A.q,HTMLTableCellElement:A.q,HTMLTableDataCellElement:A.q,HTMLTableHeaderCellElement:A.q,HTMLTableColElement:A.q,HTMLTextAreaElement:A.q,HTMLTimeElement:A.q,HTMLTitleElement:A.q,HTMLTrackElement:A.q,HTMLUnknownElement:A.q,HTMLVideoElement:A.q,HTMLDirectoryElement:A.q,HTMLFontElement:A.q,HTMLFrameElement:A.q,HTMLFrameSetElement:A.q,HTMLMarqueeElement:A.q,HTMLElement:A.q,AccessibleNodeList:A.dt,HTMLAnchorElement:A.aW,HTMLAreaElement:A.du,HTMLBaseElement:A.bL,Blob:A.aY,HTMLBodyElement:A.bh,CDATASection:A.aD,CharacterData:A.aD,Comment:A.aD,ProcessingInstruction:A.aD,Text:A.aD,CSSPerspective:A.dI,CSSCharsetRule:A.y,CSSConditionRule:A.y,CSSFontFaceRule:A.y,CSSGroupingRule:A.y,CSSImportRule:A.y,CSSKeyframeRule:A.y,MozCSSKeyframeRule:A.y,WebKitCSSKeyframeRule:A.y,CSSKeyframesRule:A.y,MozCSSKeyframesRule:A.y,WebKitCSSKeyframesRule:A.y,CSSMediaRule:A.y,CSSNamespaceRule:A.y,CSSPageRule:A.y,CSSRule:A.y,CSSStyleRule:A.y,CSSSupportsRule:A.y,CSSViewportRule:A.y,CSSStyleDeclaration:A.bk,MSStyleCSSProperties:A.bk,CSS2Properties:A.bk,CSSImageValue:A.a4,CSSKeywordValue:A.a4,CSSNumericValue:A.a4,CSSPositionValue:A.a4,CSSResourceValue:A.a4,CSSUnitValue:A.a4,CSSURLImageValue:A.a4,CSSStyleValue:A.a4,CSSMatrixComponent:A.ax,CSSRotation:A.ax,CSSScale:A.ax,CSSSkew:A.ax,CSSTranslation:A.ax,CSSTransformComponent:A.ax,CSSTransformValue:A.dJ,CSSUnparsedValue:A.dK,DataTransferItemList:A.dL,HTMLDivElement:A.ci,XMLDocument:A.bl,Document:A.bl,DOMException:A.dN,DOMImplementation:A.cj,ClientRectList:A.ck,DOMRectList:A.ck,DOMRectReadOnly:A.cl,DOMStringList:A.dO,DOMTokenList:A.dP,MathMLElement:A.r,Element:A.r,AbortPaymentEvent:A.l,AnimationEvent:A.l,AnimationPlaybackEvent:A.l,ApplicationCacheErrorEvent:A.l,BackgroundFetchClickEvent:A.l,BackgroundFetchEvent:A.l,BackgroundFetchFailEvent:A.l,BackgroundFetchedEvent:A.l,BeforeInstallPromptEvent:A.l,BeforeUnloadEvent:A.l,BlobEvent:A.l,CanMakePaymentEvent:A.l,ClipboardEvent:A.l,CloseEvent:A.l,CustomEvent:A.l,DeviceMotionEvent:A.l,DeviceOrientationEvent:A.l,ErrorEvent:A.l,ExtendableEvent:A.l,ExtendableMessageEvent:A.l,FetchEvent:A.l,FontFaceSetLoadEvent:A.l,ForeignFetchEvent:A.l,GamepadEvent:A.l,HashChangeEvent:A.l,InstallEvent:A.l,MediaEncryptedEvent:A.l,MediaKeyMessageEvent:A.l,MediaQueryListEvent:A.l,MediaStreamEvent:A.l,MediaStreamTrackEvent:A.l,MessageEvent:A.l,MIDIConnectionEvent:A.l,MIDIMessageEvent:A.l,MutationEvent:A.l,NotificationEvent:A.l,PageTransitionEvent:A.l,PaymentRequestEvent:A.l,PaymentRequestUpdateEvent:A.l,PresentationConnectionAvailableEvent:A.l,PresentationConnectionCloseEvent:A.l,ProgressEvent:A.l,PromiseRejectionEvent:A.l,PushEvent:A.l,RTCDataChannelEvent:A.l,RTCDTMFToneChangeEvent:A.l,RTCPeerConnectionIceEvent:A.l,RTCTrackEvent:A.l,SecurityPolicyViolationEvent:A.l,SensorErrorEvent:A.l,SpeechRecognitionError:A.l,SpeechRecognitionEvent:A.l,SpeechSynthesisEvent:A.l,StorageEvent:A.l,SyncEvent:A.l,TrackEvent:A.l,TransitionEvent:A.l,WebKitTransitionEvent:A.l,VRDeviceEvent:A.l,VRDisplayEvent:A.l,VRSessionEvent:A.l,MojoInterfaceRequestEvent:A.l,ResourceProgressEvent:A.l,USBConnectionEvent:A.l,IDBVersionChangeEvent:A.l,AudioProcessingEvent:A.l,OfflineAudioCompletionEvent:A.l,WebGLContextEvent:A.l,Event:A.l,InputEvent:A.l,SubmitEvent:A.l,AbsoluteOrientationSensor:A.b,Accelerometer:A.b,AccessibleNode:A.b,AmbientLightSensor:A.b,Animation:A.b,ApplicationCache:A.b,DOMApplicationCache:A.b,OfflineResourceList:A.b,BackgroundFetchRegistration:A.b,BatteryManager:A.b,BroadcastChannel:A.b,CanvasCaptureMediaStreamTrack:A.b,DedicatedWorkerGlobalScope:A.b,EventSource:A.b,FileReader:A.b,FontFaceSet:A.b,Gyroscope:A.b,XMLHttpRequest:A.b,XMLHttpRequestEventTarget:A.b,XMLHttpRequestUpload:A.b,LinearAccelerationSensor:A.b,Magnetometer:A.b,MediaDevices:A.b,MediaKeySession:A.b,MediaQueryList:A.b,MediaRecorder:A.b,MediaSource:A.b,MediaStream:A.b,MediaStreamTrack:A.b,MIDIAccess:A.b,MIDIInput:A.b,MIDIOutput:A.b,MIDIPort:A.b,NetworkInformation:A.b,Notification:A.b,OffscreenCanvas:A.b,OrientationSensor:A.b,PaymentRequest:A.b,Performance:A.b,PermissionStatus:A.b,PresentationAvailability:A.b,PresentationConnection:A.b,PresentationConnectionList:A.b,PresentationRequest:A.b,RelativeOrientationSensor:A.b,RemotePlayback:A.b,RTCDataChannel:A.b,DataChannel:A.b,RTCDTMFSender:A.b,RTCPeerConnection:A.b,webkitRTCPeerConnection:A.b,mozRTCPeerConnection:A.b,ScreenOrientation:A.b,Sensor:A.b,ServiceWorker:A.b,ServiceWorkerContainer:A.b,ServiceWorkerGlobalScope:A.b,ServiceWorkerRegistration:A.b,SharedWorker:A.b,SharedWorkerGlobalScope:A.b,SpeechRecognition:A.b,webkitSpeechRecognition:A.b,SpeechSynthesis:A.b,SpeechSynthesisUtterance:A.b,VR:A.b,VRDevice:A.b,VRDisplay:A.b,VRSession:A.b,VisualViewport:A.b,WebSocket:A.b,Worker:A.b,WorkerGlobalScope:A.b,WorkerPerformance:A.b,BluetoothDevice:A.b,BluetoothRemoteGATTCharacteristic:A.b,Clipboard:A.b,MojoInterfaceInterceptor:A.b,USB:A.b,IDBDatabase:A.b,IDBOpenDBRequest:A.b,IDBVersionChangeRequest:A.b,IDBRequest:A.b,IDBTransaction:A.b,AnalyserNode:A.b,RealtimeAnalyserNode:A.b,AudioBufferSourceNode:A.b,AudioDestinationNode:A.b,AudioNode:A.b,AudioScheduledSourceNode:A.b,AudioWorkletNode:A.b,BiquadFilterNode:A.b,ChannelMergerNode:A.b,AudioChannelMerger:A.b,ChannelSplitterNode:A.b,AudioChannelSplitter:A.b,ConstantSourceNode:A.b,ConvolverNode:A.b,DelayNode:A.b,DynamicsCompressorNode:A.b,GainNode:A.b,AudioGainNode:A.b,IIRFilterNode:A.b,MediaElementAudioSourceNode:A.b,MediaStreamAudioDestinationNode:A.b,MediaStreamAudioSourceNode:A.b,OscillatorNode:A.b,Oscillator:A.b,PannerNode:A.b,AudioPannerNode:A.b,webkitAudioPannerNode:A.b,ScriptProcessorNode:A.b,JavaScriptAudioNode:A.b,StereoPannerNode:A.b,WaveShaperNode:A.b,EventTarget:A.b,File:A.a7,FileList:A.bO,FileWriter:A.dQ,HTMLFormElement:A.dS,Gamepad:A.a8,History:A.dT,HTMLCollection:A.b2,HTMLFormControlsCollection:A.b2,HTMLOptionsCollection:A.b2,HTMLDocument:A.cp,ImageData:A.bP,HTMLInputElement:A.bQ,KeyboardEvent:A.aF,HTMLLIElement:A.aK,HTMLLinkElement:A.bW,Location:A.bX,MediaList:A.e1,MessagePort:A.bY,MIDIInputMap:A.e2,MIDIOutputMap:A.e3,MimeType:A.a9,MimeTypeArray:A.e4,MouseEvent:A.ai,DragEvent:A.ai,PointerEvent:A.ai,WheelEvent:A.ai,DocumentFragment:A.o,ShadowRoot:A.o,DocumentType:A.o,Node:A.o,NodeList:A.cB,RadioNodeList:A.cB,Plugin:A.aa,PluginArray:A.ei,PopStateEvent:A.aN,RTCStatsReport:A.en,HTMLSelectElement:A.ep,SourceBuffer:A.ab,SourceBufferList:A.eq,HTMLSpanElement:A.cG,SpeechGrammar:A.ac,SpeechGrammarList:A.er,SpeechRecognitionResult:A.ad,Storage:A.et,CSSStyleSheet:A.a_,StyleSheet:A.a_,HTMLTableElement:A.cL,HTMLTableRowElement:A.ev,HTMLTableSectionElement:A.ew,HTMLTemplateElement:A.c2,TextTrack:A.af,TextTrackCue:A.a0,VTTCue:A.a0,TextTrackCueList:A.ey,TextTrackList:A.ez,TimeRanges:A.eA,Touch:A.ag,TouchList:A.eB,TrackDefaultList:A.eC,CompositionEvent:A.aG,FocusEvent:A.aG,TextEvent:A.aG,TouchEvent:A.aG,UIEvent:A.aG,HTMLUListElement:A.cM,URL:A.eJ,VideoTrackList:A.eK,Window:A.c3,DOMWindow:A.c3,Attr:A.c4,CSSRuleList:A.eP,ClientRect:A.cS,DOMRect:A.cS,GamepadList:A.f0,NamedNodeMap:A.cZ,MozNamedAttrMap:A.cZ,SpeechRecognitionResultList:A.fo,StyleSheetList:A.fv,SVGLength:A.ah,SVGLengthList:A.e0,SVGNumber:A.aj,SVGNumberList:A.ee,SVGPointList:A.ej,SVGScriptElement:A.c_,SVGStringList:A.eu,SVGAElement:A.n,SVGAnimateElement:A.n,SVGAnimateMotionElement:A.n,SVGAnimateTransformElement:A.n,SVGAnimationElement:A.n,SVGCircleElement:A.n,SVGClipPathElement:A.n,SVGDefsElement:A.n,SVGDescElement:A.n,SVGDiscardElement:A.n,SVGEllipseElement:A.n,SVGFEBlendElement:A.n,SVGFEColorMatrixElement:A.n,SVGFEComponentTransferElement:A.n,SVGFECompositeElement:A.n,SVGFEConvolveMatrixElement:A.n,SVGFEDiffuseLightingElement:A.n,SVGFEDisplacementMapElement:A.n,SVGFEDistantLightElement:A.n,SVGFEFloodElement:A.n,SVGFEFuncAElement:A.n,SVGFEFuncBElement:A.n,SVGFEFuncGElement:A.n,SVGFEFuncRElement:A.n,SVGFEGaussianBlurElement:A.n,SVGFEImageElement:A.n,SVGFEMergeElement:A.n,SVGFEMergeNodeElement:A.n,SVGFEMorphologyElement:A.n,SVGFEOffsetElement:A.n,SVGFEPointLightElement:A.n,SVGFESpecularLightingElement:A.n,SVGFESpotLightElement:A.n,SVGFETileElement:A.n,SVGFETurbulenceElement:A.n,SVGFilterElement:A.n,SVGForeignObjectElement:A.n,SVGGElement:A.n,SVGGeometryElement:A.n,SVGGraphicsElement:A.n,SVGImageElement:A.n,SVGLineElement:A.n,SVGLinearGradientElement:A.n,SVGMarkerElement:A.n,SVGMaskElement:A.n,SVGMetadataElement:A.n,SVGPathElement:A.n,SVGPatternElement:A.n,SVGPolygonElement:A.n,SVGPolylineElement:A.n,SVGRadialGradientElement:A.n,SVGRectElement:A.n,SVGSetElement:A.n,SVGStopElement:A.n,SVGStyleElement:A.n,SVGSVGElement:A.n,SVGSwitchElement:A.n,SVGSymbolElement:A.n,SVGTSpanElement:A.n,SVGTextContentElement:A.n,SVGTextElement:A.n,SVGTextPathElement:A.n,SVGTextPositioningElement:A.n,SVGTitleElement:A.n,SVGUseElement:A.n,SVGViewElement:A.n,SVGGradientElement:A.n,SVGComponentTransferFunctionElement:A.n,SVGFEDropShadowElement:A.n,SVGMPathElement:A.n,SVGElement:A.n,SVGTransform:A.al,SVGTransformList:A.eD,AudioBuffer:A.dz,AudioParamMap:A.dA,AudioTrackList:A.dB,AudioContext:A.aX,webkitAudioContext:A.aX,BaseAudioContext:A.aX,OfflineAudioContext:A.ef}) +hunkHelpers.setOrUpdateLeafTags({WebGL:true,AnimationEffectReadOnly:true,AnimationEffectTiming:true,AnimationEffectTimingReadOnly:true,AnimationTimeline:true,AnimationWorkletGlobalScope:true,AuthenticatorAssertionResponse:true,AuthenticatorAttestationResponse:true,AuthenticatorResponse:true,BackgroundFetchFetch:true,BackgroundFetchManager:true,BackgroundFetchSettledFetch:true,BarProp:true,BarcodeDetector:true,BluetoothRemoteGATTDescriptor:true,Body:true,BudgetState:true,CacheStorage:true,CanvasGradient:true,CanvasPattern:true,CanvasRenderingContext2D:true,Client:true,Clients:true,CookieStore:true,Coordinates:true,Credential:true,CredentialUserData:true,CredentialsContainer:true,Crypto:true,CryptoKey:true,CSS:true,CSSVariableReferenceValue:true,CustomElementRegistry:true,DataTransfer:true,DataTransferItem:true,DeprecatedStorageInfo:true,DeprecatedStorageQuota:true,DeprecationReport:true,DetectedBarcode:true,DetectedFace:true,DetectedText:true,DeviceAcceleration:true,DeviceRotationRate:true,DirectoryEntry:true,webkitFileSystemDirectoryEntry:true,FileSystemDirectoryEntry:true,DirectoryReader:true,WebKitDirectoryReader:true,webkitFileSystemDirectoryReader:true,FileSystemDirectoryReader:true,DocumentOrShadowRoot:true,DocumentTimeline:true,DOMError:true,Iterator:true,DOMMatrix:true,DOMMatrixReadOnly:true,DOMParser:true,DOMPoint:true,DOMPointReadOnly:true,DOMQuad:true,DOMStringMap:true,Entry:true,webkitFileSystemEntry:true,FileSystemEntry:true,External:true,FaceDetector:true,FederatedCredential:true,FileEntry:true,webkitFileSystemFileEntry:true,FileSystemFileEntry:true,DOMFileSystem:true,WebKitFileSystem:true,webkitFileSystem:true,FileSystem:true,FontFace:true,FontFaceSource:true,FormData:true,GamepadButton:true,GamepadPose:true,Geolocation:true,Position:true,GeolocationPosition:true,Headers:true,HTMLHyperlinkElementUtils:true,IdleDeadline:true,ImageBitmap:true,ImageBitmapRenderingContext:true,ImageCapture:true,InputDeviceCapabilities:true,IntersectionObserver:true,IntersectionObserverEntry:true,InterventionReport:true,KeyframeEffect:true,KeyframeEffectReadOnly:true,MediaCapabilities:true,MediaCapabilitiesInfo:true,MediaDeviceInfo:true,MediaError:true,MediaKeyStatusMap:true,MediaKeySystemAccess:true,MediaKeys:true,MediaKeysPolicy:true,MediaMetadata:true,MediaSession:true,MediaSettingsRange:true,MemoryInfo:true,MessageChannel:true,Metadata:true,MutationObserver:true,WebKitMutationObserver:true,MutationRecord:true,NavigationPreloadManager:true,Navigator:true,NavigatorAutomationInformation:true,NavigatorConcurrentHardware:true,NavigatorCookies:true,NavigatorUserMediaError:true,NodeFilter:true,NodeIterator:true,NonDocumentTypeChildNode:true,NonElementParentNode:true,NoncedElement:true,OffscreenCanvasRenderingContext2D:true,OverconstrainedError:true,PaintRenderingContext2D:true,PaintSize:true,PaintWorkletGlobalScope:true,PasswordCredential:true,Path2D:true,PaymentAddress:true,PaymentInstruments:true,PaymentManager:true,PaymentResponse:true,PerformanceEntry:true,PerformanceLongTaskTiming:true,PerformanceMark:true,PerformanceMeasure:true,PerformanceNavigation:true,PerformanceNavigationTiming:true,PerformanceObserver:true,PerformanceObserverEntryList:true,PerformancePaintTiming:true,PerformanceResourceTiming:true,PerformanceServerTiming:true,PerformanceTiming:true,Permissions:true,PhotoCapabilities:true,PositionError:true,GeolocationPositionError:true,Presentation:true,PresentationReceiver:true,PublicKeyCredential:true,PushManager:true,PushMessageData:true,PushSubscription:true,PushSubscriptionOptions:true,Range:true,RelatedApplication:true,ReportBody:true,ReportingObserver:true,ResizeObserver:true,ResizeObserverEntry:true,RTCCertificate:true,RTCIceCandidate:true,mozRTCIceCandidate:true,RTCLegacyStatsReport:true,RTCRtpContributingSource:true,RTCRtpReceiver:true,RTCRtpSender:true,RTCSessionDescription:true,mozRTCSessionDescription:true,RTCStatsResponse:true,Screen:true,ScrollState:true,ScrollTimeline:true,Selection:true,SpeechRecognitionAlternative:true,SpeechSynthesisVoice:true,StaticRange:true,StorageManager:true,StyleMedia:true,StylePropertyMap:true,StylePropertyMapReadonly:true,SyncManager:true,TaskAttributionTiming:true,TextDetector:true,TextMetrics:true,TrackDefault:true,TreeWalker:true,TrustedHTML:true,TrustedScriptURL:true,TrustedURL:true,UnderlyingSourceBase:true,URLSearchParams:true,VRCoordinateSystem:true,VRDisplayCapabilities:true,VREyeParameters:true,VRFrameData:true,VRFrameOfReference:true,VRPose:true,VRStageBounds:true,VRStageBoundsPoint:true,VRStageParameters:true,ValidityState:true,VideoPlaybackQuality:true,VideoTrack:true,VTTRegion:true,WindowClient:true,WorkletAnimation:true,WorkletGlobalScope:true,XPathEvaluator:true,XPathExpression:true,XPathNSResolver:true,XPathResult:true,XMLSerializer:true,XSLTProcessor:true,Bluetooth:true,BluetoothCharacteristicProperties:true,BluetoothRemoteGATTServer:true,BluetoothRemoteGATTService:true,BluetoothUUID:true,BudgetService:true,Cache:true,DOMFileSystemSync:true,DirectoryEntrySync:true,DirectoryReaderSync:true,EntrySync:true,FileEntrySync:true,FileReaderSync:true,FileWriterSync:true,HTMLAllCollection:true,Mojo:true,MojoHandle:true,MojoWatcher:true,NFC:true,PagePopupController:true,Report:true,Request:true,Response:true,SubtleCrypto:true,USBAlternateInterface:true,USBConfiguration:true,USBDevice:true,USBEndpoint:true,USBInTransferResult:true,USBInterface:true,USBIsochronousInTransferPacket:true,USBIsochronousInTransferResult:true,USBIsochronousOutTransferPacket:true,USBIsochronousOutTransferResult:true,USBOutTransferResult:true,WorkerLocation:true,WorkerNavigator:true,Worklet:true,IDBCursor:true,IDBCursorWithValue:true,IDBFactory:true,IDBIndex:true,IDBKeyRange:true,IDBObjectStore:true,IDBObservation:true,IDBObserver:true,IDBObserverChanges:true,SVGAngle:true,SVGAnimatedAngle:true,SVGAnimatedBoolean:true,SVGAnimatedEnumeration:true,SVGAnimatedInteger:true,SVGAnimatedLength:true,SVGAnimatedLengthList:true,SVGAnimatedNumber:true,SVGAnimatedNumberList:true,SVGAnimatedPreserveAspectRatio:true,SVGAnimatedRect:true,SVGAnimatedString:true,SVGAnimatedTransformList:true,SVGMatrix:true,SVGPoint:true,SVGPreserveAspectRatio:true,SVGRect:true,SVGUnitTypes:true,AudioListener:true,AudioParam:true,AudioTrack:true,AudioWorkletGlobalScope:true,AudioWorkletProcessor:true,PeriodicWave:true,WebGLActiveInfo:true,ANGLEInstancedArrays:true,ANGLE_instanced_arrays:true,WebGLBuffer:true,WebGLCanvas:true,WebGLColorBufferFloat:true,WebGLCompressedTextureASTC:true,WebGLCompressedTextureATC:true,WEBGL_compressed_texture_atc:true,WebGLCompressedTextureETC1:true,WEBGL_compressed_texture_etc1:true,WebGLCompressedTextureETC:true,WebGLCompressedTexturePVRTC:true,WEBGL_compressed_texture_pvrtc:true,WebGLCompressedTextureS3TC:true,WEBGL_compressed_texture_s3tc:true,WebGLCompressedTextureS3TCsRGB:true,WebGLDebugRendererInfo:true,WEBGL_debug_renderer_info:true,WebGLDebugShaders:true,WEBGL_debug_shaders:true,WebGLDepthTexture:true,WEBGL_depth_texture:true,WebGLDrawBuffers:true,WEBGL_draw_buffers:true,EXTsRGB:true,EXT_sRGB:true,EXTBlendMinMax:true,EXT_blend_minmax:true,EXTColorBufferFloat:true,EXTColorBufferHalfFloat:true,EXTDisjointTimerQuery:true,EXTDisjointTimerQueryWebGL2:true,EXTFragDepth:true,EXT_frag_depth:true,EXTShaderTextureLOD:true,EXT_shader_texture_lod:true,EXTTextureFilterAnisotropic:true,EXT_texture_filter_anisotropic:true,WebGLFramebuffer:true,WebGLGetBufferSubDataAsync:true,WebGLLoseContext:true,WebGLExtensionLoseContext:true,WEBGL_lose_context:true,OESElementIndexUint:true,OES_element_index_uint:true,OESStandardDerivatives:true,OES_standard_derivatives:true,OESTextureFloat:true,OES_texture_float:true,OESTextureFloatLinear:true,OES_texture_float_linear:true,OESTextureHalfFloat:true,OES_texture_half_float:true,OESTextureHalfFloatLinear:true,OES_texture_half_float_linear:true,OESVertexArrayObject:true,OES_vertex_array_object:true,WebGLProgram:true,WebGLQuery:true,WebGLRenderbuffer:true,WebGLRenderingContext:true,WebGL2RenderingContext:true,WebGLSampler:true,WebGLShader:true,WebGLShaderPrecisionFormat:true,WebGLSync:true,WebGLTexture:true,WebGLTimerQueryEXT:true,WebGLTransformFeedback:true,WebGLUniformLocation:true,WebGLVertexArrayObject:true,WebGLVertexArrayObjectOES:true,WebGL2RenderingContextBase:true,ArrayBuffer:true,SharedArrayBuffer:true,ArrayBufferView:false,DataView:true,Float32Array:true,Float64Array:true,Int16Array:true,Int32Array:true,Int8Array:true,Uint16Array:true,Uint32Array:true,Uint8ClampedArray:true,CanvasPixelArray:true,Uint8Array:false,HTMLAudioElement:true,HTMLBRElement:true,HTMLButtonElement:true,HTMLCanvasElement:true,HTMLContentElement:true,HTMLDListElement:true,HTMLDataElement:true,HTMLDataListElement:true,HTMLDetailsElement:true,HTMLDialogElement:true,HTMLEmbedElement:true,HTMLFieldSetElement:true,HTMLHRElement:true,HTMLHeadElement:true,HTMLHeadingElement:true,HTMLHtmlElement:true,HTMLIFrameElement:true,HTMLImageElement:true,HTMLLabelElement:true,HTMLLegendElement:true,HTMLMapElement:true,HTMLMediaElement:true,HTMLMenuElement:true,HTMLMetaElement:true,HTMLMeterElement:true,HTMLModElement:true,HTMLOListElement:true,HTMLObjectElement:true,HTMLOptGroupElement:true,HTMLOptionElement:true,HTMLOutputElement:true,HTMLParagraphElement:true,HTMLParamElement:true,HTMLPictureElement:true,HTMLPreElement:true,HTMLProgressElement:true,HTMLQuoteElement:true,HTMLScriptElement:true,HTMLShadowElement:true,HTMLSlotElement:true,HTMLSourceElement:true,HTMLStyleElement:true,HTMLTableCaptionElement:true,HTMLTableCellElement:true,HTMLTableDataCellElement:true,HTMLTableHeaderCellElement:true,HTMLTableColElement:true,HTMLTextAreaElement:true,HTMLTimeElement:true,HTMLTitleElement:true,HTMLTrackElement:true,HTMLUnknownElement:true,HTMLVideoElement:true,HTMLDirectoryElement:true,HTMLFontElement:true,HTMLFrameElement:true,HTMLFrameSetElement:true,HTMLMarqueeElement:true,HTMLElement:false,AccessibleNodeList:true,HTMLAnchorElement:true,HTMLAreaElement:true,HTMLBaseElement:true,Blob:false,HTMLBodyElement:true,CDATASection:true,CharacterData:true,Comment:true,ProcessingInstruction:true,Text:true,CSSPerspective:true,CSSCharsetRule:true,CSSConditionRule:true,CSSFontFaceRule:true,CSSGroupingRule:true,CSSImportRule:true,CSSKeyframeRule:true,MozCSSKeyframeRule:true,WebKitCSSKeyframeRule:true,CSSKeyframesRule:true,MozCSSKeyframesRule:true,WebKitCSSKeyframesRule:true,CSSMediaRule:true,CSSNamespaceRule:true,CSSPageRule:true,CSSRule:true,CSSStyleRule:true,CSSSupportsRule:true,CSSViewportRule:true,CSSStyleDeclaration:true,MSStyleCSSProperties:true,CSS2Properties:true,CSSImageValue:true,CSSKeywordValue:true,CSSNumericValue:true,CSSPositionValue:true,CSSResourceValue:true,CSSUnitValue:true,CSSURLImageValue:true,CSSStyleValue:false,CSSMatrixComponent:true,CSSRotation:true,CSSScale:true,CSSSkew:true,CSSTranslation:true,CSSTransformComponent:false,CSSTransformValue:true,CSSUnparsedValue:true,DataTransferItemList:true,HTMLDivElement:true,XMLDocument:true,Document:false,DOMException:true,DOMImplementation:true,ClientRectList:true,DOMRectList:true,DOMRectReadOnly:false,DOMStringList:true,DOMTokenList:true,MathMLElement:true,Element:false,AbortPaymentEvent:true,AnimationEvent:true,AnimationPlaybackEvent:true,ApplicationCacheErrorEvent:true,BackgroundFetchClickEvent:true,BackgroundFetchEvent:true,BackgroundFetchFailEvent:true,BackgroundFetchedEvent:true,BeforeInstallPromptEvent:true,BeforeUnloadEvent:true,BlobEvent:true,CanMakePaymentEvent:true,ClipboardEvent:true,CloseEvent:true,CustomEvent:true,DeviceMotionEvent:true,DeviceOrientationEvent:true,ErrorEvent:true,ExtendableEvent:true,ExtendableMessageEvent:true,FetchEvent:true,FontFaceSetLoadEvent:true,ForeignFetchEvent:true,GamepadEvent:true,HashChangeEvent:true,InstallEvent:true,MediaEncryptedEvent:true,MediaKeyMessageEvent:true,MediaQueryListEvent:true,MediaStreamEvent:true,MediaStreamTrackEvent:true,MessageEvent:true,MIDIConnectionEvent:true,MIDIMessageEvent:true,MutationEvent:true,NotificationEvent:true,PageTransitionEvent:true,PaymentRequestEvent:true,PaymentRequestUpdateEvent:true,PresentationConnectionAvailableEvent:true,PresentationConnectionCloseEvent:true,ProgressEvent:true,PromiseRejectionEvent:true,PushEvent:true,RTCDataChannelEvent:true,RTCDTMFToneChangeEvent:true,RTCPeerConnectionIceEvent:true,RTCTrackEvent:true,SecurityPolicyViolationEvent:true,SensorErrorEvent:true,SpeechRecognitionError:true,SpeechRecognitionEvent:true,SpeechSynthesisEvent:true,StorageEvent:true,SyncEvent:true,TrackEvent:true,TransitionEvent:true,WebKitTransitionEvent:true,VRDeviceEvent:true,VRDisplayEvent:true,VRSessionEvent:true,MojoInterfaceRequestEvent:true,ResourceProgressEvent:true,USBConnectionEvent:true,IDBVersionChangeEvent:true,AudioProcessingEvent:true,OfflineAudioCompletionEvent:true,WebGLContextEvent:true,Event:false,InputEvent:false,SubmitEvent:false,AbsoluteOrientationSensor:true,Accelerometer:true,AccessibleNode:true,AmbientLightSensor:true,Animation:true,ApplicationCache:true,DOMApplicationCache:true,OfflineResourceList:true,BackgroundFetchRegistration:true,BatteryManager:true,BroadcastChannel:true,CanvasCaptureMediaStreamTrack:true,DedicatedWorkerGlobalScope:true,EventSource:true,FileReader:true,FontFaceSet:true,Gyroscope:true,XMLHttpRequest:true,XMLHttpRequestEventTarget:true,XMLHttpRequestUpload:true,LinearAccelerationSensor:true,Magnetometer:true,MediaDevices:true,MediaKeySession:true,MediaQueryList:true,MediaRecorder:true,MediaSource:true,MediaStream:true,MediaStreamTrack:true,MIDIAccess:true,MIDIInput:true,MIDIOutput:true,MIDIPort:true,NetworkInformation:true,Notification:true,OffscreenCanvas:true,OrientationSensor:true,PaymentRequest:true,Performance:true,PermissionStatus:true,PresentationAvailability:true,PresentationConnection:true,PresentationConnectionList:true,PresentationRequest:true,RelativeOrientationSensor:true,RemotePlayback:true,RTCDataChannel:true,DataChannel:true,RTCDTMFSender:true,RTCPeerConnection:true,webkitRTCPeerConnection:true,mozRTCPeerConnection:true,ScreenOrientation:true,Sensor:true,ServiceWorker:true,ServiceWorkerContainer:true,ServiceWorkerGlobalScope:true,ServiceWorkerRegistration:true,SharedWorker:true,SharedWorkerGlobalScope:true,SpeechRecognition:true,webkitSpeechRecognition:true,SpeechSynthesis:true,SpeechSynthesisUtterance:true,VR:true,VRDevice:true,VRDisplay:true,VRSession:true,VisualViewport:true,WebSocket:true,Worker:true,WorkerGlobalScope:true,WorkerPerformance:true,BluetoothDevice:true,BluetoothRemoteGATTCharacteristic:true,Clipboard:true,MojoInterfaceInterceptor:true,USB:true,IDBDatabase:true,IDBOpenDBRequest:true,IDBVersionChangeRequest:true,IDBRequest:true,IDBTransaction:true,AnalyserNode:true,RealtimeAnalyserNode:true,AudioBufferSourceNode:true,AudioDestinationNode:true,AudioNode:true,AudioScheduledSourceNode:true,AudioWorkletNode:true,BiquadFilterNode:true,ChannelMergerNode:true,AudioChannelMerger:true,ChannelSplitterNode:true,AudioChannelSplitter:true,ConstantSourceNode:true,ConvolverNode:true,DelayNode:true,DynamicsCompressorNode:true,GainNode:true,AudioGainNode:true,IIRFilterNode:true,MediaElementAudioSourceNode:true,MediaStreamAudioDestinationNode:true,MediaStreamAudioSourceNode:true,OscillatorNode:true,Oscillator:true,PannerNode:true,AudioPannerNode:true,webkitAudioPannerNode:true,ScriptProcessorNode:true,JavaScriptAudioNode:true,StereoPannerNode:true,WaveShaperNode:true,EventTarget:false,File:true,FileList:true,FileWriter:true,HTMLFormElement:true,Gamepad:true,History:true,HTMLCollection:true,HTMLFormControlsCollection:true,HTMLOptionsCollection:true,HTMLDocument:true,ImageData:true,HTMLInputElement:true,KeyboardEvent:true,HTMLLIElement:true,HTMLLinkElement:true,Location:true,MediaList:true,MessagePort:true,MIDIInputMap:true,MIDIOutputMap:true,MimeType:true,MimeTypeArray:true,MouseEvent:true,DragEvent:true,PointerEvent:true,WheelEvent:true,DocumentFragment:true,ShadowRoot:true,DocumentType:true,Node:false,NodeList:true,RadioNodeList:true,Plugin:true,PluginArray:true,PopStateEvent:true,RTCStatsReport:true,HTMLSelectElement:true,SourceBuffer:true,SourceBufferList:true,HTMLSpanElement:true,SpeechGrammar:true,SpeechGrammarList:true,SpeechRecognitionResult:true,Storage:true,CSSStyleSheet:true,StyleSheet:true,HTMLTableElement:true,HTMLTableRowElement:true,HTMLTableSectionElement:true,HTMLTemplateElement:true,TextTrack:true,TextTrackCue:true,VTTCue:true,TextTrackCueList:true,TextTrackList:true,TimeRanges:true,Touch:true,TouchList:true,TrackDefaultList:true,CompositionEvent:true,FocusEvent:true,TextEvent:true,TouchEvent:true,UIEvent:false,HTMLUListElement:true,URL:true,VideoTrackList:true,Window:true,DOMWindow:true,Attr:true,CSSRuleList:true,ClientRect:true,DOMRect:true,GamepadList:true,NamedNodeMap:true,MozNamedAttrMap:true,SpeechRecognitionResultList:true,StyleSheetList:true,SVGLength:true,SVGLengthList:true,SVGNumber:true,SVGNumberList:true,SVGPointList:true,SVGScriptElement:true,SVGStringList:true,SVGAElement:true,SVGAnimateElement:true,SVGAnimateMotionElement:true,SVGAnimateTransformElement:true,SVGAnimationElement:true,SVGCircleElement:true,SVGClipPathElement:true,SVGDefsElement:true,SVGDescElement:true,SVGDiscardElement:true,SVGEllipseElement:true,SVGFEBlendElement:true,SVGFEColorMatrixElement:true,SVGFEComponentTransferElement:true,SVGFECompositeElement:true,SVGFEConvolveMatrixElement:true,SVGFEDiffuseLightingElement:true,SVGFEDisplacementMapElement:true,SVGFEDistantLightElement:true,SVGFEFloodElement:true,SVGFEFuncAElement:true,SVGFEFuncBElement:true,SVGFEFuncGElement:true,SVGFEFuncRElement:true,SVGFEGaussianBlurElement:true,SVGFEImageElement:true,SVGFEMergeElement:true,SVGFEMergeNodeElement:true,SVGFEMorphologyElement:true,SVGFEOffsetElement:true,SVGFEPointLightElement:true,SVGFESpecularLightingElement:true,SVGFESpotLightElement:true,SVGFETileElement:true,SVGFETurbulenceElement:true,SVGFilterElement:true,SVGForeignObjectElement:true,SVGGElement:true,SVGGeometryElement:true,SVGGraphicsElement:true,SVGImageElement:true,SVGLineElement:true,SVGLinearGradientElement:true,SVGMarkerElement:true,SVGMaskElement:true,SVGMetadataElement:true,SVGPathElement:true,SVGPatternElement:true,SVGPolygonElement:true,SVGPolylineElement:true,SVGRadialGradientElement:true,SVGRectElement:true,SVGSetElement:true,SVGStopElement:true,SVGStyleElement:true,SVGSVGElement:true,SVGSwitchElement:true,SVGSymbolElement:true,SVGTSpanElement:true,SVGTextContentElement:true,SVGTextElement:true,SVGTextPathElement:true,SVGTextPositioningElement:true,SVGTitleElement:true,SVGUseElement:true,SVGViewElement:true,SVGGradientElement:true,SVGComponentTransferFunctionElement:true,SVGFEDropShadowElement:true,SVGMPathElement:true,SVGElement:false,SVGTransform:true,SVGTransformList:true,AudioBuffer:true,AudioParamMap:true,AudioTrackList:true,AudioContext:true,webkitAudioContext:true,BaseAudioContext:false,OfflineAudioContext:true}) +A.V.$nativeSuperclassTag="ArrayBufferView" +A.d_.$nativeSuperclassTag="ArrayBufferView" +A.d0.$nativeSuperclassTag="ArrayBufferView" +A.cx.$nativeSuperclassTag="ArrayBufferView" +A.d1.$nativeSuperclassTag="ArrayBufferView" +A.d2.$nativeSuperclassTag="ArrayBufferView" +A.cy.$nativeSuperclassTag="ArrayBufferView" +A.d6.$nativeSuperclassTag="EventTarget" +A.d7.$nativeSuperclassTag="EventTarget" +A.d9.$nativeSuperclassTag="EventTarget" +A.da.$nativeSuperclassTag="EventTarget"})() +Function.prototype.$2=function(a,b){return this(a,b)} +Function.prototype.$1=function(a){return this(a)} +Function.prototype.$0=function(){return this()} +Function.prototype.$3=function(a,b,c){return this(a,b,c)} +Function.prototype.$4=function(a,b,c,d){return this(a,b,c,d)} +Function.prototype.$1$0=function(){return this()} +Function.prototype.$1$1=function(a){return this(a)} +convertAllToFastObject(w) +convertToFastObject($);(function(a){if(typeof document==="undefined"){a(null) +return}if(typeof document.currentScript!="undefined"){a(document.currentScript) +return}var s=document.scripts +function onLoad(b){for(var q=0;q'); + --ifm-breadcrumb-separator-filter: invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%); + --ifm-breadcrumb-separator-size: 0.5rem; + --ifm-breadcrumb-separator-size-multiplier: 1.25; + --ifm-button-background-color: inherit; + --ifm-button-border-color: var(--ifm-button-background-color); + --ifm-button-border-width: var(--ifm-global-border-width); + --ifm-button-color: var(--ifm-font-color-base-inverse); + --ifm-button-font-weight: var(--ifm-font-weight-bold); + --ifm-button-padding-horizontal: 1.5rem; + --ifm-button-padding-vertical: 0.375rem; + --ifm-button-size-multiplier: 1; + --ifm-button-transition-duration: var(--ifm-transition-fast); + --ifm-button-border-radius: calc( + var(--ifm-global-radius) * var(--ifm-button-size-multiplier) + ); + --ifm-button-group-spacing: 2px; + --ifm-card-background-color: var(--ifm-background-surface-color); + --ifm-card-border-radius: calc(var(--ifm-global-radius) * 2); + --ifm-card-horizontal-spacing: var(--ifm-global-spacing); + --ifm-card-vertical-spacing: var(--ifm-global-spacing); + --ifm-toc-border-color: var(--ifm-color-emphasis-300); + --ifm-toc-link-color: var(--ifm-color-content-secondary); + --ifm-toc-padding-vertical: 0.5rem; + --ifm-toc-padding-horizontal: 0.5rem; + --ifm-dropdown-background-color: var(--ifm-background-surface-color); + --ifm-dropdown-font-weight: var(--ifm-font-weight-semibold); + --ifm-dropdown-link-color: var(--ifm-font-color-base); + --ifm-dropdown-hover-background-color: var(--ifm-hover-overlay); + --ifm-footer-background-color: var(--ifm-color-emphasis-100); + --ifm-footer-color: inherit; + --ifm-footer-link-color: var(--ifm-color-emphasis-700); + --ifm-footer-link-hover-color: var(--ifm-color-primary); + --ifm-footer-link-horizontal-spacing: 0.5rem; + --ifm-footer-padding-horizontal: calc(var(--ifm-spacing-horizontal) * 2); + --ifm-footer-padding-vertical: calc(var(--ifm-spacing-vertical) * 2); + --ifm-footer-title-color: inherit; + --ifm-footer-logo-max-width: min(30rem, 90vw); + --ifm-hero-background-color: var(--ifm-background-surface-color); + --ifm-hero-text-color: var(--ifm-color-emphasis-800); + --ifm-menu-color: var(--ifm-color-emphasis-700); + --ifm-menu-color-active: var(--ifm-color-primary); + --ifm-menu-color-background-active: var(--ifm-hover-overlay); + --ifm-menu-color-background-hover: var(--ifm-hover-overlay); + --ifm-menu-link-padding-horizontal: 0.75rem; + --ifm-menu-link-padding-vertical: 0.375rem; + --ifm-menu-link-sublist-icon: url('data:image/svg+xml;utf8,'); + --ifm-menu-link-sublist-icon-filter: none; + --ifm-navbar-background-color: var(--ifm-background-surface-color); + --ifm-navbar-height: 3.75rem; + --ifm-navbar-item-padding-horizontal: 0.75rem; + --ifm-navbar-item-padding-vertical: 0.25rem; + --ifm-navbar-link-color: var(--ifm-font-color-base); + --ifm-navbar-link-hover-color: var(--ifm-color-primary); + --ifm-navbar-link-active-color: var(--ifm-link-color); + --ifm-navbar-padding-horizontal: var(--ifm-spacing-horizontal); + --ifm-navbar-padding-vertical: calc(var(--ifm-spacing-vertical) * 0.5); + --ifm-navbar-shadow: var(--ifm-global-shadow-lw); + --ifm-navbar-search-input-background-color: var(--ifm-color-emphasis-200); + --ifm-navbar-search-input-color: var(--ifm-color-emphasis-800); + --ifm-navbar-search-input-placeholder-color: var(--ifm-color-emphasis-500); + --ifm-navbar-search-input-icon: url('data:image/svg+xml;utf8,'); + --ifm-navbar-sidebar-width: 83vw; + --ifm-pagination-border-radius: var(--ifm-global-radius); + --ifm-pagination-color-active: var(--ifm-color-primary); + --ifm-pagination-font-size: 1rem; + --ifm-pagination-item-active-background: var(--ifm-hover-overlay); + --ifm-pagination-page-spacing: 0.2em; + --ifm-pagination-padding-horizontal: calc(var(--ifm-spacing-horizontal) * 1); + --ifm-pagination-padding-vertical: calc(var(--ifm-spacing-vertical) * 0.25); + --ifm-pagination-nav-border-radius: var(--ifm-global-radius); + --ifm-pagination-nav-color-hover: var(--ifm-color-primary); + --ifm-pills-color-active: var(--ifm-color-primary); + --ifm-pills-color-background-active: var(--ifm-hover-overlay); + --ifm-pills-spacing: 0.125rem; + --ifm-tabs-color: var(--ifm-font-color-secondary); + --ifm-tabs-color-active: var(--ifm-color-primary); + --ifm-tabs-color-active-border: var(--ifm-tabs-color-active); + --ifm-tabs-padding-horizontal: 1rem; + --ifm-tabs-padding-vertical: 1rem; + --ifm-color-scheme: dark; + + --ifm-color-emphasis-100: var(--ifm-color-gray-900); + --ifm-color-emphasis-200: var(--ifm-color-gray-800); + --ifm-color-emphasis-300: var(--ifm-color-gray-700); + --ifm-color-emphasis-400: var(--ifm-color-gray-600); + --ifm-color-emphasis-500: var(--ifm-color-gray-500); + --ifm-color-emphasis-600: var(--ifm-color-gray-400); + --ifm-color-emphasis-700: var(--ifm-color-gray-300); + --ifm-color-emphasis-800: var(--ifm-color-gray-200); + --ifm-color-emphasis-900: var(--ifm-color-gray-100); + + --ifm-background-color: #121212; + --ifm-background-surface-color: #1e2125; + + --ifm-hover-overlay: rgba(255, 255, 255, 0.05); +} + +@supports (color: rgb(0 0 0 / 0)) { +:root { + --ifm-color-primary-contrast-background: rgb(16, 36, 69); + --ifm-color-primary-contrast-foreground: rgb(235, 242, 252); + --ifm-color-secondary-contrast-background: rgb(71, 71, 72); + --ifm-color-secondary-contrast-foreground: rgb(253, 253, 254); + --ifm-color-success-contrast-background: rgb(0, 49, 0); + --ifm-color-success-contrast-foreground: rgb(230, 246, 230); + --ifm-color-info-contrast-background: rgb(25, 60, 71); + --ifm-color-info-contrast-foreground: rgb(238, 249, 253); + --ifm-color-warning-contrast-background: rgb(77, 56, 0); + --ifm-color-warning-contrast-foreground: rgb(255, 248, 230); + --ifm-color-danger-contrast-background: rgb(75, 17, 19); + --ifm-color-danger-contrast-foreground: rgb(255, 235, 236); +} +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +@supports (color: rgb(0 0 0 / 0)) { +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +* { + box-sizing: border-box; +} + +html { + background-color: var(--ifm-background-color); + color: var(--ifm-font-color-base); + color-scheme: var(--ifm-color-scheme); + font: var(--ifm-font-size-base) / var(--ifm-line-height-base) + var(--ifm-font-family-base); + -webkit-font-smoothing: antialiased; + -webkit-tap-highlight-color: transparent; + text-rendering: optimizelegibility; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; +} + +body { + margin: 0; + word-wrap: break-word; +} + +iframe { + border: 0; + color-scheme: auto; +} + +/* Layout */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.container { + margin: 0 auto; + max-width: var(--ifm-container-width); + padding: 0 var(--ifm-spacing-horizontal); + width: 100%; +} + +.container--fluid { + max-width: inherit; + } + +.row { + display: flex; + flex-wrap: wrap; + margin: 0 calc(var(--ifm-spacing-horizontal) * -1); +} + +.row--no-gutters { + margin-left: 0; + margin-right: 0; + } + +.row--no-gutters > .col { + padding-left: 0; + padding-right: 0; + } + +.row--align-top { + align-items: flex-start; + } + +.row--align-bottom { + align-items: flex-end; + } + +.row--align-center { + align-items: center; + } + +.row--align-stretch { + align-items: stretch; + } + +.row--align-baseline { + align-items: baseline; + } + +.col { + --ifm-col-width: 100%; + + flex: 1 0; + margin-left: 0; + max-width: var(--ifm-col-width); + padding: 0 var(--ifm-spacing-horizontal); + width: 100%; +} + +.col[class*='col--'] { + flex: 0 0 var(--ifm-col-width); + } + +.col--1 { + --ifm-col-width: calc(1 / 12 * 100%); + } + +.col--offset-1 { + margin-left: calc(1 / 12 * 100%); + } + +.col--2 { + --ifm-col-width: calc(2 / 12 * 100%); + } + +.col--offset-2 { + margin-left: calc(2 / 12 * 100%); + } + +.col--3 { + --ifm-col-width: calc(3 / 12 * 100%); + } + +.col--offset-3 { + margin-left: calc(3 / 12 * 100%); + } + +.col--4 { + --ifm-col-width: calc(4 / 12 * 100%); + } + +.col--offset-4 { + margin-left: calc(4 / 12 * 100%); + } + +.col--5 { + --ifm-col-width: calc(5 / 12 * 100%); + } + +.col--offset-5 { + margin-left: calc(5 / 12 * 100%); + } + +.col--6 { + --ifm-col-width: calc(6 / 12 * 100%); + } + +.col--offset-6 { + margin-left: calc(6 / 12 * 100%); + } + +.col--7 { + --ifm-col-width: calc(7 / 12 * 100%); + } + +.col--offset-7 { + margin-left: calc(7 / 12 * 100%); + } + +.col--8 { + --ifm-col-width: calc(8 / 12 * 100%); + } + +.col--offset-8 { + margin-left: calc(8 / 12 * 100%); + } + +.col--9 { + --ifm-col-width: calc(9 / 12 * 100%); + } + +.col--offset-9 { + margin-left: calc(9 / 12 * 100%); + } + +.col--10 { + --ifm-col-width: calc(10 / 12 * 100%); + } + +.col--offset-10 { + margin-left: calc(10 / 12 * 100%); + } + +.col--11 { + --ifm-col-width: calc(11 / 12 * 100%); + } + +.col--offset-11 { + margin-left: calc(11 / 12 * 100%); + } + +.col--12 { + --ifm-col-width: calc(12 / 12 * 100%); + } + +.col--offset-12 { + margin-left: calc(12 / 12 * 100%); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.margin--none { + margin: 0 !important; + } + +.margin-top--none { + margin-top: 0 !important; + } + +.margin-left--none { + margin-left: 0 !important; + } + +.margin-bottom--none { + margin-bottom: 0 !important; + } + +.margin-right--none { + margin-right: 0 !important; + } + +.margin-vert--none { + margin-bottom: 0 !important; + margin-top: 0 !important; + } + +.margin-horiz--none { + margin-left: 0 !important; + margin-right: 0 !important; + } + +.margin--xs { + margin: 0.25rem !important; + } + +.margin-top--xs { + margin-top: 0.25rem !important; + } + +.margin-left--xs { + margin-left: 0.25rem !important; + } + +.margin-bottom--xs { + margin-bottom: 0.25rem !important; + } + +.margin-right--xs { + margin-right: 0.25rem !important; + } + +.margin-vert--xs { + margin-bottom: 0.25rem !important; + margin-top: 0.25rem !important; + } + +.margin-horiz--xs { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; + } + +.margin--sm { + margin: 0.5rem !important; + } + +.margin-top--sm { + margin-top: 0.5rem !important; + } + +.margin-left--sm { + margin-left: 0.5rem !important; + } + +.margin-bottom--sm { + margin-bottom: 0.5rem !important; + } + +.margin-right--sm { + margin-right: 0.5rem !important; + } + +.margin-vert--sm { + margin-bottom: 0.5rem !important; + margin-top: 0.5rem !important; + } + +.margin-horiz--sm { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; + } + +.margin--md { + margin: 1rem !important; + } + +.margin-top--md { + margin-top: 1rem !important; + } + +.margin-left--md { + margin-left: 1rem !important; + } + +.margin-bottom--md { + margin-bottom: 1rem !important; + } + +.margin-right--md { + margin-right: 1rem !important; + } + +.margin-vert--md { + margin-bottom: 1rem !important; + margin-top: 1rem !important; + } + +.margin-horiz--md { + margin-left: 1rem !important; + margin-right: 1rem !important; + } + +.margin--lg { + margin: 2rem !important; + } + +.margin-top--lg { + margin-top: 2rem !important; + } + +.margin-left--lg { + margin-left: 2rem !important; + } + +.margin-bottom--lg { + margin-bottom: 2rem !important; + } + +.margin-right--lg { + margin-right: 2rem !important; + } + +.margin-vert--lg { + margin-bottom: 2rem !important; + margin-top: 2rem !important; + } + +.margin-horiz--lg { + margin-left: 2rem !important; + margin-right: 2rem !important; + } + +.margin--xl { + margin: 5rem !important; + } + +.margin-top--xl { + margin-top: 5rem !important; + } + +.margin-left--xl { + margin-left: 5rem !important; + } + +.margin-bottom--xl { + margin-bottom: 5rem !important; + } + +.margin-right--xl { + margin-right: 5rem !important; + } + +.margin-vert--xl { + margin-bottom: 5rem !important; + margin-top: 5rem !important; + } + +.margin-horiz--xl { + margin-left: 5rem !important; + margin-right: 5rem !important; + } + +.padding--none { + padding: 0 !important; + } + +.padding-top--none { + padding-top: 0 !important; + } + +.padding-left--none { + padding-left: 0 !important; + } + +.padding-bottom--none { + padding-bottom: 0 !important; + } + +.padding-right--none { + padding-right: 0 !important; + } + +.padding-vert--none { + padding-bottom: 0 !important; + padding-top: 0 !important; + } + +.padding-horiz--none { + padding-left: 0 !important; + padding-right: 0 !important; + } + +.padding--xs { + padding: 0.25rem !important; + } + +.padding-top--xs { + padding-top: 0.25rem !important; + } + +.padding-left--xs { + padding-left: 0.25rem !important; + } + +.padding-bottom--xs { + padding-bottom: 0.25rem !important; + } + +.padding-right--xs { + padding-right: 0.25rem !important; + } + +.padding-vert--xs { + padding-bottom: 0.25rem !important; + padding-top: 0.25rem !important; + } + +.padding-horiz--xs { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; + } + +.padding--sm { + padding: 0.5rem !important; + } + +.padding-top--sm { + padding-top: 0.5rem !important; + } + +.padding-left--sm { + padding-left: 0.5rem !important; + } + +.padding-bottom--sm { + padding-bottom: 0.5rem !important; + } + +.padding-right--sm { + padding-right: 0.5rem !important; + } + +.padding-vert--sm { + padding-bottom: 0.5rem !important; + padding-top: 0.5rem !important; + } + +.padding-horiz--sm { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + +.padding--md { + padding: 1rem !important; + } + +.padding-top--md { + padding-top: 1rem !important; + } + +.padding-left--md { + padding-left: 1rem !important; + } + +.padding-bottom--md { + padding-bottom: 1rem !important; + } + +.padding-right--md { + padding-right: 1rem !important; + } + +.padding-vert--md { + padding-bottom: 1rem !important; + padding-top: 1rem !important; + } + +.padding-horiz--md { + padding-left: 1rem !important; + padding-right: 1rem !important; + } + +.padding--lg { + padding: 2rem !important; + } + +.padding-top--lg { + padding-top: 2rem !important; + } + +.padding-left--lg { + padding-left: 2rem !important; + } + +.padding-bottom--lg { + padding-bottom: 2rem !important; + } + +.padding-right--lg { + padding-right: 2rem !important; + } + +.padding-vert--lg { + padding-bottom: 2rem !important; + padding-top: 2rem !important; + } + +.padding-horiz--lg { + padding-left: 2rem !important; + padding-right: 2rem !important; + } + +.padding--xl { + padding: 5rem !important; + } + +.padding-top--xl { + padding-top: 5rem !important; + } + +.padding-left--xl { + padding-left: 5rem !important; + } + +.padding-bottom--xl { + padding-bottom: 5rem !important; + } + +.padding-right--xl { + padding-right: 5rem !important; + } + +.padding-vert--xl { + padding-bottom: 5rem !important; + padding-top: 5rem !important; + } + +.padding-horiz--xl { + padding-left: 5rem !important; + padding-right: 5rem !important; + } + +/* Content */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +code { + background-color: var(--ifm-code-background); + border: 0.1rem solid rgba(0, 0, 0, 0.1); + border-radius: var(--ifm-code-border-radius); + font-family: var(--ifm-font-family-monospace); + font-size: var(--ifm-code-font-size); + padding: var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal); + vertical-align: middle; +} + +a code { + color: inherit; +} + +pre { + background-color: var(--ifm-pre-background); + border-radius: var(--ifm-pre-border-radius); + color: var(--ifm-pre-color); + font: var(--ifm-code-font-size) / var(--ifm-pre-line-height) + var(--ifm-font-family-monospace); + margin: 0 0 var(--ifm-spacing-vertical); + overflow: auto; + padding: var(--ifm-pre-padding); +} + +pre code { + background-color: transparent; + border: none; + font-size: 100%; + line-height: inherit; + padding: 0; + } + +kbd { + background-color: var(--ifm-color-emphasis-0); + border: 1px solid var(--ifm-color-emphasis-400); + border-radius: 0.2rem; + box-shadow: inset 0 -1px 0 var(--ifm-color-emphasis-400); + color: var(--ifm-color-emphasis-800); + font: 80% var(--ifm-font-family-monospace); + padding: 0.15rem 0.3rem; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +h1, +h2, +h3, +h4, +h5, +h6 { + color: var(--ifm-heading-color); + font-family: var(--ifm-heading-font-family); + font-weight: var(--ifm-heading-font-weight); + line-height: var(--ifm-heading-line-height); + margin: var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0; +} + +h1 { + font-size: var(--ifm-h1-font-size); + } + +h2 { + font-size: var(--ifm-h2-font-size); + } + +h3 { + font-size: var(--ifm-h3-font-size); + } + +h4 { + font-size: var(--ifm-h4-font-size); + } + +h5 { + font-size: var(--ifm-h5-font-size); + } + +h6 { + font-size: var(--ifm-h6-font-size); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +img { + max-width: 100%; +} + +img[align='right'] { + padding-left: var(--image-alignment-padding); +} + +img[align='left'] { + padding-right: var(--image-alignment-padding); +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.markdown { + --ifm-h1-vertical-rhythm-top: 3; + --ifm-h2-vertical-rhythm-top: 2; + --ifm-h3-vertical-rhythm-top: 1.5; + --ifm-heading-vertical-rhythm-top: 1.25; + + --ifm-h1-vertical-rhythm-bottom: 1.25; + --ifm-heading-vertical-rhythm-bottom: 1; +} + +.markdown:before { + content: ''; + display: table; + } + +.markdown:after { + clear: both; + content: ''; + display: table; + } + +.markdown > *:last-child { + margin-bottom: 0 !important; + } + +.markdown h1:first-child { + --ifm-h1-font-size: 3rem; + + margin-bottom: calc( + var(--ifm-h1-vertical-rhythm-bottom) * var(--ifm-leading) + ); + } + +.markdown > h2 { + --ifm-h2-font-size: 2rem; + + margin-bottom: calc( + var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) + ); + margin-top: calc(var(--ifm-h2-vertical-rhythm-top) * var(--ifm-leading)); + } + +.markdown > h3 { + --ifm-h3-font-size: 1.5rem; + + margin-bottom: calc( + var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) + ); + margin-top: calc(var(--ifm-h3-vertical-rhythm-top) * var(--ifm-leading)); + } + +.markdown > h4, + .markdown > h5, + .markdown > h6 { + margin-bottom: calc( + var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) + ); + margin-top: calc( + var(--ifm-heading-vertical-rhythm-top) * var(--ifm-leading) + ); + } + +/* Consistent spacing between content paragraphs. */ + +.markdown > pre, + .markdown > ul, + .markdown > p { + margin-bottom: var(--ifm-leading); + } + +.markdown li { + word-wrap: break-word; + } + +.markdown li > p { + margin-top: var(--ifm-list-paragraph-margin); + } + +.markdown li + li { + margin-top: var(--ifm-list-item-margin); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* Lists */ + +ul, +ol { + margin: 0 0 var(--ifm-list-margin); + padding-left: var(--ifm-list-left-padding); +} + +ol ol, +ul ol { + list-style-type: lower-roman; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin: 0; +} + +ul ul ol, +ul ol ol, +ol ul ol, +ol ol ol { + list-style-type: lower-alpha; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +table { + border-collapse: collapse; + display: block; + margin-bottom: var(--ifm-spacing-vertical); + overflow: auto; +} + +table thead tr { + border-bottom: 2px solid var(--ifm-table-border-color); + } + +table thead { + background-color: var(--ifm-table-stripe-background); + } + +table tr { + background-color: var(--ifm-table-background); + border-top: var(--ifm-table-border-width) solid + var(--ifm-table-border-color); + } + +table tr:nth-child(2n) { + background-color: var(--ifm-table-stripe-background); + } + +table th, + table td { + border: var(--ifm-table-border-width) solid var(--ifm-table-border-color); + padding: var(--ifm-table-cell-padding); + } + +table th { + background-color: var(--ifm-table-head-background); + color: var(--ifm-table-head-color); + font-weight: var(--ifm-table-head-font-weight); + } + +table td { + color: var(--ifm-table-cell-color); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +strong { + font-weight: var(--ifm-font-weight-bold); +} + +/* Links */ + +a { + color: var(--ifm-link-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-decoration); + transition: color var(--ifm-transition-fast) var(--ifm-transition-timing-default); +} + +a:hover { + color: var(--ifm-link-hover-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-hover-decoration); + } + +a:not([href]) { + text-decoration: none; + } + +/* Paragraphs */ + +p { + margin: 0 0 var(--ifm-paragraph-margin-bottom); +} + +/* Blockquotes */ + +blockquote { + border-left: var(--ifm-blockquote-border-left-width) solid + var(--ifm-blockquote-border-color); + box-shadow: var(--ifm-blockquote-shadow); + color: var(--ifm-blockquote-color); + font-size: var(--ifm-blockquote-font-size); + margin: 0 0 var(--ifm-spacing-vertical); + padding: var(--ifm-blockquote-padding-vertical) + var(--ifm-blockquote-padding-horizontal); +} + +blockquote > :first-child { + margin-top: 0; + } + +blockquote > :last-child { + margin-bottom: 0; + } + +/* Horizontal Rules */ + +hr { + background-color: var(--ifm-hr-background-color); + border: 0; + height: var(--ifm-hr-height); + margin: var(--ifm-hr-margin-vertical) 0; +} + +/* Utilities */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.shadow--lw { + box-shadow: var(--ifm-global-shadow-lw) !important; + } + +.shadow--md { + box-shadow: var(--ifm-global-shadow-md) !important; + } + +.shadow--tl { + box-shadow: var(--ifm-global-shadow-tl) !important; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.text--primary { + color: var(--ifm-color-primary); + } + +.text--secondary { + color: var(--ifm-color-secondary); + } + +.text--success { + color: var(--ifm-color-success); + } + +.text--info { + color: var(--ifm-color-info); + } + +.text--warning { + color: var(--ifm-color-warning); + } + +.text--danger { + color: var(--ifm-color-danger); + } + +.text--center { + text-align: center; + } + +.text--left { + text-align: left; + } + +.text--justify { + text-align: justify; + } + +.text--right { + text-align: right; + } + +.text--capitalize { + text-transform: capitalize; + } + +.text--lowercase { + text-transform: lowercase; + } + +.text--uppercase { + text-transform: uppercase; + } + +.text--light { + font-weight: var(--ifm-font-weight-light); + } + +.text--normal { + font-weight: var(--ifm-font-weight-normal); + } + +.text--semibold { + font-weight: var(--ifm-font-weight-semibold); + } + +.text--bold { + font-weight: var(--ifm-font-weight-bold); + } + +.text--italic { + font-style: italic; +} + +.text--truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text--break { + word-wrap: break-word !important; + word-break: break-word !important; +} + +.text--no-decoration, + .text--no-decoration:hover { + text-decoration: none; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.clean-btn { + background: none; + border: none; + color: inherit; + cursor: pointer; + font-family: inherit; + padding: 0; +} + +.clean-list { + list-style: none; + padding-left: 0; +} + +/* Components */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.alert--primary { + --ifm-alert-background-color: var( + --ifm-color-primary-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(53, 120, 229, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-primary-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-primary-dark); + } + +.alert--secondary { + --ifm-alert-background-color: var( + --ifm-color-secondary-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(235, 237, 240, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-secondary-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-secondary-dark); + } + +.alert--success { + --ifm-alert-background-color: var( + --ifm-color-success-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(0, 164, 0, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-success-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-success-dark); + } + +.alert--info { + --ifm-alert-background-color: var( + --ifm-color-info-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(84, 199, 236, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-info-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-info-dark); + } + +.alert--warning { + --ifm-alert-background-color: var( + --ifm-color-warning-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(255, 186, 0, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-warning-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-warning-dark); + } + +.alert--danger { + --ifm-alert-background-color: var( + --ifm-color-danger-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(250, 56, 62, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-danger-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-danger-dark); + } + +.alert { + + --ifm-code-background: var(--ifm-alert-background-color-highlight); + --ifm-link-color: var(--ifm-alert-foreground-color); + --ifm-link-hover-color: var(--ifm-alert-foreground-color); + --ifm-link-decoration: underline; + --ifm-tabs-color: var(--ifm-alert-foreground-color); + --ifm-tabs-color-active: var(--ifm-alert-foreground-color); + --ifm-tabs-color-active-border: var(--ifm-alert-border-color); + + background-color: var(--ifm-alert-background-color); + border: var(--ifm-alert-border-width) solid var(--ifm-alert-border-color); + border-left-width: var(--ifm-alert-border-left-width); + border-radius: var(--ifm-alert-border-radius); + box-shadow: var(--ifm-alert-shadow); + color: var(--ifm-alert-foreground-color); + padding: var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal); +} + +.alert__heading { + align-items: center; + display: flex; + font: bold var(--ifm-h5-font-size) / var(--ifm-heading-line-height) + var(--ifm-heading-font-family); + margin-bottom: 0.5rem; + text-transform: uppercase; + } + +.alert__icon { + display: inline-flex; + margin-right: 0.4em; + } + +.alert__icon svg { + fill: var(--ifm-alert-foreground-color); + stroke: var(--ifm-alert-foreground-color); + stroke-width: 0; + } + +.alert .close { + color: var(--ifm-alert-foreground-color); + margin: calc(var(--ifm-alert-padding-vertical) * -1) + calc(var(--ifm-alert-padding-horizontal) * -1) 0 0; + + opacity: 0.75; + } + +.alert .close:hover, + .alert .close:focus { + opacity: 1; + } + +.alert a { + text-decoration-color: var(--ifm-alert-border-color); + } + +.alert a:hover { + text-decoration-thickness: 2px; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.avatar { + -moz-column-gap: var(--ifm-avatar-intro-margin); + column-gap: var(--ifm-avatar-intro-margin); + display: flex; +} + +.avatar__photo { + border-radius: 50%; + display: block; + height: var(--ifm-avatar-photo-size); + overflow: hidden; + width: var(--ifm-avatar-photo-size); + } + +.avatar__photo--sm { + --ifm-avatar-photo-size: 2rem; + } + +.avatar__photo--lg { + --ifm-avatar-photo-size: 4rem; + } + +.avatar__photo--xl { + --ifm-avatar-photo-size: 6rem; + } + +.avatar__intro { + display: flex; + flex: 1 1; + flex-direction: column; + justify-content: center; + text-align: var(--ifm-avatar-intro-alignment); + } + +.avatar__name { + font: bold var(--ifm-h4-font-size) / var(--ifm-heading-line-height) + var(--ifm-font-family-base); + } + +.avatar__subtitle { + margin-top: 0.25rem; + } + +.avatar--vertical { + --ifm-avatar-intro-alignment: center; + --ifm-avatar-intro-margin: 0.5rem; + + align-items: center; + flex-direction: column; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.badge { + background-color: var(--ifm-badge-background-color); + border: var(--ifm-badge-border-width) solid var(--ifm-badge-border-color); + border-radius: var(--ifm-badge-border-radius); + color: var(--ifm-badge-color); + display: inline-block; + font-size: 75%; + font-weight: var(--ifm-font-weight-bold); + line-height: 1; + padding: var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal); +} + +.badge--primary { + --ifm-badge-background-color: var(--ifm-color-primary); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--secondary { + --ifm-badge-background-color: var(--ifm-color-secondary); + --ifm-badge-border-color: var(--ifm-badge-background-color); + color: var(--ifm-color-black); + } + +.badge--success { + --ifm-badge-background-color: var(--ifm-color-success); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--info { + --ifm-badge-background-color: var(--ifm-color-info); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--warning { + --ifm-badge-background-color: var(--ifm-color-warning); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--danger { + --ifm-badge-background-color: var(--ifm-color-danger); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.breadcrumbs { + margin-bottom: 0; + padding-left: 0; +} + +.breadcrumbs__item { + display: inline-block; + } + +.breadcrumbs__item:not(:last-child):after { + background: var(--ifm-breadcrumb-separator) center; + content: ' '; + display: inline-block; + filter: var(--ifm-breadcrumb-separator-filter); + height: calc( + var(--ifm-breadcrumb-separator-size) * + var(--ifm-breadcrumb-size-multiplier) * + var(--ifm-breadcrumb-separator-size-multiplier) + ); + margin: 0 var(--ifm-breadcrumb-spacing); + opacity: 0.5; + width: calc( + var(--ifm-breadcrumb-separator-size) * + var(--ifm-breadcrumb-size-multiplier) * + var(--ifm-breadcrumb-separator-size-multiplier) + ); + /*rtl:raw: + transform: rotate(180deg); + */ + } + +.breadcrumbs__item--active .breadcrumbs__link { + background: var(--ifm-breadcrumb-item-background-active); + color: var(--ifm-breadcrumb-color-active); + } + +.breadcrumbs__link { + border-radius: var(--ifm-breadcrumb-border-radius); + color: var(--ifm-font-color-base); + display: inline-block; + font-size: calc(1rem * var(--ifm-breadcrumb-size-multiplier)); + padding: calc( + var(--ifm-breadcrumb-padding-vertical) * + var(--ifm-breadcrumb-size-multiplier) + ) + calc( + var(--ifm-breadcrumb-padding-horizontal) * + var(--ifm-breadcrumb-size-multiplier) + ); + transition-property: background, color; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: var(--ifm-transition-timing-default); + } + +.breadcrumbs__link:link:hover, .breadcrumbs__link:visited:hover, area[href].breadcrumbs__link:hover { + background: var(--ifm-breadcrumb-item-background-active); + text-decoration: none; + } + +.breadcrumbs__link:-moz-any-link:hover { + background: var(--ifm-breadcrumb-item-background-active); + text-decoration: none; + } + +.breadcrumbs__link:any-link:hover { + background: var(--ifm-breadcrumb-item-background-active); + text-decoration: none; + } + +.breadcrumbs--sm { + --ifm-breadcrumb-size-multiplier: 0.8; + } + +.breadcrumbs--lg { + --ifm-breadcrumb-size-multiplier: 1.2; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.button { + background-color: var(--ifm-button-background-color); + border: var(--ifm-button-border-width) solid var(--ifm-button-border-color); + border-radius: var(--ifm-button-border-radius); + color: var(--ifm-button-color); + cursor: pointer; + display: inline-block; + font-size: calc(0.875rem * var(--ifm-button-size-multiplier)); + font-weight: var(--ifm-button-font-weight); + line-height: 1.5; + padding: calc( + var(--ifm-button-padding-vertical) * var(--ifm-button-size-multiplier) + ) + calc( + var(--ifm-button-padding-horizontal) * var(--ifm-button-size-multiplier) + ); + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + vertical-align: middle; + white-space: nowrap; + transition-property: color, background, border-color; + transition-duration: var(--ifm-button-transition-duration); + transition-timing-function: var(--ifm-transition-timing-default); +} + +.button:hover { + color: var(--ifm-button-color); /* Override for button links. */ + text-decoration: none; + } + +.button--outline { + --ifm-button-background-color: transparent; + --ifm-button-color: var(--ifm-button-border-color); + } + +.button--outline:hover { + --ifm-button-background-color: var(--ifm-button-border-color); + } + +.button--outline:hover, + .button--outline:active, + .button--outline.button--active { + --ifm-button-color: var(--ifm-font-color-base-inverse); + } + +.button--link { + --ifm-button-background-color: transparent; + --ifm-button-border-color: transparent; + + color: var(--ifm-link-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-decoration); + } + +.button--link:hover, + .button--link:active, + .button--link.button--active { + color: var(--ifm-link-hover-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-hover-decoration); + } + +.button.disabled, + .button:disabled, + .button[disabled] { + opacity: 0.65; + pointer-events: none; + } + +.button--sm { + --ifm-button-size-multiplier: 0.8; + } + +.button--lg { + --ifm-button-size-multiplier: 1.35; + } + +.button--block { + display: block; + width: 100%; + } + +.button.button--secondary { + color: var(--ifm-color-gray-900); + } + +.button.button--secondary.button--outline:not(.button--active):not(:hover) { + color: var(--ifm-font-color-base); + } + +:where(.button--primary) { + --ifm-button-background-color: var(--ifm-color-primary); + --ifm-button-border-color: var(--ifm-color-primary); + } + +:where(.button--primary):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-primary-dark); + --ifm-button-border-color: var(--ifm-color-primary-dark); + } + +.button--primary:active, + .button--primary.button--active { + --ifm-button-background-color: var(--ifm-color-primary-darker); + --ifm-button-border-color: var(--ifm-color-primary-darker); + } + +:where(.button--secondary) { + --ifm-button-background-color: var(--ifm-color-secondary); + --ifm-button-border-color: var(--ifm-color-secondary); + } + +:where(.button--secondary):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-secondary-dark); + --ifm-button-border-color: var(--ifm-color-secondary-dark); + } + +.button--secondary:active, + .button--secondary.button--active { + --ifm-button-background-color: var(--ifm-color-secondary-darker); + --ifm-button-border-color: var(--ifm-color-secondary-darker); + } + +:where(.button--success) { + --ifm-button-background-color: var(--ifm-color-success); + --ifm-button-border-color: var(--ifm-color-success); + } + +:where(.button--success):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-success-dark); + --ifm-button-border-color: var(--ifm-color-success-dark); + } + +.button--success:active, + .button--success.button--active { + --ifm-button-background-color: var(--ifm-color-success-darker); + --ifm-button-border-color: var(--ifm-color-success-darker); + } + +:where(.button--info) { + --ifm-button-background-color: var(--ifm-color-info); + --ifm-button-border-color: var(--ifm-color-info); + } + +:where(.button--info):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-info-dark); + --ifm-button-border-color: var(--ifm-color-info-dark); + } + +.button--info:active, + .button--info.button--active { + --ifm-button-background-color: var(--ifm-color-info-darker); + --ifm-button-border-color: var(--ifm-color-info-darker); + } + +:where(.button--warning) { + --ifm-button-background-color: var(--ifm-color-warning); + --ifm-button-border-color: var(--ifm-color-warning); + } + +:where(.button--warning):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-warning-dark); + --ifm-button-border-color: var(--ifm-color-warning-dark); + } + +.button--warning:active, + .button--warning.button--active { + --ifm-button-background-color: var(--ifm-color-warning-darker); + --ifm-button-border-color: var(--ifm-color-warning-darker); + } + +:where(.button--danger) { + --ifm-button-background-color: var(--ifm-color-danger); + --ifm-button-border-color: var(--ifm-color-danger); + } + +:where(.button--danger):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-danger-dark); + --ifm-button-border-color: var(--ifm-color-danger-dark); + } + +.button--danger:active, + .button--danger.button--active { + --ifm-button-background-color: var(--ifm-color-danger-darker); + --ifm-button-border-color: var(--ifm-color-danger-darker); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.button-group { + display: inline-flex; + gap: var(--ifm-button-group-spacing); +} + +.button-group > .button:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } + +.button-group > .button:not(:last-child) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } + +.button-group--block { + display: flex; + justify-content: stretch; + } + +.button-group--block > .button { + flex-grow: 1; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.card { + background-color: var(--ifm-card-background-color); + border-radius: var(--ifm-card-border-radius); + box-shadow: var(--ifm-global-shadow-lw); + display: flex; + flex-direction: column; + overflow: hidden; +} + +/* Because of border-radius. */ + +.card--full-height { + height: 100%; + } + +.card__image { + padding-top: var(--ifm-card-vertical-spacing); + } + +.card__image:first-child { + padding-top: 0; + } + +.card__header, + .card__body, + .card__footer { + padding: var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing); + } + +.card__header:not(:last-child), .card__body:not(:last-child), .card__footer:not(:last-child) { + padding-bottom: 0; + } + +.card__header > :last-child, .card__body > :last-child, .card__footer > :last-child { + margin-bottom: 0; + } + +.card__footer { + margin-top: auto; /* Pushes the footer to the bottom of the card. */ + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.table-of-contents { + font-size: 0.8rem; + margin-bottom: 0; + padding: var(--ifm-toc-padding-vertical) 0; +} + +.table-of-contents, + .table-of-contents ul { + list-style: none; + padding-left: var(--ifm-toc-padding-horizontal); + } + +.table-of-contents li { + margin: var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal); + } + +.table-of-contents__left-border { + border-left: 1px solid var(--ifm-toc-border-color); + } + +.table-of-contents__link { + color: var(--ifm-toc-link-color); + display: block; + } + +.table-of-contents__link:hover, + .table-of-contents__link:hover code, + .table-of-contents__link--active, + .table-of-contents__link--active code { + color: var(--ifm-color-primary); + text-decoration: none; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.close { + color: var(--ifm-color-black); + float: right; + font-size: 1.5rem; + font-weight: var(--ifm-font-weight-bold); + line-height: 1; + opacity: 0.5; + padding: 1rem; + transition: opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default); +} + +.close:hover { + opacity: 0.7; + } + +.close:focus { + opacity: 0.8; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.dropdown { + display: inline-flex; + font-weight: var(--ifm-dropdown-font-weight); + position: relative; + vertical-align: top; +} + +.dropdown--hoverable:hover .dropdown__menu, .dropdown--show .dropdown__menu { + opacity: 1; + pointer-events: all; + transform: translateY(-1px); + visibility: visible; + } + +.dropdown--right .dropdown__menu { + left: inherit; + right: 0; + } + +.dropdown--nocaret .navbar__link:after { + content: none !important; + } + +.dropdown__menu { + background-color: var(--ifm-dropdown-background-color); + border-radius: var(--ifm-global-radius); + box-shadow: var(--ifm-global-shadow-md); + left: 0; + list-style: none; + max-height: 80vh; + min-width: 10rem; + opacity: 0; + overflow-y: auto; + padding: 0.5rem; + pointer-events: none; + position: absolute; + top: calc(100% - var(--ifm-navbar-item-padding-vertical) + 0.3rem); + transform: translateY(-0.625rem); + visibility: hidden; + z-index: var(--ifm-z-index-dropdown); + transition-property: opacity, transform, visibility; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: var(--ifm-transition-timing-default); + } + +.dropdown__link { + border-radius: 0.25rem; + color: var(--ifm-dropdown-link-color); + display: block; + font-size: 0.875rem; + margin-top: 0.2rem; + padding: 0.25rem 0.5rem; + white-space: nowrap; + } + +.dropdown__link:hover, + .dropdown__link--active { + background-color: var(--ifm-dropdown-hover-background-color); + color: var(--ifm-dropdown-link-color); + text-decoration: none; + } + +.dropdown__link--active, + .dropdown__link--active:hover { + --ifm-dropdown-link-color: var(--ifm-link-color); + } + +.dropdown > .navbar__link:after { + border-color: currentColor transparent; + border-style: solid; + border-width: 0.4em 0.4em 0; + content: ''; + display: inline-block; + margin-left: 0.3em; + position: relative; + top: 2px; + transform: translateY(-50%); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.footer { + background-color: var(--ifm-footer-background-color); + color: var(--ifm-footer-color); + padding: var(--ifm-footer-padding-vertical) + var(--ifm-footer-padding-horizontal); +} + +.footer--dark { + --ifm-footer-background-color: #303846; + --ifm-footer-color: var(--ifm-footer-link-color); + --ifm-footer-link-color: var(--ifm-color-secondary); + --ifm-footer-title-color: var(--ifm-color-white); + } + +.footer__links { + margin-bottom: 1rem; + } + +.footer__link-item { + color: var(--ifm-footer-link-color); + line-height: 2; + } + +.footer__link-item:hover { + color: var(--ifm-footer-link-hover-color); + } + +.footer__link-separator { + margin: 0 var(--ifm-footer-link-horizontal-spacing); + } + +.footer__logo { + margin-top: 1rem; + max-width: var(--ifm-footer-logo-max-width); + } + +.footer__title { + color: var(--ifm-footer-title-color); + font: bold var(--ifm-h4-font-size) / var(--ifm-heading-line-height) + var(--ifm-font-family-base); + margin-bottom: var(--ifm-heading-margin-bottom); + } + +.footer__item { + margin-top: 0; + } + +.footer__items { + margin-bottom: 0; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +[type='checkbox'] { + padding: 0; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.hero { + align-items: center; + background-color: var(--ifm-hero-background-color); + color: var(--ifm-hero-text-color); + display: flex; + padding: 4rem 2rem; +} + +.hero--primary { + --ifm-hero-background-color: var(--ifm-color-primary); + --ifm-hero-text-color: var(--ifm-font-color-base-inverse); + } + +.hero--dark { + --ifm-hero-background-color: #303846; + --ifm-hero-text-color: var(--ifm-color-white); + } + +.hero__title { + font-size: 3rem; + } + +.hero__subtitle { + font-size: 1.5rem; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.menu { + font-weight: var(--ifm-font-weight-semibold); + overflow-x: hidden; +} + +.menu__list { + list-style: none; + margin: 0; + padding-left: 0; + } + +/* Non-top level menus */ + +.menu__list .menu__list { + flex: 0 0 100%; + margin-top: 0.25rem; + padding-left: var(--ifm-menu-link-padding-horizontal); + } + +.menu__list-item:not(:first-child) { + margin-top: 0.25rem; + } + +.menu__list-item--collapsed .menu__list { + height: 0; + overflow: hidden; + } + +.menu__list-item--collapsed .menu__link--sublist:after, + .menu__list-item--collapsed .menu__caret:before { + transform: rotateZ(90deg); + } + +.menu__list-item-collapsible { + flex-wrap: wrap; + position: relative; + border-radius: 0.25rem; + display: flex; + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.menu__list-item-collapsible:hover { + background: var(--ifm-menu-color-background-hover); + } + +.menu__list-item-collapsible--active { + background: var(--ifm-menu-color-background-hover); + } + +.menu__list-item-collapsible .menu__link:hover, + .menu__list-item-collapsible .menu__link--active { + background: none !important; + } + +.menu__link, + .menu__caret { + align-items: center; + border-radius: 0.25rem; + display: flex; + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.menu__link:hover, .menu__caret:hover { + background: var(--ifm-menu-color-background-hover); + } + +.menu__link { + color: var(--ifm-menu-color); + flex: 1; + line-height: 1.25; + padding: var(--ifm-menu-link-padding-vertical) + var(--ifm-menu-link-padding-horizontal); + } + +.menu__link:hover { + text-decoration: none; + color: var(--ifm-menu-color); + transition: color var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.menu__link--sublist-caret:after { + content: ''; + margin-left: auto; + min-width: 1.25rem; + background: var(--ifm-menu-link-sublist-icon) 50% / 2rem 2rem; + filter: var(--ifm-menu-link-sublist-icon-filter); + height: 1.25rem; + transform: rotate(180deg); + width: 1.25rem; + transition: transform var(--ifm-transition-fast) linear; + } + +.menu__link--active { + color: var(--ifm-menu-color-active); + } + +.menu__link--active:hover { + color: var(--ifm-menu-color-active); + } + +.menu__link--active:not(.menu__link--sublist) { + background-color: var(--ifm-menu-color-background-active); + } + +.menu__caret { + padding: var(--ifm-menu-link-padding-vertical) + var(--ifm-menu-link-padding-horizontal); + } + +.menu__caret:before { + content: ''; + background: var(--ifm-menu-link-sublist-icon) 50% / 2rem 2rem; + filter: var(--ifm-menu-link-sublist-icon-filter); + height: 1.25rem; + transform: rotate(180deg); + width: 1.25rem; + transition: transform var(--ifm-transition-fast) linear; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +html[data-theme='dark'], +.navbar--dark { + --ifm-menu-link-sublist-icon-filter: invert(100%) sepia(94%) saturate(17%) + hue-rotate(223deg) brightness(104%) contrast(98%); +} + +.navbar { + background-color: var(--ifm-navbar-background-color); + box-shadow: var(--ifm-navbar-shadow); + display: flex; + height: var(--ifm-navbar-height); + padding: var(--ifm-navbar-padding-vertical) + var(--ifm-navbar-padding-horizontal); +} + +.navbar > .container, + .navbar > .container-fluid { + display: flex; + } + +.navbar--fixed-top { + position: sticky; + top: 0; + z-index: var(--ifm-z-index-fixed); + } + +.navbar__inner { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + width: 100%; + } + +.navbar__brand { + align-items: center; + color: var(--ifm-navbar-link-color); + display: flex; + margin-right: 1rem; + min-width: 0; + } + +.navbar__brand:hover { + color: var(--ifm-navbar-link-hover-color); + text-decoration: none; + } + +.navbar__title { + flex: 1 1 auto; + } + +.navbar__toggle { + display: none; + margin-right: 0.5rem; + } + +.navbar__logo { + flex: 0 0 auto; + height: 2rem; + margin-right: 0.5rem; + } + +.navbar__logo img { + height: 100%; + } + +.navbar__items { + align-items: center; + display: flex; + flex: 1; + min-width: 0; + } + +.navbar__items--center { + flex: 0 0 auto; + } + +.navbar__items--center .navbar__brand { + margin: 0; + } + +.navbar__items--center + .navbar__items--right { + flex: 1; + } + +.navbar__items--right { + flex: 0 0 auto; + justify-content: flex-end; + } + +.navbar__items--right > :last-child { + padding-right: 0; + } + +.navbar__item { + display: inline-block; + padding: var(--ifm-navbar-item-padding-vertical) + var(--ifm-navbar-item-padding-horizontal); + } + +.navbar__item.dropdown .navbar__link:not([href]) { + pointer-events: none; + } + +.navbar__link { + color: var(--ifm-navbar-link-color); + font-weight: var(--ifm-font-weight-semibold); + } + +.navbar__link:hover, + .navbar__link--active { + color: var(--ifm-navbar-link-hover-color); + text-decoration: none; + } + +.navbar--dark, + .navbar--primary { + --ifm-menu-color: var(--ifm-color-gray-300); + --ifm-navbar-link-color: var(--ifm-color-gray-100); + --ifm-navbar-search-input-background-color: rgba(255, 255, 255, 0.1); + --ifm-navbar-search-input-placeholder-color: rgba(255, 255, 255, 0.5); + + color: var(--ifm-color-white); + } + +.navbar--dark { + --ifm-navbar-background-color: #242526; + --ifm-navbar-link-hover-color: var(--ifm-color-primary); + --ifm-menu-color-background-active: rgba(255, 255, 255, 0.05); + --ifm-navbar-search-input-color: var(--ifm-color-white); + } + +.navbar--primary { + --ifm-navbar-background-color: var(--ifm-color-primary); + --ifm-navbar-link-hover-color: var(--ifm-color-white); + --ifm-menu-color-active: var(--ifm-color-white); + --ifm-navbar-search-input-color: var(--ifm-color-emphasis-500); + } + +.navbar__search-input { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; /* Algolia will add type="search" to the input in Safari and Safari's styling will override the styling here. */ + background: var(--ifm-navbar-search-input-background-color) + var(--ifm-navbar-search-input-icon) no-repeat 0.75rem center / 1rem 1rem; + border: none; + border-radius: 2rem; + color: var(--ifm-navbar-search-input-color); + cursor: text; + display: inline-block; + font-size: 0.9rem; + height: 2rem; + padding: 0 0.5rem 0 2.25rem; + width: 12.5rem; + } + +.navbar__search-input::-moz-placeholder { + color: var(--ifm-navbar-search-input-placeholder-color); + } + +.navbar__search-input::placeholder { + color: var(--ifm-navbar-search-input-placeholder-color); + } + +.navbar-sidebar { + background-color: var(--ifm-navbar-background-color); + bottom: 0; + box-shadow: var(--ifm-global-shadow-md); + left: 0; + opacity: 0; + overflow-x: hidden; + position: fixed; + top: 0; + transform: translate3d(-100%, 0, 0); + visibility: hidden; + width: var(--ifm-navbar-sidebar-width); + transition-property: opacity, visibility, transform; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: ease-in-out; + } + +.navbar-sidebar--show .navbar-sidebar, + .navbar-sidebar--show .navbar-sidebar__backdrop { + opacity: 1; + visibility: visible; + } + +.navbar-sidebar--show .navbar-sidebar { + transform: translate3d(0, 0, 0); + } + +.navbar-sidebar__backdrop { + background-color: rgba(0, 0, 0, 0.6); + bottom: 0; + left: 0; + opacity: 0; + position: fixed; + right: 0; + top: 0; + visibility: hidden; + transition-property: opacity, visibility; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: ease-in-out; + } + +.navbar-sidebar__brand { + align-items: center; + box-shadow: var(--ifm-navbar-shadow); + display: flex; + flex: 1; + height: var(--ifm-navbar-height); + padding: var(--ifm-navbar-padding-vertical) + var(--ifm-navbar-padding-horizontal); + } + +.navbar-sidebar__items { + display: flex; + height: calc(100% - var(--ifm-navbar-height)); + transform: translateZ(0); + transition: transform var(--ifm-transition-fast) ease-in-out; + } + +.navbar-sidebar__items--show-secondary { + transform: translate3d( + calc((var(--ifm-navbar-sidebar-width)) * -1), + 0, + 0 + ); + } + +.navbar-sidebar__item { + flex-shrink: 0; + padding: 0.5rem; + width: calc(var(--ifm-navbar-sidebar-width)); + } + +.navbar-sidebar__back { + background: var(--ifm-menu-color-background-active); + font-size: 15px; + font-weight: var(--ifm-button-font-weight); + margin: 0 0 0.2rem -0.5rem; + padding: 0.6rem 1.5rem; + position: relative; + text-align: left; + top: -0.5rem; + width: calc(100% + 1rem); + } + +.navbar-sidebar__close { + display: flex; + margin-left: auto; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.pagination { + -moz-column-gap: var(--ifm-pagination-page-spacing); + column-gap: var(--ifm-pagination-page-spacing); + display: flex; + font-size: var(--ifm-pagination-font-size); + padding-left: 0; +} + +.pagination--sm { + --ifm-pagination-font-size: 0.8rem; + --ifm-pagination-padding-horizontal: 0.8rem; + --ifm-pagination-padding-vertical: 0.2rem; + } + +.pagination--lg { + --ifm-pagination-font-size: 1.2rem; + --ifm-pagination-padding-horizontal: 1.2rem; + --ifm-pagination-padding-vertical: 0.3rem; + } + +.pagination__item { + display: inline-flex; + } + +.pagination__item > span { + padding: var(--ifm-pagination-padding-vertical); + } + +.pagination__item--active .pagination__link { + background: var(--ifm-pagination-item-active-background); + color: var(--ifm-pagination-color-active); + } + +.pagination__item:not(.pagination__item--active):hover .pagination__link { + background: var(--ifm-pagination-item-active-background); + } + +.pagination__item--disabled, + .pagination__item[disabled] { + opacity: 0.25; + pointer-events: none; + } + +.pagination__link { + border-radius: var(--ifm-pagination-border-radius); + color: var(--ifm-font-color-base); + display: inline-block; + padding: var(--ifm-pagination-padding-vertical) + var(--ifm-pagination-padding-horizontal); + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.pagination__link:hover { + text-decoration: none; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.pagination-nav { + display: grid; + grid-gap: var(--ifm-spacing-horizontal); + gap: var(--ifm-spacing-horizontal); + grid-template-columns: repeat(2, 1fr); +} + +.pagination-nav__link { + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: var(--ifm-pagination-nav-border-radius); + display: block; + height: 100%; + line-height: var(--ifm-heading-line-height); + padding: var(--ifm-global-spacing); + transition: border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.pagination-nav__link:hover { + border-color: var(--ifm-pagination-nav-color-hover); + text-decoration: none; + } + +.pagination-nav__link--next { + grid-column: 2/3; + text-align: right; + } + +.pagination-nav__label { + font-size: var(--ifm-h4-font-size); + font-weight: var(--ifm-heading-font-weight); + word-break: break-word; + } + +.pagination-nav__link--prev .pagination-nav__label::before { + content: '« '; + } + +.pagination-nav__link--next .pagination-nav__label::after { + content: ' »'; + } + +.pagination-nav__sublabel { + color: var(--ifm-color-content-secondary); + font-size: var(--ifm-h5-font-size); + font-weight: var(--ifm-font-weight-semibold); + margin-bottom: 0.25rem; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.pills { + display: flex; + gap: var(--ifm-pills-spacing); + padding-left: 0; +} + +.pills__item { + border-radius: 0.5rem; + cursor: pointer; + display: inline-block; + font-weight: var(--ifm-font-weight-bold); + padding: 0.25rem 1rem; + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.pills__item--active { + background: var(--ifm-pills-color-background-active); + color: var(--ifm-pills-color-active); + } + +.pills__item:not(.pills__item--active):hover { + background: var(--ifm-pills-color-background-active); + } + +.pills--block { + justify-content: stretch; + } + +.pills--block .pills__item { + flex-grow: 1; + text-align: center; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.tabs { + color: var(--ifm-tabs-color); + display: flex; + font-weight: var(--ifm-font-weight-bold); + margin-bottom: 0; + overflow-x: auto; + padding-left: 0; +} + +.tabs__item { + border-bottom: 3px solid transparent; + border-radius: var(--ifm-global-radius); + cursor: pointer; + display: inline-flex; + padding: var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal); + transition: background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.tabs__item--active { + border-bottom-color: var(--ifm-tabs-color-active-border); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + color: var(--ifm-tabs-color-active); + } + +.tabs__item:hover { + background-color: var(--ifm-hover-overlay); + } + +.tabs--block { + justify-content: stretch; + } + +.tabs--block .tabs__item { + flex-grow: 1; + justify-content: center; + } + +/* Mode */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +html[data-theme='dark'] { + --ifm-color-scheme: dark; + + --ifm-color-emphasis-0: var(--ifm-color-gray-1000); + --ifm-color-emphasis-100: var(--ifm-color-gray-900); + --ifm-color-emphasis-200: var(--ifm-color-gray-800); + --ifm-color-emphasis-300: var(--ifm-color-gray-700); + --ifm-color-emphasis-400: var(--ifm-color-gray-600); + --ifm-color-emphasis-500: var(--ifm-color-gray-500); + --ifm-color-emphasis-600: var(--ifm-color-gray-400); + --ifm-color-emphasis-700: var(--ifm-color-gray-300); + --ifm-color-emphasis-800: var(--ifm-color-gray-200); + --ifm-color-emphasis-900: var(--ifm-color-gray-100); + --ifm-color-emphasis-1000: var(--ifm-color-gray-0); + + --ifm-background-color: #1b1b1d; + --ifm-background-surface-color: #242526; + + --ifm-hover-overlay: rgba(255, 255, 255, 0.05); + + --ifm-color-content: #e3e3e3; + --ifm-color-content-secondary: rgba(255, 255, 255, 1); + + --ifm-breadcrumb-separator-filter: invert(64%) sepia(11%) saturate(0%) + hue-rotate(149deg) brightness(99%) contrast(95%); + + --ifm-code-background: rgba(255, 255, 255, 0.1); + + --ifm-scrollbar-track-background-color: #444444; + --ifm-scrollbar-thumb-background-color: #686868; + --ifm-scrollbar-thumb-hover-background-color: #7a7a7a; + + --ifm-table-stripe-background: rgba(255, 255, 255, 0.07); + + --ifm-toc-border-color: var(--ifm-color-emphasis-200); + --ifm-color-primary-contrast-background: rgb(16, 36, 69); + --ifm-color-primary-contrast-foreground: rgb(235, 242, 252); + --ifm-color-secondary-contrast-background: rgb(71, 71, 72); + --ifm-color-secondary-contrast-foreground: rgb(253, 253, 254); + --ifm-color-success-contrast-background: rgb(0, 49, 0); + --ifm-color-success-contrast-foreground: rgb(230, 246, 230); + --ifm-color-info-contrast-background: rgb(25, 60, 71); + --ifm-color-info-contrast-foreground: rgb(238, 249, 253); + --ifm-color-warning-contrast-background: rgb(77, 56, 0); + --ifm-color-warning-contrast-foreground: rgb(255, 248, 230); + --ifm-color-danger-contrast-background: rgb(75, 17, 19); + --ifm-color-danger-contrast-foreground: rgb(255, 235, 236) +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +@media (min-width: 1440px) { + .container { + max-width: var(--ifm-container-width-xl); + } +} + +@media (max-width: 996px) { + .col { + --ifm-col-width: 100%; + flex-basis: var(--ifm-col-width); + margin-left: 0; + } + +.footer { + --ifm-footer-padding-horizontal: 0 +} + + .footer__link-separator { + display: none; + } + + .footer__col { + margin-bottom: calc(var(--ifm-spacing-vertical) * 3); + } + + .footer__link-item { + display: block; + } + +.hero { + padding-left: 0; + padding-right: 0 +} + +.navbar > .container, + .navbar > .container-fluid { + padding: 0 + } + +.navbar__toggle { + display: inherit + } + +.navbar__item { + display: none + } + +.navbar__search-input { + width: 9rem + } + +.pills--block { + flex-direction: column + } + +.tabs--block { + flex-direction: column + } +} + +@media (max-width: 576px) { + .markdown h1:first-child { + --ifm-h1-font-size: 2rem; + } + .markdown > h2 { + --ifm-h2-font-size: 1.5rem; + } + .markdown > h3 { + --ifm-h3-font-size: 1.25rem; + } +} + +@media (pointer: fine) { + .thin-scrollbar { + scrollbar-width: thin; + } + .thin-scrollbar::-webkit-scrollbar { + height: var(--ifm-scrollbar-size); + width: var(--ifm-scrollbar-size); + } + .thin-scrollbar::-webkit-scrollbar-track { + background: var(--ifm-scrollbar-track-background-color); + border-radius: 10px; + } + .thin-scrollbar::-webkit-scrollbar-thumb { + background: var(--ifm-scrollbar-thumb-background-color); + border-radius: 10px; + } + .thin-scrollbar::-webkit-scrollbar-thumb:hover { + background: var(--ifm-scrollbar-thumb-hover-background-color); + } +} + +@media (prefers-reduced-motion: reduce) { + :root { + --ifm-transition-fast: 0ms; + --ifm-transition-slow: 0ms; + } +} + +@media print { + +.table-of-contents { + display: none +} + +.footer { + display: none +} + +.menu { + display: none +} + +.navbar { + display: none +} + +.pagination-nav { + display: none +} + +.tabs { + page-break-inside: avoid +} +} diff --git a/pkgs/jot/lib/resources/styles-light.css b/pkgs/jot/lib/resources/styles-light.css new file mode 100644 index 00000000..3ffe4021 --- /dev/null +++ b/pkgs/jot/lib/resources/styles-light.css @@ -0,0 +1,3052 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* Common */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +:root { + --ifm-color-scheme: light; + + /* Colors. */ + --ifm-dark-value: 10%; + --ifm-darker-value: 15%; + --ifm-darkest-value: 30%; + --ifm-light-value: 15%; + --ifm-lighter-value: 30%; + --ifm-lightest-value: 50%; + + /* + This seems like a lot, but we want to ensure enough contrast. + Goal is to have a min score of 3 on https://www.myndex.com/APCA/fullmatrix + For fontWeight 400 + score 3, the cell must show a value < 16px (fontsize we use in places like alerts) + See also https://github.com/facebookincubator/infima/issues/55#issuecomment-884023075 + */ + --ifm-contrast-background-value: 90%; + --ifm-contrast-foreground-value: 70%; + /* Using slightly different values for dark mode */ + --ifm-contrast-background-dark-value: 70%; + --ifm-contrast-foreground-dark-value: 90%; + + --ifm-color-primary: #3578e5; + --ifm-color-secondary: #ebedf0; + --ifm-color-success: #00a400; + --ifm-color-info: #54c7ec; + --ifm-color-warning: #ffba00; + --ifm-color-danger: #fa383e; + --ifm-color-primary-dark: rgb(48, 108, 206); + --ifm-color-primary-darker: rgb(45, 102, 195); + --ifm-color-primary-darkest: rgb(37, 84, 160); + --ifm-color-primary-light: rgb(83, 140, 233); + --ifm-color-primary-lighter: rgb(114, 161, 237); + --ifm-color-primary-lightest: rgb(154, 188, 242); + --ifm-color-primary-contrast-background: rgb(235, 242, 252); + --ifm-color-primary-contrast-foreground: rgb(16, 36, 69); + --ifm-color-secondary-dark: rgb(212, 213, 216); + --ifm-color-secondary-darker: rgb(200, 201, 204); + --ifm-color-secondary-darkest: rgb(164, 166, 168); + --ifm-color-secondary-light: rgb(238, 240, 242); + --ifm-color-secondary-lighter: rgb(241, 242, 245); + --ifm-color-secondary-lightest: rgb(245, 246, 248); + --ifm-color-secondary-contrast-background: rgb(253, 253, 254); + --ifm-color-secondary-contrast-foreground: rgb(71, 71, 72); + --ifm-color-success-dark: rgb(0, 148, 0); + --ifm-color-success-darker: rgb(0, 139, 0); + --ifm-color-success-darkest: rgb(0, 115, 0); + --ifm-color-success-light: rgb(38, 178, 38); + --ifm-color-success-lighter: rgb(77, 191, 77); + --ifm-color-success-lightest: rgb(128, 210, 128); + --ifm-color-success-contrast-background: rgb(230, 246, 230); + --ifm-color-success-contrast-foreground: rgb(0, 49, 0); + --ifm-color-info-dark: rgb(76, 179, 212); + --ifm-color-info-darker: rgb(71, 169, 201); + --ifm-color-info-darkest: rgb(59, 139, 165); + --ifm-color-info-light: rgb(110, 207, 239); + --ifm-color-info-lighter: rgb(135, 216, 242); + --ifm-color-info-lightest: rgb(170, 227, 246); + --ifm-color-info-contrast-background: rgb(238, 249, 253); + --ifm-color-info-contrast-foreground: rgb(25, 60, 71); + --ifm-color-warning-dark: rgb(230, 167, 0); + --ifm-color-warning-darker: rgb(217, 158, 0); + --ifm-color-warning-darkest: rgb(179, 130, 0); + --ifm-color-warning-light: rgb(255, 196, 38); + --ifm-color-warning-lighter: rgb(255, 207, 77); + --ifm-color-warning-lightest: rgb(255, 221, 128); + --ifm-color-warning-contrast-background: rgb(255, 248, 230); + --ifm-color-warning-contrast-foreground: rgb(77, 56, 0); + --ifm-color-danger-dark: rgb(225, 50, 56); + --ifm-color-danger-darker: rgb(213, 48, 53); + --ifm-color-danger-darkest: rgb(175, 39, 43); + --ifm-color-danger-light: rgb(251, 86, 91); + --ifm-color-danger-lighter: rgb(251, 116, 120); + --ifm-color-danger-lightest: rgb(253, 156, 159); + --ifm-color-danger-contrast-background: rgb(255, 235, 236); + --ifm-color-danger-contrast-foreground: rgb(75, 17, 19); + + --ifm-color-white: #fff; + --ifm-color-black: #000; + + --ifm-color-gray-0: var(--ifm-color-white); + --ifm-color-gray-100: #f5f6f7; + --ifm-color-gray-200: #ebedf0; + --ifm-color-gray-300: #dadde1; + --ifm-color-gray-400: #ccd0d5; + --ifm-color-gray-500: #bec3c9; + --ifm-color-gray-600: #8d949e; + --ifm-color-gray-700: #606770; + --ifm-color-gray-800: #444950; + --ifm-color-gray-900: #1c1e21; + --ifm-color-gray-1000: var(--ifm-color-black); + + --ifm-color-emphasis-0: var(--ifm-color-gray-0); + --ifm-color-emphasis-100: var(--ifm-color-gray-100); + --ifm-color-emphasis-200: var(--ifm-color-gray-200); + --ifm-color-emphasis-300: var(--ifm-color-gray-300); + --ifm-color-emphasis-400: var(--ifm-color-gray-400); + --ifm-color-emphasis-500: var(--ifm-color-gray-500); + --ifm-color-emphasis-600: var(--ifm-color-gray-600); + --ifm-color-emphasis-700: var(--ifm-color-gray-700); + --ifm-color-emphasis-800: var(--ifm-color-gray-800); + --ifm-color-emphasis-900: var(--ifm-color-gray-900); + --ifm-color-emphasis-1000: var(--ifm-color-gray-1000); + + /* Base. */ + --ifm-color-content: var(--ifm-color-emphasis-900); + --ifm-color-content-inverse: var(--ifm-color-emphasis-0); + --ifm-color-content-secondary: #525860; + + --ifm-background-color: transparent; /* Body's background. */ + --ifm-background-surface-color: var(--ifm-color-content-inverse); + --ifm-global-border-width: 1px; + --ifm-global-radius: 0.4rem; + + --ifm-hover-overlay: rgba(0, 0, 0, 0.05); + + /* Typography. */ + --ifm-font-color-base: var(--ifm-color-content); + --ifm-font-color-base-inverse: var(--ifm-color-content-inverse); + --ifm-font-color-secondary: var(--ifm-color-content-secondary); + --ifm-font-family-base: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, + 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', + 'Segoe UI Emoji', 'Segoe UI Symbol'; + --ifm-font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, + 'Liberation Mono', 'Courier New', monospace; + --ifm-font-size-base: 100%; + + --ifm-font-weight-light: 300; + --ifm-font-weight-normal: 400; + --ifm-font-weight-semibold: 500; + --ifm-font-weight-bold: 700; + + --ifm-font-weight-base: var(--ifm-font-weight-normal); + --ifm-line-height-base: 1.65; + + /* Spacing. */ + --ifm-global-spacing: 1rem; + --ifm-spacing-vertical: var(--ifm-global-spacing); + --ifm-spacing-horizontal: var(--ifm-global-spacing); + + /* Transitions. */ + --ifm-transition-fast: 200ms; + --ifm-transition-slow: 400ms; + --ifm-transition-timing-default: cubic-bezier(0.08, 0.52, 0.52, 1); + + /* Shadows. */ + --ifm-global-shadow-lw: 0 1px 2px 0 rgba(0, 0, 0, 0.1); + --ifm-global-shadow-md: 0 5px 40px rgba(0, 0, 0, 0.2); + --ifm-global-shadow-tl: 0 12px 28px 0 rgba(0, 0, 0, 0.2), + 0 2px 4px 0 rgba(0, 0, 0, 0.1); + + /* Z-index. */ + --ifm-z-index-dropdown: 100; + --ifm-z-index-fixed: 200; + --ifm-z-index-overlay: 400; + --ifm-container-width: 1140px; + --ifm-container-width-xl: 1320px; + --ifm-code-background: rgb(246, 247, 248); + --ifm-code-border-radius: var(--ifm-global-radius); + --ifm-code-font-size: 90%; + --ifm-code-padding-horizontal: 0.1rem; + --ifm-code-padding-vertical: 0.1rem; + + --ifm-pre-background: var(--ifm-code-background); + --ifm-pre-border-radius: var(--ifm-code-border-radius); + --ifm-pre-color: inherit; + --ifm-pre-line-height: 1.45; + --ifm-pre-padding: 1rem; + --ifm-heading-color: inherit; + --ifm-heading-margin-top: 0; + --ifm-heading-margin-bottom: var(--ifm-spacing-vertical); + --ifm-heading-font-family: var(--ifm-font-family-base); + --ifm-heading-font-weight: var(--ifm-font-weight-bold); + --ifm-heading-line-height: 1.25; + + --ifm-h1-font-size: 2rem; + --ifm-h2-font-size: 1.5rem; + --ifm-h3-font-size: 1.25rem; + --ifm-h4-font-size: 1rem; + --ifm-h5-font-size: 0.875rem; + --ifm-h6-font-size: 0.85rem; + --ifm-image-alignment-padding: 1.25rem; + /* Leading is the distance between two baselines */ + /* TODO: add appropriate mobile leading */ + --ifm-leading-desktop: 1.25; + --ifm-leading: calc(var(--ifm-leading-desktop) * 1rem); + --ifm-list-left-padding: 2rem; + --ifm-list-margin: 1rem; + --ifm-list-item-margin: 0.25rem; + --ifm-list-paragraph-margin: 1rem; + --ifm-table-cell-padding: 0.75rem; + + --ifm-table-background: transparent; + --ifm-table-stripe-background: rgba(0, 0, 0, 0.03); + + --ifm-table-border-width: 1px; + --ifm-table-border-color: var(--ifm-color-emphasis-300); + + --ifm-table-head-background: inherit; + --ifm-table-head-color: inherit; + --ifm-table-head-font-weight: var(--ifm-font-weight-bold); + + --ifm-table-cell-color: inherit; + /* Links. */ + --ifm-link-color: var(--ifm-color-primary); + --ifm-link-decoration: none; + --ifm-link-hover-color: var(--ifm-link-color); + --ifm-link-hover-decoration: underline; + + /* Paragraphs. */ + --ifm-paragraph-margin-bottom: var(--ifm-leading); + + /* Blockquotes. */ + --ifm-blockquote-font-size: var(--ifm-font-size-base); + --ifm-blockquote-border-left-width: 2px; + --ifm-blockquote-padding-horizontal: var(--ifm-spacing-horizontal); + --ifm-blockquote-padding-vertical: 0; + --ifm-blockquote-shadow: none; + --ifm-blockquote-color: var(--ifm-color-emphasis-800); + --ifm-blockquote-border-color: var(--ifm-color-emphasis-300); + + /* Horizontal Rules. */ + --ifm-hr-background-color: var(--ifm-color-emphasis-500); + --ifm-hr-height: 1px; + --ifm-hr-margin-vertical: 1.5rem; + --ifm-scrollbar-size: 7px; + --ifm-scrollbar-track-background-color: #f1f1f1; + --ifm-scrollbar-thumb-background-color: #c0c0c0; + --ifm-scrollbar-thumb-hover-background-color: #a7a7a7; + --ifm-alert-background-color: inherit; /* Set a default which will be overridden later. */ + --ifm-alert-border-color: inherit; /* Set a default which will be overridden later. */ + --ifm-alert-border-radius: var(--ifm-global-radius); + --ifm-alert-border-width: 0px; /* For users that want to easily add a border */ + --ifm-alert-border-left-width: 5px; + --ifm-alert-color: var(--ifm-font-color-base); + --ifm-alert-padding-horizontal: var(--ifm-spacing-horizontal); + --ifm-alert-padding-vertical: var(--ifm-spacing-vertical); + --ifm-alert-shadow: var(--ifm-global-shadow-lw); + --ifm-avatar-intro-margin: 1rem; + --ifm-avatar-intro-alignment: inherit; + --ifm-avatar-photo-size: 3rem; + --ifm-badge-background-color: inherit; /* Set a default which will be overridden later. */ + --ifm-badge-border-color: inherit; /* Set a default which will be overridden later. */ + --ifm-badge-border-radius: var(--ifm-global-radius); + --ifm-badge-border-width: var(--ifm-global-border-width); + --ifm-badge-color: var(--ifm-color-white); + --ifm-badge-padding-horizontal: calc(var(--ifm-spacing-horizontal) * 0.5); + --ifm-badge-padding-vertical: calc(var(--ifm-spacing-vertical) * 0.25); + --ifm-breadcrumb-border-radius: 1.5rem; + --ifm-breadcrumb-spacing: 0.5rem; + --ifm-breadcrumb-color-active: var(--ifm-color-primary); + --ifm-breadcrumb-item-background-active: var(--ifm-hover-overlay); + --ifm-breadcrumb-padding-horizontal: 0.8rem; + --ifm-breadcrumb-padding-vertical: 0.4rem; + --ifm-breadcrumb-size-multiplier: 1; + --ifm-breadcrumb-separator: url('data:image/svg+xml;utf8,'); + --ifm-breadcrumb-separator-filter: none; + --ifm-breadcrumb-separator-size: 0.5rem; + --ifm-breadcrumb-separator-size-multiplier: 1.25; + --ifm-button-background-color: inherit; + --ifm-button-border-color: var(--ifm-button-background-color); + --ifm-button-border-width: var(--ifm-global-border-width); + --ifm-button-color: var(--ifm-font-color-base-inverse); + --ifm-button-font-weight: var(--ifm-font-weight-bold); + --ifm-button-padding-horizontal: 1.5rem; + --ifm-button-padding-vertical: 0.375rem; + --ifm-button-size-multiplier: 1; + --ifm-button-transition-duration: var(--ifm-transition-fast); + --ifm-button-border-radius: calc( + var(--ifm-global-radius) * var(--ifm-button-size-multiplier) + ); + --ifm-button-group-spacing: 2px; + --ifm-card-background-color: var(--ifm-background-surface-color); + --ifm-card-border-radius: calc(var(--ifm-global-radius) * 2); + --ifm-card-horizontal-spacing: var(--ifm-global-spacing); + --ifm-card-vertical-spacing: var(--ifm-global-spacing); + --ifm-toc-border-color: var(--ifm-color-emphasis-300); + --ifm-toc-link-color: var(--ifm-color-content-secondary); + --ifm-toc-padding-vertical: 0.5rem; + --ifm-toc-padding-horizontal: 0.5rem; + --ifm-dropdown-background-color: var(--ifm-background-surface-color); + --ifm-dropdown-font-weight: var(--ifm-font-weight-semibold); + --ifm-dropdown-link-color: var(--ifm-font-color-base); + --ifm-dropdown-hover-background-color: var(--ifm-hover-overlay); + --ifm-footer-background-color: var(--ifm-color-emphasis-100); + --ifm-footer-color: inherit; + --ifm-footer-link-color: var(--ifm-color-emphasis-700); + --ifm-footer-link-hover-color: var(--ifm-color-primary); + --ifm-footer-link-horizontal-spacing: 0.5rem; + --ifm-footer-padding-horizontal: calc(var(--ifm-spacing-horizontal) * 2); + --ifm-footer-padding-vertical: calc(var(--ifm-spacing-vertical) * 2); + --ifm-footer-title-color: inherit; + --ifm-footer-logo-max-width: min(30rem, 90vw); + --ifm-hero-background-color: var(--ifm-background-surface-color); + --ifm-hero-text-color: var(--ifm-color-emphasis-800); + --ifm-menu-color: var(--ifm-color-emphasis-700); + --ifm-menu-color-active: var(--ifm-color-primary); + --ifm-menu-color-background-active: var(--ifm-hover-overlay); + --ifm-menu-color-background-hover: var(--ifm-hover-overlay); + --ifm-menu-link-padding-horizontal: 0.75rem; + --ifm-menu-link-padding-vertical: 0.375rem; + --ifm-menu-link-sublist-icon: url('data:image/svg+xml;utf8,'); + --ifm-menu-link-sublist-icon-filter: none; + --ifm-navbar-background-color: var(--ifm-background-surface-color); + --ifm-navbar-height: 3.75rem; + --ifm-navbar-item-padding-horizontal: 0.75rem; + --ifm-navbar-item-padding-vertical: 0.25rem; + --ifm-navbar-link-color: var(--ifm-font-color-base); + --ifm-navbar-link-hover-color: var(--ifm-color-primary); + --ifm-navbar-link-active-color: var(--ifm-link-color); + --ifm-navbar-padding-horizontal: var(--ifm-spacing-horizontal); + --ifm-navbar-padding-vertical: calc(var(--ifm-spacing-vertical) * 0.5); + --ifm-navbar-shadow: var(--ifm-global-shadow-lw); + --ifm-navbar-search-input-background-color: var(--ifm-color-emphasis-200); + --ifm-navbar-search-input-color: var(--ifm-color-emphasis-800); + --ifm-navbar-search-input-placeholder-color: var(--ifm-color-emphasis-500); + --ifm-navbar-search-input-icon: url('data:image/svg+xml;utf8,'); + --ifm-navbar-sidebar-width: 83vw; + --ifm-pagination-border-radius: var(--ifm-global-radius); + --ifm-pagination-color-active: var(--ifm-color-primary); + --ifm-pagination-font-size: 1rem; + --ifm-pagination-item-active-background: var(--ifm-hover-overlay); + --ifm-pagination-page-spacing: 0.2em; + --ifm-pagination-padding-horizontal: calc(var(--ifm-spacing-horizontal) * 1); + --ifm-pagination-padding-vertical: calc(var(--ifm-spacing-vertical) * 0.25); + --ifm-pagination-nav-border-radius: var(--ifm-global-radius); + --ifm-pagination-nav-color-hover: var(--ifm-color-primary); + --ifm-pills-color-active: var(--ifm-color-primary); + --ifm-pills-color-background-active: var(--ifm-hover-overlay); + --ifm-pills-spacing: 0.125rem; + --ifm-tabs-color: var(--ifm-font-color-secondary); + --ifm-tabs-color-active: var(--ifm-color-primary); + --ifm-tabs-color-active-border: var(--ifm-tabs-color-active); + --ifm-tabs-padding-horizontal: 1rem; + --ifm-tabs-padding-vertical: 1rem; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +* { + box-sizing: border-box; +} + +html { + background-color: var(--ifm-background-color); + color: var(--ifm-font-color-base); + color-scheme: var(--ifm-color-scheme); + font: var(--ifm-font-size-base) / var(--ifm-line-height-base) + var(--ifm-font-family-base); + -webkit-font-smoothing: antialiased; + -webkit-tap-highlight-color: transparent; + text-rendering: optimizelegibility; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; +} + +body { + margin: 0; + word-wrap: break-word; +} + +iframe { + border: 0; + color-scheme: auto; +} + +/* Layout */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.container { + margin: 0 auto; + max-width: var(--ifm-container-width); + padding: 0 var(--ifm-spacing-horizontal); + width: 100%; +} + +.container--fluid { + max-width: inherit; + } + +.row { + display: flex; + flex-wrap: wrap; + margin: 0 calc(var(--ifm-spacing-horizontal) * -1); +} + +.row--no-gutters { + margin-left: 0; + margin-right: 0; + } + +.row--no-gutters > .col { + padding-left: 0; + padding-right: 0; + } + +.row--align-top { + align-items: flex-start; + } + +.row--align-bottom { + align-items: flex-end; + } + +.row--align-center { + align-items: center; + } + +.row--align-stretch { + align-items: stretch; + } + +.row--align-baseline { + align-items: baseline; + } + +.col { + --ifm-col-width: 100%; + + flex: 1 0; + margin-left: 0; + max-width: var(--ifm-col-width); + padding: 0 var(--ifm-spacing-horizontal); + width: 100%; +} + +.col[class*='col--'] { + flex: 0 0 var(--ifm-col-width); + } + +.col--1 { + --ifm-col-width: calc(1 / 12 * 100%); + } + +.col--offset-1 { + margin-left: calc(1 / 12 * 100%); + } + +.col--2 { + --ifm-col-width: calc(2 / 12 * 100%); + } + +.col--offset-2 { + margin-left: calc(2 / 12 * 100%); + } + +.col--3 { + --ifm-col-width: calc(3 / 12 * 100%); + } + +.col--offset-3 { + margin-left: calc(3 / 12 * 100%); + } + +.col--4 { + --ifm-col-width: calc(4 / 12 * 100%); + } + +.col--offset-4 { + margin-left: calc(4 / 12 * 100%); + } + +.col--5 { + --ifm-col-width: calc(5 / 12 * 100%); + } + +.col--offset-5 { + margin-left: calc(5 / 12 * 100%); + } + +.col--6 { + --ifm-col-width: calc(6 / 12 * 100%); + } + +.col--offset-6 { + margin-left: calc(6 / 12 * 100%); + } + +.col--7 { + --ifm-col-width: calc(7 / 12 * 100%); + } + +.col--offset-7 { + margin-left: calc(7 / 12 * 100%); + } + +.col--8 { + --ifm-col-width: calc(8 / 12 * 100%); + } + +.col--offset-8 { + margin-left: calc(8 / 12 * 100%); + } + +.col--9 { + --ifm-col-width: calc(9 / 12 * 100%); + } + +.col--offset-9 { + margin-left: calc(9 / 12 * 100%); + } + +.col--10 { + --ifm-col-width: calc(10 / 12 * 100%); + } + +.col--offset-10 { + margin-left: calc(10 / 12 * 100%); + } + +.col--11 { + --ifm-col-width: calc(11 / 12 * 100%); + } + +.col--offset-11 { + margin-left: calc(11 / 12 * 100%); + } + +.col--12 { + --ifm-col-width: calc(12 / 12 * 100%); + } + +.col--offset-12 { + margin-left: calc(12 / 12 * 100%); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.margin--none { + margin: 0 !important; + } + +.margin-top--none { + margin-top: 0 !important; + } + +.margin-left--none { + margin-left: 0 !important; + } + +.margin-bottom--none { + margin-bottom: 0 !important; + } + +.margin-right--none { + margin-right: 0 !important; + } + +.margin-vert--none { + margin-bottom: 0 !important; + margin-top: 0 !important; + } + +.margin-horiz--none { + margin-left: 0 !important; + margin-right: 0 !important; + } + +.margin--xs { + margin: 0.25rem !important; + } + +.margin-top--xs { + margin-top: 0.25rem !important; + } + +.margin-left--xs { + margin-left: 0.25rem !important; + } + +.margin-bottom--xs { + margin-bottom: 0.25rem !important; + } + +.margin-right--xs { + margin-right: 0.25rem !important; + } + +.margin-vert--xs { + margin-bottom: 0.25rem !important; + margin-top: 0.25rem !important; + } + +.margin-horiz--xs { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; + } + +.margin--sm { + margin: 0.5rem !important; + } + +.margin-top--sm { + margin-top: 0.5rem !important; + } + +.margin-left--sm { + margin-left: 0.5rem !important; + } + +.margin-bottom--sm { + margin-bottom: 0.5rem !important; + } + +.margin-right--sm { + margin-right: 0.5rem !important; + } + +.margin-vert--sm { + margin-bottom: 0.5rem !important; + margin-top: 0.5rem !important; + } + +.margin-horiz--sm { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; + } + +.margin--md { + margin: 1rem !important; + } + +.margin-top--md { + margin-top: 1rem !important; + } + +.margin-left--md { + margin-left: 1rem !important; + } + +.margin-bottom--md { + margin-bottom: 1rem !important; + } + +.margin-right--md { + margin-right: 1rem !important; + } + +.margin-vert--md { + margin-bottom: 1rem !important; + margin-top: 1rem !important; + } + +.margin-horiz--md { + margin-left: 1rem !important; + margin-right: 1rem !important; + } + +.margin--lg { + margin: 2rem !important; + } + +.margin-top--lg { + margin-top: 2rem !important; + } + +.margin-left--lg { + margin-left: 2rem !important; + } + +.margin-bottom--lg { + margin-bottom: 2rem !important; + } + +.margin-right--lg { + margin-right: 2rem !important; + } + +.margin-vert--lg { + margin-bottom: 2rem !important; + margin-top: 2rem !important; + } + +.margin-horiz--lg { + margin-left: 2rem !important; + margin-right: 2rem !important; + } + +.margin--xl { + margin: 5rem !important; + } + +.margin-top--xl { + margin-top: 5rem !important; + } + +.margin-left--xl { + margin-left: 5rem !important; + } + +.margin-bottom--xl { + margin-bottom: 5rem !important; + } + +.margin-right--xl { + margin-right: 5rem !important; + } + +.margin-vert--xl { + margin-bottom: 5rem !important; + margin-top: 5rem !important; + } + +.margin-horiz--xl { + margin-left: 5rem !important; + margin-right: 5rem !important; + } + +.padding--none { + padding: 0 !important; + } + +.padding-top--none { + padding-top: 0 !important; + } + +.padding-left--none { + padding-left: 0 !important; + } + +.padding-bottom--none { + padding-bottom: 0 !important; + } + +.padding-right--none { + padding-right: 0 !important; + } + +.padding-vert--none { + padding-bottom: 0 !important; + padding-top: 0 !important; + } + +.padding-horiz--none { + padding-left: 0 !important; + padding-right: 0 !important; + } + +.padding--xs { + padding: 0.25rem !important; + } + +.padding-top--xs { + padding-top: 0.25rem !important; + } + +.padding-left--xs { + padding-left: 0.25rem !important; + } + +.padding-bottom--xs { + padding-bottom: 0.25rem !important; + } + +.padding-right--xs { + padding-right: 0.25rem !important; + } + +.padding-vert--xs { + padding-bottom: 0.25rem !important; + padding-top: 0.25rem !important; + } + +.padding-horiz--xs { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; + } + +.padding--sm { + padding: 0.5rem !important; + } + +.padding-top--sm { + padding-top: 0.5rem !important; + } + +.padding-left--sm { + padding-left: 0.5rem !important; + } + +.padding-bottom--sm { + padding-bottom: 0.5rem !important; + } + +.padding-right--sm { + padding-right: 0.5rem !important; + } + +.padding-vert--sm { + padding-bottom: 0.5rem !important; + padding-top: 0.5rem !important; + } + +.padding-horiz--sm { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + +.padding--md { + padding: 1rem !important; + } + +.padding-top--md { + padding-top: 1rem !important; + } + +.padding-left--md { + padding-left: 1rem !important; + } + +.padding-bottom--md { + padding-bottom: 1rem !important; + } + +.padding-right--md { + padding-right: 1rem !important; + } + +.padding-vert--md { + padding-bottom: 1rem !important; + padding-top: 1rem !important; + } + +.padding-horiz--md { + padding-left: 1rem !important; + padding-right: 1rem !important; + } + +.padding--lg { + padding: 2rem !important; + } + +.padding-top--lg { + padding-top: 2rem !important; + } + +.padding-left--lg { + padding-left: 2rem !important; + } + +.padding-bottom--lg { + padding-bottom: 2rem !important; + } + +.padding-right--lg { + padding-right: 2rem !important; + } + +.padding-vert--lg { + padding-bottom: 2rem !important; + padding-top: 2rem !important; + } + +.padding-horiz--lg { + padding-left: 2rem !important; + padding-right: 2rem !important; + } + +.padding--xl { + padding: 5rem !important; + } + +.padding-top--xl { + padding-top: 5rem !important; + } + +.padding-left--xl { + padding-left: 5rem !important; + } + +.padding-bottom--xl { + padding-bottom: 5rem !important; + } + +.padding-right--xl { + padding-right: 5rem !important; + } + +.padding-vert--xl { + padding-bottom: 5rem !important; + padding-top: 5rem !important; + } + +.padding-horiz--xl { + padding-left: 5rem !important; + padding-right: 5rem !important; + } + +/* Content */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +code { + background-color: var(--ifm-code-background); + border: 0.1rem solid rgba(0, 0, 0, 0.1); + border-radius: var(--ifm-code-border-radius); + font-family: var(--ifm-font-family-monospace); + font-size: var(--ifm-code-font-size); + padding: var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal); + vertical-align: middle; +} + +a code { + color: inherit; +} + +pre { + background-color: var(--ifm-pre-background); + border-radius: var(--ifm-pre-border-radius); + color: var(--ifm-pre-color); + font: var(--ifm-code-font-size) / var(--ifm-pre-line-height) + var(--ifm-font-family-monospace); + margin: 0 0 var(--ifm-spacing-vertical); + overflow: auto; + padding: var(--ifm-pre-padding); +} + +pre code { + background-color: transparent; + border: none; + font-size: 100%; + line-height: inherit; + padding: 0; + } + +kbd { + background-color: var(--ifm-color-emphasis-0); + border: 1px solid var(--ifm-color-emphasis-400); + border-radius: 0.2rem; + box-shadow: inset 0 -1px 0 var(--ifm-color-emphasis-400); + color: var(--ifm-color-emphasis-800); + font: 80% var(--ifm-font-family-monospace); + padding: 0.15rem 0.3rem; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +h1, +h2, +h3, +h4, +h5, +h6 { + color: var(--ifm-heading-color); + font-family: var(--ifm-heading-font-family); + font-weight: var(--ifm-heading-font-weight); + line-height: var(--ifm-heading-line-height); + margin: var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0; +} + +h1 { + font-size: var(--ifm-h1-font-size); + } + +h2 { + font-size: var(--ifm-h2-font-size); + } + +h3 { + font-size: var(--ifm-h3-font-size); + } + +h4 { + font-size: var(--ifm-h4-font-size); + } + +h5 { + font-size: var(--ifm-h5-font-size); + } + +h6 { + font-size: var(--ifm-h6-font-size); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +img { + max-width: 100%; +} + +img[align='right'] { + padding-left: var(--image-alignment-padding); +} + +img[align='left'] { + padding-right: var(--image-alignment-padding); +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.markdown { + --ifm-h1-vertical-rhythm-top: 3; + --ifm-h2-vertical-rhythm-top: 2; + --ifm-h3-vertical-rhythm-top: 1.5; + --ifm-heading-vertical-rhythm-top: 1.25; + + --ifm-h1-vertical-rhythm-bottom: 1.25; + --ifm-heading-vertical-rhythm-bottom: 1; +} + +.markdown:before { + content: ''; + display: table; + } + +.markdown:after { + clear: both; + content: ''; + display: table; + } + +.markdown > *:last-child { + margin-bottom: 0 !important; + } + +.markdown h1:first-child { + --ifm-h1-font-size: 3rem; + + margin-bottom: calc( + var(--ifm-h1-vertical-rhythm-bottom) * var(--ifm-leading) + ); + } + +.markdown > h2 { + --ifm-h2-font-size: 2rem; + + margin-bottom: calc( + var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) + ); + margin-top: calc(var(--ifm-h2-vertical-rhythm-top) * var(--ifm-leading)); + } + +.markdown > h3 { + --ifm-h3-font-size: 1.5rem; + + margin-bottom: calc( + var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) + ); + margin-top: calc(var(--ifm-h3-vertical-rhythm-top) * var(--ifm-leading)); + } + +.markdown > h4, + .markdown > h5, + .markdown > h6 { + margin-bottom: calc( + var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) + ); + margin-top: calc( + var(--ifm-heading-vertical-rhythm-top) * var(--ifm-leading) + ); + } + +/* Consistent spacing between content paragraphs. */ + +.markdown > pre, + .markdown > ul, + .markdown > p { + margin-bottom: var(--ifm-leading); + } + +.markdown li { + word-wrap: break-word; + } + +.markdown li > p { + margin-top: var(--ifm-list-paragraph-margin); + } + +.markdown li + li { + margin-top: var(--ifm-list-item-margin); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* Lists */ + +ul, +ol { + margin: 0 0 var(--ifm-list-margin); + padding-left: var(--ifm-list-left-padding); +} + +ol ol, +ul ol { + list-style-type: lower-roman; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin: 0; +} + +ul ul ol, +ul ol ol, +ol ul ol, +ol ol ol { + list-style-type: lower-alpha; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +table { + border-collapse: collapse; + display: block; + margin-bottom: var(--ifm-spacing-vertical); + overflow: auto; +} + +table thead tr { + border-bottom: 2px solid var(--ifm-table-border-color); + } + +table thead { + background-color: var(--ifm-table-stripe-background); + } + +table tr { + background-color: var(--ifm-table-background); + border-top: var(--ifm-table-border-width) solid + var(--ifm-table-border-color); + } + +table tr:nth-child(2n) { + background-color: var(--ifm-table-stripe-background); + } + +table th, + table td { + border: var(--ifm-table-border-width) solid var(--ifm-table-border-color); + padding: var(--ifm-table-cell-padding); + } + +table th { + background-color: var(--ifm-table-head-background); + color: var(--ifm-table-head-color); + font-weight: var(--ifm-table-head-font-weight); + } + +table td { + color: var(--ifm-table-cell-color); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +strong { + font-weight: var(--ifm-font-weight-bold); +} + +/* Links */ + +a { + color: var(--ifm-link-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-decoration); + transition: color var(--ifm-transition-fast) var(--ifm-transition-timing-default); +} + +a:hover { + color: var(--ifm-link-hover-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-hover-decoration); + } + +a:not([href]) { + text-decoration: none; + } + +/* Paragraphs */ + +p { + margin: 0 0 var(--ifm-paragraph-margin-bottom); +} + +/* Blockquotes */ + +blockquote { + border-left: var(--ifm-blockquote-border-left-width) solid + var(--ifm-blockquote-border-color); + box-shadow: var(--ifm-blockquote-shadow); + color: var(--ifm-blockquote-color); + font-size: var(--ifm-blockquote-font-size); + margin: 0 0 var(--ifm-spacing-vertical); + padding: var(--ifm-blockquote-padding-vertical) + var(--ifm-blockquote-padding-horizontal); +} + +blockquote > :first-child { + margin-top: 0; + } + +blockquote > :last-child { + margin-bottom: 0; + } + +/* Horizontal Rules */ + +hr { + background-color: var(--ifm-hr-background-color); + border: 0; + height: var(--ifm-hr-height); + margin: var(--ifm-hr-margin-vertical) 0; +} + +/* Utilities */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.shadow--lw { + box-shadow: var(--ifm-global-shadow-lw) !important; + } + +.shadow--md { + box-shadow: var(--ifm-global-shadow-md) !important; + } + +.shadow--tl { + box-shadow: var(--ifm-global-shadow-tl) !important; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.text--primary { + color: var(--ifm-color-primary); + } + +.text--secondary { + color: var(--ifm-color-secondary); + } + +.text--success { + color: var(--ifm-color-success); + } + +.text--info { + color: var(--ifm-color-info); + } + +.text--warning { + color: var(--ifm-color-warning); + } + +.text--danger { + color: var(--ifm-color-danger); + } + +.text--center { + text-align: center; + } + +.text--left { + text-align: left; + } + +.text--justify { + text-align: justify; + } + +.text--right { + text-align: right; + } + +.text--capitalize { + text-transform: capitalize; + } + +.text--lowercase { + text-transform: lowercase; + } + +.text--uppercase { + text-transform: uppercase; + } + +.text--light { + font-weight: var(--ifm-font-weight-light); + } + +.text--normal { + font-weight: var(--ifm-font-weight-normal); + } + +.text--semibold { + font-weight: var(--ifm-font-weight-semibold); + } + +.text--bold { + font-weight: var(--ifm-font-weight-bold); + } + +.text--italic { + font-style: italic; +} + +.text--truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text--break { + word-wrap: break-word !important; + word-break: break-word !important; +} + +.text--no-decoration, + .text--no-decoration:hover { + text-decoration: none; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.clean-btn { + background: none; + border: none; + color: inherit; + cursor: pointer; + font-family: inherit; + padding: 0; +} + +.clean-list { + list-style: none; + padding-left: 0; +} + +/* Components */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.alert--primary { + --ifm-alert-background-color: var( + --ifm-color-primary-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(53, 120, 229, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-primary-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-primary-dark); + } + +.alert--secondary { + --ifm-alert-background-color: var( + --ifm-color-secondary-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(235, 237, 240, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-secondary-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-secondary-dark); + } + +.alert--success { + --ifm-alert-background-color: var( + --ifm-color-success-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(0, 164, 0, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-success-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-success-dark); + } + +.alert--info { + --ifm-alert-background-color: var( + --ifm-color-info-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(84, 199, 236, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-info-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-info-dark); + } + +.alert--warning { + --ifm-alert-background-color: var( + --ifm-color-warning-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(255, 186, 0, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-warning-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-warning-dark); + } + +.alert--danger { + --ifm-alert-background-color: var( + --ifm-color-danger-contrast-background + ); + --ifm-alert-background-color-highlight: rgba(250, 56, 62, 0.15); + --ifm-alert-foreground-color: var( + --ifm-color-danger-contrast-foreground + ); + --ifm-alert-border-color: var(--ifm-color-danger-dark); + } + +.alert { + + --ifm-code-background: var(--ifm-alert-background-color-highlight); + --ifm-link-color: var(--ifm-alert-foreground-color); + --ifm-link-hover-color: var(--ifm-alert-foreground-color); + --ifm-link-decoration: underline; + --ifm-tabs-color: var(--ifm-alert-foreground-color); + --ifm-tabs-color-active: var(--ifm-alert-foreground-color); + --ifm-tabs-color-active-border: var(--ifm-alert-border-color); + + background-color: var(--ifm-alert-background-color); + border: var(--ifm-alert-border-width) solid var(--ifm-alert-border-color); + border-left-width: var(--ifm-alert-border-left-width); + border-radius: var(--ifm-alert-border-radius); + box-shadow: var(--ifm-alert-shadow); + color: var(--ifm-alert-foreground-color); + padding: var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal); +} + +.alert__heading { + align-items: center; + display: flex; + font: bold var(--ifm-h5-font-size) / var(--ifm-heading-line-height) + var(--ifm-heading-font-family); + margin-bottom: 0.5rem; + text-transform: uppercase; + } + +.alert__icon { + display: inline-flex; + margin-right: 0.4em; + } + +.alert__icon svg { + fill: var(--ifm-alert-foreground-color); + stroke: var(--ifm-alert-foreground-color); + stroke-width: 0; + } + +.alert .close { + color: var(--ifm-alert-foreground-color); + margin: calc(var(--ifm-alert-padding-vertical) * -1) + calc(var(--ifm-alert-padding-horizontal) * -1) 0 0; + + opacity: 0.75; + } + +.alert .close:hover, + .alert .close:focus { + opacity: 1; + } + +.alert a { + text-decoration-color: var(--ifm-alert-border-color); + } + +.alert a:hover { + text-decoration-thickness: 2px; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.avatar { + -moz-column-gap: var(--ifm-avatar-intro-margin); + column-gap: var(--ifm-avatar-intro-margin); + display: flex; +} + +.avatar__photo { + border-radius: 50%; + display: block; + height: var(--ifm-avatar-photo-size); + overflow: hidden; + width: var(--ifm-avatar-photo-size); + } + +.avatar__photo--sm { + --ifm-avatar-photo-size: 2rem; + } + +.avatar__photo--lg { + --ifm-avatar-photo-size: 4rem; + } + +.avatar__photo--xl { + --ifm-avatar-photo-size: 6rem; + } + +.avatar__intro { + display: flex; + flex: 1 1; + flex-direction: column; + justify-content: center; + text-align: var(--ifm-avatar-intro-alignment); + } + +.avatar__name { + font: bold var(--ifm-h4-font-size) / var(--ifm-heading-line-height) + var(--ifm-font-family-base); + } + +.avatar__subtitle { + margin-top: 0.25rem; + } + +.avatar--vertical { + --ifm-avatar-intro-alignment: center; + --ifm-avatar-intro-margin: 0.5rem; + + align-items: center; + flex-direction: column; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.badge { + background-color: var(--ifm-badge-background-color); + border: var(--ifm-badge-border-width) solid var(--ifm-badge-border-color); + border-radius: var(--ifm-badge-border-radius); + color: var(--ifm-badge-color); + display: inline-block; + font-size: 75%; + font-weight: var(--ifm-font-weight-bold); + line-height: 1; + padding: var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal); +} + +.badge--primary { + --ifm-badge-background-color: var(--ifm-color-primary); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--secondary { + --ifm-badge-background-color: var(--ifm-color-secondary); + --ifm-badge-border-color: var(--ifm-badge-background-color); + color: var(--ifm-color-black); + } + +.badge--success { + --ifm-badge-background-color: var(--ifm-color-success); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--info { + --ifm-badge-background-color: var(--ifm-color-info); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--warning { + --ifm-badge-background-color: var(--ifm-color-warning); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +.badge--danger { + --ifm-badge-background-color: var(--ifm-color-danger); + --ifm-badge-border-color: var(--ifm-badge-background-color); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.breadcrumbs { + margin-bottom: 0; + padding-left: 0; +} + +.breadcrumbs__item { + display: inline-block; + } + +.breadcrumbs__item:not(:last-child):after { + background: var(--ifm-breadcrumb-separator) center; + content: ' '; + display: inline-block; + filter: var(--ifm-breadcrumb-separator-filter); + height: calc( + var(--ifm-breadcrumb-separator-size) * + var(--ifm-breadcrumb-size-multiplier) * + var(--ifm-breadcrumb-separator-size-multiplier) + ); + margin: 0 var(--ifm-breadcrumb-spacing); + opacity: 0.5; + width: calc( + var(--ifm-breadcrumb-separator-size) * + var(--ifm-breadcrumb-size-multiplier) * + var(--ifm-breadcrumb-separator-size-multiplier) + ); + /*rtl:raw: + transform: rotate(180deg); + */ + } + +.breadcrumbs__item--active .breadcrumbs__link { + background: var(--ifm-breadcrumb-item-background-active); + color: var(--ifm-breadcrumb-color-active); + } + +.breadcrumbs__link { + border-radius: var(--ifm-breadcrumb-border-radius); + color: var(--ifm-font-color-base); + display: inline-block; + font-size: calc(1rem * var(--ifm-breadcrumb-size-multiplier)); + padding: calc( + var(--ifm-breadcrumb-padding-vertical) * + var(--ifm-breadcrumb-size-multiplier) + ) + calc( + var(--ifm-breadcrumb-padding-horizontal) * + var(--ifm-breadcrumb-size-multiplier) + ); + transition-property: background, color; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: var(--ifm-transition-timing-default); + } + +.breadcrumbs__link:link:hover, .breadcrumbs__link:visited:hover, area[href].breadcrumbs__link:hover { + background: var(--ifm-breadcrumb-item-background-active); + text-decoration: none; + } + +.breadcrumbs__link:-moz-any-link:hover { + background: var(--ifm-breadcrumb-item-background-active); + text-decoration: none; + } + +.breadcrumbs__link:any-link:hover { + background: var(--ifm-breadcrumb-item-background-active); + text-decoration: none; + } + +.breadcrumbs--sm { + --ifm-breadcrumb-size-multiplier: 0.8; + } + +.breadcrumbs--lg { + --ifm-breadcrumb-size-multiplier: 1.2; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.button { + background-color: var(--ifm-button-background-color); + border: var(--ifm-button-border-width) solid var(--ifm-button-border-color); + border-radius: var(--ifm-button-border-radius); + color: var(--ifm-button-color); + cursor: pointer; + display: inline-block; + font-size: calc(0.875rem * var(--ifm-button-size-multiplier)); + font-weight: var(--ifm-button-font-weight); + line-height: 1.5; + padding: calc( + var(--ifm-button-padding-vertical) * var(--ifm-button-size-multiplier) + ) + calc( + var(--ifm-button-padding-horizontal) * var(--ifm-button-size-multiplier) + ); + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + vertical-align: middle; + white-space: nowrap; + transition-property: color, background, border-color; + transition-duration: var(--ifm-button-transition-duration); + transition-timing-function: var(--ifm-transition-timing-default); +} + +.button:hover { + color: var(--ifm-button-color); /* Override for button links. */ + text-decoration: none; + } + +.button--outline { + --ifm-button-background-color: transparent; + --ifm-button-color: var(--ifm-button-border-color); + } + +.button--outline:hover { + --ifm-button-background-color: var(--ifm-button-border-color); + } + +.button--outline:hover, + .button--outline:active, + .button--outline.button--active { + --ifm-button-color: var(--ifm-font-color-base-inverse); + } + +.button--link { + --ifm-button-background-color: transparent; + --ifm-button-border-color: transparent; + + color: var(--ifm-link-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-decoration); + } + +.button--link:hover, + .button--link:active, + .button--link.button--active { + color: var(--ifm-link-hover-color); + /* autoprefixer: ignore next */ + text-decoration: var(--ifm-link-hover-decoration); + } + +.button.disabled, + .button:disabled, + .button[disabled] { + opacity: 0.65; + pointer-events: none; + } + +.button--sm { + --ifm-button-size-multiplier: 0.8; + } + +.button--lg { + --ifm-button-size-multiplier: 1.35; + } + +.button--block { + display: block; + width: 100%; + } + +.button.button--secondary { + color: var(--ifm-color-gray-900); + } + +.button.button--secondary.button--outline:not(.button--active):not(:hover) { + color: var(--ifm-font-color-base); + } + +:where(.button--primary) { + --ifm-button-background-color: var(--ifm-color-primary); + --ifm-button-border-color: var(--ifm-color-primary); + } + +:where(.button--primary):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-primary-dark); + --ifm-button-border-color: var(--ifm-color-primary-dark); + } + +.button--primary:active, + .button--primary.button--active { + --ifm-button-background-color: var(--ifm-color-primary-darker); + --ifm-button-border-color: var(--ifm-color-primary-darker); + } + +:where(.button--secondary) { + --ifm-button-background-color: var(--ifm-color-secondary); + --ifm-button-border-color: var(--ifm-color-secondary); + } + +:where(.button--secondary):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-secondary-dark); + --ifm-button-border-color: var(--ifm-color-secondary-dark); + } + +.button--secondary:active, + .button--secondary.button--active { + --ifm-button-background-color: var(--ifm-color-secondary-darker); + --ifm-button-border-color: var(--ifm-color-secondary-darker); + } + +:where(.button--success) { + --ifm-button-background-color: var(--ifm-color-success); + --ifm-button-border-color: var(--ifm-color-success); + } + +:where(.button--success):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-success-dark); + --ifm-button-border-color: var(--ifm-color-success-dark); + } + +.button--success:active, + .button--success.button--active { + --ifm-button-background-color: var(--ifm-color-success-darker); + --ifm-button-border-color: var(--ifm-color-success-darker); + } + +:where(.button--info) { + --ifm-button-background-color: var(--ifm-color-info); + --ifm-button-border-color: var(--ifm-color-info); + } + +:where(.button--info):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-info-dark); + --ifm-button-border-color: var(--ifm-color-info-dark); + } + +.button--info:active, + .button--info.button--active { + --ifm-button-background-color: var(--ifm-color-info-darker); + --ifm-button-border-color: var(--ifm-color-info-darker); + } + +:where(.button--warning) { + --ifm-button-background-color: var(--ifm-color-warning); + --ifm-button-border-color: var(--ifm-color-warning); + } + +:where(.button--warning):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-warning-dark); + --ifm-button-border-color: var(--ifm-color-warning-dark); + } + +.button--warning:active, + .button--warning.button--active { + --ifm-button-background-color: var(--ifm-color-warning-darker); + --ifm-button-border-color: var(--ifm-color-warning-darker); + } + +:where(.button--danger) { + --ifm-button-background-color: var(--ifm-color-danger); + --ifm-button-border-color: var(--ifm-color-danger); + } + +:where(.button--danger):not(.button--outline):hover { + --ifm-button-background-color: var(--ifm-color-danger-dark); + --ifm-button-border-color: var(--ifm-color-danger-dark); + } + +.button--danger:active, + .button--danger.button--active { + --ifm-button-background-color: var(--ifm-color-danger-darker); + --ifm-button-border-color: var(--ifm-color-danger-darker); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.button-group { + display: inline-flex; + gap: var(--ifm-button-group-spacing); +} + +.button-group > .button:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } + +.button-group > .button:not(:last-child) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } + +.button-group--block { + display: flex; + justify-content: stretch; + } + +.button-group--block > .button { + flex-grow: 1; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.card { + background-color: var(--ifm-card-background-color); + border-radius: var(--ifm-card-border-radius); + box-shadow: var(--ifm-global-shadow-lw); + display: flex; + flex-direction: column; + overflow: hidden; +} + +/* Because of border-radius. */ + +.card--full-height { + height: 100%; + } + +.card__image { + padding-top: var(--ifm-card-vertical-spacing); + } + +.card__image:first-child { + padding-top: 0; + } + +.card__header, + .card__body, + .card__footer { + padding: var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing); + } + +.card__header:not(:last-child), .card__body:not(:last-child), .card__footer:not(:last-child) { + padding-bottom: 0; + } + +.card__header > :last-child, .card__body > :last-child, .card__footer > :last-child { + margin-bottom: 0; + } + +.card__footer { + margin-top: auto; /* Pushes the footer to the bottom of the card. */ + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.table-of-contents { + font-size: 0.8rem; + margin-bottom: 0; + padding: var(--ifm-toc-padding-vertical) 0; +} + +.table-of-contents, + .table-of-contents ul { + list-style: none; + padding-left: var(--ifm-toc-padding-horizontal); + } + +.table-of-contents li { + margin: var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal); + } + +.table-of-contents__left-border { + border-left: 1px solid var(--ifm-toc-border-color); + } + +.table-of-contents__link { + color: var(--ifm-toc-link-color); + display: block; + } + +.table-of-contents__link:hover, + .table-of-contents__link:hover code, + .table-of-contents__link--active, + .table-of-contents__link--active code { + color: var(--ifm-color-primary); + text-decoration: none; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.close { + color: var(--ifm-color-black); + float: right; + font-size: 1.5rem; + font-weight: var(--ifm-font-weight-bold); + line-height: 1; + opacity: 0.5; + padding: 1rem; + transition: opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default); +} + +.close:hover { + opacity: 0.7; + } + +.close:focus { + opacity: 0.8; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.dropdown { + display: inline-flex; + font-weight: var(--ifm-dropdown-font-weight); + position: relative; + vertical-align: top; +} + +.dropdown--hoverable:hover .dropdown__menu, .dropdown--show .dropdown__menu { + opacity: 1; + pointer-events: all; + transform: translateY(-1px); + visibility: visible; + } + +.dropdown--right .dropdown__menu { + left: inherit; + right: 0; + } + +.dropdown--nocaret .navbar__link:after { + content: none !important; + } + +.dropdown__menu { + background-color: var(--ifm-dropdown-background-color); + border-radius: var(--ifm-global-radius); + box-shadow: var(--ifm-global-shadow-md); + left: 0; + list-style: none; + max-height: 80vh; + min-width: 10rem; + opacity: 0; + overflow-y: auto; + padding: 0.5rem; + pointer-events: none; + position: absolute; + top: calc(100% - var(--ifm-navbar-item-padding-vertical) + 0.3rem); + transform: translateY(-0.625rem); + visibility: hidden; + z-index: var(--ifm-z-index-dropdown); + transition-property: opacity, transform, visibility; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: var(--ifm-transition-timing-default); + } + +.dropdown__link { + border-radius: 0.25rem; + color: var(--ifm-dropdown-link-color); + display: block; + font-size: 0.875rem; + margin-top: 0.2rem; + padding: 0.25rem 0.5rem; + white-space: nowrap; + } + +.dropdown__link:hover, + .dropdown__link--active { + background-color: var(--ifm-dropdown-hover-background-color); + color: var(--ifm-dropdown-link-color); + text-decoration: none; + } + +.dropdown__link--active, + .dropdown__link--active:hover { + --ifm-dropdown-link-color: var(--ifm-link-color); + } + +.dropdown > .navbar__link:after { + border-color: currentColor transparent; + border-style: solid; + border-width: 0.4em 0.4em 0; + content: ''; + display: inline-block; + margin-left: 0.3em; + position: relative; + top: 2px; + transform: translateY(-50%); + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.footer { + background-color: var(--ifm-footer-background-color); + color: var(--ifm-footer-color); + padding: var(--ifm-footer-padding-vertical) + var(--ifm-footer-padding-horizontal); +} + +.footer--dark { + --ifm-footer-background-color: #303846; + --ifm-footer-color: var(--ifm-footer-link-color); + --ifm-footer-link-color: var(--ifm-color-secondary); + --ifm-footer-title-color: var(--ifm-color-white); + } + +.footer__links { + margin-bottom: 1rem; + } + +.footer__link-item { + color: var(--ifm-footer-link-color); + line-height: 2; + } + +.footer__link-item:hover { + color: var(--ifm-footer-link-hover-color); + } + +.footer__link-separator { + margin: 0 var(--ifm-footer-link-horizontal-spacing); + } + +.footer__logo { + margin-top: 1rem; + max-width: var(--ifm-footer-logo-max-width); + } + +.footer__title { + color: var(--ifm-footer-title-color); + font: bold var(--ifm-h4-font-size) / var(--ifm-heading-line-height) + var(--ifm-font-family-base); + margin-bottom: var(--ifm-heading-margin-bottom); + } + +.footer__item { + margin-top: 0; + } + +.footer__items { + margin-bottom: 0; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +[type='checkbox'] { + padding: 0; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.hero { + align-items: center; + background-color: var(--ifm-hero-background-color); + color: var(--ifm-hero-text-color); + display: flex; + padding: 4rem 2rem; +} + +.hero--primary { + --ifm-hero-background-color: var(--ifm-color-primary); + --ifm-hero-text-color: var(--ifm-font-color-base-inverse); + } + +.hero--dark { + --ifm-hero-background-color: #303846; + --ifm-hero-text-color: var(--ifm-color-white); + } + +.hero__title { + font-size: 3rem; + } + +.hero__subtitle { + font-size: 1.5rem; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.menu { + font-weight: var(--ifm-font-weight-semibold); + overflow-x: hidden; +} + +.menu__list { + list-style: none; + margin: 0; + padding-left: 0; + } + +/* Non-top level menus */ + +.menu__list .menu__list { + flex: 0 0 100%; + margin-top: 0.25rem; + padding-left: var(--ifm-menu-link-padding-horizontal); + } + +.menu__list-item:not(:first-child) { + margin-top: 0.25rem; + } + +.menu__list-item--collapsed .menu__list { + height: 0; + overflow: hidden; + } + +.menu__list-item--collapsed .menu__link--sublist:after, + .menu__list-item--collapsed .menu__caret:before { + transform: rotateZ(90deg); + } + +.menu__list-item-collapsible { + flex-wrap: wrap; + position: relative; + border-radius: 0.25rem; + display: flex; + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.menu__list-item-collapsible:hover { + background: var(--ifm-menu-color-background-hover); + } + +.menu__list-item-collapsible--active { + background: var(--ifm-menu-color-background-hover); + } + +.menu__list-item-collapsible .menu__link:hover, + .menu__list-item-collapsible .menu__link--active { + background: none !important; + } + +.menu__link, + .menu__caret { + align-items: center; + border-radius: 0.25rem; + display: flex; + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.menu__link:hover, .menu__caret:hover { + background: var(--ifm-menu-color-background-hover); + } + +.menu__link { + color: var(--ifm-menu-color); + flex: 1; + line-height: 1.25; + padding: var(--ifm-menu-link-padding-vertical) + var(--ifm-menu-link-padding-horizontal); + } + +.menu__link:hover { + text-decoration: none; + color: var(--ifm-menu-color); + transition: color var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.menu__link--sublist-caret:after { + content: ''; + margin-left: auto; + min-width: 1.25rem; + background: var(--ifm-menu-link-sublist-icon) 50% / 2rem 2rem; + filter: var(--ifm-menu-link-sublist-icon-filter); + height: 1.25rem; + transform: rotate(180deg); + width: 1.25rem; + transition: transform var(--ifm-transition-fast) linear; + } + +.menu__link--active { + color: var(--ifm-menu-color-active); + } + +.menu__link--active:hover { + color: var(--ifm-menu-color-active); + } + +.menu__link--active:not(.menu__link--sublist) { + background-color: var(--ifm-menu-color-background-active); + } + +.menu__caret { + padding: var(--ifm-menu-link-padding-vertical) + var(--ifm-menu-link-padding-horizontal); + } + +.menu__caret:before { + content: ''; + background: var(--ifm-menu-link-sublist-icon) 50% / 2rem 2rem; + filter: var(--ifm-menu-link-sublist-icon-filter); + height: 1.25rem; + transform: rotate(180deg); + width: 1.25rem; + transition: transform var(--ifm-transition-fast) linear; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +html[data-theme='dark'], +.navbar--dark { + --ifm-menu-link-sublist-icon-filter: invert(100%) sepia(94%) saturate(17%) + hue-rotate(223deg) brightness(104%) contrast(98%); +} + +.navbar { + background-color: var(--ifm-navbar-background-color); + box-shadow: var(--ifm-navbar-shadow); + display: flex; + height: var(--ifm-navbar-height); + padding: var(--ifm-navbar-padding-vertical) + var(--ifm-navbar-padding-horizontal); +} + +.navbar > .container, + .navbar > .container-fluid { + display: flex; + } + +.navbar--fixed-top { + position: sticky; + top: 0; + z-index: var(--ifm-z-index-fixed); + } + +.navbar__inner { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + width: 100%; + } + +.navbar__brand { + align-items: center; + color: var(--ifm-navbar-link-color); + display: flex; + margin-right: 1rem; + min-width: 0; + } + +.navbar__brand:hover { + color: var(--ifm-navbar-link-hover-color); + text-decoration: none; + } + +.navbar__title { + flex: 1 1 auto; + } + +.navbar__toggle { + display: none; + margin-right: 0.5rem; + } + +.navbar__logo { + flex: 0 0 auto; + height: 2rem; + margin-right: 0.5rem; + } + +.navbar__logo img { + height: 100%; + } + +.navbar__items { + align-items: center; + display: flex; + flex: 1; + min-width: 0; + } + +.navbar__items--center { + flex: 0 0 auto; + } + +.navbar__items--center .navbar__brand { + margin: 0; + } + +.navbar__items--center + .navbar__items--right { + flex: 1; + } + +.navbar__items--right { + flex: 0 0 auto; + justify-content: flex-end; + } + +.navbar__items--right > :last-child { + padding-right: 0; + } + +.navbar__item { + display: inline-block; + padding: var(--ifm-navbar-item-padding-vertical) + var(--ifm-navbar-item-padding-horizontal); + } + +.navbar__item.dropdown .navbar__link:not([href]) { + pointer-events: none; + } + +.navbar__link { + color: var(--ifm-navbar-link-color); + font-weight: var(--ifm-font-weight-semibold); + } + +.navbar__link:hover, + .navbar__link--active { + color: var(--ifm-navbar-link-hover-color); + text-decoration: none; + } + +.navbar--dark, + .navbar--primary { + --ifm-menu-color: var(--ifm-color-gray-300); + --ifm-navbar-link-color: var(--ifm-color-gray-100); + --ifm-navbar-search-input-background-color: rgba(255, 255, 255, 0.1); + --ifm-navbar-search-input-placeholder-color: rgba(255, 255, 255, 0.5); + + color: var(--ifm-color-white); + } + +.navbar--dark { + --ifm-navbar-background-color: #242526; + --ifm-navbar-link-hover-color: var(--ifm-color-primary); + --ifm-menu-color-background-active: rgba(255, 255, 255, 0.05); + --ifm-navbar-search-input-color: var(--ifm-color-white); + } + +.navbar--primary { + --ifm-navbar-background-color: var(--ifm-color-primary); + --ifm-navbar-link-hover-color: var(--ifm-color-white); + --ifm-menu-color-active: var(--ifm-color-white); + --ifm-navbar-search-input-color: var(--ifm-color-emphasis-500); + } + +.navbar__search-input { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; /* Algolia will add type="search" to the input in Safari and Safari's styling will override the styling here. */ + background: var(--ifm-navbar-search-input-background-color) + var(--ifm-navbar-search-input-icon) no-repeat 0.75rem center / 1rem 1rem; + border: none; + border-radius: 2rem; + color: var(--ifm-navbar-search-input-color); + cursor: text; + display: inline-block; + font-size: 0.9rem; + height: 2rem; + padding: 0 0.5rem 0 2.25rem; + width: 12.5rem; + } + +.navbar__search-input::-moz-placeholder { + color: var(--ifm-navbar-search-input-placeholder-color); + } + +.navbar__search-input::placeholder { + color: var(--ifm-navbar-search-input-placeholder-color); + } + +.navbar-sidebar { + background-color: var(--ifm-navbar-background-color); + bottom: 0; + box-shadow: var(--ifm-global-shadow-md); + left: 0; + opacity: 0; + overflow-x: hidden; + position: fixed; + top: 0; + transform: translate3d(-100%, 0, 0); + visibility: hidden; + width: var(--ifm-navbar-sidebar-width); + transition-property: opacity, visibility, transform; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: ease-in-out; + } + +.navbar-sidebar--show .navbar-sidebar, + .navbar-sidebar--show .navbar-sidebar__backdrop { + opacity: 1; + visibility: visible; + } + +.navbar-sidebar--show .navbar-sidebar { + transform: translate3d(0, 0, 0); + } + +.navbar-sidebar__backdrop { + background-color: rgba(0, 0, 0, 0.6); + bottom: 0; + left: 0; + opacity: 0; + position: fixed; + right: 0; + top: 0; + visibility: hidden; + transition-property: opacity, visibility; + transition-duration: var(--ifm-transition-fast); + transition-timing-function: ease-in-out; + } + +.navbar-sidebar__brand { + align-items: center; + box-shadow: var(--ifm-navbar-shadow); + display: flex; + flex: 1; + height: var(--ifm-navbar-height); + padding: var(--ifm-navbar-padding-vertical) + var(--ifm-navbar-padding-horizontal); + } + +.navbar-sidebar__items { + display: flex; + height: calc(100% - var(--ifm-navbar-height)); + transform: translateZ(0); + transition: transform var(--ifm-transition-fast) ease-in-out; + } + +.navbar-sidebar__items--show-secondary { + transform: translate3d( + calc((var(--ifm-navbar-sidebar-width)) * -1), + 0, + 0 + ); + } + +.navbar-sidebar__item { + flex-shrink: 0; + padding: 0.5rem; + width: calc(var(--ifm-navbar-sidebar-width)); + } + +.navbar-sidebar__back { + background: var(--ifm-menu-color-background-active); + font-size: 15px; + font-weight: var(--ifm-button-font-weight); + margin: 0 0 0.2rem -0.5rem; + padding: 0.6rem 1.5rem; + position: relative; + text-align: left; + top: -0.5rem; + width: calc(100% + 1rem); + } + +.navbar-sidebar__close { + display: flex; + margin-left: auto; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.pagination { + -moz-column-gap: var(--ifm-pagination-page-spacing); + column-gap: var(--ifm-pagination-page-spacing); + display: flex; + font-size: var(--ifm-pagination-font-size); + padding-left: 0; +} + +.pagination--sm { + --ifm-pagination-font-size: 0.8rem; + --ifm-pagination-padding-horizontal: 0.8rem; + --ifm-pagination-padding-vertical: 0.2rem; + } + +.pagination--lg { + --ifm-pagination-font-size: 1.2rem; + --ifm-pagination-padding-horizontal: 1.2rem; + --ifm-pagination-padding-vertical: 0.3rem; + } + +.pagination__item { + display: inline-flex; + } + +.pagination__item > span { + padding: var(--ifm-pagination-padding-vertical); + } + +.pagination__item--active .pagination__link { + background: var(--ifm-pagination-item-active-background); + color: var(--ifm-pagination-color-active); + } + +.pagination__item:not(.pagination__item--active):hover .pagination__link { + background: var(--ifm-pagination-item-active-background); + } + +.pagination__item--disabled, + .pagination__item[disabled] { + opacity: 0.25; + pointer-events: none; + } + +.pagination__link { + border-radius: var(--ifm-pagination-border-radius); + color: var(--ifm-font-color-base); + display: inline-block; + padding: var(--ifm-pagination-padding-vertical) + var(--ifm-pagination-padding-horizontal); + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.pagination__link:hover { + text-decoration: none; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.pagination-nav { + display: grid; + grid-gap: var(--ifm-spacing-horizontal); + gap: var(--ifm-spacing-horizontal); + grid-template-columns: repeat(2, 1fr); +} + +.pagination-nav__link { + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: var(--ifm-pagination-nav-border-radius); + display: block; + height: 100%; + line-height: var(--ifm-heading-line-height); + padding: var(--ifm-global-spacing); + transition: border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.pagination-nav__link:hover { + border-color: var(--ifm-pagination-nav-color-hover); + text-decoration: none; + } + +.pagination-nav__link--next { + grid-column: 2/3; + text-align: right; + } + +.pagination-nav__label { + font-size: var(--ifm-h4-font-size); + font-weight: var(--ifm-heading-font-weight); + word-break: break-word; + } + +.pagination-nav__link--prev .pagination-nav__label::before { + content: '« '; + } + +.pagination-nav__link--next .pagination-nav__label::after { + content: ' »'; + } + +.pagination-nav__sublabel { + color: var(--ifm-color-content-secondary); + font-size: var(--ifm-h5-font-size); + font-weight: var(--ifm-font-weight-semibold); + margin-bottom: 0.25rem; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.pills { + display: flex; + gap: var(--ifm-pills-spacing); + padding-left: 0; +} + +.pills__item { + border-radius: 0.5rem; + cursor: pointer; + display: inline-block; + font-weight: var(--ifm-font-weight-bold); + padding: 0.25rem 1rem; + transition: background var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.pills__item--active { + background: var(--ifm-pills-color-background-active); + color: var(--ifm-pills-color-active); + } + +.pills__item:not(.pills__item--active):hover { + background: var(--ifm-pills-color-background-active); + } + +.pills--block { + justify-content: stretch; + } + +.pills--block .pills__item { + flex-grow: 1; + text-align: center; + } + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.tabs { + color: var(--ifm-tabs-color); + display: flex; + font-weight: var(--ifm-font-weight-bold); + margin-bottom: 0; + overflow-x: auto; + padding-left: 0; +} + +.tabs__item { + border-bottom: 3px solid transparent; + border-radius: var(--ifm-global-radius); + cursor: pointer; + display: inline-flex; + padding: var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal); + transition: background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default); + } + +.tabs__item--active { + border-bottom-color: var(--ifm-tabs-color-active-border); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + color: var(--ifm-tabs-color-active); + } + +.tabs__item:hover { + background-color: var(--ifm-hover-overlay); + } + +.tabs--block { + justify-content: stretch; + } + +.tabs--block .tabs__item { + flex-grow: 1; + justify-content: center; + } + +/* Mode */ + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +html[data-theme='dark'] { + --ifm-color-scheme: dark; + + --ifm-color-emphasis-0: var(--ifm-color-gray-1000); + --ifm-color-emphasis-100: var(--ifm-color-gray-900); + --ifm-color-emphasis-200: var(--ifm-color-gray-800); + --ifm-color-emphasis-300: var(--ifm-color-gray-700); + --ifm-color-emphasis-400: var(--ifm-color-gray-600); + --ifm-color-emphasis-500: var(--ifm-color-gray-500); + --ifm-color-emphasis-600: var(--ifm-color-gray-400); + --ifm-color-emphasis-700: var(--ifm-color-gray-300); + --ifm-color-emphasis-800: var(--ifm-color-gray-200); + --ifm-color-emphasis-900: var(--ifm-color-gray-100); + --ifm-color-emphasis-1000: var(--ifm-color-gray-0); + + --ifm-background-color: #1b1b1d; + --ifm-background-surface-color: #242526; + + --ifm-hover-overlay: rgba(255, 255, 255, 0.05); + + --ifm-color-content: #e3e3e3; + --ifm-color-content-secondary: rgba(255, 255, 255, 1); + + --ifm-breadcrumb-separator-filter: invert(64%) sepia(11%) saturate(0%) + hue-rotate(149deg) brightness(99%) contrast(95%); + + --ifm-code-background: rgba(255, 255, 255, 0.1); + + --ifm-scrollbar-track-background-color: #444444; + --ifm-scrollbar-thumb-background-color: #686868; + --ifm-scrollbar-thumb-hover-background-color: #7a7a7a; + + --ifm-table-stripe-background: rgba(255, 255, 255, 0.07); + + --ifm-toc-border-color: var(--ifm-color-emphasis-200); + --ifm-color-primary-contrast-background: rgb(16, 36, 69); + --ifm-color-primary-contrast-foreground: rgb(235, 242, 252); + --ifm-color-secondary-contrast-background: rgb(71, 71, 72); + --ifm-color-secondary-contrast-foreground: rgb(253, 253, 254); + --ifm-color-success-contrast-background: rgb(0, 49, 0); + --ifm-color-success-contrast-foreground: rgb(230, 246, 230); + --ifm-color-info-contrast-background: rgb(25, 60, 71); + --ifm-color-info-contrast-foreground: rgb(238, 249, 253); + --ifm-color-warning-contrast-background: rgb(77, 56, 0); + --ifm-color-warning-contrast-foreground: rgb(255, 248, 230); + --ifm-color-danger-contrast-background: rgb(75, 17, 19); + --ifm-color-danger-contrast-foreground: rgb(255, 235, 236) +} + +@media (min-width: 1440px) { + .container { + max-width: var(--ifm-container-width-xl); + } +} + +@media (max-width: 996px) { + .col { + --ifm-col-width: 100%; + flex-basis: var(--ifm-col-width); + margin-left: 0; + } + +.footer { + --ifm-footer-padding-horizontal: 0 +} + + .footer__link-separator { + display: none; + } + + .footer__col { + margin-bottom: calc(var(--ifm-spacing-vertical) * 3); + } + + .footer__link-item { + display: block; + } + +.hero { + padding-left: 0; + padding-right: 0 +} + +.navbar > .container, + .navbar > .container-fluid { + padding: 0 + } + +.navbar__toggle { + display: inherit + } + +.navbar__item { + display: none + } + +.navbar__search-input { + width: 9rem + } + +.pills--block { + flex-direction: column + } + +.tabs--block { + flex-direction: column + } +} + +@media (max-width: 576px) { + .markdown h1:first-child { + --ifm-h1-font-size: 2rem; + } + .markdown > h2 { + --ifm-h2-font-size: 1.5rem; + } + .markdown > h3 { + --ifm-h3-font-size: 1.25rem; + } +} + +@media (pointer: fine) { + .thin-scrollbar { + scrollbar-width: thin; + } + .thin-scrollbar::-webkit-scrollbar { + height: var(--ifm-scrollbar-size); + width: var(--ifm-scrollbar-size); + } + .thin-scrollbar::-webkit-scrollbar-track { + background: var(--ifm-scrollbar-track-background-color); + border-radius: 10px; + } + .thin-scrollbar::-webkit-scrollbar-thumb { + background: var(--ifm-scrollbar-thumb-background-color); + border-radius: 10px; + } + .thin-scrollbar::-webkit-scrollbar-thumb:hover { + background: var(--ifm-scrollbar-thumb-hover-background-color); + } +} + +@media (prefers-reduced-motion: reduce) { + :root { + --ifm-transition-fast: 0ms; + --ifm-transition-slow: 0ms; + } +} + +@media print { + +.table-of-contents { + display: none +} + +.footer { + display: none +} + +.menu { + display: none +} + +.navbar { + display: none +} + +.pagination-nav { + display: none +} + +.tabs { + page-break-inside: avoid +} +} diff --git a/pkgs/jot/lib/resources/styles.css b/pkgs/jot/lib/resources/styles.css new file mode 100644 index 00000000..bba7aecf --- /dev/null +++ b/pkgs/jot/lib/resources/styles.css @@ -0,0 +1,320 @@ +:root { + --doc-sidebar-width: 300px; + --doc-sidebar-hidden-width: 30px; + + --ifm-footer-padding-vertical: var(--ifm-spacing-vertical); + + --search-glasspane-background: rgba(94, 100, 112, 0.7); + --search-model-background: #f1f2f5; +} + +[data-theme=dark]:root { + --ifm-background-color: #1b1b1d; + --ifm-footer-background-color: #2b3137; + --search-glasspane-background: rgba(47, 55, 69, .5); + --search-model-background: var(--ifm-background-color); +} + +body { + display: flex; + flex-direction: column; + min-height: 100%; +} + +.docPage { + display: flex; + width: 100%; +} + +.docSidebarContainer { + border-right: 1px solid var(--ifm-toc-border-color); + -webkit-clip-path: inset(0); + clip-path: inset(0); + display: block; + margin-top: calc(var(--ifm-navbar-height) * -1); + transition: width var(--ifm-transition-fast) ease; + width: var(--doc-sidebar-width); + will-change: width; +} + +.docMainContainer { + flex-grow: 1; + max-width: calc(100% - var(--doc-sidebar-width)); + display: flex; + min-height: 300px; + width: 100%; +} + +.colorModeToggle { + height: 2rem; + width: 2rem; +} + +.toggleButton { + align-items: center; + border-radius: 50%; + display: flex; + height: 100%; + justify-content: center; + transition: background var(--ifm-transition-fast); + width: 100%; +} + +[data-theme=dark] .lightToggleIcon, +[data-theme=light] .darkToggleIcon { + display: none; +} + +.breadcrumbsContainer { + margin-bottom: 0.8rem; + --ifm-breadcrumb-size-multiplier: 0.8; +} + +.breadcrumbHomeIcon { + height: 1.1rem; + position: relative; + top: 1px; + vertical-align: top; + width: 1.1rem; +} + +.sidebarViewport { + height: 100%; + max-height: 100vh; + position: sticky; + top: 0; +} + +.sidebar { + display: flex; + flex-direction: column; + height: 100%; + padding-top: var(--ifm-navbar-height); + width: var(--doc-sidebar-width); +} + +.menu_jmj1 { + padding: 0.5rem 0 0.5rem 0.5rem; + scrollbar-gutter: stable; + flex-grow: 1; +} + +.menu__list-item-collapsible { + flex-wrap: nowrap; +} + +.menu__link { + overflow-x: clip; + text-overflow: ellipsis; + white-space: nowrap; +} + +.docItemCol { + max-width: 75% !important; +} + +.tableOfContents { + max-height: calc(100vh - var(--ifm-navbar-height) - 2rem); + overflow-y: auto; + position: sticky; + top: calc(var(--ifm-navbar-height) + 1rem); +} + +.markdown h1:first-child { + --ifm-h1-font-size: 2.5rem; +} + +.markdown h3 { + border-bottom: 1px solid var(--ifm-toc-border-color); + padding-bottom: 0.3em; + margin-bottom: 20px; +} + +.markdown td p { + margin-bottom: 0; +} + +.markdown td { + vertical-align: top; +} + +td.item-title { + white-space: nowrap; + font-weight: bold; +} + +td.item-docs { + width: 100%; +} + +p.annotations-container { + text-align: start; + margin-bottom: 16px; +} + +.markdown code.annotation { + margin-right: 0.5em; + padding-left: 0.25em; + padding-right: 0.25em; +} + +.markdown>pre { + /* margin-left: 2em; */ + margin-right: 0; +} + +.markdown>pre.declaration { + margin-left: 0; + margin-right: 0; +} + +.markdown pre.declaration code a { + padding: 0; +} + +/* todo: clean up the css here */ +.markdown span.symbol-type { + float: right; + font-size: 14px; + line-height: 2.7em; + text-emphasis: none; + color: #777; +} + +.markdown code a { + color: var(--ifm-color-primary-lighter); + padding: 0 2px; +} + +a.code, +span.code { + font-family: var(--ifm-font-family-monospace); + font-size: var(--ifm-code-font-size); +} + +div.search-glass-pane { + position: fixed; + left: 0; + top: 0; + height: 100vh; + width: 100vw; + + background-color: var(--search-glasspane-background); + transition: opacity 0.2s linear; + + z-index: calc(var(--ifm-z-index-fixed) - 1); +} + +div.search-area { + position: fixed; + top: var(--ifm-navbar-height); + right: 0px; + width: calc(var(--doc-sidebar-width) * 1.6); + background: var(--search-model-background); + z-index: var(--ifm-z-index-fixed); + min-height: 100px; + border-radius: 6px; + max-height: 80vh; + display: flex; + flex-direction: column; +} + +.search-area div.search-header { + background: var(--ifm-color-emphasis-200); + min-height: 1em; + border-radius: 6px 6px 0 0; + font-size: 0.8em; + flex-shrink: 0; +} + +.search-area div.search-footer { + background: var(--ifm-color-emphasis-200); + min-height: 1em; + border-radius: 0 0 6px 6px; + text-align: center; + font-size: 0.8em; + flex-shrink: 0; +} + +.search-area ul { + margin: 0; + padding: 0; + list-style: none; + overflow-y: scroll; + flex: 1; +} + +.search-area li { + border-radius: 4px; + box-shadow: var(--ifm-global-shadow-lw) !important; + cursor: pointer; +} + +.search-area li div { + text-overflow: ellipsis; + overflow-x: clip; + white-space: nowrap; +} + +.search-area span.location { + opacity: 0.5; + font-style: italic; + font-size: 0.8em; + margin-left: 0.4em; +} + +.search-area span.type { + float: right; + background-color: var(--ifm-menu-color-background-active); +} + +.search-area div.docs { + font-size: 0.8em; +} + +.search-area li span.match { + color: var(--ifm-color-info); +} + +.search-area li { + transition: background-color 0.1s linear; +} + +.search-area li.selected, +.search-area li:hover { + background-color: var(--ifm-menu-color-background-active); +} + +.badge { + border-radius: 1rem; +} + +.badge--secondary { + color: var(--ifm-color-secondary-contrast-background); +} + +/* have a denser TOC */ +.menu__list-item:not(:first-child) { + margin-top: 0; +} + +li.menu__list-item.group { + border-bottom: 1px solid var(--ifm-toc-border-color); + margin-top: 20px; + font-size: 1.2em; + font-weight: bold; +} + +.table-of-contents { + padding: 0; + padding-left: var(--ifm-toc-padding-horizontal); +} + +.table-of-contents li { + white-space: nowrap; +} + +.table-of-contents__link { + overflow-x: hidden; + text-overflow: ellipsis; +} diff --git a/pkgs/jot/lib/resources/toggle-dark.svg b/pkgs/jot/lib/resources/toggle-dark.svg new file mode 100644 index 00000000..2c81ed68 --- /dev/null +++ b/pkgs/jot/lib/resources/toggle-dark.svg @@ -0,0 +1,6 @@ + + + + diff --git a/pkgs/jot/lib/resources/toggle-light.svg b/pkgs/jot/lib/resources/toggle-light.svg new file mode 100644 index 00000000..9f94259b --- /dev/null +++ b/pkgs/jot/lib/resources/toggle-light.svg @@ -0,0 +1,6 @@ + + + + diff --git a/pkgs/jot/lib/src/analysis.dart b/pkgs/jot/lib/src/analysis.dart new file mode 100644 index 00000000..a32bd8e9 --- /dev/null +++ b/pkgs/jot/lib/src/analysis.dart @@ -0,0 +1,143 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/analysis/analysis_context.dart'; +import 'package:analyzer/dart/analysis/analysis_context_collection.dart'; +import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/file_system/file_system.dart'; +import 'package:analyzer/file_system/physical_file_system.dart'; +import 'package:path/path.dart' as p; + +class Analyzer { + late AnalysisContextCollection _collection; + late ResourceProvider resourceProvider; + + int _lastCheckedMillis = DateTime.now().millisecondsSinceEpoch; + + /// Create an analysis context using the given paths. + /// + /// Note that all paths must the absolute. These are assumed to the paths to + /// packages; for these packages, only the code in `lib/` will be analyzed. + Analyzer.packages({ + required List includedPaths, + ResourceProvider? resourceProvider, + }) { + this.resourceProvider = + resourceProvider ?? PhysicalResourceProvider.INSTANCE; + + _collection = AnalysisContextCollection( + includedPaths: [...includedPaths.map((path) => p.join(path, 'lib'))], + resourceProvider: this.resourceProvider, + ); + } + + AnalysisContext get context => _collection.contexts.first; + + AnalysisContext contextFor(String path) { + return _collection.contextFor(path); + } + + Stream resolvedPublicLibraries() async* { + for (var file in _publicFiles) { + var lib = + await context.currentSession.getResolvedLibrary(file.path) + as ResolvedLibraryResult; + + // TODO: Filter out parts? + + yield lib; + } + } + + Stream resolvedLibrariesFor(String path) async* { + var context = contextFor(path); + + for (var file in context.publicFiles) { + var lib = + await context.currentSession.getResolvedLibrary(file.path) + as ResolvedLibraryResult; + + // TODO: Filter out parts? + + yield lib; + } + } + + /// Check for any changed files and reanalyze changes. + /// + /// Returns `true` if any changed files had been detected. + Future reanalyzeChanges() async { + var hasChanges = false; + + var context = _collection.contexts.first; + + final currentMillis = DateTime.now().millisecondsSinceEpoch; + + for (var path in context.contextRoot.analyzedFiles().where( + (path) => path.endsWith('.dart'), + )) { + var modificationStamp = context.contextRoot.resourceProvider + .getFile(path) + .modificationStamp; + + if (modificationStamp > _lastCheckedMillis) { + hasChanges = true; + context.changeFile(path); + } + } + + _lastCheckedMillis = currentMillis; + + await context.applyPendingFileChanges(); + + return hasChanges; + } + + Iterable get _publicFiles sync* { + for (var context in _collection.contexts) { + var root = context.contextRoot; + var src = root.root.getChildAssumingFolder('src'); + + var dartFiles = + context.contextRoot + .analyzedFiles() + .where((path) => path.endsWith('.dart')) + .toList() + ..sort(); + + for (var path in dartFiles) { + if (src.contains(path)) continue; + // TODO: Ignore files whose names starts with '_'? + + yield root.resourceProvider.getFile(path); + } + } + } + + Future getLibraryByUri(String uri) async { + var result = await context.currentSession.getLibraryByUri(uri); + return result as LibraryElementResult; + } +} + +extension AnalysisContextExtension on AnalysisContext { + Iterable get publicFiles sync* { + var root = contextRoot; + var src = root.root.getChildAssumingFolder('src'); + + var dartFiles = + contextRoot + .analyzedFiles() + .where((path) => path.endsWith('.dart')) + .toList() + ..sort(); + + for (var path in dartFiles) { + if (src.contains(path)) continue; + // TODO: Ignore files whose names starts with '_' ? + + yield root.resourceProvider.getFile(path); + } + } +} diff --git a/pkgs/jot/lib/src/display.dart b/pkgs/jot/lib/src/display.dart new file mode 100644 index 00000000..f1af5343 --- /dev/null +++ b/pkgs/jot/lib/src/display.dart @@ -0,0 +1,591 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// ignore_for_file: implementation_imports + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/nullability_suffix.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/type.dart'; +import 'package:analyzer/src/dart/element/type_algebra.dart'; + +import '../api.dart'; + +/// A class that builds a "display string" for [Element]s and [DartType]s. +class ElementDisplayStringBuilder { + final LinkedText linkedText; + + /// Whether to allow a display string to be written in multiple lines. + final bool _multiline; + + ElementDisplayStringBuilder(this.linkedText, {bool multiline = false}) + : _multiline = multiline; + + @override + String toString() => linkedText.toString(); + + void writeAbstractElement(Element element) { + _write(element.name ?? ''); + } + + void writeClassElement(ClassElement element) { + if (element.isAugmentation) { + _write('augment '); + } + + if (element.isSealed) { + _write('sealed '); + } else if (element.isAbstract) { + _write('abstract '); + } + if (element.isBase && element.isMixinClass) { + _write('base '); + } else if (element.isInterface) { + _write('interface '); + } else if (element.isFinal) { + _write('final '); + } + if (element.isMixinClass) { + _write('mixin '); + } + + _write('class '); + _write(element.displayName); + + _writeTypeParameters(element.typeParameters); + + _writeTypeIfNotObject(' extends ', element.supertype); + _writeTypesIfNotEmpty(' with ', element.mixins); + _writeTypesIfNotEmpty(' implements ', element.interfaces); + } + + void writeCompilationUnitElement(CompilationUnitElement element) { + var path = element.source.fullName; + _write(path); + } + + void writeConstructorElement(ConstructorElement element) { + // Note: this is commented out as otherwise the code won't parse. + + // _writeType(element.returnType); + // _write(' '); + + _write(element.displayName); + + _writeFormalParameters( + element.parameters, + forElement: true, + allowMultiline: true, + ); + } + + void writeDynamicType() { + _write('dynamic'); + } + + void writeEnumElement(EnumElement element) { + _write('enum '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _writeTypesIfNotEmpty(' with ', element.mixins); + _writeTypesIfNotEmpty(' implements ', element.interfaces); + } + + void writeExecutableElement(ExecutableElement element, String name) { + if (element.isAugmentation) { + _write('augment '); + } + + if (element.kind != ElementKind.SETTER) { + _writeType(element.returnType); + _write(' '); + } + + if (element.kind == ElementKind.GETTER) { + _write('get '); + } + + if (element.kind == ElementKind.SETTER) { + _write('set '); + } + + if (element.isOperator) { + _write('operator'); + } + + _write(name); + + if (element.kind != ElementKind.GETTER) { + _writeTypeParameters(element.typeParameters); + _writeFormalParameters( + element.parameters, + forElement: true, + allowMultiline: true, + ); + } + } + + void writeExportElement(LibraryExportElement element) { + _write('export '); + _writeDirectiveUri(element.uri); + } + + void writeExtensionElement(ExtensionElement element) { + _write('extension '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _write(' on '); + _writeType(element.extendedType); + } + + // ignore: experimental_member_use + void writeExtensionTypeElement(ExtensionTypeElement element) { + _write('extension type '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _write('._'); + _writeFormalParameters( + element.primaryConstructor.parameters, + forElement: true, + allowMultiline: true, + ); + _writeTypesIfNotEmpty(' implements ', element.interfaces); + } + + void writeFormalParameter(ParameterElement element) { + if (element.isRequiredPositional) { + _writeWithoutDelimiters(element, forElement: true); + } else if (element.isOptionalPositional) { + _write('['); + _writeWithoutDelimiters(element, forElement: true); + _write(']'); + } else if (element.isNamed) { + _write('{'); + _writeWithoutDelimiters(element, forElement: true); + _write('}'); + } + } + + void writeFunctionType(FunctionType type) { + type = _uniqueTypeParameters(type); + + _writeType(type.returnType); + _write(' Function'); + _writeTypeParameters(type.typeFormals); + _writeFormalParameters(type.parameters, forElement: false); + _writeNullability(type.nullabilitySuffix); + } + + void writeGenericFunctionTypeElement(GenericFunctionTypeElement element) { + _writeType(element.returnType); + _write(' Function'); + _writeTypeParameters(element.typeParameters); + _writeFormalParameters(element.parameters, forElement: true); + } + + void writeImportElement(LibraryImportElement element) { + _write('import '); + _writeDirectiveUri(element.uri); + } + + void writeInterfaceType(InterfaceType type) { + // Note: make sure we write types through the linked writer. + _writeElement(type.element.name, type.element); + + _writeTypeArguments(type.typeArguments); + _writeNullability(type.nullabilitySuffix); + } + + void writeInvalidType() { + _write('InvalidType'); + } + + void writeLibraryElement(LibraryElement element) { + _write('library '); + _write('${element.source.uri}'); + } + + void writeMixinElement(MixinElement element) { + if (element.isAugmentation) { + _write('augment '); + } + if (element.isBase) { + _write('base '); + } + _write('mixin '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _writeTypesIfNotEmpty(' on ', element.superclassConstraints); + _writeTypesIfNotEmpty(' implements ', element.interfaces); + } + + void writeNeverType(NeverType type) { + _write('Never'); + _writeNullability(type.nullabilitySuffix); + } + + void writePartElement(PartElement element) { + _write('part '); + _writeDirectiveUri(element.uri); + } + + void writePrefixElement(PrefixElement element) { + _write('as '); + _write(element.displayName); + } + + void writeRecordType(RecordType type) { + final positionalFields = type.positionalFields; + final namedFields = type.namedFields; + final fieldCount = positionalFields.length + namedFields.length; + _write('('); + + var index = 0; + for (final field in positionalFields) { + _writeType(field.type); + if (index++ < fieldCount - 1) { + _write(', '); + } + } + + if (namedFields.isNotEmpty) { + _write('{'); + for (final field in namedFields) { + _writeType(field.type); + _write(' '); + _write(field.name); + if (index++ < fieldCount - 1) { + _write(', '); + } + } + _write('}'); + } + + // Add trailing comma for record types with only one position field. + if (positionalFields.length == 1 && namedFields.isEmpty) { + _write(','); + } + + _write(')'); + _writeNullability(type.nullabilitySuffix); + } + + void writeTypeAliasElement(TypeAliasElement element) { + _write('typedef '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _write(' = '); + + var aliasedElement = element.aliasedElement; + + if (aliasedElement != null) { + appendTypeImplTo(element.aliasedType as TypeImpl); + } else { + _writeType(element.aliasedType); + } + } + + void writeTypeParameter(TypeParameterElement element) { + // Note: This is commented out as using 'in' and 'out' when declaring type + // parameters won't parse correctly. + + // if (element is TypeParameterElementImpl) { + // var variance = element.variance; + // if (!element.isLegacyCovariant && variance != Variance.unrelated) { + // _write(variance.toKeywordString()); + // _write(' '); + // } + // } + + _write(element.displayName); + + var bound = element.bound; + if (bound != null) { + _write(' extends '); + _writeType(bound); + } + } + + void writeTypeParameterType(TypeParameterType type) { + _write(type.element.displayName); + _writeNullability(type.nullabilitySuffix); + } + + void writeUnknownInferredType() { + _write('_'); + } + + void writeVariableElement(VariableElement element) { + switch (element) { + case FieldElement(isAugmentation: true): + case TopLevelVariableElement(isAugmentation: true): + _write('augment '); + } + + _writeType(element.type); + _write(' '); + _write(element.displayName); + } + + void writeVoidType() { + _write('void'); + } + + void _write(String str) { + linkedText.write(str); + } + + void _writeElement(String str, Element element) { + linkedText.writeElement(str, element); + } + + void _writeDirectiveUri(DirectiveUri uri) { + if (uri is DirectiveUriWithUnit) { + _write('unit ${uri.unit.source.uri}'); + } else if (uri is DirectiveUriWithSource) { + _write('source ${uri.source}'); + } else { + _write(''); + } + } + + void _writeFormalParameters( + List parameters, { + required bool forElement, + bool allowMultiline = false, + }) { + var startLength = linkedText.toString().length; + + // Assume the display string looks better wrapped when there are at least + // three parameters. This avoids having to pre-compute the single-line + // version and know the length of the function name/return type. + var multiline = allowMultiline && _multiline && parameters.length >= 3; + + // The prefix for open groups is included in separator for single-line but + // not for multline so must be added explicitly. + var openGroupPrefix = multiline ? ' ' : ''; + var separator = multiline ? ',' : ', '; + // var trailingComma = multiline ? ',\n' : ''; + var parameterPrefix = multiline ? '\n ' : ''; + + _write('('); + + _WriteFormalParameterKind? lastKind; + var lastClose = ''; + + void openGroup(_WriteFormalParameterKind kind, String open, String close) { + if (lastKind != kind) { + _write(lastClose); + if (lastKind != null) { + // We only need to include the space before the open group if there + // was a previous parameter, otherwise it goes immediately after the + // open paren. + _write(openGroupPrefix); + } + _write(open); + lastKind = kind; + lastClose = close; + } + } + + for (var i = 0; i < parameters.length; i++) { + if (i != 0) { + _write(separator); + } + + var parameter = parameters[i]; + if (parameter.isRequiredPositional) { + openGroup(_WriteFormalParameterKind.requiredPositional, '', ''); + } else if (parameter.isOptionalPositional) { + openGroup(_WriteFormalParameterKind.optionalPositional, '[', ']'); + } else if (parameter.isNamed) { + openGroup(_WriteFormalParameterKind.named, '{', '}'); + } + _write(parameterPrefix); + _writeWithoutDelimiters(parameter, forElement: forElement); + } + + var textLength = linkedText.toString().length - startLength; + if (textLength >= 58 && parameters.length > 1) { + _write(','); + } + // _write(trailingComma); + _write(lastClose); + _write(')'); + } + + void _writeNullability(NullabilitySuffix nullabilitySuffix) { + switch (nullabilitySuffix) { + case NullabilitySuffix.question: + _write('?'); + break; + case NullabilitySuffix.star: + _write('*'); + break; + case NullabilitySuffix.none: + break; + } + } + + void _writeType(DartType type) { + appendTypeImplTo(type as TypeImpl); + } + + void _writeTypeArguments(List typeArguments) { + if (typeArguments.isEmpty) { + return; + } + + _write('<'); + for (var i = 0; i < typeArguments.length; i++) { + if (i != 0) { + _write(', '); + } + appendTypeImplTo(typeArguments[i] as TypeImpl); + } + _write('>'); + } + + void _writeTypeIfNotObject(String prefix, DartType? type) { + if (type != null && !type.isDartCoreObject) { + _write(prefix); + _writeType(type); + } + } + + void _writeTypeParameters(List elements) { + if (elements.isEmpty) return; + + _write('<'); + for (var i = 0; i < elements.length; i++) { + if (i != 0) { + _write(', '); + } + // (elements[i] as TypeParameterElementImpl).appendTo(this); + writeTypeParameter(elements[i]); + } + _write('>'); + } + + void _writeTypes(List types) { + for (var i = 0; i < types.length; i++) { + if (i != 0) { + _write(', '); + } + _writeType(types[i]); + } + } + + void _writeTypesIfNotEmpty(String prefix, List types) { + if (types.isNotEmpty) { + _write(prefix); + _writeTypes(types); + } + } + + void _writeWithoutDelimiters( + ParameterElement element, { + required bool forElement, + }) { + if (element.isRequiredNamed) { + _write('required '); + } + + _writeType(element.type); + + if (forElement || element.isNamed) { + _write(' '); + _write(element.displayName); + } + + if (forElement) { + var defaultValueCode = element.defaultValueCode; + if (defaultValueCode != null) { + _write(' = '); + _write(defaultValueCode); + } + } + } + + static FunctionType _uniqueTypeParameters(FunctionType type) { + if (type.typeFormals.isEmpty) { + return type; + } + + var referencedTypeParameters = {}; + + void collectTypeParameters(DartType? type) { + if (type is TypeParameterType) { + referencedTypeParameters.add(type.element); + } else if (type is FunctionType) { + for (var typeParameter in type.typeFormals) { + collectTypeParameters(typeParameter.bound); + } + for (var parameter in type.parameters) { + collectTypeParameters(parameter.type); + } + collectTypeParameters(type.returnType); + } else if (type is InterfaceType) { + for (var typeArgument in type.typeArguments) { + collectTypeParameters(typeArgument); + } + } + } + + collectTypeParameters(type); + referencedTypeParameters.removeAll(type.typeFormals); + + var namesToAvoid = {}; + for (var typeParameter in referencedTypeParameters) { + namesToAvoid.add(typeParameter.displayName); + } + + var newTypeParameters = []; + for (var typeParameter in type.typeFormals) { + var name = typeParameter.name; + for (var counter = 0; !namesToAvoid.add(name); counter++) { + const unicodeSubscriptZero = 0x2080; + const unicodeZero = 0x30; + + var subscript = String.fromCharCodes( + '$counter'.codeUnits.map((n) { + return unicodeSubscriptZero + (n - unicodeZero); + }), + ); + + name = typeParameter.name + subscript; + } + + var newTypeParameter = TypeParameterElementImpl(name, -1); + newTypeParameter.bound = typeParameter.bound; + newTypeParameters.add(newTypeParameter); + } + + return replaceTypeParameters(type as FunctionTypeImpl, newTypeParameters); + } + + void appendTypeImplTo(DartType type) { + // handle all the types + if (type is DynamicType) { + writeDynamicType(); + } else if (type is FunctionType) { + writeFunctionType(type); + } else if (type is InterfaceType) { + writeInterfaceType(type); + } else if (type is NeverType) { + writeNeverType(type); + } else if (type is RecordType) { + writeRecordType(type); + } else if (type is TypeParameterType) { + writeTypeParameterType(type); + } else if (type is VoidType) { + writeVoidType(); + } else { + throw StateError('unhandled type: $type'); + } + } +} + +enum _WriteFormalParameterKind { requiredPositional, optionalPositional, named } diff --git a/pkgs/jot/lib/src/formatting.dart b/pkgs/jot/lib/src/formatting.dart new file mode 100644 index 00000000..e7d28421 --- /dev/null +++ b/pkgs/jot/lib/src/formatting.dart @@ -0,0 +1,96 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:dart_style/dart_style.dart'; + +class DartFormat { + // TODO: if there are any formatting failures, return the input string + static String asFunction(String str) { + return _dartFormat(str, '{}'); + } + + static String asConstructor( + String str, { + required String className, + bool isConst = false, + }) { + return _dartFormat( + str, + isConst ? ';' : '{}', + prefix: 'class $className {', + suffix: '}', + trimIndent: true, + ); + } + + static String asMethod(String str) { + return _dartFormat( + str, + '{}', + prefix: 'class Foo {', + suffix: '}', + trimIndent: true, + ); + } + + static String asField(String str) { + return _dartFormat( + str, + ';', + prefix: 'class Foo {', + suffix: '}', + trimIndent: true, + ); + } + + static String asTypeAlias(String str) { + return _dartFormat(str, ';'); + } + + static String asClass(String str) { + return _dartFormat(str, ' {}'); + } + + static String asEnum(String str) { + return _dartFormat(str, ' { foo }'); + } + + static String _dartFormat( + String fragment, + String formattingSuffix, { + String? prefix, + String? suffix, + bool trimIndent = false, + }) { + var source = + ''' +${prefix ?? ''} +// cut 1 +$fragment$formattingSuffix +// cut 2 +${suffix ?? ''} +'''; + final formatter = DartFormatter(); + source = formatter.format(source); + source = source.substring( + source.indexOf('// cut 1') + '// cut 1'.length, + source.indexOf('// cut 2'), + ); + source = source.trim(); + if (source.endsWith(formattingSuffix)) { + source = source.substring(0, source.length - formattingSuffix.length); + } + + if (trimIndent) { + source = source + .split('\n') + .map((line) => line.startsWith(' ') ? line.substring(2) : line) + .join('\n'); + } + + source = source.trimRight(); + + return source; + } +} diff --git a/pkgs/jot/lib/src/generate.dart b/pkgs/jot/lib/src/generate.dart new file mode 100644 index 00000000..4335cce5 --- /dev/null +++ b/pkgs/jot/lib/src/generate.dart @@ -0,0 +1,588 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// ignore_for_file: lines_longer_than_80_chars + +import 'dart:io'; + +import 'package:cli_util/cli_logging.dart'; +import 'package:path/path.dart' as p; + +import '../api.dart'; +import '../workspace.dart'; +import 'markdown.dart'; +import 'render.dart'; +import 'utils.dart'; + +class Generator { + final Workspace workspace; + final Directory outDir; + final Logger logger; + final Stats? stats; + + Generator({ + required this.workspace, + required this.outDir, + required this.logger, + this.stats, + }); + + Future generate() async { + // write out the static resources + await workspace.htmlTemplate.generateStaticResources(outDir, stats: stats); + + // mainFile + if (workspace.mainFile != null) { + await _generateFile(workspace.mainFile!); + } + + // navFiles + for (var navElement in workspace.navFiles) { + await _generateFile(navElement, printProgress: false); + } + + // children + for (var child in workspace.children) { + if (child is WorkspaceSeparator) { + // nothing to generate + } else if (child is WorkspaceFile) { + await _generateFile(child, printProgress: !child.isMarkdown); + } else if (child is WorkspaceDirectory) { + await _generateContainer(child); + } else { + throw StateError('unexpected type: $child'); + } + } + + // left nav data file + var navFile = File(p.join(outDir.path, '_resources', 'nav.json')); + navFile.writeAsStringSync(workspace.generateNavData()); + stats?.genFile(navFile); + + // search index file + var indexFile = File(p.join(outDir.path, '_resources', 'index.json')); + indexFile.writeAsStringSync(workspace.api.index.toJson()); + stats?.genFile(indexFile); + } + + Future _generateContainer(WorkspaceDirectory container) async { + // mainFile + // todo: always generate an index file + if (container.mainFile != null) { + await _generateFile(container.mainFile!); + } + + // children + for (var child in container.children) { + if (child is WorkspaceSeparator) { + // nothing to generate + } else if (child is WorkspaceFile) { + await _generateFile(child, printProgress: false); + } else if (child is WorkspaceDirectory) { + await _generateContainer(child); + } else { + throw StateError('unexpected type: $child'); + } + } + } + + Future _generateFile( + WorkspaceFile file, { + bool printProgress = true, + }) async { + var pageContents = await file.generatePageContents(); + var fileContents = await workspace.generateWorkspacePage( + file, + pageContents, + ); + var outFile = File(p.join(outDir.path, file.path)); + outFile.parent.createSync(recursive: true); + outFile.writeAsStringSync(fileContents); + + stats?.genFile(outFile); + + if (printProgress) logger.stdout(' ${p.relative(outFile.path)}'); + } +} + +FileContentGenerator libraryGenerator(LibraryItemContainer library) { + return (Workspace workspace, WorkspaceFile thisFile) async { + return _LibraryGenerator( + library: library, + workspace: workspace, + thisFile: thisFile, + ).generate(); + }; +} + +FileContentGenerator itemsGenerator(Items items) { + if (items is InterfaceElementItems) { + return (Workspace workspace, WorkspaceFile thisFile) async { + return _InterfaceElementGenerator( + classItems: items, + workspace: workspace, + thisFile: thisFile, + ).generate(); + }; + } else if (items is ExtensionElementItems) { + return (Workspace workspace, WorkspaceFile thisFile) async { + return _ExtentionElementGenerator( + extensionItems: items, + workspace: workspace, + thisFile: thisFile, + ).generate(); + }; + } else { + throw StateError('unhandled type: $items'); + } +} + +class _LibraryGenerator { + final LibraryItemContainer library; + final Workspace workspace; + final WorkspaceFile thisFile; + + _LibraryGenerator({ + required this.library, + required this.workspace, + required this.thisFile, + }); + + GenerationResults generate() { + var api = workspace.api; + var linkedCodeRenderer = LinkedCodeRenderer(api.resolver, thisFile); + + var buf = StringBuffer(); + + if (thisFile.importScript != null) { + buf.writeln('

${thisFile.name}

'); + buf.writeln( + '
'
+        "import '${thisFile.importScript}';"
+        '
', + ); + } else { + buf.writeln('

${thisFile.name}

'); + } + + if (library.docs != null) { + // todo: also support compound references - Class.field, Class.method + buf.writeln( + convertMarkdown( + library.docs!, + linkResolver: library.markdownLinkResolver(api.resolver), + ), + ); + } + + var pageItemRenderer = OutlineRenderer(); + + if (library.exports.isNotEmpty) { + buf.writeln('

Exports

'); + + for (var entry in library.exportsByLibrary.entries) { + var library = entry.key; + var exports = entry.value; + + buf.writeln(''); + buf.write(''); + + var itemsByGroup = Items.itemsByGroup(exports); + + for (var entry in itemsByGroup.entries) { + var groupType = entry.key; + var items = entry.value; + + buf.write(''); + buf.write(''); + buf.write(''); + buf.writeln(''); + } + + buf.writeln('
'); + buf.write('Exports from ${library.urlName}'); + buf.writeln('
${groupType.title}'); + buf.writeln( + items + .map((item) { + var ref = api.hrefOrSpan( + pageItemRenderer.render(item.type, item), + item.element, + from: thisFile, + ); + return '$ref'; + }) + .join(',\n'), + ); + buf.write('
'); + } + } + + for (var group in library.groups.values) { + buf.writeln('

${group.name}

'); + + if (group.containerType) { + buf.writeln(''); + + for (var item in group.items) { + buf.write(''); + buf.write(''); + } + + buf.writeln('
'); + buf.writeln( + api.hrefOrSpan( + pageItemRenderer.render(group.type, item), + item.element, + from: thisFile, + ), + ); + buf.write(''); + if (item.docs != null) { + buf.writeln( + convertMarkdown( + firstSentence(item.docs!), + linkResolver: item.markdownLinkResolver(api.resolver), + ), + ); + } + buf.write('
'); + } else { + for (var item in group.items) { + buf.writeln( + '

${pageItemRenderer.render(group.type, item)}' + '${item.element.kind.displayName}' + '

', + ); + buf.write(writeAnnotations(item)); + buf.writeln(linkedCodeRenderer.render(group.type, item)); + if (item.docs != null) { + buf.writeln( + convertMarkdown( + item.docs!, + linkResolver: item.markdownLinkResolver(api.resolver), + ), + ); + } + } + } + } + + var outline = Outline(); + var outlineRenderer = OutlineRenderer(); + + if (library.exports.isNotEmpty) { + outline.add(Heading('Exports', id: '_Exports', level: 2)); + } + + for (var group in library.groups.values) { + outline.add(Heading(group.name, id: group.anchorId, level: 2)); + + if (!group.containerType) { + for (var item in group.items) { + outline.add( + Heading( + outlineRenderer.render(group.type, item), + id: item.anchorId, + level: 3, + ), + ); + } + } + } + + return GenerationResults(buf.toString(), outline); + } +} + +class _InterfaceElementGenerator { + final InterfaceElementItems classItems; + final Workspace workspace; + final WorkspaceFile thisFile; + + _InterfaceElementGenerator({ + required this.classItems, + required this.workspace, + required this.thisFile, + }); + + GenerationResults generate() { + var api = workspace.api; + + var linkedCodeRenderer = LinkedCodeRenderer(api.resolver, thisFile); + + var buf = StringBuffer(); + buf.writeln('

${classItems.name}

'); + buf.write(writeAnnotations(classItems)); + buf.writeln(linkedCodeRenderer.render(classItems.type, classItems)); + writeAncestors(buf); + _writeChildRelationships( + buf, + classItems.relationships, + thisFile, + workspace.api, + ); + if (classItems.docs != null) { + buf.writeln( + convertMarkdown( + classItems.docs!, + linkResolver: classItems.markdownLinkResolver(api.resolver), + ), + ); + } + + var pageItemRenderer = OutlineRenderer(); + + for (var group in classItems.groups.values) { + buf.writeln('

${group.name}

'); + + if (group.type == GroupType.enumValue) { + // For enums, add a 'values' table. + buf.writeln(''); + + // todo: also include information about the enum's value + + for (var item in group.items) { + buf.write(''); + buf.writeln(''); + buf.write(''); + } + + buf.writeln('
${item.name}'); + if (item.docs != null) { + buf.writeln( + convertMarkdown( + item.docs!, + linkResolver: item.markdownLinkResolver(api.resolver), + ), + ); + } + buf.write('
'); + } else { + for (var item in group.items) { + buf.writeln( + '

${pageItemRenderer.render(group.type, item)}' + '${item.element.kind.displayName}' + '

', + ); + buf.write(writeAnnotations(item)); + buf.writeln(linkedCodeRenderer.render(group.type, item)); + if (item.docs != null) { + buf.writeln( + convertMarkdown( + item.docs!, + linkResolver: item.markdownLinkResolver(api.resolver), + ), + ); + } + } + } + } + + var outline = Outline(); + var outlineRenderer = OutlineRenderer(); + + for (var group in classItems.groups.values) { + outline.add(Heading(group.name, id: group.anchorId, level: 2)); + + if (group.type != GroupType.enumValue) { + for (var item in group.items) { + outline.add( + Heading( + outlineRenderer.render(group.type, item), + id: item.anchorId, + level: 3, + ), + ); + } + } + } + + return GenerationResults(buf.toString(), outline); + } + + void writeAncestors(StringBuffer out) { + var buf = StringBuffer(); + final api = workspace.api; + + var element = classItems.element; + var superElement = element.supertype?.element; + if (superElement != null) { + buf.writeln('Extends'); + buf.write(''); + var ref = api.hrefOrSpan(superElement.name, superElement, from: thisFile); + buf.write('$ref'); + } + + if (element.interfaces.isNotEmpty) { + buf.writeln('Implements'); + buf.write(''); + buf.write( + element.interfaces + .map( + (i) => api.hrefOrSpan(i.element.name, i.element, from: thisFile), + ) + .map((s) => '$s') + .join(', '), + ); + buf.write(''); + } + + if (element.mixins.isNotEmpty) { + buf.writeln('Mixins'); + buf.write(''); + buf.write( + element.mixins + .map( + (m) => api.hrefOrSpan(m.element.name, m.element, from: thisFile), + ) + .map((s) => '$s') + .join(', '), + ); + buf.write(''); + } + + if (buf.isNotEmpty) { + out.writeln(''); + out.write(buf.toString()); + out.writeln('
'); + } + } +} + +class _ExtentionElementGenerator { + final ExtensionElementItems extensionItems; + final Workspace workspace; + final WorkspaceFile thisFile; + + _ExtentionElementGenerator({ + required this.extensionItems, + required this.workspace, + required this.thisFile, + }); + + GenerationResults generate() { + var api = workspace.api; + + var linkedCodeRenderer = LinkedCodeRenderer(api.resolver, thisFile); + + var buf = StringBuffer(); + buf.writeln('

${extensionItems.name}

'); + buf.write(writeAnnotations(extensionItems)); + buf.writeln(linkedCodeRenderer.render(extensionItems.type, extensionItems)); + writeAncestors(buf); + _writeChildRelationships( + buf, + extensionItems.relationships, + thisFile, + workspace.api, + ); + if (extensionItems.docs != null) { + buf.writeln( + convertMarkdown( + extensionItems.docs!, + linkResolver: extensionItems.markdownLinkResolver(api.resolver), + ), + ); + } + + var pageItemRenderer = OutlineRenderer(); + + for (var group in extensionItems.groups.values) { + buf.writeln('

${group.name}

'); + + for (var item in group.items) { + buf.writeln( + '

${pageItemRenderer.render(group.type, item)}' + '${item.element.kind.displayName}' + '

', + ); + buf.write(writeAnnotations(item)); + buf.writeln(linkedCodeRenderer.render(group.type, item)); + if (item.docs != null) { + buf.writeln( + convertMarkdown( + item.docs!, + linkResolver: item.markdownLinkResolver(api.resolver), + ), + ); + } + } + } + + var outline = Outline(); + var outlineRenderer = OutlineRenderer(); + + for (var group in extensionItems.groups.values) { + outline.add(Heading(group.name, id: group.anchorId, level: 2)); + + for (var item in group.items) { + outline.add( + Heading( + outlineRenderer.render(group.type, item), + id: item.anchorId, + level: 3, + ), + ); + } + } + + return GenerationResults(buf.toString(), outline); + } + + void writeAncestors(StringBuffer out) { + var buf = StringBuffer(); + final api = workspace.api; + + var element = extensionItems.asExtension; + var extendedElement = element.extendedType.element; + if (extendedElement != null && extendedElement.name != null) { + buf.writeln('Extension on'); + buf.write(''); + var ref = api.hrefOrSpan( + extendedElement.name!, + extendedElement, + from: thisFile, + ); + buf.write('$ref'); + } + + if (buf.isNotEmpty) { + out.writeln(''); + out.write(buf.toString()); + out.writeln('
'); + } + } +} + +void _writeChildRelationships( + StringBuffer buf, + RelationshipMap relationships, + WorkspaceFile thisFile, + Api api, +) { + if (relationships.isEmpty) return; + + buf.writeln(''); + + for (var kind in relationships.keys) { + buf.write(''); + buf.write(''); + + buf.write(''); + } + + buf.writeln('
${kind.title}'); + var items = relationships[kind]!; + items.sort((a, b) => adjustedLexicalCompare(a.name, b.name)); + buf.write( + items + .map((item) { + var ref = api.hrefOrSpan(item.name, item.element, from: thisFile); + return '$ref'; + }) + .join(', '), + ); + buf.writeln('
'); +} diff --git a/pkgs/jot/lib/src/html.dart b/pkgs/jot/lib/src/html.dart new file mode 100644 index 00000000..d82139cb --- /dev/null +++ b/pkgs/jot/lib/src/html.dart @@ -0,0 +1,129 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; +import 'dart:isolate'; +import 'dart:typed_data'; + +import 'package:path/path.dart' as p; + +import 'utils.dart'; + +class HtmlTemplate { + static Future createDefault() async { + final htmlData = await loadResourceDataAsString('index.html'); + return HtmlTemplate._(htmlData); + } + + final String htmlTemplateData; + + HtmlTemplate._(this.htmlTemplateData) { + _parseTemplate(); + } + + Future generateStaticResources(Directory outDir, {Stats? stats}) async { + const resources = [ + 'script.js', + 'styles.css', + 'styles-dark.css', + 'styles-light.css', + 'toggle-dark.svg', + 'toggle-light.svg', + ]; + + for (var resource in resources) { + final file = File(p.join(outDir.path, '_resources', resource)); + if (!file.parent.existsSync()) { + file.parent.createSync(recursive: true); + } + var data = await loadResourceDataAsBytes(resource); + file.writeAsBytesSync(data); + stats?.genFile(file); + } + } + + String templateSubtitute({ + required String pageTitle, + required String pathPrefix, + required String pageRef, + String navbar = '', + String breadcrumbs = '', + String pageContent = '', + String toc = '', + String footer = '', + }) { + final subs = { + 'page-title': pageTitle, + 'prefix': pathPrefix, + 'pageRef': pageRef, + 'navbar': navbar, + 'breadcrumbs': breadcrumbs, + 'page-content': pageContent, + 'toc': toc, + 'footer': footer, + }; + + var results = _generateString(subs); + + return results; + } + + late final List<_Location> _locations; + + void _parseTemplate() { + final regex = RegExp(r'{{\s+([\w-]+)\s+}}'); + + var results = <_Location>[]; + + for (var match in regex.allMatches(htmlTemplateData)) { + results.add(_Location(match.start, match.end, match.group(1)!)); + } + + _locations = results.toList(); + } + + String _generateString(Map subs) { + var buf = StringBuffer(); + var offset = 0; + + for (var loc in _locations) { + if (offset < loc.start) { + buf.write(htmlTemplateData.substring(offset, loc.start)); + offset = loc.start; + } + + buf.write(subs[loc.id]!); + offset = loc.end; + } + + if (offset < htmlTemplateData.length) { + buf.write(htmlTemplateData.substring(offset)); + } + + return buf.toString(); + } +} + +class _Location { + final int start; + final int end; + final String id; + + _Location(this.start, this.end, this.id); + + @override + String toString() => '$id $start $end'; +} + +Future loadResourceDataAsString(String name) async { + var packageUri = Uri.parse('package:jot/resources/$name'); + var fileUri = await Isolate.resolvePackageUri(packageUri); + return File(fileUri!.toFilePath()).readAsStringSync(); +} + +Future loadResourceDataAsBytes(String name) async { + var packageUri = Uri.parse('package:jot/resources/$name'); + var fileUri = await Isolate.resolvePackageUri(packageUri); + return File(fileUri!.toFilePath()).readAsBytesSync(); +} diff --git a/pkgs/jot/lib/src/index.dart b/pkgs/jot/lib/src/index.dart new file mode 100644 index 00000000..cdee0e2f --- /dev/null +++ b/pkgs/jot/lib/src/index.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:convert'; + +import '../api.dart'; +import 'markdown.dart'; + +// build the index +String? docSummary(Item item) { + // get docs + var docs = item.docs; + if (docs == null) return null; + + // first sentence + docs = firstSentence(docs); + + // convert to plaintext; resolve refs to plain text + docs = markdownToText(docs); + + // consolidate ws + docs = docs.replaceAll('\n', ' '); + + // first 80 chars + const limit = 80; + return docs.length > limit + ? '${docs.substring(0, limit - 1).trimRight()}…' + : docs; +} + +// "t":"$class" +// "t":"$enum" +// "t":"$extension" +// "t":"accessor" +// "t":"constructor" +// "t":"enumValue" +// "t":"field" +// "t":"function" +// "t":"library" +// "t":"method" +// "t":"package" +// "t":"typeAlias" + +class Index extends IndexMember { + Index() : super('', 'index'); + + String toJson() { + var buf = StringBuffer('[\n'); + children.sort(); + for (var child in children) { + child._writeTo(buf, appendComma: child != children.last); + } + buf.writeln(']'); + return buf.toString(); + } +} + +class IndexMember implements Comparable { + final String name; + final String type; + final String? ref; + final String? id; + final String? docs; + + final List children = []; + + IndexMember(this.name, this.type, {this.ref, this.id, this.docs}); + + IndexMember add( + String name, + String type, { + String? ref, + String? id, + String? docs, + }) { + var child = IndexMember(name, type, ref: ref, id: id, docs: docs); + children.add(child); + return child; + } + + void _writeTo(StringBuffer buf, {bool appendComma = false}) { + // One optimization here would be to + // 1) use a single char for the type field + // 2) prepend the type to the name field + buf.write('{"t":"$type","n":"$name"'); + if (docs != null) buf.write(',"d":${jsonEncode(docs)}'); + if (ref != null) buf.write(',"ref":"$ref"'); + // Only write an explicit anchor value if it is different from the item + // name. + if (id != null && id != name) buf.write(',"#":"$id"'); + if (children.isNotEmpty) { + buf.writeln(',"c":['); + children.sort(); + for (var child in children) { + child._writeTo(buf, appendComma: child != children.last); + } + buf.writeln(']}${appendComma ? ',' : ''}'); + } else { + buf.writeln('}${appendComma ? ',' : ''}'); + } + } + + @override + int compareTo(IndexMember other) { + var a = (children.isEmpty ? '_' : '') + type; + var b = (other.children.isEmpty ? '_' : '') + other.type; + return a.compareTo(b); + } +} diff --git a/pkgs/jot/lib/src/llm_summary.dart b/pkgs/jot/lib/src/llm_summary.dart new file mode 100644 index 00000000..b94bdbfa --- /dev/null +++ b/pkgs/jot/lib/src/llm_summary.dart @@ -0,0 +1,515 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:cli_util/cli_logging.dart'; +import 'package:meta/meta.dart'; +import 'package:path/path.dart' as p; + +import '../api.dart'; +import '../workspace.dart'; +import 'markdown.dart'; +import 'render.dart'; +import 'utils.dart'; + +class LLMSummary { + final Workspace workspace; + final Directory outDir; + final Logger logger; + final Stats? stats; + + LLMSummary({ + required this.workspace, + required this.outDir, + required this.logger, + this.stats, + }); + + void generate() { + final api = workspace.api; + final packages = api.packages; + + final wroteFiles = {}; + + if (packages.length == 1) { + final wrote = _generatePackage(packages.first, outDir); + wroteFiles.addAll(wrote.map((file) => file.absolute.path)); + } else { + for (var package in packages) { + final packageDir = Directory(p.join(outDir.path, package.name)); + final wrote = _generatePackage(packages.first, packageDir); + wroteFiles.addAll(wrote.map((file) => file.absolute.path)); + } + } + } + + Set _generatePackage(Package package, Directory dir) { + final out = StringBuffer(); + out.writeln('# Package: ${package.name}'); + out.writeln(); + + if (package.description != null) { + out.writeln(package.description!.trimRight()); + } + + out.writeln(); + out.writeln('## Libraries'); + out.writeln(); + + final wroteFiles = {}; + + // TODO: Disambiguate this from any 'index' library in the package. + final indexFile = File(p.join(dir.path, 'index.md')); + logger.stdout(' ${p.relative(indexFile.path)}'); + + for (var library in package.libraries) { + final filePath = + '${p.withoutExtension(library.name).replaceAll(':', '_')}.md'; + final docs = library.hasDocs ? firstSentence(library.docs!) : null; + out.writeln(_listWrapped('[${library.name}]($filePath)', docs)); + final file = File(p.join(dir.path, filePath)); + + file.parent.createSync(recursive: true); + + final output = generateForLibrary(library); + file.writeAsStringSync(output); + wroteFiles.add(file); + + logger.stdout(' ${p.relative(file.path)}'); + } + + // Emit the index file. + indexFile.writeAsStringSync(out.toString()); + wroteFiles.add(indexFile); + + return wroteFiles; + } + + @visibleForTesting + String generateForLibrary(LibraryItemContainer library) { + final out = StringBuffer(); + out.writeln('# Library: ${library.name}'); + out.writeln(); + + // TODO: we should do some escaping here + if (library.docs != null) { + out.writeln(library.docs); + out.writeln(); + } + + out.writeln('## Members'); + out.writeln(); + + final renderer = SignatureRenderer(); + + // members + final members = library.allChildren + .where((item) => item is! Items) + .toList(); + // normalize order + members.sort(compareByNaturalOrdering); + + if (members.isNotEmpty) { + for (var member in members) { + final docs = member.hasDocs ? firstSentence(member.docs!) : null; + out.writeln( + _listWrapped( + '${member.type.displayName} `${renderer.renderItem(member)}`', + docs, + ), + ); + } + out.writeln(); + } + + // classes + final classes = library.allChildren.whereType().toList(); + final classesByGroup = Items.itemsByGroup(classes); + final classGroups = classesByGroup.keys.toList()..sort(); + + for (final groupType in classGroups) { + for (var clazz + in classesByGroup[groupType]!.cast().toList() + ..sort(compareByName)) { + out.writeln('## ${titleCase(groupType.displayName)}: ${clazz.name}'); + if (clazz.hasDocs) { + out.writeln(); + out.writeln(firstSentence(clazz.docs!)); + } + out.writeln(); + out.writeln(renderer.renderItem(clazz)); + out.writeln(); + + // members + final members = clazz.allChildren.toList(); + // normalize order + members.sort(compareByNaturalOrdering); + if (members.isNotEmpty) { + for (var member in members) { + final modifiers = + member.isStatic && member.type != GroupType.enumValue + ? 'static ' + : ''; + final docs = member.hasDocs ? firstSentence(member.docs!) : null; + out.writeln( + _listWrapped('$modifiers`${renderer.renderItem(member)}`', docs), + ); + } + out.writeln(); + } + } + } + + return '${out.toString().trimRight()}\n'; + } +} + +class SignatureRenderer extends Renderer { + final StringBuffer buf = StringBuffer(); + + @override + String handleConstructor(Item item) { + var element = item.asConstructor; + _write(element.displayName); + _writeFormalParameters(element.parameters, forElement: true); + return _finish(); + } + + @override + String handleEnumValue(Item item) { + _write(item.name); + return _finish(); + } + + @override + String handleField(Item item) { + final element = item.asField; + _writeType(element.type); + _write(' '); + _write(element.displayName); + return _finish(); + } + + @override + String handleAccessor(Item item) { + final element = item.asAccessor; + if (element.isGetter) { + _writeType(element.returnType); + _write(' '); + } + _write(element.isGetter ? 'get ' : 'set '); + _write(element.name); + if (element.isSetter) { + _writeFormalParameters(element.parameters, forElement: true); + } + return _finish(); + } + + @override + String handleMethod(Item item) { + var element = item.asMethod; + _writeType(element.returnType); + _write(' '); + if (element.isOperator) { + _write('operator'); + } + _write(element.name); + _writeTypeParameters(element.typeParameters); + _writeFormalParameters(element.parameters, forElement: true); + return _finish(); + } + + @override + String handleTopLevelVariable(Item item) { + final element = item.asTopLevelVariableElement; + _writeType(element.type); + _write(' '); + _write(element.displayName); + return _finish(); + } + + @override + String handleFunction(Item item) { + var element = item.asFunction; + _writeType(element.returnType); + _write(' '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _writeFormalParameters(element.parameters, forElement: true); + return _finish(); + } + + @override + String handleFunctionTypeAlias(Item item) { + var element = item.asTypeAlias; + _write('typedef '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _write(' = '); + var aliasedElement = element.aliasedElement; + if (aliasedElement != null) { + _writeType(element.aliasedType); + } else { + _writeType(element.aliasedType); + } + return _finish(); + } + + @override + String handleTypeAlias(Item item) { + final element = item.asTypeAlias; + _write('typedef '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _write(' = '); + var aliasedElement = element.aliasedElement; + if (aliasedElement != null) { + _writeType(element.aliasedType); + } else { + _writeType(element.aliasedType); + } + return _finish(); + } + + @override + String handleMixin(Item item) { + final element = item.asMixin; + if (element.isBase) _write('base '); + _write('mixin '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _writeTypesIfNotEmpty('\non ', element.superclassConstraints); + _writeTypesIfNotEmpty('\nimplements ', element.interfaces); + _write(' { … }'); + return '```dart\n${_finish()}\n```'; + } + + @override + String handleClass(Item item) { + final element = item.asClass; + if (element.isSealed) { + _write('sealed '); + } else if (element.isAbstract) { + _write('abstract '); + } + if (element.isBase && element.isMixinClass) { + _write('base '); + } else if (element.isInterface) { + _write('interface '); + } else if (element.isFinal) { + _write('final '); + } + if (element.isMixinClass) _write('mixin '); + _write('class '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _writeTypeIfNotObject('\nextends ', element.supertype); + _writeTypesIfNotEmpty('\nwith ', element.mixins); + _writeTypesIfNotEmpty('\nimplements ', element.interfaces); + _write(' { … }'); + return '```dart\n${_finish()}\n```'; + } + + @override + String handleEnum(Item item) { + final element = item.asEnum; + _write('enum '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _writeTypesIfNotEmpty('\nwith ', element.mixins); + _writeTypesIfNotEmpty('\nimplements ', element.interfaces); + _write(' { … }'); + return '```dart\n${_finish()}\n```'; + } + + @override + String handleExtension(Item item) { + final element = item.asExtension; + _write('extension '); + _write(element.displayName); + _writeTypeParameters(element.typeParameters); + _write(' on '); + _writeType(element.extendedType); + _write(' { … }'); + return '```dart\n${_finish()}\n```'; + } + + void _write(String str) => buf.write(str); + + String _finish() { + var result = buf.toString(); + buf.clear(); + + // handle newlines + if (result.contains('\n')) { + if (result.length <= 80) { + result = result.replaceAll('\n', ' '); + } else { + result = result.replaceAll('\n', '\n '); + } + } + + return result; + } + + void _writeType(DartType type) { + _write(type.getDisplayString(withNullability: true)); + } + + void _writeTypes(List types) { + for (var i = 0; i < types.length; i++) { + if (i != 0) { + _write(', '); + } + _writeType(types[i]); + } + } + + void _writeTypeIfNotObject(String prefix, DartType? type) { + if (type != null && !type.isDartCoreObject) { + _write(prefix); + _writeType(type); + } + } + + void _writeTypesIfNotEmpty(String prefix, List types) { + if (types.isNotEmpty) { + _write(prefix); + _writeTypes(types); + } + } + + void writeTypeParameter(TypeParameterElement element) { + _write(element.displayName); + + var bound = element.bound; + if (bound != null) { + _write(' extends '); + _writeType(bound); + } + } + + void _writeTypeParameters(List elements) { + if (elements.isEmpty) return; + + _write('<'); + for (var i = 0; i < elements.length; i++) { + if (i != 0) _write(', '); + writeTypeParameter(elements[i]); + } + _write('>'); + } + + void _writeFormalParameters( + List parameters, { + required bool forElement, + }) { + _write('('); + + _WriteFormalParameterKind? lastKind; + var lastClose = ''; + + void openGroup(_WriteFormalParameterKind kind, String open, String close) { + if (lastKind != kind) { + _write(lastClose); + _write(open); + lastKind = kind; + lastClose = close; + } + } + + for (var i = 0; i < parameters.length; i++) { + if (i != 0) _write(', '); + + var parameter = parameters[i]; + if (parameter.isRequiredPositional) { + openGroup(_WriteFormalParameterKind.requiredPositional, '', ''); + } else if (parameter.isOptionalPositional) { + openGroup(_WriteFormalParameterKind.optionalPositional, '[', ']'); + } else if (parameter.isNamed) { + openGroup(_WriteFormalParameterKind.named, '{', '}'); + } + _writeWithoutDelimiters(parameter, forElement: forElement); + } + + _write(lastClose); + _write(')'); + } + + void _writeWithoutDelimiters( + ParameterElement element, { + required bool forElement, + }) { + if (element.isRequiredNamed) { + _write('required '); + } + _writeType(element.type); + if (forElement || element.isNamed) { + _write(' '); + _write(element.displayName); + } + } +} + +enum _WriteFormalParameterKind { requiredPositional, optionalPositional, named } + +int compareByName(Item a, Item b) { + return a.name.compareTo(b.name); +} + +int compareByNaturalOrdering(Item a, Item b) { + int compareCtor(Item a, Item b) { + final valA = a.element is ConstructorElement ? true : false; + final valB = b.element is ConstructorElement ? true : false; + + return valA == valB ? 0 : (valA ? -1 : 1); + } + + int compareStatic(Item a, Item b) { + final valA = a.element is ClassMemberElement + ? (a.element as ClassMemberElement).isStatic + : false; + final valB = b.element is ClassMemberElement + ? (b.element as ClassMemberElement).isStatic + : false; + + return valA == valB ? 0 : (valA ? -1 : 1); + } + + // ctors first + var compare = compareCtor(a, b); + if (compare != 0) return compare; + + // anything static + compare = compareStatic(a, b); + if (compare != 0) return compare; + + // types + compare = a.type.compareTo(b.type); + if (compare != 0) return compare; + + // lexially by name + return a.name.compareTo(b.name); +} + +/// Return a markdown list item, roughly wrapped at 80 cols. +String _listWrapped(String item, String? docs) { + // Decide if we need to wrap, and when wrapping, make sure we indent + // appropriately. + var result = '- $item'; + if (docs != null) { + final lines = docs.split('\n'); + final first = lines.first; + if (first.length + item.length > 78) { + result = '$result:\n '; + } else { + result = '$result: '; + } + result = '$result${lines.join('\n ')}'; + } + return result; +} diff --git a/pkgs/jot/lib/src/markdown.dart b/pkgs/jot/lib/src/markdown.dart new file mode 100644 index 00000000..0d1ec0c1 --- /dev/null +++ b/pkgs/jot/lib/src/markdown.dart @@ -0,0 +1,112 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:markdown/markdown.dart'; + +import 'utils.dart'; + +// todo: sanitize html (see lib/src/render/documentation_renderer.dart from +// dartdoc) + +// todo: link resolver + +// todo: markdown files can create id attributes + +// todo: ensure that element docs cannot create id attributes + +class MarkdownResults { + final String html; + final Outline outline; + + MarkdownResults(this.html, this.outline); +} + +typedef MarkdownLinkResolver = String? Function(String reference); + +String convertMarkdown(String markdown, {MarkdownLinkResolver? linkResolver}) { + return markdownToHtml( + markdown, + extensionSet: ExtensionSet.gitHubWeb, + enableTagfilter: true, + linkResolver: (String name, [String? title]) { + String? href; + + if (linkResolver != null) { + href = linkResolver(name); + } + + if (href == null) { + return Element.text('span', name)..attributes['class'] = 'code'; + } else { + return Element.text('a', name) + ..attributes['href'] = href + ..attributes['class'] = 'code'; + } + }, + ); +} + +String firstSentence(String markdown) { + return markdown + .split('\n') + .takeWhile((line) => line.trim().isNotEmpty && !line.startsWith('```')) + .join('\n'); +} + +String markdownToText(String markdown) { + final visitor = _TextVisitor(); + final document = Document( + extensionSet: ExtensionSet.gitHubWeb, + encodeHtml: false, + linkResolver: (name, [text]) => Element.text('span', name), + ); + for (final node in document.parse(markdown)) { + node.accept(visitor); + } + return visitor.toString(); +} + +MarkdownResults convertMarkdownWithOutline(String markdown) { + final document = Document(extensionSet: ExtensionSet.gitHubWeb); + + final nodes = document.parse(markdown); + + var contents = '${renderToHtml(nodes, enableTagfilter: true)}\n'; + var elements = nodes.whereType().where( + (element) => element.tag == 'h2' || element.tag == 'h3', + ); + + return MarkdownResults(contents, _toOutline(elements)); +} + +Outline _toOutline(Iterable elements) { + var outline = Outline(); + for (var element in elements) { + var level = int.parse(element.tag.substring(1)); + outline.add( + Heading(element.textContent, level: level, id: element.generatedId), + ); + } + return outline; +} + +class _TextVisitor implements NodeVisitor { + final StringBuffer buf = StringBuffer(); + + @override + String toString() => buf.toString(); + + @override + bool visitElementBefore(Element element) { + return true; + } + + @override + void visitText(Text text) { + buf.write(text.text); + } + + @override + void visitElementAfter(Element element) {} +} diff --git a/pkgs/jot/lib/src/render.dart b/pkgs/jot/lib/src/render.dart new file mode 100644 index 00000000..27077850 --- /dev/null +++ b/pkgs/jot/lib/src/render.dart @@ -0,0 +1,283 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// ignore_for_file: implementation_imports + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/src/dart/element/element.dart'; + +import '../api.dart'; +import '../workspace.dart'; +import 'display.dart'; +import 'formatting.dart'; +import 'utils.dart'; + +abstract class Renderer { + String render(GroupType type, Item item) { + switch (type) { + case GroupType.constructor: + return handleConstructor(item); + case GroupType.enumValue: + return handleEnumValue(item); + case GroupType.field: + return handleField(item); + case GroupType.accessor: + return handleAccessor(item); + case GroupType.method: + return handleMethod(item); + + case GroupType.topLevelVariable: + return handleTopLevelVariable(item); + case GroupType.function: + return handleFunction(item); + case GroupType.functionTypeAlias: + return handleFunctionTypeAlias(item); + case GroupType.typeAlias: + return handleTypeAlias(item); + case GroupType.$enum: + return handleEnum(item); + case GroupType.$mixin: + return handleMixin(item); + case GroupType.$class: + return handleClass(item); + case GroupType.$extension: + return handleExtension(item); + case GroupType.$extensionType: + return handleExtensionType(item); + + // unexpected values + case GroupType.skip: + case GroupType.other: + throw StateError('unexpected item: $item'); + } + } + + String renderItem(Item item) => render(item.type, item); + + String handleConstructor(Item item) => handleDefault(item); + String handleEnumValue(Item item) => handleDefault(item); + String handleField(Item item) => handleDefault(item); + String handleAccessor(Item item) => handleDefault(item); + String handleMethod(Item item) => handleDefault(item); + + String handleTopLevelVariable(Item item) => handleDefault(item); + String handleFunction(Item item) => handleDefault(item); + String handleFunctionTypeAlias(Item item) => handleDefault(item); + String handleTypeAlias(Item item) => handleDefault(item); + String handleMixin(Item item) => handleDefault(item); + String handleClass(Item item) => handleDefault(item); + String handleEnum(Item item) => handleDefault(item); + String handleExtension(Item item) => handleDefault(item); + String handleExtensionType(Item item) => handleDefault(item); + + String handleDefault(Item item) => item.name; +} + +class OutlineRenderer extends Renderer { + @override + String handleConstructor(Item item) { + var element = item.asConstructor; + var arity = element.parameters.isEmpty ? '' : '…'; + return '${element.displayName}($arity)'; + } + + @override + String handleAccessor(Item item) { + var prefix = (item.element as PropertyAccessorElement).isGetter + ? 'get' + : 'set'; + return '$prefix\u00A0${item.name}'; + } + + @override + String handleMethod(Item item) { + var element = item.asMethod; + if (element.isOperator) { + return item.name; + } else { + var arity = element.parameters.isEmpty ? '' : '…'; + return '${item.name}($arity)'; + } + } + + @override + String handleFunction(Item item) { + var element = item.asFunction; + var arity = element.parameters.isEmpty ? '' : '…'; + return '${item.name}($arity)'; + } +} + +String writeAnnotations(Item item) { + var annotations = item.annotations; + if (annotations.isEmpty) return ''; + + var buf = StringBuffer('

\n'); + for (var annotation in annotations) { + var text = annotation.toSource(); + buf.writeln( + '' + '${htmlEscape(text)}', + ); + } + + buf.writeln('

'); + return buf.toString(); +} + +class LinkedCodeRenderer extends Renderer { + final Resolver resolver; + final WorkspaceFile fromFile; + + LinkedCodeRenderer(this.resolver, this.fromFile); + + @override + String handleConstructor(Item item) { + var element = item.asConstructor; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeConstructorElement(element); + return text.emitHtml( + (text) => DartFormat.asConstructor( + text, + className: element.enclosingElement.name, + isConst: !element.isFactory && element.isConst, + ), + ); + } + + @override + String handleField(Item item) { + var element = item.asField; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeVariableElement(element); + return text.emitHtml(DartFormat.asField); + } + + @override + String handleAccessor(Item item) { + var element = item.asAccessor; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeExecutableElement(element, element.displayName); + return text.emitHtml(DartFormat.asMethod); + } + + @override + String handleMethod(Item item) { + var element = item.asMethod; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeExecutableElement( + element, + element.isOperator ? element.displayName : element.name, + ); + return text.emitHtml(DartFormat.asMethod); + } + + @override + String handleFunction(Item item) { + var element = item.asFunction; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeExecutableElement(element, element.name); + return text.emitHtml(DartFormat.asFunction); + } + + @override + String handleFunctionTypeAlias(Item item) { + var element = item.asTypeAlias; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeTypeAliasElement(element as TypeAliasElementImpl); + return text.emitHtml(DartFormat.asTypeAlias); + } + + @override + String handleTypeAlias(Item item) { + var element = item.asTypeAlias; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeTypeAliasElement(element as TypeAliasElementImpl); + return text.emitHtml(DartFormat.asTypeAlias); + } + + @override + String handleClass(Item item) { + var element = item.asClass; + + var text = LinkedText(resolver, fromFile); + + var builder = ElementDisplayStringBuilder(text); + + builder.writeClassElement(element as ClassElementImpl); + + // // todo: replicate this but call out to LinkedText + // //text.write(element.getDisplayString(withNullability: true)); + // // "class DocWorkspace extends DocContainer" + // text.write('class '); + // // todo: note that we don't need to link to ourself + // text.writeElement(element.name, element); + // var $super = element.supertype?.element; + // if ($super != null) { + // text.write(' extends '); + // text.writeElement($super.name, $super); + // } + + return text.emitHtml(DartFormat.asClass, ' { … }'); + } + + @override + String handleMixin(Item item) { + var element = item.asMixin; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeMixinElement(element as MixinElementImpl); + return text.emitHtml(DartFormat.asClass, ' { … }'); + } + + @override + String handleEnum(Item item) { + var element = item.asEnum; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeEnumElement(element); + return text.emitHtml(DartFormat.asEnum, ' { … }'); + } + + @override + String handleExtension(Item item) { + var element = item.asExtension; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeExtensionElement(element); + return text.emitHtml(DartFormat.asClass, ' { … }'); + } + + @override + String handleExtensionType(Item item) { + var element = item.asExtensionType; + + var text = LinkedText(resolver, fromFile); + var builder = ElementDisplayStringBuilder(text); + builder.writeExtensionTypeElement(element); + return text.emitHtml(DartFormat.asClass, ' { … }'); + } + + @override + String handleDefault(Item item) { + throw StateError('${item.type} not yet handled from LinkedCodeRenderer'); + } +} diff --git a/pkgs/jot/lib/src/server.dart b/pkgs/jot/lib/src/server.dart new file mode 100644 index 00000000..10c0030c --- /dev/null +++ b/pkgs/jot/lib/src/server.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:path/path.dart' as p; + +const _mimeMap = { + 'css': 'text/css', + 'html': 'text/html', + 'js': 'text/javascript', + 'json': 'application/json', + 'png': 'image/png', + 'svg': 'image/svg+xml', +}; + +Map headersFor(String path) { + var ext = p.extension(path).toLowerCase(); + var mime = + (ext.startsWith('.') ? _mimeMap[ext.substring(1)] : null) ?? 'text/plain'; + return {'content-type': mime}; +} diff --git a/pkgs/jot/lib/src/utils.dart b/pkgs/jot/lib/src/utils.dart new file mode 100644 index 00000000..7f1e0c0c --- /dev/null +++ b/pkgs/jot/lib/src/utils.dart @@ -0,0 +1,224 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:convert' as convert; +import 'dart:io'; + +import 'package:path/path.dart' as p; + +String stripDartdoc(String str) { + str = str.trim(); + + if (str.startsWith('/**')) { + str = str.substring('/**'.length); + if (str.endsWith('*/')) str = str.substring(0, str.length - '*/'.length); + return str + .split('\n') + .map((line) => line.trimLeft()) + .map((line) { + if (line.startsWith('* ')) return line.substring(2); + if (line.startsWith('*')) return line.substring(1); + return line; + }) + .map((line) => line.trimRight()) + .skipWhile((l) => l.trim().isEmpty) + .join('\n'); + } else { + return str + .split('\n') + .map((line) => line.trimLeft()) + .map((line) { + if (line.startsWith('/// ')) return line.substring(4); + if (line.startsWith('///')) return line.substring(3); + return line; + }) + .map((line) => line.trimRight()) + .join('\n'); + } +} + +String titleCase(String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); +} + +String htmlEscape(String text) => convert.htmlEscape.convert(text); + +/// Returns an adjusted lexical compare. +/// +/// Adjustments include sorting case-insensitive. +int adjustedLexicalCompare(String a, String b) { + if (a.isEmpty || b.isEmpty) return a.compareTo(b); + + var lowerA = a.toLowerCase(); + var lowerB = b.toLowerCase(); + + return lowerA.compareTo(lowerB); +} + +String stringToAnchorId(String str) => Uri.encodeQueryComponent(str); + +typedef _JsonType = Map; + +String? getPackageRoot(Directory fromDir, String packageName) { + var packageFile = _findPackageConfig(fromDir); + if (packageFile == null) return null; + + var packageInfo = + convert.jsonDecode(packageFile.readAsStringSync()) as _JsonType; + for (var info in packageInfo['packages'] as List<_JsonType>) { + if (info['name'] == packageName) { + return File.fromUri(Uri.parse(info['rootUri'] as String)).path; + } + } + + return null; +} + +File? _findPackageConfig(Directory dir) { + var file = File(p.join(dir.path, '.dart_tool', 'package_config.json')); + if (file.existsSync()) return file; + + return dir.parent == dir ? null : _findPackageConfig(dir.parent); +} + +extension DirectoryExtension on Directory { + List listSyncSorted({bool recursive = false}) { + var entites = listSync(recursive: recursive); + entites.sort((a, b) => adjustedLexicalCompare(a.path, b.path)); + return entites; + } +} + +extension FileSystemEntityExtension on FileSystemEntity { + String get name => p.basename(path); +} + +extension FileExtension on File { + bool get publicMarkdownFile => + !name.startsWith('_') && p.extension(path) == '.md'; +} + +class Outline { + final List items = []; + + void add(Heading heading) { + if (items.isEmpty) { + items.add(heading); + } else if (items.last.level >= heading.level) { + items.add(heading); + } else { + items.last.add(heading); + } + } + + String get asHtml { + var buf = StringBuffer( + '
    \n', + ); + for (var item in items) { + buf.writeln(item.asHtml); + } + buf.write('
'); + return buf.toString(); + } +} + +class Heading { + final String label; + final String? id; + final int level; + + final List children = []; + + Heading(this.label, {this.id, this.level = 2}); + + void add(Heading heading) { + if (children.isEmpty) { + children.add(heading); + } else if (children.last.level >= heading.level) { + children.add(heading); + } else { + children.last.add(heading); + } + } + + String get asHtml { + var buf = StringBuffer('
  • '); + var href = id == null ? '' : 'href="#$id"'; + buf.write( + '$label', + ); + if (children.isNotEmpty) { + buf.writeln(); + buf.writeln('
      '); + for (var child in children) { + buf.writeln(child.asHtml); + } + buf.writeln('
    '); + } + buf.write('
  • '); + return buf.toString(); + } + + @override + String toString() => id == null ? '$label h$level' : '$label h$level ($id)'; +} + +class Stats { + final Stopwatch timer = Stopwatch(); + int fileCount = 0; + int byteCount = 0; + + void start() { + timer.start(); + } + + void genFile(File file) { + fileCount++; + byteCount += file.lengthSync(); + } + + String get elapsedSeconds => + (timer.elapsedMilliseconds / 1000.0).toStringAsFixed(1); + + String get sizeDesc { + const bytesPerMB = 1024.0 * 1024; + + if (byteCount >= bytesPerMB) { + return '${(byteCount / (1024.0 * 1024.0)).toStringAsFixed(1)}MB'; + } else { + return '${byteCount ~/ 1024.0}k'; + } + } + + void stop() { + timer.stop(); + } +} + +extension StringExtension on String { + /// A simple implementation of `package:path`'s `relative` function. + /// + /// The implementation from `package:path` ends up calling `Directory.current` + /// enough that that call along can account for 60% of this tool's run time. + String pathRelative({required String fromDir}) { + if (fromDir.isEmpty || fromDir == '.') { + return this; + } + + var paths = split('/'); + var froms = fromDir.split('/'); + + while (paths.isNotEmpty && froms.isNotEmpty && paths.first == froms.first) { + paths = paths.sublist(1); + froms = froms.sublist(1); + } + + for (var _ in froms) { + paths.insert(0, '..'); + } + + return paths.join('/'); + } +} diff --git a/pkgs/jot/lib/workspace.dart b/pkgs/jot/lib/workspace.dart new file mode 100644 index 00000000..12e14047 --- /dev/null +++ b/pkgs/jot/lib/workspace.dart @@ -0,0 +1,427 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// Used to model the desired generation output. +/// +/// See [Workspace]. +library; + +import 'dart:convert'; +import 'dart:io'; + +import 'package:collection/collection.dart'; +import 'package:path/path.dart' as p; +import 'package:yaml/yaml.dart' as yaml; + +import 'api.dart'; +import 'src/html.dart'; +import 'src/markdown.dart'; +import 'src/utils.dart'; + +typedef FileContentGenerator = + Future Function( + Workspace workspace, + WorkspaceFile thisFile, + ); + +class GenerationResults { + final String contents; + final Outline? outline; + + GenerationResults(this.contents, [this.outline]); +} + +Future emptyContentGenerator( + Workspace workspace, + WorkspaceFile thisFile, +) { + return Future.value(GenerationResults('')); +} + +FileContentGenerator createMarkdownGenerator(File markdownFile) { + return (Workspace workspace, WorkspaceFile thisFile) async { + var content = markdownFile.readAsStringSync(); + var results = convertMarkdownWithOutline(content); + return GenerationResults(results.html, results.outline); + }; +} + +abstract class WorkspaceEntity { + final WorkspaceEntity? parent; + final String name; + + WorkspaceEntity(this.parent, this.name); + + WorkspaceFile? get mainFile; + + Workspace get workspace => parent!.workspace; + + WorkspaceDirectory? get parentPackage => parent?.parentPackage; + + Iterable get breadcrumbs { + var result = []; + WorkspaceEntity? item = this; + + while (item != null) { + if (item is WorkspaceFile) { + result.add(item); + } else if (item is WorkspaceDirectory) { + if (item.mainFile != null && !result.contains(item.mainFile)) { + result.add(item.mainFile!); + } + } + item = item.parent; + } + + return result.reversed; + } + + @override + String toString() => name; +} + +class WorkspaceFile extends WorkspaceEntity { + final String path; + final FileContentGenerator contentGenerator; + final FileType fileType; + + /// If set, the script to specify in an import. + String? importScript; + + WorkspaceFile( + super.parent, + super.name, + this.path, + this.contentGenerator, [ + this.fileType = FileType.dart, + ]); + + bool get isMarkdown => fileType == FileType.markdown; + + @override + WorkspaceFile? get mainFile => this; + + Future generatePageContents() { + return contentGenerator(workspace, this); + } + + @override + String toString() => 'DocFile $name'; +} + +enum FileType { markdown, dart } + +class WorkspaceSeparator extends WorkspaceEntity { + WorkspaceSeparator(super.parent, super.name); + + @override + WorkspaceFile? get mainFile => null; +} + +class WorkspaceDirectory extends WorkspaceEntity { + // todo: is isGroup used? an important distinction? + final bool isGroup; + final bool isPackage; + + final List children = []; + + String? version; + String? description; + + @override + WorkspaceFile? mainFile; + + WorkspaceDirectory( + super.parent, + super.name, { + this.isGroup = false, + this.isPackage = false, + }) { + // TODO: have a default mainfile? + } + + int get itemCount { + var count = mainFile == null ? 0 : 1; + for (var child in children) { + if (child is WorkspaceDirectory) { + count += child.itemCount; + } else { + count++; + } + } + return count; + } + + @override + WorkspaceDirectory? get parentPackage => + isPackage ? this : parent?.parentPackage; + + T addChild(T entity) { + children.add(entity); + return entity; + } + + WorkspaceEntity? getChild(String name) { + return children.firstWhereOrNull((c) => c.name == name); + } + + @override + String toString() => 'DocContainer $name'; + + bool hasChild(WorkspaceFile page) { + if (mainFile == page) return true; + if (children.contains(page)) return true; + return false; + } +} + +/// A model of the generation output. +class Workspace extends WorkspaceDirectory { + final Api api = Api(); + final HtmlTemplate htmlTemplate; + final List navFiles = []; + + String? footer; + + Workspace(String name, {super.isPackage, required this.htmlTemplate}) + : super(null, name) { + // Placeholder for the main file. + mainFile = WorkspaceFile( + this, + 'index.html', + 'index.html', + emptyContentGenerator, + FileType.markdown, + ); + } + + @override + Workspace get workspace => this; + + final Map> _pathToCache = {}; + + String pathTo(WorkspaceFile target, {WorkspaceFile? from}) { + if (from == null) return target.path; + + var to = target.path; + var fromDir = p.dirname(from.path); + + var fromCache = _pathToCache.putIfAbsent(fromDir, () => {}); + return fromCache.putIfAbsent(to, () { + // We use our own custom 'relative' implementation as the package:path one + // obsessively call's Directory.current, and would contribute as much as + // 60% of our run time. + return to.pathRelative(fromDir: fromDir); + // return p.relative(target.path, from: p.dirname(from.path)); + }); + } + + Future generateWorkspacePage( + WorkspaceFile file, + GenerationResults page, + ) async { + // navbar + var navbarContent = [mainFile!, ...navFiles] + .map((target) { + var active = ''; + if (navFiles.contains(file) && target == file) { + active = ' navbar__link--active'; + } else if (!navFiles.contains(file) && target == mainFile) { + active = ' navbar__link--active'; + } + + var href = 'href="${pathTo(target, from: file)}"'; + var name = target == mainFile ? 'Docs' : target.name; + return '$name'; + }) + .join(' '); + + // breadcrumbs + var breadcrumbs = file.breadcrumbs; + if (breadcrumbs.length == 1) { + breadcrumbs = []; + } + var breadcrumbsContent = breadcrumbs + .map((entity) { + var target = entity is WorkspaceFile + ? entity + : (entity as WorkspaceDirectory).mainFile!; + var href = 'href="${pathTo(target, from: file)}"'; + + if (workspace.mainFile == target) { + return ''' + '''; + } else if (file == target) { + return ''; + } else { + return ''; + } + }) + .join(' '); + + var pathPrefix = p + .split(file.path) + .skip(1) + .map((e) => '..') + .join(p.separator); + if (pathPrefix.isNotEmpty) pathPrefix = '$pathPrefix/'; + + return htmlTemplate.templateSubtitute( + pageTitle: name, + pathPrefix: pathPrefix, + pageRef: file.path, + navbar: navbarContent, + breadcrumbs: breadcrumbsContent, + pageContent: page.contents.trimRight(), + toc: page.outline?.asHtml ?? '', + footer: footer ?? '', + ); + } + + String generateNavData() { + const encoder = JsonEncoder.withIndent(''); + + var navItems = [mainFile!, ...children].map(_generateNavData).toList(); + return encoder.convert(navItems); + } + + Map _generateNavData(WorkspaceEntity page) { + if (page is WorkspaceFile) { + return {'n': page.name, 'h': page.path}; + } else if (page is WorkspaceSeparator) { + return {'n': page.name, 't': 'separator'}; + } else if (page is WorkspaceDirectory) { + final mainFile = page.mainFile!; + + return { + 'n': mainFile.name, + 'h': mainFile.path, + 'c': page.children.map(_generateNavData).toList(), + }; + } else { + throw StateError('unexpected subclass'); + } + } + + @override + String toString() => 'DocWorkspace $name'; + + static Workspace fromPackage(HtmlTemplate htmlTemplate, Directory dir) { + var pubspec = + yaml.loadYaml(File(p.join(dir.path, 'pubspec.yaml')).readAsStringSync()) + as yaml.YamlMap; + + final packageName = pubspec['name'] as String?; + final packageVersion = pubspec['version'] as String?; + + var workspace = Workspace( + 'package:$packageName', + htmlTemplate: htmlTemplate, + isPackage: true, + ); + workspace.version = packageVersion; + if (packageVersion != null) { + workspace.footer = 'package:$packageName v$packageVersion'; + } + workspace.description = pubspec['description'] as String?; + + for (var file in dir.listSyncSorted().whereType().where( + (f) => f.publicMarkdownFile, + )) { + var name = p.relative(file.path, from: dir.path); + var title = titleCase( + p.basenameWithoutExtension(file.path).toLowerCase(), + ); + + var path = '${p.withoutExtension(name)}.html'; + if (name == 'README.md') { + workspace.mainFile = WorkspaceFile( + workspace, + title, + 'index.html', + createMarkdownGenerator(file), + FileType.markdown, + ); + } else if (name == 'CHANGELOG.md' || name == 'LICENSE.md') { + workspace.navFiles.add( + WorkspaceFile( + workspace, + title, + path, + createMarkdownGenerator(file), + FileType.markdown, + ), + ); + } else { + workspace.addChild( + WorkspaceFile( + workspace, + title, + path, + createMarkdownGenerator(file), + FileType.markdown, + ), + ); + } + } + + var docDir = Directory(p.join(dir.path, 'doc')); + if (docDir.existsSync()) { + for (var file in docDir.listSyncSorted().whereType().where( + (f) => f.publicMarkdownFile, + )) { + var name = file.name; + var title = titleCase( + p.basenameWithoutExtension(file.path).toLowerCase(), + ); + var path = '${p.withoutExtension(name)}.html'; + workspace.addChild( + WorkspaceFile( + workspace, + title, + path, + createMarkdownGenerator(file), + FileType.markdown, + ), + ); + } + } + + return workspace; + } + + WorkspaceFile? getForPath(String path) { + for (var file in navFiles) { + if (file.path == path) return file; + } + + WorkspaceFile? check(WorkspaceDirectory container, String path) { + if (container.mainFile?.path == path) return container.mainFile; + + for (var child in container.children) { + if (child is WorkspaceFile) { + if (child.path == path) return child; + } else { + var result = check(child as WorkspaceDirectory, path); + if (result != null) return result; + } + } + + return null; + } + + return check(this, path); + } +} diff --git a/pkgs/jot/pubspec.yaml b/pkgs/jot/pubspec.yaml new file mode 100644 index 00000000..de9c8869 --- /dev/null +++ b/pkgs/jot/pubspec.yaml @@ -0,0 +1,36 @@ +name: jot +description: An experimental documentation generator for Dart projects. +version: 0.1.0-dev +repository: https://github.com/dart-lang/labs/tree/main/pkgs/jot +issue_tracker: https://github.com/dart-lang/labs/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Ajot + +environment: + sdk: ^3.9.0 + +dependencies: + # bin/ + cli_util: ^0.4.0 + shelf: ^1.4.0 + shelf_router: ^1.1.0 + + # lib/ + analyzer: ^6.4.0 + args: ^2.4.0 + collection: ^1.17.0 + dart_style: ^2.3.6 + js: ^0.6.0 + markdown: ^7.0.0 + meta: ^1.11.0 + path: ^1.8.0 + yaml: ^3.1.0 + +dev_dependencies: + crypto: ^3.0.0 + dart_flutter_team_lints: ^3.0.0 + http: ^1.1.0 + test: ^1.23.0 + +# Test packages. +workspace: + - test/fixtures/demo + - test/fixtures/server diff --git a/pkgs/jot/test/fixtures/demo/doc/api/demo.md b/pkgs/jot/test/fixtures/demo/doc/api/demo.md new file mode 100644 index 00000000..8e46884f --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/doc/api/demo.md @@ -0,0 +1,244 @@ +# Library: demo.dart + +A sample library to exercise most Dart language features. + +## Members + +- accessor `double get antennaDiameter` +- accessor `set antennaDiameter=(double _antennaDiameter)` +- accessor `List get flybyObjects` +- accessor `set flybyObjects=(List _flybyObjects)` +- accessor `List get il` +- accessor `set il=(List _il)` +- accessor `Map get image` +- accessor `set image=(Map _image)` +- accessor `Map> get m1` +- accessor `set m1=(Map> _m1)` +- accessor `Map> get m2` +- accessor `set m2=(Map> _m2)` +- accessor `set myCar=(VehicleSealed _myCar)` +- accessor `VehicleSealed get myCar` +- accessor `String get name` +- accessor `set name=(String _name)` +- accessor `Duration get oneSecond` +- accessor `(String, String, {int a, bool b}) get record` +- accessor `set record=((String, String, {int a, bool b}) _record)` +- accessor `double get xOrigin` +- accessor `double get yOrigin` +- accessor `int get year` +- accessor `set year=(int _year)` +- function `Stream asynchronousNaturalsTo(int n)` +- function `String checkList(List? list)` +- function `Future createDescriptions(Iterable objects)` +- function `void enableFlags({bool? bold, bool? hidden})` +- function `T first(List ts)` +- function `(String, int) foo()` +- function `String getVehicleSound(VehicleSealed vehicle)` +- function `bool isNoble(int atomicNumber)` +- function `Iterable naturalsTo(int n)` +- function `Future printWithDelay(String message)` +- function `String say(String from, String msg, [String? device])` +- function `(int, int) swap((int, int) record)` +- function `(String, int) userInfo(Map json)` +- type alias `typedef Compare = int Function(T, T)` +- type alias `typedef IntList = List` +- type alias `typedef JSAnyRepType = Object` +- type alias `typedef ListMapper = Map>` + +## Enum: Vehicle + +```dart +enum Vehicle implements Comparable { … } +``` + +- `Vehicle({required int tires, required int passengers, required int carbonPerKilometer})` +- `bicycle` +- `bus` +- `car` +- `int carbonPerKilometer` +- `int passengers` +- `int tires` +- `int get carbonFootprint` +- `bool get isTwoWheeled` +- `int compareTo(Vehicle other)`: Compares this object to another object. + +## Mixin: MusicalPerformer + +```dart +mixin MusicalPerformer on Musician { … } +``` + +## Class: BicycleSealed + +```dart +class BicycleSealed extends VehicleSealed { … } +``` + +## Class: Cache + +```dart +abstract class Cache { … } +``` + +- `T getByKey(String key)` +- `void setByKey(String key, T value)` + +## Class: CarSealed + +```dart +class CarSealed extends VehicleSealed { … } +``` + +## Class: Describable + +```dart +abstract class Describable { … } +``` + +- `void describe()` +- `void describeWithEmphasis()` + +## Class: Foo + +```dart +class Foo { … } +``` + +## Class: JSObjectRepType + +```dart +abstract class JSObjectRepType { … } +``` + +## Class: MockSpaceship + +```dart +class MockSpaceship implements Spacecraft { … } +``` + +- `DateTime? launchDate` +- `String name` +- `int? get launchYear` +- `void describe()` + +## Class: Musician + +```dart +class Musician { … } +``` + +## Class: Orbiter + +```dart +class Orbiter extends Spacecraft { … } +``` + +- `Orbiter(String name, DateTime launchDate, double altitude)` +- `double altitude` + +## Class: Point + +```dart +class Point { … } +``` + +- `Point(double x, double y)` +- `Point.fromJson(Map json)` +- `Point.origin()` +- static `Point zero` +- static `double distanceBetween(Point a, Point b)` +- `double x` +- `double y` + +## Class: SingerDancer + +```dart +class SingerDancer extends Musician with MusicalPerformer { … } +``` + +## Class: Spacecraft + +```dart +class Spacecraft { … } +``` + +- `Spacecraft(String name, DateTime? launchDate)` +- `Spacecraft.unlaunched(String name)` +- `DateTime? launchDate` +- `String name` +- `int? get launchYear` +- `void describe()` + +## Class: TruckSealed + +```dart +class TruckSealed implements VehicleSealed { … } +``` + +## Class: Vector2d + +```dart +class Vector2d { … } +``` + +- `Vector2d(double x, double y)` +- `double x` +- `double y` + +## Class: Vector3d + +```dart +class Vector3d extends Vector2d { … } +``` + +- `Vector3d(double x, double y, double z)` +- `double z` + +## Class: VehicleSealed + +```dart +sealed class VehicleSealed { … } +``` + +## Extension: NumberParsing + +```dart +extension NumberParsing on String { … } +``` + +- `double parseDouble()` +- `int parseInt()` + +## Extension type: EventInit + +EventInit + +- `EventInit({bool bubbles, bool cancelable, bool composed})` +- `set bubbles=(bool value)` +- `bool get bubbles` +- `set cancelable=(bool value)` +- `bool get cancelable` +- `set composed=(bool value)` +- `bool get composed` + +## Extension type: JSAny + +JSAny + +## Extension type: JSObject + +JSObject + +- `JSObject.fromInteropObject(Object interopObject)` + +## Extension type: ProgressEventInit + +ProgressEventInit + +- `ProgressEventInit({bool lengthComputable, int loaded, int total})` +- `set lengthComputable=(bool value)` +- `bool get lengthComputable` +- `set loaded=(int value)` +- `int get loaded` +- `set total=(int value)` +- `int get total` diff --git a/pkgs/jot/test/fixtures/demo/doc/api/index.md b/pkgs/jot/test/fixtures/demo/doc/api/index.md new file mode 100644 index 00000000..070eea59 --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/doc/api/index.md @@ -0,0 +1,9 @@ +# Package: package:demo + + +## Libraries + +- [demo.dart](demo.md): A sample library to exercise most Dart language features. +- [modifiers_a.dart](modifiers_a.md): + class modifiers (https://dart.dev/language/class-modifiers) +- [modifiers_b.dart](modifiers_b.md) diff --git a/pkgs/jot/test/fixtures/demo/doc/api/modifiers_a.md b/pkgs/jot/test/fixtures/demo/doc/api/modifiers_a.md new file mode 100644 index 00000000..5aae014a --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/doc/api/modifiers_a.md @@ -0,0 +1,45 @@ +# Library: modifiers_a.dart + +class modifiers (https://dart.dev/language/class-modifiers) + +## Members + +## Class: AnimalInterface + +```dart +final class AnimalInterface { … } +``` + +- `void growl(int count)` + +## Class: FruitInterface + +```dart +abstract interface class FruitInterface { … } +``` + +- `void eat(int bites)` + +## Class: Vehicle + +```dart +abstract class Vehicle { … } +``` + +- `void moveForward(int meters)` + +## Class: VehicleBase + +```dart +class VehicleBase { … } +``` + +- `void moveForward(int meters)` + +## Class: VehicleInterface + +```dart +interface class VehicleInterface { … } +``` + +- `void moveForward(int meters)` diff --git a/pkgs/jot/test/fixtures/demo/doc/api/modifiers_b.md b/pkgs/jot/test/fixtures/demo/doc/api/modifiers_b.md new file mode 100644 index 00000000..58cf0bbe --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/doc/api/modifiers_b.md @@ -0,0 +1,41 @@ +# Library: modifiers_b.dart + +## Members + +- accessor `VehicleBase get myVehicle` +- accessor `set myVehicle=(VehicleBase _myVehicle)` +- accessor `VehicleInterface get myVehicle2` +- accessor `set myVehicle2=(VehicleInterface _myVehicle2)` + +## Class: Car + +```dart +class Car extends Vehicle { … } +``` + +- `int passengers` +- `void moveForward(int meters)` + +## Class: CarBase + +```dart +class CarBase extends VehicleBase { … } +``` + +- `int passengers` + +## Class: MockVehicle + +```dart +class MockVehicle implements Vehicle { … } +``` + +- `void moveForward(int meters)` + +## Class: MockVehicleInterface + +```dart +class MockVehicleInterface implements VehicleInterface { … } +``` + +- `void moveForward(int meters)` diff --git a/pkgs/jot/test/fixtures/demo/lib/demo.dart b/pkgs/jot/test/fixtures/demo/lib/demo.dart new file mode 100644 index 00000000..07c43f27 --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/lib/demo.dart @@ -0,0 +1,369 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// A sample library to exercise most Dart language features. + +library; + +import 'dart:io'; +import 'dart:math'; + +// classes (https://dart.dev/language/classes) + +const double xOrigin = 0; +const double yOrigin = 0; + +class Point { + static final Point zero = Point(0, 0); + + final double x, y; + + Point(this.x, this.y); + + // Named constructor + Point.origin() : x = xOrigin, y = yOrigin; + + // factory constructor + factory Point.fromJson(Map json) { + return Point(json['x'] as double, json['y'] as double); + } + + static double distanceBetween(Point a, Point b) { + var dx = a.x - b.x; + var dy = a.y - b.y; + return sqrt(dx * dx + dy * dy); + } +} + +class Vector2d { + final double x; + final double y; + + Vector2d(this.x, this.y); +} + +// super parameters +class Vector3d extends Vector2d { + final double z; + + // Forward the x and y parameters to the default super constructor like: + // Vector3d(final double x, final double y, this.z) : super(x, y); + Vector3d(super.x, super.y, this.z); +} + +class Spacecraft { + String name; + DateTime? launchDate; + + // Read-only non-final property + int? get launchYear => launchDate?.year; + + // Constructor, with syntactic sugar for assignment to members. + Spacecraft(this.name, this.launchDate) { + // Initialization code goes here. + } + + // Named constructor that forwards to the default one. + Spacecraft.unlaunched(String name) : this(name, null); + + // Method. + void describe() { + print('Spacecraft: $name'); + // Type promotion doesn't work on getters. + var launchDate = this.launchDate; + if (launchDate != null) { + var years = DateTime.now().difference(launchDate).inDays ~/ 365; + print('Launched: $launchYear ($years years ago)'); + } else { + print('Unlaunched'); + } + } +} + +// mixins (https://dart.dev/language/mixins) + +class Musician { + // ... +} + +mixin MusicalPerformer on Musician { + // ... +} + +class SingerDancer extends Musician with MusicalPerformer { + // ... +} + +// enums (https://dart.dev/language/enums) + +enum Vehicle implements Comparable { + car(tires: 4, passengers: 5, carbonPerKilometer: 400), + bus(tires: 6, passengers: 50, carbonPerKilometer: 800), + bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0); + + const Vehicle({ + required this.tires, + required this.passengers, + required this.carbonPerKilometer, + }); + + final int tires; + final int passengers; + final int carbonPerKilometer; + + int get carbonFootprint => (carbonPerKilometer / passengers).round(); + + bool get isTwoWheeled => this == Vehicle.bicycle; + + @override + int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint; +} + +// extension methods (https://dart.dev/language/extension-methods) + +extension NumberParsing on String { + int parseInt() { + return int.parse(this); + } + + double parseDouble() { + return double.parse(this); + } +} + +// functions (https://dart.dev/language/functions) + +final List _nobleGases = []; + +bool isNoble(int atomicNumber) { + return _nobleGases[atomicNumber] != null; +} + +// names parameters +void enableFlags({bool? bold, bool? hidden}) {} + +// positional parameters +String say(String from, String msg, [String? device]) { + var result = '$from says $msg'; + if (device != null) { + result = '$result with a $device'; + } + return result; +} + +// returning multiple values +(String, int) foo() { + return ('something', 42); +} + +// generators +Iterable naturalsTo(int n) sync* { + var k = 0; + while (k < n) { + yield k++; + } +} + +Stream asynchronousNaturalsTo(int n) async* { + var k = 0; + while (k < n) { + yield k++; + } +} + +// records (https://dart.dev/language/records) + +(String, String, {int a, bool b}) record = ('first', a: 2, b: true, 'last'); + +(int, int) swap((int, int) record) { + var (a, b) = record; + return (b, a); +} + +(String, int) userInfo(Map json) { + return (json['name'] as String, json['age'] as int); +} + +// generics (https://dart.dev/language/generics) + +abstract class Cache { + T getByKey(String key); + void setByKey(String key, T value); +} + +class Foo { + // Any type provided to Foo for T must be non-nullable. +} + +T first(List ts) { + // Do some initial work or error checking, then... + var tmp = ts[0]; + // Do some additional checking or processing... + return tmp; +} + +// typedefs / type aliases (https://dart.dev/language/typedefs) + +typedef IntList = List; +IntList il = [1, 2, 3]; + +typedef ListMapper = Map>; +Map> m1 = {}; // Verbose. +ListMapper m2 = {}; // Same thing but shorter and clearer. + +// function typedef +typedef Compare = int Function(T a, T b); + +// interfaces and abstract classes (https://dart.dev/language#interfaces-and-abstract-classes) + +class MockSpaceship implements Spacecraft { + @override + DateTime? launchDate; + + @override + String name = 'mock'; + + @override + void describe() => throw UnimplementedError(); + + @override + int? get launchYear => throw UnimplementedError(); +} + +abstract class Describable { + void describe(); + + void describeWithEmphasis() { + print('========='); + describe(); + print('========='); + } +} + +// inheritance (https://dart.dev/language#inheritance) + +class Orbiter extends Spacecraft { + double altitude; + + Orbiter(super.name, DateTime super.launchDate, this.altitude); +} + +// async (https://dart.dev/language#async) + +const oneSecond = Duration(seconds: 1); +// ··· +Future printWithDelay(String message) async { + await Future.delayed(oneSecond); + print(message); +} + +Future createDescriptions(Iterable objects) async { + for (final object in objects) { + try { + var file = File('$object.txt'); + if (await file.exists()) { + var modified = await file.lastModified(); + print('File for $object already exists. It was modified on $modified.'); + continue; + } + await file.create(); + await file.writeAsString('Start describing $object in this file.'); + } on IOException catch (e) { + print('Cannot create description for $object: $e'); + } + } +} + +// variables (https://dart.dev/language#variables) + +// ignore: type_annotate_public_apis +var name = 'Voyager I'; +// ignore: type_annotate_public_apis +var year = 1977; +// ignore: type_annotate_public_apis +var antennaDiameter = 3.7; +// ignore: type_annotate_public_apis +var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune']; +// ignore: type_annotate_public_apis +var image = { + 'tags': ['saturn'], + 'url': '//path/to/saturn.jpg', +}; + +// null safety (https://dart.dev/null-safety/understanding-null-safety) + +String checkList(List? list) { + if (list == null) return 'No list'; + if (list.isEmpty) { + return 'Empty list'; + } + return 'Got something'; +} + +// class modifiers (https://dart.dev/language/class-modifiers) + +sealed class VehicleSealed {} + +class CarSealed extends VehicleSealed {} + +class TruckSealed implements VehicleSealed {} + +class BicycleSealed extends VehicleSealed {} + +// ERROR: Cannot be instantiated +// Vehicle myVehicle = Vehicle(); + +// Subclasses can be instantiated +VehicleSealed myCar = CarSealed(); + +String getVehicleSound(VehicleSealed vehicle) { + // ERROR: The switch is missing the Bicycle subtype or a default case. + return switch (vehicle) { + CarSealed() => 'vroom', + TruckSealed() => 'VROOOOMM', + BicycleSealed() => throw UnimplementedError(), + }; +} + +// extension types (https://dart.dev/language/extension-types) + +abstract class JSObjectRepType {} + +typedef JSAnyRepType = Object; + +extension type JSAny._(JSAnyRepType _jsAny) implements Object {} + +extension type JSObject._(JSObjectRepType _jsObject) implements JSAny { + JSObject.fromInteropObject(Object interopObject) + : _jsObject = interopObject as JSObjectRepType; + + // /// Creates a new JavaScript object. + // JSObject() : _jsObject = _createObjectLiteral(); +} + +extension type EventInit._(JSObject _) implements JSObject { + external factory EventInit({bool bubbles, bool cancelable, bool composed}); + + external set bubbles(bool value); + external bool get bubbles; + external set cancelable(bool value); + external bool get cancelable; + external set composed(bool value); + external bool get composed; +} + +extension type ProgressEventInit._(JSObject _) implements EventInit, JSObject { + external factory ProgressEventInit({ + bool lengthComputable, + int loaded, + int total, + }); + + external set lengthComputable(bool value); + external bool get lengthComputable; + external set loaded(int value); + external int get loaded; + external set total(int value); + external int get total; +} diff --git a/pkgs/jot/test/fixtures/demo/lib/modifiers_a.dart b/pkgs/jot/test/fixtures/demo/lib/modifiers_a.dart new file mode 100644 index 00000000..e6f59470 --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/lib/modifiers_a.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// class modifiers (https://dart.dev/language/class-modifiers) +library; + +// abstract + +abstract class Vehicle { + void moveForward(int meters); +} + +// base + +base class VehicleBase { + void moveForward(int meters) { + // ... + } +} + +// interface + +interface class VehicleInterface { + void moveForward(int meters) { + // ... + } +} + +abstract interface class FruitInterface { + void eat(int bites) { + // ... + } +} + +final class AnimalInterface { + void growl(int count) { + // ... + } +} diff --git a/pkgs/jot/test/fixtures/demo/lib/modifiers_b.dart b/pkgs/jot/test/fixtures/demo/lib/modifiers_b.dart new file mode 100644 index 00000000..1584f359 --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/lib/modifiers_b.dart @@ -0,0 +1,66 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'modifiers_a.dart'; + +// abstract + +// Error: Cannot be constructed +// Vehicle myVehicle = Vehicle(); + +// Can be extended +class Car extends Vehicle { + int passengers = 4; + + @override + void moveForward(int meters) { + // TODO: implement moveForward + } +} + +// Can be implemented +class MockVehicle implements Vehicle { + @override + void moveForward(int meters) { + // ... + } +} + +// base + +// Can be constructed +VehicleBase myVehicle = VehicleBase(); + +// Can be extended +base class CarBase extends VehicleBase { + int passengers = 4; + // ... +} + +// ERROR: Cannot be implemented +// base class MockVehicleBase implements VehicleBase { +// @override +// void moveForward() { +// // ... +// } +// } + +// interface + +// Can be constructed +VehicleInterface myVehicle2 = VehicleInterface(); + +// ERROR: Cannot be inherited +// class Car extends Vehicle { +// int passengers = 4; +// // ... +// } + +// Can be implemented +class MockVehicleInterface implements VehicleInterface { + @override + void moveForward(int meters) { + // ... + } +} diff --git a/pkgs/jot/test/fixtures/demo/pubspec.yaml b/pkgs/jot/test/fixtures/demo/pubspec.yaml new file mode 100644 index 00000000..484c0626 --- /dev/null +++ b/pkgs/jot/test/fixtures/demo/pubspec.yaml @@ -0,0 +1,8 @@ +name: demo +version: 0.1.0 +publish_to: none + +resolution: workspace + +environment: + sdk: ^3.9.0 diff --git a/pkgs/jot/test/fixtures/server/lib/a.dart b/pkgs/jot/test/fixtures/server/lib/a.dart new file mode 100644 index 00000000..2dd0eea7 --- /dev/null +++ b/pkgs/jot/test/fixtures/server/lib/a.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +void bar(String param) {} + +class A { + void foo() {} +} diff --git a/pkgs/jot/test/fixtures/server/lib/b.dart b/pkgs/jot/test/fixtures/server/lib/b.dart new file mode 100644 index 00000000..30a2e7f6 --- /dev/null +++ b/pkgs/jot/test/fixtures/server/lib/b.dart @@ -0,0 +1,5 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +void baz(int param) {} diff --git a/pkgs/jot/test/fixtures/server/pubspec.yaml b/pkgs/jot/test/fixtures/server/pubspec.yaml new file mode 100644 index 00000000..6d22b343 --- /dev/null +++ b/pkgs/jot/test/fixtures/server/pubspec.yaml @@ -0,0 +1,7 @@ +name: server_demo +publish_to: none + +resolution: workspace + +environment: + sdk: ^3.9.0 diff --git a/pkgs/jot/test/index_test.dart b/pkgs/jot/test/index_test.dart new file mode 100644 index 00000000..198e3128 --- /dev/null +++ b/pkgs/jot/test/index_test.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:convert'; + +import 'package:jot/src/index.dart'; +import 'package:test/test.dart'; + +void main() { + test('empty', () { + var index = Index(); + + var text = index.toJson(); + var json = jsonDecode(text); + expect(json, isEmpty); + }); + + test('ref', () { + var index = Index(); + var package = index.add('package:foo', 'package'); + package.add('main.dart', 'library', ref: 'main.html'); + + var text = index.toJson(); + var json = jsonDecode(text); + expect(json, isNotEmpty); + var packageRef = _Item((json as List)[0] as _JsonType); + var libraryRef = packageRef.children[0]; + expect(libraryRef.ref, isNotEmpty); + }); + + test('id', () { + var index = Index(); + var package = index.add('package:foo', 'package'); + var library = package.add('main.dart', 'library', ref: 'main.html'); + library.add('foo', 'field', id: 'foo'); + + var text = index.toJson(); + var json = jsonDecode(text); + expect(json, isNotEmpty); + var packageRef = _Item((json as List)[0] as _JsonType); + var libraryRef = packageRef.children[0]; + var fieldRef = libraryRef.children[0]; + expect(fieldRef.id, isNotEmpty); + }); + + test('simple', () { + var index = Index(); + var package = index.add('package:foo', 'package'); + var library = package.add('main.dart', 'library', ref: 'main.html'); + library.add('foo', 'field', id: 'foo'); + library.add('bar', 'method', id: 'bar'); + + var text = index.toJson(); + var json = jsonDecode(text); + expect(json, isNotEmpty); + }); +} + +typedef _JsonType = Map; + +class _Item { + final _JsonType json; + + _Item(this.json); + + List<_Item> get children { + if (!json.containsKey('c')) return []; + return (json['c'] as List).map((json) => _Item(json as _JsonType)).toList(); + } + + String get name => json['n'] as String; + String get type => json['t'] as String; + String? get ref => json['ref'] as String?; + String? get id => + (json['#'] as String?) ?? (!json.containsKey('c') ? name : null); +} diff --git a/pkgs/jot/test/llm_summary_test.dart b/pkgs/jot/test/llm_summary_test.dart new file mode 100644 index 00000000..f228ec7f --- /dev/null +++ b/pkgs/jot/test/llm_summary_test.dart @@ -0,0 +1,84 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:jot/api.dart'; +import 'package:jot/src/llm_summary.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; + +import 'support.dart'; + +// LLM markdown summary integration tests using test/fixtures/demo. + +void main() { + group('signature', () { + late final TestProject demoProject; + + setUpAll(() async { + demoProject = TestProject.fromTemplate( + Directory(p.join('test', 'fixtures', 'demo')), + ); + await demoProject.init(); + }); + + tearDownAll(() { + demoProject.dispose(); + }); + + Directory? tempDir; + + setUp(() { + tempDir = Directory.systemTemp.createTempSync(); + }); + + tearDown(() { + tempDir?.deleteSync(); + }); + + LibraryItemContainer library(String name) { + final package = demoProject.workspace.api.packages.single; + return package.libraries.firstWhere((lib) => lib.name == name); + } + + test('demo.dart', () { + final sig = LLMSummary( + workspace: demoProject.workspace, + outDir: tempDir!, + logger: NullLogger(), + ); + + final actual = sig.generateForLibrary(library('demo.dart')); + expect(actual, golden('demo.md')); + }); + + test('modifiers_a.dart', () { + final sig = LLMSummary( + workspace: demoProject.workspace, + outDir: tempDir!, + logger: NullLogger(), + ); + + final actual = sig.generateForLibrary(library('modifiers_a.dart')); + expect(actual, golden('modifiers_a.md')); + }); + + test('modifiers_b.dart', () { + final sig = LLMSummary( + workspace: demoProject.workspace, + outDir: tempDir!, + logger: NullLogger(), + ); + + final actual = sig.generateForLibrary(library('modifiers_b.dart')); + expect(actual, golden('modifiers_b.md')); + }); + }); +} + +String golden(String sigName) { + final path = p.join('test', 'fixtures', 'demo', 'doc', 'api', sigName); + return File(path).readAsStringSync(); +} diff --git a/pkgs/jot/test/render_test.dart b/pkgs/jot/test/render_test.dart new file mode 100644 index 00000000..983f4580 --- /dev/null +++ b/pkgs/jot/test/render_test.dart @@ -0,0 +1,289 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/element/element.dart'; +import 'package:jot/api.dart'; +import 'package:jot/src/render.dart'; +import 'package:test/test.dart'; + +import 'support.dart'; + +void main() { + group('LinkedCodeRenderer', () { + testWithSource( + 'handleConstructor', + ''' +class A { + A(); +} +''', + (TestProject project) { + final interfaceItem = project.classNamed('A'); + final item = interfaceItem.allChildren.firstWhere( + (item) => item.element is ConstructorElement, + ); + final renderer = project.rendererFor(item); + final result = renderer.render(GroupType.typeFor(item.element), item); + + expect(result, '
    A()
    '); + }, + ); + + testWithSource( + 'handleField', + ''' +class A { + final String foo = 'bar'; +} +''', + (TestProject project) { + final interfaceItem = project.classNamed('A'); + final item = interfaceItem.allChildren.firstWhere( + (item) => item.element is FieldElement, + ); + final renderer = project.rendererFor(item); + final result = renderer.render(GroupType.typeFor(item.element), item); + + expect( + result, + '
    String foo
    ', + ); + }, + ); + + testWithSource( + 'handleAccessor', + ''' +String get foo => 'bar'; +''', + (TestProject project) { + final library = project.firstLibrary; + final item = library.allChildren.firstWhere( + (item) => item.element is PropertyAccessorElement, + ); + final renderer = LinkedCodeRenderer( + project.resolver, + project.resolver.fileFor(library.element)!, + ); + final result = renderer.render(GroupType.typeFor(item.element), item); + + expect( + result, + '
    String get foo
    ', + ); + }, + ); + + testWithSource( + 'handleMethod', + ''' +class A { + String foo() => 'bar'; +} +''', + (TestProject project) { + final interfaceItem = project.classNamed('A'); + final item = interfaceItem.allChildren.firstWhere( + (item) => item.element is MethodElement, + ); + final renderer = project.rendererFor(item); + final result = renderer.render(GroupType.typeFor(item.element), item); + + expect( + result, + '
    String foo()
    ', + ); + }, + ); + + testWithSource( + 'handleFunction', + r''' +String foo(Object param1) => 'bar: $param1'; +''', + (TestProject project) { + final item = project.firstLibrary.allChildren.firstWhere( + (item) => item.element is FunctionElement, + ); + final renderer = project.rendererFor(item); + final result = renderer.render(GroupType.typeFor(item.element), item); + + expect( + result, + '
    String foo(Object param1)
    ', + ); + }, + ); + + testWithSource( + 'handleTypeAlias', + r''' +typedef ListMapper = Map>; + +typedef Compare = int Function(T a, T b); +''', + (TestProject project) { + var item = project.itemNamed('ListMapper'); + final renderer = project.rendererFor(item); + var result = renderer.render(GroupType.typeFor(item.element), item); + + expect( + result, + '
    '
    +          'typedef ListMapper<X> = Map<X, List<X>>'
    +          '
    ', + ); + + item = project.itemNamed('Compare'); + result = renderer.render(GroupType.typeFor(item.element), item); + + expect( + result, + '
    '
    +          'typedef Compare<T> = int Function(T, T)'
    +          '
    ', + ); + }, + ); + + testWithSource( + 'handleMixin', + ''' +class Musician { } + +mixin MusicalPerformer on Musician { } +''', + (TestProject project) { + final interfaceItem = project.classNamed('MusicalPerformer'); + final renderer = project.rendererFor(interfaceItem); + final result = renderer.render( + GroupType.typeFor(interfaceItem.element), + interfaceItem, + ); + + expect( + result, + '
    '
    +          'mixin MusicalPerformer on Musician { … }'
    +          '
    ', + ); + }, + ); + + testWithSource( + 'handleClass', + ''' +class A extends B { + final String foo = 'bar'; +} +class B { } +''', + (TestProject project) { + final interfaceItem = project.classNamed('A'); + final renderer = project.rendererFor(interfaceItem); + final result = renderer.render( + GroupType.typeFor(interfaceItem.element), + interfaceItem, + ); + + expect( + result, + '
    '
    +          'class A extends B { … }'
    +          '
    ', + ); + }, + ); + + testWithSource( + 'handleEnum', + ''' +enum Animals { + cat, + dog; +} +''', + (TestProject project) { + final item = project.firstInterfaceItem; + + final renderer = LinkedCodeRenderer( + project.resolver, + project.resolver.fileFor(item.element)!, + ); + final result = renderer.render(GroupType.$enum, item); + + expect( + result, + '
    enum Animals { … }
    ', + ); + }, + ); + + testWithSource( + 'handleExtension', + ''' +extension NumberParsing on String { + int parseInt() => int.parse(this); +} +''', + (TestProject project) { + final item = project.firstItem as Items; + final renderer = project.rendererFor(item); + final result = renderer.render(GroupType.typeFor(item.element), item); + + expect( + result, + '
    '
    +          'extension NumberParsing on String { … }'
    +          '
    ', + ); + }, + ); + + testWithSource( + 'handleExtensionType', + ''' +abstract class JSObjectRepType {} + +extension type JSAny._(Object _jsAny) implements Object {} + +extension type JSObject._(JSObjectRepType _jsObject) implements JSAny { + JSObject.fromInteropObject(Object interopObject) + : _jsObject = interopObject as JSObjectRepType; +} +''', + (TestProject project) { + final extensionTypeNamedJSAny = project.extensionTypeNamed('JSAny'); + final renderer = project.rendererFor(extensionTypeNamedJSAny); + var result = renderer.render( + GroupType.$extensionType, + extensionTypeNamedJSAny, + ); + + expect( + result, + '
    '
    +          'extension type JSAny._(Object _jsAny) implements Object { … }'
    +          '
    ', + ); + + final extensionTypeNamedJSObject = project.extensionTypeNamed( + 'JSObject', + ); + result = renderer.render( + GroupType.$extensionType, + extensionTypeNamedJSObject, + ); + + expect( + result, + '
    '
    +          'extension type JSObject._(JSObjectRepType _jsObject) '
    +          'implements JSAny { … }'
    +          '
    ', + ); + }, + ); + }); +} diff --git a/pkgs/jot/test/server_test.dart b/pkgs/jot/test/server_test.dart new file mode 100644 index 00000000..b388e9d1 --- /dev/null +++ b/pkgs/jot/test/server_test.dart @@ -0,0 +1,66 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:http/http.dart' as http; +import 'package:jot/jot.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; + +import 'support.dart'; + +// Server (--serve) integration tests using test/fixtures/demo. + +void main() { + group('server', () { + late final DocServer server; + late final Directory tempDir; + + setUpAll(() async { + final sourceDir = Directory(p.join('test', 'fixtures', 'server')); + tempDir = Directory.systemTemp.createTempSync('jot'); + + final jot = Jot(inDir: sourceDir, outDir: tempDir, logger: NullLogger()); + server = await jot.serve(0); + }); + + tearDownAll(() async { + tempDir.deleteSync(recursive: true); + await server.dispose(); + }); + + test('index.html', () async { + final response = await http.read( + Uri.http('localhost:${server.port}', 'index.html'), + ); + expect(response, contains('package:server_demo')); + }); + + test('a.html', () async { + var response = await http.read( + Uri.http('localhost:${server.port}', 'a.html'), + ); + expect(response, contains('

    a.dart

    ')); + expect(response, contains('bar(')); + expect(response, contains('Classes')); + + response = await http.read( + Uri.http('localhost:${server.port}', 'a/A.html'), + ); + expect(response, contains('

    A

    ')); + expect(response, contains('class A')); + expect(response, contains('foo()')); + }); + + test('b.html', () async { + final response = await http.read( + Uri.http('localhost:${server.port}', 'b.html'), + ); + expect(response, contains('

    b.dart

    ')); + expect(response, contains('baz(')); + expect(response, isNot(contains('Classes'))); + }); + }); +} diff --git a/pkgs/jot/test/support.dart b/pkgs/jot/test/support.dart new file mode 100644 index 00000000..bbefb8f8 --- /dev/null +++ b/pkgs/jot/test/support.dart @@ -0,0 +1,220 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:analyzer/dart/element/element.dart'; +import 'package:cli_util/cli_logging.dart'; +import 'package:jot/api.dart'; +import 'package:jot/src/analysis.dart'; +import 'package:jot/src/html.dart'; +import 'package:jot/src/render.dart'; +import 'package:jot/workspace.dart'; +import 'package:meta/meta.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; + +@isTest +void testWithSource( + String description, + String source, + void Function(TestProject) body, +) { + test(description, () async { + final project = TestProject({'main.dart': source}); + + try { + await project.init(); + + body(project); + } finally { + project.dispose(); + } + }); +} + +class TestProject { + final Directory dir; + final Map sources; + + late final Workspace workspace; + late final Analyzer analyzer; + + TestProject(this.sources) : dir = Directory.systemTemp.createTempSync(); + + factory TestProject.fromTemplate(Directory dir) { + final libDir = Directory(p.join(dir.path, 'lib')); + final files = libDir + .listSync() + .whereType() + .where((file) => file.path.endsWith('.dart')) + .toList(); + return TestProject({ + for (var file in files) + p.relative(file.path, from: libDir.path): file.readAsStringSync(), + }); + } + + String get libDirPath => p.join(dir.path, 'lib'); + + Directory get outDir => Directory(p.join(dir.path, 'doc', 'api')); + + Resolver get resolver => workspace.api.resolver; + + List get libraries => + workspace.api.packages.first.libraries; + + LibraryItemContainer get firstLibrary => libraries.first; + + Item get firstItem => firstLibrary.allChildren.first; + + Item itemNamed(String name) => + firstLibrary.allChildren.firstWhere((item) => item.element.name == name); + + Items get firstInterfaceItem => + firstLibrary.allChildren.firstWhere( + (item) => item.element is InterfaceElement, + ) + as Items; + + Items classNamed(String name) => + firstLibrary.allChildren.firstWhere( + (item) => + item.element is InterfaceElement && item.element.name == name, + ) + as Items; + + Items extensionTypeNamed(String name) => + firstLibrary.allChildren.firstWhere( + (item) => + // ignore: experimental_member_use + item.element is ExtensionTypeElement && + item.element.name == name, + ) + as Items; + + LinkedCodeRenderer rendererFor(Item item) { + return LinkedCodeRenderer(resolver, resolver.fileFor(item.element)!); + } + + void _create() { + final pubspec = File(p.join(dir.path, 'pubspec.yaml')); + pubspec.writeAsStringSync('name: testing'); + + Directory(libDirPath).createSync(); + + for (final entry in sources.entries) { + final file = File(p.join(libDirPath, entry.key)); + file.writeAsStringSync(entry.value); + } + } + + Future init() async { + _create(); + + final htmlTemplate = await HtmlTemplate.createDefault(); + workspace = Workspace.fromPackage(htmlTemplate, dir); + var packageName = workspace.name.substring('package:'.length); + + analyzer = Analyzer.packages( + includedPaths: [p.normalize(dir.absolute.path)], + ); + + await for (var resolvedLibrary in analyzer.resolvedPublicLibraries()) { + var libraryPath = resolvedLibrary.element.source.fullName; + + var dartLibraryPath = p.relative(libraryPath, from: libDirPath); + var htmlOutputPath = '${p.withoutExtension(dartLibraryPath)}.html'; + + var libraryContainer = workspace.addChild( + WorkspaceDirectory(workspace, dartLibraryPath), + ); + + var library = workspace.api.addLibrary( + resolvedLibrary.element, + workspace.name, + dartLibraryPath, + ); + + libraryContainer.mainFile = WorkspaceFile( + workspace, + dartLibraryPath, + htmlOutputPath, + emptyContentGenerator, + )..importScript = 'package:$packageName/$dartLibraryPath'; + + workspace.api.addResolution(library, libraryContainer.mainFile!); + + for (var itemContainer in library.allChildrenSorted.whereType()) { + var path = + '${p.withoutExtension(dartLibraryPath)}/${itemContainer.name}.html'; + var docFile = WorkspaceFile( + libraryContainer, + itemContainer.name, + path, + emptyContentGenerator, + ); + libraryContainer.addChild(docFile); + workspace.api.addResolution(itemContainer, docFile); + } + } + + workspace.api.finish(); + } + + void dispose() { + dir.deleteSync(recursive: true); + } +} + +class NullLogger implements Logger { + final Ansi _ansi = Ansi(false); + + @override + Ansi get ansi => _ansi; + + @override + void flush() {} + + @override + bool get isVerbose => false; + + @override + Progress progress(String message) => NullProgress(message); + + @override + void stderr(String message) {} + + @override + void stdout(String message) {} + + @override + void trace(String message) {} + + @override + void write(String message) {} + + @override + void writeCharCode(int charCode) {} +} + +class NullProgress implements Progress { + @override + final String message; + + final Stopwatch _timer = Stopwatch()..start(); + + NullProgress(this.message); + + @override + void cancel() {} + + @override + Duration get elapsed => _timer.elapsed; + + @override + void finish({String? message, bool showTiming = false}) { + _timer.stop(); + } +} diff --git a/pkgs/jot/third_party/docusaurus/LICENSE b/pkgs/jot/third_party/docusaurus/LICENSE new file mode 100644 index 00000000..b96dcb04 --- /dev/null +++ b/pkgs/jot/third_party/docusaurus/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pkgs/jot/third_party/docusaurus/README.md b/pkgs/jot/third_party/docusaurus/README.md new file mode 100644 index 00000000..2c1aeea3 --- /dev/null +++ b/pkgs/jot/third_party/docusaurus/README.md @@ -0,0 +1,9 @@ +The CSS page layout for this API generator are sourced from the +[Docusaurus](https://docusaurus.io/) project. + +See https://github.com/facebook/docusaurus. + +Docusaurus resources: + +- lib/resources/styles-dark.css +- lib/resources/styles-light.css diff --git a/pkgs/jot/todo.md b/pkgs/jot/todo.md new file mode 100644 index 00000000..7a147122 --- /dev/null +++ b/pkgs/jot/todo.md @@ -0,0 +1,95 @@ +# TODO + +- [x] script for doc'ing the dart sdk +- [x] script for doc'ing flutter +- [x] support generating package:flutter +- [x] cleaner API for generation +- [ ] support generating the flutter SDK +- [ ] libraries should have a section for symbols exported from other libs +- [ ] classes should have a section for symbols inherited from parent classes +- [ ] use pragmas to control dartdoc specific imports +- [ ] support front-matter for markdown files? +- [ ] switch over to reading the dart sdk libraries declaratively + +## Model elements + +- [x] item (documentable, backed by an element) +- [x] items +- [x] group and group ordering + +## Testing + +- [x] tests for LinkedCodeRenderer +- [x] tests for markdown signature feature +- [ ] tests for workspace code +- [ ] tests for api code +- [ ] tests for DartFormat + +source code => api => generation? +source code => workspace? +we don't need to test at the html level; is the api model well-formed? can we +separately convert from api to html correctly? + +### Language features + +- [ ] tests for language features + +## Html output + +- [x] clean +- [x] small +- [ ] smaller css +- [ ] version the css (from Infima) + +## Page layout and nav + +- [x] dart script +- [x] full SPA +- [x] convert the left-nav to runtime generated +- [x] manage the scroll during page transitions +- [x] simplify wrappers around DOM +- [ ] ensure items in the left nav scroll into focus on page changes +- [ ] ensure we don't reload a page when navigating within the same page +- [ ] update outline view selection on page scroll + +## Search + +- [x] simple, comprehensive + +## Server + +- [x] have a server mode; allow preview of docs, and refreshing will pick up + file changes and re-generate +- [x] test --serve; we can ping localhost and get expected pages + +## Generation + +- [x] no args +- [x] cli just supports documenting packages +- [x] more sophisticated use cases (dart sdk, flutter) should use the package as + a library +- [x] fast +- [ ] configuration via a yaml file + +## Fixes + +- [x] have a method to convert from an element to a valid in-page ID +- [x] rename the resources directory to prevent namespace conflicts +- [ ] fix issues with top-level vars vs. getters vs setters in the model +- [ ] make sure a field is documented as a field and not as a getter and setter + +## Completeness + +- [ ] indicate which API members are exports from other libraries +- [ ] correctly determine where to document elements for Flutter (for things + exported from multiple libraries) +- [ ] determine the export chain length (e.g. symbol A is exported from B, C, + defined in D) +- [ ] support for dartdoc categories +- [ ] support for resolving qualified (foo.Bar) dartdoc references +- [ ] support for flutter phantom references +- [ ] support for dartdoc macros (`{@template foo-bar}` / `{@macro foo-bar}`) + +## Other + +- [x] generate a markdown file representing the package's public API diff --git a/pkgs/jot/tool/build_web.dart b/pkgs/jot/tool/build_web.dart new file mode 100644 index 00000000..5ea2a5a2 --- /dev/null +++ b/pkgs/jot/tool/build_web.dart @@ -0,0 +1,119 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:crypto/crypto.dart'; + +void main(List args) async { + var argsParser = ArgParser() + ..addFlag( + 'help', + abbr: 'h', + negatable: false, + help: 'Show this command help.', + ) + ..addFlag( + 'optimize', + defaultsTo: true, + help: 'Build with dart2js optimization flags enabled.', + ) + ..addFlag( + 'verify', + negatable: false, + help: + 'Verify the compilation signature against lib/resources/script.sig.', + ); + + var argsResult = argsParser.parse(args); + + final help = argsResult['help'] as bool; + + if (help) { + print('usage: dart tool/build_web.dart [options]'); + print(''); + print(argsParser.usage); + exit(0); + } + + final optimize = argsResult['optimize'] as bool; + final shouldVerify = argsResult['verify'] as bool; + if (shouldVerify) { + await verify(); + } else { + await build(optimize); + } +} + +Future build(bool optimize) async { + // dart compile js -o lib/resources/script.js + var params = [ + 'compile', + 'js', + if (optimize) '-O2', + '-o', + 'lib/resources/script.js', + 'web/main.dart', + ]; + print('dart ${params.join(' ')}'); + var result = await Process.run(Platform.resolvedExecutable, params); + if ((result.stdout as String).trim().isNotEmpty) { + stdout.write(result.stdout as String); + } + if ((result.stderr as String).trim().isNotEmpty) { + stderr.write(result.stderr as String); + } + if (result.exitCode != 0) { + exit(result.exitCode); + } + + final sigFile = File('lib/resources/script.sig'); + var sig = await calcSig(); + sigFile.writeAsStringSync('$sig\n'); +} + +Future verify() async { + var sig = await calcSig(); + + var existing = File('lib/resources/script.sig').readAsStringSync().trim(); + if (existing != sig) { + stderr.writeln( + 'Compilation artifacts not up-to-date; ' + "re-run 'dart tool/build_web.dart'.", + ); + exit(1); + } else { + print('Compilation artifacts up-to-date.'); + } +} + +Future calcSig() async { + final digest = await _fileLines() + .transform(utf8.encoder) + .transform(md5) + .single; + + return digest.bytes + .map((byte) => byte.toRadixString(16).padLeft(2, '0').toUpperCase()) + .join(); +} + +Stream _fileLines() async* { + // Collect lib/ Dart files. + final files = + Directory('web') + .listSync(recursive: true) + .whereType() + .where((file) => file.path.endsWith('.dart')) + .toList() + ..sort((a, b) => a.path.toLowerCase().compareTo(b.path.toLowerCase())); + + for (var file in files) { + for (var line in file.readAsLinesSync()) { + yield line; + } + } +} diff --git a/pkgs/jot/tool/create_dart_sdk.dart b/pkgs/jot/tool/create_dart_sdk.dart new file mode 100644 index 00000000..f5bc4a99 --- /dev/null +++ b/pkgs/jot/tool/create_dart_sdk.dart @@ -0,0 +1,330 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:cli_util/cli_logging.dart'; +import 'package:jot/api.dart'; +import 'package:jot/src/analysis.dart'; +import 'package:jot/src/generate.dart'; +import 'package:jot/src/html.dart'; +import 'package:jot/src/llm_summary.dart'; +import 'package:jot/src/utils.dart'; +import 'package:jot/workspace.dart'; +import 'package:path/path.dart' as p; + +void main(List args) async { + var parser = createArgsParser(); + ArgResults results; + + try { + results = parser.parse(args); + } catch (e) { + printUsage(parser, e); + exit(64); + } + + var help = results['help'] as bool; + if (help) { + printUsage(parser); + exit(0); + } + + var rest = results.rest; + var sdkDir = rest.isEmpty ? detectSdk : Directory(rest.first); + if (!sdkDir.existsSync()) { + stderr.writeln("error: '${sdkDir.path}' does not exist."); + exit(1); + } + + validateSdk(sdkDir); + + var outDir = Directory(results['output'] as String); + + await generate(sdkDir, outDir); +} + +Future generate(Directory sdkDir, Directory outDir) async { + var log = Logger.standard(); + + if (!outDir.existsSync()) { + outDir.createSync(recursive: true); + } + + var versionFile = File(p.join(sdkDir.path, 'version')); + final version = _parserSdkVersion(versionFile); + + log.stdout('SDK ${sdkDir.path}'); + log.stdout('Version $version'); + log.stdout(''); + + var progress = log.progress('Resolving SDK libraries'); + + // parse the libraries file + var librariesFile = File(p.join(sdkDir.path, 'lib', 'libraries.json')); + var libraries = + jsonDecode(librariesFile.readAsStringSync()) as Map; + + var libNames = Directory(p.join(sdkDir.path, 'lib')) + .listSyncSorted() + .whereType() + .map((d) => d.name) + .where((name) => !name.startsWith('_')) + .where((name) => libraryUriFor(name, libraries) != null) + .toList(); + + const knownVmLibs = {'cli', 'ffi', 'io', 'isolate', 'mirrors'}; + + const knownWebLibs = { + 'html', + 'indexed_db', + 'js', + 'js_interop_unsafe', + 'js_interop', + 'js_util', + 'svg', + 'web_audio', + 'web_gl', + }; + + var vmLibs = libNames.toSet().intersection(knownVmLibs).toList()..sort(); + var webLibs = libNames.toSet().intersection(knownWebLibs).toList()..sort(); + var coreLibs = + (libNames.toSet() + ..removeAll(webLibs) + ..removeAll(vmLibs)) + .toList(); + + // set up the analysis context + var analyzer = Analyzer.packages( + includedPaths: [p.normalize(sdkDir.absolute.path)], + ); + + // create the workspace + var stats = Stats()..start(); + var htmlTemplate = await HtmlTemplate.createDefault(); + var workspace = Workspace('Dart SDK', htmlTemplate: htmlTemplate); + workspace.version = version; + workspace.footer = 'Dart SDK $version'; + final sdkReadmeFile = File(p.join(sdkDir.path, 'lib', 'api_readme.md')); + workspace.mainFile = WorkspaceFile( + workspace, + 'Readme', + 'index.html', + createMarkdownGenerator(sdkReadmeFile), + FileType.markdown, + ); + workspace.description = sdkReadmeFile.readAsStringSync(); + + final api = workspace.api; + + // workspace.addChild(DocSeparator(workspace, 'Dart SDK')); + + final libDir = Directory(p.join(sdkDir.path, 'lib')); + for (var entry in { + 'Core libraries': coreLibs, + 'VM libraries': vmLibs, + 'Web libraries': webLibs, + }.entries) { + var categoryName = entry.key; + var libNames = entry.value; + + workspace.addChild(WorkspaceSeparator(workspace, categoryName)); + + // var categoryContainer = + // workspace.addChild(DocContainer(workspace, categoryName)); + + for (var libName in libNames) { + var libUrl = libraryUriFor(libName, libraries)!; + + var libFile = File(p.join(libDir.path, libUrl)); + var libraryElement = await analyzer.getLibraryByUri( + libFile.uri.toString(), + ); + + var packageContainer = workspace.addChild( + WorkspaceDirectory(workspace, 'dart:$libName'), + ); + + var library = api.addLibrary( + libraryElement.element, + 'Dart SDK', + 'dart:$libName', + ); + var file = WorkspaceFile( + packageContainer, + 'dart:$libName', + '$libName.html', + libraryGenerator(library), + ); + file.importScript = file.name; + packageContainer.mainFile = file; + + api.addResolution(library, packageContainer.mainFile!); + + for (var itemContainer in library.allChildrenSorted.whereType()) { + var path = '$libName/${itemContainer.name}.html'; + var docFile = packageContainer.addChild( + WorkspaceFile( + packageContainer, + itemContainer.name, + path, + itemsGenerator(itemContainer), + ), + ); + api.addResolution(itemContainer, docFile); + } + } + + workspace.api.packages.first.version = workspace.version; + workspace.api.packages.first.description = workspace.description; + } + + // workspace.addChild(DocSeparator(workspace, 'Core Packages')); + + // Add a few packages - path, args, collection, ... + // todo: This is temporary for now; decide whether we do want to document the + // sdk w/ a core set of packages or not. + + // workspace.addPackage( + // analyzer, 'args', getPackageRoot(Directory.current, 'args')!); + // workspace.addPackage( + // analyzer, + // 'collection', + // getPackageRoot(Directory.current, 'collection')!, + // ); + // workspace.addPackage( + // analyzer, 'path', getPackageRoot(Directory.current, 'path')!); + + progress.cancel(); + + // build model + api.finish(); + + // generate + log.stdout(''); + log.stdout('Generating docs...'); + + // generate docs + final generator = Generator( + workspace: workspace, + outDir: outDir, + logger: log, + stats: stats, + ); + await generator.generate(); + + // generate the markdown summary files + final summary = LLMSummary( + workspace: workspace, + outDir: outDir, + logger: log, + stats: stats, + ); + summary.generate(); + + stats.stop(); + + log.stdout(''); + // "1,347 symbols, 82% have documentation, 4 libraries, 8MB of html, 0.3s" + log.stdout( + 'Wrote docs to ${p.relative(outDir.path)} in ' + '${stats.elapsedSeconds}s (${stats.fileCount} files, ' + '${stats.sizeDesc}).', + ); +} + +String _parserSdkVersion(File versionFile) { + var version = versionFile.readAsStringSync().trim(); + if (version.contains(' ')) { + version = version.substring(0, version.indexOf(' ')); + } + if (version.contains('-edge.')) { + // Dart SDK 3.0.0-edge.3ad45940d6e...a585d088639f5 + version = version.substring(0, version.lastIndexOf('.')); + } + return version; +} + +String? libraryUriFor(String name, Map libraries) { + for (var key in libraries.keys) { + var value = libraries[key]; + if (value is Map && value.containsKey('libraries')) { + var info = value['libraries'] as Map; + if (info.containsKey(name)) { + return (info[name] as Map)['uri'] as String?; + } + } + } + + return null; +} + +ArgParser createArgsParser() { + return ArgParser() + ..addFlag( + 'help', + abbr: 'h', + negatable: false, + help: 'Print this command help.', + ) + ..addOption( + 'output', + abbr: 'o', + defaultsTo: 'doc/sdk', + help: 'Configure the output directory.', + ); +} + +void printUsage(ArgParser parser, [Object? error]) { + if (error != null) { + print(error); + } else { + print('Generate API documentation for the Dart SDK.'); + } + + print(''); + + print('usage: dart tool/create_dart_sdk.dart []'); + print(''); + print(parser.usage); +} + +Directory get detectSdk { + final vm = Platform.resolvedExecutable; + // /bin/dart + return Directory(p.dirname(p.dirname(vm))); +} + +void validateSdk(Directory sdk) { + var versionFile = File(p.join(sdk.path, 'version')); + if (!versionFile.existsSync()) { + stderr.writeln('Invalid SDK (${sdk.path}) - missing version file'); + exit(1); + } + + var librariesFile = File(p.join(sdk.path, 'lib', 'libraries.json')); + if (!librariesFile.existsSync()) { + stderr.writeln('Invalid SDK (${sdk.path}) - missing libraries file'); + exit(1); + } +} + +// ignore: unreachable_from_main +extension WorkspaceExtension on Workspace { + // ignore: unreachable_from_main + void addPackage( + Analyzer analyzer, + String packageName, + String fullPackagePath, + ) { + // todo: find the file location + + // todo: get the element info + + // todo: find the public libraries + } +} diff --git a/pkgs/jot/tool/create_flutter_sdk.dart b/pkgs/jot/tool/create_flutter_sdk.dart new file mode 100644 index 00000000..004c001e --- /dev/null +++ b/pkgs/jot/tool/create_flutter_sdk.dart @@ -0,0 +1,141 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:args/args.dart'; +import 'package:cli_util/cli_logging.dart'; +import 'package:path/path.dart' as p; + +// todo: generate for flutter and some core packges +// characters: 1.3.0 +// collection: 1.17.1 +// js: 0.6.7 +// material_color_utilities: 0.3.0 +// meta: 1.9.1 +// vector_math: 2.1.4 +// sky_engine: + +// flutter_test + +// todo: add workspace separators (named and unnamed) +// (or use a named group?) + +// todo: add the flutter sdk (flutter and flutter_test) + +// todo: add a placeholder for the dart sdk + +// todo: add an area for general packages + +void main(List args) async { + var parser = createArgsParser(); + ArgResults results; + + try { + results = parser.parse(args); + } catch (e) { + printUsage(parser, e); + exit(64); + } + + var help = results['help'] as bool; + if (help) { + printUsage(parser); + exit(0); + } + + var rest = results.rest; + var sdkDir = rest.isEmpty + ? calcFlutterSdk(detectDartSdk) + : Directory(rest.first); + if (!sdkDir.existsSync()) { + stderr.writeln("error: '${sdkDir.path}' does not exist."); + exit(1); + } + + validateFlutterSdk(sdkDir); + + var outDir = Directory(results['output'] as String); + + await generate(sdkDir, outDir); +} + +Directory get detectDartSdk { + final vm = Platform.resolvedExecutable; + // /bin/dart + return Directory(p.dirname(p.dirname(vm))); +} + +Directory calcFlutterSdk(Directory dartSdk) { + // flutter/bin/cache/dart-sdk + return dartSdk.parent.parent.parent; +} + +void printUsage(ArgParser parser, [Object? error]) { + if (error != null) { + print(error); + } else { + print('Generate API documentation for the Flutter SDK.'); + } + + print(''); + + print('usage: dart tool/create_flutter_sdk.dart []'); + print(''); + print(parser.usage); +} + +ArgParser createArgsParser() { + return ArgParser() + ..addFlag( + 'help', + abbr: 'h', + negatable: false, + help: 'Print this command help.', + ) + ..addOption( + 'output', + abbr: 'o', + defaultsTo: 'doc/sdk', + help: 'Configure the output directory.', + ); +} + +void validateFlutterSdk(Directory sdk) { + // bin/ + // packages/ + // packages/flutter/pubspec.yaml + + // todo: also validate whether pub get has been run for the packages + + var binDir = Directory(p.join(sdk.path, 'bin')); + if (!binDir.existsSync()) { + stderr.writeln('Invalid SDK (${sdk.path}) - missing bin/ directory'); + exit(1); + } + + var packagesDir = Directory(p.join(sdk.path, 'packages')); + if (!packagesDir.existsSync()) { + stderr.writeln('Invalid SDK (${sdk.path}) - missing packages/ directory'); + exit(1); + } + + var flutterPubspec = File( + p.join(sdk.path, 'packages', 'flutter', 'pubspec.yaml'), + ); + if (!flutterPubspec.existsSync()) { + stderr.writeln( + 'Invalid SDK (${sdk.path}) - missing packages/flutter/pubspec.yaml file', + ); + exit(1); + } +} + +Future generate(Directory sdkDir, Directory outDir) async { + var log = Logger.standard(); + + if (!outDir.existsSync()) outDir.createSync(recursive: true); + + log.stdout('todo: generate docs for the flutter SDK'); +} diff --git a/pkgs/jot/web/dom.dart b/pkgs/jot/web/dom.dart new file mode 100644 index 00000000..f2a0bfd4 --- /dev/null +++ b/pkgs/jot/web/dom.dart @@ -0,0 +1,94 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// TODO(devoncarew): Update away from this. +// ignore: deprecated_member_use +import 'dart:html'; + +T $id(String id) => document.getElementById(id) as T; + +T? $query(String selector) => + document.querySelector(selector) as T?; + +ElementList $queryAll(String selectors) => + document.querySelectorAll(selectors); + +extension ElementExtension on Element { + bool parentOf(Element? potentialChild) { + while (potentialChild != null) { + potentialChild = potentialChild.parent; + if (this == potentialChild) return true; + } + return false; + } +} + +DivElement div({ + List classes = const [], + Map attributes = const {}, + List children = const [], +}) { + return DivElement() + ..classes.addAll(classes) + ..attributes.addAll(attributes) + ..children = children; +} + +SpanElement span({ + String? text, + String? innerHtml, + List classes = const [], + Map attributes = const {}, +}) { + final element = SpanElement() + ..classes.addAll(classes) + ..attributes.addAll(attributes); + if (text != null) element.text = text; + if (innerHtml != null) element.innerHtml = innerHtml; + return element; +} + +UListElement ul({ + List classes = const [], + List children = const [], +}) { + return UListElement() + ..classes.addAll(classes) + ..children = children; +} + +LIElement li({ + List classes = const [], + Map attributes = const {}, + List children = const [], +}) { + return LIElement() + ..classes.addAll(classes) + ..attributes.addAll(attributes) + ..children = children; +} + +ButtonElement button({String? type, List classes = const []}) { + final element = ButtonElement()..classes.addAll(classes); + if (type != null) element.type = type; + return element; +} + +typedef ClickHandler = void Function(MouseEvent event); + +AnchorElement a({ + String? text, + String? href, + List classes = const [], + Map attributes = const {}, + ClickHandler? onClick, +}) { + final element = AnchorElement() + ..classes.addAll(classes) + ..attributes.addAll(attributes); + if (text != null) element.text = text; + if (href != null) element.href = href; + if (onClick != null) element.onClick.listen(onClick); + return element; +} diff --git a/pkgs/jot/web/interop.dart b/pkgs/jot/web/interop.dart new file mode 100644 index 00000000..62d3dff8 --- /dev/null +++ b/pkgs/jot/web/interop.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:js_interop'; + +import 'package:js/js.dart' as js; + +@JS('Response') +@js.staticInterop +class FetchResponse {} + +extension FetchResponseExtension on FetchResponse { + external int get status; + + // JSPromise + external JSPromise text(); +} diff --git a/pkgs/jot/web/main.dart b/pkgs/jot/web/main.dart new file mode 100644 index 00000000..5f860bfc --- /dev/null +++ b/pkgs/jot/web/main.dart @@ -0,0 +1,427 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; +// TODO(devoncarew): Update away from this. +// ignore: deprecated_member_use +import 'dart:html'; + +import 'dom.dart'; +import 'interop.dart'; +import 'search.dart'; +import 'utils.dart'; + +// TODO: improve animation of the sidenav opening / closing + +// TODO: update the outline view active element as the content area scrolls + +final Path p = Path(); + +void main() { + // The web url that serves as the base of the generated content. + final urlBase = _calcUrlBase(); + + // Initial url. + final rel = _body.attributes['data-path']!; + + final jot = Jot(urlBase: urlBase, initialUrl: '$urlBase$rel'); + jot.setup(); +} + +final Element _sideNav = $id('sidebar-nav'); +final Element _docMainContainer = $id('doc-main-container'); +final Element _body = $query('body')!; + +String _calcUrlBase() { + var loc = window.location.href; + var rel = _body.attributes['data-path']!; + for (var _ in rel.split('/')) { + loc = p.parent(loc); + } + return '$loc/'; +} + +class Jot { + final String urlBase; + final String initialUrl; + + final PageHistoryManager pageHistory = PageHistoryManager(); + + late final NavbarManager navbarManager; + late final SidebarManager sidebarManager; + late final SearchUI search; + + Jot({required this.urlBase, required this.initialUrl}); + + String get baseRel { + final rel = _body.attributes['data-path']!; + return p.parent(rel); + } + + Future setup() async { + // hook up the color theme toggle + var colorModeButton = $id('color-mode-button'); + colorModeButton.onClick.listen((event) { + theme = theme == 'light' ? 'dark' : 'light'; + }); + + // update the theme from the last session's value + var previousThemeValue = window.localStorage['theme']; + if (previousThemeValue != null) { + theme = previousThemeValue; + } + + // search + search = SearchUI(urlBase, (url) { + jumpToPage('$urlBase$url'); + }); + + // listen for history events + window.onPopState.listen((PopStateEvent event) { + final url = window.location.href; + final scrollPos = event.state as int?; + + jumpToPage(url, updateHistory: false, scrollPos: scrollPos); + }); + + // replace all the a hrefs with listeners + for (var anchor in $queryAll('a[data-jot]')) { + anchor.onClick.listen((event) { + event.preventDefault(); + + final relParent = p.parent(initialUrl); + final relPath = anchor.attributes['href']!; + final url = p.normalize(p.join(relParent, relPath)); + + jumpToPage(url); + }); + } + + _updateContentLinks(); + + navbarManager = NavbarManager(urlBase: urlBase); + + sidebarManager = SidebarManager(this); + await sidebarManager.setup(); + } + + String get theme => + document.documentElement!.attributes['data-theme'] ?? 'dark'; + + set theme(String value) { + if (theme == value) return; + + var stylesLink = $id('theme-stylesheet'); + stylesLink.href = '${urlBase}_resources/styles-$value.css'; + document.documentElement!.attributes['data-theme'] = value; + window.localStorage['theme'] = value; + } + + void jumpToPage( + String url, { + bool updateHistory = true, + int? scrollPos, + }) async { + if (updateHistory) { + pageHistory.rememberScrollPosition(); + } + + if (updateHistory) { + pageHistory.navigateTo(url); + } + + // TODO: make sure we're only loading from the same domain + var response = (await window.fetch(url)) as FetchResponse; + var code = response.status; + if (code == 404) { + print('error response: $response'); + return; + } + + var text = await promiseToFuture(response.text()); + var loadedDoc = DomParser().parseFromString(text, 'text/html'); + var content = loadedDoc.getElementById('doc-main-child')!; + + _docMainContainer.setInnerHtml( + content.outerHtml, + treeSanitizer: NodeTreeSanitizer.trusted, + ); + + var uri = Uri.parse(url); + + // Manage scrolled position. + if (scrollPos != null) { + pageHistory.restoreScrollPos(scrollPos); + } else { + if (uri.hasFragment) { + var target = _docMainContainer.querySelector('#${uri.fragment}'); + target?.scrollIntoViewIfNeeded(); + } else { + pageHistory.restoreScrollPos(0); + } + } + + // update a[hrefs] + _updateContentLinks(); + + navbarManager.updateActive(uri.removeFragment()); + sidebarManager.updateActive(uri.removeFragment()); + } + + void _updateContentLinks() { + var docMainChild = $id('doc-main-child'); + + var filePath = docMainChild.attributes['data-path']!; + var parentPath = p.parent(filePath); + + // todo: don't allow urls to escape the dir root + + for (var anchor in _docMainContainer.querySelectorAll('a[href]')) { + final relPath = anchor.attributes['href']!; + + // don't handle full urls + if (Uri.tryParse(relPath) == null) continue; + + anchor.onClick.listen((event) { + event.preventDefault(); + + var url = relPath.startsWith('#') + ? '$urlBase$filePath$relPath' + : '$urlBase${p.join(parentPath, relPath)}'; + jumpToPage(p.normalize(url)); + }); + } + } +} + +/// Manages the items in the navbar at the top of the page. +class NavbarManager { + final String urlBase; + + NavbarManager({required this.urlBase}); + + void updateActive(final Uri uri) { + var rel = uri.toString().substring(urlBase.length); + if (rel.startsWith('/')) { + rel = rel.substring(1); + } + + final nav = $query('nav')!; + var found = false; + + for (var anchor in nav.querySelectorAll('a[data-jot]')) { + var href = anchor.attributes['href']; + found |= href == rel; + anchor.classes.toggle('navbar__link--active', href == rel); + } + + if (!found) { + for (var anchor in nav.querySelectorAll('a[data-jot]')) { + var href = anchor.attributes['href']; + if (href == 'index.html') { + anchor.classes.toggle('navbar__link--active', true); + } + } + } + } +} + +/// Manages the items in the left-hand side nav. +class SidebarManager { + final Jot jot; + late Element _nav; + + SidebarManager(this.jot) { + _nav = $query('aside.docSidebarContainer')!; + } + + Future setup() async { + // build the left nav + await _populateNav(); + + // hook up sidenav menu collapse buttons + for (var element in $queryAll('button.menu__caret')) { + element.onClick.listen((event) { + event.preventDefault(); + + element.parent!.parent!.classes.toggle('menu__list-item--collapsed'); + }); + } + } + + void updateActive(final Uri uri) { + var rel = uri.toString().substring(jot.urlBase.length); + if (rel.startsWith('/')) { + rel = rel.substring(1); + } + + AnchorElement? itemAnchor; + + // all a hrefs should not have menu__link--active except for the active one + for (var anchor in _nav.querySelectorAll('a[data-jot]')) { + var href = anchor.attributes['href']; + + if (href == rel) itemAnchor = anchor; + anchor.classes.toggle('menu__link--active', href == rel); + } + + // if a menu or contained in a menu, open all the ancestor menus, close all + // other menus + if (itemAnchor != null) { + var parents = []; + + for (var item in _nav.querySelectorAll( + 'li.theme-doc-sidebar-item-category', + )) { + if (item.parentOf(itemAnchor)) { + parents.add(item); + } + } + + if (parents.isNotEmpty) { + for (var item in _nav.querySelectorAll( + 'li.theme-doc-sidebar-item-category', + )) { + item.classes.toggle( + 'menu__list-item--collapsed', + !parents.contains(item), + ); + } + } + } + } + + Future _populateNav() async { + // todo: write a utility for fetch() + var response = + (await window.fetch('${jot.urlBase}_resources/nav.json')) + as FetchResponse; + var code = response.status; + if (code == 404) { + print('error response: $response'); + // todo: ?? + return; + } + + var text = await promiseToFuture(response.text()); + var navInfo = (jsonDecode(text) as List) + .cast() + .map(SidebarItem._parse) + .toList(); + + // write the item info into the dom + final outer = ul(classes: ['theme-doc-sidebar-menu', 'menu__list']); + for (var nav in navInfo) { + outer.append(nav.createElement(jot)); + } + _sideNav.append(outer); + + updateActive(Uri.parse(window.location.href).removeFragment()); + } +} + +class SidebarItem { + final String name; + final String? href; + final String? type; + final List? children; + + SidebarItem({required this.name, this.href, this.type, this.children}); + + factory SidebarItem._parse(JsonType json) { + List? children; + + if (json.containsKey('c')) { + var temp = (json['c'] as List).cast(); + children = temp.map(SidebarItem._parse).toList(); + } + + return SidebarItem( + name: json['n'] as String, + href: json['h'] as String?, + type: json['t'] as String?, + children: children, + ); + } + + bool get separator => type == 'separator'; + + Element createElement(Jot jot) { + if (separator) { + return li( + classes: ['menu__list-item', 'group'], + children: [ + a(text: name, classes: ['menu__link']), + ], + ); + } else if (children == null) { + return li( + classes: ['menu__list-item'], + children: [ + a( + text: name, + href: href, + classes: ['menu__link'], + attributes: {'data-jot': ''}, + onClick: (event) { + event.preventDefault(); + jot.jumpToPage(p.normalize(p.join(jot.urlBase, href!))); + }, + ), + ], + ); + } else { + return li( + classes: [ + 'theme-doc-sidebar-item-category', + 'menu__list-item', + 'menu__list-item--collapsed', + ], + children: [ + div( + classes: ['menu__list-item-collapsible'], + children: [ + a( + text: name, + href: href, + classes: ['menu__link', 'menu__link--sublist'], + attributes: {'data-jot': ''}, + onClick: (event) { + event.preventDefault(); + jot.jumpToPage(p.normalize(p.join(jot.urlBase, href!))); + }, + ), + if (children!.isNotEmpty) + button(type: 'button', classes: ['clean-btn', 'menu__caret']), + ], + ), + ul( + classes: ['menu__list'], + children: [...children!.map((child) => child.createElement(jot))], + ), + ], + ); + } + } + + @override + String toString() => '$name [$href]'; +} + +class PageHistoryManager { + int get _scrollPos => window.document.documentElement!.scrollTop; + + void navigateTo(String url) { + window.history.pushState(null, '', url); + } + + void rememberScrollPosition() { + window.history.replaceState(_scrollPos, '', null); + } + + void restoreScrollPos(int value) { + window.document.documentElement!.scrollTop = value; + } +} diff --git a/pkgs/jot/web/search.dart b/pkgs/jot/web/search.dart new file mode 100644 index 00000000..54bc58eb --- /dev/null +++ b/pkgs/jot/web/search.dart @@ -0,0 +1,552 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; +// TODO(devoncarew): Update away from this. +// ignore: deprecated_member_use +import 'dart:html'; + +import 'dom.dart'; +import 'interop.dart'; +import 'utils.dart'; + +typedef UrlHandler = void Function(String url); + +class SearchUI { + final String urlBase; + final UrlHandler urlHandler; + + late final InputElement searchBox; + late final SearchResultsUI searchResultsUI; + + late final Index index; + + SearchUI(this.urlBase, this.urlHandler) { + index = Index(urlBase); + + searchBox = $id('search') as InputElement; + searchResultsUI = SearchResultsUI( + urlHandler, + $query('div.search-glass-pane')!, + $query('div.search-area')!, + ); + + document.onKeyPress.listen((event) { + if (event.key == '/') { + event.preventDefault(); + + _activate(); + } + }); + + searchBox.onKeyDown.listen((event) { + if (event.key == 'Escape') { + _deactivate(); + } else if (event.key == 'Enter') { + event.preventDefault(); + _selectCurrent(); + } else if (event.key == 'ArrowDown') { + searchResultsUI.selectDown(); + } else if (event.key == 'ArrowUp') { + searchResultsUI.selectUp(); + } + }); + + searchBox.onInput.listen((event) { + _handleInputChanged(searchBox.value ?? ''); + }); + + searchBox.onClick.listen((event) { + _activate(); + }); + } + + void _activate() { + searchBox.focus(); + + var text = (searchBox.value ?? '').trim(); + if (text.isNotEmpty) { + searchResultsUI.show(); + } + } + + void _selectCurrent() { + searchResultsUI.selectCurrent(); + } + + void _deactivate() { + searchBox.blur(); + searchResultsUI.hide(); + } + + void _handleInputChanged(String text) { + text = text.trim(); + + if (text.isEmpty) { + searchResultsUI.hide(); + } else { + searchResultsUI.show(); + + // ignore: unnecessary_lambdas + index.search(text).then((results) { + // Show the search results in the UI. + searchResultsUI.displayResults(results); + }); + } + } +} + +class SearchResultsUI { + static const Duration _delay = Duration(milliseconds: 200); + + final UrlHandler urlHandler; + + final Element glassPane; + final Element searchArea; + + List items = []; + final Map itemToElement = {}; + IndexMember? selected; + + SearchResultsUI(this.urlHandler, this.glassPane, this.searchArea) { + glassPane.onMouseDown.listen((_) { + hide(); + }); + searchArea.onMouseDown.listen((event) { + event.stopPropagation(); + }); + } + + bool get showing => glassPane.style.display != 'none'; + + void show() { + if (!showing) { + glassPane.style.display = 'block'; + Timer.run(() => glassPane.style.opacity = '1.0'); + } + } + + void selectCurrent() { + if (selected != null) { + urlHandler(selected!.url); + } + + hide(); + } + + void selectUp() { + if (selected == null) return; + var index = items.indexOf(selected!); + if (index == 0) return; + + var li = itemToElement[selected]!; + li.classes.remove('selected'); + selected = items[index - 1]; + li = itemToElement[selected]!; + li.classes.add('selected'); + + li.scrollIntoViewIfNeeded(); + } + + void selectDown() { + if (selected == null) return; + var index = items.indexOf(selected!); + if (index + 1 >= items.length) return; + + var li = itemToElement[selected]!; + li.classes.remove('selected'); + selected = items[index + 1]; + li = itemToElement[selected]!; + li.classes.add('selected'); + + li.scrollIntoViewIfNeeded(); + } + + void displayResults(SearchResults results) { + const maxLimit = 100; + + var items = results.items.map((result) => result.item).toList(); + var total = items.length; + + if (items.length > maxLimit) { + items = items.take(maxLimit).toList(); + } + + this.items = items; + itemToElement.clear(); + selected = null; + + var ul = searchArea.querySelector('ul')!; + ul.children.clear(); + ul.children.addAll( + items.map((item) { + var li = _renderItem(results.pattern, item); + itemToElement[item] = li; + return li; + }), + ); + selected = items.isEmpty ? null : items.first; + itemToElement[selected]?.classes.add('selected'); + ul.scrollTop = 0; + + var footer = searchArea.querySelector('div.search-footer')!; + + if (total != items.length) { + footer.text = + 'showing ${items.length} of $total ${plural('item', total)}'; + } else { + footer.text = '${items.length} ${plural('item', total)}'; + } + } + + LIElement _renderItem(String pattern, IndexMember item) { + return li( + classes: ['margin--sm', 'padding--sm'], + children: [ + div( + children: [ + ..._renderMatchText(item.display, item.name, pattern), + span(text: item.importReference(true), classes: ['location']), + span(text: item.type, classes: ['type', 'badge']), + ], + ), + div( + classes: ['docs'], + children: [ + if (item.docs == null) span(innerHtml: ' '), + if (item.docs != null) span(text: item.docs), + ], + ), + ], + ) + ..onMouseDown.listen((event) { + event.stopPropagation(); + urlHandler(item.url); + hide(); + }); + } + + void hide() { + if (showing) { + glassPane.style.opacity = '0.0'; + Timer(_delay, () => glassPane.style.display = 'none'); + } + } +} + +List _renderMatchText(String display, String name, String pattern) { + var startsAt = 0; + var nameIndex = display.indexOf('.$name'); + if (nameIndex != -1) { + startsAt = nameIndex; + } + + var matchAt = display.indexOf(pattern, startsAt); + if (matchAt == -1) { + matchAt = display.toLowerCase().indexOf(pattern.toLowerCase(), startsAt); + } + if (matchAt == -1) { + matchAt = display.toLowerCase().indexOf(pattern.toLowerCase()); + } + + if (matchAt == -1) { + return [span(text: display)]; + } else { + return [ + span(text: display.substring(0, matchAt)), + span( + text: display.substring(matchAt, matchAt + pattern.length), + classes: ['match'], + ), + span(text: display.substring(matchAt + pattern.length)), + ]; + } +} + +class Index { + late final List members; + + final Completer _completer = Completer(); + + Index(String urlBase) { + _init(urlBase) + .then((result) { + members = result; + _completer.complete(); + }) + .catchError((dynamic error) { + members = []; + print('error reading index: $error'); + _completer.complete(); + }); + } + + Future ready() => _completer.future; + + Future> _init(String urlBase) async { + var response = + (await window.fetch('${urlBase}_resources/index.json')) + as FetchResponse; + var code = response.status; + if (code == 404) { + print('error response: $response'); + return []; + } + + var text = await promiseToFuture(response.text()); + var jsonIndex = (jsonDecode(text) as List).cast(); + return jsonIndex.map(IndexMember._parse).toList(); + } + + Future search(String pattern) async { + await ready(); + + var lower = pattern.toLowerCase(); + + var potential = []; + for (var member in members) { + _gatherPotentialMatches(lower, member, potential); + } + + return SearchResults(pattern, potential); + } + + static void _gatherPotentialMatches( + String pattern, + IndexMember member, + List matches, + ) { + if (member.ref != null) { + if (member.name.toLowerCase().contains(pattern) || + member.display.toLowerCase().contains(pattern)) { + matches.add(member); + } + } + + if (member.children.isNotEmpty) { + for (var child in member.children) { + _gatherPotentialMatches(pattern, child, matches); + } + } + } +} + +// [ +// {"t":"package","n":"package:jot","c":[ +// {"t":"library","n":"jot.dart","d": +// "To create a new DocWorkspace, see ...","ref":"jot.html","c":[ +// {"t":"class","n":"Jot","ref":"jot/Jot.html","c":[ +// {"t":"constructor","n":"Jot"}, +// {"t":"field","n":"inDir"}, +// {"t":"field","n":"outDir"}, +// {"t":"method","n":"generate"}, +// {"t":"method","n":"serve"} +// ]} +// ]}, +// ... + +abstract class IndexMember { + final String name; + final String type; + final String? docs; + + IndexMember? parent; + + String? get ref; + String? get id; + List get children; + + IndexMember(this.name, this.type, this.docs); + + String get display { + if (type == 'class') { + return '$name { … }'; + } else if (type == 'function' || type == 'constructor') { + return '$name()'; + } else if (type == 'method') { + return '$_maybeParent$name()'; + } else if (type == 'field' || type == 'accessor') { + return '$_maybeParent$name'; + } else { + return name; + } + } + + String? get packageName { + var p = parent; + while (p != null) { + if (p.type == 'package') return p.name; + p = p.parent; + } + return null; + } + + String get url => id != null ? '$ref#$id' : ref!; + + String? importReference(bool includePackageName) { + IndexMember? p = this; + while (p != null) { + if (p.type == 'library') { + var libraryName = p.name; + if (!includePackageName) return libraryName; + var package = p.packageName; + return package == null ? libraryName : '$package/$libraryName'; + } + p = p.parent; + } + return null; + } + + String get _maybeParent { + if (parent == null) return ''; + if (parent!.type == 'library') return ''; + + return '${parent!.name}.'; + } + + factory IndexMember._parse(JsonType json) { + var name = json['n'] as String; + var type = json['t'] as String; + var docs = json['d'] as String?; + + var ref = json['ref'] as String?; + var children = json['c'] as List?; + + if (ref != null || children != null) { + var item = IndexParent( + name, + type, + docs, + ref, + children == null + ? const [] + : children.map((c) => IndexMember._parse(c as JsonType)).toList(), + ); + for (var child in item.children) { + child.parent = item; + } + return item; + } else { + return IndexLeaf(name, type, docs, json['#'] as String?); + } + } + + static const Set importantPackages = {'flutter'}; + + static const Set discouragedPackages = { + 'dart:cli', + 'dart:html', + 'dart:indexed_db', + 'dart:mirrors', + 'dart:svg', + 'dart:web_audio', + 'dart:web_gl', + }; + + int calcRank(String pattern, String patternLower) { + var rank = 100; + + var name = this.name; + + // grouping: + if (name == pattern) { + // - exact, same length + rank += 300; + } else if (name.startsWith(pattern)) { + // - exact (case is the same) + rank += 200; + } else if (name.toLowerCase().startsWith(patternLower)) { + // - same (same case-insensitive) + rank += 100; + } else if (display.toLowerCase().startsWith(patternLower)) { + rank += 50; + } + + // sorting: + + // - Class, extension, enums + if (type == 'class' || type == 'extension' || type == 'enum') { + rank += 10; + } + + var package = packageName; + if (importantPackages.contains(package)) { + // - from an important package + rank += 5; + } else if (discouragedPackages.contains(package)) { + // - from a deprecated package + rank -= 5; + } + + return rank; + } + + @override + String toString() => '$type $name'; +} + +class IndexParent extends IndexMember { + @override + final String? ref; + @override + final List children; + + IndexParent(super.name, super.type, super.docs, this.ref, this.children); + + @override + String? get id => null; +} + +class IndexLeaf extends IndexMember { + final String? _id; + + IndexLeaf(super.name, super.type, super.docs, this._id); + + @override + String? get id => _id ?? (ref != null ? name : null); + + @override + String? get ref => parent?.ref; + + @override + List get children => const []; +} + +class SearchResults { + final String pattern; + late final List items; + + SearchResults(this.pattern, List rawItems) { + final patternLower = pattern.toLowerCase(); + + items = rawItems.map((item) { + return SearchResult(item.calcRank(pattern, patternLower), item); + }).toList()..sort(); + } +} + +class SearchResult implements Comparable { + final int rank; + final IndexMember item; + + SearchResult(this.rank, this.item); + + @override + int compareTo(SearchResult other) { + var diff = other.rank - rank; + if (diff != 0) return diff; + + diff = item.name.compareTo(other.item.name); + if (diff != 0) return diff; + + diff = item.display.length - other.item.display.length; + if (diff != 0) return diff; + + return item.display.compareTo(other.item.display); + } + + @override + String toString() => '[$rank $item]'; +} diff --git a/pkgs/jot/web/utils.dart b/pkgs/jot/web/utils.dart new file mode 100644 index 00000000..a5813949 --- /dev/null +++ b/pkgs/jot/web/utils.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +typedef JsonType = Map; + +String plural(String word, int count) => count == 1 ? word : '${word}s'; + +class Path { + String parent(String path) { + if (path.contains('/')) { + return path.substring(0, path.lastIndexOf('/')); + } else { + return ''; + } + } + + String file(String path) { + if (path.contains('/')) { + return path.substring(path.lastIndexOf('/') + 1); + } else { + return path; + } + } + + String join(String a, String b) { + if (a.endsWith('/')) { + return '$a$b'; + } else if (a.isNotEmpty) { + return '$a/$b'; + } else { + return b; + } + } + + String normalize(String path) { + if (!path.contains('..')) return path; + + var tokens = path.split('/'); + + for (var i = 0; i < tokens.length;) { + var token = tokens[i]; + if (token == '..' && i > 0 && tokens[i - 1] != '..') { + tokens.removeAt(i); + tokens.removeAt(i - 1); + i--; + } else { + i++; + } + } + + return tokens.join('/'); + } + + String relative(String path, {required String from}) { + if (from.isEmpty) return path; + + var paths = path.split('/'); + var froms = from.split('/'); + + while (paths.isNotEmpty && froms.isNotEmpty && paths.first == froms.first) { + paths = paths.sublist(1); + froms = froms.sublist(1); + } + + for (var _ in froms) { + paths.insert(0, '..'); + } + + return paths.join('/'); + } +} From 33a59271c05c97fb7826c6af24145f68507cb5e8 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 27 Oct 2025 12:29:31 -0700 Subject: [PATCH 2/5] package CI infra --- .github/ISSUE_TEMPLATE/jot.md | 5 +++++ .github/labeler.yml | 4 ++++ .github/workflows/jot.yml | 42 +++++++++++++++++++++++++++++++++++ CODEOWNERS | 2 ++ 4 files changed, 53 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/jot.md create mode 100644 .github/workflows/jot.yml diff --git a/.github/ISSUE_TEMPLATE/jot.md b/.github/ISSUE_TEMPLATE/jot.md new file mode 100644 index 00000000..26618ff9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/jot.md @@ -0,0 +1,5 @@ +--- +name: "package:jot" +about: "Create a bug or file a feature request against package:jot." +labels: "package:jot" +--- diff --git a/.github/labeler.yml b/.github/labeler.yml index 610c0a0e..11c5ebf6 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -20,6 +20,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/io_file/**' +'package:jot': + - changed-files: + - any-glob-to-any-file: 'pkgs/jot/**' + 'package:native_synchronization': - changed-files: - any-glob-to-any-file: 'pkgs/native_synchronization/**' diff --git a/.github/workflows/jot.yml b/.github/workflows/jot.yml new file mode 100644 index 00000000..90eed726 --- /dev/null +++ b/.github/workflows/jot.yml @@ -0,0 +1,42 @@ +name: package:jot +permissions: read-all + +on: + pull_request: + branches: [ main ] + push: + branches: [ main ] + schedule: + - cron: '0 0 * * 0' # weekly + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + sdk: [stable, beta, dev] + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: ${{matrix.sdk}} + + - run: dart pub get + + - run: dart analyze --fatal-infos + + - run: dart format --output=none --set-exit-if-changed . + if: ${{ matrix.sdk == 'stable' }} + + # Ensure that the front-end is up to date. + - run: dart tool/build_web.dart --verify + + # Ensure that we can build the front-end. + - run: dart tool/build_web.dart + + - run: dart test + + # Ensure that we can build the Dart SDK docs. + - run: dart tool/create_dart_sdk.dart diff --git a/CODEOWNERS b/CODEOWNERS index be02b830..557b4349 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -6,4 +6,6 @@ /pkgs/appengine/ @dart-lang/dart-pub-team /pkgs/gcloud/ @dart-lang/dart-pub-team /pkgs/io_file @brianquinlan +# TODO: +# /pkgs/jot/ /pkgs/native_synchronization/ @mraleph From d0a14003ea0f48462036aa12b7bdb16c1b47ec0e Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 27 Oct 2025 12:29:42 -0700 Subject: [PATCH 3/5] add license file --- pkgs/jot/LICENSE | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 pkgs/jot/LICENSE diff --git a/pkgs/jot/LICENSE b/pkgs/jot/LICENSE new file mode 100644 index 00000000..2b76736b --- /dev/null +++ b/pkgs/jot/LICENSE @@ -0,0 +1,27 @@ +Copyright 2025, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From adf13643379b5c5c5a68ba9c50f9822d5795e65a Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 27 Oct 2025 12:34:42 -0700 Subject: [PATCH 4/5] update CI workflow --- .github/workflows/jot.yml | 27 +++++++++++++++++++-------- pkgs/jot/pubspec.yaml | 2 ++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/jot.yml b/.github/workflows/jot.yml index 90eed726..abc4dd93 100644 --- a/.github/workflows/jot.yml +++ b/.github/workflows/jot.yml @@ -1,27 +1,38 @@ name: package:jot + permissions: read-all on: - pull_request: - branches: [ main ] + # Run CI on pushes to the main branch, and on PRs against main. push: branches: [ main ] + paths: + - '.github/workflows/jot.yml' + - 'pkgs/jot/**' + pull_request: + branches: [ main ] + paths: + - '.github/workflows/jot.yml' + - 'pkgs/jot/**' schedule: - cron: '0 0 * * 0' # weekly +defaults: + run: + working-directory: pkgs/jot + jobs: build: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: fail-fast: false matrix: - os: [ubuntu-latest] - sdk: [stable, beta, dev] + sdk: [stable, dev] steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c with: - sdk: ${{matrix.sdk}} + sdk: ${{ matrix.sdk }} - run: dart pub get diff --git a/pkgs/jot/pubspec.yaml b/pkgs/jot/pubspec.yaml index de9c8869..a07c7745 100644 --- a/pkgs/jot/pubspec.yaml +++ b/pkgs/jot/pubspec.yaml @@ -4,6 +4,8 @@ version: 0.1.0-dev repository: https://github.com/dart-lang/labs/tree/main/pkgs/jot issue_tracker: https://github.com/dart-lang/labs/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Ajot +publish_to: none + environment: sdk: ^3.9.0 From 1a641a7c4a27bfa2722c8d497e5db208388e58c1 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 27 Oct 2025 12:48:51 -0700 Subject: [PATCH 5/5] update compilation artifacts --- pkgs/jot/lib/resources/script.js | 290 +++++++++++++++--------------- pkgs/jot/lib/resources/script.sig | 2 +- 2 files changed, 144 insertions(+), 148 deletions(-) diff --git a/pkgs/jot/lib/resources/script.js b/pkgs/jot/lib/resources/script.js index 1547fd79..32ec429f 100644 --- a/pkgs/jot/lib/resources/script.js +++ b/pkgs/jot/lib/resources/script.js @@ -150,7 +150,7 @@ lj(a,b){return J.bb(a).v(a,b)}, iU(a,b){return J.cb(a).q(a,b)}, jx(a,b){return J.cb(a).F(a,b)}, lk(a){return J.a1(a).gcG(a)}, -jy(a){return J.a1(a).gbz(a)}, +jy(a){return J.a1(a).gby(a)}, bK(a){return J.bD(a).gu(a)}, ll(a){return J.bb(a).gI(a)}, aV(a){return J.cb(a).gA(a)}, @@ -159,10 +159,10 @@ iV(a){return J.a1(a).gbH(a)}, jz(a){return J.a1(a).gbI(a)}, lm(a){return J.a1(a).gbJ(a)}, ln(a){return J.bD(a).gD(a)}, -lo(a,b,c){return J.cb(a).b_(a,b,c)}, +lo(a,b,c){return J.cb(a).aZ(a,b,c)}, jA(a){return J.a1(a).d2(a)}, lp(a,b){return J.a1(a).d4(a,b)}, -lq(a,b){return J.a1(a).sbk(a,b)}, +lq(a,b){return J.a1(a).sbj(a,b)}, jB(a,b){return J.a1(a).sae(a,b)}, lr(a,b,c){return J.a1(a).aD(a,b,c)}, ls(a){return J.nW(a).d9(a)}, @@ -1426,13 +1426,13 @@ ba(a,b){A.na(a,b)}, dl(a,b){b.an(0,a)}, dk(a,b){b.aP(A.aU(a),A.bE(a))}, na(a,b){var s,r,q=new A.ix(b),p=new A.iy(b) -if(a instanceof A.M)a.bs(q,p,t.z) +if(a instanceof A.M)a.br(q,p,t.z) else{s=t.z -if(a instanceof A.M)a.b3(q,p,s) +if(a instanceof A.M)a.b2(q,p,s) else{r=new A.M($.C,t._) r.a=8 r.c=a -r.bs(q,p,s)}}}, +r.br(q,p,s)}}}, ds(a){var s=function(b,c){return function(d,e){while(true){try{b(d,e) break}catch(r){e=r d=c}}}}(a,1) @@ -1457,7 +1457,7 @@ s=n.a=r|q if((s&24)===0){p=t.F.a(b.c) b.a=b.a&1|4 b.c=n -n.bn(p) +n.bm(p) return}if(!c)if(b.c==null)n=(s&16)===0||q!==0 else n=!1 else n=!0 @@ -1550,7 +1550,7 @@ oU(a,b){A.fP(a,"stream",t.K) return new A.fq(b.h("fq<0>"))}, k1(a,b){var s=$.C if(s===B.d)return A.ja(a,t.M.a(b)) -return A.ja(a,t.M.a(s.by(b)))}, +return A.ja(a,t.M.a(s.bx(b)))}, iA(a,b){A.nF(new A.iB(a,b))}, kD(a,b,c,d,e){var s,r=$.C if(r===c)return d.$0() @@ -1571,7 +1571,7 @@ s=r try{r=d.$2(e,f) return r}finally{$.C=s}}, fO(a,b,c,d){t.M.a(d) -if(B.d!==c){d=c.by(d) +if(B.d!==c){d=c.bx(d) d=d}A.kH(d)}, hY:function hY(a){this.a=a}, hX:function hX(a,b,c){this.a=a @@ -2252,15 +2252,11 @@ n4(a,b){var s,r,q,p,o,n if(!A.km(a))return!b?A.kk(a):a s=A.t([],t.s) for(r=a.split("/"),q=r.length,p=!1,o=0;o=s.length)return A.j(s,-1) -s.pop()}else B.b.m(s,"..")}else{p="."===n -if(!p)B.b.m(s,n)}}r=s.length -if(r!==0)if(r===1){if(0>=r)return A.j(s,0) -r=s[0].length===0}else r=!1 -else r=!0 -if(r)return"./" -if(p||B.b.gaZ(s)==="..")B.b.m(s,"") +if(".."===n){if(s.length!==0&&B.b.gbG(s)!==".."){if(0>=s.length)return A.j(s,-1) +s.pop()}else B.b.m(s,"..") +p=!0}else{p="."===n +if(!p)B.b.m(s,n.length===0&&s.length===0?"./":n)}}if(s.length===0)return"./" +if(p)B.b.m(s,"") if(!b){if(0>=s.length)return A.j(s,0) B.b.l(s,0,A.kk(s[0]))}return B.b.W(s,"/")}, kk(a){var s,r,q,p=u.f,o=a.length @@ -2280,7 +2276,7 @@ while(p!==44){B.b.m(j,r);++r for(o=-1;r=0))return A.j(a,r) p=a.charCodeAt(r) if(p===61){if(o<0)o=r}else if(p===59||p===44)break}if(o>=0)B.b.m(j,o) -else{n=B.b.gaZ(j) +else{n=B.b.gbG(j) if(p!==44||r!==n+7||!B.a.G(a,"base64",n+1))throw A.f(A.X("Expecting '='",a,r)) break}}B.b.m(j,r) m=r+1 @@ -2407,7 +2403,7 @@ A.B(b) A.B(c) s=t.cr.a(d).a r=s.a -B.l.sbG(r,c) +B.l.sbF(r,c) q=r.hostname s=s.b p=!1 @@ -2666,13 +2662,13 @@ dR:function dR(a,b){this.a=a this.b=b}, fZ:function fZ(){}, h_:function h_(){}, +hl:function hl(a){this.a=a}, fQ(a,b){var s=new A.M($.C,b.h("M<0>")),r=new A.bt(s,b.h("bt<0>")) a.then(A.bB(new A.iP(r,b),1),A.bB(new A.iQ(r),1)) return s}, iP:function iP(a,b){this.a=a this.b=b}, iQ:function iQ(a){this.a=a}, -hl:function hl(a){this.a=a}, ah:function ah(){}, e0:function e0(){}, aj:function aj(){}, @@ -2704,7 +2700,7 @@ r.toString new A.h5(s,s+r,new A.hn()).P()}, nb(){var s,r,q,p=t.d.a(window.location).href p.toString -for(s=$.jt().getAttribute("data-path").split("/").length,r=p,q=0;q=a.length)throw A.f(A.jY(b,null)) return a.splice(b,1)[0]}, -b_(a,b,c){var s=A.U(a) +aZ(a,b,c){var s=A.U(a) return new A.K(a,s.B(c).h("1(2)").a(b),s.h("@<1>").B(c).h("K<1,2>"))}, W(a,b){var s,r=A.he(a.length,"",!1,t.N) for(s=0;s=0&&b0)return a[0] throw A.f(A.j0())}, -gaZ(a){var s=a.length +gbG(a){var s=a.length if(s>0)return a[s-1] throw A.f(A.j0())}, -bx(a,b){var s,r +bw(a,b){var s,r A.U(a).h("S(1)").a(b) s=a.length for(r=0;r0)return s return s+b}, -bq(a,b){return(a|0)===a?a/b|0:this.cD(a,b)}, +bp(a,b){return(a|0)===a?a/b|0:this.cD(a,b)}, cD(a,b){var s=a/b if(s>=-2147483648&&s<=2147483647)return s|0 if(s>0){if(s!==1/0)return Math.floor(s)}else if(s>-1/0)return Math.ceil(s) throw A.f(A.G("Result of truncating division is "+A.u(s)+": "+A.u(a)+" ~/ "+b))}, aO(a,b){var s -if(a>0)s=this.bp(a,b) +if(a>0)s=this.bo(a,b) else{s=b>31?31:b s=a>>s>>>0}return s}, cA(a,b){if(0>b)throw A.f(A.kJ(b)) -return this.bp(a,b)}, -bp(a,b){return b>31?0:a>>>b}, +return this.bo(a,b)}, +bo(a,b){return b>31?0:a>>>b}, gD(a){return A.bC(t.q)}, $ia3:1, $ix:1, @@ -3067,7 +3063,7 @@ if(!(r>=0))return A.j(p,r) q=p.charCodeAt(r)===133?J.lU(p,r):o if(s===0&&q===o)return p return p.substring(s,q)}, -b7(a,b){var s,r +b6(a,b){var s,r if(0>=b)return"" if(b===1||a.length===0)return a if(b!==b>>>0)throw A.f(B.I) @@ -3077,7 +3073,7 @@ if(b===0)break s+=s}return r}, d1(a,b,c){var s=b-a.length if(s<=0)return a -return this.b7(c,s)+a}, +return this.b6(c,s)+a}, a2(a,b,c){var s if(c<0||c>a.length)throw A.f(A.az(c,0,a.length,null,null)) s=a.indexOf(b,c) @@ -3155,14 +3151,14 @@ return s-q}, q(a,b){var s=this,r=s.gcB()+b if(b<0||r>=s.gcl())throw A.f(A.I(b,s.gi(0),s,"index")) return J.iU(s.a,r)}, -b5(a,b){var s,r,q,p=this,o=p.b,n=p.a,m=J.bb(n),l=m.gi(n),k=p.c +b4(a,b){var s,r,q,p=this,o=p.b,n=p.a,m=J.bb(n),l=m.gi(n),k=p.c if(k!=null&&k0){s.b=s.c=s.d=s.e=s.f=null s.a=0 -s.bm()}}, +s.bl()}}, F(a,b){var s,r,q=this A.D(q).h("~(1,2)").a(b) s=q.e @@ -3356,20 +3352,20 @@ r=q.r while(s!=null){b.$2(s.a,s.b) if(r!==q.r)throw A.f(A.bj(q)) s=s.c}}, -bb(a,b,c){var s,r=A.D(this) +ba(a,b,c){var s,r=A.D(this) r.c.a(b) r.y[1].a(c) s=a[b] if(s==null)a[b]=this.aN(b,c) else s.b=c}, -bm(){this.r=this.r+1&1073741823}, +bl(){this.r=this.r+1&1073741823}, aN(a,b){var s=this,r=A.D(s),q=new A.hc(r.c.a(a),r.y[1].a(b)) if(s.e==null)s.e=s.f=q else{r=s.f r.toString q.d=r s.f=r.c=q}++s.a -s.bm() +s.bl() return q}, aV(a){return J.bK(a)&1073741823}, aW(a,b){var s,r @@ -3420,7 +3416,7 @@ A.eb.prototype={$ik_:1} A.Q.prototype={ cn(a,b,c,d){var s=A.az(b,0,c,d,null) throw A.f(s)}, -bf(a,b,c,d){if(b>>>0!==b||b>c)this.cn(a,b,c,d)}, +be(a,b,c,d){if(b>>>0!==b||b>c)this.cn(a,b,c,d)}, $iQ:1} A.e5.prototype={ gD(a){return B.a2}, @@ -3447,8 +3443,8 @@ c_(a,b,c,d,e){var s,r,q t.hb.a(d) a.$flags&2&&A.bI(a,5) s=a.length -this.bf(a,b,s,"start") -this.bf(a,c,s,"end") +this.be(a,b,s,"start") +this.be(a,c,s,"end") if(b>c)A.bH(A.az(b,0,c,null,null)) r=c-b if(e<0)A.bH(A.dv(e,null)) @@ -3543,10 +3539,10 @@ A.cP.prototype={ an(a,b){var s,r=this,q=r.$ti q.h("1/?").a(b) if(b==null)b=q.c.a(b) -if(!r.b)r.a.bc(b) +if(!r.b)r.a.bb(b) else{s=r.a -if(q.h("bo<1>").b(b))s.be(b) -else s.bi(b)}}, +if(q.h("bo<1>").b(b))s.bd(b) +else s.bh(b)}}, aP(a,b){var s=this.a if(this.b)s.aH(new A.aq(a,b)) else s.aF(new A.aq(a,b))}, @@ -3568,26 +3564,26 @@ A.cR.prototype={ aP(a,b){var s=this.a if((s.a&30)!==0)throw A.f(A.cI("Future already completed")) s.aF(A.nm(a,b))}, -bB(a){return this.aP(a,null)}, +bA(a){return this.aP(a,null)}, $ifU:1} A.bt.prototype={ an(a,b){var s,r=this.$ti r.h("1/?").a(b) s=this.a if((s.a&30)!==0)throw A.f(A.cI("Future already completed")) -s.bc(r.h("1/").a(b))}, -bA(a){return this.an(0,null)}} +s.bb(r.h("1/").a(b))}, +bz(a){return this.an(0,null)}} A.aR.prototype={ cZ(a){if((this.c&15)!==6)return!0 -return this.b.b.b2(t.al.a(this.d),a.a,t.y,t.K)}, +return this.b.b.b1(t.al.a(this.d),a.a,t.y,t.K)}, cU(a){var s,r=this,q=r.e,p=null,o=t.z,n=t.K,m=a.a,l=r.b.b if(t.W.b(q))p=l.d6(q,m,a.b,o,n,t.l) -else p=l.b2(t.x.a(q),m,o,n) +else p=l.b1(t.x.a(q),m,o,n) try{o=r.$ti.h("2/").a(p) return o}catch(s){if(t.eK.b(A.aU(s))){if((r.c&1)!==0)throw A.f(A.dv("The error handler of Future.then must return a value of the returned future's type","onError")) throw A.f(A.dv("The error handler of Future.catchError must return a value of the future's type","onError"))}else throw s}}} A.M.prototype={ -b3(a,b,c){var s,r,q,p=this.$ti +b2(a,b,c){var s,r,q,p=this.$ti p.B(c).h("1/(2)").a(a) s=$.C if(s===B.d){if(b!=null&&!t.W.b(b)&&!t.x.b(b))throw A.f(A.iW(b,"onError",u.c))}else{c.h("@<0/>").B(p.c).h("1(2)").a(a) @@ -3595,8 +3591,8 @@ if(b!=null)b=A.kC(b,s)}r=new A.M(s,c.h("M<0>")) q=b==null?1:3 this.ah(new A.aR(r,q,a,b,p.h("@<1>").B(c).h("aR<1,2>"))) return r}, -bQ(a,b){return this.b3(a,null,b)}, -bs(a,b,c){var s,r=this.$ti +bQ(a,b){return this.b2(a,null,b)}, +br(a,b,c){var s,r=this.$ti r.B(c).h("1/(2)").a(a) s=new A.M($.C,c.h("M<0>")) this.ah(new A.aR(s,19,a,b,r.h("@<1>").B(c).h("aR<1,2>"))) @@ -3610,7 +3606,7 @@ if(q<=3){a.a=t.F.a(r.c) r.c=a}else{if((q&4)!==0){s=t._.a(r.c) if((s.a&24)===0){s.ah(a) return}r.ai(s)}A.fO(null,null,r.b,t.M.a(new A.i4(r,a)))}}, -bn(a){var s,r,q,p,o,n,m=this,l={} +bm(a){var s,r,q,p,o,n,m=this,l={} l.a=a if(a==null)return s=m.a @@ -3619,7 +3615,7 @@ m.c=a if(r!=null){q=a.a for(p=a;q!=null;p=q,q=o)o=q.a p.a=r}}else{if((s&4)!==0){n=t._.a(m.c) -if((n.a&24)===0){n.bn(a) +if((n.a&24)===0){n.bm(a) return}m.ai(n)}l.a=m.al(a) A.fO(null,null,m.b,t.M.a(new A.i8(l,m)))}}, a9(){var s=t.F.a(this.c) @@ -3628,7 +3624,7 @@ return this.al(s)}, al(a){var s,r,q for(s=a,r=null;s!=null;r=s,s=q){q=s.a s.a=r}return r}, -bi(a){var s,r=this +bh(a){var s,r=this r.$ti.c.a(a) s=r.a9() r.a=8 @@ -3644,15 +3640,15 @@ A.bu(q,r)}, aH(a){var s=this.a9() this.cz(a) A.bu(this,s)}, -bc(a){var s=this.$ti +bb(a){var s=this.$ti s.h("1/").a(a) -if(s.h("bo<1>").b(a)){this.be(a) +if(s.h("bo<1>").b(a)){this.bd(a) return}this.cf(a)}, cf(a){var s=this s.$ti.c.a(a) s.a^=2 A.fO(null,null,s.b,t.M.a(new A.i6(s,a)))}, -be(a){A.jc(this.$ti.h("bo<1>").a(a),this,!1) +bd(a){A.jc(this.$ti.h("bo<1>").a(a),this,!1) return}, aF(a){this.a^=2 A.fO(null,null,this.b,t.M.a(new A.i5(this,a)))}, @@ -3667,7 +3663,7 @@ A.i7.prototype={ $0(){A.jc(this.a.a,this.b,!0)}, $S:0} A.i6.prototype={ -$0(){this.a.bi(this.b)}, +$0(){this.a.bh(this.b)}, $S:0} A.i5.prototype={ $0(){this.a.aH(this.b)}, @@ -3688,7 +3684,7 @@ return}if(j instanceof A.M&&(j.a&24)!==0){if((j.a&16)!==0){q=k.a q.c=t.n.a(j.c) q.b=!0}return}if(j instanceof A.M){m=k.b.a l=new A.M(m.b,m.$ti) -j.b3(new A.ic(l,m),new A.id(l),t.H) +j.b2(new A.ic(l,m),new A.id(l),t.H) q=k.a q.c=l q.b=!1}}, @@ -3708,7 +3704,7 @@ p=q.a o=p.$ti n=o.c m=n.a(this.b) -q.c=p.b.b.b2(o.h("2/(1)").a(p.d),m,o.h("2/"),n)}catch(l){s=A.aU(l) +q.c=p.b.b.b1(o.h("2/(1)").a(p.d),m,o.h("2/"),n)}catch(l){s=A.aU(l) r=A.bE(l) q=s p=r @@ -3772,12 +3768,12 @@ try{if(B.d===$.C){a.$1(b) return}A.kE(null,null,this,a,b,t.H,c)}catch(q){s=A.aU(q) r=A.bE(q) A.iA(A.c7(s),t.l.a(r))}}, -by(a){return new A.ig(this,t.M.a(a))}, +bx(a){return new A.ig(this,t.M.a(a))}, cH(a,b){return new A.ih(this,b.h("~(0)").a(a),b)}, d5(a,b){b.h("0()").a(a) if($.C===B.d)return a.$0() return A.kD(null,null,this,a,b)}, -b2(a,b,c,d){c.h("@<0>").B(d).h("1(2)").a(a) +b1(a,b,c,d){c.h("@<0>").B(d).h("1(2)").a(a) d.a(b) if($.C===B.d)return a.$1(b) return A.kE(null,null,this,a,b,c,d)}, @@ -3811,8 +3807,8 @@ return this.aL(s[this.aI(a)],a)>=0}, m(a,b){var s,r,q=this A.D(q).c.a(b) if(typeof b=="string"&&b!=="__proto__"){s=q.b -return q.bg(s==null?q.b=A.jd():s,b)}else if(typeof b=="number"&&(b&1073741823)===b){r=q.c -return q.bg(r==null?q.c=A.jd():r,b)}else return q.cd(0,b)}, +return q.bf(s==null?q.b=A.jd():s,b)}else if(typeof b=="number"&&(b&1073741823)===b){r=q.c +return q.bf(r==null?q.c=A.jd():r,b)}else return q.cd(0,b)}, cd(a,b){var s,r,q,p=this A.D(p).c.a(b) s=p.d @@ -3834,9 +3830,9 @@ q=o.aL(r,b) if(q<0)return!1 p=r.splice(q,1)[0] if(0===r.length)delete n[s] -o.bt(p) +o.bs(p) return!0}, -bg(a,b){A.D(this).c.a(b) +bf(a,b){A.D(this).c.a(b) if(t.g.a(a[b])!=null)return!1 a[b]=this.aG(b) return!0}, @@ -3844,24 +3840,24 @@ cr(a,b){var s if(a==null)return!1 s=t.g.a(a[b]) if(s==null)return!1 -this.bt(s) +this.bs(s) delete a[b] return!0}, -bh(){this.r=this.r+1&1073741823}, +bg(){this.r=this.r+1&1073741823}, aG(a){var s,r=this,q=new A.f8(A.D(r).c.a(a)) if(r.e==null)r.e=r.f=q else{s=r.f s.toString q.c=s r.f=s.b=q}++r.a -r.bh() +r.bg() return q}, -bt(a){var s=this,r=a.c,q=a.b +bs(a){var s=this,r=a.c,q=a.b if(r==null)s.e=q else r.b=q if(q==null)s.f=r else q.c=r;--s.a -s.bh()}, +s.bg()}, aI(a){return J.bK(a)&1073741823}, aL(a,b){var s,r if(a==null)return-1 @@ -3883,15 +3879,15 @@ A.c.prototype={ gA(a){return new A.P(a,this.gi(a),A.ao(a).h("P"))}, q(a,b){return this.k(a,b)}, gI(a){return this.gi(a)===0}, -b_(a,b,c){var s=A.ao(a) +aZ(a,b,c){var s=A.ao(a) return new A.K(a,s.B(c).h("1(c.E)").a(b),s.h("@").B(c).h("K<1,2>"))}, -b5(a,b){var s,r,q,p,o=this +b4(a,b){var s,r,q,p,o=this if(o.gI(a)){s=J.j2(0,A.ao(a).h("c.E")) return s}r=o.k(a,0) q=A.he(o.gi(a),r,!0,A.ao(a).h("c.E")) for(p=1;p").B(b).h("aI<1,2>"))}, cQ(a,b,c,d){var s A.ao(a).h("c.E?").a(d) @@ -4031,7 +4027,7 @@ A.fT.prototype={} A.ce.prototype={} A.dG.prototype={} A.e_.prototype={ -bD(a,b,c){var s=A.nB(b,this.gcN().a) +bC(a,b,c){var s=A.nB(b,this.gcN().a) return s}, gcN(){return B.S}} A.hb.prototype={} @@ -4055,10 +4051,10 @@ M(a,b){if(b==null)return!1 return b instanceof A.b0&&this.a===b.a}, gu(a){return B.c.gu(this.a)}, N(a,b){return B.c.N(this.a,t.fu.a(b).a)}, -j(a){var s,r,q,p=this.a,o=p%36e8,n=B.c.bq(o,6e7) +j(a){var s,r,q,p=this.a,o=p%36e8,n=B.c.bp(o,6e7) o%=6e7 s=n<10?"0":"" -r=B.c.bq(o,1e6) +r=B.c.bp(o,1e6) q=r<10?"0":"" return""+(p/36e8|0)+":"+s+n+":"+q+r+"."+B.a.d1(B.c.j(o%1e6),6,"0")}, $ia3:1} @@ -4137,10 +4133,10 @@ j=r k=""}else{i=f-36 j=f+36}l="..."}}else{j=r i=p -k=""}return g+l+B.a.n(e,i,j)+k+"\n"+B.a.b7(" ",f-i+l.length)+"^\n"}else return f!=null?g+(" (at offset "+A.u(f)+")"):g}} +k=""}return g+l+B.a.n(e,i,j)+k+"\n"+B.a.b6(" ",f-i+l.length)+"^\n"}else return f!=null?g+(" (at offset "+A.u(f)+")"):g}} A.e.prototype={ am(a,b){return A.lw(this,A.D(this).h("e.E"),b)}, -b_(a,b,c){var s=A.D(this) +aZ(a,b,c){var s=A.D(this) return A.lZ(this,s.B(c).h("1(e.E)").a(b),s.h("e.E"),c)}, aA(a,b){var s=A.D(this) return new A.aQ(this,s.h("S(e.E)").a(b),s.h("aQ"))}, @@ -4179,7 +4175,7 @@ A.hT.prototype={ $2(a,b){throw A.f(A.X("Illegal IPv6 address, "+a,this.a,b))}, $S:14} A.df.prototype={ -gbr(){var s,r,q,p,o=this,n=o.w +gbq(){var s,r,q,p,o=this,n=o.w if(n===$){s=o.a r=s.length!==0?s+":":"" q=o.c @@ -4197,7 +4193,7 @@ r=o.r if(r!=null)s=s+"#"+r n=o.w=s.charCodeAt(0)==0?s:s}return n}, gu(a){var s,r=this,q=r.y -if(q===$){s=B.a.gu(r.gbr()) +if(q===$){s=B.a.gu(r.gbq()) r.y!==$&&A.og() r.y=s q=s}return q}, @@ -4206,7 +4202,7 @@ gaT(a){var s=this.c if(s==null)return"" if(B.a.C(s,"[")&&!B.a.G(s,"v",1))return B.a.n(s,1,s.length-1) return s}, -gb1(a){var s=this.d +gb0(a){var s=this.d return s==null?A.kj(this.a):s}, gbM(a){var s=this.f return s==null?"":s}, @@ -4215,23 +4211,23 @@ return s==null?"":s}, au(){var s=this if(s.r==null)return s return A.ki(s.a,s.b,s.c,s.d,s.e,s.f,null)}, -gbE(){return this.c!=null}, -gbF(){return this.f!=null}, +gbD(){return this.c!=null}, +gbE(){return this.f!=null}, gaS(){return this.r!=null}, -j(a){return this.gbr()}, +j(a){return this.gbq()}, M(a,b){var s,r,q,p=this if(b==null)return!1 if(p===b)return!0 s=!1 -if(t.dD.b(b))if(p.a===b.gb8())if(p.c!=null===b.gbE())if(p.b===b.gbU())if(p.gaT(0)===b.gaT(b))if(p.gb1(0)===b.gb1(b))if(p.e===b.gbL(b)){r=p.f +if(t.dD.b(b))if(p.a===b.gb7())if(p.c!=null===b.gbD())if(p.b===b.gbU())if(p.gaT(0)===b.gaT(b))if(p.gb0(0)===b.gb0(b))if(p.e===b.gbL(b)){r=p.f q=r==null -if(!q===b.gbF()){if(q)r="" +if(!q===b.gbE()){if(q)r="" if(r===b.gbM(b)){r=p.r q=r==null if(!q===b.gaS()){s=q?"":r s=s===b.gaR()}}}}return s}, $ieH:1, -gb8(){return this.a}, +gb7(){return this.a}, gbL(a){return this.e}} A.hS.prototype={ gbS(){var s,r,q,p,o=this,n=null,m=o.c @@ -4249,10 +4245,10 @@ if(0>=r.length)return A.j(r,0) s=this.a return r[0]===-1?"data:"+s:s}} A.d5.prototype={ -gbE(){return this.c>0}, -gbF(){return this.f0}, +gbE(){return this.fr?B.a.n(this.a,r,s-1):""}, gaT(a){var s=this.c return s>0?B.a.n(this.a,s,this.d):""}, -gb1(a){var s,r=this +gb0(a){var s,r=this if(r.c>0&&r.d+1=0&&b"))}, E(a,b){A.my(this.a,t.c.a(b))}, ab(a){J.iS(this.a)}} @@ -4454,7 +4450,7 @@ s=A.t(b.slice(0),A.U(b)) r=this.gK(a) r.ab(0) r.E(0,s)}, -gbz(a){return new A.eW(a)}, +gby(a){return new A.eW(a)}, j(a){var s=a.localName s.toString return s}, @@ -4514,10 +4510,10 @@ document.adoptNode(p).toString return p}, cL(a,b,c){return this.L(a,b,c,null)}, aD(a,b,c){this.sae(a,null) -if(c instanceof A.db)this.sbk(a,b) +if(c instanceof A.db)this.sbj(a,b) else a.appendChild(this.L(a,b,c,null)).toString}, bZ(a,b){return this.aD(a,b,null)}, -sbk(a,b){a.innerHTML=b}, +sbj(a,b){a.innerHTML=b}, gbJ(a){return a.outerHTML}, gbH(a){return new A.aH(a,"click",!1,t.C)}, gbI(a){return new A.aH(a,"mousedown",!1,t.C)}, @@ -5005,11 +5001,11 @@ r.toString q=a.height q.toString return A.j7(p,s,r,q)}, -gbj(a){return a.height}, +gbi(a){return a.height}, ga0(a){var s=a.height s.toString return s}, -gbw(a){return a.width}, +gbv(a){return a.width}, ga5(a){var s=a.width s.toString return s}} @@ -5111,7 +5107,7 @@ A.eW.prototype={ U(){var s,r,q,p,o=A.cv(t.N) for(s=this.a.className.split(" "),r=s.length,q=0;q"))}} A.cC.prototype={ -Z(a){return B.b.bx(this.a,new A.hk(a))}, -T(a,b,c){return B.b.bx(this.a,new A.hj(a,b,c))}, +Z(a){return B.b.bw(this.a,new A.hk(a))}, +T(a,b,c){return B.b.bw(this.a,new A.hj(a,b,c))}, $iay:1} A.hk.prototype={ $1(a){return t.f6.a(a).Z(this.a)}, @@ -5460,17 +5456,17 @@ t.Y.a(b) for(s=Object.keys(a),r=s.length,q=0;q") k=A.br(new A.K(h,m.h("as(c.E)").a(A.kP()),l),l.h("T.E")) j=A.kT(B.U,A.t(["theme-doc-sidebar-menu","menu__list"],t.s)) -for(h=k.length,i=0;i") q=A.br(new A.K(k,s.h("J(1)").a(new A.hw()),r),r.h("T.E")) p=q.length -if(p>100)q=A.mk(q,0,A.fP(100,"count",t.S),A.U(q).c).b4(0) +if(p>100)q=A.mk(q,0,A.fP(100,"count",t.S),A.U(q).c).b3(0) l.d=q k=l.e k.ab(0) @@ -6166,7 +6162,7 @@ A.am(o,"mousedown",n.h("~(1)?").a(new A.ht(this,b)),!1,n.c) return o}, ac(){var s=this.b.style,r=s.display r.toString -if(r!=="none"){B.j.bo(s,B.j.bd(s,"opacity"),"0.0","") +if(r!=="none"){B.j.bn(s,B.j.bc(s,"opacity"),"0.0","") A.k1(B.M,new A.hy(this))}}} A.hu.prototype={ $1(a){t.V.a(a) @@ -6178,7 +6174,7 @@ $S:1} A.hz.prototype={ $0(){var s=this.a.b.style s.toString -B.j.bo(s,B.j.bd(s,"opacity"),"1.0","") +B.j.bn(s,B.j.bc(s,"opacity"),"1.0","") return"1.0"}, $S:0} A.hw.prototype={ @@ -6224,7 +6220,7 @@ k=t.j j=B.t s=4 return A.ba(A.fQ(A.iw(p.text()),t.N),$async$a7) -case 4:o=l.iT(k.a(j.bD(0,c,null)),t.a) +case 4:o=l.iT(k.a(j.bC(0,c,null)),t.a) m=o.$ti n=m.h("K") m=A.br(new A.K(o,m.h("J(c.E)").a(A.od()),n),n.h("T.E")) @@ -6254,23 +6250,23 @@ t.w.a(a) s=this.a s.a!==$&&A.be() s.a=a -s.b.bA(0)}, +s.b.bz(0)}, $S:34} A.h3.prototype={ $1(a){var s=this.a,r=t.w.a(A.t([],t.I)) s.a!==$&&A.be() s.a=r A.iO("error reading index: "+A.u(a)) -s.b.bA(0)}, +s.b.bz(0)}, $S:4} A.J.prototype={ gV(a){var s,r=this,q=r.b if(q==="class")return r.a+" { \u2026 }" else if(q==="function"||q==="constructor")return r.a+"()" -else if(q==="method")return r.gbl()+r.a+"()" +else if(q==="method")return r.gbk()+r.a+"()" else{q=q==="field"||q==="accessor" s=r.a -if(q)return r.gbl()+s +if(q)return r.gbk()+s else return s}}, gbK(){var s=this.d while(s!=null){if(s.b==="package")return s.a @@ -6283,7 +6279,7 @@ cV(a){var s,r,q for(s=this;s!=null;){if(s.b==="library"){r=s.a q=s.gbK() return q==null?r:q+"/"+r}s=s.d}return null}, -gbl(){var s=this.d +gbk(){var s=this.d if(s==null)return"" if(s.b==="library")return"" return s.a+"."}, @@ -6341,7 +6337,7 @@ return B.a.N(r.gV(0),q.gV(0))}, j(a){return"["+this.a+" "+this.b.j(0)+"]"}, $ia3:1} A.ho.prototype={ -b0(a,b){if(B.a.v(b,"/"))return B.a.n(b,0,B.a.cY(b,"/")) +b_(a,b){if(B.a.v(b,"/"))return B.a.n(b,0,B.a.cY(b,"/")) else return""}, ap(a,b,c){if(B.a.cP(b,"/"))return b+c else if(b.length!==0)return b+"/"+c diff --git a/pkgs/jot/lib/resources/script.sig b/pkgs/jot/lib/resources/script.sig index aae97f9f..2e6b9129 100644 --- a/pkgs/jot/lib/resources/script.sig +++ b/pkgs/jot/lib/resources/script.sig @@ -1 +1 @@ -98E61B7573D5A2C261D9CA5EA3F90275 +FE207515A70C715524FB451BF604FF32