diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /dom/docs | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/docs')
33 files changed, 6286 insertions, 0 deletions
diff --git a/dom/docs/fedcm.rst b/dom/docs/fedcm.rst new file mode 100644 index 0000000000..4ec2e8c8d1 --- /dev/null +++ b/dom/docs/fedcm.rst @@ -0,0 +1,67 @@ +=============================== +Federated Credential Management +=============================== + +FedCM, as it is abbreviated, is a platform feature that requires a full-stack implementation. +As such, its code is scattered throughout the codebase and it can be hard to follow the flow of execution. +This documentation aims to make those two points easier. + +Code sites +========== + +Code relevant to it can be found in all of the following places. + +The webidl for this spec lives in ``dom/webidl/IdentityCredential.webidl`` + +Core spec algorithm logic and the implementation of the ``IdentityCredential`` live in ``dom/credentialmanagement/identity/IdentityCredential.{cpp,h}``. The static functions of ``IdentityCredential`` are the spec algorithm logic. Helpers for managing the ``IdentityCredential.webidl`` objects are in the other files in ``dom/credentialmanagement/identity/``. The IPC is defined on the WindowGlobal in ``dom/ipc/PWindowGlobal.ipdl`` and ``dom/ipc/WindowGlobalParent.cpp``, and is a very thin layer. + +The service for managing state associated with IdentityCredentials is ``IdentityCredentialStorageService`` and the service for managing the UI prompts associated with IdentityCredentials is ``IdentityCredentialPromptService``. Both definitions and implementations are in ``toolkit/components/credentialmanagement``. + +The UI panel is spread around a little. The actual DOM elements are in the HTML subtree with root at ``#identity-credential-notification`` in ``browser/base/content/popup-notifications.inc``. But the CSS describing it is spread through ``browser/themes/shared/customizableui/panelUI-shared.css``, ``browser/themes/shared/identity-credential-notification.css``, and ``browser/themes/shared/notification-icons.css``. Generally speaking, search for ``identity-credential`` in those files to find the relevant ids and classes. + +Content strings: ``browser/locales/en-US/browser/identityCredentialNotification.ftl``. + +All of this is entered from the ``navigator.credentials`` object, implemented in ``dom/credentialmanagement/CredentialsContainer.{cpp,h}``. + +Flow of Execution +================= + +This is the general flow through code relevant to the core spec algorithms, which happens to be the complicated parts imo. + +A few notes: + +- All functions without a class specified are in ``IdentityCredential``. +- Functions in ``IdentityCredentialPromptService`` mutate the Chrome DOM +- FetchT functions send network requests via ``mozilla::dom::FetchJSONStructure<T>``. +- A call to ``IdentityCredentialStorageService`` is made in ``PromptUserWithPolicy`` + +.. graphviz:: + + digraph fedcm { + "RP (visited page) calls ``navigator.credentials.get()``" -> "CredentialsContainer::Get" + "CredentialsContainer::Get" -> "DiscoverFromExternalSource" + "DiscoverFromExternalSource" -> "DiscoverFromExternalSourceInMainProcess" [label="IPC via WindowGlobal's DiscoverIdentityCredentialFromExternalSource"] + "DiscoverFromExternalSourceInMainProcess" -> "anonymous timeout callback" -> "CloseUserInterface" -> "IdentityCredentialPromptService::Close" + "DiscoverFromExternalSourceInMainProcess" -> "CheckRootManifest A" + "CheckRootManifest A" -> "FetchInternalManifest A" [label="via promise chain in DiscoverFromExternalSourceInMainProcess"] + "FetchInternalManifest A" -> "DiscoverFromExternalSourceInMainProcess inline anonymous callback (Promise::All)" + "DiscoverFromExternalSourceInMainProcess" -> "CheckRootManifest N" + "CheckRootManifest N" -> "FetchInternalManifest N" [label="via promise chain in DiscoverFromExternalSourceInMainProcess"] + "FetchInternalManifest N" -> "DiscoverFromExternalSourceInMainProcess inline anonymous callback (Promise::All)" + "DiscoverFromExternalSourceInMainProcess inline anonymous callback (Promise::All)" -> "PromptUserToSelectProvider" + "PromptUserToSelectProvider" -> "IdentityCredentialPromptService::ShowProviderPrompt" + "IdentityCredentialPromptService::ShowProviderPrompt" -> "CreateCredential" [label="via promise chain in DiscoverFromExternalSourceInMainProcess"] + "CreateCredential" -> "FetchAccountList" [label="via promise chain in CreateCredential"] + "FetchAccountList" -> "PromptUserToSelectAccount" [label="via promise chain in CreateCredential"] + "PromptUserToSelectAccount" -> "IdentityCredentialPromptService::ShowAccountListPrompt" + "IdentityCredentialPromptService::ShowAccountListPrompt" -> "PromptUserWithPolicy" [label="via promise chain in CreateCredential"] + "PromptUserWithPolicy" -> "FetchMetadata" + "FetchMetadata" -> "IdentityCredentialPromptService::ShowPolicyPrompt" [label="via promise chain in PromptUserWithPolicy"] + "IdentityCredentialPromptService::ShowPolicyPrompt" -> "FetchToken" [label="via promise chain in CreateCredential"] + "FetchToken" -> "cancel anonymous timeout callback" + "FetchToken" -> "CreateCredential inline anonymous callback" + "CreateCredential inline anonymous callback" -> "DiscoverFromExternalSourceInMainProcess inline anonymous callback" + "DiscoverFromExternalSourceInMainProcess inline anonymous callback" -> "DiscoverFromExternalSource inline anonymous callback" [label="Resolving IPC via WindowGlobal's DiscoverIdentityCredentialFromExternalSource"] + "DiscoverFromExternalSource inline anonymous callback" -> "CredentialsContainer::Get inline anonymous callback" + "CredentialsContainer::Get inline anonymous callback" -> "RP (visited page) gets the credential" + } diff --git a/dom/docs/index.rst b/dom/docs/index.rst new file mode 100644 index 0000000000..2b414732ec --- /dev/null +++ b/dom/docs/index.rst @@ -0,0 +1,19 @@ +DOM +=== + +These linked pages contain design documents for the DOM implementation in Gecko. They live in-tree under the 'dom/docs' directory. + +.. toctree:: + :maxdepth: 1 + + ipc/index + navigation/index + push/index + scriptSecurity/index + scriptSecurity/xray_vision + workersAndStorage/index + webIdlBindings/index + ioutils_migration + fedcm + streams + use-counters diff --git a/dom/docs/ioutils_migration.md b/dom/docs/ioutils_migration.md new file mode 100644 index 0000000000..c9f959b564 --- /dev/null +++ b/dom/docs/ioutils_migration.md @@ -0,0 +1,589 @@ +# IOUtils Migration Guide + +**Improving performance through a new file API** + +--- + +## What is IOUtils? + +`IOUtils` is a privileged JavaScript API for performing file I/O in the Firefox frontend. +It was developed as a replacement for `OS.File`, addressing +[bug 1231711](https://bugzilla.mozilla.org/show_bug.cgi?id=1231711). +It is *not to be confused* with the unprivileged +[DOM File API](https://developer.mozilla.org/en-US/docs/Web/API/File). + +`IOUtils` provides a minimal API surface to perform common +I/O tasks via a collection of static methods inspired from `OS.File`. +It is implemented in C++, and exposed to JavaScript via WebIDL bindings. + +The most up-to-date API can always be found in +[IOUtils.webidl](https://searchfox.org/mozilla-central/source/dom/chrome-webidl/IOUtils.webidl). + +## Differences from `OS.File` + +`IOUtils` has a similar API to `OS.File`, but one should keep in mind some key differences. + +### No `File` instances (except `SyncReadFile` in workers) + +Most of the `IOUtils` methods only operate on absolute path strings, and don't expose a file handle to the caller. +The exception to this rule is the `openFileForSyncReading` API, which is only available in workers. + +Furthermore, `OS.File` was exposing platform-specific file descriptors through the +[`fd`](https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File_for_workers#Attributes) +attribute. `IOUtils` does not expose file descriptors. + +### WebIDL has no `Date` type + +`IOUtils` is written in C++ and exposed to JavaScript through WebIDL. +Many uses of `OS.File` concern themselves with obtaining or manipulating file metadata, +like the last modified time, however the `Date` type does not exist in WebIDL. +Using `IOUtils`, +these values are returned to the caller as the number of milliseconds since +`1970-01-01T00:00:00Z`. +`Date`s can be safely constructed from these values if needed. + +For example, to obtain the last modification time of a file and update it to the current time: + +```js +let { lastModified } = await IOUtils.stat(path); + +let lastModifiedDate = new Date(lastModified); + +let now = new Date(); + +await IOUtils.touch(path, now.valueOf()); +``` + +### Some methods are not implemented + +For various reasons +(complexity, safety, availability of underlying system calls, usefulness, etc.) +the following `OS.File` methods have no analogue in IOUtils. +They also will **not** be implemented. + +- void unixSymlink(in string targetPath, in string createPath) +- string getCurrentDirectory(void) +- void setCurrentDirectory(in string path) +- object open(in string path) +- object openUnique(in string path) + +### Errors are reported as `DOMException`s + +When an `OS.File` method runs into an error, +it will throw/reject with a custom +[`OS.File.Error`](https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File.Error). +These objects have custom attributes that can be checked for common error cases. + +`IOUtils` has similar behaviour, however its methods consistently reject with a +[`DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) +whose name depends on the failure: + +| Exception Name | Reason for exception | +| -------------- | -------------------- | +| `NotFoundError` | A file at the specified path could not be found on disk. | +| `NotAllowedError` | Access to a file at the specified path was denied by the operating system. | +| `NotReadableError` | A file at the specified path could not be read for some reason. It may have been too big to read, or it was corrupt, or some other reason. The exception message should have more details. | +| `ReadOnlyError` | A file at the specified path is read only and could not be modified. | +| `NoModificationAllowedError` | A file already exists at the specified path and could not be overwritten according to the specified options. The exception message should have more details. | +| `OperationError` | Something went wrong during the I/O operation. E.g. failed to allocate a buffer. The exception message should have more details. | +| `UnknownError` | An unknown error occurred in the implementation. An nsresult error code should be included in the exception message to assist with debugging and improving `IOUtils` internal error handling. | + +### `IOUtils` is mostly async-only + +`OS.File` provided an asynchronous front-end for main-thread consumers, +and a synchronous front-end for workers. +`IOUtils` only provides an asynchronous API for the vast majority of its API surface. +These asynchronous methods can be called from both the main thread and from chrome-privileged worker threads. + +The one exception to this rule is `openFileForSyncReading`, which allows synchronous file reading in workers. + +## `OS.File` vs `IOUtils` + +Some methods and options of `OS.File` keep the same name and underlying behaviour in `IOUtils`, +but others have been renamed. +The following is a detailed comparison with examples of the methods and options in each API. + +### Reading a file + +`IOUtils` provides the following methods to read data from a file. Like +`OS.File`, they accept an `options` dictionary. + +Note: The maximum file size that can be read is `UINT32_MAX` bytes. Attempting +to read a file larger will result in a `NotReadableError`. + +```idl +Promise<Uint8Array> read(DOMString path, ...); + +Promise<DOMString> readUTF8(DOMString path, ...); + +Promise<any> readJSON(DOMString path, ...); + +// Workers only: +SyncReadFile openFileForSyncReading(DOMString path); +``` + +#### Options + +| `OS.File` option | `IOUtils` option | Description | +| ------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| bytes: number? | maxBytes: number? | If specified, read only up to this number of bytes. Otherwise, read the entire file. Default is null. | +| compression: 'lz4' | decompress: boolean | If true, read the file and return the decompressed LZ4 stream. Otherwise, just read the file byte-for-byte. Default is false. | +| encoding: 'utf-8' | N/A; use `readUTF8` instead. | Interprets the file as UTF-8 encoded text, and returns a string to the caller. | + +#### Examples + +##### Read raw (unsigned) byte values + +**`OS.File`** +```js +let bytes = await OS.File.read(path); // Uint8Array +``` +**`IOUtils`** +```js +let bytes = await IOUtils.read(path); // Uint8Array +``` + +##### Read UTF-8 encoded text + +**`OS.File`** +```js +let utf8 = await OS.File.read(path, { encoding: 'utf-8' }); // string +``` +**`IOUtils`** +```js +let utf8 = await IOUtils.readUTF8(path); // string +``` + +##### Read JSON file + +**`IOUtils`** +```js +let obj = await IOUtils.readJSON(path); // object +``` + +##### Read LZ4 compressed file contents + +**`OS.File`** +```js +// Uint8Array +let bytes = await OS.File.read(path, { compression: 'lz4' }); +// string +let utf8 = await OS.File.read(path, { + encoding: 'utf-8', + compression: 'lz4', +}); +``` +**`IOUtils`** +```js +let bytes = await IOUtils.read(path, { decompress: true }); // Uint8Array +let utf8 = await IOUtils.readUTF8(path, { decompress: true }); // string +``` + +##### Synchronously read a fragment of a file into a buffer, from a worker + +**`OS.File`** +```js +// Read 64 bytes at offset 128, workers only: +let file = OS.File.open(path, { read: true }); +file.setPosition(128); +let bytes = file.read({ bytes: 64 }); // Uint8Array +file.close(); +``` +**`IOUtils`** +```js +// Read 64 bytes at offset 128, workers only: +let file = IOUtils.openFileForSyncReading(path); +let bytes = new Uint8Array(64); +file.readBytesInto(bytes, 128); +file.close(); +``` + +### Writing to a file + +IOUtils provides the following methods to write data to a file. Like +OS.File, they accept an options dictionary. + +```idl +Promise<unsigned long long> write(DOMString path, Uint8Array data, ...); + +Promise<unsigned long long> writeUTF8(DOMString path, DOMString string, ...); + +Promise<unsigned long long> writeJSON(DOMString path, any value, ...); +``` + +#### Options + +| `OS.File` option | `IOUtils` option | Description | +| -------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| backupTo: string? | backupFile: string? | Identifies the path to backup the target file to before performing the write operation. If unspecified, no backup will be performed. Default is null. | +| tmpPath: string? | tmpPath: string? | Identifies a path to write to first, before performing a move to overwrite the target file. If unspecified, the target file will be written to directly. Default is null. | +| noOverwrite: boolean | mode: 'overwrite' or 'create' | 'create' mode will refuse to overwrite an existing file. Default is 'overwrite'. | +| flush: boolean | flush: boolean | If true, force the OS to flush its internal buffers to disk. Default is false. | +| encoding: 'utf-8' | N/A; use `writeUTF8` instead. | Allows the caller to supply a string to be encoded as utf-8 text on disk. | + +#### Examples +##### Write raw (unsigned) byte values + +**`OS.File`** +```js +let bytes = new Uint8Array(); +await OS.File.writeAtomic(path, bytes); +``` + +**`IOUtils`** +```js +let bytes = new Uint8Array(); +await IOUtils.write(path, bytes); +``` + +##### Write UTF-8 encoded text + +**`OS.File`** +```js +let str = ""; +await OS.File.writeAtomic(path, str, { encoding: 'utf-8' }); +``` + +**`IOUtils`** +```js +let str = ""; +await IOUtils.writeUTF8(path, str); +``` + +##### Write A JSON object + +**`IOUtils`** +```js +let obj = {}; +await IOUtils.writeJSON(path, obj); +``` + +##### Write with LZ4 compression + +**`OS.File`** +```js +let bytes = new Uint8Array(); +await OS.File.writeAtomic(path, bytes, { compression: 'lz4' }); +let str = ""; +await OS.File.writeAtomic(path, str, { + compression: 'lz4', +}); +``` + +**`IOUtils`** +```js +let bytes = new Uint8Array(); +await IOUtils.write(path, bytes, { compress: true }); +let str = ""; +await IOUtils.writeUTF8(path, str, { compress: true }); +``` + +### Move a file + +`IOUtils` provides the following method to move files on disk. +Like `OS.File`, it accepts an options dictionary. + +```idl +Promise<void> move(DOMString sourcePath, DOMString destPath, ...); +``` + +#### Options + +| `OS.File` option | `IOUtils` option | Description | +| -------------------- | ----------------------------------- | ---------------------------------------------------------------------------- | +| noOverwrite: boolean | noOverwrite: boolean | If true, fail if the destination already exists. Default is false. | +| noCopy: boolean | N/A; will not be implemented | This option is not implemented in `IOUtils`, and will be ignored if provided | + +#### Example + +**`OS.File`** +```js +await OS.File.move(srcPath, destPath); +``` + +**`IOUtils`** +```js +await IOUtils.move(srcPath, destPath); +``` + +### Remove a file + +`IOUtils` provides *one* method to remove files from disk. +`OS.File` provides several methods. + +```idl +Promise<void> remove(DOMString path, ...); +``` + +#### Options + +| `OS.File` option | `IOUtils` option | Description | +| ---------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------- | +| ignoreAbsent: boolean | ignoreAbsent: boolean | If true, and the destination does not exist, then do not raise an error. Default is true. | +| N/A; `OS.File` has dedicated methods for directory removal | recursive: boolean | If true, and the target is a directory, recursively remove the directory and all its children. Default is false. | + +#### Examples + +##### Remove a file + +**`OS.File`** +```js +await OS.File.remove(path, { ignoreAbsent: true }); +``` + +**`IOUtils`** +```js +await IOUtils.remove(path); +``` + +##### Remove a directory and all its contents + +**`OS.File`** +```js +await OS.File.removeDir(path, { ignoreAbsent: true }); +``` + +**`IOUtils`** +```js +await IOUtils.remove(path, { recursive: true }); +``` + +##### Remove an empty directory + +**`OS.File`** +```js +await OS.File.removeEmptyDir(path); // Will throw an exception if `path` is not empty. +``` + +**`IOUtils`** +```js +await IOUtils.remove(path); // Will throw an exception if `path` is not empty. +``` + +### Make a directory + +`IOUtils` provides the following method to create directories on disk. +Like `OS.File`, it accepts an options dictionary. + +```idl +Promise<void> makeDirectory(DOMString path, ...); +``` + +#### Options + +| `OS.File` option | `IOUtils` option | Description | +| ----------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ignoreExisting: boolean | ignoreExisting: boolean | If true, succeed even if the target directory already exists. Default is true. | +| from: string | createAncestors: boolean | If true, `IOUtils` will create all missing ancestors in a path. Default is true. This option differs from `OS.File`, which requires the caller to specify a root path from which to create missing directories. | +| unixMode: number | permissions: unsigned long | The file mode to create the directory with. Ignored on Windows. Default is 0755. | +| winSecurity | N/A | `IOUtils` does not support setting custom directory security settings on Windows. | + +#### Example + +**`OS.File`** +```js +await OS.File.makeDir(srcPath, destPath); +``` +**`IOUtils`** +```js +await IOUtils.makeDirectory(srcPath, destPath); +``` + +### Update a file's modification time + +`IOUtils` provides the following method to update a file's modification time. + +```idl +Promise<void> setModificationTime(DOMString path, optional long long modification); +``` + +#### Example + +**`OS.File`** +```js +await OS.File.setDates(path, new Date(), new Date()); +``` + +**`IOUtils`** +```js +await IOUtils.setModificationTime(path, new Date().valueOf()); +``` + +### Get file metadata + +`IOUtils` provides the following method to query file metadata. + +```idl +Promise<void> stat(DOMString path); +``` + +#### Example + +**`OS.File`** +```js +let fileInfo = await OS.File.stat(path); +``` + +**`IOUtils`** +```js +let fileInfo = await IOUtils.stat(path); +``` + +### Copy a file + +`IOUtils` provides the following method to copy a file on disk. +Like `OS.File`, it accepts an options dictionary. + +```idl +Promise<void> copy(DOMString path, ...); +``` + +#### Options + +| `OS.File` option | `IOUtils` option | Description | +| ------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------| +| noOverwrite: boolean | noOverwrite: boolean | If true, fail if the destination already exists. Default is false. | +| N/A; `OS.File` does not appear to support recursively copying files | recursive: boolean | If true, copy the source recursively. | + +#### Examples + +##### Copy a file + +**`OS.File`** +```js +await OS.File.copy(srcPath, destPath); +``` + +**`IOUtils`** +```js +await IOUtils.copy(srcPath, destPath); +``` + +##### Copy a directory recursively + +**`OS.File`** +```js +// Not easy to do. +``` + +**`IOUtils`** +```js +await IOUtils.copy(srcPath, destPath, { recursive: true }); +``` + +### Iterate a directory + +At the moment, `IOUtils` does not have a way to expose an iterator for directories. +This is blocked by +[bug 1577383](https://bugzilla.mozilla.org/show_bug.cgi?id=1577383). +As a stop-gap for this functionality, +one can get all the children of a directory and iterate through the returned path array using the following method. + +```idl +Promise<sequence<DOMString>> getChildren(DOMString path); +``` + +#### Example + +**`OS.File`** +```js +for await (const { path } of new OS.FileDirectoryIterator(dirName)) {</p> + ... +} +``` + +**`IOUtils`** +```js +for (const path of await IOUtils.getChildren(dirName)) { + ... +} +``` + +### Check if a file exists + +`IOUtils` provides the following method analogous to the `OS.File` method of the same name. + +```idl +Promise<boolean> exists(DOMString path); +``` + +#### Example + +**`OS.File`** +```js +if (await OS.File.exists(path)) { + ... +} +``` + +**`IOUtils`** +```js +if (await IOUtils.exists(path)) { + ... +} +``` + +### Set the permissions of a file + +`IOUtils` provides the following method analogous to the `OS.File` method of the same name. + +```idl +Promise<void> setPermissions(DOMString path, unsigned long permissions, optional boolean honorUmask = true); +``` + +#### Options + +| `OS.File` option | `IOUtils` option | Description | +| ----------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| unixMode: number | permissions: unsigned long | The UNIX file mode representing the permissions. Required in IOUtils. | +| unixHonorUmask: boolean | honorUmask: boolean | If omitted or true, any UNIX file mode is modified by the permissions. Otherwise the exact value of the permissions will be applied. | + +#### Example + +**`OS.File`** +```js +await OS.File.setPermissions(path, { unixMode: 0o600 }); +``` + +**`IOUtils`** +```js +await IOUtils.setPermissions(path, 0o600); +``` + +## FAQs + +**Why should I use `IOUtils` instead of `OS.File`?** + +[Bug 1231711](https://bugzilla.mozilla.org/show_bug.cgi?id=1231711) +provides some good context, but some reasons include: +* reduced cache-contention, +* faster startup, and +* less memory usage. + +Additionally, `IOUtils` benefits from a native implementation, +which assists in performance-related work for +[Project Fission](https://hacks.mozilla.org/2021/05/introducing-firefox-new-site-isolation-security-architecture/). + +We are actively working to migrate old code usages of `OS.File` +to analogous `IOUtils` calls, so new usages of `OS.File` +should not be introduced at this time. + +**Do I need to import anything to use this API?** + +Nope! It's available via the `IOUtils` global in JavaScript (`ChromeOnly` context). + +**Can I use this API from C++ or Rust?** + +Currently usage is geared exclusively towards JavaScript callers, +and all C++ methods are private except for the Web IDL bindings. +However given sufficient interest, +it should be easy to expose ergonomic public methods for C++ and/or Rust. + +**Why isn't `IOUtils` written in Rust?** + +At the time of writing, +support for Web IDL bindings was more mature for C++ oriented tooling than it was for Rust. + +**Is `IOUtils` feature complete? When will it be available?** + +`IOUtils` is considered feature complete as of Firefox 83. diff --git a/dom/docs/ipc/Fission-IPC-Diagram.svg b/dom/docs/ipc/Fission-IPC-Diagram.svg new file mode 100644 index 0000000000..f53d4b65b4 --- /dev/null +++ b/dom/docs/ipc/Fission-IPC-Diagram.svg @@ -0,0 +1,5 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" version="1.1" width="841px" height="861px" viewBox="-0.5 -0.5 841 861" content="<mxfile modified="2019-04-26T17:33:16.547Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0" etag="ryQDoUVJ1oS_b3fguxas" version="10.6.5" type="google"><diagram id="GcJpJ4Eku4OUxVByAJcz" name="Page-1">7Vxbc9o6EP41PDZjyzd4DCSkZ6ZnJnNyZto+dYQtQImxOLZISH/9kWzJNxlsKAY1pQ+ptbp6d7/VrrRmYE1W24cYrpd/kwCFA2AE24F1NwBgZA7ZX054zwiO7WWERYyDjGQWhCf8EwmiIagbHKCk0pASElK8rhJ9EkXIpxUajGPyVm02J2F11jVcIIXw5MNQpX7FAV1m1KFjFPTPCC+WcmbTEDUrKBsLQrKEAXkrkaz7gTWJCaHZ02o7QSHnneRL1m+6ozZfWIwi2qXDN289dbav0x8Pw89T4IHk2f7nkxjlFYYb8cJisfRdciAmmyhAfBBzYI3flpiipzX0ee0bEzmjLekqFNXqouQMKKZoWyKJRT4gskI0fmdNRK0t+CUUxrSNGyejvBUC8FzRalliPpC8h0Loi3zwgi/sQbDmADYB7dlkgyY22cMGNtm9scnSj02O24VPOTfPwydb4dOYWyoUM+JjTHyUJArj2PvSKncSGpMXNCEhiRklIhFrOZ7jMKyRYIgXESv6jItsCmvMuYeZibsVFSscBHyaRnEUAjP48CSiT2JRDRboYPEM62C3G6RjNkkH9CUcp0GJ3ZDzPsCv7HHBHyeMD/ytS/LK2rApS83+TCl6I/PCMnSvMjxUhq6pmxCBo7AeBcw5E0US0yVZkAiG9wW1xqSizRdC1kJaz4jSd+Fpwg0lVVmiLabfeHdmiLLS91LN3VaMnBbeZSFi71vqxIvfy3VFt7Qk+zXqTUJhTG+568o1JYRJgn1JnuKwdW9MyCb20R6+CgecjbdAdE874blznu9VoBiFkOLXqsN8em3w2p2LM6jHVTr7Vr3f4LL/4YpbsrRiu2Ez3M5yxyeJ/bSn+9+Gh0RjeOOTVVHk65P95WiN1lqZNkqmMVyhLwQGfKKsfhbXe7RY/arm9O+4jmqekdfkt5qgwSC7vRnk0U4p892owi8pNl7xKUnRdMsamGC9Lcs0Y/Zj7v7mosgG3CELfXB+rOU/3j4MO9qH0antg+j6SHAqaqnETi2+MnM9lYNkSxX9aiqYL+R4rRwqSim06THjrmZAZvC8OJAt48/YS0cdsSJdX002U9XMCo2eLHEY6KbQduMB3ZkV2lS48uFChZ6xIjHQDhZTK7CYqi2Lkq9olrsUeqHFsTRAy0Ws/cdCi7yLakUL0AstTRc+LYEanvPwqSFCm/Uaoekdj7nyYvNiKLatS6LYLGG4QHQbiisYvvGci8MYdIVxP+EUezf4Xmqw5kFSUhq5Fm05Ru2Q1hqJ3WTasQcL2Ko92EO2ipMGZbZ6ICSD/HGMORPruqueqscowT/hLG3AtUEwh7V2xgPnbnDIeXoIZygcQ/9lkSJAHrkOgDVP/zVq0V7YKZYjz0EQSx6Ur/mbLIpxYw09cVNxbBQupJorsuxC5vME9RJuy5nU6CQTrJYximeMLu91Nd2Ol7bCYw/PznQE12lTvrqRB+4/dtf9x9HLjdyZwaDJoZvlaHjqZv8ueOlf752Oeg/0Opkz1eQQrY7m6mqvxdnc7oSaD3drpCfY3K6bjKcX2NQsHr02GRdouMl4V72vqXP7JqPZibYaO2u1ydTVXodNxv5tLoD6V/uuGQLSiddF7Xde5GcHC5oY/bqLpUNijuX+LtqvbyTeOVfA1Qs1O5MFtEJNfc/QATVA85vjuqXR4up4dLU0v2hp8s8YW91SoJWlyRVYU7jUTYwOcJHfS1zhcjxcQFe4WHrBBShwOT7Tot9ceM0yLepA1iDV4jIn9xKSZgWQN+BEaRO5mSgZibZUjufNai1fG3Il/RVkW11d7pN/69KcK1FXPA8ouezZSym57AfncdS/mGzP46h/KTs8Tx6HGl7onscR4Bj5FBPej4mLW4zOuR3yWvMEuR3G0AEVicnfWjhWSftP7QBqhoKGqR0KSjXI7ZCibtjsl6bcWB+Q/0JYo78e2STGnCkuMKaYGWemqvu+SitGaNjQ77fMDeCiuO3sA1zoM7y8WzRL1mnZOHeeqbqEtnLXJXblUvtnh02LPu6LxeO/U08YfnG0YASnKP2bui381KQZ5YRBeB6mPseSmWsUKT7QCcBf/3EYQwH+0GgAfm4NDkA+KxY/zpOZ2OIXjqz7/wE=</diagram></mxfile>"><defs/><g><rect x="20" y="160.5" width="760" height="200" rx="30" ry="30" fill="#ffffff" stroke="#000000" pointer-events="none"/><rect x="20" y="440.5" width="480" height="400" rx="60" ry="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><rect x="540" y="440.5" width="240" height="400" rx="36" ry="36" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(80.5,168.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="98" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 99px; white-space: nowrap; overflow-wrap: normal; font-weight: bold; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Browser Process</div></div></foreignObject><text x="49" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica" font-weight="bold">Browser Process</text></switch></g><g transform="translate(82.5,814.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="95" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 96px; white-space: nowrap; overflow-wrap: normal; font-weight: bold; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>Content Process</div></div></div></foreignObject><text x="48" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica" font-weight="bold"><div>Content Process</div></text></switch></g><g transform="translate(612.5,814.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="95" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 96px; white-space: nowrap; overflow-wrap: normal; font-weight: bold; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div>Content Process</div></div></div></foreignObject><text x="48" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica" font-weight="bold"><div>Content Process</div></text></switch></g><path d="M 130 256.87 L 130 271 L 130 261 L 130 274.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 251.62 L 133.5 258.62 L 130 256.87 L 126.5 258.62 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 279.38 L 126.5 272.38 L 130 274.13 L 133.5 272.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="70" y="190.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(71.5,199.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="116" height="41" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 116px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div><xul:browser src="a.com"/></div><div>nsFrameLoader<br /></div></div></div></foreignObject><text x="58" y="27" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><path d="M 130 346.87 L 130 454.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 341.62 L 133.5 348.62 L 130 346.87 L 126.5 348.62 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 459.88 L 126.5 452.88 L 130 454.63 L 133.5 452.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(103.5,394.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="52" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;background-color:#ffffff;"><font style="font-size: 12px">PBrowser</font></div></div></foreignObject><text x="26" y="12" fill="#000000" text-anchor="middle" font-size="11px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><rect x="70" y="280.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(90.5,304.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="79" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 80px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserParent</div></div></foreignObject><text x="40" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserParent</text></switch></g><path d="M 130 526.87 L 130 541 L 130 531 L 130 544.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 521.62 L 133.5 528.62 L 130 526.87 L 126.5 528.62 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 549.38 L 126.5 542.38 L 130 544.13 L 133.5 542.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="70" y="460.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(94.5,484.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="71" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 72px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserChild</div></div></foreignObject><text x="36" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserChild</text></switch></g><path d="M 130 617.37 L 130 631.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 612.12 L 133.5 619.12 L 130 617.37 L 126.5 619.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 636.88 L 126.5 629.88 L 130 631.63 L 133.5 629.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="70" y="550.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(89.5,574.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="81" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 82px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">nsWebBrowser</div></div></foreignObject><text x="41" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">nsWebBrowser</text></switch></g><path d="M 130 704.37 L 130 723.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 699.12 L 133.5 706.12 L 130 704.37 L 126.5 706.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 130 728.88 L 126.5 721.88 L 130 723.63 L 133.5 721.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="70" y="638" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(71.5,647.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="116" height="41" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 116px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div><iframe src="b.com"/></div><div>nsFrameLoader</div></div></div></foreignObject><text x="58" y="27" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><path d="M 196.37 760 L 480 760 L 480 236 L 593.63 236" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 191.12 760 L 198.12 756.5 L 196.37 760 L 198.12 763.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 598.88 236 L 591.88 239.5 L 593.63 236 L 591.88 232.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(436.5,384.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="87" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;background-color:#ffffff;">PBrowserBridge</div></div></foreignObject><text x="44" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">PBrowserBridge</text></switch></g><rect x="70" y="729.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(76.5,753.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="106" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 107px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserBridgeChild</div></div></foreignObject><text x="53" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserBridgeChild</text></switch></g><path d="M 390 347.37 L 390 454.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 390 342.12 L 393.5 349.12 L 390 347.37 L 386.5 349.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 390 459.88 L 386.5 452.88 L 390 454.63 L 393.5 452.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(363.5,394.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="52" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;background-color:#ffffff;"><div style="font-size: 12px"><font style="font-size: 12px">PBrowser</font></div></div></div></foreignObject><text x="26" y="12" fill="#000000" text-anchor="middle" font-size="11px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><rect x="330" y="280.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(350.5,304.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="79" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 80px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserParent</div></div></foreignObject><text x="40" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserParent</text></switch></g><path d="M 390 527.37 L 390 541 L 390 531 L 390 544.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 390 522.12 L 393.5 529.12 L 390 527.37 L 386.5 529.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 390 549.38 L 386.5 542.38 L 390 544.13 L 393.5 542.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="330" y="460.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(354.5,484.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="71" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 72px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserChild</div></div></foreignObject><text x="36" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserChild</text></switch></g><path d="M 660 347.37 L 660 454.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 342.12 L 663.5 349.12 L 660 347.37 L 656.5 349.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 459.38 L 656.5 452.38 L 660 454.13 L 663.5 452.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(633.5,394.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="52" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;background-color:#ffffff;"><font style="font-size: 12px">PBrowser</font></div></div></foreignObject><text x="26" y="12" fill="#000000" text-anchor="middle" font-size="11px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><rect x="600" y="280.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(620.5,304.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="79" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 80px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserParent</div></div></foreignObject><text x="40" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserParent</text></switch></g><path d="M 660 527.37 L 660 541 L 660 531 L 660 544.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 522.12 L 663.5 529.12 L 660 527.37 L 656.5 529.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 549.38 L 656.5 542.38 L 660 544.13 L 663.5 542.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="600" y="460.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(624.5,484.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="71" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 72px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserChild</div></div></foreignObject><text x="36" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserChild</text></switch></g><path d="M 390 257.37 L 390 271 L 390 261 L 390 274.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 390 252.12 L 393.5 259.12 L 390 257.37 L 386.5 259.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 390 279.38 L 386.5 272.38 L 390 274.13 L 393.5 272.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="330" y="190.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(332.5,214.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="114" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 115px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserBridgeParent</div></div></foreignObject><text x="57" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserBridgeParent</text></switch></g><path d="M 660 257.37 L 660 274.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 252.12 L 663.5 259.12 L 660 257.37 L 656.5 259.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 279.88 L 656.5 272.88 L 660 274.63 L 663.5 272.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="600" y="190.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(602.5,214.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="114" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 115px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserBridgeParent</div></div></foreignObject><text x="57" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserBridgeParent</text></switch></g><rect x="330" y="550.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(349.5,574.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="81" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 82px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">nsWebBrowser</div></div></foreignObject><text x="41" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">nsWebBrowser</text></switch></g><path d="M 660 617.37 L 660 631.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 612.12 L 663.5 619.12 L 660 617.37 L 656.5 619.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 636.88 L 656.5 629.88 L 660 631.63 L 663.5 629.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="600" y="550.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(619.5,574.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="81" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 82px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">nsWebBrowser</div></div></foreignObject><text x="41" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">nsWebBrowser</text></switch></g><path d="M 660 704.37 L 660 723.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 699.12 L 663.5 706.12 L 660 704.37 L 656.5 706.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 660 728.88 L 656.5 721.88 L 660 723.63 L 663.5 721.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="600" y="638" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(601.5,647.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="116" height="41" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 116px; white-space: normal; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><div><iframe src="a.com"/></div><div>nsFrameLoader</div></div></div></foreignObject><text x="58" y="27" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g><path d="M 593.63 760 L 560 760 L 560 239 C 563.9 239 563.9 233 560 233 L 560 233 L 560 206 L 456.37 206" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 598.88 760 L 591.88 763.5 L 593.63 760 L 591.88 756.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 451.12 206 L 458.12 202.5 L 456.37 206 L 458.12 209.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(517.5,412.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="87" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;background-color:#ffffff;">PBrowserBridge</div></div></foreignObject><text x="44" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">PBrowserBridge</text></switch></g><rect x="600" y="729.5" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(606.5,753.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="106" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 107px; white-space: nowrap; overflow-wrap: normal; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">BrowserBridgeChild</div></div></foreignObject><text x="53" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">BrowserBridgeChild</text></switch></g><g transform="translate(24.5,19.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="249" height="130" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; overflow: hidden; max-height: 130px; max-width: 790px; width: 250px; white-space: normal; overflow-wrap: normal;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;"><h1>Gecko IPC for Fission<br /></h1><div>Example:</div><div><xul:browser src="a.com"/></div><div> <iframe src="b.com"/></div><div> <iframe src="a.com"/><br /></div><div><br /></div></div></div></foreignObject><text x="125" y="71" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">[Not supported by viewer]</text></switch></g></g></svg>
\ No newline at end of file diff --git a/dom/docs/ipc/Fission-actors-diagram.png b/dom/docs/ipc/Fission-actors-diagram.png Binary files differnew file mode 100644 index 0000000000..d3acce2c5c --- /dev/null +++ b/dom/docs/ipc/Fission-actors-diagram.png diff --git a/dom/docs/ipc/Fission-framescripts.png b/dom/docs/ipc/Fission-framescripts.png Binary files differnew file mode 100644 index 0000000000..98748bc965 --- /dev/null +++ b/dom/docs/ipc/Fission-framescripts.png diff --git a/dom/docs/ipc/index.rst b/dom/docs/ipc/index.rst new file mode 100644 index 0000000000..4a044ab906 --- /dev/null +++ b/dom/docs/ipc/index.rst @@ -0,0 +1,9 @@ +DOM IPC +======= + +.. toctree:: + :maxdepth: 1 + + jsactors + mainthread + process_model diff --git a/dom/docs/ipc/jsactors.rst b/dom/docs/ipc/jsactors.rst new file mode 100644 index 0000000000..0e8648c1d6 --- /dev/null +++ b/dom/docs/ipc/jsactors.rst @@ -0,0 +1,550 @@ +JSActors +======== + +In the Fission world, the preferred method of communication between between things-that-may-live-in-a-different-process are JSActors. + +At the time of this writing, Fission offers the following JSActors: + +- `JSProcessActor`, to communicate between a child process and its parent; +- `JSWindowActor`, to communicate between a frame and its parent. + +JSProcessActor +--------------- + +What are JSProcessActors? +~~~~~~~~~~~~~~~~~~~~~~~~~ + +A JSProcess pair (see below) is the preferred method of communication between a child process and its parent process. + +In the Fission world, JSProcessActors are the replacement for e10s-era *process scripts*. + +The life of a JSProcessActor pair +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +JSProcessActors always exist by pair: + +- one instance of `JSProcessActorChild`, which lives in the child process – for instance, `MyActorChild`; +- one instance of `JSProcessActorParent`, which lives in the parent process – for instance, `MyActorParent`. + +The pair is instantiated lazily, upon the first call to `getActor("MyActor")` (see below). Note that if a +parent process has several children, the parent process will typically host several instances of `MyActorParent` +whereas the children will each host a single instance of `MyActorChild`. + +JSProcessActor primitives allow sending and receiving messages *within the pair*. As of this writing, +JSProcessActor does not offer primitives for broadcasting, enumerating, etc. + +The pair dies when the child process dies. + +About actor names +`````````````````` + +Note that the names +`MyActorChild` and `MyActorParent` are meaningful – suffixes `Child` and `Parent` are how `getActor(...)` finds +the correct classes to load within the JS code. + + +JSWindowActor +--------------- + +What are JSWindowActors? +~~~~~~~~~~~~~~~~~~~~~~~~~ + +A JSWindowActor pair (see below) is the preferred method of communication between a frame and its parent, regardless of whether the frame +and parent live in the same process or in distinct processes. + +In the Fission world, JSWindowActors are the replacement for *framescripts*. Framescripts were how we structured code to be aware of the parent (UI) and child (content) separation, including establishing the communication channel between the two (via the Frame Message Manager). + +However, the framescripts had no way to establish further process separation downwards (that is, for out-of-process iframes). JSWindowActors will be the replacement. + +How are they structured? +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A review of the pre-Fission Message Manager mechanism +````````````````````````````````````````````````````` + +.. note:: + There are actually several types of Message Managers: Frame Message Managers, Window Message Managers, Group Message Managers and Process Message Managers. For the purposes of this documentation, it's simplest to refer to all of these mechanisms altogether as the "Message Manager mechanism". Most of the examples in this document will be operating on the assumption that the Message Manager is a Frame Message Manager, which is the most commonly used one. + +Currently, in the post `Electrolysis Project`_ Firefox codebase, we have code living in the parent process (UI) that is in plain JS (.js files) or in JS modules (.jsm files). In the child process (hosting the content), we use framescripts (.js) and also JS modules. The framescripts are instantiated once per top-level frame (or, in simpler terms, once per tab). This code has access to all of the DOM from the web content, including all iframes within it. + +The two processes communicate via the Frame Message Manager (mm) using the ``sendAsyncMessage`` / ``receiveMessage`` API, and any code in the parent can communicate with any code in the child (and vice versa), by just listening to the messages of interest. + +The Frame Message Manager communication mechanism follows a publish / subscribe pattern similar to how Events work in Firefox: + +1. Something exposes a mechanism for subscribing to notifications (``addMessageListener`` for the Frame Message Manager, ``addEventListener`` for Events). +2. The subscriber is responsible for unsubscribing when there's no longer interest in the notifications (``removeMessageListener`` for the Frame Message Manager, ``removeEventListener`` for Events). +3. Any number of subscribers can be attached at any one time. + +.. figure:: Fission-framescripts.png + :width: 320px + :height: 200px + +How JSWindowActors differ from the Frame Message Manager +`````````````````````````````````````````````````````````` + +For Fission, the JSWindowActors replacing framescripts will be structured in pairs. A pair of JSWindowActors will be instantiated lazily: one in the parent and one in the child process, and a direct channel of communication between the two will be established. The JSWindowActor in the parent must extend the global ``JSWindowActorParent`` class, and the JSWindowActor in the child must extend the global ``JSWindowActorChild`` class. + +The JSWindowActor mechanism is similar to how `IPC Actors`_ work in the native layer of Firefox: + +#. Every Actor has one counterpart in another process that they can communicate directly with. +#. Every Actor inherits a common communications API from a parent class. +#. Every Actor has a name that ends in either ``Parent`` or ``Child``. +#. There is no built-in mechanism for subscribing to messages. When one JSWindowActor sends a message, the counterpart JSWindowActor on the other side will receive it without needing to explicitly listen for it. + +Other notable differences between JSWindowActor's and Message Manager / framescripts: + +#. Each JSWindowActor pair is associated with a particular frame. For example, given the following DOM hierarchy:: + + <browser src="https://www.example.com"> + <iframe src="https://www.a.com" /> + <iframe src="https://www.b.com" /> + + A ``JSWindowActorParent`` / ``JSWindowActorChild`` pair instantiated for either of the ``iframe``'s would only be sending messages to and from that ``iframe``. + +#. There's only one pair per actor type, per frame. + + For example, suppose we have a ``ContextMenu`` actor. The parent process can have up to N instances of the ``ContextMenuParent`` actor, where N is the number of frames that are currently loaded. For any individual frame though, there's only ever one `ContextMenuChild` associated with that frame. + +#. We can no longer assume full, synchronous access to the frame tree, even in content processes. + + This is a natural consequence of splitting frames to run out-of-process. + +#. ``JSWindowActorChild``'s live as long as the ``WindowGlobalChild`` they're associated with. + + If in the previously mentioned DOM hierarchy, one of the ``<iframe>``'s unload, any associated JSWindowActor pairs will be torn down. + +.. hint:: + JSWindowActors are "managed" by the WindowGlobal IPC Actors, and are implemented as JS classes (subclasses of ``JSWindowActorParent`` and ``JSWindowActorChild``) instantiated when requested for any particular window. Like the Frame Message Manager, they are ultimately using IPC Actors to communicate under the hood. + +.. figure:: Fission-actors-diagram.png + :width: 233px + :height: 240px + +.. note:: + Like the Message Manager, JSWindowActors are implemented for both in-process and out-of-process frame communication. This means that porting to JSWindowActors can be done immediately without waiting for out-of-process iframes to be enabled. + + +Communication with actors +------------------------- + +Sending messages +~~~~~~~~~~~~~~~~ + +The ``JSActor`` base class exposes two methods for sending messages. Both methods are asynchronous. +There **is no way to send messages synchronously** with ``JSActor``. + + +``sendAsyncMessage`` +```````````````````` + + sendAsyncMessage("SomeMessage", value[, transferables]); + +The ``value`` is anything that can be serialized using the structured clone algorithm. Additionally, a ``nsIPrincipal`` can be sent without having to manually serialize and deserialize it. + +The ``transferables`` argument is an optional array of `Transferable`_ objects. Note that transferable objects like ``ArrayBuffers`` are not transferable across process and their contents will just be copied into the serialized data. However, ``transferables`` are still useful for objects like ``MessageChannel`` ports, as these can be transferred across process boundaries. + +.. note:: + Cross Process Object Wrappers (CPOWs) cannot be sent over JSWindowActors. + + +``sendQuery`` +````````````` + + Promise<any> sendQuery("SomeMessage", value); + + +``sendQuery`` improves upon ``sendAsyncMessage`` by returning a ``Promise``. The receiver of the message must then return a ``Promise`` that can eventually resolve into a value - at which time the ``sendQuery`` ``Promise`` resolves with that value. + +The ``sendQuery`` method arguments follow the same conventions as ``sendAsyncMessage``, with the second argument being a structured clone. + +Receiving messages +~~~~~~~~~~~~~~~~~~ + +``receiveMessage`` +`````````````````` + +To receive messages, you need to implement + + receiveMessage(value) + +The method receives a single argument, which is the de-serialized arguments that were sent via either ``sendAsyncMessage`` or ``sendQuery``. + +.. note:: + If `receiveMessage` is responding to a `sendQuery`, it MUST return a ``Promise`` for that message. + +.. hint:: + Using ``sendQuery``, and the ``receiveMessage`` is able to return a value right away? Try using ``Promise.resolve(value);`` to return ``value``, or you could also make your ``receiveMessage`` method an async function, presuming none of the other messages it handles need to get a non-Promise return value. + +Other methods that can be overridden +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``constructor()`` + +If there's something you need to do as soon as the ``JSActor`` is instantiated, the ``constructor`` function is a great place to do that. + +.. note:: + At this point the infrastructure for sending messages is not ready yet and objects such as ``manager`` or ``browsingContext`` are not available. + +``observe(subject, topic, data)`` +````````````````````````````````` + +If you register your Actor to listen for ``nsIObserver`` notifications, implement an ``observe`` method with the above signature to handle the notification. + +``handleEvent(event)`` +`````````````````````` + +If you register your Actor to listen for content events, implement a ``handleEvent`` method with the above signature to handle the event. + +.. note:: + Only JSWindowActors can register to listen for content events. + +``actorCreated`` +```````````````` + +This method is called immediately *after* a child actor is created and initialized. Unlike the actor's constructor, it is possible to do things like access the actor's content window and send messages from this callback. + +``didDestroy`` +`````````````` + +This is another point to clean-up an Actor before it is destroyed, but at this point, no communication is possible with the other side. + +.. note:: + This method cannot be async. + +.. note:: + As a `JSProcessActorChild` is destroyed when its process dies, a `JSProcessActorChild` will never receive this call. + +Other things exposed on a JSWindowActorParent +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``CanonicalBrowsingContext`` +```````````````````````````` + +Getter: ``this.browsingcontext``. + +``WindowGlobalParent`` +`````````````````````` + +TODO + +Other things exposed on a JSWindowActorChild +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``BrowsingContext`` +``````````````````` + +TODO + +``WindowGlobalChild`` +````````````````````` + +TODO + + +Helpful getters +``````````````` + +A number of helpful getters exist on a ``JSWindowActorChild``, including: + +``this.document`` +^^^^^^^^^^^^^^^^^ + +The currently loaded document in the frame associated with this ``JSWindowActorChild``. + +``this.contentWindow`` +^^^^^^^^^^^^^^^^^^^^^^ + +The outer window for the frame associated with this ``JSWindowActorChild``. + +``this.docShell`` +^^^^^^^^^^^^^^^^^ + +The ``nsIDocShell`` for the frame associated with this ``JSWindowActorChild``. + +See `JSWindowActor.webidl`_ for more detail on exactly what is exposed on both ``JSWindowActorParent`` and ``JSWindowActorChild`` implementations. + +How to port from message manager and framescripts to JSWindowActors +------------------------------------------------------------------- + +.. _fission.message-manager-actors: + +Message Manager Actors +~~~~~~~~~~~~~~~~~~~~~~ + +While the JSWindowActor mechanism was being designed and developed, large sections of our framescripts were converted to an "actor style" pattern to make eventual porting to JSWindowActors easier. These Actors use the Message Manager under the hood, but made it much easier to shrink our framescripts, and also allowed us to gain significant memory savings by having the actors be lazily instantiated. + +You can find the list of Message Manager Actors (or "Legacy Actors") in :searchfox:`BrowserGlue.sys.mjs <browser/components/BrowserGlue.sys.mjs>` and :searchfox:`ActorManagerParent.sys.mjs <toolkit/modules/ActorManagerParent.sys.mjs>`, in the ``LEGACY_ACTORS`` lists. + +.. note:: + The split in Message Manager Actors defined between ``BrowserGlue`` and ``ActorManagerParent`` is mainly to keep Firefox Desktop specific Actors separate from Actors that can (in theory) be instantiated for non-Desktop browsers (like Fennec and GeckoView-based browsers). Firefox Desktop-specific Actors should be registered in ``BrowserGlue``. Shared "toolkit" Actors should go into ``ActorManagerParent``. + +"Porting" these Actors often means doing what is necessary in order to move their registration entries from ``LEGACY_ACTORS`` to the ``JSWINDOWACTORS`` list. + +Figuring out the lifetime of a new Actor pair +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the old model, framescript were loaded and executed as soon as possible by the top-level frame. In the JSWindowActor model, the Actors are much lazier, and only instantiate when: + +1. They're instantiated explicitly by calling ``getActor`` on a ``WindowGlobal``, and passing in the name of the Actor. +2. A message is sent to them. +3. A pre-defined ``nsIObserver`` observer notification fires with the subject of the notification corresponding to an inner or outer window. +4. A pre-defined content Event fires. + +Making the Actors lazy like this saves on processing time to get a frame ready to load web pages, as well as the overhead of loading the Actor into memory. + +When porting a framescript to JSWindowActors, often the first question to ask is: what's the entrypoint? At what point should the Actors instantiate and become active? + +For example, when porting the content area context menu for Firefox, it was noted that the ``contextmenu`` event firing in content was a natural event to wait for to instantiate the Actor pair. Once the ``ContextMenuChild`` instantiated, the ``handleEvent`` method was used to inspect the event and prepare a message to be sent to the ``ContextMenuParent``. This example can be found by looking at the patch for the `Context Menu Fission Port`_. + +.. _fission.registering-a-new-jswindowactor: + +Using ContentDOMReference instead of CPOWs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Despite being outlawed as a way of synchronously accessing the properties of objects in other processes, CPOWs ended up being useful as a way of passing handles for DOM elements between processes. + +CPOW messages, however, cannot be sent over the JSWindowActor communications pipe, so this handy mechanism will no longer work. + +Instead, a new module called :searchfox:`ContentDOMReference.sys.mjs <toolkit/modules/ContentDOMReference.sys.mjs>` has been created which supplies the same capability. See that file for documentation. + +How to start porting parent-process browser code to use JSWindowActors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :ref:`fission.message-manager-actors` work made it much easier to migrate away from framescripts towards something that is similar to ``JSWindowActors``. It did not, however, substantially change how the parent process interacted with those framescripts. + +So when porting code to work with ``JSWindowActors``, we find that this is often where the time goes - refactoring the parent process browser code to accommodate the new ``JSWindowActor`` model. + +Usually, the first thing to do is to find a reasonable name for your actor pair, and get them registered (see :ref:`fission.registering-a-new-jswindowactor`), even if the actors implementations themselves are nothing but unmodified subclasses of ``JSWindowActorParent`` and ``JSWindowActorChild``. + +Next, it's often helpful to find and note all of the places where ``sendAsyncMessage`` is being used to send messages through the old message manager interface for the component you're porting, and where any messages listeners are defined. + +Let's look at a hypothetical example. Suppose we're porting part of the Page Info dialog, which scans each frame for useful information to display in the dialog. Given a chunk of code like this: + +.. code-block:: javascript + + // This is some hypothetical Page Info dialog code. + + let mm = browser.messageManager; + mm.sendAsyncMessage("PageInfo:getInfoFromAllFrames", { someArgument: 123 }); + + // ... and then later on + + mm.addMessageListener("PageInfo:info", async function onmessage(message) { + // ... + }); + +If a ``PageInfo`` pair of ``JSWindowActor``'s is registered, it might be tempting to simply replace the first part with: + +.. code-block:: javascript + + let actor = browser.browsingContext.currentWindowGlobal.getActor("PageInfo"); + actor.sendAsyncMessage("PageInfo:getInfoFromAllFrames", { someArgument: 123 }); + +However, if any of the frames on the page are running in their own process, they're not going to receive that ``PageInfo:getInfoFromAllFrames`` message. Instead, in this case, we should walk the ``BrowsingContext`` tree, and instantiate a ``PageInfo`` actor for each global, and send one message each to get information for each frame. Perhaps something like this: + +.. code-block:: javascript + + let contextsToVisit = [browser.browsingContext]; + while (contextsToVisit.length) { + let currentContext = contextsToVisit.pop(); + let global = currentContext.currentWindowGlobal; + + if (!global) { + continue; + } + + let actor = global.getActor("PageInfo"); + actor.sendAsyncMessage("PageInfo:getInfoForFrame", { someArgument: 123 }); + + contextsToVisit.push(...currentContext.children); + } + +The original ``"PageInfo:info"`` message listener will need to be updated, too. Any responses from the ``PageInfoChild`` actor will end up being passed to the ``receiveMessage`` method of the ``PageInfoParent`` actor. It will be necessary to pass that information along to the interested party (in this case, the dialog code which is showing the table of interesting Page Info). + +It might be necessary to refactor or rearchitect the original senders and consumers of message manager messages in order to accommodate the ``JSWindowActor`` model. Sometimes it's also helpful to have a singleton management object that manages all ``JSWindowActorParent`` instances and does something with their results. + +Where to store state +~~~~~~~~~~~~~~~~~~~~ + +It's not a good idea to store any state within a ``JSWindowActorChild`` that you want to last beyond the lifetime of its ``BrowsingContext``. An out-of-process ``<iframe>`` can be closed at any time, and if it's the only one for a particular content process, that content process will soon be shut down, and any state you may have stored there will go away. + +Your best bet for storing state is in the parent process. + +.. hint:: + If each individual frame needs state, consider using a ``WeakMap`` in the parent process, mapping ``CanonicalBrowsingContext``'s with that state. That way, if the associates frames ever go away, you don't have to do any cleaning up yourself. + +If you have state that you want multiple ``JSWindowActorParent``'s to have access to, consider having a "manager" of those ``JSWindowActorParent``'s inside of the same .jsm file to hold that state. + +Registering a new actor +----------------------- + +``ChromeUtils`` exposes an API for registering actors, but both ``BrowserGlue`` and ``ActorManagerParent`` are the main entry points where the registration occurs. If you want to register an actor, +you should add it either to ``JSPROCESSACTORS`` or ``JSWINDOWACTORS`` in either of those two files. + +In the ``JS*ACTORS`` objects, each key is the name of the actor pair (example: ``ContextMenu``), and the associated value is an ``Object`` of registration parameters. + +The full list of registration parameters can be found: + +- for JSProcessActor in file `JSProcessActor.webidl`_ as ``WindowActorOptions``, ``ProcessActorSidedOptions`` and ``ProcessActorChildOptions``. +- for JSWindowActor in file `JSWindowActor.webidl`_ as ``WindowActorOptions``, ``WindowActorSidedOptions`` and ``WindowActorChildOptions``. + +Here's an example ``JSWindowActor`` registration pulled from ``BrowserGlue.sys.mjs``: + +.. code-block:: javascript + + Plugin: { + kind: "JSWindowActor", + parent: { + esModuleURI: "resource:///actors/PluginParent.sys.mjs", + }, + child: { + esModuleURI: "resource:///actors/PluginChild.sys.mjs", + events: { + PluginCrashed: { capture: true }, + }, + + observers: ["decoder-doctor-notification"], + }, + + allFrames: true, + }, + +This example is for the JSWindowActor implementation of crash reporting for GMP. + +Let's examine parent registration: + +.. code-block:: javascript + + parent: { + esModuleURI: "resource:///actors/PluginParent.sys.mjs", + }, + +Here, we're declaring that class ``PluginParent`` (here, a subclass of ``JSWindowActorParent``) is defined and exported from module ``PluginParent.sys.mjs``. That's all we have to say for the parent (main process) side of things. + +.. note:: + It's not sufficient to just add a new .jsm file to the actors subdirectories. You also need to update the ``moz.build`` files in the same directory to get the ``resource://`` linkages set up correctly. + +Let's look at the second chunk: + +.. code-block:: javascript + + child: { + esModuleURI: "resource:///actors/PluginChild.sys.mjs", + events: { + PluginCrashed: { capture: true }, + }, + + observers: ["decoder-doctor-notification"], + }, + + allFrames: true, + }, + +We're similarly declaring where the ``PluginChild`` subclassing ``JSWindowActorChild`` can be found. + +Next, we declare the content events which, when fired in a window, will cause the ``JSWindowActorChild`` to instantiate if it doesn't already exist, and then have ``handleEvent`` called on the ``PluginChild`` instance. For each event name, an Object of event listener options can be passed. You can use the same event listener options as accepted by ``addEventListener``. If an event listener has no useful effect when the actor hasn't been created yet, ``createActor: false`` may also be specified to avoid creating the actor when not needed. + +.. note:: + Content events make sense for ``JSWindowActorChild`` (which *have* a content) but are ignored for ``JSProcessActorChild`` (which don't). + +Next, we declare that ``PluginChild`` should observe the ``decoder-doctor-notification`` ``nsIObserver`` notification. When that observer notification fires, the ``PluginChild`` actor will be instantiated for the ``BrowsingContext`` corresponding to the inner or outer window that is the subject argument of the observer notification, and the ``observe`` method on that ``PluginChild`` implementation will be called. If you need this functionality to work with other subjects, please file a bug. + +.. note:: + Unlike ``JSWindowActorChild`` subclasses, observer topics specified for ``JSProcessActorChild`` subclasses will cause those child actor instances to be created and invoke their ``observe`` method no matter what the subject argument of the observer is. + +Finally, we say that the ``PluginChild`` actor should apply to ``allFrames``. This means that the ``PluginChild`` is allowed to be loaded in any subframe. If ``allFrames`` is set to false (the default), the actor will only ever load in the top-level frame. + +Design considerations when adding a new actor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A few things worth bearing in mind when adding your own actor registration: + +- Any ``child`` or ``parent`` side you register **must** have a ``moduleURI`` property. +- You do not need to have both ``child`` and ``parent`` modules, and should avoid having actor sides that do nothing but send messages. The process without a defined module will still get an actor, and you can send messages from that side, but cannot receive them via ``receiveMessage``. Note that you **can** also use ``sendQuery`` from this side, enabling you to handle a response from the other process despite not having a ``receiveMessage`` method. +- If you are writing a JSWindowActor, consider whether you really need ``allFrames`` - it'll save memory and CPU time if we don't need to instantiate the actor for subframes. +- When copying/moving "Legacy" :ref:`fission.message-manager-actors`, remove their ``messages`` properties. They are no longer necessary. + + +Minimal Example Actors +----------------------- + +Get a JSWindowActor +~~~~~~~~~~~~~~~~~~~~ + +**Define an Actor** + +.. code-block:: javascript + + // resource://testing-common/TestWindowParent.jsm + var EXPORTED_SYMBOLS = ["TestWindowParent"]; + class TestParent extends JSWindowActorParent { + ... + } + +.. code-block:: javascript + + // resource://testing-common/TestWindowChild.jsm + var EXPORTED_SYMBOLS = ["TestWindowChild"]; + class TestChild extends JSWindowActorChild { + ... + } + + +**Get a JS window actor for a specific window** + +.. code-block:: javascript + + // get parent side actor + let parentActor = this.browser.browsingContext.currentWindowGlobal.getActor("TestWindow"); + + // get child side actor + let childActor = content.windowGlobalChild.getActor("TestWindow"); + +Get a JSProcessActor +~~~~~~~~~~~~~~~~~~~~ + +**Define an Actor** + +.. code-block:: javascript + + // resource://testing-common/TestProcessParent.jsm + var EXPORTED_SYMBOLS = ["TestProcessParent"]; + class TestParent extends JSProcessActorParent { + ... + } + +.. code-block:: javascript + + // resource://testing-common/TestProcessChild.jsm + var EXPORTED_SYMBOLS = ["TestProcessChild"]; + class TestChild extends JSProcessActorChild { + ... + } + + +**Get a JS process actor for a specific process** + +.. code-block:: javascript + + // get parent side actor + let parentActor = this.browser + .browsingContext + .currentWindowGlobal + .domProcess + .getActor("TestProcess"); + + // get child side actor + let childActor = ChromeUtils.domProcessChild + .getActor("TestProcess"); + +And more +=========== + + +.. _Electrolysis Project: https://wiki.mozilla.org/Electrolysis +.. _IPC Actors: https://developer.mozilla.org/en-US/docs/Mozilla/IPDL/Tutorial +.. _Context Menu Fission Port: https://hg.mozilla.org/mozilla-central/rev/adc60720b7b8 +.. _JSProcessActor.webidl: https://searchfox.org/mozilla-central/source/dom/chrome-webidl/JSProcessActor.webidl +.. _JSWindowActor.webidl: https://searchfox.org/mozilla-central/source/dom/chrome-webidl/JSWindowActor.webidl +.. _BrowserElementParent.jsm: https://searchfox.org/mozilla-central/rev/ec806131cb7bcd1c26c254d25cd5ab8a61b2aeb6/toolkit/actors/BrowserElementParent.jsm +.. _Transferable: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects diff --git a/dom/docs/ipc/mainthread.rst b/dom/docs/ipc/mainthread.rst new file mode 100644 index 0000000000..c04e8dc484 --- /dev/null +++ b/dom/docs/ipc/mainthread.rst @@ -0,0 +1,13 @@ +================== +Main Thread Actors +================== + +Actors on the main thread between the parent and content processes are +generally managed by ``PContent``, the primary actor for a content process. + +TODO + +Fission Actor Diagram +===================== + +.. image:: Fission-IPC-Diagram.svg diff --git a/dom/docs/ipc/process_model.rst b/dom/docs/ipc/process_model.rst new file mode 100644 index 0000000000..b405566a1d --- /dev/null +++ b/dom/docs/ipc/process_model.rst @@ -0,0 +1,334 @@ +Process Model +============= + +The complete set of recognized process types is defined in `GeckoProcessTypes <https://searchfox.org/mozilla-central/source/xpcom/geckoprocesstypes_generator/geckoprocesstypes/__init__.py>`_. + +For more details on how process types are added and managed by IPC, see the process creation documentation :ref:`Gecko Processes`. + +Diagram +------- + +.. digraph:: processtypes + :caption: Diagram of processes used by Firefox. All child processes are spawned and managed by the Parent process. + + compound=true; + node [shape=rectangle]; + + launcher [label=<Launcher Process>] + parent [label=<Parent Process>] + + subgraph cluster_child { + color=lightgrey; + label=<Child Processes>; + + subgraph cluster_content { + color=lightgrey; + label=<Content Processes>; + + web [ + color=lightgrey; + label=< + <TABLE BORDER="0" CELLSPACING="5" CELLPADDING="5" COLOR="black"> + <TR><TD BORDER="0" CELLPADDING="0" CELLSPACING="0">Web Content</TD></TR> + <TR><TD BORDER="1">Shared Web Content<BR/>(<FONT FACE="monospace">web</FONT>)</TD></TR> + <TR><TD BORDER="1">Isolated Web Content<BR/>(<FONT FACE="monospace">webIsolated=$SITE</FONT>)</TD></TR> + <TR><TD BORDER="1">COOP+COEP Web Content<BR/>(<FONT FACE="monospace">webCOOP+COEP=$SITE</FONT>)</TD></TR> + <TR><TD BORDER="1">ServiceWorker Web Content<BR/>(<FONT FACE="monospace">webServiceWorker</FONT>)</TD></TR> + </TABLE> + > + ] + + nonweb [ + shape=none; + label=< + <TABLE BORDER="0" CELLSPACING="5" CELLPADDING="5" COLOR="black"> + <TR><TD BORDER="1">Preallocated Content<BR/>(<FONT FACE="monospace">prealloc</FONT>)</TD></TR> + <TR><TD BORDER="1">File Content<BR/>(<FONT FACE="monospace">file</FONT>)</TD></TR> + <TR><TD BORDER="1">WebExtensions<BR/>(<FONT FACE="monospace">extension</FONT>)</TD></TR> + <TR><TD BORDER="1">Privileged Content<BR/>(<FONT FACE="monospace">privilegedabout</FONT>)</TD></TR> + <TR><TD BORDER="1">Privileged Mozilla Content<BR/>(<FONT FACE="monospace">privilegedmozilla</FONT>)</TD></TR> + </TABLE> + > + ] + } + + helper [ + color=lightgrey; + label=< + <TABLE BORDER="0" CELLSPACING="5" CELLPADDING="5" COLOR="black"> + <TR><TD BORDER="0" CELLPADDING="0" CELLSPACING="0">Helper Processes</TD></TR> + <TR><TD BORDER="1">Gecko Media Plugins (GMP) Process</TD></TR> + <TR><TD BORDER="1">GPU Process</TD></TR> + <TR><TD BORDER="1">VR Process</TD></TR> + <TR><TD BORDER="1">Data Decoder (RDD) Process</TD></TR> + <TR><TD BORDER="1">Network (Socket) Process</TD></TR> + <TR><TD BORDER="1">Utility Process</TD></TR> + <TR><TD BORDER="1">Remote Sandbox Broker Process</TD></TR> + <TR><TD BORDER="1">Fork Server</TD></TR> + </TABLE> + > + ] + } + + subgraph { rank=same; launcher -> parent; } + + parent -> web [lhead="cluster_content"]; + parent -> helper; + +.. _parent-process: + +Parent Process +-------------- + +:remoteType: *null* +:other names: UI Process, Main Process, Chrome Process, Browser Process, Default Process, Broker Process +:sandboxed?: no + +The parent process is the primary process which handles the core functionality of Firefox, including its UI, profiles, process selection, navigation, and more. The parent process is responsible for launching all other child processes, and acts as a broker establishing communication between them. + +All primary protocols establish a connection between the parent process and the given child process, which can then be used to establish additional connections to other processes. + +As the parent process can display HTML and JS, such as the browser UI and privileged internal pages such as ``about:preferences`` and ``about:config``, it is often treated as-if it was a content process with a *null* remote type by process selection logic. The parent process has extra protections in place to ensure it cannot load untrusted code when running in multiprocess mode. To this effect, any attempts to load web content in the parent process will lead to a browser crash, and all navigations to and from parent-process documents immediately perform full isolation, to prevent content processes from manipulating them. + +.. _content-process: + +Content Process +--------------- + +:primary protocol: `PContent <https://searchfox.org/mozilla-central/source/dom/ipc/PContent.ipdl>`_ +:other names: Renderer Process +:sandboxed?: yes (content sandbox policy) + +Content processes are used to load web content, and are the only process type (other than the parent process) which can load and execute JS code. These processes are further subdivided into specific "remote types", which specify the type of content loaded within them, their sandboxing behavior, and can gate access to certain privileged IPC methods. + +The specific remote type and isolation behaviour used for a specific resource is currently controlled in 2 major places. When performing a document navigation, the final process to load the document in is selected by the logic in `ProcessIsolation.cpp <https://searchfox.org/mozilla-central/source/dom/ipc/ProcessIsolation.cpp>`_. This will combine information about the specific response, such as the site and headers, with other state to select which process and other isolating actions should be taken. When selecting which process to create the initial process for a new tab in, and when selecting processes for serviceworkers and shared workers, the logic in :searchfox:`E10SUtils.sys.mjs <toolkit/modules/E10SUtils.sys.mjs>`_ is used to select a process. The logic in ``E10SUtils.sys.mjs`` will likely be removed and replaced with ``ProcessIsolation.cpp`` in the future. + +.. note:: + + The "Renderer" alternative name is used by Chromium for its equivalent to content processes, and is occasionally used in Gecko as well, due to the similarity in process architecture. The actual rendering & compositing steps are performed in the GPU or main process. + +Preallocated Content +^^^^^^^^^^^^^^^^^^^^ + +:remoteType: ``prealloc`` +:default count: 3 (``dom.ipc.processPrelaunch.fission.number``, or 1 if Fission is disabled) + +To avoid the need to launch new content processes to host new content when navigating, new content processes are pre-launched and specialized when they are requested. These preallocated content processes will never load content, and must be specialized before they can be used. + +The count of preallocated processes can vary depending on various factors, such as the memory available in the host system. + +The ``prealloc`` process cannot be used to launch ``file`` content processes, due to their weakened OS sandbox. ``extension`` content processes are also currently not supported due to `Bug 1637119 <https://bugzilla.mozilla.org/show_bug.cgi?id=1638119>`_. + +File Content +^^^^^^^^^^^^ + +:remoteType: ``file`` +:default count: 1 (``dom.ipc.processCount.file``) +:capabilities: File System Access + +The File content process is used to load ``file://`` URIs, and is therefore less sandboxed than other content processes. It may also be used to load remote web content if the browser has used a legacy CAPS preference to allow that site to access local resources (see `Bug 995943 <https://bugzilla.mozilla.org/show_bug.cgi?id=995943>`_) + +WebExtensions +^^^^^^^^^^^^^ + +:remoteType: ``extension`` +:default count: 1 (``dom.ipc.processCount.extension``) +:capabilities: Extension APIs, Shared Memory (SharedArrayBuffer) + +The WebExtension content process is used to load background pages and top level WebExtension frames. This process generally has access to elevated permissions due to loading privileged extension pages with access to the full WebExtension API surface. Currently all extensions share a single content process. + +Privileged extensions loaded within the extension process may also be granted access to shared memory using SharedArrayBuffer. + +.. note:: + + ``moz-extension://`` subframes are currently loaded in the same process as the parent document, rather than in the ``extension`` content process, due to existing permissions behaviour granting content scripts the ability to access the content of extension subframes. This may change in the future. + +Privileged Content +^^^^^^^^^^^^^^^^^^ + +:remoteType: ``privilegedabout`` +:default count: 1 (``dom.ipc.processCount.privilegedabout``) +:capabilities: Restricted JSWindowActor APIs + +The ``privilegedabout`` content process is used to load internal pages which have privileged access to internal state. The use of the ``privilegedabout`` content process is requested by including both ``nsIAboutModule::URI_MUST_LOAD_IN_CHILD`` and ``nsIAboutModule::URI_CAN_LOAD_IN_PRIVILEGEDABOUT_PROCESS`` flags in the corresponding ``nsIAboutModule``. + +As of August 11, 2021, the following internal pages load in the privileged content process: ``about:logins``, ``about:loginsimportreport``, ``about:privatebrowsing``, ``about:home``, ``about:newtab``, ``about:welcome``, ``about:protections``, and ``about:certificate``. + +Various ``JSWindowActor`` instances which provide special API access for these internal about pages are restricted to only be available in this content process through the ``remoteTypes`` attribute, which will block attempts to use them from other content processes. + +Privileged Mozilla Content +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:remoteType: ``privilegedmozilla`` +:default count: 1 (``dom.ipc.processCount.privilegedmozilla``) +:domains: ``addons.mozilla.org`` and ``accounts.firefox.com`` (``browser.tabs.remote.separatedMozillaDomains``) +:capabilities: Restricted Addon Manager APIs + +The ``privilegedmozilla`` content process is used to load specific high-value Mozilla-controlled webpages which have been granted access to privileged features. To provide an extra layer of security for these sites, they are loaded in a separate process from other web content even when Fission is disabled. + +This separate remote type is also used to gate access at the IPC boundary to certain high-power web APIs, such as access to the ability to interact with installed extension APIs. + +Web Content Processes +^^^^^^^^^^^^^^^^^^^^^ + +These processes all have remote types beginning with ``web``, and are used to host general untrusted web content. The different variants of web content processes are used at different times, depending on the isolation strategy requested by the page and the browser's configuration. + +Shared Web Content +"""""""""""""""""" + +:remoteType: ``web`` +:default count: 8 (``dom.ipc.processCount``) + +The shared web content process is used to host content which is not isolated into one of the other web content process types. This includes almost all web content with Fission disabled, and web content which cannot be attributed to a specific origin with Fission enabled, such as user-initiated ``data:`` URI loads. + +Isolated Web Content +"""""""""""""""""""" + +:remoteType: ``webIsolated=$SITE`` +:default count: 1 per-site (``dom.ipc.processCount.webIsolated``) + +Isolated web content processes are used to host web content with Fission which can be attributed to a specific site. These processes are allocated when navigating, and will only load content from the named site. When Fission is disabled, isolated web content processes are not used. + +A different ``webIsolated=`` remote type, and therefore a different pool of processes, is used for each site loaded, with separation also being used for different container tabs and private browsing. + +COOP+COEP Web Content +""""""""""""""""""""" + +:remoteType: ``webCOOP+COEP=$SITE`` +:default count: 1 per-site (``dom.ipc.processCount.webCOOP+COEP``) +:capabilities: Shared Memory (SharedArrayBuffer) + +When loading a top level document with both the ``Cross-Origin-Opener-Policy`` and ``Cross-Origin-Embedder-Policy`` headers configured correctly, the document is requesting access to Shared Memory. For security reasons, we only provide this API access to sufficiently-isolated pages, and we load them within special isolated content processes. + +Like Isolated Web Content, these processes are keyed by the site loaded within them, and are also segmented based on container tabs and private browsing. + +.. note:: + + Another name for this process may be "Cross-Origin Isolated Web Content", to correspond with the ``window.crossOriginIsolated`` attribute which is set for documents loaded with these headers set. Unfortunately that may be confused with Fission's "Isolated Web Content" processes, as the attribute was named after the ``webIsolated`` remote type was already in use. + + In ``about:processes``, COOP+COEP Web Content processes will be listed with a "cross-origin isolated" note after the PID, like ``https://example.com (12345, cross-origin isolated)``. + +ServiceWorker Web Content +""""""""""""""""""""""""" + +:remoteType: ``webServiceWorker=$SITE`` +:default count: 1 per-site using ServiceWorkers + +ServiceWorker web content processes are used to host ServiceWorkers on a per-site basis, so that ServiceWorker operations aren't impacted by MainThread event latency whenrunning in the same process as the content for the page. ServiceWorkers are usually transitory, and will disappear if unused for a short period of time. + +.. _gecko-media-plugins-process: + +Gecko Media Plugins (GMP) Process +--------------------------------- + +:primary protocol: `PGMP <https://searchfox.org/mozilla-central/source/dom/media/gmp/PGMP.ipdl>`_ +:sandboxed?: yes (GMP sandbox policy) + +The GMP process is used to sandbox third-party "Content Decryption Module" (CDM) binaries used for media playback in a sandboxed environment. This process is only launched when DRM-enabled content is loaded. + +.. _gpu-process: + +GPU Process +----------- + +:primary protocol: `PGPU <https://searchfox.org/mozilla-central/source/gfx/ipc/PGPU.ipdl>`_ +:other names: Compositor Process +:sandboxed?: no (`bug 1347710 <https://bugzilla.mozilla.org/show_bug.cgi?id=1347710>`_ tracks sandboxing on windows) + +The GPU process performs compositing, and is used to talk to GPU hardware in an isolated process. This helps isolate things like GPU driver crashes from impacting the entire browser, and will allow for this code to be sandboxed in the future. In addition, some components like Windows Media Foundation (WMF) are run in the GPU process when it is available. + +The GPU process is not used on all platforms. Platforms which do not use it, such as macOS and some Linux configurations, will perform compositing on a background thread in the Parent Process. + +.. _vr-process: + +VR Process +---------- + +:primary protocol: `PVR <https://searchfox.org/mozilla-central/source/gfx/vr/ipc/PVR.ipdl>`_ +:sandboxed?: no (`bug 1430043 <https://bugzilla.mozilla.org/show_bug.cgi?id=1430043>`_ tracks sandboxing on windows) + +VR headset libraries require access to specific OS level features and other requirements which we would generally like to block with the sandbox in other processes. In order to allow the GPU process to have tighter sandboxing rules, these VR libraries are loaded into the less-restricted VR process. Like the GPU process, this serves to isolate them from the rest of Firefox and reduce the impact of bugs in these libraries on the rest of the browser. The VR process is launched only after a user visits a site which uses WebVR. + +.. _data-decoder-process: + +Data Decoder (RDD) Process +-------------------------- + +:primary protocol: `PRDD <https://searchfox.org/mozilla-central/source/dom/media/ipc/PRDD.ipdl>`_ +:sandboxed?: yes (RDD sandbox policy) + +This process is used to run media data decoders within their own sandboxed process, allowing the code to be isolated from other code in Gecko. This aims to reduce the severity of potential bugs in media decoder libraries, and improve the security of the browser. + +.. note:: + + This process is in the process of being restructured into a generic "utility" process type for running untrusted code in a maximally secure sandbox. After these changes, the following new process types will exist, replacing the RDD process: + + * ``Utility``: A maximally sandboxed process used to host untrusted code which does not require access to OS resources. This process will be even more sandboxed than RDD today on Windows, where the RDD process has access to Win32k. + * ``UtilityWithWin32k``: A Windows-only process with the same sandboxing as the RDD process today. This will be used to host untrusted sandboxed code which requires access to Win32k to allow decoding directly into GPU surfaces. + * ``GPUFallback``: A Windows-only process using the GPU process' sandboxing policy which will be used to run Windows Media Foundation (WMF) when the GPU process itself is unavailable, allowing ``UtilityWithWin32k`` to re-enable Arbitrary Code Guard (ACG) on Windows. + + For more details about the planned utility process architecture changes, see `the planning document <https://docs.google.com/document/d/1WDEY5fQetK_YE5oxGxXK9BzC1A8kJP3q6F1gAPc2UGE>`_. + +.. _network-socket-process: + +Network (Socket) Process +------------------------ + +:primary protocol: `PSocketProcess <https://searchfox.org/mozilla-central/source/netwerk/ipc/PSocketProcess.ipdl>`_ +:sandboxed?: yes (socket sandbox policy) + +The socket process is used to separate certain networking operations from the parent process, allowing them to be performed more directly in a partially sandboxed process. The eventual goal is to move all TCP/UDP network operations into this dedicated process, and is being tracked in `Bug 1322426 <https://bugzilla.mozilla.org/show_bug.cgi?id=1322426>`_. + +.. _remote-sandbox-process: + +Remote Sandbox Broker Process +----------------------------- + +:platform: Windows on ARM only +:primary protocol: `PRemoteSandboxBroker <https://searchfox.org/mozilla-central/source/security/sandbox/win/src/remotesandboxbroker/PRemoteSandboxBroker.ipdl>`_ +:sandboxed?: no + +In order to run sandboxed x86 plugin processes from Windows-on-ARM, the remote sandbox broker process is launched in x86-mode, and used to launch sandboxed x86 subprocesses. This avoids issues with the sandboxing layer, which unfortunately assumes that pointer width matches between the sandboxer and sandboxing process. To avoid this, the remote sandbox broker is used as an x86 sandboxing process which wraps these plugins. + +.. _fork-server: + +Fork Server +----------- + +:platform: Linux only +:pref: ``dom.ipc.forkserver.enable`` (disabled by default) +:primary protocol: *none* +:sandboxed?: no (processes forked by the fork server are sandboxed) + +The fork server process is used to reduce the memory overhead and improve launch efficiency for new processes. When a new supported process is requested and the feature is enabled, the parent process will ask the fork server to ``fork(2)`` itself, and then begin executing. This avoids the need to re-load ``libxul.so`` and re-perform relocations. + +The fork server must run before having initialized XPCOM or the IPC layer, and therefore uses a custom low-level IPC system called ``MiniTransceiver`` rather than IPDL to communicate. + +.. _launcher-process: + +Launcher Process +---------------- + +:platform: Windows only +:metabug: `Bug 1435780 <https://bugzilla.mozilla.org/show_bug.cgi?id=1435780>`_ +:sandboxed?: no + +The launcher process is used to bootstrap Firefox on Windows before launching the main Firefox process, allowing things like DLL injection blocking to initialize before the main thread even starts running, and improving stability. Unlike the other utility processes, this process is not launched by the parent process, but rather launches it. + +IPDLUnitTest +------------ + +:primary protocol: varies + +This test-only process type is intended for use when writing IPDL unit tests. However, it is currently broken, due to these tests having never been run in CI. The type may be removed or re-used when these unit tests are fixed. + +.. _utility-process: + +Utility Process +--------------- + +:primary protocol: `PUtilityProcess <https://searchfox.org/mozilla-central/source/ipc/glue/PUtilityProcess.ipdl>`_ +:metabug: `Bug 1722051 <https://bugzilla.mozilla.org/show_bug.cgi?id=1722051>`_ +:sandboxed?: yes, customizable + +The utility process is used to provide a simple way to implement IPC actor with some more specific sandboxing properties, in case where you don't need or want to deal with the extra complexity of adding a whole new process type but you just want to apply different sandboxing policies. Details can be found in :ref:`Utility Process`. diff --git a/dom/docs/navigation/BrowsingContext.rst b/dom/docs/navigation/BrowsingContext.rst new file mode 100644 index 0000000000..213b2fcce5 --- /dev/null +++ b/dom/docs/navigation/BrowsingContext.rst @@ -0,0 +1,149 @@ +BrowsingContext and WindowContext +================================= + +The ``BrowsingContext`` is the Gecko representation of the spec-defined +`Browsing Context`_ object. + +.. _Browsing Context: https://html.spec.whatwg.org/multipage/browsers.html#browsing-context + + +The Browsing Context Tree +------------------------- + +``BrowsingContext`` and ``WindowContext`` objects form a tree, corresponding +to the tree of frame elements which was used to construct them. + + +Example +^^^^^^^ + +Loading the HTML documents listed here, would end up creating a set of BrowsingContexts and WindowContexts forming the tree. + +.. code-block:: html + + <!-- http://example.com/top.html --> + <iframe src="frame1.html"></iframe> + <iframe src="http://mozilla.org/"></iframe> + + <!-- http://example.com/frame1.html --> + <iframe src="http://example.com/frame2.html"></iframe> + + <!-- http://mozilla.org --> + <iframe></iframe> + <iframe></iframe> + +.. digraph:: browsingcontext + + node [shape=rectangle] + + "BC1" [label="BrowsingContext A"] + "BC2" [label="BrowsingContext B"] + "BC3" [label="BrowsingContext C"] + "BC4" [label="BrowsingContext D"] + "BC5" [label="BrowsingContext E"] + "BC6" [label="BrowsingContext F"] + + "WC1" [label="WindowContext\n(http://example.com/top.html)"] + "WC2" [label="WindowContext\n(http://example.com/frame1.html)"] + "WC3" [label="WindowContext\n(http://mozilla.org)"] + "WC4" [label="WindowContext\n(http://example.com/frame2.html)"] + "WC5" [label="WindowContext\n(about:blank)"] + "WC6" [label="WindowContext\n(about:blank)"] + + "BC1" -> "WC1"; + "WC1" -> "BC2"; + "WC1" -> "BC3"; + "BC2" -> "WC2"; + "BC3" -> "WC3"; + "WC2" -> "BC4"; + "BC4" -> "WC4"; + "WC3" -> "BC5"; + "BC5" -> "WC5"; + "WC3" -> "BC6"; + "BC6" -> "WC6"; + + +Synced Fields +------------- + +WIP - In-progress documentation at `<https://wiki.mozilla.org/Project_Fission/BrowsingContext>`_. + + +API Documentation +----------------- + +.. cpp:class:: BrowsingContext + + .. hlist:: + :columns: 3 + + * `header (searchfox) <https://searchfox.org/mozilla-central/source/docshell/base/BrowsingContext.h>`_ + * `source (searchfox) <https://searchfox.org/mozilla-central/source/docshell/base/BrowsingContext.cpp>`_ + * `html spec <https://html.spec.whatwg.org/multipage/browsers.html#browsing-context>`_ + + This is a synced-context type. Instances of it will exist in every + "relevant" content process for the navigation. + + Instances of :cpp:class:`BrowsingContext` created in the parent processes + will be :cpp:class:`CanonicalBrowsingContext`. + + .. cpp:function:: WindowContext* GetParentWindowContext() + + Get the parent ``WindowContext`` embedding this context, or ``nullptr``, + if this is the toplevel context. + + .. cpp:function:: WindowContext* GetTopWindowContext() + + Get the toplevel ``WindowContext`` embedding this context, or ``nullptr`` + if this is the toplevel context. + + This is equivalent to repeatedly calling ``GetParentWindowContext()`` + until it returns nullptr. + + .. cpp:function:: BrowsingContext* GetParent() + + .. cpp:function:: BrowsingContext* Top() + + .. cpp:function:: static already_AddRefed<BrowsingContext> Get(uint64_t aId) + + Look up a specific ``BrowsingContext`` by it's unique ID. Callers should + check if the returned context has already been discarded using + ``IsDiscarded`` before using it. + +.. cpp:class:: CanonicalBrowsingContext : public BrowsingContext + + .. hlist:: + :columns: 3 + + * `header (searchfox) <https://searchfox.org/mozilla-central/source/docshell/base/CanonicalBrowsingContext.h>`_ + * `source (searchfox) <https://searchfox.org/mozilla-central/source/docshell/base/CanonicalBrowsingContext.cpp>`_ + + When a :cpp:class:`BrowsingContext` is constructed in the parent process, + it is actually an instance of :cpp:class:`CanonicalBrowsingContext`. + + Due to being in the parent process, more information about the context is + available from a ``CanonicalBrowsingContext``. + +.. cpp:class:: WindowContext + + .. hlist:: + :columns: 3 + + * `header (searchfox) <https://searchfox.org/mozilla-central/source/docshell/base/WindowContext.h>`_ + * `source (searchfox) <https://searchfox.org/mozilla-central/source/docshell/base/WindowContext.cpp>`_ + +.. cpp:class:: WindowGlobalParent : public WindowContext, public WindowGlobalActor, public PWindowGlobalParent + + .. hlist:: + :columns: 3 + + * `header (searchfox) <https://searchfox.org/mozilla-central/source/dom/ipc/WindowGlobalParent.h>`_ + * `source (searchfox) <https://searchfox.org/mozilla-central/source/dom/ipc/WindowGlobalParent.cpp>`_ + +.. cpp:class:: WindowGlobalChild : public WindowGlobalActor, public PWindowGlobalChild + + .. hlist:: + :columns: 3 + + * `header (searchfox) <https://searchfox.org/mozilla-central/source/dom/ipc/WindowGlobalChild.h>`_ + * `source (searchfox) <https://searchfox.org/mozilla-central/source/dom/ipc/WindowGlobalChild.cpp>`_ diff --git a/dom/docs/navigation/embedding.rst b/dom/docs/navigation/embedding.rst new file mode 100644 index 0000000000..a42aabc6f5 --- /dev/null +++ b/dom/docs/navigation/embedding.rst @@ -0,0 +1,92 @@ +Browsing Context Embedding +========================== + +Embedder Element to nsDocShell +------------------------------ + +In order to render the contents of a ``BrowsingContext``, the embedding +element needs to be able to communicate with the ``nsDocShell`` which is +currently being used to host it's content. This is done in 3 different ways +depending on which combination of processes is in-use. + +- *in-process*: The ``nsFrameLoader`` directly embeds the ``nsDocShell``. +- *remote tab*: The parent process is the embedder, and uses a ``PBrowser``, + via a ``BrowserHost``. The ``BrowserChild`` actor holds the actual + ``nsDocShell`` alive. +- *remote subframe*: A content process is the embedder, and uses a + ``PBrowserBridge``, via a ``BrowserBridgeHost`` to communicate with the + parent process. The parent process then uses a ``BrowserParent``, as in the + *remote tab* case, to communicate with the ``nsDocShell``. + +Diagram +^^^^^^^ + +.. digraph:: embedding + + node [shape=rectangle] + + subgraph cluster_choice { + color=transparent; + node [shape=none]; + + "In-Process"; + "Remote Tab"; + "Remote Subframe"; + } + + "nsFrameLoaderOwner" [label="nsFrameLoaderOwner\ne.g. <iframe>, <xul:browser>, <embed>"] + + "nsFrameLoaderOwner" -> "nsFrameLoader"; + + "nsFrameLoader" -> "In-Process" [dir=none]; + "nsFrameLoader" -> "Remote Tab" [dir=none]; + "nsFrameLoader" -> "Remote Subframe" [dir=none]; + + "In-Process" -> "nsDocShell"; + "Remote Tab" -> "BrowserHost"; + "Remote Subframe" -> "BrowserBridgeHost"; + + "BrowserHost" -> "BrowserParent"; + "BrowserParent" -> "BrowserChild" [label="PBrowser" style=dotted]; + "BrowserChild" -> "nsDocShell"; + + "BrowserBridgeHost" -> "BrowserBridgeChild"; + "BrowserBridgeChild" -> "BrowserBridgeParent" [label="PBrowserBridge", style=dotted]; + "BrowserBridgeParent" -> "BrowserParent"; + +nsDocShell to Document +---------------------- + +Embedding an individual document within a ``nsDocShell`` is done within the +content process, which has that docshell. + + +Diagram +^^^^^^^ + +This diagram shows the objects involved in a content process which is being +used to host a given ``BrowsingContext``, along with rough relationships +between them. Dotted lines represent a "current" relationship, whereas solid +lines are a stronger lifetime relationship. + +.. graph:: document + + node [shape=rectangle] + + "BrowsingContext" -- "nsDocShell" [style=dotted]; + "nsDocShell" -- "nsGlobalWindowOuter"; + "nsGlobalWindowOuter" -- "nsGlobalWindowInner" [style=dotted]; + "nsGlobalWindowInner" -- "Document" [style=dotted]; + + "nsDocShell" -- "nsDocumentViewer" [style=dotted]; + "nsDocumentViewer" -- "Document"; + "nsDocumentViewer" -- "PresShell"; + + "nsGlobalWindowInner" -- "WindowGlobalChild"; + "BrowsingContext" -- "WindowContext" [style=dotted]; + "WindowContext" -- "nsGlobalWindowInner"; + + subgraph cluster_synced { + label = "Synced Contexts"; + "BrowsingContext" "WindowContext"; + } diff --git a/dom/docs/navigation/index.rst b/dom/docs/navigation/index.rst new file mode 100644 index 0000000000..b322855eb6 --- /dev/null +++ b/dom/docs/navigation/index.rst @@ -0,0 +1,9 @@ +DOM Navigation +============== + +.. toctree:: + :maxdepth: 1 + + embedding + BrowsingContext + nav_replace diff --git a/dom/docs/navigation/nav_replace.rst b/dom/docs/navigation/nav_replace.rst new file mode 100644 index 0000000000..6e2c710e28 --- /dev/null +++ b/dom/docs/navigation/nav_replace.rst @@ -0,0 +1,119 @@ +Objects Replaced by Navigations +=============================== + +There are 3 major types of navigations, each of which can cause different +objects to be replaced. The general rules look something like this: + +.. csv-table:: objects replaced or preserved across navigations + :header: "Class/Id", ":ref:`in-process navigations <in-process navigations>`", ":ref:`cross-process navigations <cross-process navigations>`", ":ref:`cross-group navigations <cross-group navigations>`" + + "BrowserId [#bid]_", |preserve|, |preserve|, |preserve| + "BrowsingContextWebProgress", |preserve|, |preserve|, |preserve| + "BrowsingContextGroup", |preserve|, |preserve|, |replace| + "BrowsingContext", |preserve|, |preserve|, |replace| + "nsFrameLoader", |preserve|, |replace|, |replace| + "RemoteBrowser", |preserve|, |replace|, |replace| + "Browser{Parent,Child}", |preserve|, |replace|, |replace| + "nsDocShell", |preserve|, |replace|, |replace| + "nsGlobalWindowOuter", |preserve|, |replace|, |replace| + "nsGlobalWindowInner", "|replace| [#inner]_", |replace|, |replace| + "WindowContext", "|replace| [#inner]_", |replace|, |replace| + "WindowGlobal{Parent,Child}", "|replace| [#inner]_", |replace|, |replace| + "Document", "|replace|", |replace|, |replace| + + +.. |replace| replace:: ❌ replaced +.. |preserve| replace:: ✔️ preserved + +.. [#bid] + + The BrowserId is a unique ID on each ``BrowsingContext`` object, obtained + using ``GetBrowserId``, not a class. This ID will persist even when a + ``BrowsingContext`` is replaced (e.g. due to + ``Cross-Origin-Opener-Policy``). + +.. [#inner] + + When navigating from the initial ``about:blank`` document to a same-origin + document, the same ``nsGlobalWindowInner``, ``WindowContext`` and + ``WindowGlobal{Parent,Child}`` may be used. This initial ``about:blank`` + document is the one created when synchronously accessing a newly-created + pop-up window from ``window.open``, or a newly-created document in an + ``<iframe>``. + +Types of Navigations +-------------------- + +.. _in-process navigations: + +in-process navigations +^^^^^^^^^^^^^^^^^^^^^^ + +An in-process navigation is the traditional type of navigation, and the most +common type of navigation when :ref:`Fission` is not enabled. + +These navigations are used when no process switching or BrowsingContext +replacement is required, which includes most navigations with Fission +disabled, and most same site-origin navigations when Fission is enabled. + +.. _cross-process navigations: + +cross-process navigations +^^^^^^^^^^^^^^^^^^^^^^^^^ + +A cross-process navigation is used when a navigation requires a process +switch to occur, and no BrowsingContext replacement is required. This is a +common type of load when :ref:`Fission` is enabled, though it is also used +for navigations to and from special URLs like ``file://`` URIs when +Fission is disabled. + +These process changes are triggered by ``DocumentLoadListener`` when it +determines that a process switch is required. See that class's documentation +for more details. + +.. _cross-group navigations: + +cross-group navigations +^^^^^^^^^^^^^^^^^^^^^^^ + +A cross-group navigation is used when the navigation's `response requires +a browsing context group switch +<https://html.spec.whatwg.org/multipage/origin.html#browsing-context-group-switches-due-to-cross-origin-opener-policy>`_. + +These types of switches may or may not cause the process to change, but will +finish within a different ``BrowsingContextGroup`` than they started with. +Like :ref:`cross-process navigations`, these navigations are triggered using +the process switching logic in ``DocumentLoadListener``. + +As the parent of a content browsing context cannot change due to a navigation, +only toplevel content browsing contexts can cross-group navigate. Navigations in +chrome browsing contexts [#chromebc]_ or content subframes only experience +either in-process or cross-process navigations. + +As of the time of this writing, we currently trigger a cross-group navigation +in the following circumstances, though this may change in the future: + +- If the `Cross-Origin-Opener-Policy + <https://html.spec.whatwg.org/multipage/origin.html#the-cross-origin-opener-policy-header>`_ + header is specified, and a mismatch is detected. +- When switching processes between the parent process, and a content process. +- When loading an extension document in a toplevel browsing context. +- When navigating away from a preloaded ``about:newtab`` document. +- When putting a ``BrowsingContext`` into BFCache for the session history + in-parent BFCache implementation. This will happen on most toplevel + navigations without opener relationships when the ``fission.bfcacheInParent`` + pref is enabled. + +State which needs to be saved over cross-group navigations on +``BrowsingContext`` instances is copied in the +``CanonicalBrowsingContext::ReplacedBy`` method. + +.. [#chromebc] + + A chrome browsing context does **not** refer to pages with the system + principal loaded in the content area such as ``about:preferences``. + Chrome browsing contexts are generally used as the root context in a chrome + window, such where ``browser.xhtml`` is loaded for a browser window. + + All chrome browsing contexts exclusively load in the parent process and + cannot process switch when navigating. diff --git a/dom/docs/push/index.md b/dom/docs/push/index.md new file mode 100644 index 0000000000..fb9e3db380 --- /dev/null +++ b/dom/docs/push/index.md @@ -0,0 +1,118 @@ +# Push +<div class="note"> +<div class="admonition-title">Note</div> +This document describes how Firefox implements the Web Push standard internally, and is intended for developers working directly on Push. If you are looking for how to consume push, please refer to the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Push_API" target="_blank">following MDN document</a> + +</div> + +## High level push architecture +The following sequence diagram describes the high level push architecture as observed by web application. The diagram describes the interactions between a Web application's client code running in the browser, Firefox, [Autopush](https://autopush.readthedocs.io/en/latest/) (Firefox's push server that delivers push notifications) and a third party server that sends the push notifications to Autopush + +The dotted lines are done by the consumer of push. +```{mermaid} +sequenceDiagram + participant TP as Web Application JS + participant F as Firefox + participant A as Autopush + participant TPS as Third party Server + TP->>F: subscribe(scope) + activate TP + activate F + F->>A: subscribe(scope) using web socket + activate A + A->>F: URL + deactivate A + F->>F: Create pub/privKey Encryption pair + F->>F: Persist URL, pubKey, privKey indexed using an id derived from scope + F->>TP: URL + pubKey + deactivate F + TP-->>TPS: URL + pubKey + deactivate TP + TPS-->>TPS: Encrypt payload using pubKey + TPS-->>A: Send encrypted payload using URL + activate A + A->>F: Send encrypted payload using web socket + deactivate A + activate F + F->>F: Decrypt payload using privKey + F->>F: Display Notification + deactivate F +``` + +## Flow diagram for source code + +The source code for push is available under [`dom/push`](https://searchfox.org/mozilla-central/source/dom/push) in mozilla-central. + +The following flow diagram describes how different modules interact with each other to provide the push API to consumers. + +```{mermaid} +flowchart TD + subgraph Public API + + W[Third party Web app]-->|imports| P[PushManager.webidl] + end + subgraph Browser Code + P-->|Implemented by| MM + MM{Main Thread?}-->|Yes| B[Push.sys.mjs] + MM -->|NO| A[PushManager.cpp] + B-->|subscribe,getSubscription| D[PushComponents.sys.mjs] + A-->|subscribe,getSubscription| D + D-->|subscribe,getSubscription| M[PushService.sys.mjs] + M-->|Storage| S[PushDB.sys.mjs] + M-->|Network| N[PushWebSocket.sys.mjs] + F[FxAccountsPush.sys.mjs] -->|uses| D + end + subgraph Server + N-. Send, Receive.-> O[Autopush] + end + subgraph Local Storage + S-->|Read,Write| PP[(IndexedDB)] + end +``` + +## The Push Web Socket +Push in Firefox Desktop communicates with Autopush using a web socket connection. + +The web socket connection is created as the browser initializes and is managed by the following state diagram. + +```{mermaid} +stateDiagram-v2 + state "Shut Down" as SD + state "Waiting for WebSocket to start" as W1 + state "Waiting for server hello" as W2 + state "Ready" as R + [*] --> SD + SD --> W1: beginWSSetup + W1 --> W2: wsOnStart Success + W2 --> R: handleHelloReply + R --> R: send (subscribe) + R --> R: Receive + notify observers + R --> SD: wsOnStop + R --> SD: sendPing Fails + W1 --> SD: wsOnStart fails + W2 --> SD: invalid server hello + R --> [*] +``` + +Once the Push web socket is on the `Ready` state, it is ready to send new subscriptions to Autopush, and receive push notifications from those subscriptions. + +Push uses an observer pattern to notify observers of any incoming push notifications. See the [high level architecture](#high-level-push-architecture) section. + + +## Push Storage +Push uses IndexedDB to store subscriptions for the following reasons: +1. In case the consumer attempts to re-subscribe, storage is used as a cache to serve the URL and the public key +1. In order to persist the private key, so that it can be used to decrypt any incoming push notifications + +The following is what gets persisted: + +```{mermaid} +erDiagram + Subscription { + string channelID "Key, Derived from scope" + string pushEndpoint "Unique endpoint for this subscription" + string scope "Usually the origin, unique value for internal consumers" + Object p256dhPublicKey "Object representing the public key" + Object p256dhPrivateKey "Object representing the private key" + } +``` diff --git a/dom/docs/scriptSecurity/images/compartments.png b/dom/docs/scriptSecurity/images/compartments.png Binary files differnew file mode 100644 index 0000000000..c80ea166ca --- /dev/null +++ b/dom/docs/scriptSecurity/images/compartments.png diff --git a/dom/docs/scriptSecurity/images/computing-a-wrapper.png b/dom/docs/scriptSecurity/images/computing-a-wrapper.png Binary files differnew file mode 100644 index 0000000000..1221ff4a00 --- /dev/null +++ b/dom/docs/scriptSecurity/images/computing-a-wrapper.png diff --git a/dom/docs/scriptSecurity/images/cross-compartment-wrapper.png b/dom/docs/scriptSecurity/images/cross-compartment-wrapper.png Binary files differnew file mode 100644 index 0000000000..ba31355d44 --- /dev/null +++ b/dom/docs/scriptSecurity/images/cross-compartment-wrapper.png diff --git a/dom/docs/scriptSecurity/images/cross-origin-wrapper.png b/dom/docs/scriptSecurity/images/cross-origin-wrapper.png Binary files differnew file mode 100644 index 0000000000..14b7022c3d --- /dev/null +++ b/dom/docs/scriptSecurity/images/cross-origin-wrapper.png diff --git a/dom/docs/scriptSecurity/images/opaque-wrapper.png b/dom/docs/scriptSecurity/images/opaque-wrapper.png Binary files differnew file mode 100644 index 0000000000..67cd87ba5b --- /dev/null +++ b/dom/docs/scriptSecurity/images/opaque-wrapper.png diff --git a/dom/docs/scriptSecurity/images/principal-relationships.png b/dom/docs/scriptSecurity/images/principal-relationships.png Binary files differnew file mode 100644 index 0000000000..0a4e7014f6 --- /dev/null +++ b/dom/docs/scriptSecurity/images/principal-relationships.png diff --git a/dom/docs/scriptSecurity/images/same-origin-wrapper.png b/dom/docs/scriptSecurity/images/same-origin-wrapper.png Binary files differnew file mode 100644 index 0000000000..ec966afa1b --- /dev/null +++ b/dom/docs/scriptSecurity/images/same-origin-wrapper.png diff --git a/dom/docs/scriptSecurity/images/xray-wrapper.png b/dom/docs/scriptSecurity/images/xray-wrapper.png Binary files differnew file mode 100644 index 0000000000..43316d9089 --- /dev/null +++ b/dom/docs/scriptSecurity/images/xray-wrapper.png diff --git a/dom/docs/scriptSecurity/index.rst b/dom/docs/scriptSecurity/index.rst new file mode 100644 index 0000000000..420f480d3c --- /dev/null +++ b/dom/docs/scriptSecurity/index.rst @@ -0,0 +1,318 @@ +Script Security +=============== + +.. container:: summary + + This page provides an overview of the script security architecture in + Gecko. + +Like any web browser, Gecko can load JavaScript from untrusted and +potentially hostile web pages and run it on the user's computer. The +security model for web content is based on the `same-origin policy +<https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy>`__, +in which code +gets full access to objects from its origin but highly restricted access +to objects from a different origin. The rules for determining whether an +object is same-origin with another, and what access is allowed +cross-origin, are now mostly standardized across browsers. + +Gecko has an additional problem, though: while its core is written in +C++, the front-end code is written in JavaScript. This JavaScript code, +which is commonly referred to as c\ *hrome code*, runs with system +privileges. If the code is compromised, the attacker can take over the +user's computer. Legacy SDK extensions also run with chrome privileges. + +Having the browser front end in JavaScript has benefits: it can be much +quicker to develop in JavaScript than in C++, and contributors do not +need to learn C++. However, JavaScript is a highly dynamic, malleable +language, and without help it's difficult to write system-privileged +code that interacts safely with untrusted web content. From the point of +view of chrome code, the script security model in Gecko is intended to +provide that help to make writing secure, system-privileged JavaScript a +realistic expectation. + +.. _Security_policy: + +Security policy +--------------- + +Gecko implements the following security policy: + +- **Objects that are same-origin** are able to access each other + freely. For example, the objects associated with a document served + from *https://example.org/* can access each other, and they can also + access objects served from *https://example.org/foo*. +- **Objects that are cross-origin** get highly restricted access to + each other, according to the same-origin policy. + For example, code served from *https://example.org/* trying to access + objects from *https://somewhere-else.org/* will have restricted + access. +- **Objects in a privileged scope** are allowed complete access to + objects in a less privileged scope, but by default they see a + `restricted view <#privileged-to-unprivileged-code>`__ + of such objects, designed to prevent them from being tricked by the + untrusted code. An example of this scope is chrome-privileged + JavaScript accessing web content. +- **Objects in a less privileged scope** don't get any access to + objects in a more privileged scope, unless the more privileged scope + `explicitly clones those objects <#unprivileged-to-privileged-code>`__. + An example of this scope is web content accessing objects in a + chrome-privileged scope. + +.. _Compartments: + +Compartments +------------ + +Compartments are the foundation for Gecko's script security +architecture. A compartment is a specific, separate area of memory. In +Gecko, there's a separate compartment for every global object. This +means that each global object and the objects associated with it live in +their own region of memory. + +.. image:: images/compartments.png + +Normal content windows are globals, of course, but so are chrome +windows, sandboxes, workers, the ``ContentFrameMessageManager`` in a frame +script, and so on. + +Gecko guarantees that JavaScript code running in a given compartment is +only allowed to access objects in the same compartment. When code from +compartment A tries to access an object in compartment B, Gecko gives it +a *cross-compartment wrapper*. This is a proxy in compartment A for the +real object, which lives in compartment B. + +.. image:: images/cross-compartment-wrapper.png + +Inside the same compartment, all objects share a global and are +therefore same-origin with each other. Therefore there's no need for any +security checks, there are no wrappers, and there is no performance +overhead for the common case of objects in a single window interacting +with each other. + +Whenever cross-compartment access happens, the wrappers enable us to +implement the appropriate security policy. Because the wrapper we choose +is specific to the relationship between the two compartments, the +security policy it implements can be static: when the caller uses the +wrapper, there's no need to check who is making the call or where it is +going. + +.. _Cross-compartment_access: + +Cross-compartment access +------------------------ + +.. _Same-origin: + +Same-origin +~~~~~~~~~~~ + +As we've already seen, the most common scenario for same-origin access +is when objects belonging to the same window object interact. This all +takes place within the same compartment, with no need for security +checks or wrappers. + +When objects share an origin but not a global - for example two web +pages from the same protocol, port, and domain - they belong to two +different compartments, and the caller gets a *transparent wrapper* to +the target object. + +.. image:: images/same-origin-wrapper.png + +Transparent wrappers allow access to all the target's properties: +functionally, it's as if the target is in the caller's compartment. + +.. _Cross-origin: + +Cross-origin +~~~~~~~~~~~~ + +If the two compartments are cross-origin, the caller gets a +*cross-origin wrapper*. + +.. image:: images/cross-origin-wrapper.png + +This denies access to all the object's properties, except for a few +properties of Window and Location objects, as defined by +the `same-origin +policy <https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#cross-origin_script_api_access>`__. + +.. _Privileged_to_unprivileged_code: + +Privileged to unprivileged code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The most obvious example of this kind of security relation is between +system-privileged chrome code and untrusted web content, but there are +other examples in Gecko. The Add-on SDK runs content scripts in +sandboxes, which are initialized with an `expanded +principal <#expanded-principal>`__, +giving them elevated privileges with respect to the web content they +operate on, but reduced privileges with respect to chrome. + +If the caller has a higher privilege than the target object, the caller +gets an *Xray wrapper* for the object. + +.. image:: images/xray-wrapper.png + +Xrays are designed to prevent untrusted code from confusing trusted code +by redefining objects in unexpected ways. For example, privileged code +using an Xray to a DOM object sees only the original version of the DOM +object. Any expando properties are not visible, and if any native DOM properties have been +redefined, they are not visible in the Xray. + +The privileged code is able to waive Xrays if it wants unfiltered access to the untrusted object. + +See `Xray vision <xray_vision.html>`__ for much more information on Xrays. + +.. _Unprivileged_to_privileged_code: + +Unprivileged to privileged code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the caller has lower privileges than the target object, then the +caller gets an *opaque wrapper.* + +.. image:: images/opaque-wrapper.png + +An opaque wrapper denies all access to the target object. + +However, the privileged target is able to copy objects and functions +into the less privileged scope using the ``exportFunction()`` and +``cloneInto()`` functions, and the less privileged scope is then able +to use them. + +.. _Security_checks: + +Security checks +--------------- + +To determine the security relation between two compartments, Gecko uses +two concepts: *security principals* and the act of *subsuming*. To +establish the security relationship between two compartments A and B, +Gecko asks: + +*Does the security principal for compartment A subsume the security +principal for compartment B, and vice versa?* + +.. _Subsumes: + +Subsumes +~~~~~~~~ + ++-----------------------------------+-----------------------------------+ +| *A subsumes B* | A has all of the privileges of B, | +| | and possibly more, and therefore | +| | A is allowed to see and do | +| | anything that B can see and do. | ++-----------------------------------+-----------------------------------+ +| *A Subsumes B &&* *B Subsumes A* | A and B are same-origin. | ++-----------------------------------+-----------------------------------+ +| *A Subsumes B && B !Subsumes A* | A is more privileged than B. | +| | | +| | A gets access to all of B, by | +| | default with Xray vision, which | +| | it may choose to waive. | +| | | +| | B gets no access to A, although A | +| | may choose to export objects to | +| | B. | ++-----------------------------------+-----------------------------------+ +| *A !Subsumes B && B !Subsumes A* | A and B are cross-origin. | ++-----------------------------------+-----------------------------------+ + +.. _Security_principals: + +Security principals +~~~~~~~~~~~~~~~~~~~ + +There are four types of security principal: the system principal, +content principals, expanded principals, and the null principal. + +.. _System_principal: + +System principal +^^^^^^^^^^^^^^^^ + +The system principal passes all security checks. It subsumes itself and +all other principals. Chrome code, by definition, runs with the system +principal, as do frame scripts. + +.. _Content_principal: + +Content principal +^^^^^^^^^^^^^^^^^ + +A content principal is associated with some web content and is defined +by the origin +of the content. For example, a normal DOM window has a content principal +defined by the window's origin. A content principal subsumes only other +content principals with the same origin. It is subsumed by the system +principal, any expanded principals that include its origin, and any +other content principals with the same origin. + +.. _Expanded_principal: + +Expanded principal +^^^^^^^^^^^^^^^^^^ + +An expanded principal is specified as an array of origins: + +.. code:: JavaScript + + ["http://mozilla.org", "http://moz.org"] + +The expanded principal subsumes every content principal it contains. The +content principals do not subsume the expanded principal, even if the +expanded principal only contains a single content principal. + +Thus ``["http://moz.org"]`` subsumes ``"http://moz.org"`` but not vice +versa. The expanded principal gets full access to the content principals +it contains, with Xray vision by default, and the content principals get +no access to the expanded principal. + +This also enables the script security model to treat compartments that +have expanded principals more like part of the browser than like web +content. This means, for example, that it can run when JavaScript is +disabled for web content. + +Expanded principals are useful when you want to give code extra +privileges, including cross-origin access, but don't want to give the +code full system privileges. For example, expanded principals are used +in the Add-on SDK to give content scripts cross-domain privileges for a predefined set of +domains, +and to protect content scripts from access by untrusted web content, +without having to give content scripts system privileges. + +.. _Null_principal: + +Null principal +^^^^^^^^^^^^^^ + +The null principal fails almost all security checks. It has no +privileges and can't be accessed by anything but itself and chrome. It +subsumes no other principals, even other null principals. (This is what +is used when HTML5 and other specs say "origin is a globally unique +identifier".) + +.. _Principal_relationships: + +Principal relationships +~~~~~~~~~~~~~~~~~~~~~~~ + +The diagram below summarizes the relationships between the different +principals. The arrow connecting principals A and B means "A subsumes +B". (A is the start of the arrow, and B is the end.) + +.. image:: images/principal-relationships.png + +.. _Computing_a_wrapper: + +Computing a wrapper +------------------- + +The following diagram shows the factors that determine the kind of +wrapper that compartment A would get when trying to access an object in +compartment B. + +.. image:: images/computing-a-wrapper.png diff --git a/dom/docs/scriptSecurity/xray_vision.rst b/dom/docs/scriptSecurity/xray_vision.rst new file mode 100644 index 0000000000..0e2eb2caf4 --- /dev/null +++ b/dom/docs/scriptSecurity/xray_vision.rst @@ -0,0 +1,411 @@ +Xray Vision +=========== + +.. container:: summary + + Xray vision helps JavaScript running in a privileged security context + safely access objects created by less privileged code, by showing the + caller only the native version of the objects. + +Gecko runs JavaScript from a variety of different sources and at a +variety of different privilege levels. + +- The JavaScript code that along with the C++ core, implements the + browser itself is called *chrome code* and runs using system + privileges. If chrome-privileged code is compromised, the attacker + can take over the user's computer. +- JavaScript loaded from normal web pages is called *content code*. + Because this code is being loaded from arbitrary web pages, it is + regarded as untrusted and potentially hostile, both to other websites + and to the user. +- As well as these two levels of privilege, chrome code can create + sandboxes. The security principal defined for the sandbox determines + its privilege level. If an + Expanded Principal is used, the sandbox is granted certain privileges + over content code and is protected from direct access by content + code. + +| The security machinery in Gecko ensures that there's asymmetric access + between code at different privilege levels: so for example, content + code can't access objects created by chrome code, but chrome code can + access objects created by content. +| However, even the ability to access content objects can be a security + risk for chrome code. JavaScript's a highly malleable language. + Scripts running in web pages can add extra properties to DOM objects + (also known as expando properties) + and even redefine standard DOM objects to do something unexpected. If + chrome code relies on such modified objects, it can be tricked into + doing things it shouldn't. +| For example: ``window.confirm()`` is a DOM + API that's supposed to ask the user to confirm an action, and return a + boolean depending on whether they clicked "OK" or "Cancel". A web page + could redefine it to return ``true``: + +.. code:: JavaScript + + window.confirm = function() { + return true; + } + +Any privileged code calling this function and expecting its result to +represent user confirmation would be deceived. This would be very naive, +of course, but there are more subtle ways in which accessing content +objects from chrome can cause security problems. + +| This is the problem that Xray vision is designed to solve. When a + script accesses an object using Xray vision it sees only the native + version of the object. Any expandos are invisible, and if any + properties of the object have been redefined, it sees the original + implementation, not the redefined version. +| So in the example above, chrome code calling the content's + ``window.confirm()`` would get the original version of ``confirm()``, + not the redefined version. + +.. note:: + + It's worth emphasizing that even if content tricks chrome into + running some unexpected code, that code does not run with chrome + privileges. So this is not a straightforward privilege escalation + attack, although it might lead to one if the chrome code is + sufficiently confused. + +.. _How_you_get_Xray_vision: + +How you get Xray vision +----------------------- + +Privileged code automatically gets Xray vision whenever it accesses +objects belonging to less-privileged code. So when chrome code accesses +content objects, it sees them with Xray vision: + +.. code:: JavaScript + + // chrome code + var transfer = gBrowser.contentWindow.confirm("Transfer all my money?"); + // calls the native implementation + +.. note:: + + Note that using window.confirm() would be a terrible way to implement + a security policy, and is only shown here to illustrate how Xray + vision works. + +.. _Waiving_Xray_vision: + +Waiving Xray vision +------------------- + +| Xray vision is a kind of security heuristic, designed to make most + common operations on untrusted objects simple and safe. However, there + are some operations for which they are too restrictive: for example, + if you need to see expandos on DOM objects. In cases like this you can + waive Xray protection, but then you can no longer rely on any + properties or functions being, or doing, what you expect. Any of them, + even setters and getters, could have been redefined by untrusted code. +| To waive Xray vision for an object you can use + Components.utils.waiveXrays(object), + or use the object's ``wrappedJSObject`` property: + +.. code:: JavaScript + + // chrome code + var waivedWindow = Components.utils.waiveXrays(gBrowser.contentWindow); + var transfer = waivedWindow.confirm("Transfer all my money?"); + // calls the redefined implementation + +.. code:: JavaScript + + // chrome code + var waivedWindow = gBrowser.contentWindow.wrappedJSObject; + var transfer = waivedWindow.confirm("Transfer all my money?"); + // calls the redefined implementation + +Waivers are transitive: so if you waive Xray vision for an object, then +you automatically waive it for all the object's properties. For example, +``window.wrappedJSObject.document`` gets you the waived version of +``document``. + +To undo the waiver again, call Components.utils.unwaiveXrays(waivedObject): + +.. code:: JavaScript + + var unwaived = Components.utils.unwaiveXrays(waivedWindow); + unwaived.confirm("Transfer all my money?"); + // calls the native implementation + +.. _Xrays_for_DOM_objects: + +Xrays for DOM objects +--------------------- + +The primary use of Xray vision is for DOM objects: that is, the +objects that represent parts of the web page. + +In Gecko, DOM objects have a dual representation: the canonical +representation is in C++, and this is reflected into JavaScript for the +benefit of JavaScript code. Any modifications to these objects, such as +adding expandos or redefining standard properties, stays in the +JavaScript reflection and does not affect the C++ representation. + +The dual representation enables an elegant implementation of Xrays: the +Xray just directly accesses the C++ representation of the original +object, and doesn't go to the content's JavaScript reflection at all. +Instead of filtering out modifications made by content, the Xray +short-circuits the content completely. + +This also makes the semantics of Xrays for DOM objects clear: they are +the same as the DOM specification, since that is defined using the +`WebIDL <http://www.w3.org/TR/WebIDL/>`__, and the WebIDL also defines +the C++ representation. + +.. _Xrays_for_JavaScript_objects: + +Xrays for JavaScript objects +---------------------------- + +Until recently, built-in JavaScript objects that are not part of the +DOM, such as +``Date``, ``Error``, and ``Object``, did not get Xray vision when +accessed by more-privileged code. + +Most of the time this is not a problem: the main concern Xrays solve is +with untrusted web content manipulating objects, and web content is +usually working with DOM objects. For example, if content code creates a +new ``Date`` object, it will usually be created as a property of a DOM +object, and then it will be filtered out by the DOM Xray: + +.. code:: JavaScript + + // content code + + // redefine Date.getFullYear() + Date.prototype.getFullYear = function() {return 1000}; + var date = new Date(); + +.. code:: JavaScript + + // chrome code + + // contentWindow is an Xray, and date is an expando on contentWindow + // so date is filtered out + gBrowser.contentWindow.date.getFullYear() + // -> TypeError: gBrowser.contentWindow.date is undefined + +The chrome code will only even see ``date`` if it waives Xrays, and +then, because waiving is transitive, it should expect to be vulnerable +to redefinition: + +.. code:: JavaScript + + // chrome code + + Components.utils.waiveXrays(gBrowser.contentWindow).date.getFullYear(); + // -> 1000 + +However, there are some situations in which privileged code will access +JavaScript objects that are not themselves DOM objects and are not +properties of DOM objects. For example: + +- the ``detail`` property of a CustomEvent fired by content could be a JavaScript + Object or Date as well as a string or a primitive +- the return value of ``evalInSandbox()`` and any properties attached to the + ``Sandbox`` object may be pure JavaScript objects + +Also, the WebIDL specifications are starting to use JavaScript types +such as ``Date`` and ``Promise``: since WebIDL definition is the basis +of DOM Xrays, not having Xrays for these JavaScript types starts to seem +arbitrary. + +So, in Gecko 31 and 32 we've added Xray support for most JavaScript +built-in objects. + +Like DOM objects, most JavaScript built-in objects have an underlying +C++ state that is separate from their JavaScript representation, so the +Xray implementation can go straight to the C++ state and guarantee that +the object will behave as its specification defines: + +.. code:: JavaScript + + // chrome code + + var sandboxScript = 'Date.prototype.getFullYear = function() {return 1000};' + + 'var date = new Date(); '; + + var sandbox = Components.utils.Sandbox("https://example.org/"); + Components.utils.evalInSandbox(sandboxScript, sandbox); + + // Date objects are Xrayed + console.log(sandbox.date.getFullYear()); + // -> 2014 + + // But you can waive Xray vision + console.log(Components.utils.waiveXrays(sandbox.date).getFullYear()); + // -> 1000 + +.. note:: + + To test out examples like this, you can use the Scratchpad in + browser context + for the code snippet, and the Browser Console to see the expected + output. + + Because code running in Scratchpad's browser context has chrome + privileges, any time you use it to run code, you need to understand + exactly what the code is doing. That includes the code samples in + this article. + +.. _Xray_semantics_for_Object_and_Array: + +Xray semantics for Object and Array +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The exceptions are ``Object`` +and ``Array``: their interesting state is in JavaScript, not C++. This +means that the semantics of their Xrays have to be independently +defined: they can't simply be defined as "the C++ representation". + +The aim of Xray vision is to make most common operations simple and +safe, avoiding the need to access the underlying object except in more +involved cases. So the semantics defined for ``Object`` and ``Array`` +Xrays aim to make it easy for privileged code to treat untrusted objects +like simple dictionaries. + +Any value properties +of the object are visible in the Xray. If the object has properties +which are themselves objects, and these objects are same-origin with the +content, then their value properties are visible as well. + +There are two main sorts of restrictions: + +- First, the chrome code might expect to rely on the prototype's + integrity, so the object's prototype is protected: + + - the Xray has the standard ``Object`` or ``Array`` prototype, + without any modifications that content may have done to that + prototype. The Xray always inherits from this standard prototype, + even if the underlying instance has a different prototype. + - if a script has created a property on an object instance that + shadows a property on the prototype, the shadowing property is not + visible in the Xray + +- Second, we want to prevent the chrome code from running content code, + so functions and accessor properties + of the object are not visible in the Xray. + +These rules are demonstrated in the script below, which evaluates a +script in a sandbox, then examines the object attached to the sandbox. + +.. note:: + + To test out examples like this, you can use the Scratchpad in + browser context for the code snippet, and the Browser Console + to see the expected output. + + Because code running in Scratchpad's browser context has chrome + privileges, any time you use it to run code, you need to understand + exactly what the code is doing. That includes the code samples in + this article. + +.. code:: JavaScript + + /* + The sandbox script: + * redefines Object.prototype.toSource() + * creates a Person() constructor that: + * defines a value property "firstName" using assignment + * defines a value property which shadows "constructor" + * defines a value property "address" which is a simple object + * defines a function fullName() + * using defineProperty, defines a value property on Person "lastName" + * using defineProperty, defines an accessor property on Person "middleName", + which has some unexpected accessor behavior + */ + + var sandboxScript = 'Object.prototype.toSource = function() {'+ + ' return "not what you expected?";' + + '};' + + 'function Person() {' + + ' this.constructor = "not a constructor";' + + ' this.firstName = "Joe";' + + ' this.address = {"street" : "Main Street"};' + + ' this.fullName = function() {' + + ' return this.firstName + " " + this.lastName;'+ + ' };' + + '};' + + 'var me = new Person();' + + 'Object.defineProperty(me, "lastName", {' + + ' enumerable: true,' + + ' configurable: true,' + + ' writable: true,' + + ' value: "Smith"' + + '});' + + 'Object.defineProperty(me, "middleName", {' + + ' enumerable: true,' + + ' configurable: true,' + + ' get: function() { return "wait, is this really a getter?"; }' + + '});'; + + var sandbox = Components.utils.Sandbox("https://example.org/"); + Components.utils.evalInSandbox(sandboxScript, sandbox); + + // 1) trying to access properties in the prototype that have been redefined + // (non-own properties) will show the original 'native' version + // note that functions are not included in the output + console.log("1) Property redefined in the prototype:"); + console.log(sandbox.me.toSource()); + // -> "({firstName:"Joe", address:{street:"Main Street"}, lastName:"Smith"})" + + // 2) trying to access properties on the object that shadow properties + // on the prototype will show the original 'native' version + console.log("2) Property that shadows the prototype:"); + console.log(sandbox.me.constructor); + // -> function() + + // 3) value properties defined by assignment to this are visible: + console.log("3) Value property defined by assignment to this:"); + console.log(sandbox.me.firstName); + // -> "Joe" + + // 4) value properties defined using defineProperty are visible: + console.log("4) Value property defined by defineProperty"); + console.log(sandbox.me.lastName); + // -> "Smith" + + // 5) accessor properties are not visible + console.log("5) Accessor property"); + console.log(sandbox.me.middleName); + // -> undefined + + // 6) accessing a value property of a value-property object is fine + console.log("6) Value property of a value-property object"); + console.log(sandbox.me.address.street); + // -> "Main Street" + + // 7) functions defined on the sandbox-defined object are not visible in the Xray + console.log("7) Call a function defined on the object"); + try { + console.log(sandbox.me.fullName()); + } + catch (e) { + console.error(e); + } + // -> TypeError: sandbox.me.fullName is not a function + + // now with waived Xrays + console.log("Now with waived Xrays"); + + console.log("1) Property redefined in the prototype:"); + console.log(Components.utils.waiveXrays(sandbox.me).toSource()); + // -> "not what you expected?" + + console.log("2) Property that shadows the prototype:"); + console.log(Components.utils.waiveXrays(sandbox.me).constructor); + // -> "not a constructor" + + console.log("3) Accessor property"); + console.log(Components.utils.waiveXrays(sandbox.me).middleName); + // -> "wait, is this really a getter?" + + console.log("4) Call a function defined on the object"); + console.log(Components.utils.waiveXrays(sandbox.me).fullName()); + // -> "Joe Smith" diff --git a/dom/docs/streams.md b/dom/docs/streams.md new file mode 100644 index 0000000000..51705a949a --- /dev/null +++ b/dom/docs/streams.md @@ -0,0 +1,203 @@ +# Implementing specifications using WHATWG Streams API + +[Streams API](https://streams.spec.whatwg.org/) is [a modern way to produce and consume data progressively and asynchronously](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API). Multiple specifications are starting to use it, namely [Fetch](https://fetch.spec.whatwg.org/), [File Stream](https://fs.spec.whatwg.org/), [WebTransport](https://w3c.github.io/webtransport/), and so on. This documentation will briefly explain how to implement such specifications in Gecko. + +## Calling functions on stream objects + +You can mostly follow the steps in a given spec as-is, as the implementation in Gecko is deliberately written in a way that a given spec prose can match 1:1 to a function call. Let's say the spec says: + +> [Enqueue](https://streams.spec.whatwg.org/#readablestream-enqueue) `view` into `stream`. + +The prose can be written in C++ as: + +```cpp +stream->EnqueueNative(cx, view, rv); +``` + +Note that the function name ends with `Native` to disambiguate itself from the Web IDL `enqueue` method. See the [list below](#mapping-spec-terms-to-functions) for the complete mapping between spec terms and functions. + +## Creating a stream + +The stream creation can be generally done by calling `CreateNative()`. You may need to call something else if the spec: + +* Wants a byte stream and uses the term "Set up with byte reading support". In that case you need to call `ByteNative` variant. +* Defines a new interface that inherits the base stream interfaces. In this case you need to define a subclass and call `SetUpNative()` inside its init method. + * To make the cycle collection happy, you need to pass `HoldDropJSObjectsCaller::Explicit` to the superclass constructor and call `mozilla::HoldJSObjects(this)`/`mozilla::DropJSObjects(this)` respectively in the constructor/destructor. + +Both `CreateNative()`/`SetUpNative()` functions require an argument to implement custom algorithms for callbacks, whose corresponding spec phrases could be: + +> 1. Let `readable` be a [new](https://webidl.spec.whatwg.org/#new) [`ReadableStream`](https://streams.spec.whatwg.org/#readablestream). +> 1. Let `pullAlgorithm` be the following steps: +> 1. (...) +> 1. Set up `stream` with `pullAlgorithm` set to `pullAlgorithm`. + +This can roughly translate to the following C++: + +```cpp +class MySourceAlgorithms : UnderlyingSourceAlgorithmsWrapper { + already_AddRefed<Promise> PullCallbackImpl( + JSContext* aCx, ReadableStreamController& aController, + ErrorResult& aRv) override; +}; + +already_AddRefed<ReadableStream> CreateMyReadableStream( + JSContext* aCx, nsIGlobalObject* aGlobal, ErrorResult& aRv) { + // Step 2: Let pullAlgorithm be the following steps: + auto algorithms = MakeRefPtr<MySourceAlgorithms>(); + + // Step 1: Let readable be a new ReadableStream. + // Step 3: Set up stream with pullAlgorithm set to pullAlgorithm. + RefPtr<ReadableStream> readable = ReadableStream::CreateNative( + aCx, + aGlobal, + *algorithms, + /* aHighWaterMark */ Nothing(), + /* aSizeAlgorithm */ nullptr, + aRv + ); +} +``` + +Note that the `new ReadableStream()` and "Set up" steps are done together inside `CreateNative()` for convenience. For subclasses this needs to be split again: + +```cpp +class MyReadableStream : public ReadableStream { + public: + MyReadableStream(nsIGlobalObject* aGlobal) + : ReadableStream(aGlobal, ReadableStream::HoldDropJSObjectsCaller::Explicit) { + mozilla::HoldJSObjects(this); + } + + ~MyReadableStream() { + mozilla::DropJSObjects(this); + } + + void Init(ErrorResult& aRv) { + // Step 2: Let pullAlgorithm be the following steps: + auto algorithms = MakeRefPtr<MySourceAlgorithms>(); + + // Step 3: Set up stream with pullAlgorithm set to pullAlgorithm. + // + // NOTE: + // For now there's no SetUpNative but only SetUpByteNative. + // File a bug on DOM: Streams if you need to create a subclass + // for non-byte ReadableStream. + SetUpNative(aCx, *algorithms, Nothing(), nullptr, aRv); + } +} +``` + +After creating the stream with the algorithms, the rough flow will look like this: + +```{mermaid} +sequenceDiagram + JavaScript->>ReadableStream: await reader.read() + ReadableStream->>UnderlyingSourceAlgorithmsWrapper: PullCallback() + UnderlyingSourceAlgorithmsWrapper->>(Data source): (implementation detail) + NOTE left of (Data source): (Can be file IO, network IO, etc.) + (Data source)->>UnderlyingSourceAlgorithmsWrapper: (notifies back) + UnderlyingSourceAlgorithmsWrapper->>ReadableStream: EnqueueNative() + ReadableStream->>JavaScript: Resolves reader.read() +``` + +### Implementing the callbacks + +As the flow says, the real implementation will be done inside the algorithms, in this case PullCallbackImpl(). Let's say there's a spec term: + +> 1. Let `pullAlgorithm` be the following steps: +> 1. [Enqueue](https://streams.spec.whatwg.org/#readablestream-enqueue) a JavaScript string value "Hello Fox!". + +This can translate to the following C++: + +```cpp +class MySourceAlgorithms : UnderlyingSourceAlgorithmsWrapper { + // Step 1: Let `pullAlgorithm` be the following steps: + already_AddRefed<Promise> PullCallbackImpl( + JSContext* aCx, ReadableStreamController& aController, ErrorResult& aRv) { + RefPtr<ReadableStream> stream = aController.Stream(); + + // Step 1.1: Enqueue a JavaScript string value "Hello Fox!". + JS::Rooted<JSString*> hello(aCx, JS_NewStringCopyZ(aCx, "Hello Fox!")); + stream->EnqueueNative(aCx, JS::StringValue(hello), aRv); + + // Return a promise if the task is asynchronous, or nullptr if not. + return nullptr; + + // NOTE: + // Please don't use aController directly, as it's more for JavaScript. + // The *Native() functions are safer with additional assertions and more + // automatic state management. + // Please file a bug if there's no *Native() function that fulfills your need. + // In the future this function should receive a ReadableStream instead. + + // Also note that you'll need to touch JS APIs frequently as the functions + // often expect JS::Value. + }; +}; +``` + +Note that `PullCallbackImpl` returns a promise. The function will not be called again until the promise resolves. The call sequence would be roughly look like the following with repeated read requests: + +1. `await read()` from JS +1. `PullCallbackImpl()` call, which returns a Promise +1. The second `await read()` from JS +1. (Time flies) +1. The promise resolves +1. The second `PullCallbackImpl()` call + +The same applies to write and transform callbacks in `WritableStream` and `TransformStream`, except they use `UnderlyingSinkAlgorithmsWrapper` and `TransformerAlgorithmsWrapper` respectively. + +## Exposing existing XPCOM streams as WHATWG Streams + +You may simply want to expose an existing XPCOM stream to JavaScript without any more customization. Fortunately there are some helper functions for this. You can use: + +* `InputToReadableStreamAlgorithms` to send data from nsIAsyncInputStream to ReadableStream +* `WritableStreamToOutputAlgorithms` to receive data from WritableStream to nsIAsyncOutputStream + +The usage would look like the following: + +```cpp +// For nsIAsyncInputStream: +already_AddRefed<ReadableStream> ConvertInputStreamToReadableStream( + JSContext* aCx, nsIGlobalObject* aGlobal, nsIAsyncInputStream* aInput, + ErrorResult& aRv) { + auto algorithms = MakeRefPtr<InputToReadableStreamAlgorithms>( + stream->GetParentObject(), aInput); + return do_AddRef(ReadableStream::CreateNative(aCx, aGlobal, *algorithms, + Nothing(), nullptr, aRv)); +} + +// For nsIAsyncOutputStream +already_AddRefed<ReadableStream> ConvertOutputStreamToWritableStream( + JSContext* aCx, nsIGlobalObject* aGlobal, nsIAsyncOutputStream* aInput, + ErrorResult& aRv) { + auto algorithms = MakeRefPtr<WritableStreamToOutputAlgorithms>( + stream->GetParentObject(), aInput); + return do_AddRef(WritableStream::CreateNative(aCx, aGlobal, *algorithms, + Nothing(), nullptr, aRv)); +} +``` + +## Mapping spec terms to functions + +1. [ReadableStream](https://streams.spec.whatwg.org/#other-specs-rs) + * [Set up](https://streams.spec.whatwg.org/#readablestream-set-up): [`CreateNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStream.h#132) + * [Set up with byte reading support](https://streams.spec.whatwg.org/#readablestream-set-up-with-byte-reading-support): + - [`CreateByteNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStream.h#143): You can call this when the spec uses the term with `new ReadableStream`. + - [`SetUpByteNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStream.h#150): You need to use this instead when the spec uses the term with a subclass of `ReadableStream`. Call this inside the constructor of the subclass. + * [Close](https://streams.spec.whatwg.org/#readablestream-close): [`CloseNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStream.h#160) + * [Error](https://streams.spec.whatwg.org/#readablestream-error): [`ErrorNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStream.h#163) + * [Enqueue](https://streams.spec.whatwg.org/#readablestream-enqueue): [`EnqueueNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStream.h#167) + * [Get a reader](https://streams.spec.whatwg.org/#readablestream-get-a-reader): [`GetReader()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStream.h#177) + * [Read a chunk](https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-a-chunk) on reader: [`ReadChunk()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/ReadableStreamDefaultReader.h#81) on ReadableStreamDefaultReader +2. [WritableStream](https://streams.spec.whatwg.org/#other-specs-ws) + * [Set up](https://streams.spec.whatwg.org/#writablestream-set-up): + - [`CreateNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/WritableStream.h#182): You can call this when the spec uses the term with `new WritableStream`. + - [`SetUpNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/WritableStream.h#174): You need to use this instead when the spec uses the term with a subclass of `WritableStream`. Call this inside the constructor of the subclass. + * [Error](https://streams.spec.whatwg.org/#writablestream-error): [`ErrorNative()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/WritableStream.h#192) +3. [TransformStream](https://streams.spec.whatwg.org/#other-specs-ts): For now this just uses the functions in TransfromStreamDefaultController, which will be provided as an argument of transform or flush algorithms. + * [Enqueue](https://streams.spec.whatwg.org/#transformstream-enqueue): [`Enqueue()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/TransformStreamDefaultController.h#47) on TransformStreamDefaultController + * [Terminate](https://streams.spec.whatwg.org/#transformstream-terminate): [`Terminate()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/TransformStreamDefaultController.h#51) on TransformStreamDefaultController + * [Error](https://streams.spec.whatwg.org/#transformstream-error): [`Error()`](https://searchfox.org/mozilla-central/rev/31f5847a4494b3646edabbdd7ea39cb88509afe2/dom/streams/TransformStreamDefaultController.h#49) on TransformStreamDefaultController + +The mapping is only implemented on demand and does not cover every function in the spec. Please file a bug on [DOM: Streams](https://bugzilla.mozilla.org/describecomponents.cgi?product=Core&component=DOM%3A%20Streams#DOM%3A%20Streams) component in Bugzilla if you need something that is missing here. diff --git a/dom/docs/use-counters.rst b/dom/docs/use-counters.rst new file mode 100644 index 0000000000..f17c12cd41 --- /dev/null +++ b/dom/docs/use-counters.rst @@ -0,0 +1,165 @@ +============ +Use Counters +============ + +Use counters are used to report statistics on how much a given web platform feature is used across the Web. +Supported features include: + +* WebIDL methods and attributes (getters and setters are reported separately) for pages, documents, and workers, +* CSS properties (including properties that aren't in the web platform, but we're interested in), +* Deprecated DOM operations, +* Other things like SVG filters and APIs specifically unsupported in Private Browsing Mode, + via custom use counters. + +Adding a new Use Counter +======================== +How you add a new use counter is different depending on what kind of web platform feature you're instrumenting. +The one constant is that you must run ``./mach gen-use-counter-metrics`` +after adding or removing a use counter. + +(Why this is a manual step and not part of the build is explained in +`the implementation bug 1852098 <https://bugzilla.mozilla.org/show_bug.cgi?id=1852098#c11>`_.) + +WebIDL Methods and Attributes +----------------------------- +Use counters for WebIDL Methods and Attributes are added manually by editing +:searchfox:`UseCounters.conf <dom/base/UseCounters.conf>` or, for workers, +:searchfox:`UseCountersWorker.conf <dom/base/UseCountersWorker.conf>`, and +by annotating the WebIDL Method or Attribute with the ``[UseCounter]`` +extended attribute. + +(Why you must write this in two places is because generating things from +bindings codegen and ensuring all the dependencies were correct proved to be +rather difficult) + +Then run ``./mach gen-use-counter-metrics`` and build as normal. + +CSS Properties +-------------- +Use counters for CSS properties are automatically generated for every property Gecko supports. + +To add a use counter for a CSS property that isn't supported by Gecko, +add it to :searchfox:`counted_unknown_properties.py <servo/components/style/properties/counted_unknown_properties.py>`. + +Then run ``./mach gen-use-counter-metrics`` and build as normal. + +Deprecated DOM operations +------------------------- +Use counters for deprecated DOM operations are declared in +:searchfox:`nsDeprecatedOperationList.h <dom/base/nsDeprecatedOperationList.h>`. +To add a use counter for a deprecated DOM operation, you'll add an invocation of the +``DEPRECATED_OPERATION(DeprecationReference)`` macro. +The provided parameter must have the same value of the deprecation note added to the *IDL* file. + +See `bug 1860635 <https://bugzilla.mozilla.org/show_bug.cgi?id=1860635>`_ for a sample +deprecated operation. + +Then run ``./mach gen-use-counter-metrics`` and build as normal. + +Custom use counters +------------------- +Custom use counters are for counting per-page, per-document, or per-worker +uses of web platform features that can't be handled directly through WebIDL annotation. + +For example, the use of specific SVG filters isn't a WebIDL method or attribute, +but was still an aspect of the web platform of interest. + +To add a custom use counter, define it in +:searchfox:`UseCounters.conf <dom/base/UseCounters.conf>` or, for workers, +:searchfox:`UseCountersWorker.conf <dom/base/UseCountersWorker.conf>` +by following the instructions in the file. +Broadly, you'll be writing a line like ``custom feBlend uses the feBlend SVG filter``. + +Then, by running the build as normal, an enum in ``enum class UseCounter`` +will be generated for your use counter, which you should pass to +``Document::SetUseCounter()`` when it's used. +``Document::SetUseCounter()`` is very cheap, +so do not be afraid to call it every time the feature is used. + +Take care to craft the description appropriately. +It will be appended to "Whether a document " or "Whether a shared worker ", +so write only the ending. + + +The processor scripts +===================== +The definition files are processed during the build to generate C++ headers +included by web platform components (e.g. DOM) that own the features to be tracked. + +The definition files are also processed during ``./mach gen-use-counter-metrics`` +to generate :searchfox:`use_counter_metrics.yaml <dom/base/use_counter_metrics.yaml>` +which generates the necessary Glean metrics for recording and reporting use counter data. + +gen-usecounters.py +------------------ +This script is called by the build system to generate: + +- the ``UseCounterList.h`` header for the WebIDL, out of the definition files. +- the ``UseCounterWorkerList.h`` header for the WebIDL, out of the definition files. + +usecounters.py +-------------- +Contains methods for parsing and transforming use counter definition files, +as well as the mechanism that outputs the Glean use counter metrics definitions. + +Data Review +=========== +The concept of a Use Counter data collection +(being a web platform feature which has the number of pages, documents, workers +(of various types), or other broad category of web platform API surfaces that +*use* it recorded and reported by a data collection mechanism (like Glean)) +was approved for opt-out collection in all products using Gecko and Glean in +`bug 1852098 <https://bugzilla.mozilla.org/show_bug.cgi?id=1852098>`_. + +As a result, +if you are adding new use counter data collections for WebIDL methods or attributes, +deprecated operations, or CSS properties: +you almost certainly don't need a data collection review. + +If you are adding a custom use counter, you might need a data collection review. +The criteria for whether you do or not is whether the custom use counter you're adding +can fall under +`the over-arching data collection review request <https://bugzilla.mozilla.org/show_bug.cgi?id=1852098>`_. +For example: a custom use counter for an SVG filter? Clearly a web platform feature being counted. +A custom use counter that solely increments when you visit a social media website? +Doesn't seem like it'd be covered, no. + +If unsure, please ask on +`the #data-stewards channel on Matrix <https://chat.mozilla.org/#/room/#data-stewards:mozilla.org>`_. + +The Data +======== +Use Counters are, as of Firefox 121, collected using Glean as +``counter`` metrics on the "use-counters" ping. +They are in a variety of metrics categories of ``use.counter.X`` +which you can browse on +`the Glean Dictionary <https://dictionary.telemetry.mozilla.org/apps/firefox_desktop?page=1&search=use.counter>`_. +The dictionary also contains information about how to view the data. + +Interpreting the data +--------------------- +A use counter on its own is minimally useful, as it is solely a count of how many +(pages, documents, workers of a specific type, other web platform API surfaces) +a given part of the web platform was used on. + +Knowing a feature was encountered ``0`` times across all of Firefox would be useful to know. +(If you wanted to remove something). +Knowing a feature was encountered *more than* ``0`` times would be useful. +(If you wanted to argue against removing something). + +But any other number of, say, pages using a web platform feature is only useful +in context with how many total pages were viewed. + +Thus, each use counter has in its description a name of another counter +-- a denominator -- to convert the use counter into a usage rate. + +Using pages as an example, knowing the CSS property ``overflow`` +is used on ``1504`` pages is... nice. I guess. +But if you sum up ``use.counters.top_level_content_documents_destroyed`` +to find that there were only ``1506`` pages loaded? +That's a figure we can do something with. +We can order MDN search results by popularity. +We can prioritize performance efforts in Gecko to focus on the most-encountered features. +We can view the popularity over time and see when we expect we'll be able to deprecate and remove the feature. + +This is why you'll more likely encounter use counter data expressed as usage rates. diff --git a/dom/docs/webIdlBindings/index.md b/dom/docs/webIdlBindings/index.md new file mode 100644 index 0000000000..a239179071 --- /dev/null +++ b/dom/docs/webIdlBindings/index.md @@ -0,0 +1,2444 @@ +# Web IDL bindings + +<div class="note"> +<div class="admonition-title">Note</div> + +Need to document the setup for indexed and named +setters/creators/deleters. + +</div> + +The [Web IDL](https://webidl.spec.whatwg.org/) bindings are generated +at build time based on two things: the actual Web IDL file and a +configuration file that lists some metadata about how the Web IDL should +be reflected into Gecko-internal code. + +All Web IDL files should be placed in +[`dom/webidl`](https://searchfox.org/mozilla-central/source/dom/webidl/) +and added to the list in the +[moz.build](https://searchfox.org/mozilla-central/source/dom/webidl/moz.build) +file in that directory. + +Note that if you're adding new interfaces, then the test at +`dom/tests/mochitest/general/test_interfaces.html` will most likely +fail. This is a signal that you need to get a review from a [DOM +peer](https://wiki.mozilla.org/Modules/All#Document_Object_Model). +Resist the urge to just add your interfaces to the +[moz.build](https://searchfox.org/mozilla-central/source/dom/webidl/moz.build) list +without the review; it will just annoy the DOM peers and they'll make +you get the review anyway. + +The configuration file, `dom/bindings/Bindings.conf`, is basically a +Python dict that maps interface names to information about the +interface, called a *descriptor*. There are all sorts of possible +options here that handle various edge cases, but most descriptors can be +very simple. + +All the generated code is placed in the `mozilla::dom` namespace. For +each interface, a namespace whose name is the name of the interface with +`Binding` appended is created, and all the things pertaining to that +interface's binding go in that namespace. + +There are various helper objects and utility methods in +[`dom/bindings`](https://searchfox.org/mozilla-central/source/dom/bindings) +that are also all in the `mozilla::dom` namespace and whose headers +are all exported into `mozilla/dom` (placed in +`$OBJDIR/dist/include` by the build process). + +## Adding Web IDL bindings to a class + +To add a Web IDL binding for interface `MyInterface` to a class +`mozilla::dom::MyInterface` that's supposed to implement that +interface, you need to do the following: + +1. If your interface doesn't inherit from any other interfaces, inherit + from `nsWrapperCache` and hook up the class to the cycle collector + so it will trace the wrapper cache properly. Note that you may not + need to do this if your objects can only be created, never gotten + from other objects. If you also inherit from `nsISupports`, make + sure the `nsISupports` comes before the `nsWrapperCache` in your + list of parent classes. If your interface *does* inherit from another + interface, just inherit from the C++ type that the other interface + corresponds to. + + If you do need to hook up cycle collection, it will look like this in + the common case of also inheriting from nsISupports: + + ``` cpp + // Add strong pointers your class holds here. If you do, change to using + // NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE. + NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MyClass) + NS_IMPL_CYCLE_COLLECTING_ADDREF(MyClass) + NS_IMPL_CYCLE_COLLECTING_RELEASE(MyClass) + NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MyClass) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) + NS_INTERFACE_MAP_END + ``` + +1. If your class doesn't inherit from a class that implements + `GetParentObject`, then add a function of that name that, for a + given instance of your class, returns the same object every time + (unless you write explicit code that handles your parent object + changing by reparenting JS wrappers, as nodes do). The idea is that + walking the `GetParentObject` chain will eventually get you to a + Window, so that every Web IDL object is associated with a particular + Window. + For example, `nsINode::GetParentObject` returns the node's owner + document. The return type of `GetParentObject` doesn't matter other + than it must either singly-inherit from `nsISupports` or have a + corresponding + [`ToSupports`](https://searchfox.org/mozilla-central/search?q=ToSupports&path=&case=true®exp=false) + method that can produce an `nsISupports` from it. (This allows the + return value to be implicitly converted to a + [`ParentObject`](https://searchfox.org/mozilla-central/search?q=ParentObject&path=&case=true®exp=false) + instance by the compiler via one of that class's non-explicit + constructors.) + If many instances of `MyInterface` are expected to be created + quickly, the return value of `GetParentObject` should itself inherit + from `nsWrapperCache` for optimal performance. Returning null from + `GetParentObject` is allowed in situations in which it's OK to + associate the resulting object with a random global object for + security purposes; this is not usually ok for things that are exposed + to web content. Again, if you do not need wrapper caching you don't + need to do this. The actual type returned from `GetParentObject` + must be defined in a header included from your implementation header, + so that this type's definition is visible to the binding code. + +1. Add the Web IDL for `MyInterface` in `dom/webidl` and to the list + in `dom/webidl/moz.build`. + +1. Add an entry to `dom/bindings/Bindings.conf` that sets some basic + information about the implementation of the interface. If the C++ + type is not `mozilla::dom::MyInterface`, you need to set the + `'nativeType'` to the right type. If the type is not in the header + file one gets by replacing '::' with '/' and appending '`.h`', then + add a corresponding `'headerFile'` annotation (or + [`HeaderFile`](#headerfile-path-to-headerfile-h) annotation to the .webidl file). If + you don't have to set any annotations, then you don't need to add an + entry either and the code generator will simply assume the defaults + here. Note that using a `'headerFile'` annotation is generally not + recommended. If you do use it, you will need to make sure your + header includes all the headers needed for your [`Func`](#func-funcname) + annotations. + +1. Add external interface entries to `Bindings.conf` for whatever + non-Web IDL interfaces your new interface has as arguments or return + values. + +1. Implement a `WrapObject` override on `mozilla::dom::MyInterface` + that just calls through to + `mozilla::dom::MyInterface_Binding::Wrap`. Note that if your C++ + type is implementing multiple distinct Web IDL interfaces, you need + to choose which `mozilla::dom::MyInterface_Binding::Wrap` to call + here. See `AudioContext::WrapObject`, for example. + +1. Expose whatever methods the interface needs on + `mozilla::dom::MyInterface`. These can be inline, virtual, have any + calling convention, and so forth, as long as they have the right + argument types and return types. You can see an example of what the + function declarations should look like by running + `mach webidl-example MyInterface`. This will produce two files in + `dom/bindings` in your objdir: `MyInterface-example.h` and + `MyInterface-example.cpp`, which show a basic implementation of the + interface using a class that inherits from `nsISupports` and has a + wrapper cache. + +See this [sample patch that migrates window.performance.\* to Web IDL +bindings](https://hg.mozilla.org/mozilla-central/rev/dd08c10193c6). + +<div class="note"><div class="admonition-title">Note</div> + +If your object can only be reflected into JS by creating it, not by +retrieving it from somewhere, you can skip steps 1 and 2 above and +instead add `'wrapperCache': False` to your descriptor. You will +need to flag the functions that return your object as +[`[NewObject]`](https://webidl.spec.whatwg.org/#NewObject) in +the Web IDL. If your object is not refcounted then the return value of +functions that return it should return a UniquePtr. + +</div> + +## C++ reflections of Web IDL constructs + +### C++ reflections of Web IDL operations (methods) + +A Web IDL operation is turned into a method call on the underlying C++ +object. The return type and argument types are determined [as described +below](#c-reflections-of-webidl-constructs). In addition to those, all [methods that are +allowed to throw](#throws-getterthrows-setterthrows) will get an `ErrorResult&` argument +appended to their argument list. Non-static methods that use certain +Web IDL types like `any` or `object` will get a `JSContext*` +argument prepended to the argument list. Static methods will be passed a +[`const GlobalObject&`](#globalobject) for the relevant global and +can get a `JSContext*` by calling `Context()` on it. + +The name of the C++ method is simply the name of the Web IDL operation +with the first letter converted to uppercase. + +Web IDL overloads are turned into C++ overloads: they simply call C++ +methods with the same name and different signatures. + +For example, this Web IDL: + +``` webidl +interface MyInterface +{ + undefined doSomething(long number); + double doSomething(MyInterface? otherInstance); + + [Throws] + MyInterface doSomethingElse(optional long maybeNumber); + [Throws] + undefined doSomethingElse(MyInterface otherInstance); + + undefined doTheOther(any something); + + undefined doYetAnotherThing(optional boolean actuallyDoIt = false); + + static undefined staticOperation(any arg); +}; +``` + +will require these method declarations: + +``` cpp +class MyClass +{ + void DoSomething(int32_t a number); + double DoSomething(MyClass* aOtherInstance); + + already_AddRefed<MyInterface> DoSomethingElse(Optional<int32_t> aMaybeNumber, + ErrorResult& rv); + void DoSomethingElse(MyClass& aOtherInstance, ErrorResult& rv); + + void DoTheOther(JSContext* cx, JS::Handle<JS::Value> aSomething); + + void DoYetAnotherThing(bool aActuallyDoIt); + + static void StaticOperation(const GlobalObject& aGlobal, JS::Handle<JS::Value> aSomething); +} +``` + +### C++ reflections of Web IDL attributes + +A Web IDL attribute is turned into a pair of method calls for the getter +and setter on the underlying C++ object. A readonly attribute only has a +getter and no setter. + +The getter's name is the name of the attribute with the first letter +converted to uppercase. This has `Get` prepended to it if any of these +conditions hold: + +1. The type of the attribute is nullable. +1. The getter can throw. +1. The return value of the attribute is returned via an out parameter in + the C++. + +The method signature for the getter looks just like an operation with no +arguments and the attribute's type as the return type. + +The setter's name is `Set` followed by the name of the attribute with +the first letter converted to uppercase. The method signature looks just +like an operation with an undefined return value and a single argument +whose type is the attribute's type. + +### C++ reflections of Web IDL constructors + +A Web IDL constructor is turned into a static class method named +`Constructor`. The arguments of this method will be the arguments of +the Web IDL constructor, with a +[`const GlobalObject&`](#globalobject) for the relevant global +prepended. For the non-worker case, the global is typically the inner +window for the DOM Window the constructor function is attached to. If a +`JSContext*` is also needed due to some of the argument types, it will +come after the global. The return value of the constructor for +`MyInterface` is exactly the same as that of a method returning an +instance of `MyInterface`. Constructors are always allowed to throw. + +For example, this IDL: + +``` webidl +interface MyInterface { + constructor(); + constructor(unsigned long someNumber); +}; +``` + +will require the following declarations in `MyClass`: + +``` cpp +class MyClass { + // Various nsISupports stuff or whatnot + static + already_AddRefed<MyClass> Constructor(const GlobalObject& aGlobal, + ErrorResult& rv); + static + already_AddRefed<MyClass> Constructor(const GlobalObject& aGlobal, + uint32_t aSomeNumber, + ErrorResult& rv); +}; +``` + +### C++ reflections of Web IDL types + +The exact C++ representation for Web IDL types can depend on the precise +way that they're being used (e.g., return values, arguments, and +sequence or dictionary members might all have different +representations). + +Unless stated otherwise, a type only has one representation. Also, +unless stated otherwise, nullable types are represented by wrapping +[`Nullable<>`](#nullable-t) around the base type. + +In all cases, optional arguments which do not have a default value are +represented by wrapping [`const Optional<>&`](#optional-t) around the +representation of the argument type. If the argument type is a C++ +reference, it will also become a [`NonNull<>`](#nonnull-t) around the +actual type of the object in the process. Optional arguments which do +have a default value are just represented by the argument type itself, +set to the default value if the argument was not in fact passed in. + +Variadic Web IDL arguments are treated as a +[`const Sequence<>&`](#sequence-t) around the actual argument type. + +Here's a table, see the specific sections below for more details and +explanations. + +| Web IDL Type | Argument Type | Return Type | Dictionary/Member Type | +| -------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| any | `JS::Handle<JS::Value>` | `JS::MutableHandle<JS::Value>` | `JS::Value` | +| boolean | `bool` | `bool` | `bool` | +| byte | `int8_t` | `int8_t` | `int8_t` | +| ByteString | `const nsACString&` | `nsCString&` _(outparam)_<br>`nsACString&` _(outparam)_ | `nsCString` | +| Date | | | `mozilla::dom::Date` | +| DOMString | `const nsAString&` | [`mozilla::dom::DOMString&`](#domstring-c) _(outparam)_<br>`nsAString&` _(outparam)_<br>`nsString&` _(outparam)_ | `nsString` | +| UTF8String | `const nsACString&` _(outparam)_ | `nsACString&` | `nsCString` | +| double | `double` | `double` | `double` | +| float | `float` | `float` | `float` | +| interface:<br>non-nullable | `Foo&` | `already_addRefed<Foo>` | [`OwningNonNull<Foo>`](#owningnonnull-t) | +| interface:<br>nullable | `Foo*` | `already_addRefed<Foo>`<br>`Foo*` | `RefPtr<Foo>` | +| long | `int32_t` | `int32_t` | `int32_t` | +| long long | `int64_t` | `int64_t` | `int64_t` | +| object | `JS::Handle<JSObject*>` | `JS::MutableHandle<JSObject*>` | `JSObject*` | +| octet | `uint8_t` | `uint8_t` | `uint8_t` | +| sequence | [`const Sequence<T>&`](#sequence-t) | `nsTArray<T>&` _(outparam)_ | | +| short | `int16_t` | `int16_t` | `int16_t` | +| unrestricted double | `double` | `double` | `double` | +| unrestricted float | `float` | `float` | `float` | +| unsigned long | `uint32_t` | `uint32_t` | `uint32_t` | +| unsigned long long | `uint64_t` | `uint64_t` | `uint64_t` | +| unsigned short | `uint16_t` | `uint16_t` | `uint16_t` | +| USVString | `const nsAString&` | [`mozilla::dom::DOMString&`](#domstring-c) _(outparam)_<br>`nsAString&` _(outparam)_<br>`nsString&` _(outparam)_ | `nsString` | + +#### `any` + +`any` is represented in three different ways, depending on use: + +- `any` arguments become `JS::Handle<JS::Value>`. They will be in + the compartment of the passed-in JSContext. +- `any` return values become a `JS::MutableHandle<JS::Value>` out + param appended to the argument list. This comes after all IDL + arguments, but before the `ErrorResult&`, if any, for the method. + The return value is allowed to be in any compartment; bindings will + wrap it into the context compartment as needed. +- `any` dictionary members and sequence elements become + `JS::Value`. The dictionary members and sequence elements are + guaranteed to be marked by whomever puts the sequence or dictionary + on the stack, using `SequenceRooter` and `DictionaryRooter`. + +Methods using `any` always get a `JSContext*` argument. + +For example, this Web IDL: + +``` webidl +interface Test { + attribute any myAttr; + any myMethod(any arg1, sequence<any> arg2, optional any arg3); +}; +``` + +will correspond to these C++ function declarations: + +``` cpp +void MyAttr(JSContext* cx, JS::MutableHandle<JS::Value> retval); +void SetMyAttr(JSContext* cx, JS::Handle<JS::Value> value); +void MyMethod(JSContext* cx, JS::Handle<JS::Value> arg1, + const Sequence<JS::Value>& arg2, + const Optional<JS::Handle<JS::Value>>& arg3, + JS::MutableHandle<JS::Value> retval); +``` + +#### `boolean` + +The `boolean` Web IDL type is represented as a C++ `bool`. + +For example, this Web IDL: + +``` webidl +interface Test { + attribute boolean myAttr; + boolean myMethod(optional boolean arg); +}; +``` + +will correspond to these C++ function declarations: + +``` cpp +bool MyAttr(); +void SetMyAttr(bool value); +bool MyMethod(const Optional<bool>& arg); +``` + +#### Integer types + +Integer Web IDL types are mapped to the corresponding C99 stdint types. + +For example, this Web IDL: + +``` webidl +interface Test { + attribute short myAttr; + long long myMethod(unsigned long? arg); +}; +``` + +will correspond to these C++ function declarations: + +``` cpp +int16_t MyAttr(); +void SetMyAttr(int16_t value); +int64_t MyMethod(const Nullable<uint32_t>& arg); +``` + +#### Floating point types + +Floating point Web IDL types are mapped to the C++ type of the same +name. So `float` and `unrestricted float` become a C++ `float`, +while `double` and `unrestricted double` become a C++ `double`. + +For example, this Web IDL: + +``` webidl +interface Test { + float myAttr; + double myMethod(unrestricted double? arg); +}; +``` + +will correspond to these C++ function declarations: + +``` cpp +float MyAttr(); +void SetMyAttr(float value); +double MyMethod(const Nullable<double>& arg); +``` + +#### `DOMString` + +Strings are reflected in three different ways, depending on use: + +- String arguments become `const nsAString&`. +- String return values become a + [`mozilla::dom::DOMString&`](#domstring-c) out param + appended to the argument list. This comes after all IDL arguments, + but before the `ErrorResult&`, if any, for the method. Note that + this allows callees to declare their methods as taking an + `nsAString&` or `nsString&` if desired. +- Strings in sequences, dictionaries, owning unions, and variadic + arguments become `nsString`. + +Nullable strings are represented by the same types as non-nullable ones, +but the string will return true for `DOMStringIsNull()`. Returning +null as a string value can be done using `SetDOMStringToNull` on the +out param if it's an `nsAString` or calling `SetNull()` on a +`DOMString`. + +For example, this Web IDL: + +``` webidl +interface Test { + DOMString myAttr; + [Throws] + DOMString myMethod(sequence<DOMString> arg1, DOMString? arg2, optional DOMString arg3); +}; +``` + +will correspond to these C++ function declarations: + +``` cpp +void GetMyAttr(nsString& retval); +void SetMyAttr(const nsAString& value); +void MyMethod(const Sequence<nsString>& arg1, const nsAString& arg2, + const Optional<nsAString>& arg3, nsString& retval, ErrorResult& rv); +``` + +#### `USVString` + +`USVString` is reflected just like `DOMString`. + +#### `UTF8String` + +`UTF8String` is a string with guaranteed-valid UTF-8 contents. It is +not a standard in the Web IDL spec, but its observables are the same as +those of `USVString`. + +It is a good fit for when the specification allows a `USVString`, but +you want to process the string as UTF-8 rather than UTF-16. + +It is reflected in three different ways, depending on use: + +- Arguments become `const nsACString&`. +- Return values become an `nsACString&` out param appended to the + argument list. This comes after all IDL arguments, but before the + `ErrorResult&`, if any, for the method. +- In sequences, dictionaries owning unions, and variadic arguments it + becomes `nsCString`. + +Nullable `UTF8String`s are represented by the same types as +non-nullable ones, but the string will return true for `IsVoid()`. +Returning null as a string value can be done using `SetIsVoid()` on +the out param. + +#### `ByteString` + +`ByteString` is reflected in three different ways, depending on use: + +- `ByteString` arguments become `const nsACString&`. +- `ByteString` return values become an `nsCString&` out param + appended to the argument list. This comes after all IDL arguments, + but before the `ErrorResult&`, if any, for the method. +- `ByteString` in sequences, dictionaries, owning unions, and + variadic arguments becomes `nsCString`. + +Nullable `ByteString` are represented by the same types as +non-nullable ones, but the string will return true for `IsVoid()`. +Returning null as a string value can be done using `SetIsVoid()` on +the out param. + +#### `object` + +`object` is represented in three different ways, depending on use: + +- `object` arguments become `JS::Handle<JSObject*>`. They will be + in the compartment of the passed-in JSContext. +- `object` return values become a `JS::MutableHandle<JSObject*>` + out param appended to the argument list. This comes after all IDL + arguments, but before the `ErrorResult&`, if any, for the method. + The return value is allowed to be in any compartment; bindings will + wrap it into the context compartment as needed. +- `object` dictionary members and sequence elements become + `JSObject*`. The dictionary members and sequence elements are + guaranteed to be marked by whoever puts the sequence or dictionary on + the stack, using `SequenceRooter` and `DictionaryRooter`. + +Methods using `object` always get a `JSContext*` argument. + +For example, this Web IDL: + +``` webidl +interface Test { + object myAttr; + object myMethod(object arg1, object? arg2, sequence<object> arg3, optional object arg4, + optional object? arg5); +}; +``` + +will correspond to these C++ function declarations: + +``` cpp +void GetMyAttr(JSContext* cx, JS::MutableHandle<JSObject*> retval); +void SetMyAttr(JSContext* cx, JS::Handle<JSObject*> value); +void MyMethod(JSContext* cx, JS::Handle<JSObject*> arg1, JS::Handle<JSObject*> arg2, + const Sequence<JSObject*>& arg3, + const Optional<JS::Handle<JSObject*>>& arg4, + const Optional<JS::Handle<JSObject*>>& arg5, + JS::MutableHandle<JSObject*> retval); +``` + +#### Interface types + +There are four kinds of interface types in the Web IDL bindings. Callback +interfaces are used to represent script objects that browser code can +call into. External interfaces are used to represent objects that have +not been converted to the Web IDL bindings yet. Web IDL interfaces are +used to represent Web IDL binding objects. "SpiderMonkey" interfaces are +used to represent objects that are implemented natively by the +JavaScript engine (e.g., typed arrays). + +##### Callback interfaces + +Callback interfaces are represented in C++ as objects inheriting from +[`mozilla::dom::CallbackInterface`](#callbackinterface), whose +name, in the `mozilla::dom` namespace, matches the name of the +callback interface in the Web IDL. The exact representation depends on +how the type is being used. + +- Nullable arguments become `Foo*`. +- Non-nullable arguments become `Foo&`. +- Return values become `already_AddRefed<Foo>` or `Foo*` as + desired. The pointer form is preferred because it results in faster + code, but it should only be used if the return value was not addrefed + (and so it can only be used if the return value is kept alive by the + callee until at least the binding method has returned). +- Web IDL callback interfaces in sequences, dictionaries, owning unions, + and variadic arguments are represented by `RefPtr<Foo>` if nullable + and [`OwningNonNull<Foo>`](#owningnonnull-t) otherwise. + +If the interface is a single-operation interface, the object exposes two +methods that both invoke the same underlying JS callable. The first of +these methods allows the caller to pass in a `this` object, while the +second defaults to `undefined` as the `this` value. In either case, +the `this` value is only used if the callback interface is implemented +by a JS callable. If it's implemented by an object with a property whose +name matches the operation, the object itself is always used as +`this`. + +If the interface is not a single-operation interface, it just exposes a +single method for every IDL method/getter/setter. + +The signatures of the methods correspond to the signatures for throwing +IDL methods/getters/setters with an additional trailing +`mozilla::dom::CallbackObject::ExceptionHandling aExceptionHandling` +argument, defaulting to `eReportExceptions`. +If `aReportExceptions` is set to `eReportExceptions`, the methods +will report JS exceptions before returning. If `aReportExceptions` is +set to `eRethrowExceptions`, JS exceptions will be stashed in the +`ErrorResult` and will be reported when the stack unwinds to wherever +the `ErrorResult` was set up. + +For example, this Web IDL: + +``` webidl +callback interface MyCallback { + attribute long someNumber; + short someMethod(DOMString someString); +}; +callback interface MyOtherCallback { + // single-operation interface + short doSomething(Node someNode); +}; +interface MyInterface { + attribute MyCallback foo; + attribute MyCallback? bar; +}; +``` + +will lead to these C++ class declarations in the `mozilla::dom` +namespace: + +``` cpp +class MyCallback : public CallbackInterface +{ + int32_t GetSomeNumber(ErrorResult& rv, ExceptionHandling aExceptionHandling = eReportExceptions); + void SetSomeNumber(int32_t arg, ErrorResult& rv, + ExceptionHandling aExceptionHandling = eReportExceptions); + int16_t SomeMethod(const nsAString& someString, ErrorResult& rv, + ExceptionHandling aExceptionHandling = eReportExceptions); +}; + +class MyOtherCallback : public CallbackInterface +{ +public: + int16_t + DoSomething(nsINode& someNode, ErrorResult& rv, + ExceptionHandling aExceptionHandling = eReportExceptions); + + template<typename T> + int16_t + DoSomething(const T& thisObj, nsINode& someNode, ErrorResult& rv, + ExceptionHandling aExceptionHandling = eReportExceptions); +}; +``` + +and these C++ function declarations on the implementation of +`MyInterface`: + +``` cpp +already_AddRefed<MyCallback> GetFoo(); +void SetFoo(MyCallback&); +already_AddRefed<MyCallback> GetBar(); +void SetBar(MyCallback*); +``` + +A consumer of MyCallback would be able to use it like this: + +``` cpp +void +SomeClass::DoSomethingWithCallback(MyCallback& aCallback) +{ + ErrorResult rv; + int32_t number = aCallback.GetSomeNumber(rv); + if (rv.Failed()) { + // The error has already been reported to the JS console; you can handle + // things however you want here. + return; + } + + // For some reason we want to catch and rethrow exceptions from SetSomeNumber, say. + aCallback.SetSomeNumber(2*number, rv, eRethrowExceptions); + if (rv.Failed()) { + // The exception is now stored on rv. This code MUST report + // it usefully; otherwise it will assert. + } +} +``` + +##### External interfaces + +External interfaces are represented in C++ as objects that XPConnect +knows how to unwrap to. This can mean XPCOM interfaces (whether declared +in XPIDL or not) or it can mean some type that there's a castable native +unwrapping function for. The C++ type to be used should be the +`nativeType` listed for the external interface in the +[`Bindings.conf`](#bindings-conf-details) file. The exact representation +depends on how the type is being used. + +- Arguments become `nsIFoo*`. +- Return values can be `already_AddRefed<nsIFoo>` or `nsIFoo*` as + desired. The pointer form is preferred because it results in faster + code, but it should only be used if the return value was not addrefed + (and so it can only be used if the return value is kept alive by the + callee until at least the binding method has returned). +- External interfaces in sequences, dictionaries, owning unions, and + variadic arguments are represented by `RefPtr<nsIFoo>`. + +##### Web IDL interfaces + +Web IDL interfaces are represented in C++ as C++ classes. The class +involved must either be refcounted or must be explicitly annotated in +`Bindings.conf` as being directly owned by the JS object. If the class +inherits from `nsISupports`, then the canonical `nsISupports` must +be on the primary inheritance chain of the object. If the interface has +a parent interface, the C++ class corresponding to the parent must be on +the primary inheritance chain of the object. This guarantees that a +`void*` can be stored in the JSObject which can then be +`reinterpret_cast` to any of the classes that correspond to interfaces +the object implements. The C++ type to be used should be the +`nativeType` listed for the interface in the +[`Bindings.conf`](#bindings-conf-details) file, or +`mozilla::dom::InterfaceName` if none is listed. The exact +representation depends on how the type is being used. + +- Nullable arguments become `Foo*`. +- Non-nullable arguments become `Foo&`. +- Return values become `already_AddRefed<Foo>` or `Foo*` as + desired. The pointer form is preferred because it results in faster + code, but it should only be used if the return value was not addrefed + (and so it can only be used if the return value is kept alive by the + callee until at least the binding method has returned). +- Web IDL interfaces in sequences, dictionaries, owning unions, and + variadic arguments are represented by `RefPtr<Foo>` if nullable and + [`OwningNonNull<Foo>`](#owningnonnull-t) otherwise. + +For example, this Web IDL: + +``` webidl +interface MyInterface { + attribute MyInterface myAttr; + undefined passNullable(MyInterface? arg); + MyInterface? doSomething(sequence<MyInterface> arg); + MyInterface doTheOther(sequence<MyInterface?> arg); + readonly attribute MyInterface? nullableAttr; + readonly attribute MyInterface someOtherAttr; + readonly attribute MyInterface someYetOtherAttr; +}; +``` + +Would correspond to these C++ function declarations: + +``` cpp +already_AddRefed<MyClass> MyAttr(); +void SetMyAttr(MyClass& value); +void PassNullable(MyClass* arg); +already_AddRefed<MyClass> doSomething(const Sequence<OwningNonNull<MyClass>>& arg); +already_AddRefed<MyClass> doTheOther(const Sequence<RefPtr<MyClass>>& arg); +already_Addrefed<MyClass> GetNullableAttr(); +MyClass* SomeOtherAttr(); +MyClass* SomeYetOtherAttr(); // Don't have to return already_AddRefed! +``` + +##### "SpiderMonkey" interfaces + +Typed array, array buffer, and array buffer view arguments are +represented by the objects in [`TypedArray.h`](#typed-arrays-arraybuffers-array-buffer-views). For +example, this Web IDL: + +``` webidl +interface Test { + undefined passTypedArrayBuffer(ArrayBuffer arg); + undefined passTypedArray(ArrayBufferView arg); + undefined passInt16Array(Int16Array? arg); +} +``` + +will correspond to these C++ function declarations: + +``` cpp +void PassTypedArrayBuffer(const ArrayBuffer& arg); +void PassTypedArray(const ArrayBufferView& arg); +void PassInt16Array(const Nullable<Int16Array>& arg); +``` + +Typed array return values become a `JS::MutableHandle<JSObject*>` out +param appended to the argument list. This comes after all IDL arguments, +but before the `ErrorResult&`, if any, for the method. The return +value is allowed to be in any compartment; bindings will wrap it into +the context compartment as needed. + +Typed arrays store a `JSObject*` and hence need to be rooted +properly. On-stack typed arrays can be declared as +`RootedTypedArray<TypedArrayType>` (e.g. +`RootedTypedArray<Int16Array>`). Typed arrays on the heap need to be +traced. + +#### Dictionary types + +A dictionary argument is represented by a const reference to a struct +whose name is the dictionary name in the `mozilla::dom` namespace. +The struct has one member for each of the dictionary's members with the +same name except the first letter uppercased and prefixed with "m". The +members that are required or have default values have types as described +under the corresponding Web IDL type in this document. The members that +are not required and don't have default values have those types wrapped +in [`Optional<>`](#optional-t). + +Dictionary return values are represented by an out parameter whose type +is a non-const reference to the struct described above, with all the +members that have default values preinitialized to those default values. + +Note that optional dictionary arguments are always forced to have a +default value of an empty dictionary by the IDL parser and code +generator, so dictionary arguments are never wrapped in `Optional<>`. + +If necessary, dictionaries can be directly initialized from a +`JS::Value` in C++ code by invoking their `Init()` method. Consumers +doing this should declare their dictionary as +`RootedDictionary<DictionaryName>`. When this is done, passing in a +null `JSContext*` is allowed if the passed-in `JS::Value` is +`JS::NullValue()`. Likewise, a dictionary struct can be converted to a +`JS::Value` in C++ by calling `ToJSValue` with the dictionary as the +second argument. If `Init()` or `ToJSValue()` returns false, they +will generally set a pending exception on the JSContext; reporting those +is the responsibility of the caller. + +For example, this Web IDL: + +``` webidl +dictionary Dict { + long foo = 5; + DOMString bar; +}; + +interface Test { + undefined initSomething(optional Dict arg = {}); +}; +``` + +will correspond to this C++ function declaration: + +``` cpp +void InitSomething(const Dict& arg); +``` + +and the `Dict` struct will look like this: + +``` cpp +struct Dict { + bool Init(JSContext* aCx, JS::Handle<JS::Value> aVal, const char* aSourceDescription = "value"); + + Optional<nsString> mBar; + int32_t mFoo; +} +``` + +Note that the dictionary members are sorted in the struct in +alphabetical order. + +##### API for working with dictionaries + +There are a few useful methods found on dictionaries and dictionary +members that you can use to quickly determine useful things. + +- **member.WasPassed()** - as the name suggests, was a particular + member passed? + (e.g., `if (arg.foo.WasPassed() { /* do nice things!*/ }`) +- **dictionary.IsAnyMemberPresent()** - great for checking if you need + to do anything. + (e.g., `if (!arg.IsAnyMemberPresent()) return; // nothing to do`) +- **member.Value()** - getting the actual data/value of a member that + was passed. + (e.g., `mBar.Assign(args.mBar.value())`) + +Example implementation using all of the above: + +``` cpp +void +MyInterface::InitSomething(const Dict& aArg){ + if (!aArg.IsAnyMemberPresent()) { + return; // nothing to do! + } + if (aArg.mBar.WasPassed() && !mBar.Equals(aArg.mBar.value())) { + mBar.Assign(aArg.mBar.Value()); + } +} +``` + +#### Enumeration types + +Web IDL enumeration types are represented as C++ enum classes. The values +of the C++ enum are named by taking the strings in the Web IDL +enumeration, replacing all non-alphanumerics with underscores, and +uppercasing the first letter, with a special case for the empty string, +which becomes the value `_empty`. + +For a Web IDL enum named `MyEnum`, the C++ enum is named `MyEnum` and +placed in the `mozilla::dom` namespace, while the values are placed in +the `mozilla::dom::MyEnum` namespace. There is also a +`mozilla::dom::MyEnumValues::strings` which is an array of +`mozilla::dom::EnumEntry` structs that gives access to the string +representations of the values. + +The type of the enum class is automatically selected to be the smallest +unsigned integer type that can hold all the values. In practice, this +is always uint8_t, because Web IDL enums tend to not have more than 255 +values. + +For example, this Web IDL: + +``` webidl +enum MyEnum { + "something", + "something-else", + "", + "another" +}; +``` + +would lead to this C++ enum declaration: + +``` cpp +enum class MyEnum : uint8_t { + Something, + Something_else, + _empty, + Another +}; + +namespace MyEnumValues { +extern const EnumEntry strings[10]; +} // namespace MyEnumValues +``` + +#### Callback function types + +Callback functions are represented as an object, inheriting from +[`mozilla::dom::CallbackFunction`](#callbackfunction), whose name, +in the `mozilla::dom` namespace, matches the name of the callback +function in the Web IDL. If the type is nullable, a pointer is passed in; +otherwise a reference is passed in. + +The object exposes two `Call` methods, which both invoke the +underlying JS callable. The first `Call` method has the same signature +as a throwing method declared just like the callback function, with an +additional trailing `mozilla::dom::CallbackObject::ExceptionHandling aExceptionHandling` +argument, defaulting to `eReportExceptions`, +and calling it will invoke the callable with `undefined` as the +`this` value. The second `Call` method allows passing in an explicit +`this` value as the first argument. This second call method is a +template on the type of the first argument, so the `this` value can be +passed in in whatever form is most convenient, as long as it's either a +type that can be wrapped by XPConnect or a Web IDL interface type. + +If `aReportExceptions` is set to `eReportExceptions`, the `Call` +methods will report JS exceptions before returning. If +`aReportExceptions` is set to `eRethrowExceptions`, JS exceptions +will be stashed in the `ErrorResult` and will be reported when the +stack unwinds to wherever the `ErrorResult` was set up. + +For example, this Web IDL: + +``` webidl +callback MyCallback = long (MyInterface arg1, boolean arg2); +interface MyInterface { + attribute MyCallback foo; + attribute MyCallback? bar; +}; +``` + +will lead to this C++ class declaration, in the `mozilla::dom` +namespace: + +``` cpp +class MyCallback : public CallbackFunction +{ +public: + int32_t + Call(MyInterface& arg1, bool arg2, ErrorResult& rv, + ExceptionHandling aExceptionHandling = eReportExceptions); + + template<typename T> + int32_t + Call(const T& thisObj, MyInterface& arg1, bool arg2, ErrorResult& rv, + ExceptionHandling aExceptionHandling = eReportExceptions); +}; +``` + +and these C++ function declarations in the `MyInterface` class: + +``` cpp +already_AddRefed<MyCallback> GetFoo(); +void SetFoo(MyCallback&); +already_AddRefed<MyCallback> GetBar(); +void SetBar(MyCallback*); +``` + +A consumer of MyCallback would be able to use it like this: + +``` cpp +void +SomeClass::DoSomethingWithCallback(MyCallback& aCallback, MyInterface& aInterfaceInstance) +{ + ErrorResult rv; + int32_t number = aCallback.Call(aInterfaceInstance, false, rv); + if (rv.Failed()) { + // The error has already been reported to the JS console; you can handle + // things however you want here. + return; + } + + // Now for some reason we want to catch and rethrow exceptions from the callback, + // and use "this" as the this value for the call to JS. + number = aCallback.Call(*this, true, rv, eRethrowExceptions); + if (rv.Failed()) { + // The exception is now stored on rv. This code MUST report + // it usefully; otherwise it will assert. + } +} +``` + +#### Sequences + +Sequence arguments are represented by +[`const Sequence<T>&`](#sequence-t), where `T` depends on the type +of elements in the Web IDL sequence. + +Sequence return values are represented by an `nsTArray<T>` out param +appended to the argument list, where `T` is the return type for the +elements of the Web IDL sequence. This comes after all IDL arguments, but +before the `ErrorResult&`, if any, for the method. + +#### Arrays + +IDL array objects are not supported yet. The spec on these is likely to +change drastically anyway. + +#### Union types + +Union types are reflected as a struct in the `mozilla::dom` namespace. +There are two kinds of union structs: one kind does not keep its members +alive (is "non-owning"), and the other does (is "owning"). Const +references to non-owning unions are used for plain arguments. Owning +unions are used in dictionaries, sequences, and for variadic arguments. +Union return values become a non-const owning union out param. The name +of the struct is the concatenation of the names of the types in the +union, with "Or" inserted between them, and for an owning struct +"Owning" prepended. So for example, this IDL: + +``` webidl +undefined passUnion((object or long) arg); +(object or long) receiveUnion(); +undefined passSequenceOfUnions(sequence<(object or long)> arg); +undefined passOtherUnion((HTMLDivElement or ArrayBuffer or EventInit) arg); +``` + +would correspond to these C++ function declarations: + +``` cpp +void PassUnion(const ObjectOrLong& aArg); +void ReceiveUnion(OwningObjectObjectOrLong& aArg); +void PassSequenceOfUnions(const Sequence<OwningObjectOrLong>& aArg); +void PassOtherUnion(const HTMLDivElementOrArrayBufferOrEventInit& aArg); +``` + +Union structs expose accessors to test whether they're of a given type +and to get hold of the data of that type. They also expose setters that +set the union as being of a particular type and return a reference to +the union's internal storage where that type could be stored. The one +exception is the `object` type, which uses a somewhat different form +of setter where the `JSObject*` is passed in directly. For example, +`ObjectOrLong` would have the following methods: + +``` cpp +bool IsObject() const; +JSObject* GetAsObject() const; +void SetToObject(JSContext*, JSObject*); +bool IsLong() const; +int32_t GetAsLong() const; +int32_t& SetAsLong() +``` + +Owning unions used on the stack should be declared as a +`RootedUnion<UnionType>`, for example, +`RootedUnion<OwningObjectOrLong>`. + +#### `Date` + +Web IDL `Date` types are represented by a `mozilla::dom::Date` +struct. + +### C++ reflections of Web IDL declarations + +Web IDL declarations (maplike/setlike/iterable) are turned into a set of +properties and functions on the interface they are declared on. Each has +a different set of helper functions it comes with. In addition, for +iterable, there are requirements for C++ function implementation by the +interface developer. + +#### Maplike + +Example Interface: + +``` webidl +interface StringToLongMap { + maplike<DOMString, long>; +}; +``` + +The bindings for this interface will generate the storage structure for +the map, as well as helper functions for accessing that structure from +C++. The generated C++ API will look as follows: + +``` cpp +namespace StringToLongMapBinding { +namespace MaplikeHelpers { +void Clear(mozilla::dom::StringToLongMap* self, ErrorResult& aRv); +bool Delete(mozilla::dom::StringToLongMap* self, const nsAString& aKey, ErrorResult& aRv); +bool Has(mozilla::dom::StringToLongMap* self, const nsAString& aKey, ErrorResult& aRv); +void Set(mozilla::dom::StringToLongMap* self, const nsAString& aKey, int32_t aValue, ErrorResult& aRv); +} // namespace MaplikeHelpers +} // namespace StringToLongMapBindings +``` + +#### Setlike + +Example Interface: + +``` webidl +interface StringSet { + setlike<DOMString>; +}; +``` + +The bindings for this interface will generate the storage structure for +the set, as well as helper functions for accessing that structure from +c++. The generated C++ API will look as follows: + +``` cpp +namespace StringSetBinding { +namespace SetlikeHelpers { +void Clear(mozilla::dom::StringSet* self, ErrorResult& aRv); +bool Delete(mozilla::dom::StringSet* self, const nsAString& aKey, ErrorResult& aRv); +bool Has(mozilla::dom::StringSet* self, const nsAString& aKey, ErrorResult& aRv); +void Add(mozilla::dom::StringSet* self, const nsAString& aKey, ErrorResult& aRv); +} // namespace SetlikeHelpers +} +``` + +#### Iterable + +Unlike maplike and setlike, iterable does not have any C++ helpers, as +the structure backing the iterable data for the interface is left up to +the developer. With that in mind, the generated iterable bindings expect +the wrapper object to provide certain methods for the interface to +access. + +Iterable interfaces have different requirements, based on if they are +single or pair value iterators. + +Example Interface for a single value iterator: + +``` webidl +interface LongIterable { + iterable<long>; + getter long(unsigned long index); + readonly attribute unsigned long length; +}; +``` + +For single value iterator interfaces, we treat the interface as an +[indexed getter](#indexed-getters), as required by the spec. See the +[indexed getter implementation section](#indexed-getters) for more +information on building this kind of structure. + +Example Interface for a pair value iterator: + +``` webidl +interface StringAndLongIterable { + iterable<DOMString, long>; +}; +``` + +The bindings for this pair value iterator interface require the +following methods be implemented in the C++ object: + +``` cpp +class StringAndLongIterable { +public: + // Returns the number of items in the iterable storage + size_t GetIterableLength(); + // Returns key of pair at aIndex in iterable storage + nsAString& GetKeyAtIndex(uint32_t aIndex); + // Returns value of pair at aIndex in iterable storage + uint32_t& GetValueAtIndex(uint32_t aIndex); +} +``` + +### Stringifiers + +Named stringifiers operations in Web IDL will just invoke the +corresponding C++ method. + +Anonymous stringifiers in Web IDL will invoke the C++ method called +`Stringify`. So, for example, given this IDL: + +``` webidl +interface FirstInterface { + stringifier; +}; + +interface SecondInterface { + stringifier DOMString getStringRepresentation(); +}; +``` + +the corresponding C++ would be: + +``` cpp +class FirstInterface { +public: + void Stringify(nsAString& aResult); +}; + +class SecondInterface { +public: + void GetStringRepresentation(nsAString& aResult); +}; +``` + +### Legacy Callers + +Only anonymous legacy callers are supported, and will invoke the C++ +method called `LegacyCall`. This will be passed the JS "this" value as +the first argument, then the arguments to the actual operation. A +`JSContext` will be passed if any of the operation arguments need it. +So for example, given this IDL: + +``` webidl +interface InterfaceWithCall { + legacycaller long (float arg); +}; +``` + +the corresponding C++ would be: + +``` cpp +class InterfaceWithCall { +public: + int32_t LegacyCall(JS::Handle<JS::Value> aThisVal, float aArgument); +}; +``` + +### Named getters + +If the interface has a named getter, the binding will expect several +methods on the C++ implementation: + +- A `NamedGetter` method. This takes a property name and returns + whatever type the named getter is declared to return. It also has a + boolean out param for whether a property with that name should exist + at all. +- A `NameIsEnumerable` method. This takes a property name and + returns a boolean that indicates whether the property is enumerable. +- A `GetSupportedNames` method. This takes an unsigned integer which + corresponds to the flags passed to the `iterate` proxy trap and + returns a list of property names. For implementations of this method, + the important flags is `JSITER_HIDDEN`. If that flag is set, the + call needs to return all supported property names. If it's not set, + the call needs to return only the enumerable ones. + +The `NameIsEnumerable` and `GetSupportedNames` methods need to agree +on which names are and are not enumerable. The `NamedGetter` and +`GetSupportedNames` methods need to agree on which names are +supported. + +So for example, given this IDL: + +``` webidl +interface InterfaceWithNamedGetter { + getter long(DOMString arg); +}; +``` + +the corresponding C++ would be: + +``` cpp +class InterfaceWithNamedGetter +{ +public: + int32_t NamedGetter(const nsAString& aName, bool& aFound); + bool NameIsEnumerable(const nsAString& aName); + undefined GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames); +}; +``` + +### Indexed getters + +If the interface has a indexed getter, the binding will expect the +following methods on the C++ implementation: + +- A `IndexedGetter` method. This takes an integer index value and + returns whatever type the indexed getter is declared to return. It + also has a boolean out param for whether a property with that index + should exist at all. The implementation must set this out param + correctly. The return value is guaranteed to be ignored if the out + param is set to false. + +So for example, given this IDL: + +``` webidl +interface InterfaceWithIndexedGetter { + getter long(unsigned long index); + readonly attribute unsigned long length; +}; +``` + +the corresponding C++ would be: + +``` cpp +class InterfaceWithIndexedGetter +{ +public: + uint32_t Length() const; + int32_t IndexedGetter(uint32_t aIndex, bool& aFound) const; +}; +``` + +## Throwing exceptions from Web IDL methods, getters, and setters + +Web IDL methods, getters, and setters that are [explicitly marked as +allowed to throw](#throws-getterthrows-setterthrows) have an `ErrorResult&` argument as their +last argument. To throw an exception, simply call `Throw()` on the +`ErrorResult&` and return from your C++ back into the binding code. + +In cases when the specification calls for throwing a `TypeError`, you +should use `ErrorResult::ThrowTypeError()` instead of calling +`Throw()`. + +## Custom extended attributes + +Our Web IDL parser and code generator recognize several extended +attributes that are not present in the Web IDL spec. + +### `[Alias=propName]` + +This extended attribute can be specified on a method and indicates that +another property with the specified name will also appear on the +interface prototype object and will have the same Function object value +as the property for the method. For example: + +``` webidl +interface MyInterface { + [Alias=performSomething] undefined doSomething(); +}; +``` + +`MyInterface.prototype.performSomething` will have the same Function +object value as `MyInterface.prototype.doSomething`. + +Multiple `[Alias]` extended attribute can be used on the one method. +`[Alias]` cannot be used on a static method, nor on methods on a +global interface (such as `Window`). + +Aside from regular property names, the name of an alias can be +[Symbol.iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator). +This is specified by writing `[Alias="@@iterator"]`. + +### `[BindingAlias=propName]` + +This extended attribute can be specified on an attribute and indicates +that another property with the specified name will also appear on the +interface prototype object and will call the same underlying C++ +implementation for the getter and setter. This is more efficient than +using the same `BinaryName` for both attributes, because it shares the +binding glue code between them. The properties still have separate +getter/setter functions in JavaScript, so from the point of view of web +consumers it's as if you actually had two separate attribute +declarations on your interface. For example: + +``` webidl +interface MyInterface { + [BindingAlias=otherAttr] readonly attribute boolean attr; +}; +``` + +`MyInterface.prototype.otherAttr` and `MyInterface.prototype.attr` +will both exist, have separate getter/setter functions, but call the +same binding glue code and implementation function on the objects +implementing `MyInterface`. + +Multiple `[BindingAlias]` extended attributes can be used on a single +attribute. + +### `[BindingTemplate=(name, value)]` + +This extended attribute can be specified on an attribute, and causes the getter +and setter for this attribute to forward to a common generated implementation, +shared with all other attributes that have a `[BindingTemplate]` with the same +value for the `name` argument. The `TemplatedAttributes` dictionary in +Bindings.conf needs to contain a definition for the template with the name +`name`. The `value` will be passed as an argument when calling the common +generated implementation. + +This is aimed at very specialized use cases where an interface has a +large number of attributes that all have the same type, and for which we have a +native implementation that's common to all these attributes, and typically uses +some id based on the attribute's name in the implementation. All the attributes +that use the same template need to mostly have the same extended attributes, +except form a small number that are allowed to differ (`[BindingTemplate]`, +`[BindingAlias]`, `[Pure]`, [`Pref`] and [`Func`], and the annotations for +whether the getter and setter throws exceptions). + +### `[ChromeOnly]` + +This extended attribute can be specified on any method, attribute, or +constant on an interface or on an interface as a whole. It can also be +specified on dictionary members. + +Interface members flagged as `[ChromeOnly]` are only exposed in chrome +Windows (and in particular, are not exposed to webpages). From the point +of view of web content, it's as if the interface member were not there +at all. These members *are* exposed to chrome script working with a +content object via Xrays. + +If specified on an interface as a whole, this functions like +[`[Func]`](#func-funcname) except that the binding code will automatically +check whether the caller script has the system principal (is chrome or a +worker started from a chrome page) instead of calling into the C++ +implementation to determine whether to expose the interface object on +the global. This means that accessing a content global via Xrays will +show `[ChromeOnly]` interface objects on it. + +If specified on a dictionary member, then the dictionary member will +only appear to exist in system-privileged code. + +This extended attribute can be specified together with `[Func]`, and +`[Pref]`. If more than one of these is specified, all conditions will +need to test true for the interface or interface member to be exposed. + +### `[Pref=prefname]` + +This extended attribute can be specified on any method, attribute, or +constant on an interface or on an interface as a whole. It can also be +specified on dictionary members. It takes a value, which must be the +name of a boolean preference exposed from `StaticPrefs`. The +`StaticPrefs` function that will be called is calculated from the +value of the extended attribute, with dots replaced by underscores +(`StaticPrefs::my_pref_name()` in the example below). + +If specified on an interface member, the interface member involved is +only exposed if the preference is set to `true`. An example of how +this can be used: + +``` webidl +interface MyInterface { + attribute long alwaysHere; + [Pref="my.pref.name"] attribute long onlyHereIfEnabled; +}; +``` + +If specified on an interface as a whole, this functions like +[`[Func]`](#func-funcname) except that the binding will check the value of +the preference directly without calling into the C++ implementation of +the interface at all. This is useful when the enable check is simple and +it's desirable to keep the prefname with the Web IDL declaration. + +If specified on a dictionary member, the web-observable behavior when +the pref is set to false will be as if the dictionary did not have a +member of that name defined. That means that on the JS side no +observable get of the property will happen. On the C++ side, the +behavior would be as if the passed-in object did not have a property +with the relevant name: the dictionary member would either be +`!Passed()` or have the default value if there is a default value. + +> An example of how this can be used: + +``` webidl +[Pref="my.pref.name"] +interface MyConditionalInterface { +}; +``` + +This extended attribute can be specified together with `[ChromeOnly]`, +and `[Func]`. If more than one of these is specified, all conditions +will need to test true for the interface or interface member to be +exposed. + +### `[Func="funcname"]` + +This extended attribute can be specified on any method, attribute, or +constant on an interface or on an interface as a whole. It can also be +specified on dictionary members. It takes a value, which must be the +name of a static function. + +If specified on an interface member, the interface member involved is +only exposed if the specified function returns `true`. An example of +how this can be used: + +``` webidl +interface MyInterface { + attribute long alwaysHere; + [Func="MyClass::StuffEnabled"] attribute long onlyHereIfEnabled; +}; +``` + +The function is invoked with two arguments: the `JSContext` that the +operation is happening on and the `JSObject` for the global of the +object that the property will be defined on if the function returns +true. In particular, in the Xray case the `JSContext` is in the caller +compartment (typically chrome) but the `JSObject` is in the target +compartment (typically content). This allows the method implementation +to select which compartment it cares about in its checks. + +The above IDL would also require the following C++: + +``` cpp +class MyClass { + static bool StuffEnabled(JSContext* cx, JSObject* obj); +}; +``` + +If specified on an interface as a whole, then lookups for the interface +object for this interface on a DOM Window will only find it if the +specified function returns true. For objects that can only be created +via a constructor, this allows disabling the functionality altogether +and making it look like the feature is not implemented at all. + +If specified on a dictionary member, the web-observable behavior when +the function returns false will be as if the dictionary did not have a +member of that name defined. That means that on the JS side no +observable get of the property will happen. On the C++ side, the +behavior would be as if the passed-in object did not have a property +with the relevant name: the dictionary member would either be +`!Passed()` or have the default value if there is a default value. + +An example of how `[Func]` can be used: + +``` webidl +[Func="MyClass::MyConditionalInterfaceEnabled"] +interface MyConditionalInterface { +}; +``` + +In this case, the C++ function is passed a `JS::Handle<JSObject*>`. So +the C++ in this case would look like this: + +``` cpp +class MyClass { + static bool MyConditionalInterfaceEnabled(JSContext* cx, JS::Handle<JSObject*> obj); +}; +``` + +Just like in the interface member case, the `JSContext` is in the +caller compartment but the `JSObject` is the actual object the +property would be defined on. In the Xray case that means obj is in the +target compartment (typically content) and `cx` is typically chrome. + +This extended attribute can be specified together with `[ChromeOnly]`, +and `[Pref]`. If more than one of these is specified, all conditions +will need to test true for the interface or interface member to be +exposed. + +Binding code will include the headers necessary for a `[Func]`, unless +the interface is using a non-default header file. If a non-default +header file is used, that header file needs to do any header inclusions +necessary for `[Func]` annotations. + +### `[Throws]`, `[GetterThrows]`, `[SetterThrows]` + +Used to flag methods or attributes as allowing the C++ callee to throw. +This causes the binding generator, and in many cases the JIT, to +generate extra code to handle possible exceptions. Possibly-throwing +methods and attributes get an `ErrorResult&` argument. + +`[Throws]` applies to both methods and attributes; for attributes it +means both the getter and the setter can throw. `[GetterThrows]` +applies only to attributes. `[SetterThrows]` applies only to +non-readonly attributes. + +For interfaces flagged with `[JSImplementation]`, all methods and +properties are assumed to be able to throw and do not need to be flagged +as throwing. + +### `[DependsOn]` + +Used for a method or attribute to indicate what the return value depends +on. Possible values are: + +* `Everything` + + This value can't actually be specified explicitly; this is the + default value you get when `[DependsOn]` is not specified. This + means we don't know anything about the return value's dependencies + and hence can't rearrange other code that might change values around + the method or attribute. + +* `DOMState` + + The return value depends on the state of the "DOM", by which we mean + all objects specified via Web IDL. The return value is guaranteed to + not depend on the state of the JS heap or other JS engine data + structures, and is guaranteed to not change unless some function with + [`[Affects=Everything]`](#affects) is executed. + +* `DeviceState` + + The return value depends on the state of the device we're running on + (e.g., the system clock). The return value is guaranteed to not be + affected by any code running inside Gecko itself, but we might get a + new value every time the method or getter is called even if no Gecko + code ran between the calls. + +* `Nothing` + + The return value is a constant that never changes. This value cannot + be used on non-readonly attributes, since having a non-readonly + attribute whose value never changes doesn't make sense. + +Values other than `Everything`, when used in combination with +[`[Affects=Nothing]`](#affects), can used by the JIT to +perform loop-hoisting and common subexpression elimination on the return +values of IDL attributes and methods. + +### `[Affects]` + +Used for a method or attribute getter to indicate what sorts of state +can be affected when the function is called. Attribute setters are, for +now, assumed to affect everything. Possible values are: + +* `Everything` + + This value can't actually be specified explicitly; this is the + default value you get when `[Affects]` is not specified. This means + that calling the method or getter might change any mutable state in + the DOM or JS heap. + +* `Nothing` + + Calling the method or getter will have no side-effects on either the + DOM or the JS heap. + +Methods and attribute getters with `[Affects=Nothing]` are allowed to +throw exceptions, as long as they do so deterministically. In the case +of methods, whether an exception is thrown is allowed to depend on the +arguments, as long as calling the method with the same arguments will +always either throw or not throw. + +The `Nothing` value, when used with `[DependsOn]` values other than +`Everything`, can used by the JIT to perform loop-hoisting and common +subexpression elimination on the return values of IDL attributes and +methods, as well as code motion past DOM methods that might depend on +system state but have no side effects. + +### `[Pure]` + +This is an alias for `[Affects=Nothing, DependsOn=DOMState]`. +Attributes/methods flagged in this way promise that they will keep +returning the same value as long as nothing that has +`[Affects=Everything]` executes. + +### `[Constant]` + +This is an alias for `[Affects=Nothing, DependsOn=Nothing]`. Used to +flag readonly attributes or methods that could have been annotated with +`[Pure]` and also always return the same value. This should only be +used when it's absolutely guaranteed that the return value of the +attribute getter will always be the same from the JS engine's point of +view. + +The spec's `[SameObject]` extended attribute is an alias for +`[Constant]`, but can only be applied to things returning objects, +whereas `[Constant]` can be used for any type of return value. + +### `[NeedResolve]` + +Used to flag interfaces which have a custom resolve hook. This +annotation will cause the `DoResolve` method to be called on the +underlying C++ class when a property lookup happens on the object. The +signature of this method is: +`bool DoResolve(JSContext*, JS::Handle<JSObject*>, JS::Handle<jsid>, JS::MutableHandle<JS::Value>)`. +Here the passed-in object is the object the property lookup is happening +on (which may be an Xray for the actual DOM object) and the jsid is the +property name. The value that the property should have is returned in +the `MutableHandle<Value>`, with `UndefinedValue()` indicating that +the property does not exist. + +If this extended attribute is used, then the underlying C++ class must +also implement a method called `GetOwnPropertyNames` with the +signature +`void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames, ErrorResult& aRv)`. +This method will be called by the JS engine's enumerate hook and must +provide a superset of all the property names that `DoResolve` might +resolve. Providing names that `DoResolve` won't actually resolve is +OK. + +### `[HeaderFile="path/to/headerfile.h"]` + +Indicates where the implementation can be found. Similar to the +headerFile annotation in Bindings.conf. Just like headerFile in +Bindings.conf, should be avoided. + +### `[JSImplementation="@mozilla.org/some-contractid;1"]` + +Used on an interface to provide the contractid of the [JavaScript +component implementing the +interface](#implementing-webidl-using-javascript). + +### `[StoreInSlot]` + +Used to flag attributes that can be gotten very quickly from the JS +object by the JIT. Such attributes will have their getter called +immediately when the JS wrapper for the DOM object is created, and the +returned value will be stored directly on the JS object. Later gets of +the attribute will not call the C++ getter and instead use the cached +value. If the value returned by the attribute needs to change, the C++ +code should call the `ClearCachedFooValue` method in the namespace of +the relevant binding, where `foo` is the name of the attribute. This +will immediately call the C++ getter and cache the value it returns, so +it needs a `JSContext` to work on. This extended attribute can only be +used on attributes whose getters are [`[Pure]`](#pure) or +[`[Constant]`](#constant) and which are not +[`[Throws]`](#throws-getterthrows-setterthrows) or [`[GetterThrows]`](#throws-getterthrows-setterthrows). + +So for example, given this IDL: + +``` webidl +interface MyInterface { + [Pure, StoreInSlot] attribute long myAttribute; +}; +``` + +the C++ implementation of MyInterface would clear the cached value by +calling +`mozilla::dom::MyInterface_Binding::ClearCachedMyAttributeValue(cx, this)`. +This function will return false on error and the caller is responsible +for handling any JSAPI exception that is set by the failure. + +If the attribute is not readonly, setting it will automatically clear +the cached value and reget it again before the setter returns. + +### `[Cached]` + +Used to flag attributes that, when their getter is called, will cache +the returned value on the JS object. This can be used to implement +attributes whose value is a sequence or dictionary (which would +otherwise end up returning a new object each time and hence not be +allowed in Web IDL). + +Unlike [`[StoreInSlot]`](#storeinslot) this does *not* cause the +getter to be eagerly called at JS wrapper creation time; the caching is +lazy. `[Cached]` attributes must be [`[Pure]`](#pure) or +[`[Constant]`](#constant), because otherwise not calling the C++ +getter would be observable, but are allowed to have throwing getters. +Their cached value can be cleared by calling the `ClearCachedFooValue` +method in the namespace of the relevant binding, where `foo` is the +name of the attribute. Unlike `[StoreInSlot]` attributes, doing so +will not immediately invoke the getter, so it does not need a +`JSContext`. + +So for example, given this IDL: + +``` webidl +interface MyInterface { + [Pure, StoreInSlot] attribute long myAttribute; +}; +``` + +the C++ implementation of MyInterface would clear the cached value by +calling +`mozilla::dom::MyInterface_Binding::ClearCachedMyAttributeValue(this)`. +JS-implemented Web IDL can clear the cached value by calling +`this.__DOM_IMPL__._clearCachedMyAttributeValue()`. + +If the attribute is not readonly, setting it will automatically clear +the cached value. + +### `[Frozen]` + +Used to flag attributes that, when their getter is called, will call +[`Object.freeze`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) +on the return value before returning it. This extended attribute is only +allowed on attributes that return sequences, dictionaries and +`MozMap`, and corresponds to returning a frozen `Array` (for the +sequence case) or `Object` (for the other two cases). + +### `[BinaryName]` + +`[BinaryName]` can be specified on method or attribute to change the +C++ function name that will be used for the method or attribute. It +takes a single string argument, which is the name you wish the method or +attribute had instead of the one it actually has. + +For example, given this IDL: + +``` webidl +interface InterfaceWithRenamedThings { + [BinaryName="renamedMethod"] + undefined someMethod(); + [BinaryName="renamedAttribute"] + attribute long someAttribute; +}; +``` + +the corresponding C++ would be: + +``` cpp +class InterfaceWithRenamedThings +{ +public: + void RenamedMethod(); + int32_t RenamedAttribute(); + void SetRenamedAttribute(int32_t); +}; +``` + +### `[Deprecated="tag"]` + +When deprecating an interface or method, the `[Deprecated]` annotation +causes the Web IDL compiler to insert code that generates deprecation +warnings. This annotation can be added to interface methods or +interfaces. Adding this to an interface causes a warning to be issued +the first time the object is constructed, or any static method on the +object is invoked. + +The complete list of valid deprecation tags is maintained in +[nsDeprecatedOperationList.h](https://searchfox.org/mozilla-central/source/dom/base/nsDeprecatedOperationList.h). +Each new tag requires that a localized string be defined, containing the +deprecation message to display. + +### `[CrossOriginReadable]` + +Used to flag an attribute that, when read, will not have the same-origin +constraint tested: it can be read from a context with a different +origin. + +### `[CrossOriginWrite]` + +Used to flag an attribute that, when written, will not have the +same-origin constraint tested: it can be written from a context with a +different origin. + +### `[CrossOriginCallable]` + +Used to flag a method that, when called, will not have the same-origin +constraint tested: it can be called from a context with a different +origin. + +### `[SecureContext]` + +We implement the [standard extended +attribute](https://webidl.spec.whatwg.org/#SecureContext) with a few +details specific to Gecko: + +- System principals are considered secure. +- An extension poking at non-secured DOM objects will see APIs marked + with `[SecureContext]`. +- XPConnect sandboxes don't see `[SecureContext]` APIs, except if + they're created with `isSecureContext: true`. + +### `[NeedsSubjectPrincipal]`, `[GetterNeedsSubjectPrincipal]`, `[SetterNeedsSubjectPrincipal]` + +Used to flag a method or an attribute that needs to know the subject +principal. This principal will be passed as argument. The argument +will be a `nsIPrincipal&` because a subject principal is always +available. + +`[NeedsSubjectPrincipal]` applies to both methods and attributes; for +attributes it means both the getter and the setter need a subject +principal. `[GetterNeedsSubjectPrincipal]` applies only to attributes. +`[SetterNeedsSubjectPrincipal]` applies only to non-readonly +attributes. + +These attributes may also be constrained to non-system principals using +`[{Getter,Setter,}NeedsSubjectPrincipal=NonSystem]`. This changes the argument +type to `nsIPrincipal*`, and passes `nullptr` when called with a system +principal. + +### `[NeedsCallerType]` + +Used to flag a method or an attribute that needs to know the caller +type, in the `mozilla::dom::CallerType` sense. This can be safely +used for APIs exposed in workers; there it will indicate whether the +worker involved is a `ChromeWorker` or not. At the moment the only +possible caller types are `System` (representing system-principal +callers) and `NonSystem`. + +## Helper objects + +The C++ side of the bindings uses a number of helper objects. + +### `Nullable<T>` + +`Nullable<>` is a struct declared in +[`Nullable.h`](https://searchfox.org/mozilla-central/source/dom/bindings/Nullable.h) +and exported to `mozilla/dom/Nullable.h` that is used to represent +nullable values of types that don't have a natural way to represent +null. + +`Nullable<T>` has an `IsNull()` getter that returns whether null is +represented and a `Value()` getter that returns a `const T&` and can +be used to get the value when it's not null. + +`Nullable<T>` has a `SetNull()` setter that sets it as representing +null and two setters that can be used to set it to a value: +`void SetValue(T)` (for setting it to a given value) and +`T& SetValue()` for directly modifying the underlying `T&`. + +### `Optional<T>` + +`Optional<>` is a struct declared in +[`BindingDeclarations.h`](https://searchfox.org/mozilla-central/source/dom/bindings/BindingDeclarations.h) +and exported to `mozilla/dom/BindingDeclarations.h` that is used to +represent optional arguments and dictionary members, but only those that +have no default value. + +`Optional<T>` has a `WasPassed()` getter that returns true if a +value is available. In that case, the `Value()` getter can be used to +get a `const T&` for the value. + +### `NonNull<T>` + +`NonNull<T>` is a struct declared in +[`BindingUtils.h`](https://searchfox.org/mozilla-central/source/dom/bindings/BindingUtils.h) +and exported to `mozilla/dom/BindingUtils.h` that is used to represent +non-null C++ objects. It has a conversion operator that produces `T&`. + +### `OwningNonNull<T>` + +`OwningNonNull<T>` is a struct declared in +[`OwningNonNull.h`](https://searchfox.org/mozilla-central/source/xpcom/base/OwningNonNull.h) +and exported to `mozilla/OwningNonNull.h` that is used to represent +non-null C++ objects and holds a strong reference to them. It has a +conversion operator that produces `T&`. + +### Typed arrays, arraybuffers, array buffer views + +`TypedArray.h` is exported to `mozilla/dom/TypedArray.h` and exposes +structs that correspond to the various typed array types, as well as +`ArrayBuffer` and `ArrayBufferView`, all in the `mozilla::dom` +namespace. Each struct has a `Data()` method that returns a pointer to +the relevant type (`uint8_t` for `ArrayBuffer` and +`ArrayBufferView`) and a `Length()` method that returns the length +in units of `*Data()`. So for example, `Int32Array` has a `Data()` +returning `int32_t*` and a `Length()` that returns the number of +32-bit ints in the array. + +### `Sequence<T>` + +`Sequence<>` is a type declared in +[`BindingDeclarations.h`](https://searchfox.org/mozilla-central/source/dom/bindings/BindingDeclarations.h) +and exported to `mozilla/dom/BindingDeclarations.h` that is used to +represent sequence arguments. It's some kind of typed array, but which +exact kind is opaque to consumers. This allows the binding code to +change the exact definition (e.g., to use auto arrays of different sizes +and so forth) without having to update all the callees. + +### `CallbackFunction` + +`CallbackFunction` is a type declared in +[CallbackFunction.h](https://searchfox.org/mozilla-central/source/dom/bindings/CallbackFunction.h) +and exported to `mozilla/dom/CallbackFunction.h` that is used as a +common base class for all the generated callback function +representations. This class inherits from `nsISupports`, and consumers +must make sure to cycle-collect it, since it keeps JS objects alive. + +### `CallbackInterface` + +`CallbackInterface` is a type declared in +[CallbackInterface.h](https://searchfox.org/mozilla-central/source/dom/bindings/CallbackInterface.h) +and exported to `mozilla/dom/CallbackInterface.h` that is used as a +common base class for all the generated callback interface +representations. This class inherits from `nsISupports`, and consumers +must make sure to cycle-collect it, since it keeps JS objects alive. + +### `DOMString` + +`DOMString` is a class declared in +[BindingDeclarations.h](https://searchfox.org/mozilla-central/source/dom/bindings/BindingDeclarations.h) +and exported to `mozilla/dom/BindingDeclarations.h` that is used for +Web IDL `DOMString` return values. It has a conversion operator to +`nsString&` so that it can be passed to methods that take that type or +`nsAString&`, but callees that care about performance, have an +`nsStringBuffer` available, and promise to hold on to the +`nsStringBuffer` at least until the binding code comes off the stack +can also take a `DOMString` directly for their string return value and +call its `SetStringBuffer` method with the `nsStringBuffer` and its +length. This allows the binding code to avoid extra reference-counting +of the string buffer in many cases, and allows it to take a faster +codepath even if it does end up having to addref the `nsStringBuffer`. + +### `GlobalObject` + +`GlobalObject` is a class declared in +[BindingDeclarations.h](https://searchfox.org/mozilla-central/source/dom/bindings/BindingDeclarations.h) +and exported to `mozilla/dom/BindingDeclarations.h` that is used to +represent the global object for static attributes and operations +(including constructors). It has a `Get()` method that returns the +`JSObject*` for the global and a `GetAsSupports()` method that +returns an `nsISupports*` for the global on the main thread, if such +is available. It also has a `Context()` method that returns the +`JSContext*` the call is happening on. A caveat: the compartment of +the `JSContext` may not match the compartment of the global! + +### `Date` + +`Date` is a class declared in +[BindingDeclarations.h](https://searchfox.org/mozilla-central/source/dom/bindings/BindingDeclarations.h) +and exported to `mozilla/dom/BindingDeclarations.h` that is used to +represent Web IDL Dates. It has a `TimeStamp()` method returning a +double which represents a number of milliseconds since the epoch, as +well as `SetTimeStamp()` methods that can be used to initialize it +with a double timestamp or a JS `Date` object. It also has a +`ToDateObject()` method that can be used to create a new JS `Date`. + +### `ErrorResult` + +`ErrorResult` is a class declared in +[ErrorResult.h](https://searchfox.org/mozilla-central/source/dom/bindings/ErrorResult.h) +and exported to `mozilla/ErrorResult.h` that is used to represent +exceptions in Web IDL bindings. This has the following methods: + +- `Throw`: allows throwing an `nsresult`. The `nsresult` must be + a failure code. +- `ThrowTypeError`: allows throwing a `TypeError` with the given + error message. The list of allowed `TypeError`s and corresponding + messages is in + [`dom/bindings/Errors.msg`](https://searchfox.org/mozilla-central/source/dom/bindings/Errors.msg). +- `ThrowJSException`: allows throwing a preexisting JS exception + value. However, the `MightThrowJSException()` method must be called + before any such exceptions are thrown (even if no exception is + thrown). +- `Failed`: checks whether an exception has been thrown on this + `ErrorResult`. +- `ErrorCode`: returns a failure `nsresult` representing (perhaps + incompletely) the state of this `ErrorResult`. +- `operator=`: takes an `nsresult` and acts like `Throw` if the + result is an error code, and like a no-op otherwise (unless an + exception has already been thrown, in which case it asserts). This + should only be used for legacy code that has nsresult everywhere; we + would like to get rid of this operator at some point. + +## Events + +Simple `Event` interfaces can be automatically generated by adding the +interface file to GENERATED_EVENTS_WEBIDL_FILES in the +appropriate dom/webidl/moz.build file. You can also take a simple +generated C++ file pair and use it to build a more complex event (i.e., +one that has methods). + +### Event handler attributes + +A lot of interfaces define event handler attributes, like: + +``` webidl +attribute EventHandler onthingchange; +``` + +If you need to implement an event handler attribute for an interface, in +the definition (header file), you use the handy +"IMPL_EVENT_HANDLER" macro: + +``` cpp +IMPL_EVENT_HANDLER(onthingchange); +``` + +The "onthingchange" needs to be added to the StaticAtoms.py file: + +``` py +Atom("onthingchange", "onthingchange") +``` + +The actual implementation (.cpp) for firing the event would then look +something like: + +``` cpp +nsresult +MyInterface::DispatchThingChangeEvent() +{ + NS_NAMED_LITERAL_STRING(type, "thingchange"); + EventInit init; + init.mBubbles = false; + init.mCancelable = false; + RefPtr<Event> event = Event::Constructor(this, type, init); + event->SetTrusted(true); + ErrorResult rv; + DispatchEvent(*event, rv); + return rv.StealNSResult(); // Assuming the caller cares about the return code. +} +``` + +## `Bindings.conf` details + +Write me. In particular, need to describe at least use of `concrete`, +`prefable`, and `addExternalInterface`. + +### How to get a JSContext passed to a given method + +In some rare cases you may need a `JSContext*` argument to be passed +to a C++ method that wouldn't otherwise get such an argument. To see how +to achieve this, search for `implicitJSContext` in +[dom/bindings/Bindings.conf](#bindings-conf-details). + +## Implementing Web IDL using Javascript + +<div class="warning"><div class="admonition-title">Warning</div> + +Implementing Web IDL using Javascript is deprecated. New interfaces +should always be implemented in C++! + +</div> + +It is possible to implement Web IDL interfaces in JavaScript within Gecko +-- however, **this is limited to interfaces that are not exposed in Web +Workers**. When the binding occurs, two objects are created: + +- *Content-exposed object:* what gets exposed to the web page. +- *Implementation object:* running as a chrome-privileged script. This + allows the implementation object to have various APIs that the + content-exposed object does not. + +Because there are two types of objects, you have to be careful about +which object you are creating. + +### Creating JS-implemented Web IDL objects + +To create a JS-implemented Web IDL object, one must create both the +chrome-side implementation object and the content-side page-exposed +object. There are three ways to do this. + +#### Using the Web IDL constructor + +If the interface has a constructor, a content-side object can be created +by getting that constructor from the relevant content window and +invoking it. For example: + +``` js +var contentObject = new contentWin.RTCPeerConnection(); +``` + +The returned object will be an Xray wrapper for the content-side object. +Creating the object this way will automatically create the chrome-side +object using its contractID. + +This method is limited to the constructor signatures exposed to +webpages. Any additional configuration of the object needs to be done +methods on the interface. + +Creating many objects this way can be slow due to the createInstance +overhead involved. + +#### Using a `_create` method + +A content-side object can be created for a given chrome-side object by +invoking the static `_create` method on the interface. This method +takes two arguments: the content window in which to create the object +and the chrome-side object to use. For example: + +``` js +var contentObject = RTCPeerConnection._create(contentWin, new +MyPeerConnectionImpl()); +``` + +However, if you are in a JS component, you may only be able to get to +the correct interface object via some window object. In this case, the +code would look more like: + +``` js +var contentObject = contentWin.RTCPeerConnection._create(contentWin, +new MyPeerConnectionImpl()); +``` + +Creating the object this way will not invoke its `__init` method or +`init` method. + +#### By returning a chrome-side object from a JS-implemented Web IDL method + +If a JS-implemented Web IDL method is declared as returning a +JS-implemented interface, then a non-Web IDL object returned from that +method will be treated as the chrome-side part of a JS-implemented +WebIdL object and the content-side part will be automatically created. + +Creating the object this way will not invoke its `__init` method or +`init` method. + +### Implementing a Web IDL object in JavaScript + +To implement a Web IDL interface in JavaScript, first add a Web IDL file, +in the same way as you would for a C++-implemented interface. To support +implementation in JS, you must add an extended attribute +`JSImplementation="CONTRACT_ID_STRING"` on your interface, where +CONTRACT_ID_STRING is the XPCOM component contract ID of the JS +implementation -- note ";1" is just a Mozilla convention for versioning +APIs. Here's an example: + +``` webidl +[JSImplementation="@mozilla.org/my-number;1"] +interface MyNumber { + constructor(optional long firstNumber); + attribute long value; + readonly attribute long otherValue; + undefined doNothing(); +}; +``` + +Next, create an XPCOM component that implements this interface. Use +the same contract ID as you specified in the Web IDL file. The class +ID doesn't matter, except that it should be a newly generated one. For +`QueryInterface`, you only need to implement `nsISupports`, not +anything corresponding to the Web IDL interface. The name you use for +the XPCOM component should be distinct from the name of the interface, +to avoid confusing error messages. + +Web IDL attributes are implemented as properties on the JS object or its +prototype chain, whereas Web IDL methods are implemented as methods on +the object or prototype. Note that any other instances of the interface +that you are passed in as arguments are the full web-facing version of +the object, and not the JS implementation, so you currently cannot +access any private data. + +The Web IDL constructor invocation will first create your object. If the +XPCOM component implements `nsIDOMGlobalPropertyInitializer`, then +the object's `init` method will be invoked with a single argument: +the content window the constructor came from. This allows the JS +implementation to know which content window it's associated with. +The `init` method should not return anything. After this, the +content-side object will be created. Then,if there are any constructor +arguments, the object's `__init` method will be invoked, with the +constructor arguments as its arguments. + +### Static Members + +Static attributes and methods are not supported on JS-implemented Web IDL +(see [bug +863952](https://bugzilla.mozilla.org/show_bug.cgi?id=863952)). +However, with the changes in [bug +1172785](https://bugzilla.mozilla.org/show_bug.cgi?id=1172785) you +can route static methods to a C++ implementation on another object using +a `StaticClassOverride` annotation. This annotation includes the +full, namespace-qualified name of the class that contains an +implementation of the named method. The include for that class must be +found in a directory based on its name. + +``` webidl +[JSImplementation="@mozilla.org/dom/foo;1"] +interface Foo { + [StaticClassOverride="mozilla::dom::OtherClass"] + static Promise<undefined> doSomething(); +}; +``` + +Rather than calling into a method on the JS implementation; calling +`Foo.doSomething()` will result in calling +`mozilla::dom::OtherClass::DoSomething()`. + +### Checking for Permissions or Preferences + +With JS-implemented Web IDL, the `init` method should only return +undefined. If any other value, such as `null`, is returned, the +bindings code will assert or crash. In other words, it acts like it has +an "undefined" return type. Preference or permission checking should be +implemented by adding an extended attribute to the Web IDL interface. +This has the advantage that if the check fails, the constructor or +object will not show up at all. + +For preference checking, add an extended attribute +`Pref="myPref.enabled"` where `myPref.enabled` is the preference +that should be checked. `SettingsLock` is an example of this. + +For permissions or other kinds of checking, add an extended attribute +`Func="MyPermissionChecker"` where `MyPermissionChecker` is a +function implemented in C++ that returns true if the interface should be +enabled. This function can do whatever checking is needed. One example +of this is `PushManager`. + +### Example + +Here's an example JS implementation of the above interface. The +`invisibleValue` field will not be accessible to web content, but is +usable by the doNothing() method. + +``` js +function MyNumberInner() { + this.value = 111; + this.invisibleValue = 12345; +} + +MyNumberInner.prototype = { + classDescription: "Get my number XPCOM Component", + contractID: "@mozilla.org/my-number;1", + QueryInterface: ChromeUtils.generateQI([]), + doNothing: function() {}, + get otherValue() { return this.invisibleValue - 4; }, + __init: function(firstNumber) { + if (arguments.length > 0) { + this.value = firstNumber; + } + } +} +``` + +Finally, add a component and a contract and whatever other manifest +stuff you need to implement an XPCOM component. + +### Guarantees provided by bindings + +When implementing a Web IDL interface in JavaScript, certain guarantees +will be provided by the binding implementation. For example, string or +numeric arguments will actually be primitive strings or numbers. +Dictionaries will contain only the properties that they are declared to +have, and they will have the right types. Interface arguments will +actually be objects implementing that interface. + +What the bindings will NOT guarantee is much of anything about +`object` and `any` arguments. They will get cross-compartment +wrappers that make touching them from chrome code not be an immediate +security bug, but otherwise they can have quite surprising behavior if +the page is trying to be malicious. Try to avoid using these types if +possible. + +### Accessing the content object from the implementation + +If the JS implementation of the Web IDL interface needs to access the +content object, it is available as a property called `__DOM_IMPL__` on +the chrome implementation object. This property only appears after the +content-side object has been created. So it is available in `__init` +but not in `init`. + +### Determining the principal of the caller that invoked the Web IDL API + +This can be done by calling +`Component.utils.getWebIDLCallerPrincipal()`. + +### Throwing exceptions from JS-implemented APIs + +There are two reasons a JS implemented API might throw. The first reason +is that some unforeseen condition occurred and the second is that a +specification requires an exception to be thrown. + +When throwing for an unforeseen condition, the exception will be +reported to the console, and a sanitized NS_ERROR_UNEXPECTED exception +will be thrown to the calling content script, with the file/line of the +content code that invoked your API. This will avoid exposing chrome URIs +and other implementation details to the content code. + +When throwing because a specification requires an exception, you need to +create the exception from the window your Web IDL object is associated +with (the one that was passed to your `init` method). The binding code +will then rethrow that exception to the web page. An example of how +this could work: + +``` js +if (!isValid(passedInObject)) { + throw new this.contentWindow.TypeError("Object is invalid"); +} +``` + +or + +``` js +if (!isValid(passedInObject)) { + throw new this.contentWindow.DOMException("Object is invalid", "InvalidStateError"); +} +``` + +depending on which exact exception the specification calls for throwing +in this situation. + +In some cases you may need to perform operations whose exception message +you just want to propagate to the content caller. This can be done like +so: + +``` js +try { + someOperationThatCanThrow(); +} catch (e) { + throw new this.contentWindow.Error(e.message); +} +``` + +### Inheriting from interfaces implemented in C++ + +It's possible to have an interface implemented in JavaScript inherit +from an interface implemented in C++. To do so, simply have one +interface inherit from the other and the bindings code will +auto-generate a C++ object inheriting from the implementation of the +parent interface. The class implementing the parent interface will need +a constructor that takes an `nsPIDOMWindow*` (though it doesn't have +to do anything with that argument). + +If the class implementing the parent interface is abstract and you want +to use a specific concrete class as the implementation to inherit from, +you will need to add a `defaultImpl` annotation to the descriptor for +the parent interface in `Bindings.conf`. The value of the annotation +is the C++ class to use as the parent for JS-implemented descendants; if +`defaultImpl` is not specified, the `nativeType` will be used. + +For example, consider this interface that we wish to implement in +JavaScript: + +``` webidl +[JSImplementation="some-contract"] +interface MyEventTarget : EventTarget { + attribute EventHandler onmyevent; + undefined dispatchTheEvent(); // Sends a "myevent" event to this EventTarget +} +``` + +The implementation would look something like this, ignoring most of the +XPCOM boilerplate: + +``` js +function MyEventTargetImpl() { +} +MyEventTargetImpl.prototype = { + // QI to nsIDOMGlobalPropertyInitializer so we get init() called on us. + QueryInterface: ChromeUtils.generateQI(["nsIDOMGlobalPropertyInitializer"]), + + init: function(contentWindow) { + this.contentWindow = contentWindow; + }, + + get onmyevent() { + return this.__DOM_IMPL__.getEventHandler("onmyevent"); + }, + + set onmyevent(handler) { + this.__DOM_IMPL__.setEventHandler("onmyevent", handler); + }, + + dispatchTheEvent: function() { + var event = new this.contentWindow.Event("myevent"); + this.__DOM_IMPL__.dispatchEvent(event); + }, +}; +``` + +The implementation would automatically support the API exposed on +`EventTarget` (so, for example, `addEventListener`). Calling the +`dispatchTheEvent` method would cause dispatch of an event that +content script can see via listeners it has added. + +Note that in this case the chrome implementation is relying on some +`[ChromeOnly]` methods on EventTarget that were added specifically to +make it possible to easily implement event handlers. Other cases can do +similar things as needed. diff --git a/dom/docs/workersAndStorage/CodeStyle.rst b/dom/docs/workersAndStorage/CodeStyle.rst new file mode 100644 index 0000000000..ef5e6e13b5 --- /dev/null +++ b/dom/docs/workersAndStorage/CodeStyle.rst @@ -0,0 +1,354 @@ +==================================== +DOM Workers & Storage C++ Code Style +==================================== + +This page describes the code style for the components maintained by the DOM Workers & Storage team. They live in-tree under the 'dom/docs/indexedDB' directory. + +.. contents:: + :depth: 4 + +Introduction +============ + +This code style currently applies to the components living in the following directories: + +* ``dom/file`` +* ``dom/indexedDB`` +* ``dom/localstorage`` +* ``dom/payments`` +* ``dom/quota`` +* ``dom/serviceworkers`` +* ``dom/workers`` + +In the long-term, the code is intended to use the +:ref:`Mozilla Coding Style <Coding style>`, +which references the `Google C++ Coding Style <https://google.github.io/styleguide/cppguide.html>`_. + +However, large parts of the code were written before rules and in particular +the reference to the Google C++ Coding Style were enacted, and due to the +size of the code, this misalignment cannot be fixed in the short term. +To avoid that an arbitrary mixture of old-style and new-style code grows, +this document makes deviations from the "global" code style explicit, and +will be amended to describe migration paths in the future. + +In addition, to achieve higher consistency within the components maintained by +the team and to reduce style discussions during reviews, allowing them to focus +on more substantial issues, more specific rules are described here that go +beyond the global code style. These topics might have been deliberately or +accidentally omitted from the global code style. Depending on wider agreement +and applicability, these specific rules might be migrated into the global code +style in the future. + +Note that this document does not cover pure formatting issues. The code is and +must be kept formatted automatically by clang-format using the supplied +configuration file, and whatever clang-format does takes precedence over any +other stated rules regarding formatting. + +Deviations from the Google C++ Coding Style +=========================================== + +Deviations not documented yet. + +Deviations from the Mozilla C++ Coding Style +============================================ + +.. the table renders impractically, cf. https://github.com/readthedocs/sphinx_rtd_theme/issues/117 + +.. tabularcolumns:: |p{4cm}|p{4cm}|p{2cm}|p{2cm}| + ++--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+ +| Mozilla style | Prevalent WAS style | Deviation scope | Evolution | ++========================================================================================================+============================================================================================+=================+=====================================================================================+ +| We prefer using "static", instead of anonymous C++ namespaces. | Place all symbols that should have internal linkage in a single anonymous | All files | Unclear. The recommendation in the Mozilla code style says this might change in the | +| | namespace block at the top of an implementation file, rather than declaring them static. | | future depending on debugger support, so this deviation might become obsolete. | +| | | | | ++--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+ +| `All parameters passed by lvalue reference must be labeled const. [...] Input parameters may be const | Non-const reference parameters may be used. | All files | Unclear. Maybe at least restrict the use of non-const reference parameters to | +| pointers, but we never allow non-const reference parameters except when required by convention, e.g., | | | cases that are not clearly output parameters (i.e. which are assigned to). | +| swap(). <https://google.github.io/styleguide/cppguide.html#Reference_Arguments>`_ | | | | ++--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-----------------+-------------------------------------------------------------------------------------+ + +Additions to the Google/Mozilla C++ Code Style +============================================== + +This section contains style guidelines that do not conflict with the Google or +Mozilla C++ Code Style, but may make guidelines more specific or add guidelines +on topics not covered by those style guides at all. + +Naming +------ + +gtest test names +~~~~~~~~~~~~~~~~ + +gtest constructs a full test name from different fragments. Test names are +constructed somewhat differently for basic and parametrized tests. + +The *prefix* for a test should start with an identifier of the component +and class, based on the name of the source code directory, transformed to +PascalCase and underscores as separators, so e.g. for a class ``Key`` in +``dom/indexedDB``, use ``DOM_IndexedDB_Key`` as a prefix. + +For basic tests constructed with ``TEST(test_case_name, test_name)``: Use +the *prefix* as the ``test_case_name``. Test ``test_name`` should start with +the name of tested method(s), and a . Use underscores as a separator within +the ``test_name``. + +Value-parametrized tests are constructed with +``TEST_P(parametrized_test_case_name, parametrized_test_name)``. They require a +custom test base class, whose name is used as the ``parametrized_test_case_name``. +Start the class name with ``TestWithParam_``, and end it with a transliteration +of the parameter type (e.g. ``String_Int_Pair`` for ``std::pair<nsString, int>``), +and place it in an (anonymous) namespace. + +.. attention:: + It is important to place the class in an (anonymous) namespace, since its + name according to this guideline is not unique within libxul-gtest, and name + clashes are likely, which would lead to ODR violations otherwise. + +A ``parametrized_test_name`` is constructed according to the same rules +described for ``test_name`` above. + +Instances of value-parametrized tests are constructed using +``INSTANTIATE_TEST_CASE_P(prefix, parametrized_test_case_name, generator, ...)``. +As ``prefix``, use the prefix as described above. + +Similar considerations apply to type-parametrized tests. If necessary, specific +rules for type-parametrized tests will be added here. + +Rationale + All gtests (not only from the WAS components) are linked into libxul-gtest, + which requires names to be unique within that large scope. In addition, it + should be clear from the test name (e.g. in the test execution log) in what + source file (or at least which directory) the test code can be found. + Optimally, test names should be structured hierarchically to allow + easy selection of groups of tests for execution. However, gtest has some + restrictions that do not allow that completely. The guidelines try to + accommodate for these as far as possible. Note that gtest recommends not to + use underscores in test names in general, because this may lead to reserved + names and naming conflicts, but the rules stated here should avoid that. + In case of any problems arising, we can evolve the rules to accommodate + for that. + +Specifying types +---------------- + +Use of ``auto`` for declaring variables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `Google C++ Code Style on auto <https://google.github.io/styleguide/cppguide.html#auto>`_ +allows the use of ``auto`` generally with encouragements for specific cases, which still +leaves a rather wide range for interpretation. + +We extend this by some more encouragements and discouragements: + +* DO use ``auto`` when the type is already present in the + initialization expression (esp. a template argument or similar), + e.g. ``auto c = static_cast<uint16_t>(*(iter++)) << 8;`` or + ``auto x = MakeRefPtr<MediaStreamError>(mWindow, *aError);`` + +* DO use ``auto`` if the spelled out type were complex otherwise, + e.g. a nested typedef or type alias, e.g. ``foo_container::value_type``. + +* DO NOT use ``auto`` if the type were spelled out as a builtin + integer type or one of the types from ``<cstdint>``, e.g. + instead of ``auto foo = funcThatReturnsUint16();`` use + ``uint16_t foo = funcThatReturnsUint16();``. + +.. note:: + Some disadvantages of using ``auto`` relate to the unavailability of type + information outside an appropriate IDE/editor. This may be somewhat remedied + by resolving `Bug 1567464 <https://bugzilla.mozilla.org/show_bug.cgi?id=1567464>`_ + which will make the type information available in searchfox. In consequence, + the guidelines might be amended to promote a more widespread use of ``auto``. + +Pointer types +------------- + +Plain pointers +~~~~~~~~~~~~~~ + +The use of plain pointers is error-prone. Avoid using owning plain pointers. In +particular, avoid using literal, non-placement new. There are various kinds +of smart pointers, not all of which provide appropriate factory functions. +However, where such factory functions exist, do use them (along with auto). +The following is an incomplete list of smart pointer types and corresponding +factory functions: + ++------------------------+-------------------------+------------------------+ +| Type | Factory function | Header file | ++========================+=========================+========================+ +| ``mozilla::RefPtr`` | ``mozilla::MakeRefPtr`` | ``"mfbt/RefPtr.h"`` | ++------------------------+-------------------------+------------------------+ +| ``mozilla::UniquePtr`` | ``mozilla::MakeUnique`` | ``"mfbt/UniquePtr.h"`` | ++------------------------+-------------------------+------------------------+ +| ``std::unique_ptr`` | ``std::make_unique`` | ``<memory>`` | ++------------------------+-------------------------+------------------------+ +| ``std::shared_ptr`` | ``std::make_shared`` | ``<memory>`` | ++------------------------+-------------------------+------------------------+ + +Also, to create an ``already_AddRefed<>`` to pass as a parameter or return from +a function without the need to dereference it, use ``MakeAndAddRef`` instead of +creating a dereferenceable ``RefPtr`` (or similar) first and then using +``.forget()``. + +Smart pointers +~~~~~~~~~~~~~~ + +In function signatures, prefer accepting or returning ``RefPtr`` instead of +``already_AddRefed`` in conjunction with regular ``std::move`` rather than +``.forget()``. This improves readability and code generation. Prevailing +legimitate uses of ``already_AddRefed`` are described in its +`documentation <https://searchfox.org/mozilla-central/rev/4df8821c1b824db5f40f381f48432f219d99ae36/mfbt/AlreadyAddRefed.h#31>`_. + +Prefer using ``mozilla::UniquePtr`` over ``nsAutoPtr``, since the latter is +deprecated (and e.g. has no factory function, see Bug 1600079). + +Use ``nsCOMPtr<T>`` iff ``T`` is an XPCOM interface type +(`more details on MDN <https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/nsCOMPtr_versus_RefPtr>`). + +Enums +----- + +Use scoped resp. strongly typed enums (``enum struct``) rather than non-scoped +enums. Use PascalCase for naming the values of scoped enums. + +Evolution Process +================= + +This section explains the process to evolve the coding style described in this +document. For clarity, we will distinguish coding tasks from code style +evolution tasks in this section. + +Managing code style evolution tasks +----------------------------------- + +A code style evolution task is a task that ought to amend or revise the +coding style as described in this document. + +Code style evolution tasks should be managed in Bugzilla, as individual bugs +for each topic. All such tasks +should block the meta-bug +`1586788 <https://bugzilla.mozilla.org/show_bug.cgi?id=1586788>`. + +When you take on to work on a code style evolution task: + +- The task may already include a sketch of a resolution. If no preferred + solution is obvious, discuss options to resolve it via comments on the bug + first. +- When the general idea is ready to be spelled out in this document, amend or + revise it accordingly. +- Submit the changes to this document as a patch to Phabricator, and put it up + for review. Since this will affect a number of people, every change should + be reviewed by at least two people. Ideally, this should include the owner + of this style document and one person with good knowledge of the parts of + the code base this style applies to. +- If there are known violations of the amendment to the coding style, consider + fixing some of them, so that the amendment is tested on actual code. If + the code style evolution task refers to a particular code location from a + review, at least that location should be fixed to comply with the amended + coding style. +- When you have two r+, land the patch. +- Report on the addition in the next team meeting to raise awareness. + +Basis for code style evolution tasks +------------------------------------ + +The desire or necessity to evolve the code style can originate from +different activities, including +- reviews +- reading or writing code locally +- reading the coding style +- general thoughts on coding style + +The code style should not be cluttered with aspects that are rarely +relevant or rarely leads to discussions, as the maintenance of the +code style has a cost as well. The code style should be as comprehensive +as necessary to reduce the overall maintenance costs of the code and +code style combined. + +A particular focus is therefore on aspects that led to some discussion in +a code review, as reducing the number or verbosity of necessary style +discussions in reviews is a major indicator for the effectiveness of the +documented style. + +Evolving code style based on reviews +------------------------------------ + +The goal of the process described here is to take advantage of style-related +discussions that originate from a code review, but to decouple evolution of +the code style from the review process, so that it does not block progress on +the underlying bug. + +The following should be considered when performing a review: + +- Remind yourself of the code style, maybe skim through the document before + starting the review, or have it open side-by-side while doing the review. +- If you find a violation of an existing rule, add an inline comment. +- Have an eye on style-relevant aspects in the code itself or after a + discussions with the author. Consider if this could be generalized into a + style rule, but is not yet covered by the documented global or local style. + This might be something that is in a different style as opposed to other + locations, differs from your personal style, etc. +- In that case, find an acceptable temporary solution for the code fragments + at hand, which is acceptable for an r+ of the patch. Maybe agree with the + code author on adding a comment that this should be revised later, when + a rule is codified. +- Create a code style evolution task in Bugzilla as described above. In the + description of the bug, reference the review comment that gave rise to it. + If you can suggest a resolution, include that in the description, but this + is not a necessary condition for creating the task. + +Improving code style compliance when writing code +------------------------------------------------- + +Periodically look into the code style document, and remind yourself of its +rules, and give particular attention to recent changes. + +When writing code, i.e. adding new code or modify existing code, +remind yourself of checking the code for style compliance. + +Time permitting, resolve existing violations on-the-go as part of other work +in the code area. Submit such changes in dedicated patches. If you identify +major violations that are too complex to resolve on-the-go, consider +creating a bug dedicated to the resolution of that violation, which +then can be scheduled in the planning process. + +Syncing with the global Mozilla C++ Coding Style +------------------------------------------------ + +Several aspects of the coding style described here will be applicable to +the overall code base. However, amendments to the global coding style will +affect a large number of code authors and may require extended discussion. +Deviations from the global coding style should be limited in the long term. +On the other hand, amendments that are not relevant to all parts of the code +base, or where it is difficult to reach a consensus at the global scope, +may make sense to be kept in the local style. + +The details of synchronizing with the global style are subject to discussion +with the owner and peers of the global coding style (see +`Bug 1587810 <https://bugzilla.mozilla.org/show_bug.cgi?id=1587810>`). + +FAQ +--- + +* When someone introduces new code that adheres to the current style, but the + remainder of the function/class/file does not, is it their responsibility + to update that remainder on-the-go? + + The code author is not obliged to update the remainder, but they are + encouraged to do so, time permitting. Whether that is the case depends on a + number of factors, including the number and complexity of existing style + violations, the risk introduced by changing that on the go etc. Judging this + is left to the code author. + At the very least, the function/class/file should not be left in a worse + state than before. + +* Are stylistic inconsistencies introduced by applying the style as defined + here only to new code considered acceptable? + + While this is certainly not optimal, accepting such inconsistencies to + some degree is inevitable to allow making progress towards an improved style. + Personal preferences regarding the degree may differ, but in doubt such + inconsistencies should be considered acceptable. They should not block a bug + from being closed. diff --git a/dom/docs/workersAndStorage/PerformanceTesting.rst b/dom/docs/workersAndStorage/PerformanceTesting.rst new file mode 100644 index 0000000000..8e464b8116 --- /dev/null +++ b/dom/docs/workersAndStorage/PerformanceTesting.rst @@ -0,0 +1,70 @@ +================================ +Service Worker Performance Tests +================================ + +Our performance tests are mochitests running in the `mozperftest +<https://firefox-source-docs.mozilla.org/testing/perfdocs/mozperftest.html>`_ +harness. Tests reside under `dom/serviceworkers/test/performance +<https://searchfox.org/mozilla-central/source/dom/serviceworkers/test/performance>`_, +itemized in perftest.toml. Beyond the standard mochitest machinery, +performance tests define a ``perfMetadata`` variable at the top level, and call: + +``info("perfMetrics", JSON.stringify(metrics));`` + +to report their results, where *metrics* is a map from testpoint name to scalar +numeric value. See the `performance scripts documentation +<https://firefox-source-docs.mozilla.org/testing/perfdocs/writing.html#mochitest>`_ +for more. + +They can be run via mach perftest, or as normal mochitests via mach test. +(Currently we can’t run the full manifest, see `bug 1865852 +<https://bugzilla.mozilla.org/show_bug.cgi?id=1865852>`_.) + +Adding new tests +================ + +Add files to `perftest.toml +<https://searchfox.org/mozilla-central/source/dom/serviceworkers/test/performance/perftest.toml>`_ +as usual for mochitests. + +Modify linux.yml, macosx.yml, and windows.yml under `taskcluster/ci/perftest +<https://searchfox.org/mozilla-central/source/taskcluster/ci/perftest>`_. +Currently, each test needs to be added individually to the run command (`here +<https://searchfox.org/mozilla-central/rev/91cc8848427fdbbeb324e6ca56a0d08d32d3c308/taskcluster/ci/perftest/linux.yml#121-149>`_, +for example). kind.yml can be ignored–it provides some defaults. + +Modify the documentation using: + +``$ ./mach lint -l perfdocs . --fix --warnings --outgoing`` + +There's currently a `bug <https://bugzilla.mozilla.org/show_bug.cgi?id=1872613>`_ +which will likely cause the command to fail. Running it a second time should +succeed. + +Staging tests in try jobs +========================= + +``$ ./mach try fuzzy --full`` + +Look for ``‘service-worker`` to find things like: + +| >perftest-windows-service-worker +| >perftest-macosx-service-worker +| >perftest-linux-service-worker +| + +Results +======= + +Results can be found in treeherder on `mozilla-central +<https://treeherder.mozilla.org/jobs?repo=mozilla-central&searchStr=perftest>`_ +and `autoland +<https://treeherder.mozilla.org/jobs?repo=autoland&searchStr=perftest>`_. Look +for linux-sw, macosx-sw, and win-sw (`example +<https://treeherder.mozilla.org/perfherder/graphs?series=mozilla-central,4967140,1,15&selected=4967140,1814245176>`_). +These symbol names are defined in the .yml files under taskcluster/ci/perftest. + +Contacts +======== +| `Joshua Marshall <https://people.mozilla.org/p/jmarshall>`_ (DOM LWS) +| `Gregory Mierzwinski <https://people.mozilla.org/p/sparky>`_ (Performance Tools) diff --git a/dom/docs/workersAndStorage/WorkerLifeCycleAndWorkerRefs.md b/dom/docs/workersAndStorage/WorkerLifeCycleAndWorkerRefs.md new file mode 100644 index 0000000000..b20f7733b6 --- /dev/null +++ b/dom/docs/workersAndStorage/WorkerLifeCycleAndWorkerRefs.md @@ -0,0 +1,233 @@ +# Worker’s Life-Cycle and WorkerRefs + +Worker, as a thread programming model, is introduced to the Web world to use the computing power efficiently in the Web world. Just like the regular thread programming, Worker can be created and deleted anytime when needed. + +Since Worker can be deleted anytime, when developing APIs on the Workers should be careful when handling the shutdown behavior. Otherwise, memory problems, UAF, memory leaking, or shutdown hang, would not be a surprise. In addition, debugging these issues on Workers sometimes is not easy. The crash stack might not provide very useful information. The bug sometimes needs a special sequence to reproduce since it could be a thread interleaving problem. To avoid getting into these troubles, keeping the Worker’s life cycle and how to play with WorkerRefs in mind would be very helpful. + + +## Worker Life-Cycle + +The worker’s life cycle is maintained by a status machine in the WorkerPrivate class. A Worker could be in following status + +- Pending +- Running +- Closing +- Canceling +- Killing +- Dead + +Following we briefly describe what is done for each status. + + +### Pending: + +This is the initial status of a Worker. + +Worker’s initialization is done in this status in the parent(main or the parent worker) and worker thread. + +Worker’s initialization starts from its parent thread, which includes + +1. Get WorkerLoadInfo from parent window/worker +2. Create a WorkerPrivate for the Worker +3. Register the Worker in the RuntimeService object +4. Initialize a thread(worker thread) for Worker, and dispatch a WorkerThreadPrimaryRunnable on the worker thread +5. Connect debugger +6. Dispatch CompileScriptRunnable to the worker thread + +Before the Worker thread starts running runnables, a Worker could have already been exposed to its parent window/worker. So the parent window/worker can send messages to the worker through the postMessage() method. If the Worker is not in the “Running” status yet, these runnables would be kept in WorkerPrivate::mPreStartRunnables. + +When WorkerThreadPrimaryRunnable starts executing on the worker thread, it continues the initialization on the worker thread, which includes + +1. Build the connection between WorkerPrivate and the worker thread. Then moving the WorkerPrivate::mPreStartRunnables to the worker thread’s event queue. +2. Initialize the PerformanceStorage for the Worker. +3. Start the Cycle-Collector for the Worker. +4. Initialize the JS context for the Worker. +5. Call WorkerPrivate::DoRunLoop() to consume the Runnables in the worker thread’s event queue. + + +### Running: + +This is the status which the Worker starts to execute runnables on the worker thread. + +Once the Worker gets into “Running”, + +1. Enable the memory reporter +2. Start the GC timer. + +“Running” is the status where we play with the Worker. At this time point, we can + +1. Create WorkerRefs to get the Worker shutdown notifications and run shutdown cleanup jobs through the registered callback. +2. Create sync-eventLoop to make the worker thread to wait for another thread's execution. +3. Dispatching events to WorkerGlobalScope to trigger event callbacks defined in the script. + +We will talk about WorkerRef, Sync-EventLoop in detail later. + + +### Closing: + +This is a special status for DedicatedWorker and SharedWorker when DedicateWorkerGlobalScope.close()/SharedWorkerGlobalScope.close() is called. + +When Worker enters into the “Closing” status, + +1. Cancel all Timeouts/TimeIntervals of the Worker. +2. Do not allow BroadcastChannel.postMessage() on the WorkerGlobalScope. + +Worker will keep in the “Closing” status until all sync-eventLoops of the Worker are closed. + + +### Canceling: + +When Worker gets into the “Canceling” status, it starts the Worker shutdown steps. + +1. Set the WorkerGlobalScope(nsIGlobalObject) as dying. + +This means the event will not be dispatched to the WorkerGlobalScope and the callbacks of the pending dispatched event will not be executed. + +2. Cancel all Timeouts/TimeIntervals of the Worker. +3. Notify WorkerRef holders and children Workers. + +So the WorkerRef holders and children Workers will start the shutdown jobs + +4. Abort the script immediately. + +Once all sync-eventLoops are closed, + +1. Disconnect the EventTarget/WebTaskScheduler of the WorkerGlobalScope + + +### Killing: + +This is the status that starts to destroy the Worker + +1. Shutdown the GC Timer +2. Disable the memory reporter +3. Switch the status to “Dead” +4. Cancel and release the remaining WorkerControlRunnables +5. Exit the WorkerPrivate::DoRunLoop() + + +### Dead: + +The Worker quits the main event loop, it continues the shutdown process + +1. Release the remaining WorkerDebuggerRunnables + +2. Unroot the WorkerGlobalScope and WorkerDebugGlobalScope + + 1. Trigger GC to release GlobalScopes + +3. Shutdown the Cycle-Collector for Worker + +4. Dispatch TopLevelWorkerFinishRunnable/WorkerFinishRunnable to the parent thread + + 1. Disable/Disconnect the WorkerDebugger + 2. Unregister the Worker in the RuntimeService object + 3. Release WorkerPrivate::mSelf and WorkerPrivate::mParentEventTargetRef + +The WorkerPrivate is supposed to be released after its self-reference is nullified. + +5. Dispatch FinishedRunnable to the main thread to release the worker thread. + + +### How to shutdown a Worker + +Normally, there are four situations making a Worker get into shutdown. + +1. Worker is GC/CCed. + + 1. Navigating to another page. + 2. Worker is idle for a while. (Notice that idle is not a status of Worker, it is a condition in “Running” status) + +2. self.close() is called in the worker's script. + +3. Worker.terminate() is called in its parent’s script. + +4. Firefox shutdown. + + +### Worker Status Flowchart + +![Worker Status Flowchart](./WorkerStatusFlowchart.svg) + +This flowchart shows how the status of a Worker is changing. + +When the WorkerThreadPrimaryRunnable calls WorkerPrivate::DoRunLoop on the worker thread, the status changes from “Pending” to “Running.” If Firefox shutdown happens before entering into “Running,” the status directly changes from “Pending” to “Dead.” + +When a Worker is in “Running,” status changing must be caused by requesting a Worker shutdown. The status switches to “Closing,” for the special case that worker’s script calls self.close(). Otherwise, the status switches to “Canceling.” And a “Closing” Worker will switch to “Canceling” when all sync-eventLoops are completed. + +A “Canceling” Worker switches its status to “Killing” when following requirements are fulfilled. + +1. No WorkerRefs, no children Workers, no Timeouts, and no sync-eventLoops +2. No pending runnable for the worker thread main event queue, control runnables and debugger runnables + +The status switches from “Killing” to “Dead” automatically. + + +## WorkerRefs + +Since a Worker’s shutdown can happen at any time, knowing when the shutdown starts is important for development, especially for releasing the resources and completing the operation in the Worker shutdown phase. Therefore, WorkerRefs is introduced to get the notification of the Worker’s shutdown. When a Worker enters the “Canceling” status, it notifies the corresponding WorkerRefs to execute the registered callback on the worker thread. The WorkerRefs holder completes its shutdown steps synchronously or asynchronously in the registered callback and then releases the WorkerRef. + +According to the following requirements, four types of WorkerRefs are introduced. + +- Should the WorkerRef block the Worker's shutdown +- Should the WorkerRef block cycle-collection on the Worker +- Should the WorkerRef need to be held on other threads. + + +### WeakWorkerRef + +WeakWorkerRef, as its name, is a “Weak” reference since WeakWorkerRef releases the internal reference to the Worker immediately after WeakWorkerRef’s registered callback execution completes. Therefore, WeakWorkerRef does not block the Worker’s shutdown. In addition, holding a WeakWorkerRef would not block GC/CC the Worker. This means a Worker will be considered to be cycle-collected even if there are WeakWorkerRefs to the Worker. + +WeakWorkerRef is ref-counted, but not thread-safe. + +WeakWorkerRef is designed for just getting the Worker’s shutdown notification and completing shutdown steps synchronously. + + +### StrongWorkerRef + +Unlike WeakWorkerRef, StrongWorkerRef does not release its internal reference to the Worker after the callback execution. StrongWorkerRef’s internal reference is released when the StrongWorkerRef gets destroyed. That means StrongWorkerRef allows its holder to determine when to release the Worker by nulling the StrongWorkerRef. This also makes StrongWorkerRef's holder block the Worker's shutdown. + +When using the StrongWorkerRef, resource cleanup might involve multiple threads and asynchronous behavior. StrongWorkerRef release timing becomes crucial not to cause memory problems, such as UAF or leaking. StrongWorkerRef must be released. Otherwise, a shutdown hang would not be a surprise. + +StrongWorkerRef also blocks the GC/CC a Worker. Once there is a StrongWorkerRef to the Worker, GC/CC will not collect the Worker. + +StrongWorkerRef is ref-counted, but not thread-safe. + + +### ThreadSafeWorkerRef + +ThreadSafeWorkerRef is an extension of StrongWorkerRef. The difference is ThreadSafeWorkerRef holder can be on another thread. Since it is an extension of StrongWorkerRef, it gives the same characters as StrongWorkerRef. Which means its holder blocks the Worker’s shutdown, and It also blocks GC/CC a Worker. + +Playing with ThreadSafeWorkerRef, just like StrongWorkerRef, ThreadSafeWorkerRef release timing is important for memory problems. Except the release timing, it should be noticed the callback execution on the worker thread, not on the holder’s owning thread. + +ThreadSafeWorkerRef is ref-counted and thread-safe. + + +### IPCWorkerRef + +IPCWorkerRef is a special WorkerRef for IPC actors which binds its life-cycle with Worker’s shutdown notification. (In our current codebase, Cache API and Client API uses IPCWorkerRef) + +Because some IPC shutdown needs to be in a special sequence during the Worker's shutdown. However, to make these IPC shutdown needs to ensure the Worker is kept alive, so IPCWorkerRef blocks the Worker's shutdown. But IPC shutdown no need to block GC/CC a Worker. + +IPCWorkerRef is ref-counted, but not thread-safe. + +Following is a table for the comparison between WorkerRefs + +| | | | | | +| ------------------------- | :-----------: | :-------------: | :-----------------: | :-----------: | +| | WeakWorkerRef | StrongWorkerRef | ThreadSafeWorkerRef | IPCWorkerRef | +| Holder thread | Worker thread | Worker thread | Any thread | Worker thread | +| Callback execution thread | Worker thread | Worker thread | Worker thread | Worker thread | +| Block Worker’s shutdown | No | Yes | Yes | Yes | +| Block GC a Worker | No | Yes | Yes | No | + + +### WorkerRef Callback + +WorkerRef Callback can be registered when creating a WorkerRef. The Callback takes the responsibility for releasing the resources related to WorkerRef’s holder. For example, resolving/rejecting the promises created by the WorkerRef’s holder. The cleanup behavior might be synchronous or asynchronous depending on how complicated the functionality involved. For example, Cache APIs might need to wait until the operation finishes on the IO thread and release the main-thread-only objects on the main thread. + +To avoid memory problems, there are some things need to keep in mind for WorkerRef callback + +- Don’t release WorkerRef before finishing cleanup steps. (UAF) +- Don’t forget to release resources related. (Memory leaking) +- Don’t forget to release WorkerRef(StrongWorkerRef/ThreadWorkerRef/IPCWorkerRef) (Shutdown hang) diff --git a/dom/docs/workersAndStorage/WorkerStatusFlowchart.svg b/dom/docs/workersAndStorage/WorkerStatusFlowchart.svg new file mode 100644 index 0000000000..33a6859a38 --- /dev/null +++ b/dom/docs/workersAndStorage/WorkerStatusFlowchart.svg @@ -0,0 +1,4 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> +<svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="344.1558441558442" viewBox="0, 0, 400,344.1558441558442"><g id="svgg"><path id="path0" d="M0.000 172.078 L 0.000 344.156 200.000 344.156 L 400.000 344.156 400.000 172.078 L 400.000 0.000 200.000 0.000 L 0.000 0.000 0.000 172.078 M135.390 23.377 L 135.390 31.494 223.864 31.494 L 312.338 31.494 312.257 176.542 L 312.175 321.591 225.995 321.673 L 139.815 321.754 140.759 322.740 L 141.703 323.726 138.546 322.583 L 135.390 321.440 135.390 329.714 L 135.390 337.987 98.214 337.987 L 61.039 337.987 61.039 321.266 L 61.039 304.545 79.531 304.545 L 98.024 304.545 96.879 301.380 L 95.734 298.214 96.730 299.168 L 97.727 300.121 97.727 290.161 L 97.727 280.200 79.464 280.116 L 61.201 280.032 61.117 263.393 L 61.033 246.753 79.537 246.753 L 98.040 246.753 96.898 243.596 L 95.755 240.440 96.741 241.384 L 97.727 242.329 97.727 232.204 L 97.727 222.078 79.380 222.078 L 61.033 222.078 61.117 205.438 L 61.201 188.799 79.591 188.715 L 97.980 188.631 96.921 185.793 C 95.742 182.634,95.742 182.339,96.917 183.443 L 97.727 184.204 97.727 174.245 L 97.727 164.286 79.383 164.286 L 61.039 164.286 61.039 147.568 L 61.039 130.849 79.496 130.766 L 97.953 130.682 96.901 127.841 C 95.782 124.820,95.790 124.592,96.976 125.706 L 97.727 126.412 97.727 116.453 L 97.727 106.494 79.383 106.494 L 61.039 106.494 61.039 89.773 L 61.039 73.052 79.540 73.052 L 98.040 73.052 96.898 69.895 L 95.755 66.738 96.741 67.683 L 97.727 68.628 97.727 58.667 L 97.727 48.707 79.464 48.623 L 61.201 48.539 61.117 31.899 L 61.033 15.260 98.211 15.260 L 135.390 15.260 135.390 23.377 M62.013 31.818 L 62.013 47.727 98.377 47.727 L 134.740 47.727 134.740 31.818 L 134.740 15.909 98.377 15.909 L 62.013 15.909 62.013 31.818 M82.355 28.372 C 84.353 30.694,82.662 33.117,79.043 33.117 L 77.273 33.117 77.273 34.903 C 77.273 36.472,77.194 36.688,76.623 36.688 C 76.004 36.688,75.974 36.472,75.974 31.940 L 75.974 27.191 78.784 27.339 C 81.352 27.474,81.659 27.563,82.355 28.372 M103.824 32.072 L 103.914 36.700 103.012 36.658 C 102.516 36.635,101.654 36.720,101.096 36.847 C 98.556 37.425,96.802 33.318,98.577 30.950 C 99.159 30.174,99.497 30.032,100.769 30.032 L 102.274 30.032 102.273 28.869 C 102.273 27.562,102.497 27.206,103.231 27.347 C 103.652 27.427,103.748 28.198,103.824 32.072 M106.760 28.166 C 106.844 28.761,106.709 28.896,106.029 28.896 C 105.350 28.896,105.195 28.741,105.195 28.062 C 105.195 26.952,106.600 27.045,106.760 28.166 M77.273 30.205 C 77.273 31.754,77.651 31.981,79.711 31.672 C 82.605 31.238,82.022 28.896,79.019 28.896 L 77.273 28.896 77.273 30.205 M88.685 30.221 C 89.345 30.574,90.260 32.345,90.260 33.269 C 90.260 33.671,89.795 33.766,87.825 33.766 C 85.190 33.766,84.673 34.202,86.111 35.209 C 87.068 35.879,87.556 35.846,88.225 35.065 C 89.002 34.157,90.260 34.180,90.020 35.098 C 89.543 36.925,86.426 37.470,84.861 36.000 C 82.002 33.314,85.261 28.389,88.685 30.221 M96.171 30.418 C 97.094 31.253,97.035 36.688,96.104 36.688 C 95.513 36.688,95.455 36.472,95.455 34.293 C 95.455 31.643,95.054 30.954,93.712 31.291 C 92.795 31.521,92.543 32.279,92.537 34.821 C 92.533 36.470,92.457 36.688,91.883 36.688 C 91.276 36.688,91.234 36.472,91.234 33.327 L 91.234 29.966 93.412 29.929 C 95.005 29.902,95.746 30.033,96.171 30.418 M106.748 33.360 L 106.841 36.688 106.018 36.688 L 105.195 36.688 105.195 33.257 C 105.195 29.884,105.207 29.827,105.925 29.929 C 106.622 30.028,106.660 30.189,106.748 33.360 M113.055 30.418 C 113.977 31.253,113.918 36.688,112.987 36.688 C 112.396 36.688,112.338 36.472,112.338 34.293 C 112.338 31.643,111.938 30.954,110.595 31.291 C 109.678 31.521,109.426 32.279,109.420 34.821 C 109.416 36.470,109.340 36.688,108.766 36.688 C 108.159 36.688,108.117 36.472,108.117 33.327 L 108.117 29.966 110.295 29.929 C 111.888 29.902,112.629 30.033,113.055 30.418 M119.091 30.260 C 119.394 30.563,119.481 30.563,119.481 30.260 C 119.481 30.045,119.773 29.870,120.130 29.870 C 120.859 29.870,121.125 36.062,120.470 37.784 C 119.636 39.976,114.935 39.831,114.935 37.612 C 114.935 36.882,116.079 36.791,116.351 37.500 C 116.610 38.175,118.698 38.154,118.959 37.473 C 119.298 36.590,119.194 36.518,117.748 36.633 C 114.901 36.860,113.479 32.923,115.594 30.671 C 116.421 29.791,118.390 29.559,119.091 30.260 M85.714 31.818 C 85.388 32.428,85.467 32.468,87.002 32.468 C 88.662 32.468,88.947 32.259,88.247 31.558 C 87.619 30.931,86.106 31.086,85.714 31.818 M99.687 31.797 C 98.943 33.186,99.734 35.714,100.912 35.714 C 102.189 35.714,102.928 32.837,101.953 31.661 C 101.379 30.970,100.088 31.048,99.687 31.797 M116.623 31.558 C 116.119 32.063,116.119 34.495,116.623 35.000 C 117.752 36.129,119.156 35.175,119.156 33.279 C 119.156 31.801,118.718 31.169,117.695 31.169 C 117.320 31.169,116.838 31.344,116.623 31.558 M135.314 40.341 L 135.227 48.539 116.964 48.623 L 98.701 48.707 98.701 58.667 L 98.701 68.628 99.675 67.695 C 100.881 66.540,100.884 66.489,99.547 70.086 L 98.444 73.052 116.917 73.052 L 135.390 73.052 135.390 81.169 L 135.390 89.286 150.325 89.286 L 165.260 89.286 165.260 147.565 L 165.260 205.844 152.537 205.844 L 139.814 205.844 140.747 206.818 C 141.905 208.027,141.707 208.027,138.474 206.818 C 137.045 206.284,135.767 205.846,135.633 205.845 C 135.499 205.845,135.390 209.497,135.390 213.961 L 135.390 222.078 117.045 222.078 L 98.701 222.078 98.701 232.204 L 98.701 242.329 99.725 241.376 C 100.538 240.619,100.700 240.556,100.510 241.071 C 100.378 241.429,99.855 242.853,99.346 244.237 L 98.422 246.753 116.909 246.753 L 135.396 246.753 135.311 263.393 L 135.227 280.032 116.964 280.116 L 98.701 280.200 98.701 290.161 L 98.701 300.121 99.675 299.188 C 100.881 298.033,100.884 297.982,99.547 301.579 L 98.444 304.545 116.917 304.545 L 135.390 304.545 135.390 312.811 L 135.390 321.076 138.555 319.931 L 141.721 318.786 140.767 319.782 L 139.814 320.779 225.589 320.779 L 311.364 320.779 311.364 176.461 L 311.364 32.143 223.382 32.143 L 135.401 32.143 135.314 40.341 M217.532 57.255 C 217.532 57.317,217.277 57.865,216.964 58.473 C 216.207 59.946,216.219 63.415,216.987 64.854 C 217.470 65.761,217.480 65.909,217.060 65.909 C 215.475 65.909,214.732 61.036,215.938 58.544 C 216.466 57.454,217.532 56.592,217.532 57.255 M219.724 58.770 C 220.879 61.035,220.108 65.909,218.594 65.909 C 218.259 65.909,218.186 65.736,218.356 65.341 C 219.664 62.290,219.661 60.741,218.341 57.667 C 217.790 56.383,218.998 57.347,219.724 58.770 M106.030 58.360 C 106.140 58.851,106.405 59.911,106.620 60.714 L 107.012 62.175 107.627 59.821 C 108.151 57.817,108.346 57.468,108.942 57.468 C 109.536 57.468,109.740 57.825,110.284 59.821 L 110.925 62.175 111.504 59.821 C 111.954 57.990,112.212 57.468,112.665 57.468 C 113.208 57.468,113.192 57.669,112.435 60.471 C 111.224 64.949,110.597 65.138,109.604 61.323 L 108.980 58.929 108.370 61.039 C 108.034 62.200,107.694 63.343,107.614 63.579 C 107.535 63.816,107.216 63.960,106.906 63.900 C 106.018 63.729,104.394 57.468,105.238 57.468 C 105.621 57.468,105.902 57.784,106.030 58.360 M122.727 58.985 L 122.727 60.503 123.479 59.797 C 124.863 58.496,125.876 58.949,124.606 60.301 C 123.835 61.121,123.813 61.021,125.249 63.231 C 125.688 63.905,125.673 63.961,125.056 63.961 C 124.657 63.961,124.155 63.567,123.812 62.987 C 123.496 62.451,123.122 62.013,122.982 62.013 C 122.842 62.013,122.727 62.451,122.727 62.987 C 122.727 63.745,122.583 63.961,122.078 63.961 C 121.495 63.961,121.426 63.736,121.403 61.769 C 121.389 60.564,121.306 59.752,121.220 59.966 C 121.133 60.179,120.854 60.273,120.600 60.176 C 120.033 59.958,119.481 61.277,119.481 62.846 C 119.481 63.621,119.332 63.961,118.994 63.961 C 118.604 63.961,118.506 63.475,118.506 61.532 L 118.506 59.103 119.968 59.189 C 121.370 59.271,121.429 59.238,121.429 58.371 C 121.429 57.684,121.584 57.468,122.078 57.468 C 122.635 57.468,122.727 57.684,122.727 58.985 M138.692 58.005 C 140.166 59.338,139.025 61.364,136.800 61.364 L 135.390 61.364 135.390 62.662 C 135.390 63.745,135.281 63.961,134.740 63.961 C 134.134 63.961,134.091 63.745,134.091 60.714 L 134.091 57.468 136.095 57.468 C 137.503 57.468,138.274 57.627,138.692 58.005 M144.156 57.955 C 144.156 58.222,143.937 58.442,143.669 58.442 C 143.401 58.442,143.182 58.222,143.182 57.955 C 143.182 57.687,143.401 57.468,143.669 57.468 C 143.937 57.468,144.156 57.687,144.156 57.955 M155.844 58.461 C 155.844 58.807,155.990 59.091,156.169 59.091 C 156.347 59.091,156.494 59.310,156.494 59.578 C 156.494 59.846,156.347 60.065,156.169 60.065 C 155.990 60.065,155.844 60.722,155.844 61.526 C 155.844 62.330,155.990 62.987,156.169 62.987 C 156.347 62.987,156.494 63.206,156.494 63.474 C 156.494 64.175,154.959 64.104,154.737 63.393 C 154.332 62.089,154.390 58.533,154.826 58.008 C 155.355 57.370,155.844 57.588,155.844 58.461 M171.252 57.669 C 171.974 57.946,172.727 59.500,172.727 60.714 C 172.727 63.086,171.714 63.961,168.967 63.961 L 167.208 63.961 167.208 60.714 L 167.208 57.468 168.967 57.468 C 169.934 57.468,170.963 57.558,171.252 57.669 M183.497 58.005 C 184.272 58.706,184.251 59.690,183.443 60.551 L 182.795 61.241 183.605 62.339 C 184.583 63.665,184.614 63.961,183.775 63.961 C 183.400 63.961,182.937 63.581,182.660 63.045 C 181.499 60.801,179.870 60.470,179.870 62.478 C 179.870 63.745,179.775 63.961,179.221 63.961 C 178.615 63.961,178.571 63.745,178.571 60.714 L 178.571 57.468 180.737 57.468 C 182.297 57.468,183.070 57.618,183.497 58.005 M196.429 60.227 L 196.429 62.987 197.890 62.987 C 198.972 62.987,199.351 63.113,199.351 63.474 C 199.351 63.857,198.900 63.961,197.240 63.961 L 195.130 63.961 195.130 60.714 C 195.130 57.684,195.173 57.468,195.779 57.468 C 196.378 57.468,196.429 57.684,196.429 60.227 M135.390 59.416 C 135.390 60.388,135.439 60.425,136.607 60.328 C 137.663 60.241,137.825 60.119,137.825 59.416 C 137.825 58.712,137.663 58.590,136.607 58.503 C 135.439 58.406,135.390 58.443,135.390 59.416 M168.182 60.714 L 168.182 62.987 169.295 62.987 C 171.015 62.987,171.663 62.053,171.434 59.903 C 171.322 58.842,170.775 58.442,169.441 58.442 L 168.182 58.442 168.182 60.714 M179.870 59.253 C 179.870 60.051,179.953 60.096,181.250 60.002 C 182.380 59.921,182.630 59.785,182.630 59.253 C 182.630 58.721,182.380 58.586,181.250 58.504 C 179.953 58.410,179.870 58.455,179.870 59.253 M117.208 59.740 C 119.364 61.897,116.221 65.519,113.965 63.478 C 112.427 62.085,113.532 59.091,115.584 59.091 C 116.126 59.091,116.847 59.380,117.208 59.740 M129.689 59.813 C 130.739 61.311,130.383 62.013,128.571 62.013 C 126.917 62.013,126.500 62.379,127.510 62.945 C 127.908 63.167,128.332 63.106,128.961 62.734 C 129.961 62.144,130.511 62.413,129.990 63.239 C 128.672 65.329,125.008 63.210,125.852 60.845 C 126.507 59.011,128.712 58.418,129.689 59.813 M133.705 59.659 C 133.644 59.971,133.306 60.226,132.950 60.227 C 132.393 60.227,132.292 60.481,132.208 62.094 C 132.049 65.145,131.169 64.664,131.169 61.526 L 131.169 59.091 132.491 59.091 C 133.576 59.091,133.794 59.193,133.705 59.659 M142.793 59.670 C 142.734 59.976,142.396 60.226,142.041 60.227 C 141.484 60.227,141.383 60.481,141.299 62.094 C 141.133 65.280,139.935 64.817,139.935 61.567 L 139.935 59.173 141.418 59.144 C 142.652 59.119,142.882 59.207,142.793 59.670 M144.156 61.526 C 144.156 63.474,144.058 63.961,143.669 63.961 C 143.279 63.961,143.182 63.474,143.182 61.526 C 143.182 59.578,143.279 59.091,143.669 59.091 C 144.058 59.091,144.156 59.578,144.156 61.526 M146.061 60.376 C 146.598 62.166,146.980 62.253,147.448 60.690 C 147.813 59.472,148.483 58.764,148.887 59.169 C 148.974 59.256,148.659 60.369,148.186 61.644 C 147.066 64.667,146.531 64.692,145.452 61.774 C 145.007 60.570,144.594 59.475,144.535 59.338 C 144.475 59.202,144.708 59.091,145.051 59.091 C 145.498 59.091,145.786 59.457,146.061 60.376 M153.176 59.497 C 153.359 59.720,153.560 60.810,153.622 61.920 L 153.734 63.936 152.597 63.961 C 151.972 63.974,151.113 63.994,150.688 64.005 C 148.507 64.060,149.048 61.543,151.317 61.079 C 151.860 60.968,152.334 60.731,152.370 60.552 C 152.465 60.080,150.928 59.938,150.647 60.393 C 150.516 60.605,150.167 60.727,149.871 60.665 C 149.377 60.561,149.375 60.492,149.847 59.821 C 150.429 58.995,152.591 58.784,153.176 59.497 M160.260 59.339 C 160.738 59.658,161.364 60.877,161.364 61.488 C 161.364 61.859,160.908 62.005,159.517 62.078 C 157.758 62.171,157.698 62.202,158.242 62.744 C 158.945 63.444,159.227 63.453,159.880 62.801 C 160.768 61.912,161.574 62.334,160.803 63.285 C 159.395 65.020,156.818 63.859,156.818 61.490 C 156.818 59.685,158.863 58.407,160.260 59.339 M163.312 59.740 C 163.312 60.101,163.095 60.390,162.825 60.390 C 162.554 60.390,162.338 60.101,162.338 59.740 C 162.338 59.380,162.554 59.091,162.825 59.091 C 163.095 59.091,163.312 59.380,163.312 59.740 M165.909 59.740 C 165.909 60.101,165.693 60.390,165.422 60.390 C 165.152 60.390,164.935 60.101,164.935 59.740 C 164.935 59.380,165.152 59.091,165.422 59.091 C 165.693 59.091,165.909 59.380,165.909 59.740 M177.273 59.740 C 179.429 61.897,176.286 65.519,174.030 63.478 C 172.492 62.085,173.597 59.091,175.649 59.091 C 176.190 59.091,176.912 59.380,177.273 59.740 M186.104 60.958 C 186.254 63.842,187.773 63.825,187.923 60.937 C 188.079 57.918,189.089 58.426,189.218 61.589 L 189.313 63.918 188.244 63.945 C 187.656 63.960,186.886 63.976,186.532 63.981 C 185.534 63.995,185.065 63.035,185.065 60.977 C 185.065 58.290,185.964 58.273,186.104 60.958 M193.820 59.719 C 194.368 60.743,194.253 63.961,193.669 63.961 C 193.305 63.961,193.181 63.571,193.177 62.419 C 193.167 59.281,191.461 58.989,191.299 62.097 C 191.215 63.695,191.111 63.961,190.568 63.961 C 189.974 63.961,189.543 59.916,190.080 59.379 C 190.589 58.870,193.508 59.136,193.820 59.719 M204.004 60.140 C 205.436 62.066,203.595 64.772,201.416 63.944 C 200.240 63.497,200.011 63.109,200.005 61.552 C 199.995 59.060,202.534 58.163,204.004 60.140 M208.766 59.740 C 210.923 61.897,207.780 65.519,205.524 63.478 C 203.985 62.085,205.090 59.091,207.143 59.091 C 207.684 59.091,208.405 59.380,208.766 59.740 M213.704 59.639 C 215.280 61.066,213.785 64.580,211.811 64.085 C 211.105 63.907,211.039 63.990,211.039 65.062 C 211.039 66.373,211.207 66.476,212.072 65.693 C 212.632 65.186,212.719 65.200,213.476 65.911 C 214.425 66.802,214.271 67.264,213.314 66.398 C 212.685 65.829,212.640 65.829,212.013 66.396 C 211.408 66.944,211.323 66.947,210.770 66.446 C 210.443 66.151,210.053 65.909,209.903 65.909 C 209.752 65.909,209.362 66.151,209.035 66.446 C 208.482 66.947,208.397 66.944,207.792 66.396 C 207.166 65.829,207.120 65.829,206.494 66.396 C 205.867 66.963,205.821 66.963,205.195 66.396 C 204.568 65.829,204.523 65.829,203.896 66.396 C 203.291 66.944,203.206 66.947,202.653 66.446 C 202.326 66.151,201.936 65.909,201.786 65.909 C 201.635 65.909,201.245 66.151,200.918 66.446 C 200.365 66.947,200.281 66.944,199.675 66.396 C 199.049 65.829,199.003 65.829,198.377 66.396 C 197.750 66.963,197.705 66.963,197.078 66.396 C 196.451 65.829,196.406 65.829,195.779 66.396 C 195.153 66.963,195.107 66.963,194.481 66.396 C 193.875 65.848,193.791 65.845,193.237 66.346 C 192.495 67.018,192.245 67.018,191.503 66.346 C 190.949 65.845,190.865 65.848,190.260 66.396 C 189.633 66.963,189.588 66.963,188.961 66.396 C 188.334 65.829,188.289 65.829,187.662 66.396 C 187.036 66.963,186.990 66.963,186.364 66.396 C 185.758 65.848,185.674 65.845,185.121 66.346 C 184.794 66.641,184.404 66.883,184.253 66.883 C 184.103 66.883,183.713 66.641,183.386 66.346 C 182.832 65.845,182.748 65.848,182.143 66.396 C 181.516 66.963,181.471 66.963,180.844 66.396 C 180.218 65.829,180.172 65.829,179.545 66.396 C 178.919 66.963,178.873 66.963,178.247 66.396 C 177.641 65.848,177.557 65.845,177.004 66.346 C 176.677 66.641,176.287 66.883,176.136 66.883 C 175.986 66.883,175.596 66.641,175.269 66.346 C 174.716 65.845,174.631 65.848,174.026 66.396 C 173.399 66.963,173.354 66.963,172.727 66.396 C 172.101 65.829,172.055 65.829,171.429 66.396 C 170.802 66.963,170.756 66.963,170.130 66.396 C 169.525 65.848,169.440 65.845,168.887 66.346 C 168.072 67.084,165.862 66.173,166.622 65.412 C 166.715 65.320,166.975 65.467,167.201 65.739 C 167.729 66.374,168.149 66.364,168.887 65.696 C 169.440 65.196,169.525 65.199,170.130 65.747 C 170.756 66.314,170.802 66.314,171.429 65.747 C 172.055 65.180,172.101 65.180,172.727 65.747 C 173.354 66.314,173.399 66.314,174.026 65.747 C 174.631 65.199,174.716 65.196,175.269 65.696 C 176.012 66.368,176.261 66.368,177.004 65.696 C 177.557 65.196,177.641 65.199,178.247 65.747 C 178.873 66.314,178.919 66.314,179.545 65.747 C 180.172 65.180,180.218 65.180,180.844 65.747 C 181.471 66.314,181.516 66.314,182.143 65.747 C 182.748 65.199,182.832 65.196,183.386 65.696 C 183.713 65.992,184.103 66.234,184.253 66.234 C 184.404 66.234,184.794 65.992,185.121 65.696 C 185.674 65.196,185.758 65.199,186.364 65.747 C 186.990 66.314,187.036 66.314,187.662 65.747 C 188.289 65.180,188.334 65.180,188.961 65.747 C 189.588 66.314,189.633 66.314,190.260 65.747 C 190.865 65.199,190.949 65.196,191.503 65.696 C 191.829 65.992,192.220 66.234,192.370 66.234 C 192.521 66.234,192.911 65.992,193.237 65.696 C 193.791 65.196,193.875 65.199,194.481 65.747 C 195.107 66.314,195.153 66.314,195.779 65.747 C 196.406 65.180,196.451 65.180,197.078 65.747 C 197.705 66.314,197.750 66.314,198.377 65.747 C 199.003 65.180,199.049 65.180,199.675 65.747 C 200.281 66.295,200.365 66.298,200.918 65.797 C 201.661 65.125,201.910 65.125,202.653 65.797 C 203.206 66.298,203.291 66.295,203.896 65.747 C 204.523 65.180,204.568 65.180,205.195 65.747 C 205.821 66.314,205.867 66.314,206.494 65.747 C 207.112 65.187,207.172 65.186,207.771 65.728 C 209.158 66.983,210.043 65.592,210.055 62.135 L 210.065 59.173 211.593 59.143 C 212.583 59.123,213.326 59.297,213.704 59.639 M114.675 60.455 C 114.129 61.001,114.190 62.196,114.796 62.801 C 115.498 63.504,115.807 63.445,116.435 62.487 C 117.410 60.999,115.888 59.241,114.675 60.455 M127.165 60.281 C 126.680 60.765,127.009 61.039,128.074 61.039 C 128.942 61.039,129.157 60.927,129.014 60.552 C 128.826 60.062,127.568 59.878,127.165 60.281 M158.347 60.268 C 157.865 60.750,158.153 61.039,159.118 61.039 C 159.774 61.039,160.073 60.899,159.985 60.633 C 159.834 60.173,158.696 59.919,158.347 60.268 M174.740 60.455 C 174.194 61.001,174.255 62.196,174.861 62.801 C 175.563 63.504,175.872 63.445,176.500 62.487 C 177.475 60.999,175.953 59.241,174.740 60.455 M201.178 60.561 C 200.544 62.214,201.675 63.887,202.797 62.956 C 203.654 62.245,203.255 60.247,202.233 60.129 C 201.678 60.064,201.311 60.215,201.178 60.561 M206.234 60.455 C 205.687 61.001,205.749 62.196,206.354 62.801 C 207.057 63.504,207.365 63.445,207.993 62.487 C 208.968 60.999,207.447 59.241,206.234 60.455 M211.375 60.693 C 210.904 61.574,210.956 62.208,211.549 62.801 C 212.623 63.875,213.760 62.261,213.115 60.579 C 212.841 59.866,211.781 59.935,211.375 60.693 M151.786 61.929 C 150.311 62.206,150.171 62.323,150.696 62.849 C 151.249 63.401,152.127 63.187,152.418 62.428 C 152.655 61.811,152.609 61.775,151.786 61.929 M163.312 63.474 C 163.312 63.742,163.093 63.961,162.825 63.961 C 162.557 63.961,162.338 63.742,162.338 63.474 C 162.338 63.206,162.557 62.987,162.825 62.987 C 163.093 62.987,163.312 63.206,163.312 63.474 M165.909 63.474 C 165.909 63.742,165.690 63.961,165.422 63.961 C 165.154 63.961,164.935 63.742,164.935 63.474 C 164.935 63.206,165.154 62.987,165.422 62.987 C 165.690 62.987,165.909 63.206,165.909 63.474 M105.575 65.797 C 106.129 66.298,106.213 66.295,106.818 65.747 C 107.445 65.180,107.490 65.180,108.117 65.747 C 108.744 66.314,108.789 66.314,109.416 65.747 C 110.042 65.180,110.088 65.180,110.714 65.747 C 111.320 66.295,111.404 66.298,111.957 65.797 C 112.284 65.502,112.674 65.260,112.825 65.260 C 112.975 65.260,113.365 65.502,113.692 65.797 C 114.245 66.298,114.330 66.295,114.935 65.747 C 115.562 65.180,115.607 65.180,116.234 65.747 C 116.860 66.314,116.906 66.314,117.532 65.747 C 118.159 65.180,118.205 65.180,118.831 65.747 C 119.436 66.295,119.521 66.298,120.074 65.797 C 120.401 65.502,120.791 65.260,120.942 65.260 C 121.092 65.260,121.482 65.502,121.809 65.797 C 122.362 66.298,122.447 66.295,123.052 65.747 C 123.679 65.180,123.724 65.180,124.351 65.747 C 124.977 66.314,125.023 66.314,125.649 65.747 C 126.276 65.180,126.321 65.180,126.948 65.747 C 127.553 66.295,127.638 66.298,128.191 65.797 C 128.518 65.502,128.908 65.260,129.058 65.260 C 129.209 65.260,129.599 65.502,129.926 65.797 C 130.479 66.298,130.564 66.295,131.169 65.747 C 131.795 65.180,131.841 65.180,132.468 65.747 C 133.094 66.314,133.140 66.314,133.766 65.747 C 134.393 65.180,134.438 65.180,135.065 65.747 C 135.692 66.314,135.737 66.314,136.364 65.747 C 136.969 65.199,137.053 65.196,137.607 65.696 C 138.349 66.368,138.599 66.368,139.341 65.696 C 139.895 65.196,139.979 65.199,140.584 65.747 C 141.211 66.314,141.256 66.314,141.883 65.747 C 142.510 65.180,142.555 65.180,143.182 65.747 C 143.808 66.314,143.854 66.314,144.481 65.747 C 145.086 65.199,145.170 65.196,145.724 65.696 C 146.050 65.992,146.440 66.234,146.591 66.234 C 146.741 66.234,147.132 65.992,147.458 65.696 C 148.012 65.196,148.096 65.199,148.701 65.747 C 149.328 66.314,149.373 66.314,150.000 65.747 C 150.627 65.180,150.672 65.180,151.299 65.747 C 151.925 66.314,151.971 66.314,152.597 65.747 C 153.203 65.199,153.287 65.196,153.841 65.696 C 154.167 65.992,154.557 66.234,154.708 66.234 C 154.858 66.234,155.249 65.992,155.575 65.696 C 156.129 65.196,156.213 65.199,156.818 65.747 C 157.445 66.314,157.490 66.314,158.117 65.747 C 158.744 65.180,158.789 65.180,159.416 65.747 C 160.042 66.314,160.088 66.314,160.716 65.745 C 161.673 64.879,161.827 65.341,160.879 66.232 C 160.095 66.968,160.053 66.973,159.419 66.399 C 158.789 65.829,158.744 65.829,158.117 66.396 C 157.490 66.963,157.445 66.963,156.818 66.396 C 156.213 65.848,156.129 65.845,155.575 66.346 C 155.249 66.641,154.858 66.883,154.708 66.883 C 154.557 66.883,154.167 66.641,153.841 66.346 C 153.287 65.845,153.203 65.848,152.597 66.396 C 151.971 66.963,151.925 66.963,151.299 66.396 C 150.672 65.829,150.627 65.829,150.000 66.396 C 149.373 66.963,149.328 66.963,148.701 66.396 C 148.096 65.848,148.012 65.845,147.458 66.346 C 147.132 66.641,146.741 66.883,146.591 66.883 C 146.440 66.883,146.050 66.641,145.724 66.346 C 145.170 65.845,145.086 65.848,144.481 66.396 C 143.854 66.963,143.808 66.963,143.182 66.396 C 142.555 65.829,142.510 65.829,141.883 66.396 C 141.256 66.963,141.211 66.963,140.584 66.396 C 139.979 65.848,139.895 65.845,139.341 66.346 C 138.599 67.018,138.349 67.018,137.607 66.346 C 137.053 65.845,136.969 65.848,136.364 66.396 C 135.737 66.963,135.692 66.963,135.065 66.396 C 134.438 65.829,134.393 65.829,133.766 66.396 C 133.140 66.963,133.094 66.963,132.468 66.396 C 131.841 65.829,131.795 65.829,131.169 66.396 C 130.564 66.944,130.479 66.947,129.926 66.446 C 129.183 65.774,128.934 65.774,128.191 66.446 C 127.638 66.947,127.553 66.944,126.948 66.396 C 126.321 65.829,126.276 65.829,125.649 66.396 C 125.023 66.963,124.977 66.963,124.351 66.396 C 123.724 65.829,123.679 65.829,123.052 66.396 C 122.447 66.944,122.362 66.947,121.809 66.446 C 121.482 66.151,121.092 65.909,120.942 65.909 C 120.791 65.909,120.401 66.151,120.074 66.446 C 119.521 66.947,119.436 66.944,118.831 66.396 C 118.205 65.829,118.159 65.829,117.532 66.396 C 116.906 66.963,116.860 66.963,116.234 66.396 C 115.607 65.829,115.562 65.829,114.935 66.396 C 114.330 66.944,114.245 66.947,113.692 66.446 C 113.365 66.151,112.975 65.909,112.825 65.909 C 112.674 65.909,112.284 66.151,111.957 66.446 C 111.404 66.947,111.320 66.944,110.714 66.396 C 110.088 65.829,110.042 65.829,109.416 66.396 C 108.789 66.963,108.744 66.963,108.117 66.396 C 107.490 65.829,107.445 65.829,106.806 66.407 C 106.159 66.993,106.125 66.986,105.271 66.133 C 104.332 65.193,104.591 64.907,105.575 65.797 M62.013 89.773 L 62.013 105.519 98.377 105.519 L 134.740 105.519 134.740 89.773 L 134.740 74.026 98.377 74.026 L 62.013 74.026 62.013 89.773 M81.246 85.406 C 83.325 85.983,83.846 88.312,82.199 89.667 L 81.282 90.422 82.524 92.247 C 84.008 94.427,84.016 94.481,82.862 94.481 C 82.204 94.481,81.803 94.218,81.389 93.517 C 79.233 89.868,77.273 89.399,77.273 92.532 C 77.273 94.394,77.237 94.481,76.461 94.481 L 75.649 94.481 75.649 89.773 L 75.649 85.065 77.841 85.067 C 79.046 85.068,80.579 85.220,81.246 85.406 M107.084 85.958 C 107.169 86.553,107.033 86.688,106.354 86.688 C 105.674 86.688,105.519 86.534,105.519 85.854 C 105.519 84.744,106.925 84.837,107.084 85.958 M77.273 87.987 C 77.273 89.423,78.692 89.809,80.667 88.909 C 82.485 88.080,81.436 86.688,78.994 86.688 L 77.273 86.688 77.273 87.987 M86.039 90.248 C 86.039 93.185,86.566 93.946,87.937 92.986 C 88.547 92.559,88.636 92.185,88.636 90.079 C 88.636 87.718,88.655 87.662,89.448 87.662 L 90.260 87.662 90.260 91.082 L 90.260 94.501 89.205 94.514 C 88.624 94.521,87.579 94.541,86.882 94.559 C 84.918 94.607,84.416 93.757,84.416 90.386 C 84.416 87.697,84.426 87.662,85.227 87.662 C 86.025 87.662,86.039 87.706,86.039 90.248 M92.857 88.052 C 92.857 88.355,92.944 88.355,93.247 88.052 C 93.892 87.407,95.926 87.577,96.611 88.333 C 97.605 89.432,97.525 94.278,96.510 94.422 C 95.812 94.521,95.779 94.424,95.779 92.257 C 95.779 89.504,95.597 88.961,94.673 88.961 C 93.480 88.961,93.182 89.590,93.182 92.110 C 93.182 94.422,93.162 94.481,92.370 94.481 L 91.558 94.481 91.558 91.071 C 91.558 87.879,91.600 87.662,92.208 87.662 C 92.565 87.662,92.857 87.838,92.857 88.052 M103.720 88.391 C 104.614 89.667,104.428 94.555,103.490 94.422 C 102.818 94.327,102.747 94.110,102.597 91.721 C 102.325 87.359,100.000 87.850,100.000 92.270 C 100.000 94.264,99.936 94.481,99.351 94.481 C 98.743 94.481,98.701 94.264,98.701 91.120 L 98.701 87.760 100.961 87.718 C 102.946 87.682,103.281 87.763,103.720 88.391 M107.073 91.153 L 107.166 94.481 106.343 94.481 L 105.519 94.481 105.519 91.049 C 105.519 87.676,105.532 87.619,106.250 87.721 C 106.946 87.820,106.985 87.981,107.073 91.153 M113.379 88.210 C 114.301 89.045,114.243 94.481,113.312 94.481 C 112.721 94.481,112.662 94.264,112.662 92.085 C 112.662 89.436,112.262 88.747,110.920 89.084 C 110.003 89.314,109.751 90.071,109.745 92.614 C 109.741 94.263,109.664 94.481,109.091 94.481 C 108.483 94.481,108.442 94.264,108.442 91.119 L 108.442 87.758 110.619 87.721 C 112.212 87.694,112.954 87.825,113.379 88.210 M119.416 88.052 C 119.719 88.355,119.805 88.355,119.805 88.052 C 119.805 87.838,120.097 87.662,120.455 87.662 C 121.183 87.662,121.449 93.854,120.795 95.576 C 119.961 97.769,115.260 97.623,115.260 95.404 C 115.260 94.674,116.404 94.584,116.676 95.292 C 116.935 95.967,119.022 95.946,119.283 95.266 C 119.622 94.383,119.518 94.311,118.072 94.426 C 115.225 94.652,113.804 90.715,115.919 88.463 C 116.746 87.583,118.715 87.351,119.416 88.052 M116.948 89.351 C 116.443 89.855,116.443 92.288,116.948 92.792 C 118.077 93.921,119.481 92.968,119.481 91.071 C 119.481 89.593,119.043 88.961,118.019 88.961 C 117.644 88.961,117.162 89.136,116.948 89.351 M135.390 98.377 L 135.390 106.494 117.045 106.494 L 98.701 106.494 98.701 116.453 L 98.701 126.412 99.453 125.706 C 100.659 124.573,100.690 124.846,99.667 127.620 C 99.136 129.060,98.701 130.375,98.701 130.542 C 98.701 130.725,105.928 130.844,117.045 130.844 L 135.390 130.844 135.390 147.565 L 135.390 164.286 117.045 164.286 L 98.701 164.286 98.701 174.411 L 98.701 184.537 99.700 183.583 L 100.698 182.630 99.700 185.371 C 99.151 186.878,98.701 188.228,98.701 188.371 C 98.701 188.514,106.920 188.669,116.964 188.715 L 135.227 188.799 135.314 196.997 C 135.362 201.506,135.467 205.195,135.548 205.195 C 135.629 205.195,136.897 204.756,138.364 204.221 C 139.832 203.685,141.179 203.247,141.357 203.247 C 141.534 203.247,141.260 203.685,140.747 204.221 L 139.814 205.195 152.212 205.195 L 164.610 205.195 164.610 147.727 L 164.610 90.260 150.000 90.260 L 135.390 90.260 135.390 98.377 M65.260 115.305 C 65.260 115.509,65.004 115.883,64.692 116.137 C 64.278 116.473,64.234 116.645,64.529 116.768 C 65.002 116.965,65.082 117.857,64.627 117.857 C 64.457 117.857,64.274 118.696,64.221 119.721 C 64.072 122.567,62.987 122.662,62.987 119.829 C 62.987 118.731,62.843 117.857,62.662 117.857 C 62.484 117.857,62.338 117.638,62.338 117.370 C 62.338 117.102,62.484 116.883,62.662 116.883 C 62.841 116.883,62.987 116.674,62.987 116.419 C 62.987 116.164,63.217 115.726,63.497 115.445 C 64.088 114.855,65.260 114.761,65.260 115.305 M91.062 115.503 C 90.287 117.331,89.964 118.455,89.964 119.318 C 89.964 120.181,90.287 121.305,91.062 123.133 C 91.603 124.408,90.287 123.637,89.639 122.300 C 88.549 120.047,88.832 117.230,90.340 115.341 C 90.825 114.733,91.340 114.849,91.062 115.503 M93.303 116.006 C 94.312 117.357,94.414 120.365,93.515 122.222 C 92.493 124.335,91.749 124.219,92.564 122.074 C 93.349 120.009,93.337 118.394,92.525 116.604 C 91.603 114.571,92.002 114.264,93.303 116.006 M62.013 118.506 C 62.013 121.537,61.970 121.753,61.364 121.753 C 60.758 121.753,60.714 121.537,60.714 118.506 C 60.714 115.476,60.758 115.260,61.364 115.260 C 61.970 115.260,62.013 115.476,62.013 118.506 M73.377 118.506 C 73.377 121.176,73.290 121.753,72.890 121.753 C 72.489 121.753,72.403 121.176,72.403 118.506 C 72.403 115.837,72.489 115.260,72.890 115.260 C 73.290 115.260,73.377 115.837,73.377 118.506 M54.481 117.273 C 55.022 117.814,54.968 118.506,54.383 118.506 C 54.115 118.506,53.896 118.360,53.896 118.182 C 53.896 118.003,53.531 117.857,53.084 117.857 C 51.958 117.857,52.065 118.481,53.230 118.714 C 54.679 119.004,55.388 119.934,54.929 120.943 C 54.262 122.405,50.974 121.948,50.974 120.392 C 50.974 119.947,51.967 120.103,52.496 120.631 C 53.058 121.194,53.734 121.106,53.734 120.470 C 53.734 120.241,53.222 119.887,52.597 119.685 C 51.365 119.287,50.924 118.213,51.638 117.352 C 52.110 116.784,53.941 116.733,54.481 117.273 M59.560 117.605 C 60.609 119.104,60.253 119.805,58.442 119.805 C 56.787 119.805,56.370 120.172,57.380 120.737 C 57.779 120.960,58.202 120.898,58.832 120.527 C 59.831 119.936,60.381 120.206,59.860 121.031 C 58.542 123.122,54.878 121.002,55.722 118.637 C 56.377 116.803,58.583 116.210,59.560 117.605 M71.547 117.598 C 72.038 118.382,71.567 118.690,70.638 118.193 C 69.492 117.580,68.831 117.964,68.831 119.243 C 68.831 121.026,69.686 121.553,70.742 120.420 C 71.528 119.576,72.244 119.863,71.733 120.817 C 70.519 123.086,67.138 121.344,67.765 118.772 C 68.210 116.947,70.662 116.186,71.547 117.598 M78.067 117.513 C 78.739 118.256,78.821 120.250,78.209 120.987 C 76.615 122.908,73.466 121.171,74.197 118.774 C 74.769 116.899,76.887 116.209,78.067 117.513 M82.403 117.273 C 82.944 117.814,82.890 118.506,82.305 118.506 C 82.037 118.506,81.818 118.360,81.818 118.182 C 81.818 118.003,81.453 117.857,81.006 117.857 C 79.748 117.857,80.048 118.398,81.575 118.882 C 82.793 119.267,82.955 119.432,82.955 120.288 C 82.955 121.613,81.601 122.321,80.280 121.687 C 79.285 121.211,78.872 120.130,79.684 120.130 C 79.965 120.130,80.195 120.260,80.195 120.420 C 80.195 120.830,81.078 121.118,81.656 120.897 C 82.363 120.625,82.253 120.204,81.412 119.969 C 78.620 119.187,78.317 116.883,81.006 116.883 C 81.560 116.883,82.188 117.058,82.403 117.273 M87.442 117.469 C 88.674 118.830,88.313 119.628,86.384 119.805 C 84.685 119.961,84.640 119.990,85.203 120.549 C 85.737 121.080,85.854 121.087,86.551 120.630 C 87.880 119.760,88.675 120.453,87.483 121.443 C 86.034 122.645,83.766 121.462,83.766 119.502 C 83.766 117.183,86.044 115.923,87.442 117.469 M57.035 118.074 C 56.551 118.558,56.879 118.831,57.944 118.831 C 58.812 118.831,59.028 118.719,58.884 118.344 C 58.696 117.854,57.438 117.670,57.035 118.074 M75.541 118.074 C 75.143 118.472,75.319 120.370,75.791 120.762 C 76.891 121.675,78.023 119.993,77.400 118.371 C 77.204 117.860,75.954 117.660,75.541 118.074 M84.954 118.327 C 84.802 118.725,85.004 118.831,85.914 118.831 C 86.691 118.831,87.024 118.699,86.934 118.425 C 86.731 117.808,85.183 117.731,84.954 118.327 M66.883 121.266 C 66.883 121.537,66.595 121.753,66.234 121.753 C 65.873 121.753,65.584 121.537,65.584 121.266 C 65.584 120.996,65.873 120.779,66.234 120.779 C 66.595 120.779,66.883 120.996,66.883 121.266 M226.582 126.333 C 227.786 126.753,228.546 127.861,227.903 128.259 C 227.650 128.415,227.286 128.258,226.957 127.852 C 225.779 126.398,223.377 127.510,223.377 129.509 C 223.377 131.332,224.951 132.315,226.759 131.621 C 227.588 131.303,227.349 130.571,226.380 130.460 C 224.891 130.289,225.259 129.400,226.867 129.283 L 228.247 129.183 228.247 130.652 C 228.247 133.848,223.337 133.765,222.374 130.553 C 221.537 127.758,223.892 125.395,226.582 126.333 M233.782 126.469 C 234.309 126.742,234.740 127.022,234.740 127.092 C 234.740 127.162,234.829 127.451,234.937 127.733 C 235.205 128.430,234.126 128.419,233.614 127.719 C 232.063 125.597,229.553 128.756,230.856 131.190 C 231.327 132.072,233.291 132.057,233.766 131.169 C 234.148 130.455,235.071 130.280,235.055 130.925 C 234.998 133.162,230.801 133.608,229.708 131.495 C 228.053 128.293,230.787 124.920,233.782 126.469 M175.000 129.545 C 175.000 132.215,174.913 132.792,174.513 132.792 C 174.123 132.792,174.026 132.304,174.026 130.350 L 174.026 127.907 173.214 128.439 C 172.024 129.219,172.088 128.168,173.295 127.105 C 174.841 125.745,175.000 125.973,175.000 129.545 M183.117 128.409 C 183.453 130.191,184.091 131.340,184.091 130.164 C 184.091 126.596,186.147 125.275,186.988 128.303 C 187.687 130.815,187.830 130.842,188.316 128.550 C 188.687 126.802,189.310 125.890,189.799 126.380 C 189.888 126.468,189.570 127.947,189.093 129.666 C 187.979 133.683,187.352 133.891,186.526 130.519 C 186.220 129.269,185.871 128.247,185.751 128.247 C 185.631 128.247,185.270 129.269,184.948 130.519 C 184.484 132.320,184.236 132.792,183.752 132.792 C 183.140 132.792,183.058 132.590,182.102 128.734 C 181.924 128.019,181.705 127.179,181.615 126.867 C 181.498 126.463,181.634 126.299,182.084 126.299 C 182.608 126.299,182.788 126.668,183.117 128.409 M199.351 127.983 L 199.351 129.667 200.261 128.795 C 201.607 127.505,202.714 127.588,201.471 128.885 L 200.549 129.848 201.411 131.151 C 202.431 132.693,202.448 132.792,201.693 132.792 C 201.375 132.792,200.855 132.354,200.539 131.818 C 200.222 131.282,199.825 130.844,199.657 130.844 C 199.488 130.844,199.351 131.282,199.351 131.818 C 199.351 132.468,199.188 132.792,198.864 132.792 C 198.463 132.792,198.377 132.215,198.377 129.545 C 198.377 126.876,198.463 126.299,198.864 126.299 C 199.234 126.299,199.351 126.702,199.351 127.983 M214.286 126.786 C 214.286 127.054,214.067 127.273,213.799 127.273 C 213.531 127.273,213.312 127.054,213.312 126.786 C 213.312 126.518,213.531 126.299,213.799 126.299 C 214.067 126.299,214.286 126.518,214.286 126.786 M244.805 129.542 C 244.805 133.138,245.051 132.784,242.532 132.813 C 240.848 132.831,239.972 130.240,241.111 128.613 C 241.527 128.020,241.871 127.887,242.735 127.988 C 243.750 128.107,243.831 128.049,243.831 127.208 C 243.831 126.616,244.001 126.299,244.318 126.299 C 244.719 126.299,244.805 126.875,244.805 129.542 M193.976 128.552 C 194.648 129.295,194.730 131.289,194.118 132.026 C 192.524 133.947,189.375 132.210,190.106 129.813 C 190.678 127.938,192.796 127.248,193.976 128.552 M197.988 128.501 C 197.929 128.807,197.591 129.058,197.236 129.058 C 196.679 129.058,196.578 129.312,196.494 130.925 C 196.327 134.111,195.130 133.648,195.130 130.398 L 195.130 128.004 196.613 127.975 C 197.846 127.950,198.077 128.038,197.988 128.501 M206.039 128.171 C 206.517 128.490,207.143 129.708,207.143 130.320 C 207.143 130.690,206.687 130.836,205.297 130.909 C 203.537 131.002,203.477 131.033,204.021 131.575 C 204.724 132.275,205.007 132.285,205.659 131.632 C 206.548 130.744,207.353 131.166,206.582 132.116 C 205.174 133.851,202.597 132.690,202.597 130.321 C 202.597 128.516,204.642 127.238,206.039 128.171 M210.457 128.127 C 210.872 128.382,210.346 129.184,209.880 129.005 C 209.320 128.790,208.766 130.117,208.766 131.677 C 208.766 132.452,208.618 132.792,208.279 132.792 C 207.890 132.792,207.792 132.309,207.792 130.390 L 207.792 127.987 209.010 127.986 C 209.679 127.986,210.330 128.049,210.457 128.127 M214.286 130.357 C 214.286 132.305,214.188 132.792,213.799 132.792 C 213.409 132.792,213.312 132.305,213.312 130.357 C 213.312 128.409,213.409 127.922,213.799 127.922 C 214.188 127.922,214.286 128.409,214.286 130.357 M218.442 128.312 C 218.983 128.853,218.929 129.545,218.344 129.545 C 218.076 129.545,217.857 129.399,217.857 129.221 C 217.857 129.042,217.492 128.896,217.045 128.896 C 215.919 128.896,216.026 129.520,217.191 129.753 C 218.640 130.043,219.349 130.973,218.890 131.982 C 218.223 133.444,214.935 132.987,214.935 131.431 C 214.935 130.986,215.928 131.141,216.457 131.670 C 217.019 132.233,217.695 132.145,217.695 131.509 C 217.695 131.280,217.183 130.926,216.558 130.724 C 215.326 130.326,214.885 129.252,215.599 128.391 C 216.071 127.823,217.902 127.772,218.442 128.312 M239.390 128.508 C 240.622 129.869,240.261 130.667,238.332 130.844 C 236.633 131.000,236.588 131.029,237.151 131.588 C 237.685 132.119,237.802 132.126,238.499 131.669 C 239.828 130.799,240.623 131.492,239.431 132.482 C 237.982 133.684,235.714 132.501,235.714 130.541 C 235.714 128.222,237.992 126.962,239.390 128.508 M191.450 129.113 C 191.052 129.511,191.228 131.409,191.700 131.801 C 192.800 132.714,193.932 131.032,193.309 129.410 C 193.113 128.899,191.864 128.699,191.450 129.113 M204.126 129.099 C 203.644 129.581,203.933 129.870,204.897 129.870 C 205.553 129.870,205.852 129.730,205.765 129.464 C 205.613 129.004,204.475 128.750,204.126 129.099 M236.902 129.366 C 236.750 129.764,236.952 129.870,237.862 129.870 C 238.639 129.870,238.972 129.738,238.882 129.464 C 238.679 128.847,237.131 128.770,236.902 129.366 M241.958 129.276 C 241.408 129.826,241.457 131.021,242.055 131.619 C 242.706 132.270,243.460 131.953,243.719 130.920 C 244.073 129.510,242.858 128.376,241.958 129.276 M62.013 147.727 L 62.013 163.636 98.377 163.636 L 134.740 163.636 134.740 147.727 L 134.740 131.818 98.377 131.818 L 62.013 131.818 62.013 147.727 M178.247 132.305 C 178.247 132.573,178.028 132.792,177.760 132.792 C 177.492 132.792,177.273 132.573,177.273 132.305 C 177.273 132.037,177.492 131.818,177.760 131.818 C 178.028 131.818,178.247 132.037,178.247 132.305 M252.597 136.811 C 252.597 136.878,252.366 137.487,252.083 138.164 C 251.412 139.772,251.408 142.372,252.074 143.962 C 252.653 145.343,252.558 145.771,251.811 145.151 C 250.234 143.842,249.955 139.998,251.282 137.851 C 251.878 136.887,252.597 136.318,252.597 136.811 M254.857 138.033 C 255.849 139.798,255.870 142.196,254.910 144.078 C 253.934 145.991,253.036 145.988,253.905 144.075 C 254.658 142.415,254.724 140.016,254.058 138.424 C 253.148 136.246,253.700 135.975,254.857 138.033 M175.650 137.501 C 176.431 138.442,176.111 139.609,174.669 141.078 L 173.283 142.491 174.684 142.593 C 177.162 142.773,176.655 143.506,174.053 143.506 C 171.184 143.506,171.087 143.116,173.401 140.885 C 175.224 139.128,175.398 138.215,173.942 138.047 C 173.307 137.973,173.052 138.089,173.052 138.452 C 173.052 138.745,172.776 138.961,172.403 138.961 C 171.621 138.961,171.589 138.690,172.259 137.735 C 172.864 136.870,175.004 136.722,175.650 137.501 M183.117 139.123 C 183.453 140.905,184.091 142.054,184.091 140.878 C 184.091 137.310,186.147 135.989,186.988 139.017 C 187.687 141.529,187.830 141.556,188.316 139.264 C 188.687 137.516,189.310 136.604,189.799 137.094 C 189.888 137.182,189.570 138.662,189.093 140.381 C 187.979 144.397,187.352 144.605,186.526 141.234 C 186.220 139.984,185.871 138.961,185.751 138.961 C 185.631 138.961,185.270 139.984,184.948 141.234 C 184.484 143.034,184.236 143.506,183.752 143.506 C 183.140 143.506,183.058 143.304,182.102 139.448 C 181.924 138.734,181.705 137.894,181.615 137.581 C 181.498 137.178,181.634 137.013,182.084 137.013 C 182.608 137.013,182.788 137.382,183.117 139.123 M199.351 138.697 L 199.351 140.381 200.261 139.509 C 201.607 138.219,202.714 138.302,201.471 139.600 L 200.549 140.563 201.411 141.865 C 202.431 143.408,202.448 143.506,201.693 143.506 C 201.375 143.506,200.855 143.068,200.539 142.532 C 200.222 141.997,199.825 141.558,199.657 141.558 C 199.488 141.558,199.351 141.997,199.351 142.532 C 199.351 143.182,199.188 143.506,198.864 143.506 C 198.463 143.506,198.377 142.929,198.377 140.260 C 198.377 137.590,198.463 137.013,198.864 137.013 C 199.234 137.013,199.351 137.417,199.351 138.697 M214.561 138.844 C 215.057 139.210,215.055 139.256,214.529 139.460 C 213.781 139.749,213.715 142.369,214.448 142.650 C 215.281 142.970,214.983 143.555,214.042 143.447 C 213.197 143.350,213.144 143.245,213.052 141.477 C 212.998 140.450,212.816 139.610,212.646 139.610 C 212.476 139.610,212.338 139.391,212.338 139.123 C 212.338 138.856,212.484 138.636,212.662 138.636 C 212.841 138.636,212.987 138.356,212.987 138.014 C 212.987 137.156,213.772 136.958,213.911 137.781 C 213.973 138.148,214.266 138.627,214.561 138.844 M231.818 137.500 C 231.818 137.768,231.599 137.987,231.331 137.987 C 231.063 137.987,230.844 137.768,230.844 137.500 C 230.844 137.232,231.063 137.013,231.331 137.013 C 231.599 137.013,231.818 137.232,231.818 137.500 M244.156 138.006 C 244.156 138.353,244.302 138.636,244.481 138.636 C 244.659 138.636,244.805 138.856,244.805 139.123 C 244.805 139.391,244.659 139.610,244.481 139.610 C 244.302 139.610,244.156 140.268,244.156 141.071 C 244.156 141.875,244.302 142.532,244.481 142.532 C 244.659 142.532,244.805 142.752,244.805 143.019 C 244.805 143.721,243.270 143.650,243.049 142.938 C 242.643 141.635,242.702 138.078,243.138 137.553 C 243.667 136.916,244.156 137.133,244.156 138.006 M259.740 137.500 C 259.740 137.768,259.521 137.987,259.253 137.987 C 258.985 137.987,258.766 137.768,258.766 137.500 C 258.766 137.232,258.985 137.013,259.253 137.013 C 259.521 137.013,259.740 137.232,259.740 137.500 M278.247 140.260 C 278.247 142.929,278.160 143.506,277.760 143.506 C 277.359 143.506,277.273 142.929,277.273 140.260 C 277.273 137.590,277.359 137.013,277.760 137.013 C 278.160 137.013,278.247 137.590,278.247 140.260 M280.519 140.260 C 280.519 143.290,280.476 143.506,279.870 143.506 C 279.264 143.506,279.221 143.290,279.221 140.260 C 279.221 137.229,279.264 137.013,279.870 137.013 C 280.476 137.013,280.519 137.229,280.519 140.260 M290.260 140.224 L 290.260 143.435 289.141 143.566 C 287.598 143.746,286.740 143.359,286.337 142.301 C 285.575 140.297,286.737 138.384,288.510 138.723 C 289.182 138.851,289.286 138.746,289.286 137.942 C 289.286 137.333,289.453 137.013,289.773 137.013 C 290.173 137.013,290.260 137.586,290.260 140.224 M193.976 139.266 C 194.648 140.009,194.730 142.003,194.118 142.740 C 192.524 144.661,189.375 142.925,190.106 140.527 C 190.678 138.653,192.796 137.962,193.976 139.266 M197.988 139.215 C 197.929 139.521,197.591 139.772,197.236 139.772 C 196.679 139.773,196.578 140.026,196.494 141.640 C 196.327 144.825,195.130 144.363,195.130 141.113 L 195.130 138.719 196.613 138.689 C 197.846 138.664,198.077 138.753,197.988 139.215 M206.039 138.885 C 206.517 139.204,207.143 140.423,207.143 141.034 C 207.143 141.405,206.687 141.550,205.297 141.623 C 203.537 141.716,203.477 141.748,204.021 142.289 C 204.724 142.989,205.007 142.999,205.659 142.346 C 206.548 141.458,207.353 141.880,206.582 142.830 C 205.174 144.565,202.597 143.404,202.597 141.035 C 202.597 139.230,204.642 137.952,206.039 138.885 M210.457 138.841 C 210.872 139.096,210.346 139.898,209.880 139.719 C 209.320 139.504,208.766 140.831,208.766 142.391 C 208.766 143.166,208.618 143.506,208.279 143.506 C 207.890 143.506,207.792 143.023,207.792 141.104 L 207.792 138.701 209.010 138.701 C 209.679 138.700,210.330 138.763,210.457 138.841 M218.975 139.358 C 220.025 140.857,219.669 141.558,217.857 141.558 C 216.203 141.558,215.786 141.925,216.796 142.490 C 217.194 142.713,217.618 142.651,218.247 142.280 C 219.247 141.689,219.797 141.959,219.276 142.784 C 217.957 144.875,214.294 142.756,215.138 140.390 C 215.793 138.557,217.998 137.963,218.975 139.358 M222.990 139.204 C 222.930 139.517,222.592 139.772,222.236 139.772 C 221.679 139.773,221.578 140.026,221.494 141.640 C 221.334 144.690,220.455 144.209,220.455 141.071 L 220.455 138.636 221.777 138.636 C 222.861 138.636,223.080 138.739,222.990 139.204 M229.464 139.044 C 230.075 139.527,230.017 143.506,229.399 143.506 C 229.054 143.506,228.903 143.009,228.831 141.640 C 228.747 140.022,228.647 139.773,228.084 139.773 C 227.522 139.773,227.422 140.022,227.338 141.640 C 227.188 144.507,225.974 144.434,225.974 141.558 C 225.974 139.864,225.894 139.610,225.359 139.610 C 224.600 139.610,224.351 140.219,224.351 142.072 C 224.351 143.131,224.223 143.506,223.864 143.506 C 223.475 143.506,223.377 143.024,223.377 141.108 L 223.377 138.710 226.218 138.716 C 227.780 138.720,229.241 138.867,229.464 139.044 M231.818 141.071 C 231.818 143.019,231.721 143.506,231.331 143.506 C 230.942 143.506,230.844 143.019,230.844 141.071 C 230.844 139.123,230.942 138.636,231.331 138.636 C 231.721 138.636,231.818 139.123,231.818 141.071 M236.347 138.948 C 237.205 139.483,237.253 143.506,236.401 143.506 C 235.778 143.506,235.714 143.326,235.714 141.558 C 235.714 139.819,235.644 139.610,235.057 139.610 C 234.290 139.610,233.766 140.739,233.766 142.391 C 233.766 143.166,233.618 143.506,233.279 143.506 C 232.890 143.506,232.792 143.024,232.792 141.114 L 232.792 138.721 234.334 138.688 C 235.183 138.670,236.088 138.787,236.347 138.948 M241.453 139.042 C 241.594 139.265,241.788 140.355,241.884 141.465 L 242.058 143.481 241.048 143.443 C 240.492 143.422,239.880 143.502,239.689 143.620 C 238.917 144.097,237.662 143.235,237.662 142.227 C 237.662 141.152,238.385 140.584,239.751 140.584 C 240.275 140.584,240.584 140.404,240.584 140.097 C 240.584 139.510,239.520 139.458,238.647 140.004 C 237.769 140.552,237.436 140.074,238.148 139.288 C 238.820 138.544,241.033 138.380,241.453 139.042 M248.572 138.885 C 249.049 139.204,249.675 140.423,249.675 141.034 C 249.675 141.405,249.219 141.550,247.829 141.623 C 246.070 141.716,246.010 141.748,246.554 142.289 C 247.257 142.989,247.539 142.999,248.192 142.346 C 249.080 141.458,249.885 141.880,249.114 142.830 C 247.707 144.565,245.130 143.404,245.130 141.035 C 245.130 139.230,247.175 137.952,248.572 138.885 M259.740 141.071 C 259.740 143.019,259.643 143.506,259.253 143.506 C 258.864 143.506,258.766 143.019,258.766 141.071 C 258.766 139.123,258.864 138.636,259.253 138.636 C 259.643 138.636,259.740 139.123,259.740 141.071 M263.896 139.026 C 264.438 139.568,264.383 140.260,263.799 140.260 C 263.531 140.260,263.312 140.114,263.312 139.935 C 263.312 139.756,262.946 139.610,262.500 139.610 C 261.241 139.610,261.541 140.152,263.068 140.635 C 264.286 141.020,264.448 141.185,264.448 142.041 C 264.448 143.366,263.095 144.074,261.773 143.441 C 260.779 142.964,260.365 141.883,261.177 141.883 C 261.458 141.883,261.688 142.014,261.688 142.173 C 261.688 142.584,262.571 142.872,263.149 142.650 C 263.857 142.378,263.746 141.958,262.906 141.722 C 260.114 140.940,259.811 138.636,262.500 138.636 C 263.054 138.636,263.682 138.812,263.896 139.026 M271.243 139.147 C 272.215 140.119,271.692 140.633,270.493 139.884 C 269.534 139.285,268.831 139.766,268.831 141.021 C 268.831 142.590,269.681 143.244,270.463 142.278 C 271.213 141.352,271.827 141.355,271.695 142.286 C 271.444 144.046,268.504 144.072,267.838 142.320 C 266.892 139.832,269.499 137.403,271.243 139.147 M275.896 139.042 C 276.730 140.080,276.556 143.471,275.669 143.467 C 275.212 143.466,274.436 143.492,273.946 143.526 C 272.188 143.648,271.434 142.046,272.800 141.090 C 273.196 140.812,273.927 140.584,274.423 140.584 C 275.008 140.584,275.325 140.413,275.325 140.097 C 275.325 139.773,275.000 139.610,274.351 139.610 C 273.815 139.610,273.377 139.756,273.377 139.935 C 273.377 140.114,273.157 140.260,272.890 140.260 C 272.220 140.260,272.276 139.392,272.971 138.987 C 273.766 138.524,275.506 138.557,275.896 139.042 M284.610 138.885 C 285.088 139.204,285.714 140.423,285.714 141.034 C 285.714 141.405,285.258 141.550,283.868 141.623 C 282.109 141.716,282.049 141.748,282.593 142.289 C 283.296 142.989,283.578 142.999,284.231 142.346 C 285.119 141.458,285.924 141.880,285.153 142.830 C 283.746 144.565,281.169 143.404,281.169 141.035 C 281.169 139.230,283.214 137.952,284.610 138.885 M191.450 139.827 C 191.052 140.225,191.228 142.124,191.700 142.515 C 192.800 143.428,193.932 141.746,193.309 140.124 C 193.113 139.613,191.864 139.414,191.450 139.827 M204.126 139.813 C 203.644 140.296,203.933 140.584,204.897 140.584 C 205.553 140.584,205.852 140.444,205.765 140.179 C 205.613 139.718,204.475 139.464,204.126 139.813 M216.450 139.827 C 215.966 140.311,216.295 140.584,217.360 140.584 C 218.228 140.584,218.443 140.473,218.299 140.097 C 218.111 139.608,216.854 139.424,216.450 139.827 M246.659 139.813 C 246.176 140.296,246.465 140.584,247.430 140.584 C 248.085 140.584,248.385 140.444,248.297 140.179 C 248.145 139.718,247.007 139.464,246.659 139.813 M282.698 139.813 C 282.215 140.296,282.504 140.584,283.469 140.584 C 284.124 140.584,284.424 140.444,284.336 140.179 C 284.184 139.718,283.046 139.464,282.698 139.813 M287.321 140.466 C 287.000 141.311,287.603 142.857,288.254 142.857 C 289.085 142.857,289.552 141.330,289.089 140.124 C 288.773 139.300,287.684 139.511,287.321 140.466 M274.351 141.552 C 273.543 141.749,273.232 142.538,273.877 142.753 C 274.341 142.908,275.443 142.063,275.288 141.671 C 275.219 141.497,274.797 141.443,274.351 141.552 M238.853 141.775 C 238.495 142.133,238.606 142.451,239.165 142.666 C 239.702 142.872,240.584 142.361,240.584 141.843 C 240.584 141.512,239.172 141.456,238.853 141.775 M178.247 143.019 C 178.247 143.287,178.028 143.506,177.760 143.506 C 177.492 143.506,177.273 143.287,177.273 143.019 C 177.273 142.752,177.492 142.532,177.760 142.532 C 178.028 142.532,178.247 142.752,178.247 143.019 M211.688 143.019 C 211.688 143.290,211.400 143.506,211.039 143.506 C 210.678 143.506,210.390 143.290,210.390 143.019 C 210.390 142.749,210.678 142.532,211.039 142.532 C 211.400 142.532,211.688 142.749,211.688 143.019 M84.097 143.348 C 85.559 144.103,86.173 145.534,85.197 145.908 C 84.867 146.035,84.349 145.753,83.768 145.131 C 81.463 142.664,78.437 145.454,79.515 149.052 C 80.209 151.367,82.979 151.797,84.054 149.756 C 84.298 149.293,84.738 149.026,85.261 149.026 C 86.802 149.026,85.507 151.320,83.482 152.177 C 79.618 153.811,76.304 149.471,78.210 145.273 C 79.186 143.125,81.931 142.227,84.097 143.348 M88.312 147.565 C 88.312 152.056,88.282 152.273,87.662 152.273 C 87.043 152.273,87.013 152.056,87.013 147.565 C 87.013 143.074,87.043 142.857,87.662 142.857 C 88.282 142.857,88.312 143.074,88.312 147.565 M104.545 143.669 C 104.545 144.264,104.372 144.481,103.896 144.481 C 103.420 144.481,103.247 144.264,103.247 143.669 C 103.247 143.074,103.420 142.857,103.896 142.857 C 104.372 142.857,104.545 143.074,104.545 143.669 M94.509 145.871 C 96.462 147.371,96.227 151.039,94.107 152.136 C 91.347 153.563,88.564 150.736,89.610 147.567 C 90.238 145.663,92.995 144.709,94.509 145.871 M101.029 145.860 C 101.306 146.084,101.619 146.514,101.724 146.818 C 101.990 147.587,100.667 148.003,100.261 147.277 C 99.884 146.604,98.052 146.563,98.052 147.228 C 98.052 147.509,98.598 147.849,99.394 148.064 C 102.181 148.814,102.901 150.501,101.055 151.955 C 99.527 153.160,96.429 152.252,96.429 150.599 C 96.429 149.796,97.434 149.826,98.139 150.649 C 98.806 151.429,99.763 151.488,100.345 150.787 C 100.861 150.166,100.417 149.796,98.777 149.481 C 95.647 148.878,95.997 145.455,99.188 145.455 C 99.924 145.455,100.752 145.637,101.029 145.860 M104.545 148.864 C 104.545 152.056,104.504 152.273,103.896 152.273 C 103.288 152.273,103.247 152.056,103.247 148.864 C 103.247 145.671,103.288 145.455,103.896 145.455 C 104.504 145.455,104.545 145.671,104.545 148.864 M107.143 145.844 C 107.143 146.147,107.229 146.147,107.532 145.844 C 108.067 145.310,110.127 145.353,110.896 145.915 C 111.422 146.300,111.545 146.861,111.639 149.324 L 111.753 152.273 110.922 152.273 C 110.105 152.273,110.090 152.227,109.997 149.594 C 109.908 147.077,109.857 146.909,109.154 146.809 C 107.825 146.621,107.468 147.271,107.468 149.877 C 107.468 152.216,107.448 152.273,106.656 152.273 L 105.844 152.273 105.844 148.864 C 105.844 145.671,105.885 145.455,106.494 145.455 C 106.851 145.455,107.143 145.630,107.143 145.844 M118.506 149.492 C 118.506 153.188,118.457 153.504,117.776 154.135 C 116.189 155.606,112.662 154.881,112.662 153.084 C 112.662 152.431,113.853 152.462,114.224 153.125 C 114.622 153.836,116.240 153.797,116.777 153.063 C 117.448 152.144,117.310 152.016,115.824 152.184 C 113.459 152.450,112.107 150.527,112.697 147.735 C 113.062 146.008,113.977 145.458,116.427 145.494 L 118.506 145.526 118.506 149.492 M91.419 147.263 C 90.319 148.364,91.210 151.299,92.644 151.299 C 93.923 151.299,94.772 148.374,93.824 147.231 C 93.304 146.605,92.062 146.621,91.419 147.263 M114.436 147.298 C 113.799 147.935,113.956 150.241,114.667 150.691 C 115.903 151.475,117.208 150.536,117.208 148.864 C 117.208 147.009,115.621 146.113,114.436 147.298 M199.905 147.929 C 199.972 148.130,199.728 148.372,199.364 148.467 C 198.599 148.667,198.463 149.351,199.188 149.351 C 199.456 149.351,199.675 149.570,199.675 149.838 C 199.675 150.106,199.456 150.325,199.188 150.325 C 198.810 150.325,198.701 150.758,198.701 152.273 C 198.701 153.788,198.593 154.221,198.214 154.221 C 197.835 154.221,197.727 153.788,197.727 152.273 C 197.727 151.190,197.583 150.325,197.403 150.325 C 197.224 150.325,197.078 150.106,197.078 149.838 C 197.078 149.570,197.224 149.351,197.403 149.351 C 197.581 149.351,197.727 149.066,197.727 148.717 C 197.727 147.656,199.590 146.983,199.905 147.929 M175.503 148.517 C 175.875 149.086,175.931 149.473,175.702 149.902 C 175.476 150.323,175.517 150.678,175.841 151.122 C 177.342 153.174,174.324 155.472,172.407 153.738 C 171.671 153.072,171.541 152.273,172.168 152.273 C 172.396 152.273,172.842 152.575,173.158 152.944 C 173.784 153.675,174.290 153.651,174.785 152.866 C 175.232 152.158,174.821 151.299,174.036 151.299 C 173.185 151.299,173.177 150.453,174.026 150.231 C 174.745 150.043,174.925 148.843,174.269 148.614 C 173.665 148.403,173.052 148.710,173.052 149.223 C 173.052 149.712,172.223 149.848,171.948 149.404 C 171.080 147.998,174.589 147.123,175.503 148.517 M186.688 148.214 C 186.688 148.588,186.273 148.701,184.903 148.701 C 182.356 148.701,182.113 150.224,184.634 150.388 C 186.800 150.529,186.913 151.299,184.767 151.299 L 183.117 151.299 183.117 152.760 C 183.117 153.842,182.991 154.221,182.630 154.221 C 182.229 154.221,182.143 153.644,182.143 150.974 L 182.143 147.727 184.416 147.727 C 186.219 147.727,186.688 147.828,186.688 148.214 M188.636 148.214 C 188.636 148.485,188.348 148.701,187.987 148.701 C 187.626 148.701,187.338 148.485,187.338 148.214 C 187.338 147.944,187.626 147.727,187.987 147.727 C 188.348 147.727,188.636 147.944,188.636 148.214 M217.532 148.645 C 217.532 149.481,217.620 149.550,218.509 149.419 C 220.036 149.195,220.455 149.783,220.455 152.150 C 220.455 154.988,219.562 155.164,219.416 152.354 C 219.324 150.605,219.267 150.487,218.506 150.487 C 217.746 150.487,217.689 150.605,217.597 152.354 C 217.412 155.917,216.558 154.783,216.558 150.974 C 216.558 148.304,216.645 147.727,217.045 147.727 C 217.363 147.727,217.532 148.046,217.532 148.645 M228.106 149.351 C 228.362 149.351,228.571 149.570,228.571 149.838 C 228.571 150.106,228.352 150.325,228.084 150.325 C 227.724 150.325,227.597 150.703,227.597 151.786 C 227.597 152.868,227.724 153.247,228.084 153.247 C 228.352 153.247,228.571 153.476,228.571 153.755 C 228.571 155.438,226.785 154.043,226.685 152.283 C 226.630 151.306,226.411 150.296,226.198 150.038 C 225.898 149.674,225.902 149.539,226.218 149.433 C 226.441 149.358,226.623 149.029,226.623 148.701 C 226.623 147.802,227.418 147.706,227.538 148.590 C 227.594 149.008,227.850 149.351,228.106 149.351 M233.117 150.970 C 233.117 154.129,233.098 154.212,232.386 154.173 C 231.985 154.151,231.427 154.231,231.147 154.351 C 230.155 154.777,228.896 153.357,228.896 151.812 C 228.896 150.076,229.717 149.207,231.156 149.418 C 232.057 149.550,232.143 149.483,232.143 148.645 C 232.143 148.046,232.312 147.727,232.630 147.727 C 233.030 147.727,233.117 148.304,233.117 150.970 M188.636 151.786 C 188.636 154.004,188.579 154.221,187.987 154.221 C 187.331 154.221,186.954 150.167,187.554 149.567 C 188.319 148.802,188.636 149.452,188.636 151.786 M192.144 149.930 C 192.085 150.236,191.747 150.486,191.392 150.486 C 190.834 150.487,190.734 150.741,190.649 152.354 C 190.483 155.540,189.286 155.077,189.286 151.827 L 189.286 149.433 190.768 149.403 C 192.002 149.378,192.233 149.467,192.144 149.930 M195.649 149.599 C 196.127 149.918,196.753 151.137,196.753 151.748 C 196.753 152.119,196.297 152.264,194.907 152.338 C 193.148 152.430,193.088 152.462,193.632 153.003 C 194.335 153.703,194.617 153.713,195.270 153.061 C 196.158 152.172,196.963 152.594,196.192 153.544 C 194.785 155.279,192.208 154.119,192.208 151.750 C 192.208 149.944,194.253 148.666,195.649 149.599 M203.571 150.000 C 204.453 150.882,204.451 152.938,203.567 153.738 C 202.011 155.146,199.675 153.990,199.675 151.811 C 199.675 149.690,202.124 148.552,203.571 150.000 M206.267 150.081 L 206.770 150.812 207.299 150.081 C 207.818 149.366,208.766 149.075,208.766 149.632 C 208.766 149.786,208.457 150.306,208.078 150.787 L 207.391 151.661 208.246 152.860 C 209.261 154.281,208.485 154.900,207.414 153.524 L 206.818 152.760 206.223 153.524 C 205.171 154.875,204.370 154.296,205.334 152.882 L 206.136 151.706 205.341 150.627 C 204.387 149.334,204.389 149.351,205.155 149.351 C 205.491 149.351,205.991 149.679,206.267 150.081 M215.378 150.066 C 215.845 150.812,215.378 151.204,214.600 150.718 C 213.854 150.252,212.987 150.202,212.987 150.624 C 212.987 150.789,213.497 151.092,214.121 151.298 C 216.074 151.942,216.325 153.574,214.566 154.188 C 213.445 154.578,212.202 154.207,211.887 153.387 C 211.559 152.531,211.936 152.412,212.998 153.039 C 213.917 153.582,214.610 153.534,214.610 152.928 C 214.610 152.774,214.098 152.479,213.472 152.272 C 212.510 151.955,211.688 151.153,211.688 150.532 C 211.688 149.388,214.714 149.006,215.378 150.066 M222.468 151.218 C 222.618 154.102,224.136 154.085,224.286 151.197 C 224.443 148.177,225.453 148.686,225.582 151.849 L 225.677 154.178 224.608 154.205 C 224.020 154.220,223.250 154.236,222.896 154.241 C 221.898 154.255,221.429 153.295,221.429 151.237 C 221.429 148.549,222.328 148.533,222.468 151.218 M237.662 150.000 C 239.819 152.156,236.676 155.779,234.420 153.738 C 232.881 152.345,233.987 149.351,236.039 149.351 C 236.580 149.351,237.302 149.639,237.662 150.000 M239.959 151.055 L 240.372 152.760 240.776 151.190 C 241.381 148.841,242.311 148.651,242.713 150.795 C 242.832 151.429,243.043 151.948,243.182 151.948 C 243.321 151.948,243.532 151.429,243.651 150.795 C 243.838 149.797,244.573 149.010,244.959 149.396 C 245.028 149.465,244.773 150.579,244.393 151.871 C 243.531 154.795,242.758 155.074,242.150 152.679 L 241.758 151.136 241.399 152.597 C 240.750 155.239,238.775 153.310,238.656 149.919 C 238.610 148.600,239.566 149.434,239.959 151.055 M249.009 149.663 C 249.867 150.197,249.915 154.221,249.064 154.221 C 248.440 154.221,248.377 154.040,248.377 152.273 C 248.377 150.533,248.306 150.325,247.719 150.325 C 246.953 150.325,246.429 151.454,246.429 153.106 C 246.429 153.880,246.280 154.221,245.942 154.221 C 245.553 154.221,245.455 153.738,245.455 151.828 L 245.455 149.435 246.997 149.402 C 247.845 149.384,248.751 149.501,249.009 149.663 M193.737 150.527 C 193.254 151.010,193.543 151.299,194.508 151.299 C 195.163 151.299,195.463 151.159,195.375 150.893 C 195.223 150.433,194.085 150.179,193.737 150.527 M200.957 151.180 C 200.627 152.050,201.247 153.571,201.932 153.571 C 202.480 153.571,203.247 152.555,203.247 151.827 C 203.247 150.247,201.500 149.753,200.957 151.180 M230.067 150.838 C 229.421 152.521,230.559 154.135,231.633 153.061 C 232.226 152.468,232.278 151.833,231.807 150.953 C 231.401 150.195,230.341 150.125,230.067 150.838 M235.130 150.714 C 234.584 151.261,234.645 152.456,235.250 153.061 C 235.953 153.764,236.261 153.705,236.889 152.746 C 237.864 151.258,236.343 149.501,235.130 150.714 M178.247 153.734 C 178.247 154.002,178.028 154.221,177.760 154.221 C 177.492 154.221,177.273 154.002,177.273 153.734 C 177.273 153.466,177.492 153.247,177.760 153.247 C 178.028 153.247,178.247 153.466,178.247 153.734 M336.688 156.864 C 336.688 157.067,336.433 157.442,336.120 157.696 C 335.707 158.032,335.662 158.204,335.958 158.327 C 336.430 158.523,336.510 159.416,336.055 159.416 C 335.886 159.416,335.703 160.254,335.649 161.279 C 335.501 164.125,334.416 164.220,334.416 161.387 C 334.416 160.289,334.272 159.416,334.091 159.416 C 333.912 159.416,333.766 159.196,333.766 158.929 C 333.766 158.661,333.912 158.442,334.091 158.442 C 334.269 158.442,334.416 158.233,334.416 157.978 C 334.416 157.723,334.645 157.284,334.926 157.004 C 335.517 156.413,336.688 156.320,336.688 156.864 M323.622 157.224 C 323.544 157.461,322.788 157.671,321.809 157.728 C 319.394 157.869,319.195 159.416,321.591 159.416 C 322.673 159.416,323.052 159.542,323.052 159.903 C 323.052 160.263,322.673 160.390,321.591 160.390 L 320.130 160.390 320.130 161.851 C 320.130 163.095,320.034 163.312,319.481 163.312 C 318.874 163.312,318.831 163.095,318.831 160.065 L 318.831 156.818 321.293 156.818 C 323.118 156.818,323.721 156.923,323.622 157.224 M325.325 157.305 C 325.325 157.573,325.106 157.792,324.838 157.792 C 324.570 157.792,324.351 157.573,324.351 157.305 C 324.351 157.037,324.570 156.818,324.838 156.818 C 325.106 156.818,325.325 157.037,325.325 157.305 M354.545 157.736 C 354.545 158.582,354.626 158.642,355.572 158.503 C 356.973 158.297,357.468 159.060,357.468 161.426 C 357.468 162.886,357.358 163.312,356.981 163.312 C 356.617 163.312,356.492 162.922,356.489 161.769 C 356.478 158.632,354.773 158.340,354.610 161.448 C 354.527 163.046,354.423 163.312,353.880 163.312 C 353.294 163.312,353.247 163.068,353.247 160.065 C 353.247 157.035,353.290 156.818,353.896 156.818 C 354.392 156.818,354.545 157.035,354.545 157.736 M364.957 158.442 C 365.123 158.442,365.260 158.661,365.260 158.929 C 365.260 159.196,365.114 159.416,364.935 159.416 C 364.382 159.416,364.561 162.010,365.155 162.604 C 365.666 163.115,365.664 163.156,365.136 163.258 C 363.944 163.488,363.636 163.068,363.636 161.211 C 363.636 160.224,363.490 159.416,363.312 159.416 C 363.133 159.416,362.987 159.196,362.987 158.929 C 362.987 158.661,363.133 158.442,363.312 158.442 C 363.490 158.442,363.636 158.162,363.636 157.819 C 363.636 156.901,364.429 156.781,364.551 157.681 C 364.607 158.099,364.790 158.442,364.957 158.442 M369.805 160.029 L 369.805 163.241 368.687 163.371 C 367.144 163.551,366.285 163.164,365.883 162.106 C 365.121 160.102,366.283 158.189,368.056 158.528 C 368.727 158.656,368.831 158.551,368.831 157.747 C 368.831 157.138,368.999 156.818,369.318 156.818 C 369.718 156.818,369.805 157.391,369.805 160.029 M325.325 160.877 C 325.325 162.825,325.227 163.312,324.838 163.312 C 324.448 163.312,324.351 162.825,324.351 160.877 C 324.351 158.929,324.448 158.442,324.838 158.442 C 325.227 158.442,325.325 158.929,325.325 160.877 M328.963 158.646 C 329.379 158.901,328.852 159.703,328.387 159.524 C 327.826 159.309,327.273 160.636,327.273 162.196 C 327.273 162.971,327.124 163.312,326.786 163.312 C 326.397 163.312,326.299 162.828,326.299 160.909 L 326.299 158.506 327.516 158.506 C 328.186 158.506,328.837 158.569,328.963 158.646 M332.897 159.027 C 334.129 160.389,333.767 161.186,331.838 161.364 C 330.139 161.520,330.095 161.548,330.657 162.108 C 331.191 162.639,331.308 162.646,332.006 162.189 C 333.335 161.318,334.130 162.012,332.937 163.001 C 331.488 164.204,329.221 163.020,329.221 161.061 C 329.221 158.742,331.498 157.482,332.897 159.027 M340.692 159.491 C 342.124 161.417,340.284 164.123,338.105 163.295 C 336.928 162.847,336.699 162.460,336.693 160.902 C 336.684 158.410,339.223 157.514,340.692 159.491 M343.146 159.155 L 343.592 159.868 344.169 159.155 C 344.740 158.450,345.779 158.174,345.779 158.726 C 345.779 158.883,345.566 159.189,345.305 159.405 C 344.470 160.098,344.402 160.991,345.108 161.982 C 345.931 163.138,345.941 163.312,345.185 163.312 C 344.858 163.312,344.389 162.936,344.143 162.476 L 343.696 161.640 343.087 162.476 C 342.752 162.936,342.181 163.312,341.818 163.312 C 341.190 163.312,341.199 163.256,342.007 162.197 C 343.018 160.871,343.025 160.785,342.208 159.740 C 341.418 158.731,341.401 158.442,342.130 158.442 C 342.444 158.442,342.901 158.763,343.146 159.155 M351.883 158.831 C 352.425 159.373,352.370 160.065,351.786 160.065 C 351.518 160.065,351.299 159.919,351.299 159.740 C 351.299 159.562,350.933 159.416,350.487 159.416 C 349.228 159.416,349.528 159.957,351.055 160.440 C 352.273 160.825,352.435 160.990,352.435 161.846 C 352.435 163.171,351.082 163.879,349.760 163.246 C 348.766 162.769,348.352 161.688,349.165 161.688 C 349.445 161.688,349.675 161.819,349.675 161.978 C 349.675 162.389,350.558 162.677,351.136 162.455 C 351.844 162.184,351.733 161.763,350.893 161.527 C 348.101 160.745,347.798 158.442,350.487 158.442 C 351.041 158.442,351.669 158.617,351.883 158.831 M359.416 160.355 C 359.416 161.739,359.548 162.319,359.893 162.451 C 360.736 162.775,361.364 161.747,361.364 160.042 C 361.364 158.836,361.484 158.442,361.851 158.442 C 362.240 158.442,362.338 158.926,362.338 160.855 L 362.338 163.268 361.445 163.252 C 360.954 163.244,360.406 163.282,360.227 163.338 C 360.049 163.394,359.574 163.328,359.172 163.192 C 358.249 162.878,358.022 158.442,358.929 158.442 C 359.306 158.442,359.416 158.871,359.416 160.355 M374.495 159.071 C 375.168 159.814,375.250 161.808,374.638 162.545 C 373.043 164.466,369.894 162.730,370.626 160.332 C 371.198 158.458,373.315 157.768,374.495 159.071 M376.725 159.824 C 377.089 161.363,377.402 161.364,377.784 159.825 C 378.234 158.006,379.032 158.070,379.564 159.969 L 380.000 161.526 380.479 159.984 C 380.914 158.585,381.818 157.829,381.818 158.866 C 381.818 161.829,379.478 164.496,379.058 162.012 C 378.802 160.493,378.409 160.559,378.107 162.172 C 377.740 164.128,376.868 163.675,376.038 161.097 C 375.180 158.434,375.176 158.365,375.881 158.501 C 376.219 158.566,376.551 159.086,376.725 159.824 M385.937 158.817 C 386.565 159.338,386.526 163.312,385.893 163.312 C 385.547 163.312,385.396 162.814,385.325 161.445 C 385.233 159.696,385.176 159.578,384.416 159.578 C 383.655 159.578,383.598 159.696,383.507 161.445 C 383.349 164.469,382.468 164.022,382.468 160.918 L 382.468 158.524 383.989 158.493 C 384.826 158.477,385.703 158.622,385.937 158.817 M330.409 159.885 C 330.256 160.283,330.459 160.390,331.368 160.390 C 332.146 160.390,332.478 160.257,332.388 159.984 C 332.186 159.367,330.637 159.289,330.409 159.885 M337.866 159.912 C 337.232 161.564,338.363 163.238,339.485 162.307 C 340.342 161.596,339.944 159.598,338.921 159.479 C 338.367 159.415,337.999 159.565,337.866 159.912 M366.866 160.271 C 366.545 161.116,367.149 162.662,367.800 162.662 C 368.631 162.662,369.097 161.135,368.634 159.929 C 368.318 159.106,367.230 159.316,366.866 160.271 M371.970 159.632 C 371.571 160.030,371.748 161.929,372.220 162.320 C 373.319 163.233,374.451 161.551,373.829 159.929 C 373.633 159.418,372.383 159.219,371.970 159.632 M15.013 175.087 L 16.553 177.435 16.556 175.081 C 16.558 173.207,16.658 172.727,17.045 172.727 C 17.446 172.727,17.532 173.304,17.532 175.974 C 17.532 180.108,17.083 180.257,14.857 176.861 L 13.317 174.513 13.315 176.867 C 13.312 178.742,13.213 179.221,12.825 179.221 C 12.424 179.221,12.338 178.644,12.338 175.974 C 12.338 171.840,12.788 171.691,15.013 175.087 M68.506 173.720 C 68.506 174.067,68.653 174.351,68.831 174.351 C 69.010 174.351,69.156 174.570,69.156 174.838 C 69.156 175.106,69.010 175.325,68.831 175.325 C 68.653 175.325,68.506 175.982,68.506 176.786 C 68.506 177.589,68.653 178.247,68.831 178.247 C 69.010 178.247,69.156 178.466,69.156 178.734 C 69.156 179.435,67.621 179.364,67.399 178.653 C 66.994 177.349,67.053 173.793,67.488 173.268 C 68.017 172.630,68.506 172.848,68.506 173.720 M70.779 175.487 L 70.779 178.247 72.403 178.247 C 73.629 178.247,74.026 178.366,74.026 178.734 C 74.026 179.117,73.575 179.221,71.916 179.221 L 69.805 179.221 69.805 175.974 C 69.805 173.304,69.892 172.727,70.292 172.727 C 70.687 172.727,70.779 173.250,70.779 175.487 M22.510 175.400 C 23.942 177.326,22.102 180.032,19.923 179.204 C 18.746 178.756,18.518 178.369,18.511 176.811 C 18.502 174.320,21.041 173.423,22.510 175.400 M29.156 174.740 C 29.698 175.282,29.643 175.974,29.058 175.974 C 28.791 175.974,28.571 175.828,28.571 175.649 C 28.571 175.471,28.206 175.325,27.760 175.325 C 26.501 175.325,26.801 175.866,28.328 176.349 C 29.546 176.734,29.708 176.900,29.708 177.755 C 29.708 179.080,28.355 179.788,27.033 179.155 C 26.039 178.678,25.625 177.597,26.437 177.597 C 26.718 177.597,26.948 177.728,26.948 177.887 C 26.948 178.298,27.831 178.586,28.409 178.364 C 29.116 178.093,29.006 177.672,28.166 177.437 C 25.374 176.655,25.071 174.351,27.760 174.351 C 28.313 174.351,28.942 174.526,29.156 174.740 M31.818 175.812 C 32.324 177.617,32.567 177.641,33.128 175.940 C 33.529 174.726,34.204 174.031,34.599 174.426 C 35.254 175.081,32.112 181.169,31.119 181.169 C 30.312 181.169,30.353 180.314,31.169 180.101 C 32.013 179.880,31.988 179.362,31.006 176.754 C 30.037 174.179,30.052 174.351,30.802 174.351 C 31.244 174.351,31.520 174.747,31.818 175.812 M38.620 174.663 C 39.478 175.197,39.526 179.221,38.674 179.221 C 38.051 179.221,37.987 179.040,37.987 177.273 C 37.987 175.533,37.917 175.325,37.330 175.325 C 36.563 175.325,36.039 176.454,36.039 178.106 C 36.039 178.880,35.890 179.221,35.552 179.221 C 35.163 179.221,35.065 178.738,35.065 176.828 L 35.065 174.435 36.607 174.402 C 37.455 174.384,38.361 174.501,38.620 174.663 M43.562 174.888 C 44.335 175.587,44.315 175.974,43.506 175.974 C 43.149 175.974,42.857 175.828,42.857 175.649 C 42.857 175.045,41.584 175.320,41.218 176.004 C 40.383 177.563,41.850 179.246,42.906 177.942 C 43.204 177.574,43.592 177.273,43.767 177.273 C 43.943 177.273,44.170 177.054,44.273 176.786 C 44.397 176.464,44.905 176.299,45.769 176.299 C 46.716 176.299,47.078 176.433,47.078 176.786 C 47.078 177.145,46.703 177.273,45.652 177.273 C 44.430 177.273,44.199 177.381,44.036 178.029 C 43.637 179.622,41.088 179.794,40.279 178.284 C 38.964 175.825,41.593 173.106,43.562 174.888 M50.844 174.599 C 51.322 174.918,51.948 176.137,51.948 176.748 C 51.948 177.119,51.492 177.264,50.102 177.338 C 48.342 177.430,48.282 177.462,48.826 178.003 C 49.529 178.703,49.812 178.713,50.464 178.061 C 51.353 177.172,52.158 177.594,51.387 178.544 C 49.980 180.279,47.403 179.119,47.403 176.750 C 47.403 174.944,49.447 173.666,50.844 174.599 M53.892 176.124 L 54.431 177.735 55.039 176.043 C 55.459 174.876,55.825 174.351,56.218 174.351 C 56.739 174.351,55.905 177.484,54.991 178.964 C 54.455 179.830,52.273 176.296,52.273 174.563 C 52.273 173.641,53.437 174.763,53.892 176.124 M60.858 175.072 C 61.908 176.571,61.552 177.273,59.740 177.273 C 58.086 177.273,57.669 177.639,58.679 178.204 C 59.077 178.427,59.501 178.366,60.130 177.994 C 61.130 177.404,61.680 177.673,61.159 178.498 C 59.840 180.589,56.177 178.470,57.021 176.105 C 57.676 174.271,59.881 173.678,60.858 175.072 M65.898 174.979 C 66.446 176.003,66.331 179.221,65.747 179.221 C 65.383 179.221,65.258 178.831,65.255 177.679 C 65.245 174.541,63.539 174.249,63.377 177.357 C 63.293 178.955,63.189 179.221,62.646 179.221 C 62.052 179.221,61.621 175.175,62.158 174.638 C 62.667 174.130,65.586 174.396,65.898 174.979 M78.247 175.000 C 79.129 175.882,79.126 177.938,78.243 178.738 C 76.686 180.146,74.351 178.990,74.351 176.811 C 74.351 174.690,76.799 173.552,78.247 175.000 M83.549 175.400 C 84.981 177.326,83.141 180.032,80.962 179.204 C 79.785 178.756,79.557 178.369,79.550 176.811 C 79.541 174.320,82.080 173.423,83.549 175.400 M88.460 175.078 C 89.669 176.805,88.633 179.347,86.741 179.293 C 85.786 179.266,85.714 179.340,85.714 180.360 C 85.714 181.768,86.221 182.065,87.144 181.198 L 87.877 180.509 88.474 181.169 L 89.071 181.828 89.773 181.169 L 90.475 180.509 91.071 181.169 L 91.668 181.828 92.425 181.117 C 92.841 180.726,93.182 180.552,93.182 180.731 C 93.182 180.910,92.841 181.376,92.425 181.767 L 91.668 182.478 91.071 181.818 L 90.475 181.159 89.773 181.818 L 89.071 182.478 88.474 181.818 L 87.877 181.159 87.112 181.877 L 86.348 182.596 85.640 181.888 L 84.932 181.180 84.242 181.829 C 83.551 182.477,83.551 182.477,82.955 181.818 L 82.358 181.159 81.656 181.818 L 80.954 182.478 80.357 181.818 L 79.760 181.159 78.996 181.877 L 78.231 182.596 77.523 181.888 L 76.815 181.180 76.125 181.829 C 75.435 182.477,75.434 182.477,74.838 181.818 L 74.241 181.159 73.539 181.818 L 72.837 182.478 72.240 181.818 L 71.643 181.159 70.887 181.870 L 70.130 182.581 69.373 181.870 L 68.616 181.159 68.019 181.818 L 67.423 182.478 66.721 181.818 L 66.019 181.159 65.422 181.818 C 64.825 182.477,64.825 182.477,64.135 181.829 L 63.444 181.180 62.729 181.896 L 62.013 182.612 61.297 181.896 L 60.582 181.180 59.891 181.829 C 59.201 182.477,59.201 182.477,58.604 181.818 L 58.007 181.159 57.305 181.818 L 56.603 182.478 56.006 181.818 L 55.410 181.159 54.656 181.867 C 53.926 182.553,53.883 182.557,53.250 181.984 C 52.619 181.412,52.576 181.412,51.945 181.984 C 51.312 182.557,51.269 182.553,50.538 181.867 L 49.785 181.159 49.188 181.818 L 48.592 182.478 47.835 181.767 C 47.418 181.376,47.078 180.910,47.078 180.731 C 47.078 180.552,47.418 180.726,47.835 181.117 L 48.592 181.828 49.188 181.169 L 49.785 180.509 50.538 181.217 C 51.269 181.904,51.312 181.907,51.945 181.334 C 52.576 180.763,52.619 180.763,53.258 181.342 C 53.902 181.924,53.937 181.921,54.623 181.235 L 55.328 180.531 56.018 181.180 C 56.708 181.828,56.709 181.828,57.305 181.169 L 57.902 180.509 58.604 181.169 L 59.306 181.828 59.903 181.169 L 60.499 180.509 61.264 181.228 L 62.029 181.946 62.737 181.239 L 63.444 180.531 64.135 181.180 C 64.825 181.828,64.825 181.828,65.422 181.169 L 66.019 180.509 66.721 181.169 L 67.423 181.828 68.019 181.169 L 68.616 180.509 69.373 181.220 L 70.130 181.931 70.887 181.220 L 71.643 180.509 72.240 181.169 L 72.837 181.828 73.539 181.169 L 74.241 180.509 74.838 181.169 C 75.434 181.828,75.435 181.828,76.125 181.180 L 76.815 180.531 77.523 181.239 L 78.231 181.946 78.996 181.228 L 79.760 180.509 80.357 181.169 L 80.954 181.828 81.656 181.169 L 82.358 180.509 82.952 181.166 C 84.136 182.475,84.740 181.266,84.740 177.589 L 84.740 174.435 86.350 174.399 C 87.664 174.370,88.051 174.494,88.460 175.078 M92.792 174.740 C 93.334 175.282,93.279 175.974,92.695 175.974 C 92.427 175.974,92.208 175.828,92.208 175.649 C 92.208 175.471,91.843 175.325,91.396 175.325 C 90.137 175.325,90.437 175.866,91.964 176.349 C 93.182 176.734,93.344 176.900,93.344 177.755 C 93.344 179.080,91.991 179.788,90.670 179.155 C 89.675 178.678,89.261 177.597,90.074 177.597 C 90.355 177.597,90.584 177.728,90.584 177.887 C 90.584 178.298,91.467 178.586,92.045 178.364 C 92.753 178.093,92.642 177.672,91.802 177.437 C 89.010 176.655,88.707 174.351,91.396 174.351 C 91.950 174.351,92.578 174.526,92.792 174.740 M19.684 175.821 C 19.050 177.473,20.181 179.147,21.303 178.216 C 22.160 177.505,21.762 175.507,20.740 175.388 C 20.185 175.324,19.817 175.475,19.684 175.821 M48.931 175.527 C 48.449 176.010,48.738 176.299,49.702 176.299 C 50.358 176.299,50.657 176.159,50.570 175.893 C 50.418 175.433,49.280 175.179,48.931 175.527 M58.333 175.541 C 57.849 176.025,58.178 176.299,59.243 176.299 C 60.111 176.299,60.326 176.187,60.182 175.812 C 59.994 175.322,58.737 175.138,58.333 175.541 M75.633 176.180 C 75.302 177.050,75.922 178.571,76.608 178.571 C 77.156 178.571,77.922 177.555,77.922 176.827 C 77.922 175.247,76.175 174.753,75.633 176.180 M80.723 175.821 C 80.089 177.473,81.220 179.147,82.342 178.216 C 83.199 177.505,82.801 175.507,81.778 175.388 C 81.224 175.324,80.856 175.475,80.723 175.821 M85.911 175.838 C 85.348 177.306,86.055 178.794,87.122 178.385 C 88.374 177.904,88.169 175.325,86.879 175.325 C 86.455 175.325,86.020 175.556,85.911 175.838 M62.013 205.519 L 62.013 221.429 98.377 221.429 L 134.740 221.429 134.740 205.519 L 134.740 189.610 98.377 189.610 L 62.013 189.610 62.013 205.519 M77.792 201.753 C 79.049 203.010,79.157 203.445,78.282 203.722 C 77.862 203.856,77.357 203.606,76.684 202.933 C 75.578 201.827,75.052 201.737,73.725 202.423 C 71.214 203.721,72.163 208.766,74.917 208.766 C 76.119 208.766,77.273 208.026,77.273 207.255 C 77.273 207.001,77.627 206.818,78.120 206.818 C 80.067 206.818,78.027 209.833,75.796 210.252 C 71.152 211.123,68.693 204.089,72.699 201.390 C 74.430 200.223,76.403 200.364,77.792 201.753 M108.766 205.357 L 108.766 210.065 107.955 210.065 L 107.143 210.065 107.143 205.574 C 107.143 200.895,107.194 200.649,108.171 200.649 C 108.721 200.649,108.766 201.008,108.766 205.357 M111.630 201.546 C 111.714 202.137,111.578 202.273,110.899 202.273 C 110.307 202.273,110.065 202.100,110.065 201.677 C 110.065 200.419,111.452 200.302,111.630 201.546 M84.922 203.707 C 85.974 204.476,86.171 210.066,85.146 210.065 C 84.744 210.065,84.416 209.901,84.416 209.701 C 84.416 209.447,84.293 209.438,84.010 209.671 C 83.092 210.430,81.349 210.463,80.430 209.739 C 78.695 208.375,79.796 206.374,82.485 206.004 C 83.766 205.828,84.104 205.661,84.025 205.243 C 83.887 204.517,82.059 204.352,81.507 205.016 C 80.973 205.659,79.870 205.670,79.870 205.032 C 79.870 203.490,83.368 202.572,84.922 203.707 M88.312 203.636 C 88.312 203.939,88.398 203.939,88.701 203.636 C 89.346 202.991,91.381 203.162,92.065 203.918 C 93.059 205.016,92.979 209.862,91.964 210.006 C 91.267 210.105,91.234 210.008,91.234 207.841 C 91.234 205.089,91.051 204.545,90.128 204.545 C 88.934 204.545,88.636 205.175,88.636 207.695 C 88.636 210.006,88.616 210.065,87.825 210.065 L 87.013 210.065 87.013 206.656 C 87.013 203.463,87.054 203.247,87.662 203.247 C 88.019 203.247,88.312 203.422,88.312 203.636 M98.878 204.044 C 99.846 205.012,99.881 205.390,99.022 205.615 C 98.590 205.728,98.256 205.576,98.036 205.166 C 97.283 203.758,95.478 204.558,95.230 206.409 C 94.933 208.625,96.829 209.944,97.919 208.279 C 98.494 207.402,99.675 207.172,99.675 207.936 C 99.675 211.032,94.549 210.876,93.868 207.760 C 93.088 204.189,96.496 201.661,98.878 204.044 M105.372 204.044 C 105.810 204.482,106.169 205.128,106.169 205.478 C 106.169 205.829,106.258 206.347,106.366 206.629 C 106.535 207.070,106.212 207.143,104.093 207.143 C 101.489 207.143,101.150 207.380,102.161 208.497 C 102.860 209.270,103.651 209.250,104.383 208.442 C 105.006 207.753,106.169 207.556,106.169 208.138 C 106.169 210.528,101.652 211.018,100.481 208.755 C 98.601 205.119,102.597 201.269,105.372 204.044 M111.688 206.656 L 111.688 210.065 110.877 210.065 L 110.065 210.065 110.065 206.656 L 110.065 203.247 110.877 203.247 L 111.688 203.247 111.688 206.656 M117.925 203.795 C 118.847 204.629,118.788 210.065,117.857 210.065 C 117.266 210.065,117.208 209.848,117.208 207.670 C 117.208 205.020,116.808 204.331,115.465 204.668 C 114.548 204.898,114.296 205.656,114.290 208.198 C 114.286 209.847,114.210 210.065,113.636 210.065 C 113.029 210.065,112.987 209.848,112.987 206.704 L 112.987 203.343 115.165 203.305 C 116.758 203.278,117.499 203.410,117.925 203.795 M123.961 203.636 C 124.264 203.939,124.351 203.939,124.351 203.636 C 124.351 203.422,124.643 203.247,125.000 203.247 C 125.729 203.247,125.995 209.439,125.340 211.160 C 124.507 213.353,119.805 213.207,119.805 210.989 C 119.805 210.258,120.949 210.168,121.221 210.877 C 121.480 211.551,123.568 211.530,123.829 210.850 C 124.168 209.967,124.064 209.895,122.618 210.010 C 119.771 210.236,118.349 206.300,120.464 204.048 C 121.291 203.168,123.261 202.936,123.961 203.636 M102.013 204.935 C 101.312 205.636,101.598 205.844,103.258 205.844 C 104.792 205.844,104.872 205.804,104.545 205.195 C 104.154 204.463,102.641 204.307,102.013 204.935 M121.494 204.935 C 120.989 205.440,120.989 207.872,121.494 208.377 C 122.622 209.506,124.026 208.552,124.026 206.656 C 124.026 205.177,123.589 204.545,122.565 204.545 C 122.190 204.545,121.708 204.721,121.494 204.935 M81.875 207.487 C 80.917 207.871,81.059 208.889,82.092 209.036 C 82.906 209.152,84.091 208.288,84.091 207.580 C 84.091 207.083,82.997 207.037,81.875 207.487 M161.923 225.865 C 161.992 226.073,161.748 226.339,161.382 226.455 C 160.609 226.700,160.483 227.273,161.201 227.273 C 161.469 227.273,161.688 227.492,161.688 227.760 C 161.688 228.028,161.469 228.247,161.201 228.247 C 160.823 228.247,160.714 228.680,160.714 230.195 C 160.714 231.710,160.606 232.143,160.227 232.143 C 159.848 232.143,159.740 231.710,159.740 230.195 C 159.740 229.113,159.596 228.247,159.416 228.247 C 159.237 228.247,159.091 228.028,159.091 227.760 C 159.091 227.492,159.237 227.273,159.416 227.273 C 159.594 227.273,159.740 226.988,159.740 226.640 C 159.740 225.568,161.604 224.907,161.923 225.865 M107.897 227.831 L 109.416 230.013 109.416 227.831 C 109.416 225.866,109.480 225.649,110.065 225.649 C 110.671 225.649,110.714 225.866,110.714 228.896 C 110.714 233.063,110.183 233.267,107.961 229.955 L 106.494 227.767 106.494 229.955 C 106.494 231.926,106.429 232.143,105.844 232.143 C 105.238 232.143,105.195 231.926,105.195 228.896 C 105.195 224.787,105.652 224.607,107.897 227.831 M120.469 228.088 L 120.983 230.357 121.545 228.409 C 121.855 227.338,122.170 226.278,122.245 226.055 C 122.766 224.513,124.675 227.246,124.675 229.533 C 124.675 230.540,125.279 229.343,125.647 227.607 C 125.985 226.016,126.183 225.649,126.702 225.649 C 127.078 225.649,127.280 225.817,127.192 226.055 C 127.109 226.278,126.706 227.739,126.296 229.302 C 125.417 232.653,124.636 233.154,124.020 230.763 C 123.825 230.004,123.502 228.872,123.303 228.247 L 122.941 227.110 122.284 229.627 C 121.458 232.793,120.727 233.052,119.996 230.438 C 118.638 225.584,118.635 225.564,119.393 225.710 C 119.798 225.788,120.099 226.452,120.469 228.088 M136.688 227.167 L 136.688 228.685 137.440 227.979 C 138.824 226.678,139.837 227.131,138.567 228.483 C 137.796 229.303,137.774 229.202,139.210 231.412 C 139.649 232.087,139.634 232.143,139.017 232.143 C 138.618 232.143,138.116 231.749,137.773 231.169 C 137.457 230.633,137.083 230.195,136.943 230.195 C 136.803 230.195,136.688 230.633,136.688 231.169 C 136.688 231.926,136.544 232.143,136.039 232.143 C 135.456 232.143,135.387 231.918,135.364 229.951 C 135.350 228.746,135.267 227.934,135.181 228.147 C 135.094 228.361,134.815 228.455,134.561 228.358 C 133.995 228.140,133.442 229.458,133.442 231.028 C 133.442 231.802,133.293 232.143,132.955 232.143 C 132.565 232.143,132.468 231.657,132.468 229.714 L 132.468 227.285 133.929 227.370 C 135.331 227.452,135.390 227.419,135.390 226.553 C 135.390 225.866,135.545 225.649,136.039 225.649 C 136.596 225.649,136.688 225.866,136.688 227.167 M152.978 226.187 C 153.752 226.888,153.731 227.872,152.923 228.733 L 152.275 229.422 153.086 230.521 C 154.064 231.847,154.095 232.143,153.255 232.143 C 152.880 232.143,152.417 231.762,152.140 231.226 C 150.980 228.983,149.351 228.652,149.351 230.660 C 149.351 231.926,149.256 232.143,148.701 232.143 C 148.095 232.143,148.052 231.926,148.052 228.896 L 148.052 225.649 150.218 225.649 C 151.778 225.649,152.550 225.800,152.978 226.187 M174.429 228.009 L 175.968 230.357 175.971 228.003 C 175.973 226.129,176.073 225.649,176.461 225.649 C 176.861 225.649,176.948 226.227,176.948 228.896 C 176.948 233.030,176.498 233.179,174.272 229.783 L 172.733 227.435 172.730 229.789 C 172.728 231.664,172.628 232.143,172.240 232.143 C 171.840 232.143,171.753 231.566,171.753 228.896 C 171.753 224.762,172.203 224.613,174.429 228.009 M187.197 227.273 C 187.453 227.273,187.662 227.492,187.662 227.760 C 187.662 228.028,187.443 228.247,187.175 228.247 C 186.815 228.247,186.688 228.626,186.688 229.708 C 186.688 230.790,186.815 231.169,187.175 231.169 C 187.443 231.169,187.662 231.398,187.662 231.677 C 187.662 233.360,185.876 231.965,185.776 230.205 C 185.721 229.228,185.502 228.218,185.289 227.960 C 184.989 227.596,184.993 227.461,185.308 227.355 C 185.532 227.280,185.714 226.951,185.714 226.623 C 185.714 225.725,186.509 225.628,186.629 226.512 C 186.685 226.930,186.941 227.273,187.197 227.273 M189.286 226.136 C 189.286 226.407,188.997 226.623,188.636 226.623 C 188.276 226.623,187.987 226.407,187.987 226.136 C 187.987 225.866,188.276 225.649,188.636 225.649 C 188.997 225.649,189.286 225.866,189.286 226.136 M224.754 227.753 C 226.475 230.373,226.623 230.373,226.623 227.760 C 226.623 226.100,226.727 225.649,227.110 225.649 C 227.511 225.649,227.597 226.227,227.597 228.896 C 227.597 233.036,227.089 233.241,224.957 229.963 L 223.539 227.783 223.443 229.963 C 223.359 231.877,223.269 232.143,222.712 232.143 C 222.125 232.143,222.078 231.901,222.078 228.896 C 222.078 224.750,222.627 224.515,224.754 227.753 M278.755 227.273 C 279.011 227.273,279.221 227.492,279.221 227.760 C 279.221 228.028,279.002 228.247,278.734 228.247 C 278.373 228.247,278.247 228.626,278.247 229.708 C 278.247 230.790,278.373 231.169,278.734 231.169 C 279.002 231.169,279.221 231.398,279.221 231.677 C 279.221 233.360,277.434 231.965,277.334 230.205 C 277.279 229.228,277.060 228.218,276.847 227.960 C 276.547 227.596,276.552 227.461,276.867 227.355 C 277.090 227.280,277.273 226.951,277.273 226.623 C 277.273 225.725,278.068 225.628,278.187 226.512 C 278.244 226.930,278.499 227.273,278.755 227.273 M280.844 228.409 L 280.844 231.169 282.468 231.169 C 283.694 231.169,284.091 231.288,284.091 231.656 C 284.091 232.039,283.640 232.143,281.981 232.143 L 279.870 232.143 279.870 228.896 C 279.870 226.227,279.957 225.649,280.357 225.649 C 280.752 225.649,280.844 226.172,280.844 228.409 M149.351 227.435 C 149.351 228.233,149.433 228.278,150.731 228.184 C 151.861 228.102,152.110 227.967,152.110 227.435 C 152.110 226.903,151.861 226.768,150.731 226.686 C 149.433 226.592,149.351 226.637,149.351 227.435 M115.260 227.922 C 116.141 228.804,116.139 230.860,115.256 231.660 C 113.699 233.068,111.364 231.912,111.364 229.733 C 111.364 227.613,113.812 226.474,115.260 227.922 M131.169 227.922 C 132.051 228.804,132.048 230.860,131.165 231.660 C 129.608 233.068,127.273 231.912,127.273 229.733 C 127.273 227.613,129.721 226.474,131.169 227.922 M143.611 227.858 C 144.843 229.220,144.482 230.017,142.552 230.195 C 140.854 230.351,140.809 230.379,141.371 230.939 C 141.906 231.470,142.022 231.477,142.720 231.020 C 144.049 230.149,144.844 230.843,143.652 231.833 C 142.203 233.035,139.935 231.851,139.935 229.892 C 139.935 227.573,142.212 226.313,143.611 227.858 M147.666 227.840 C 147.605 228.153,147.267 228.408,146.911 228.409 C 146.354 228.409,146.253 228.663,146.169 230.276 C 146.010 233.327,145.130 232.845,145.130 229.708 L 145.130 227.273 146.452 227.273 C 147.537 227.273,147.755 227.375,147.666 227.840 M158.117 227.922 C 159.413 229.218,158.995 230.195,157.143 230.195 C 155.497 230.195,155.158 230.465,155.965 231.135 C 156.436 231.525,157.468 231.302,157.468 230.809 C 157.468 230.650,157.760 230.519,158.117 230.519 C 158.942 230.519,158.942 230.909,158.118 231.655 C 157.229 232.459,155.513 232.367,154.791 231.477 C 152.935 229.184,156.049 225.854,158.117 227.922 M165.195 227.662 C 165.737 228.204,165.682 228.896,165.097 228.896 C 164.830 228.896,164.610 228.750,164.610 228.571 C 164.610 228.393,164.245 228.247,163.799 228.247 C 162.673 228.247,162.779 228.871,163.944 229.104 C 165.393 229.394,166.102 230.324,165.643 231.332 C 164.977 232.795,161.688 232.337,161.688 230.782 C 161.688 230.336,162.681 230.492,163.210 231.021 C 163.772 231.583,164.448 231.495,164.448 230.860 C 164.448 230.630,163.937 230.277,163.312 230.075 C 162.079 229.677,161.638 228.603,162.352 227.742 C 162.824 227.174,164.655 227.122,165.195 227.662 M181.926 228.322 C 183.358 230.248,181.517 232.954,179.339 232.126 C 178.162 231.678,177.933 231.291,177.927 229.733 C 177.917 227.242,180.456 226.345,181.926 228.322 M189.286 229.708 C 189.286 231.926,189.228 232.143,188.636 232.143 C 187.981 232.143,187.604 228.089,188.203 227.489 C 188.968 226.724,189.286 227.375,189.286 229.708 M193.381 227.628 C 193.645 227.847,193.842 227.842,193.984 227.613 C 194.351 227.018,196.052 227.219,196.417 227.901 C 197.068 229.117,196.845 232.143,196.104 232.143 C 195.527 232.143,195.455 231.926,195.455 230.195 C 195.455 228.500,195.375 228.247,194.840 228.247 C 194.081 228.247,193.831 228.856,193.831 230.708 C 193.831 233.028,192.916 232.647,192.792 230.276 C 192.708 228.658,192.608 228.409,192.045 228.409 C 191.483 228.409,191.383 228.658,191.299 230.276 C 191.215 231.877,191.111 232.143,190.568 232.143 C 189.973 232.143,189.544 228.097,190.082 227.559 C 190.382 227.259,193.002 227.314,193.381 227.628 M200.844 227.521 C 201.322 227.840,201.948 229.059,201.948 229.670 C 201.948 230.041,201.492 230.186,200.102 230.260 C 198.342 230.353,198.282 230.384,198.826 230.925 C 199.529 231.625,199.812 231.635,200.464 230.983 C 201.353 230.094,202.158 230.516,201.387 231.466 C 199.980 233.201,197.403 232.041,197.403 229.672 C 197.403 227.866,199.447 226.589,200.844 227.521 M206.169 227.922 C 207.051 228.804,207.048 230.860,206.165 231.660 C 204.608 233.068,202.273 231.912,202.273 229.733 C 202.273 227.613,204.721 226.474,206.169 227.922 M208.701 229.305 C 208.860 232.342,210.714 231.686,210.714 228.593 C 210.714 227.636,210.848 227.273,211.201 227.273 C 211.591 227.273,211.688 227.757,211.688 229.686 L 211.688 232.099 210.633 232.127 C 210.053 232.142,209.289 232.158,208.935 232.163 C 207.934 232.177,207.468 231.215,207.468 229.135 C 207.468 226.353,208.555 226.503,208.701 229.305 M216.027 227.988 C 216.494 228.734,216.027 229.126,215.249 228.640 C 214.503 228.174,213.636 228.124,213.636 228.546 C 213.636 228.711,214.147 229.014,214.770 229.220 C 216.723 229.865,216.974 231.496,215.215 232.110 C 214.094 232.500,212.851 232.129,212.537 231.310 C 212.208 230.453,212.586 230.334,213.647 230.961 C 214.566 231.504,215.260 231.456,215.260 230.850 C 215.260 230.696,214.747 230.401,214.121 230.194 C 213.159 229.877,212.338 229.075,212.338 228.454 C 212.338 227.310,215.363 226.928,216.027 227.988 M232.287 227.902 C 232.960 228.646,233.042 230.639,232.430 231.376 C 230.835 233.298,227.686 231.561,228.418 229.164 C 228.990 227.289,231.108 226.599,232.287 227.902 M239.221 227.662 C 239.763 228.204,239.708 228.896,239.123 228.896 C 238.856 228.896,238.636 228.750,238.636 228.571 C 238.636 228.393,238.271 228.247,237.825 228.247 C 236.699 228.247,236.805 228.871,237.970 229.104 C 239.419 229.394,240.128 230.324,239.669 231.332 C 239.003 232.795,235.714 232.337,235.714 230.782 C 235.714 230.336,236.707 230.492,237.236 231.021 C 237.798 231.583,238.474 231.495,238.474 230.860 C 238.474 230.630,237.963 230.277,237.338 230.075 C 236.105 229.677,235.664 228.603,236.378 227.742 C 236.850 227.174,238.681 227.122,239.221 227.662 M241.803 228.817 C 242.336 230.417,242.686 230.354,243.224 228.558 C 243.489 227.674,243.793 227.273,244.199 227.273 C 244.737 227.273,244.702 227.508,243.804 229.951 C 242.601 233.222,242.060 234.091,241.226 234.091 C 240.388 234.091,240.394 233.242,241.234 233.023 C 242.075 232.803,242.053 232.374,241.071 229.870 C 240.113 227.423,240.088 227.192,240.801 227.330 C 241.106 227.389,241.543 228.038,241.803 228.817 M248.600 227.648 C 249.228 228.169,249.188 232.143,248.555 232.143 C 248.210 232.143,248.058 231.646,247.987 230.279 C 247.825 227.171,246.119 227.463,246.109 230.601 C 246.105 231.753,245.981 232.143,245.617 232.143 C 245.228 232.143,245.130 231.660,245.130 229.749 L 245.130 227.355 246.652 227.325 C 247.489 227.308,248.365 227.453,248.600 227.648 M253.724 228.003 C 254.198 228.677,254.195 228.743,253.674 228.852 C 253.363 228.917,253.055 228.807,252.989 228.608 C 252.746 227.882,251.321 228.207,251.113 229.035 C 250.676 230.777,252.017 232.165,252.881 230.865 C 253.126 230.497,253.512 230.195,253.739 230.195 C 253.966 230.195,254.235 229.976,254.338 229.708 C 254.462 229.386,254.970 229.221,255.834 229.221 C 256.781 229.221,257.143 229.355,257.143 229.708 C 257.143 230.069,256.764 230.195,255.682 230.195 C 254.674 230.195,254.221 230.330,254.221 230.631 C 254.221 231.321,253.024 232.224,252.110 232.224 C 250.233 232.224,249.195 229.349,250.537 227.866 C 251.313 227.009,253.078 227.085,253.724 228.003 M261.143 227.858 C 262.376 229.220,262.014 230.017,260.085 230.195 C 258.386 230.351,258.341 230.379,258.904 230.939 C 259.438 231.470,259.555 231.477,260.252 231.020 C 261.581 230.149,262.376 230.843,261.184 231.833 C 259.735 233.035,257.468 231.851,257.468 229.892 C 257.468 227.573,259.745 226.313,261.143 227.858 M263.822 228.966 L 264.384 230.660 265.028 228.966 C 265.573 227.532,266.558 226.625,266.558 227.558 C 266.558 228.575,264.937 231.981,264.452 231.981 C 263.926 231.981,262.338 228.769,262.338 227.705 C 262.338 226.599,263.310 227.425,263.822 228.966 M270.779 227.922 C 272.076 229.218,271.657 230.195,269.805 230.195 C 268.159 230.195,267.821 230.465,268.628 231.135 C 269.098 231.525,270.130 231.302,270.130 230.809 C 270.130 230.650,270.422 230.519,270.779 230.519 C 271.604 230.519,271.605 230.909,270.780 231.655 C 269.891 232.459,268.175 232.367,267.454 231.477 C 265.597 229.184,268.712 225.854,270.779 227.922 M275.633 227.585 C 276.491 228.119,276.539 232.143,275.687 232.143 C 275.064 232.143,275.000 231.962,275.000 230.195 C 275.000 228.455,274.930 228.247,274.343 228.247 C 273.576 228.247,273.052 229.376,273.052 231.028 C 273.052 231.802,272.903 232.143,272.565 232.143 C 272.176 232.143,272.078 231.661,272.078 229.750 L 272.078 227.358 273.620 227.325 C 274.468 227.306,275.374 227.423,275.633 227.585 M288.312 227.922 C 289.193 228.804,289.191 230.860,288.307 231.660 C 286.751 233.068,284.416 231.912,284.416 229.733 C 284.416 227.613,286.864 226.474,288.312 227.922 M293.326 227.902 C 293.999 228.646,294.081 230.639,293.469 231.376 C 291.874 233.298,288.725 231.561,289.457 229.164 C 290.029 227.289,292.147 226.599,293.326 227.902 M297.774 227.465 C 299.924 228.087,299.014 232.278,296.742 232.214 C 295.892 232.189,295.779 232.295,295.779 233.119 C 295.779 234.318,296.302 234.631,297.098 233.910 C 297.698 233.367,297.757 233.368,298.377 233.929 C 299.003 234.496,299.049 234.496,299.675 233.929 C 300.281 233.381,300.365 233.377,300.918 233.878 C 301.663 234.553,301.896 234.550,302.734 233.860 C 303.105 233.555,303.013 233.729,302.529 234.246 C 301.667 235.168,301.634 235.175,300.986 234.589 C 300.348 234.011,300.302 234.011,299.675 234.578 C 299.049 235.145,299.003 235.145,298.377 234.578 C 297.750 234.011,297.705 234.011,297.078 234.578 C 296.451 235.145,296.406 235.145,295.779 234.578 C 295.174 234.030,295.090 234.027,294.536 234.528 C 294.210 234.823,293.819 235.065,293.669 235.065 C 293.518 235.065,293.128 234.823,292.802 234.528 C 292.248 234.027,292.164 234.030,291.558 234.578 C 290.932 235.145,290.886 235.145,290.260 234.578 C 289.633 234.011,289.588 234.011,288.961 234.578 C 288.334 235.145,288.289 235.145,287.662 234.578 C 287.057 234.030,286.973 234.027,286.419 234.528 C 286.093 234.823,285.702 235.065,285.552 235.065 C 285.401 235.065,285.011 234.823,284.685 234.528 C 284.131 234.027,284.047 234.030,283.442 234.578 C 282.815 235.145,282.769 235.145,282.143 234.578 C 281.516 234.011,281.471 234.011,280.844 234.578 C 280.218 235.145,280.172 235.145,279.545 234.578 C 278.940 234.030,278.856 234.027,278.302 234.528 C 277.976 234.823,277.586 235.065,277.435 235.065 C 277.285 235.065,276.894 234.823,276.568 234.528 C 276.014 234.027,275.930 234.030,275.325 234.578 C 274.698 235.145,274.653 235.145,274.026 234.578 C 273.399 234.011,273.354 234.011,272.727 234.578 C 272.101 235.145,272.055 235.145,271.429 234.578 C 270.823 234.030,270.739 234.027,270.185 234.528 C 269.859 234.823,269.469 235.065,269.318 235.065 C 269.168 235.065,268.777 234.823,268.451 234.528 C 267.897 234.027,267.813 234.030,267.208 234.578 C 266.581 235.145,266.536 235.145,265.909 234.578 C 265.282 234.011,265.237 234.011,264.610 234.578 C 263.984 235.145,263.938 235.145,263.312 234.578 C 262.685 234.011,262.640 234.011,262.013 234.578 C 261.408 235.126,261.323 235.129,260.770 234.628 C 260.027 233.956,259.778 233.956,259.032 234.631 C 258.472 235.138,258.385 235.125,257.628 234.414 C 256.679 233.522,256.833 233.061,257.790 233.927 C 258.419 234.496,258.464 234.496,259.091 233.929 C 259.696 233.381,259.781 233.377,260.334 233.878 C 260.661 234.174,261.051 234.416,261.201 234.416 C 261.352 234.416,261.742 234.174,262.069 233.878 C 262.622 233.377,262.706 233.381,263.312 233.929 C 263.938 234.496,263.984 234.496,264.610 233.929 C 265.237 233.361,265.282 233.361,265.909 233.929 C 266.536 234.496,266.581 234.496,267.208 233.929 C 267.813 233.381,267.897 233.377,268.451 233.878 C 268.777 234.174,269.168 234.416,269.318 234.416 C 269.469 234.416,269.859 234.174,270.185 233.878 C 270.739 233.377,270.823 233.381,271.429 233.929 C 272.055 234.496,272.101 234.496,272.727 233.929 C 273.354 233.361,273.399 233.361,274.026 233.929 C 274.653 234.496,274.698 234.496,275.325 233.929 C 275.930 233.381,276.014 233.377,276.568 233.878 C 276.894 234.174,277.285 234.416,277.435 234.416 C 277.586 234.416,277.976 234.174,278.302 233.878 C 278.856 233.377,278.940 233.381,279.545 233.929 C 280.172 234.496,280.218 234.496,280.844 233.929 C 281.471 233.361,281.516 233.361,282.143 233.929 C 282.769 234.496,282.815 234.496,283.442 233.929 C 284.047 233.381,284.131 233.377,284.685 233.878 C 285.011 234.174,285.401 234.416,285.552 234.416 C 285.702 234.416,286.093 234.174,286.419 233.878 C 286.973 233.377,287.057 233.381,287.662 233.929 C 288.289 234.496,288.334 234.496,288.961 233.929 C 289.588 233.361,289.633 233.361,290.260 233.929 C 290.886 234.496,290.932 234.496,291.558 233.929 C 292.185 233.361,292.231 233.362,292.876 233.946 C 294.170 235.117,294.631 234.287,294.735 230.599 L 294.827 227.338 296.034 227.324 C 296.697 227.317,297.480 227.380,297.774 227.465 M302.857 227.662 C 303.399 228.204,303.344 228.896,302.760 228.896 C 302.492 228.896,302.273 228.750,302.273 228.571 C 302.273 228.393,301.907 228.247,301.461 228.247 C 300.335 228.247,300.441 228.871,301.607 229.104 C 303.056 229.394,303.765 230.324,303.305 231.332 C 302.639 232.795,299.351 232.337,299.351 230.782 C 299.351 230.336,300.344 230.492,300.873 231.021 C 301.435 231.583,302.110 231.495,302.110 230.860 C 302.110 230.630,301.599 230.277,300.974 230.075 C 299.742 229.677,299.300 228.603,300.015 227.742 C 300.486 227.174,302.317 227.122,302.857 227.662 M112.646 229.102 C 112.315 229.972,112.935 231.494,113.621 231.494 C 114.169 231.494,114.935 230.477,114.935 229.750 C 114.935 228.169,113.188 227.675,112.646 229.102 M128.555 229.102 C 128.224 229.972,128.844 231.494,129.530 231.494 C 130.078 231.494,130.844 230.477,130.844 229.750 C 130.844 228.169,129.097 227.675,128.555 229.102 M141.123 228.716 C 140.970 229.114,141.173 229.221,142.083 229.221 C 142.860 229.221,143.192 229.088,143.103 228.815 C 142.900 228.198,141.352 228.120,141.123 228.716 M155.736 228.463 C 155.246 228.953,155.586 229.221,156.696 229.221 C 157.704 229.221,157.814 229.151,157.468 228.734 C 157.049 228.230,156.115 228.084,155.736 228.463 M179.100 228.743 C 178.466 230.396,179.597 232.069,180.719 231.138 C 181.576 230.427,181.177 228.429,180.155 228.310 C 179.600 228.246,179.233 228.397,179.100 228.743 M198.931 228.450 C 198.449 228.932,198.738 229.221,199.702 229.221 C 200.358 229.221,200.657 229.081,200.570 228.815 C 200.418 228.355,199.280 228.101,198.931 228.450 M203.555 229.102 C 203.224 229.972,203.844 231.494,204.530 231.494 C 205.078 231.494,205.844 230.477,205.844 229.750 C 205.844 228.169,204.097 227.675,203.555 229.102 M229.762 228.463 C 229.363 228.862,229.540 230.760,230.012 231.152 C 231.111 232.064,232.244 230.382,231.621 228.760 C 231.425 228.250,230.175 228.050,229.762 228.463 M258.656 228.716 C 258.503 229.114,258.706 229.221,259.615 229.221 C 260.392 229.221,260.725 229.088,260.635 228.815 C 260.432 228.198,258.884 228.120,258.656 228.716 M268.398 228.463 C 267.909 228.953,268.248 229.221,269.358 229.221 C 270.367 229.221,270.476 229.151,270.130 228.734 C 269.712 228.230,268.777 228.084,268.398 228.463 M285.698 229.102 C 285.367 229.972,285.987 231.494,286.673 231.494 C 287.221 231.494,287.987 230.477,287.987 229.750 C 287.987 228.169,286.240 227.675,285.698 229.102 M290.801 228.463 C 290.402 228.862,290.579 230.760,291.051 231.152 C 292.150 232.064,293.282 230.382,292.660 228.760 C 292.464 228.250,291.214 228.050,290.801 228.463 M295.996 228.463 C 295.589 228.870,295.778 230.764,296.266 231.169 C 297.202 231.946,298.213 230.381,297.689 228.965 C 297.437 228.284,296.463 227.995,295.996 228.463 M167.797 232.199 C 167.652 233.661,166.948 233.762,166.948 232.321 C 166.948 231.526,167.095 231.169,167.423 231.169 C 167.762 231.169,167.869 231.465,167.797 232.199 M218.506 231.941 C 218.506 232.551,217.598 233.882,217.511 233.400 C 217.180 231.576,217.244 231.169,217.860 231.169 C 218.324 231.169,218.506 231.386,218.506 231.941 M305.459 232.199 C 305.315 233.661,304.610 233.762,304.610 232.321 C 304.610 231.526,304.758 231.169,305.086 231.169 C 305.424 231.169,305.531 231.465,305.459 232.199 M156.169 236.151 C 156.169 236.213,155.913 236.761,155.601 237.369 C 154.843 238.842,154.855 242.311,155.623 243.750 C 156.106 244.657,156.117 244.805,155.697 244.805 C 154.111 244.805,153.368 239.932,154.574 237.440 C 155.102 236.350,156.169 235.488,156.169 236.151 M260.958 237.666 C 262.113 239.931,261.341 244.805,259.828 244.805 C 259.493 244.805,259.420 244.632,259.590 244.237 C 260.898 241.186,260.895 239.637,259.575 236.563 C 259.024 235.279,260.232 236.243,260.958 237.666 M107.897 238.546 L 109.416 240.728 109.416 238.546 C 109.416 236.580,109.480 236.364,110.065 236.364 C 110.671 236.364,110.714 236.580,110.714 239.610 C 110.714 243.777,110.183 243.981,107.961 240.669 L 106.494 238.481 106.494 240.669 C 106.494 242.641,106.429 242.857,105.844 242.857 C 105.238 242.857,105.195 242.641,105.195 239.610 C 105.195 235.502,105.652 235.321,107.897 238.546 M138.312 239.607 C 138.312 242.765,138.293 242.849,137.581 242.810 C 137.179 242.787,136.622 242.868,136.342 242.988 C 135.350 243.413,134.091 241.993,134.091 240.449 C 134.091 238.713,134.912 237.843,136.351 238.054 C 137.252 238.187,137.338 238.119,137.338 237.281 C 137.338 236.682,137.507 236.364,137.825 236.364 C 138.225 236.364,138.312 236.940,138.312 239.607 M140.260 236.851 C 140.260 237.119,140.041 237.338,139.773 237.338 C 139.505 237.338,139.286 237.119,139.286 236.851 C 139.286 236.583,139.505 236.364,139.773 236.364 C 140.041 236.364,140.260 236.583,140.260 236.851 M183.442 239.610 C 183.442 242.641,183.398 242.857,182.792 242.857 C 182.186 242.857,182.143 242.641,182.143 239.610 C 182.143 236.580,182.186 236.364,182.792 236.364 C 183.398 236.364,183.442 236.580,183.442 239.610 M205.379 237.987 C 205.635 237.987,205.844 238.206,205.844 238.474 C 205.844 238.742,205.625 238.961,205.357 238.961 C 204.996 238.961,204.870 239.340,204.870 240.422 C 204.870 241.504,204.996 241.883,205.357 241.883 C 205.625 241.883,205.844 242.112,205.844 242.392 C 205.844 244.074,204.058 242.679,203.958 240.919 C 203.902 239.942,203.683 238.932,203.471 238.675 C 203.171 238.311,203.175 238.176,203.490 238.069 C 203.713 237.994,203.896 237.665,203.896 237.338 C 203.896 236.439,204.691 236.342,204.811 237.226 C 204.867 237.645,205.123 237.987,205.379 237.987 M215.260 239.610 C 215.260 242.280,215.173 242.857,214.773 242.857 C 214.372 242.857,214.286 242.280,214.286 239.610 C 214.286 236.941,214.372 236.364,214.773 236.364 C 215.173 236.364,215.260 236.941,215.260 239.610 M225.325 239.607 C 225.325 243.203,225.571 242.849,223.052 242.877 C 221.368 242.896,220.491 240.305,221.631 238.678 C 222.046 238.085,222.390 237.952,223.254 238.053 C 224.269 238.172,224.351 238.114,224.351 237.272 C 224.351 236.681,224.521 236.364,224.838 236.364 C 225.238 236.364,225.325 236.940,225.325 239.607 M232.468 237.175 C 232.468 237.851,232.622 237.987,233.391 237.987 C 234.971 237.987,235.958 239.673,235.389 241.398 C 234.977 242.646,234.027 243.132,232.386 242.934 L 231.169 242.786 231.169 239.575 C 231.169 236.580,231.213 236.364,231.818 236.364 C 232.294 236.364,232.468 236.580,232.468 237.175 M286.364 237.272 C 286.364 238.114,286.445 238.172,287.460 238.053 C 288.774 237.900,289.610 238.836,289.610 240.458 C 289.610 242.254,288.672 242.977,286.445 242.896 L 285.390 242.857 285.390 239.610 C 285.390 236.941,285.476 236.364,285.877 236.364 C 286.194 236.364,286.364 236.681,286.364 237.272 M291.558 239.610 C 291.558 242.641,291.515 242.857,290.909 242.857 C 290.303 242.857,290.260 242.641,290.260 239.610 C 290.260 236.580,290.303 236.364,290.909 236.364 C 291.515 236.364,291.558 236.580,291.558 239.610 M115.260 238.636 C 116.141 239.518,116.139 241.574,115.256 242.374 C 113.699 243.782,111.364 242.626,111.364 240.447 C 111.364 238.327,113.812 237.189,115.260 238.636 M122.794 238.535 C 124.371 239.962,122.876 243.476,120.902 242.981 C 120.213 242.808,120.130 242.895,120.130 243.796 C 120.130 244.477,119.971 244.805,119.643 244.805 C 119.241 244.805,119.156 244.215,119.156 241.437 L 119.156 238.069 120.684 238.039 C 121.674 238.019,122.417 238.194,122.794 238.535 M127.468 238.235 C 127.945 238.555,128.571 239.773,128.571 240.385 C 128.571 240.755,128.116 240.901,126.725 240.974 C 124.966 241.067,124.906 241.098,125.450 241.640 C 126.153 242.340,126.435 242.350,127.088 241.697 C 127.976 240.809,128.781 241.231,128.010 242.181 C 126.603 243.916,124.026 242.755,124.026 240.386 C 124.026 238.581,126.071 237.303,127.468 238.235 M132.691 238.362 C 133.319 238.883,133.279 242.857,132.646 242.857 C 132.301 242.857,132.149 242.360,132.078 240.993 C 131.916 237.885,130.210 238.177,130.200 241.315 C 130.196 242.467,130.072 242.857,129.708 242.857 C 129.319 242.857,129.221 242.375,129.221 240.463 L 129.221 238.069 130.743 238.039 C 131.579 238.022,132.456 238.167,132.691 238.362 M140.260 240.422 C 140.260 242.370,140.162 242.857,139.773 242.857 C 139.383 242.857,139.286 242.370,139.286 240.422 C 139.286 238.474,139.383 237.987,139.773 237.987 C 140.162 237.987,140.260 238.474,140.260 240.422 M144.704 238.362 C 145.332 238.883,145.292 242.857,144.659 242.857 C 144.314 242.857,144.162 242.360,144.091 240.993 C 143.929 237.885,142.223 238.177,142.213 241.315 C 142.209 242.467,142.085 242.857,141.721 242.857 C 141.332 242.857,141.234 242.375,141.234 240.463 L 141.234 238.069 142.756 238.039 C 143.592 238.022,144.469 238.167,144.704 238.362 M150.325 240.789 C 150.325 244.384,148.463 246.144,146.614 244.295 C 145.621 243.302,146.170 242.812,147.408 243.585 C 147.875 243.877,148.206 243.893,148.602 243.643 C 149.551 243.045,149.411 242.656,148.294 242.786 C 146.911 242.948,146.039 242.034,146.039 240.422 C 146.039 238.687,146.826 237.993,148.745 238.036 L 150.325 238.072 150.325 240.789 M160.288 238.362 C 160.916 238.883,160.877 242.857,160.243 242.857 C 159.898 242.857,159.747 242.360,159.675 240.990 C 159.584 239.241,159.527 239.123,158.766 239.123 C 158.006 239.123,157.948 239.241,157.857 240.990 C 157.699 244.014,156.818 243.567,156.818 240.463 L 156.818 238.069 158.340 238.039 C 159.177 238.022,160.054 238.167,160.288 238.362 M165.404 238.617 C 166.077 239.360,166.159 241.353,165.547 242.091 C 163.952 244.012,160.803 242.275,161.535 239.878 C 162.107 238.003,164.225 237.313,165.404 238.617 M169.419 238.555 C 169.359 238.868,169.020 239.122,168.664 239.123 C 168.107 239.123,168.006 239.377,167.922 240.990 C 167.763 244.041,166.883 243.560,166.883 240.422 L 166.883 237.987 168.206 237.987 C 169.290 237.987,169.508 238.089,169.419 238.555 M175.893 238.395 C 176.503 238.878,176.445 242.857,175.828 242.857 C 175.482 242.857,175.331 242.360,175.260 240.990 C 175.175 239.372,175.076 239.123,174.513 239.123 C 173.950 239.123,173.851 239.372,173.766 240.990 C 173.617 243.857,172.403 243.785,172.403 240.909 C 172.403 239.214,172.323 238.961,171.788 238.961 C 171.029 238.961,170.779 239.570,170.779 241.423 C 170.779 242.481,170.652 242.857,170.292 242.857 C 169.903 242.857,169.805 242.374,169.805 240.459 L 169.805 238.060 172.646 238.067 C 174.209 238.071,175.670 238.218,175.893 238.395 M180.766 238.393 C 181.600 239.431,181.426 242.822,180.539 242.818 C 180.082 242.816,179.306 242.843,178.816 242.877 C 177.058 242.998,176.304 241.397,177.670 240.440 C 178.067 240.163,178.797 239.935,179.293 239.935 C 179.878 239.935,180.195 239.764,180.195 239.448 C 180.195 239.123,179.870 238.961,179.221 238.961 C 178.685 238.961,178.247 239.107,178.247 239.286 C 178.247 239.464,178.028 239.610,177.760 239.610 C 177.090 239.610,177.146 238.743,177.841 238.338 C 178.636 237.874,180.376 237.907,180.766 238.393 M192.672 238.497 C 193.644 239.469,193.121 239.983,191.922 239.234 C 190.962 238.635,190.260 239.116,190.260 240.372 C 190.260 241.941,191.109 242.595,191.891 241.629 C 192.642 240.702,193.256 240.706,193.123 241.637 C 192.872 243.397,189.933 243.422,189.266 241.670 C 188.321 239.183,190.928 236.754,192.672 238.497 M197.403 238.636 C 198.284 239.518,198.282 241.574,197.398 242.374 C 195.842 243.782,193.506 242.626,193.506 240.447 C 193.506 238.327,195.955 237.189,197.403 238.636 M202.256 238.299 C 203.114 238.834,203.162 242.857,202.311 242.857 C 201.687 242.857,201.623 242.676,201.623 240.909 C 201.623 239.170,201.553 238.961,200.966 238.961 C 200.199 238.961,199.675 240.090,199.675 241.742 C 199.675 242.517,199.527 242.857,199.188 242.857 C 198.799 242.857,198.701 242.375,198.701 240.464 L 198.701 238.072 200.244 238.039 C 201.092 238.021,201.997 238.138,202.256 238.299 M209.027 238.566 C 208.968 238.872,208.630 239.122,208.275 239.123 C 207.717 239.123,207.617 239.377,207.532 240.990 C 207.366 244.176,206.169 243.713,206.169 240.463 L 206.169 238.069 207.651 238.040 C 208.885 238.015,209.116 238.103,209.027 238.566 M212.987 238.636 C 215.143 240.793,212.000 244.415,209.744 242.374 C 208.206 240.982,209.311 237.987,211.364 237.987 C 211.905 237.987,212.626 238.276,212.987 238.636 M230.014 238.709 C 231.064 240.208,230.708 240.909,228.896 240.909 C 227.242 240.909,226.825 241.275,227.835 241.841 C 228.233 242.064,228.657 242.002,229.286 241.631 C 230.286 241.040,230.835 241.310,230.315 242.135 C 228.996 244.225,225.333 242.106,226.177 239.741 C 226.831 237.907,229.037 237.314,230.014 238.709 M237.338 239.708 C 237.338 241.661,237.768 242.348,238.686 241.856 C 239.157 241.605,239.286 241.154,239.286 239.761 C 239.286 238.401,239.399 237.987,239.773 237.987 C 240.162 237.987,240.260 238.474,240.260 240.418 C 240.260 242.721,240.221 242.850,239.529 242.859 C 239.127 242.864,238.458 242.874,238.042 242.881 C 236.724 242.903,236.364 242.297,236.364 240.058 C 236.364 238.434,236.469 237.987,236.851 237.987 C 237.222 237.987,237.338 238.395,237.338 239.708 M245.455 240.789 C 245.455 244.384,243.593 246.144,241.744 244.295 C 240.751 243.302,241.300 242.812,242.538 243.585 C 243.005 243.877,243.336 243.893,243.732 243.643 C 244.681 243.045,244.541 242.656,243.424 242.786 C 242.040 242.948,241.169 242.034,241.169 240.422 C 241.169 238.687,241.956 237.993,243.875 238.036 L 245.455 238.072 245.455 240.789 M250.325 240.845 C 250.325 244.537,248.695 246.075,246.698 244.268 C 245.925 243.569,245.945 243.182,246.753 243.182 C 247.110 243.182,247.403 243.328,247.403 243.506 C 247.403 243.685,247.768 243.831,248.214 243.831 C 248.661 243.831,249.026 243.770,249.026 243.695 C 249.026 243.621,249.104 243.357,249.198 243.110 C 249.330 242.768,249.108 242.691,248.264 242.790 C 246.950 242.943,246.104 242.016,246.104 240.422 C 246.104 238.694,246.870 237.994,248.715 238.036 L 250.325 238.072 250.325 240.845 M255.014 238.709 C 256.064 240.208,255.708 240.909,253.896 240.909 C 252.242 240.909,251.825 241.275,252.835 241.841 C 253.233 242.064,253.657 242.002,254.286 241.631 C 255.286 241.040,255.835 241.310,255.315 242.135 C 253.996 244.225,250.333 242.106,251.177 239.741 C 251.831 237.907,254.037 237.314,255.014 238.709 M259.029 238.555 C 258.969 238.868,258.630 239.122,258.275 239.123 C 257.717 239.123,257.617 239.377,257.532 240.990 C 257.373 244.041,256.494 243.560,256.494 240.422 L 256.494 237.987 257.816 237.987 C 258.900 237.987,259.119 238.089,259.029 238.555 M266.493 240.016 C 266.652 243.056,268.506 242.403,268.506 239.307 C 268.506 238.350,268.640 237.987,268.994 237.987 C 269.383 237.987,269.481 238.472,269.481 240.400 L 269.481 242.814 268.425 242.841 C 267.845 242.856,267.081 242.872,266.727 242.877 C 265.769 242.891,265.263 241.956,265.234 240.117 C 265.220 239.213,265.138 238.648,265.051 238.862 C 264.964 239.075,264.685 239.170,264.432 239.072 C 263.865 238.855,263.312 240.173,263.312 241.742 C 263.312 242.517,263.163 242.857,262.825 242.857 C 262.436 242.857,262.338 242.373,262.338 240.448 L 262.338 238.040 264.367 238.095 L 266.396 238.149 266.493 240.016 M273.924 238.362 C 274.552 238.883,274.513 242.857,273.880 242.857 C 273.534 242.857,273.383 242.360,273.312 240.990 C 273.220 239.241,273.163 239.123,272.403 239.123 C 271.642 239.123,271.585 239.241,271.494 240.990 C 271.336 244.014,270.455 243.567,270.455 240.463 L 270.455 238.069 271.976 238.039 C 272.813 238.022,273.690 238.167,273.924 238.362 M278.879 238.299 C 279.737 238.834,279.786 242.857,278.934 242.857 C 278.310 242.857,278.247 242.676,278.247 240.909 C 278.247 239.170,278.176 238.961,277.589 238.961 C 276.823 238.961,276.299 240.090,276.299 241.742 C 276.299 242.517,276.150 242.857,275.812 242.857 C 275.423 242.857,275.325 242.375,275.325 240.464 L 275.325 238.072 276.867 238.039 C 277.715 238.021,278.621 238.138,278.879 238.299 M284.020 238.393 C 284.204 238.616,284.404 239.706,284.466 240.816 L 284.578 242.833 283.442 242.857 C 282.817 242.870,281.957 242.890,281.532 242.901 C 279.352 242.956,279.893 240.439,282.161 239.975 C 282.704 239.864,283.178 239.627,283.214 239.448 C 283.309 238.976,281.773 238.834,281.491 239.289 C 281.360 239.501,281.011 239.623,280.715 239.561 C 280.222 239.457,280.220 239.388,280.691 238.718 C 281.273 237.891,283.435 237.680,284.020 238.393 M295.649 238.235 C 296.127 238.555,296.753 239.773,296.753 240.385 C 296.753 240.755,296.297 240.901,294.907 240.974 C 293.148 241.067,293.088 241.098,293.632 241.640 C 294.335 242.340,294.617 242.350,295.270 241.697 C 296.158 240.809,296.963 241.231,296.192 242.181 C 294.785 243.916,292.208 242.755,292.208 240.386 C 292.208 238.581,294.253 237.303,295.649 238.235 M300.767 238.702 C 301.235 239.448,300.768 239.840,299.990 239.355 C 299.243 238.889,298.377 238.838,298.377 239.261 C 298.377 239.425,298.887 239.728,299.510 239.934 C 301.463 240.579,301.715 242.211,299.955 242.824 C 298.835 243.215,297.591 242.843,297.277 242.024 C 296.948 241.167,297.326 241.049,298.387 241.675 C 299.306 242.218,300.000 242.171,300.000 241.564 C 300.000 241.410,299.488 241.115,298.861 240.908 C 297.900 240.591,297.078 239.789,297.078 239.168 C 297.078 238.024,300.104 237.642,300.767 238.702 M112.646 239.817 C 112.315 240.687,112.935 242.208,113.621 242.208 C 114.169 242.208,114.935 241.191,114.935 240.464 C 114.935 238.883,113.188 238.389,112.646 239.817 M120.466 239.589 C 119.995 240.470,120.047 241.104,120.639 241.697 C 121.714 242.771,122.851 241.157,122.206 239.475 C 121.932 238.762,120.871 238.831,120.466 239.589 M125.555 239.164 C 125.072 239.646,125.361 239.935,126.326 239.935 C 126.981 239.935,127.281 239.795,127.193 239.529 C 127.042 239.069,125.904 238.815,125.555 239.164 M135.262 239.475 C 134.616 241.157,135.754 242.771,136.828 241.697 C 137.421 241.104,137.473 240.470,137.002 239.589 C 136.596 238.831,135.536 238.762,135.262 239.475 M147.217 239.749 C 146.944 240.836,147.333 241.883,148.009 241.883 C 148.769 241.883,149.351 241.250,149.351 240.422 C 149.351 238.939,147.562 238.375,147.217 239.749 M162.879 239.177 C 162.480 239.576,162.657 241.474,163.129 241.866 C 164.228 242.779,165.360 241.097,164.738 239.475 C 164.542 238.964,163.292 238.764,162.879 239.177 M194.789 239.817 C 194.458 240.687,195.078 242.208,195.764 242.208 C 196.312 242.208,197.078 241.191,197.078 240.464 C 197.078 238.883,195.331 238.389,194.789 239.817 M210.455 239.351 C 209.908 239.897,209.970 241.092,210.575 241.698 C 211.278 242.400,211.586 242.341,212.214 241.383 C 213.189 239.895,211.668 238.137,210.455 239.351 M222.477 239.341 C 221.927 239.891,221.977 241.086,222.574 241.684 C 223.225 242.335,223.980 242.018,224.239 240.985 C 224.593 239.575,223.377 238.441,222.477 239.341 M227.489 239.177 C 227.005 239.662,227.334 239.935,228.399 239.935 C 229.267 239.935,229.482 239.823,229.338 239.448 C 229.150 238.958,227.892 238.774,227.489 239.177 M232.698 239.164 C 232.280 239.582,232.458 241.471,232.955 241.883 C 233.738 242.533,234.469 241.698,234.351 240.288 C 234.256 239.152,233.335 238.526,232.698 239.164 M242.347 239.749 C 242.074 240.836,242.463 241.883,243.139 241.883 C 243.899 241.883,244.481 241.250,244.481 240.422 C 244.481 238.939,242.692 238.375,242.347 239.749 M247.468 239.351 C 246.631 240.187,247.139 241.883,248.227 241.883 C 249.093 241.883,249.517 240.965,249.211 239.749 C 248.998 238.899,248.120 238.698,247.468 239.351 M252.489 239.177 C 252.005 239.662,252.334 239.935,253.399 239.935 C 254.267 239.935,254.482 239.823,254.338 239.448 C 254.150 238.958,252.892 238.774,252.489 239.177 M286.561 239.475 C 285.915 241.157,287.052 242.771,288.127 241.697 C 288.732 241.092,288.793 239.897,288.247 239.351 C 287.697 238.801,286.794 238.867,286.561 239.475 M293.737 239.164 C 293.254 239.646,293.543 239.935,294.508 239.935 C 295.163 239.935,295.463 239.795,295.375 239.529 C 295.223 239.069,294.085 238.815,293.737 239.164 M179.221 240.903 C 178.413 241.100,178.102 241.889,178.747 242.104 C 179.211 242.259,180.313 241.413,180.158 241.022 C 180.089 240.848,179.667 240.794,179.221 240.903 M282.630 240.826 C 281.155 241.102,281.016 241.220,281.541 241.745 C 282.093 242.297,282.971 242.083,283.262 241.325 C 283.499 240.707,283.454 240.671,282.630 240.826 M185.714 242.655 C 185.714 243.265,184.806 244.597,184.718 244.114 C 184.388 242.290,184.451 241.883,185.068 241.883 C 185.532 241.883,185.714 242.101,185.714 242.655 M217.472 242.913 C 217.331 244.342,216.695 244.429,216.655 243.025 C 216.632 242.224,216.765 241.883,217.098 241.883 C 217.437 241.883,217.544 242.179,217.472 242.913 M62.013 263.312 L 62.013 279.221 98.377 279.221 L 134.740 279.221 134.740 263.312 L 134.740 247.403 98.377 247.403 L 62.013 247.403 62.013 263.312 M83.766 260.973 L 83.929 263.012 86.030 260.889 C 87.394 259.511,88.390 258.766,88.870 258.766 C 89.950 258.766,89.806 259.082,87.845 261.019 L 86.079 262.763 87.467 264.580 C 88.231 265.579,89.116 266.798,89.433 267.289 L 90.010 268.182 89.027 268.182 C 88.187 268.182,87.823 267.871,86.523 266.050 C 84.686 263.477,83.766 263.663,83.766 266.609 C 83.766 268.070,83.709 268.182,82.955 268.182 L 82.143 268.182 82.143 263.690 C 82.143 259.097,82.226 258.673,83.101 258.839 C 83.470 258.909,83.647 259.478,83.766 260.973 M91.883 259.578 C 91.883 260.173,91.710 260.390,91.234 260.390 C 90.758 260.390,90.584 260.173,90.584 259.578 C 90.584 258.983,90.758 258.766,91.234 258.766 C 91.710 258.766,91.883 258.983,91.883 259.578 M94.733 263.559 L 94.823 268.182 94.002 268.182 L 93.182 268.182 93.182 263.690 C 93.182 259.096,93.266 258.673,94.140 258.840 C 94.561 258.921,94.658 259.691,94.733 263.559 M97.403 263.474 C 97.403 267.965,97.373 268.182,96.753 268.182 C 96.134 268.182,96.104 267.965,96.104 263.474 C 96.104 258.983,96.134 258.766,96.753 258.766 C 97.373 258.766,97.403 258.983,97.403 263.474 M100.325 259.578 C 100.325 260.173,100.152 260.390,99.675 260.390 C 99.199 260.390,99.026 260.173,99.026 259.578 C 99.026 258.983,99.199 258.766,99.675 258.766 C 100.152 258.766,100.325 258.983,100.325 259.578 M91.883 264.773 C 91.883 267.965,91.842 268.182,91.234 268.182 C 90.626 268.182,90.584 267.965,90.584 264.773 C 90.584 261.580,90.626 261.364,91.234 261.364 C 91.842 261.364,91.883 261.580,91.883 264.773 M100.325 264.773 C 100.325 267.965,100.283 268.182,99.675 268.182 C 99.067 268.182,99.026 267.965,99.026 264.773 C 99.026 261.580,99.067 261.364,99.675 261.364 C 100.283 261.364,100.325 261.580,100.325 264.773 M102.922 261.753 C 102.922 262.056,103.009 262.056,103.312 261.753 C 103.846 261.219,105.906 261.263,106.675 261.824 C 107.202 262.209,107.324 262.770,107.419 265.233 L 107.532 268.182 106.701 268.182 C 105.885 268.182,105.869 268.136,105.776 265.503 C 105.688 262.986,105.637 262.818,104.933 262.719 C 103.604 262.530,103.247 263.180,103.247 265.787 C 103.247 268.125,103.228 268.182,102.435 268.182 L 101.623 268.182 101.623 264.773 C 101.623 261.580,101.665 261.364,102.273 261.364 C 102.630 261.364,102.922 261.539,102.922 261.753 M114.286 265.401 C 114.286 269.097,114.236 269.413,113.555 270.044 C 111.968 271.515,108.442 270.791,108.442 268.994 C 108.442 268.340,109.632 268.371,110.003 269.034 C 110.401 269.746,112.019 269.706,112.556 268.972 C 113.228 268.053,113.089 267.925,111.603 268.093 C 109.238 268.359,107.886 266.436,108.476 263.644 C 108.841 261.917,109.757 261.367,112.206 261.403 L 114.286 261.435 114.286 265.401 M110.216 263.207 C 109.579 263.844,109.735 266.150,110.446 266.600 C 111.682 267.384,112.987 266.445,112.987 264.773 C 112.987 262.918,111.401 262.022,110.216 263.207 M62.013 321.266 L 62.013 337.013 98.377 337.013 L 134.740 337.013 134.740 321.266 L 134.740 305.519 98.377 305.519 L 62.013 305.519 62.013 321.266 M90.193 317.429 C 93.953 320.220,91.615 325.974,86.721 325.974 L 84.091 325.974 84.091 321.225 L 84.091 316.475 86.702 316.626 C 88.639 316.738,89.541 316.946,90.193 317.429 M112.590 321.357 L 112.680 325.986 111.778 325.944 C 111.282 325.921,110.420 326.006,109.863 326.133 C 107.322 326.711,105.568 322.603,107.344 320.235 C 107.925 319.460,108.264 319.318,109.536 319.318 L 111.040 319.318 111.039 318.155 C 111.039 316.848,111.263 316.492,111.997 316.632 C 112.418 316.713,112.515 317.484,112.590 321.357 M85.390 321.429 L 85.390 324.675 87.013 324.675 C 88.931 324.675,89.787 324.009,90.115 322.261 C 90.618 319.577,89.596 318.182,87.125 318.182 L 85.390 318.182 85.390 321.429 M97.451 319.507 C 98.111 319.860,99.026 321.630,99.026 322.555 C 99.026 322.957,98.562 323.052,96.591 323.052 C 93.957 323.052,93.439 323.487,94.877 324.495 C 95.835 325.165,96.322 325.132,96.991 324.351 C 97.768 323.443,99.027 323.466,98.787 324.384 C 98.309 326.211,95.192 326.756,93.627 325.286 C 90.768 322.600,94.027 317.674,97.451 319.507 M104.945 319.724 C 105.284 320.110,105.490 321.202,105.586 323.124 L 105.727 325.955 104.406 325.985 C 103.679 326.001,102.546 326.031,101.889 326.052 C 98.249 326.166,98.973 322.366,102.685 321.873 C 103.872 321.716,104.212 321.550,104.076 321.195 C 103.977 320.937,103.896 320.665,103.896 320.590 C 103.896 320.186,101.580 320.514,101.416 320.942 C 101.206 321.488,99.675 321.618,99.675 321.089 C 99.675 319.473,103.787 318.408,104.945 319.724 M94.481 321.104 C 94.154 321.713,94.234 321.753,95.768 321.753 C 97.428 321.753,97.714 321.545,97.013 320.844 C 96.385 320.217,94.872 320.372,94.481 321.104 M108.453 321.083 C 107.709 322.472,108.500 325.000,109.678 325.000 C 110.956 325.000,111.694 322.122,110.719 320.947 C 110.145 320.256,108.854 320.333,108.453 321.083 M102.062 323.374 C 101.088 323.768,100.896 324.206,101.484 324.694 C 102.168 325.262,103.581 324.736,103.931 323.782 C 104.228 322.974,103.466 322.808,102.062 323.374 " stroke="none" fill="#fafafa" fill-rule="evenodd"></path><path id="path1" d="M75.974 32.143 C 75.974 36.433,76.010 36.688,76.607 36.688 C 77.150 36.688,77.254 36.423,77.338 34.821 L 77.435 32.955 79.611 32.792 C 81.999 32.614,82.342 32.413,82.763 30.946 C 83.442 28.579,82.156 27.609,78.328 27.602 L 75.974 27.597 75.974 32.143 M102.597 29.042 L 102.597 30.486 101.613 30.143 C 98.960 29.218,97.033 32.478,98.527 35.366 C 99.209 36.685,101.293 37.213,102.208 36.299 C 102.511 35.996,102.597 35.996,102.597 36.299 C 102.597 36.513,102.817 36.688,103.084 36.688 C 103.494 36.688,103.571 35.967,103.571 32.143 C 103.571 28.319,103.494 27.597,103.084 27.597 C 102.725 27.597,102.597 27.974,102.597 29.042 M105.519 28.247 C 105.519 28.608,105.736 28.896,106.006 28.896 C 106.277 28.896,106.494 28.608,106.494 28.247 C 106.494 27.886,106.277 27.597,106.006 27.597 C 105.736 27.597,105.519 27.886,105.519 28.247 M81.169 29.221 C 81.950 30.002,81.963 30.168,81.313 31.097 C 80.896 31.692,80.498 31.818,79.040 31.818 L 77.273 31.818 77.273 30.195 L 77.273 28.571 78.896 28.571 C 80.087 28.571,80.693 28.745,81.169 29.221 M85.830 30.180 C 82.824 31.446,83.729 36.688,86.954 36.688 C 88.193 36.688,89.935 35.720,89.935 35.031 C 89.935 34.355,88.906 34.349,88.435 35.022 C 87.637 36.162,86.168 35.905,85.427 34.497 C 85.044 33.770,85.054 33.766,87.489 33.766 L 89.935 33.766 89.935 32.810 C 89.935 30.918,87.612 29.429,85.830 30.180 M93.185 30.186 C 92.918 30.355,92.370 30.410,91.967 30.308 C 91.242 30.126,91.234 30.161,91.234 33.406 C 91.234 36.472,91.277 36.688,91.883 36.688 C 92.474 36.688,92.532 36.472,92.532 34.304 C 92.532 31.451,93.194 30.450,94.644 31.110 C 95.410 31.459,95.455 31.622,95.455 34.084 C 95.455 36.472,95.509 36.688,96.104 36.688 C 96.771 36.688,97.067 33.182,96.559 31.290 C 96.255 30.157,94.262 29.505,93.185 30.186 M110.068 30.186 C 109.801 30.355,109.253 30.410,108.850 30.308 C 108.125 30.126,108.117 30.161,108.117 33.406 C 108.117 36.472,108.160 36.688,108.766 36.688 C 109.357 36.688,109.416 36.472,109.416 34.304 C 109.416 31.451,110.078 30.450,111.527 31.110 C 112.293 31.459,112.338 31.622,112.338 34.084 C 112.338 36.472,112.392 36.688,112.987 36.688 C 113.655 36.688,113.950 33.182,113.442 31.290 C 113.138 30.157,111.145 29.505,110.068 30.186 M115.771 30.628 C 113.445 32.954,115.597 37.674,118.401 36.397 C 119.496 35.898,119.742 36.192,119.137 37.275 C 118.564 38.300,117.206 38.588,116.460 37.842 C 115.929 37.311,114.935 37.153,114.935 37.600 C 114.935 39.188,118.293 39.854,119.618 38.528 C 120.844 37.302,120.935 30.186,119.724 30.227 C 119.322 30.241,118.456 30.149,117.800 30.023 C 116.781 29.827,116.484 29.915,115.771 30.628 M105.519 33.442 C 105.519 36.111,105.606 36.688,106.006 36.688 C 106.407 36.688,106.494 36.111,106.494 33.442 C 106.494 30.772,106.407 30.195,106.006 30.195 C 105.606 30.195,105.519 30.772,105.519 33.442 M88.008 31.180 C 89.341 31.893,88.785 32.792,87.013 32.792 C 85.273 32.792,85.005 32.457,85.927 31.438 C 86.537 30.764,87.101 30.694,88.008 31.180 M101.948 31.494 C 103.290 32.836,102.489 35.714,100.773 35.714 C 99.851 35.714,99.351 34.846,99.351 33.245 C 99.351 31.163,100.705 30.250,101.948 31.494 M118.831 31.494 C 120.089 32.751,119.291 35.714,117.695 35.714 C 116.816 35.714,115.909 34.477,115.909 33.279 C 115.909 32.082,116.816 30.844,117.695 30.844 C 117.963 30.844,118.474 31.136,118.831 31.494 M104.870 57.661 C 104.870 57.768,105.081 58.608,105.340 59.528 C 105.598 60.448,105.969 61.822,106.164 62.581 C 106.683 64.601,107.300 64.324,107.970 61.769 C 108.921 58.145,109.058 58.224,110.242 63.068 C 110.566 64.394,111.288 64.153,111.700 62.581 C 111.899 61.822,112.284 60.423,112.555 59.473 C 113.030 57.806,112.952 57.021,112.374 57.652 C 112.221 57.818,111.834 59.047,111.514 60.382 L 110.933 62.810 110.235 60.221 C 109.337 56.884,108.694 56.629,107.946 59.314 C 106.890 63.105,106.959 63.070,106.319 60.146 C 105.849 57.995,104.870 56.317,104.870 57.661 M121.753 60.714 C 121.753 63.747,122.234 65.249,122.463 62.931 C 122.604 61.504,123.151 61.460,123.882 62.816 C 124.221 63.446,124.684 63.961,124.911 63.961 C 125.513 63.961,125.427 63.612,124.482 62.223 L 123.640 60.984 124.377 60.200 C 125.414 59.095,124.477 59.173,123.313 60.288 L 122.403 61.160 122.403 59.314 C 122.403 58.298,122.256 57.468,122.078 57.468 C 121.883 57.468,121.753 58.766,121.753 60.714 M134.416 60.714 C 134.416 62.662,134.545 63.961,134.740 63.961 C 134.919 63.961,135.065 63.377,135.065 62.662 C 135.065 61.451,135.127 61.364,135.991 61.364 C 138.362 61.364,139.581 60.236,138.965 58.613 C 138.616 57.696,138.028 57.468,136.012 57.468 L 134.416 57.468 134.416 60.714 M143.182 57.955 C 143.182 58.222,143.328 58.442,143.506 58.442 C 143.685 58.442,143.831 58.222,143.831 57.955 C 143.831 57.687,143.685 57.468,143.506 57.468 C 143.328 57.468,143.182 57.687,143.182 57.955 M167.208 60.714 L 167.208 63.961 168.648 63.961 C 170.757 63.961,171.714 63.485,172.267 62.160 C 173.378 59.502,171.940 57.468,168.950 57.468 L 167.208 57.468 167.208 60.714 M178.896 60.714 C 178.896 62.662,179.026 63.961,179.221 63.961 C 179.399 63.961,179.545 63.304,179.545 62.500 C 179.545 61.098,179.584 61.039,180.504 61.039 C 181.274 61.039,181.659 61.325,182.468 62.500 C 183.020 63.304,183.694 63.961,183.963 63.961 C 184.506 63.961,184.403 63.702,183.231 62.116 C 182.305 60.863,182.303 60.833,183.117 60.620 C 183.613 60.491,183.766 60.177,183.766 59.295 C 183.766 57.846,183.131 57.468,180.703 57.468 L 178.896 57.468 178.896 60.714 M195.455 60.714 L 195.455 63.961 197.403 63.961 C 199.709 63.961,200.033 63.391,197.808 63.248 L 196.266 63.149 196.172 60.308 C 196.042 56.363,195.455 56.695,195.455 60.714 M215.900 58.847 C 215.109 60.590,215.103 62.448,215.882 64.164 C 216.495 65.514,217.593 66.666,217.055 65.394 C 215.956 62.800,215.891 59.971,216.886 58.112 C 217.131 57.653,217.129 57.468,216.879 57.468 C 216.685 57.468,216.245 58.088,215.900 58.847 M218.506 57.571 C 218.506 57.649,218.726 58.237,218.994 58.878 C 219.659 60.470,219.593 62.869,218.840 64.529 C 218.495 65.288,218.350 65.909,218.516 65.909 C 219.858 65.909,220.706 60.823,219.691 58.860 C 219.224 57.957,218.506 57.176,218.506 57.571 M154.870 58.422 C 154.870 58.769,154.717 59.147,154.530 59.263 C 154.304 59.403,154.297 59.604,154.510 59.860 C 154.687 60.073,154.877 61.046,154.932 62.023 C 155.020 63.581,155.122 63.811,155.763 63.902 C 156.580 64.018,156.763 63.485,156.006 63.194 C 155.302 62.924,155.331 60.117,156.042 59.844 C 156.522 59.660,156.522 59.620,156.042 59.351 C 155.755 59.190,155.519 58.774,155.519 58.425 C 155.519 58.077,155.373 57.792,155.195 57.792 C 155.016 57.792,154.870 58.076,154.870 58.422 M137.798 58.544 C 139.048 59.459,137.104 61.192,135.512 60.582 C 135.058 60.407,134.886 58.729,135.281 58.333 C 135.649 57.966,137.183 58.094,137.798 58.544 M171.336 58.969 C 172.549 60.628,171.447 63.005,169.421 63.099 L 168.344 63.149 168.249 60.588 L 168.153 58.028 169.536 58.213 C 170.305 58.316,171.104 58.652,171.336 58.969 M182.489 58.453 C 183.782 59.145,182.710 60.390,180.821 60.390 C 179.580 60.390,179.545 60.359,179.545 59.253 C 179.545 58.021,180.962 57.636,182.489 58.453 M114.109 59.888 C 113.239 60.757,113.106 61.664,113.685 62.765 C 114.851 64.980,117.597 64.077,117.597 61.478 C 117.597 59.291,115.611 58.386,114.109 59.888 M119.562 59.322 C 118.888 59.450,118.831 59.635,118.831 61.711 C 118.831 64.422,119.408 64.731,119.545 62.094 C 119.633 60.426,119.722 60.216,120.392 60.121 C 120.804 60.063,121.087 59.853,121.021 59.654 C 120.876 59.219,120.527 59.139,119.562 59.322 M127.273 59.316 C 125.097 60.094,125.746 63.961,128.053 63.961 C 129.246 63.961,130.529 62.907,129.849 62.487 C 129.626 62.349,129.333 62.474,129.162 62.779 C 128.784 63.455,127.796 63.464,127.131 62.799 C 126.360 62.028,126.807 61.688,128.591 61.688 C 130.456 61.688,130.686 61.176,129.398 59.888 C 128.604 59.094,128.199 58.985,127.273 59.316 M132.314 59.401 C 132.208 59.572,131.908 59.630,131.645 59.529 C 131.254 59.379,131.169 59.758,131.169 61.654 C 131.169 62.975,131.308 63.961,131.494 63.961 C 131.672 63.961,131.818 63.459,131.818 62.846 C 131.818 61.233,132.309 60.184,133.173 59.947 C 133.801 59.775,133.846 59.686,133.442 59.421 C 132.825 59.016,132.555 59.011,132.314 59.401 M141.415 59.384 C 141.304 59.564,140.998 59.630,140.736 59.529 C 140.345 59.379,140.260 59.758,140.260 61.654 C 140.260 62.975,140.398 63.961,140.584 63.961 C 140.763 63.961,140.909 63.316,140.909 62.527 C 140.909 60.659,141.159 60.065,141.945 60.065 C 142.298 60.065,142.529 59.891,142.458 59.679 C 142.284 59.157,141.664 58.981,141.415 59.384 M150.596 59.309 C 150.040 59.456,149.528 60.351,149.828 60.651 C 149.920 60.743,150.278 60.563,150.623 60.251 C 151.371 59.574,152.385 59.689,152.535 60.467 C 152.617 60.895,152.334 61.073,151.309 61.237 C 148.432 61.697,148.856 64.003,151.795 63.876 L 153.571 63.799 153.571 61.955 C 153.571 59.430,152.784 58.730,150.596 59.309 M158.018 59.452 C 156.515 60.326,156.718 63.436,158.304 63.834 C 159.353 64.097,160.697 63.735,160.931 63.126 C 161.222 62.366,160.784 62.174,160.123 62.773 C 159.420 63.409,158.722 63.462,158.182 62.922 C 157.352 62.092,157.756 61.688,159.416 61.688 C 160.921 61.688,161.039 61.631,161.039 60.895 C 161.039 59.530,159.306 58.702,158.018 59.452 M174.174 59.888 C 173.304 60.757,173.171 61.664,173.750 62.765 C 174.916 64.980,177.662 64.077,177.662 61.478 C 177.662 59.291,175.676 58.386,174.174 59.888 M191.588 59.391 C 191.336 59.550,190.934 59.605,190.695 59.513 C 190.356 59.383,190.260 59.858,190.260 61.654 C 190.260 62.975,190.398 63.961,190.584 63.961 C 190.763 63.961,190.909 63.241,190.909 62.361 C 190.909 60.887,191.459 59.740,192.166 59.740 C 192.799 59.740,193.182 60.682,193.182 62.240 C 193.182 63.187,193.328 63.961,193.506 63.961 C 194.172 63.961,193.893 59.796,193.203 59.427 C 192.443 59.020,192.182 59.014,191.588 59.391 M200.879 59.745 C 199.165 61.094,200.079 63.961,202.222 63.961 C 203.433 63.961,204.221 63.048,204.221 61.644 C 204.221 59.490,202.469 58.495,200.879 59.745 M205.667 59.888 C 204.798 60.757,204.664 61.664,205.243 62.765 C 206.410 64.980,209.156 64.077,209.156 61.478 C 209.156 59.291,207.169 58.386,205.667 59.888 M211.718 59.391 C 211.466 59.550,211.064 59.605,210.825 59.513 C 210.480 59.381,210.390 59.991,210.390 62.465 C 210.390 64.328,210.520 65.584,210.714 65.584 C 210.893 65.584,211.039 65.166,211.039 64.655 C 211.039 63.851,211.143 63.746,211.814 63.875 C 212.989 64.099,213.908 63.440,214.139 62.206 C 214.518 60.189,213.086 58.524,211.718 59.391 M143.182 61.688 C 143.182 62.987,143.321 63.961,143.506 63.961 C 143.692 63.961,143.831 62.987,143.831 61.688 C 143.831 60.390,143.692 59.416,143.506 59.416 C 143.321 59.416,143.182 60.390,143.182 61.688 M144.805 59.575 C 144.805 60.251,146.585 63.963,146.864 63.870 C 147.184 63.763,148.701 60.295,148.701 59.671 C 148.701 58.850,148.006 59.658,147.455 61.120 L 146.812 62.825 146.461 61.917 C 146.267 61.419,146.019 60.652,145.909 60.213 C 145.746 59.562,144.805 59.018,144.805 59.575 M162.338 59.740 C 162.338 59.919,162.557 60.065,162.825 60.065 C 163.093 60.065,163.312 59.919,163.312 59.740 C 163.312 59.562,163.093 59.416,162.825 59.416 C 162.557 59.416,162.338 59.562,162.338 59.740 M164.935 59.740 C 164.935 59.919,165.154 60.065,165.422 60.065 C 165.690 60.065,165.909 59.919,165.909 59.740 C 165.909 59.562,165.690 59.416,165.422 59.416 C 165.154 59.416,164.935 59.562,164.935 59.740 M185.390 61.520 C 185.390 63.808,186.240 64.600,187.711 63.681 C 188.084 63.449,188.312 63.431,188.312 63.634 C 188.312 63.814,188.458 63.961,188.636 63.961 C 188.822 63.961,188.961 62.987,188.961 61.688 C 188.961 60.390,188.822 59.416,188.636 59.416 C 188.458 59.416,188.312 60.045,188.312 60.815 C 188.312 63.929,186.265 64.360,186.104 61.279 C 185.970 58.723,185.390 58.918,185.390 61.520 M116.390 60.268 C 117.059 60.937,116.917 62.636,116.153 63.115 C 115.320 63.636,114.470 62.978,114.345 61.716 C 114.173 59.981,115.304 59.181,116.390 60.268 M128.831 60.130 C 129.484 60.783,129.274 61.039,128.084 61.039 C 127.459 61.039,126.948 60.922,126.948 60.779 C 126.948 60.400,127.670 59.740,128.084 59.740 C 128.281 59.740,128.617 59.916,128.831 60.130 M159.941 60.308 C 160.486 60.850,160.455 60.881,159.282 60.979 C 157.790 61.104,157.415 60.819,158.261 60.201 C 159.070 59.609,159.249 59.621,159.941 60.308 M176.455 60.268 C 177.124 60.937,176.982 62.636,176.218 63.115 C 175.385 63.636,174.535 62.978,174.410 61.716 C 174.238 59.981,175.369 59.181,176.455 60.268 M202.978 60.278 C 204.002 61.204,203.509 63.312,202.269 63.312 C 201.453 63.312,200.567 61.968,200.855 61.166 C 201.390 59.674,202.019 59.410,202.978 60.278 M207.949 60.268 C 208.618 60.937,208.476 62.636,207.711 63.115 C 206.878 63.636,206.028 62.978,205.903 61.716 C 205.731 59.981,206.862 59.181,207.949 60.268 M213.195 60.683 C 213.895 62.088,212.620 63.895,211.553 63.010 C 210.584 62.205,211.168 59.592,212.270 59.805 C 212.566 59.862,212.982 60.257,213.195 60.683 M152.597 62.136 C 152.597 62.762,151.762 63.386,151.098 63.257 C 150.230 63.089,150.189 62.369,151.028 62.033 C 152.122 61.595,152.597 61.626,152.597 62.136 M162.338 63.474 C 162.338 63.742,162.557 63.961,162.825 63.961 C 163.093 63.961,163.312 63.742,163.312 63.474 C 163.312 63.206,163.093 62.987,162.825 62.987 C 162.557 62.987,162.338 63.206,162.338 63.474 M164.935 63.474 C 164.935 63.742,165.154 63.961,165.422 63.961 C 165.690 63.961,165.909 63.742,165.909 63.474 C 165.909 63.206,165.690 62.987,165.422 62.987 C 165.154 62.987,164.935 63.206,164.935 63.474 M75.649 89.935 C 75.649 94.264,75.680 94.481,76.299 94.481 C 76.876 94.481,76.948 94.264,76.948 92.522 C 76.948 89.406,78.784 89.457,80.986 92.636 C 81.926 93.993,82.465 94.481,83.026 94.481 C 83.929 94.481,83.790 94.113,82.002 91.771 C 80.930 90.366,80.907 90.284,81.538 90.083 C 82.462 89.790,83.201 87.926,82.806 86.886 C 82.347 85.680,81.498 85.390,78.430 85.390 L 75.649 85.390 75.649 89.935 M105.844 86.039 C 105.844 86.400,106.061 86.688,106.331 86.688 C 106.602 86.688,106.818 86.400,106.818 86.039 C 106.818 85.678,106.602 85.390,106.331 85.390 C 106.061 85.390,105.844 85.678,105.844 86.039 M81.308 87.079 C 82.189 88.336,81.340 89.104,78.939 89.220 L 76.948 89.317 76.948 87.840 L 76.948 86.364 78.878 86.364 C 80.499 86.364,80.887 86.478,81.308 87.079 M93.552 87.935 C 93.309 88.099,92.834 88.160,92.497 88.072 C 91.925 87.922,91.883 88.135,91.883 91.196 C 91.883 93.899,91.969 94.481,92.370 94.481 C 92.757 94.481,92.857 94.012,92.857 92.208 C 92.857 87.499,95.674 87.190,95.850 91.880 C 95.995 95.739,97.078 95.674,97.078 91.807 C 97.078 88.360,95.500 86.628,93.552 87.935 M100.652 87.978 C 100.386 88.147,99.838 88.202,99.435 88.101 C 98.710 87.919,98.701 87.954,98.701 91.199 C 98.701 94.264,98.744 94.481,99.351 94.481 C 99.942 94.481,100.000 94.264,100.000 92.069 C 100.000 89.620,100.419 88.636,101.461 88.636 C 102.506 88.636,102.922 89.620,102.922 92.092 C 102.922 94.239,102.989 94.515,103.490 94.414 C 104.446 94.222,104.249 89.058,103.255 88.253 C 102.459 87.609,101.412 87.498,100.652 87.978 M110.392 87.978 C 110.126 88.147,109.578 88.202,109.175 88.101 C 108.450 87.919,108.442 87.954,108.442 91.199 C 108.442 94.264,108.484 94.481,109.091 94.481 C 109.681 94.481,109.740 94.264,109.740 92.096 C 109.740 89.243,110.402 88.242,111.852 88.903 C 112.618 89.252,112.662 89.414,112.662 91.876 C 112.662 94.264,112.716 94.481,113.312 94.481 C 113.979 94.481,114.275 90.975,113.767 89.082 C 113.463 87.949,111.469 87.298,110.392 87.978 M116.095 88.421 C 113.770 90.746,115.922 95.467,118.725 94.189 C 119.820 93.690,120.067 93.984,119.462 95.067 C 118.889 96.093,117.531 96.380,116.785 95.635 C 116.253 95.103,115.260 94.945,115.260 95.392 C 115.260 96.981,118.617 97.646,119.943 96.320 C 121.169 95.094,121.260 87.978,120.049 88.019 C 119.647 88.033,118.781 87.941,118.125 87.815 C 117.105 87.619,116.809 87.707,116.095 88.421 M84.740 90.696 C 84.740 94.195,85.993 95.397,88.333 94.144 C 88.766 93.913,88.961 93.913,88.961 94.144 C 88.961 94.329,89.180 94.481,89.448 94.481 C 89.848 94.481,89.935 93.903,89.935 91.234 C 89.935 88.564,89.848 87.987,89.448 87.987 C 89.072 87.987,88.960 88.413,88.956 89.854 C 88.950 92.098,88.412 93.304,87.348 93.456 C 86.166 93.625,85.714 92.724,85.714 90.198 C 85.714 88.449,85.612 87.987,85.227 87.987 C 84.833 87.987,84.740 88.505,84.740 90.696 M105.844 91.234 C 105.844 93.903,105.931 94.481,106.331 94.481 C 106.732 94.481,106.818 93.903,106.818 91.234 C 106.818 88.564,106.732 87.987,106.331 87.987 C 105.931 87.987,105.844 88.564,105.844 91.234 M119.156 89.286 C 120.414 90.544,119.616 93.506,118.019 93.506 C 117.141 93.506,116.234 92.269,116.234 91.071 C 116.234 89.874,117.141 88.636,118.019 88.636 C 118.287 88.636,118.799 88.929,119.156 89.286 M61.039 118.506 C 61.039 120.455,61.169 121.753,61.364 121.753 C 61.558 121.753,61.688 120.455,61.688 118.506 C 61.688 116.558,61.558 115.260,61.364 115.260 C 61.169 115.260,61.039 116.558,61.039 118.506 M63.440 115.828 C 63.343 116.140,63.132 116.645,62.970 116.949 C 62.788 117.291,62.797 117.578,62.994 117.699 C 63.169 117.807,63.312 118.763,63.312 119.824 C 63.312 120.894,63.456 121.753,63.636 121.753 C 63.820 121.753,63.961 120.833,63.961 119.643 C 63.961 117.877,64.051 117.532,64.510 117.532 C 65.001 117.532,64.996 117.486,64.461 117.095 C 63.820 116.626,64.020 115.909,64.792 115.909 C 65.049 115.909,65.260 115.763,65.260 115.584 C 65.260 115.006,63.627 115.224,63.440 115.828 M72.403 118.506 C 72.403 121.176,72.489 121.753,72.890 121.753 C 73.290 121.753,73.377 121.176,73.377 118.506 C 73.377 115.837,73.290 115.260,72.890 115.260 C 72.489 115.260,72.403 115.837,72.403 118.506 M89.650 116.862 C 88.659 119.166,88.882 121.457,90.257 123.107 C 91.017 124.019,91.085 123.551,90.422 121.966 C 90.154 121.325,89.935 120.133,89.935 119.318 C 89.935 118.503,90.154 117.312,90.422 116.671 C 90.992 115.308,90.998 115.260,90.624 115.260 C 90.468 115.260,90.030 115.981,89.650 116.862 M92.208 115.382 C 92.208 115.450,92.427 116.030,92.695 116.671 C 93.320 118.168,93.318 120.798,92.691 122.301 C 92.046 123.843,92.320 124.065,93.163 122.683 C 94.380 120.687,94.426 118.722,93.310 116.370 C 92.880 115.465,92.208 114.862,92.208 115.382 M51.839 117.363 C 50.840 118.362,51.239 119.112,53.084 119.707 C 53.620 119.880,54.058 120.227,54.058 120.477 C 54.058 121.165,52.956 121.236,52.247 120.593 C 51.513 119.929,51.003 120.236,51.505 121.038 C 51.930 121.717,53.764 121.943,54.421 121.397 C 55.278 120.686,54.839 119.416,53.591 118.998 C 52.977 118.792,52.417 118.452,52.346 118.241 C 52.160 117.681,53.176 117.394,53.727 117.852 C 54.309 118.335,54.941 118.166,54.600 117.619 C 54.166 116.920,52.441 116.761,51.839 117.363 M57.143 117.108 C 54.967 117.886,55.617 121.753,57.923 121.753 C 59.116 121.753,60.399 120.700,59.719 120.279 C 59.496 120.141,59.203 120.266,59.032 120.571 C 58.654 121.247,57.666 121.256,57.001 120.591 C 56.230 119.820,56.677 119.481,58.461 119.481 C 60.326 119.481,60.556 118.968,59.268 117.680 C 58.474 116.886,58.069 116.777,57.143 117.108 M68.506 117.532 C 67.139 118.900,68.013 121.753,69.800 121.753 C 70.705 121.753,71.753 121.044,71.753 120.431 C 71.753 119.972,71.232 120.071,70.779 120.617 C 69.648 121.979,67.985 120.152,68.883 118.533 C 69.439 117.529,69.926 117.375,70.556 118.005 C 71.116 118.565,71.753 118.669,71.753 118.200 C 71.753 117.059,69.453 116.586,68.506 117.532 M75.649 117.108 C 73.462 117.890,74.091 121.753,76.405 121.753 C 78.721 121.753,79.455 118.351,77.375 117.256 C 76.615 116.856,76.406 116.838,75.649 117.108 M79.752 117.483 C 78.984 118.332,79.421 119.164,80.896 119.660 C 81.493 119.861,81.981 120.232,81.981 120.484 C 81.981 121.129,80.709 121.236,80.208 120.633 C 79.744 120.074,79.221 119.967,79.221 120.431 C 79.221 121.726,81.793 122.200,82.596 121.054 C 83.241 120.133,82.785 119.277,81.500 118.995 C 80.368 118.746,79.973 118.274,80.476 117.770 C 80.733 117.514,81.057 117.537,81.649 117.853 C 82.495 118.306,83.150 118.085,82.598 117.533 C 81.903 116.838,80.361 116.811,79.752 117.483 M84.594 117.649 C 83.579 118.664,83.501 120.189,84.416 121.104 C 85.250 121.938,86.746 121.937,87.502 121.102 C 88.240 120.286,87.878 119.834,87.071 120.565 C 86.368 121.201,85.670 121.255,85.130 120.714 C 84.300 119.885,84.704 119.481,86.364 119.481 C 87.713 119.481,87.987 119.382,87.987 118.893 C 87.987 117.167,85.857 116.386,84.594 117.649 M58.701 117.922 C 59.354 118.575,59.144 118.831,57.955 118.831 C 57.330 118.831,56.818 118.714,56.818 118.571 C 56.818 118.192,57.540 117.532,57.955 117.532 C 58.151 117.532,58.487 117.708,58.701 117.922 M77.540 118.609 C 78.351 120.302,76.213 122.114,75.336 120.476 C 74.852 119.572,74.921 118.807,75.548 118.114 C 76.273 117.313,77.006 117.495,77.540 118.609 M86.889 118.101 C 87.434 118.642,87.403 118.674,86.230 118.772 C 84.786 118.892,84.494 118.707,85.058 118.027 C 85.597 117.378,86.186 117.402,86.889 118.101 M65.909 121.266 C 65.909 121.534,66.055 121.753,66.234 121.753 C 66.412 121.753,66.558 121.534,66.558 121.266 C 66.558 120.998,66.412 120.779,66.234 120.779 C 66.055 120.779,65.909 120.998,65.909 121.266 M173.379 127.256 C 172.196 128.237,172.176 128.889,173.349 128.262 C 174.008 127.909,174.026 127.966,174.026 130.373 C 174.026 134.262,174.812 133.450,174.931 129.438 C 175.033 125.966,174.997 125.915,173.379 127.256 M182.442 129.464 C 183.470 133.293,183.947 133.507,184.789 130.519 C 185.712 127.242,185.742 127.233,186.511 130.014 C 187.192 132.472,187.794 133.354,188.151 132.413 C 189.005 130.158,189.822 126.299,189.445 126.299 C 189.179 126.299,188.799 127.223,188.442 128.734 C 187.916 130.965,187.338 131.954,187.338 130.622 C 187.338 130.321,187.099 129.225,186.808 128.187 C 186.052 125.492,185.368 125.613,184.599 128.578 C 183.900 131.272,183.591 131.597,183.295 129.948 C 182.858 127.513,182.433 126.299,182.017 126.299 C 181.696 126.299,181.799 127.071,182.442 129.464 M198.377 129.545 C 198.377 131.494,198.506 132.792,198.701 132.792 C 198.880 132.792,199.028 132.463,199.031 132.062 C 199.036 131.314,199.542 130.254,199.763 130.529 C 199.830 130.613,200.214 131.157,200.614 131.737 C 201.015 132.317,201.559 132.792,201.823 132.792 C 202.169 132.792,202.016 132.374,201.281 131.306 L 200.259 129.820 200.998 129.033 C 201.557 128.437,201.617 128.247,201.243 128.247 C 200.972 128.247,200.486 128.539,200.162 128.896 C 199.262 129.891,199.026 129.689,199.026 127.922 C 199.026 127.029,198.880 126.299,198.701 126.299 C 198.506 126.299,198.377 127.597,198.377 129.545 M213.312 126.786 C 213.312 127.054,213.531 127.273,213.799 127.273 C 214.067 127.273,214.286 127.054,214.286 126.786 C 214.286 126.518,214.067 126.299,213.799 126.299 C 213.531 126.299,213.312 126.518,213.312 126.786 M223.673 126.715 C 221.057 128.724,222.619 133.072,225.827 132.710 C 228.585 132.399,229.596 129.545,226.948 129.545 C 225.484 129.545,225.169 130.096,226.542 130.254 C 227.695 130.387,227.704 131.194,226.558 131.743 C 225.284 132.353,224.040 131.932,223.534 130.719 C 222.427 128.071,225.052 125.701,226.968 127.618 C 227.929 128.578,228.425 128.236,227.597 127.184 C 226.827 126.204,224.673 125.947,223.673 126.715 M230.604 126.795 C 228.229 128.459,229.520 132.792,232.392 132.792 C 233.454 132.792,235.065 131.627,235.065 130.859 C 235.065 130.254,234.363 130.499,233.708 131.331 C 232.535 132.823,230.756 132.106,230.328 129.970 C 229.864 127.646,232.149 125.990,233.604 127.597 C 234.296 128.362,234.740 128.433,234.740 127.778 C 234.740 126.508,231.958 125.847,230.604 126.795 M243.831 127.265 C 243.831 128.147,243.753 128.215,242.931 128.050 C 241.746 127.813,240.779 128.850,240.779 130.357 C 240.779 131.977,241.650 132.773,243.383 132.738 L 244.805 132.710 244.805 129.504 C 244.805 126.871,244.718 126.299,244.318 126.299 C 243.994 126.299,243.831 126.622,243.831 127.265 M191.558 128.147 C 189.371 128.929,190.000 132.792,192.315 132.792 C 194.631 132.792,195.364 129.390,193.284 128.295 C 192.524 127.895,192.315 127.877,191.558 128.147 M196.610 128.215 C 196.499 128.396,196.193 128.461,195.931 128.360 C 195.540 128.210,195.455 128.589,195.455 130.485 C 195.455 131.807,195.593 132.792,195.779 132.792 C 195.958 132.792,196.104 132.147,196.104 131.358 C 196.104 129.490,196.354 128.896,197.140 128.896 C 197.493 128.896,197.724 128.723,197.653 128.511 C 197.479 127.988,196.859 127.813,196.610 128.215 M203.797 128.283 C 202.294 129.157,202.497 132.267,204.084 132.665 C 205.132 132.928,206.476 132.566,206.710 131.957 C 207.001 131.197,206.563 131.005,205.902 131.604 C 205.199 132.240,204.501 132.294,203.961 131.753 C 203.131 130.924,203.535 130.519,205.195 130.519 C 206.700 130.519,206.818 130.462,206.818 129.726 C 206.818 128.361,205.085 127.533,203.797 128.283 M208.847 128.154 C 208.173 128.281,208.117 128.466,208.117 130.542 C 208.117 133.253,208.694 133.563,208.831 130.925 C 208.918 129.257,209.008 129.047,209.678 128.952 C 210.090 128.894,210.373 128.684,210.307 128.486 C 210.162 128.050,209.813 127.971,208.847 128.154 M215.800 128.402 C 214.801 129.401,215.200 130.151,217.045 130.746 C 217.581 130.919,218.019 131.266,218.019 131.516 C 218.019 132.204,216.917 132.275,216.208 131.632 C 215.474 130.968,214.964 131.275,215.466 132.077 C 215.891 132.756,217.725 132.982,218.382 132.436 C 219.239 131.725,218.800 130.455,217.552 130.037 C 216.938 129.831,216.378 129.491,216.308 129.280 C 216.121 128.720,217.137 128.433,217.688 128.890 C 218.270 129.374,218.902 129.205,218.561 128.657 C 218.127 127.959,216.403 127.800,215.800 128.402 M236.542 128.688 C 235.527 129.703,235.449 131.228,236.364 132.143 C 237.198 132.977,238.694 132.976,239.450 132.141 C 240.188 131.325,239.826 130.873,239.019 131.604 C 238.316 132.240,237.618 132.294,237.078 131.753 C 236.248 130.924,236.652 130.519,238.312 130.519 C 239.661 130.519,239.935 130.420,239.935 129.932 C 239.935 128.206,237.805 127.425,236.542 128.688 M213.312 130.519 C 213.312 132.323,213.412 132.792,213.799 132.792 C 214.185 132.792,214.286 132.323,214.286 130.519 C 214.286 128.716,214.185 128.247,213.799 128.247 C 213.412 128.247,213.312 128.716,213.312 130.519 M193.449 129.648 C 194.260 131.341,192.122 133.153,191.245 131.515 C 190.761 130.611,190.830 129.846,191.457 129.153 C 192.182 128.352,192.915 128.534,193.449 129.648 M205.720 129.140 C 206.265 129.681,206.235 129.713,205.061 129.811 C 203.569 129.935,203.195 129.650,204.040 129.032 C 204.849 128.440,205.028 128.452,205.720 129.140 M238.837 129.140 C 239.382 129.681,239.352 129.713,238.178 129.811 C 236.734 129.931,236.443 129.746,237.006 129.066 C 237.545 128.417,238.134 128.441,238.837 129.140 M243.489 129.037 C 244.019 129.676,243.789 131.515,243.128 131.929 C 242.343 132.420,241.558 131.646,241.558 130.382 C 241.558 128.787,242.650 128.027,243.489 129.037 M177.273 132.305 C 177.273 132.573,177.492 132.792,177.760 132.792 C 178.028 132.792,178.247 132.573,178.247 132.305 C 178.247 132.037,178.028 131.818,177.760 131.818 C 177.492 131.818,177.273 132.037,177.273 132.305 M172.588 137.523 C 172.059 138.052,171.893 138.961,172.324 138.961 C 172.460 138.961,172.754 138.669,172.977 138.312 C 173.496 137.480,174.553 137.477,174.997 138.306 C 175.291 138.855,175.079 139.234,173.547 140.900 C 171.276 143.371,171.292 143.506,173.864 143.506 C 175.054 143.506,175.974 143.365,175.974 143.182 C 175.974 143.003,175.317 142.857,174.513 142.857 C 173.709 142.857,173.052 142.765,173.052 142.653 C 173.052 142.540,173.709 141.836,174.513 141.088 C 176.118 139.593,176.394 138.468,175.380 137.550 C 174.630 136.872,173.253 136.858,172.588 137.523 M182.442 140.179 C 183.470 144.007,183.947 144.222,184.789 141.234 C 185.712 137.956,185.742 137.947,186.511 140.728 C 187.192 143.186,187.794 144.068,188.151 143.128 C 189.005 140.872,189.822 137.013,189.445 137.013 C 189.179 137.013,188.799 137.937,188.442 139.448 C 187.916 141.679,187.338 142.668,187.338 141.336 C 187.338 141.035,187.099 139.940,186.808 138.901 C 186.052 136.206,185.368 136.327,184.599 139.292 C 183.900 141.986,183.591 142.312,183.295 140.663 C 182.858 138.228,182.433 137.013,182.017 137.013 C 181.696 137.013,181.799 137.785,182.442 140.179 M198.377 140.260 C 198.377 142.208,198.506 143.506,198.701 143.506 C 198.880 143.506,199.028 143.178,199.031 142.776 C 199.036 142.028,199.542 140.968,199.763 141.243 C 199.830 141.327,200.214 141.871,200.614 142.451 C 201.015 143.032,201.559 143.506,201.823 143.506 C 202.169 143.506,202.016 143.088,201.281 142.020 L 200.259 140.534 200.998 139.748 C 201.557 139.152,201.617 138.961,201.243 138.961 C 200.972 138.961,200.486 139.253,200.162 139.610 C 199.262 140.606,199.026 140.404,199.026 138.636 C 199.026 137.744,198.880 137.013,198.701 137.013 C 198.506 137.013,198.377 138.312,198.377 140.260 M230.844 137.500 C 230.844 137.768,231.063 137.987,231.331 137.987 C 231.599 137.987,231.818 137.768,231.818 137.500 C 231.818 137.232,231.599 137.013,231.331 137.013 C 231.063 137.013,230.844 137.232,230.844 137.500 M251.295 138.068 C 250.079 140.062,250.804 145.455,252.288 145.455 C 252.467 145.455,252.361 144.980,252.051 144.399 C 251.298 142.986,251.272 139.491,252.004 138.068 C 252.303 137.488,252.411 137.013,252.243 137.013 C 252.076 137.013,251.649 137.488,251.295 138.068 M254.039 138.068 C 255.051 140.530,254.987 141.932,253.722 144.940 C 253.190 146.206,254.283 145.062,254.897 143.710 C 255.676 141.994,255.670 140.136,254.879 138.393 C 254.144 136.774,253.386 136.481,254.039 138.068 M259.091 137.500 C 259.091 137.768,259.237 137.987,259.416 137.987 C 259.594 137.987,259.740 137.768,259.740 137.500 C 259.740 137.232,259.594 137.013,259.416 137.013 C 259.237 137.013,259.091 137.232,259.091 137.500 M277.597 140.260 C 277.597 142.208,277.727 143.506,277.922 143.506 C 278.117 143.506,278.247 142.208,278.247 140.260 C 278.247 138.312,278.117 137.013,277.922 137.013 C 277.727 137.013,277.597 138.312,277.597 140.260 M279.545 140.260 C 279.545 142.208,279.675 143.506,279.870 143.506 C 280.065 143.506,280.195 142.208,280.195 140.260 C 280.195 138.312,280.065 137.013,279.870 137.013 C 279.675 137.013,279.545 138.312,279.545 140.260 M289.610 138.022 C 289.610 138.948,289.540 139.014,288.764 138.819 C 287.340 138.462,286.364 139.360,286.364 141.029 C 286.364 142.843,287.053 143.496,288.890 143.423 L 290.260 143.369 290.260 140.191 C 290.260 138.289,290.129 137.013,289.935 137.013 C 289.756 137.013,289.610 137.467,289.610 138.022 M213.128 137.697 C 212.777 138.265,212.962 142.599,213.358 143.076 C 213.777 143.581,214.610 143.651,214.610 143.182 C 214.610 143.003,214.464 142.857,214.286 142.857 C 213.800 142.857,213.877 139.374,214.367 139.176 C 214.692 139.045,214.692 139.007,214.367 138.987 C 214.144 138.973,213.961 138.596,213.961 138.149 C 213.961 137.310,213.517 137.068,213.128 137.697 M243.182 137.968 C 243.182 138.314,243.029 138.693,242.841 138.808 C 242.616 138.948,242.609 139.149,242.822 139.406 C 242.998 139.618,243.188 140.592,243.244 141.568 C 243.332 143.126,243.434 143.357,244.075 143.448 C 244.891 143.564,245.075 143.030,244.318 142.740 C 243.613 142.469,243.643 139.662,244.354 139.389 C 244.834 139.205,244.834 139.165,244.354 138.897 C 244.066 138.736,243.831 138.319,243.831 137.971 C 243.831 137.623,243.685 137.338,243.506 137.338 C 243.328 137.338,243.182 137.621,243.182 137.968 M191.558 138.862 C 189.371 139.643,190.000 143.506,192.315 143.506 C 194.631 143.506,195.364 140.104,193.284 139.010 C 192.524 138.609,192.315 138.591,191.558 138.862 M196.610 138.930 C 196.499 139.110,196.193 139.175,195.931 139.074 C 195.540 138.924,195.455 139.304,195.455 141.199 C 195.455 142.521,195.593 143.506,195.779 143.506 C 195.958 143.506,196.104 142.861,196.104 142.072 C 196.104 140.204,196.354 139.610,197.140 139.610 C 197.493 139.610,197.724 139.437,197.653 139.225 C 197.479 138.702,196.859 138.527,196.610 138.930 M203.797 138.997 C 202.294 139.872,202.497 142.981,204.084 143.379 C 205.132 143.643,206.476 143.280,206.710 142.671 C 207.001 141.911,206.563 141.720,205.902 142.318 C 205.199 142.954,204.501 143.008,203.961 142.468 C 203.131 141.638,203.535 141.234,205.195 141.234 C 206.700 141.234,206.818 141.176,206.818 140.440 C 206.818 139.076,205.085 138.248,203.797 138.997 M208.847 138.868 C 208.173 138.995,208.117 139.180,208.117 141.256 C 208.117 143.967,208.694 144.277,208.831 141.640 C 208.918 139.971,209.008 139.761,209.678 139.667 C 210.090 139.608,210.373 139.398,210.307 139.200 C 210.162 138.764,209.813 138.685,208.847 138.868 M216.558 138.862 C 214.383 139.639,215.032 143.506,217.338 143.506 C 218.532 143.506,219.815 142.453,219.134 142.032 C 218.912 141.895,218.618 142.020,218.448 142.325 C 218.070 143.000,217.082 143.009,216.416 142.344 C 215.646 141.574,216.093 141.234,217.876 141.234 C 219.742 141.234,219.972 140.721,218.684 139.433 C 217.890 138.640,217.485 138.531,216.558 138.862 M221.600 138.947 C 221.494 139.118,221.193 139.175,220.931 139.074 C 220.540 138.924,220.455 139.304,220.455 141.199 C 220.455 142.521,220.593 143.506,220.779 143.506 C 220.958 143.506,221.104 143.005,221.104 142.391 C 221.104 140.778,221.594 139.729,222.459 139.492 C 223.086 139.321,223.132 139.232,222.727 138.966 C 222.111 138.561,221.841 138.557,221.600 138.947 M224.838 138.939 C 224.481 139.080,224.006 139.127,223.782 139.044 C 223.482 138.931,223.377 139.488,223.377 141.199 C 223.377 143.034,223.476 143.506,223.864 143.506 C 224.237 143.506,224.351 143.093,224.351 141.732 C 224.351 140.339,224.480 139.889,224.950 139.637 C 225.868 139.146,226.299 139.832,226.299 141.786 C 226.299 142.732,226.445 143.506,226.623 143.506 C 226.802 143.506,226.948 142.786,226.948 141.906 C 226.948 138.750,228.680 138.379,228.830 141.503 C 228.967 144.328,229.870 144.396,229.870 141.582 C 229.870 139.388,229.269 138.435,228.117 138.805 C 227.248 139.084,226.589 139.104,225.974 138.868 C 225.706 138.766,225.195 138.797,224.838 138.939 M234.445 138.936 C 234.193 139.095,233.792 139.150,233.552 139.059 C 233.213 138.929,233.117 139.403,233.117 141.199 C 233.117 142.521,233.256 143.506,233.442 143.506 C 233.620 143.506,233.766 142.708,233.766 141.732 C 233.766 140.272,233.885 139.894,234.436 139.599 C 235.514 139.023,236.039 139.731,236.039 141.761 C 236.039 142.721,236.185 143.506,236.364 143.506 C 237.029 143.506,236.750 139.342,236.060 138.972 C 235.300 138.565,235.040 138.560,234.445 138.936 M238.718 138.971 C 237.996 139.261,237.682 140.260,238.312 140.260 C 238.490 140.260,238.636 140.129,238.636 139.970 C 238.636 139.540,239.614 139.243,240.305 139.463 C 241.350 139.794,240.963 140.480,239.563 140.782 C 236.695 141.399,237.036 143.336,240.016 143.357 L 241.809 143.370 241.647 141.409 C 241.433 138.831,240.662 138.190,238.718 138.971 M246.329 138.997 C 244.826 139.872,245.030 142.981,246.616 143.379 C 247.664 143.643,249.009 143.280,249.242 142.671 C 249.534 141.911,249.095 141.720,248.434 142.318 C 247.731 142.954,247.034 143.008,246.494 142.468 C 245.664 141.638,246.068 141.234,247.727 141.234 C 249.232 141.234,249.351 141.176,249.351 140.440 C 249.351 139.076,247.618 138.248,246.329 138.997 M261.246 139.237 C 260.478 140.085,260.915 140.917,262.390 141.414 C 262.986 141.614,263.474 141.985,263.474 142.237 C 263.474 142.882,262.202 142.989,261.701 142.386 C 261.238 141.827,260.714 141.720,260.714 142.185 C 260.714 143.479,263.287 143.953,264.090 142.807 C 264.734 141.886,264.278 141.030,262.993 140.748 C 261.862 140.500,261.467 140.027,261.970 139.524 C 262.226 139.267,262.551 139.290,263.142 139.607 C 263.988 140.059,264.643 139.838,264.092 139.286 C 263.397 138.591,261.854 138.564,261.246 139.237 M268.579 139.142 C 266.963 140.273,267.914 143.506,269.862 143.506 C 270.599 143.506,271.753 142.649,271.753 142.101 C 271.753 141.670,270.845 141.894,270.662 142.370 C 270.396 143.063,269.241 142.973,268.843 142.229 C 267.896 140.460,269.305 138.507,270.597 139.799 C 270.879 140.081,271.282 140.255,271.492 140.184 C 272.032 140.004,270.605 138.636,269.877 138.636 C 269.560 138.636,268.976 138.864,268.579 139.142 M273.007 139.258 C 272.585 139.600,272.349 139.988,272.482 140.122 C 272.615 140.255,273.006 140.109,273.350 139.796 C 274.084 139.132,275.111 139.230,275.255 139.977 C 275.328 140.356,274.950 140.602,273.879 140.871 C 270.938 141.612,271.866 143.457,275.166 143.430 L 276.468 143.419 276.294 141.335 C 276.064 138.604,274.799 137.805,273.007 139.258 M282.368 138.997 C 280.865 139.872,281.069 142.981,282.655 143.379 C 283.703 143.643,285.048 143.280,285.281 142.671 C 285.573 141.911,285.134 141.720,284.473 142.318 C 283.770 142.954,283.073 143.008,282.532 142.468 C 281.703 141.638,282.107 141.234,283.766 141.234 C 285.271 141.234,285.390 141.176,285.390 140.440 C 285.390 139.076,283.657 138.248,282.368 138.997 M230.844 141.234 C 230.844 143.038,230.945 143.506,231.331 143.506 C 231.718 143.506,231.818 143.038,231.818 141.234 C 231.818 139.430,231.718 138.961,231.331 138.961 C 230.945 138.961,230.844 139.430,230.844 141.234 M259.091 141.234 C 259.091 142.532,259.230 143.506,259.416 143.506 C 259.601 143.506,259.740 142.532,259.740 141.234 C 259.740 139.935,259.601 138.961,259.416 138.961 C 259.230 138.961,259.091 139.935,259.091 141.234 M193.449 140.362 C 194.260 142.055,192.122 143.867,191.245 142.229 C 190.761 141.325,190.830 140.561,191.457 139.867 C 192.182 139.066,192.915 139.248,193.449 140.362 M205.720 139.854 C 206.265 140.396,206.235 140.427,205.061 140.525 C 203.569 140.649,203.195 140.364,204.040 139.746 C 204.849 139.155,205.028 139.166,205.720 139.854 M218.117 139.675 C 218.770 140.328,218.560 140.584,217.370 140.584 C 216.745 140.584,216.234 140.468,216.234 140.325 C 216.234 139.945,216.955 139.286,217.370 139.286 C 217.567 139.286,217.903 139.461,218.117 139.675 M248.253 139.854 C 248.798 140.396,248.767 140.427,247.594 140.525 C 246.101 140.649,245.727 140.364,246.572 139.746 C 247.381 139.155,247.561 139.166,248.253 139.854 M284.292 139.854 C 284.837 140.396,284.806 140.427,283.633 140.525 C 282.140 140.649,281.766 140.364,282.611 139.746 C 283.420 139.155,283.600 139.166,284.292 139.854 M289.270 140.337 C 290.149 141.895,288.599 143.664,287.403 142.468 C 286.846 141.910,286.922 140.397,287.538 139.781 C 288.198 139.121,288.670 139.273,289.270 140.337 M240.909 141.656 C 240.909 142.306,240.209 142.857,239.383 142.857 C 238.478 142.857,238.328 141.687,239.205 141.458 C 240.309 141.169,240.909 141.239,240.909 141.656 M275.325 141.681 C 275.325 142.307,274.490 142.932,273.825 142.803 C 272.957 142.635,272.916 141.915,273.755 141.579 C 274.849 141.140,275.325 141.171,275.325 141.681 M177.273 143.019 C 177.273 143.287,177.492 143.506,177.760 143.506 C 178.028 143.506,178.247 143.287,178.247 143.019 C 178.247 142.752,178.028 142.532,177.760 142.532 C 177.492 142.532,177.273 142.752,177.273 143.019 M210.714 143.019 C 210.714 143.287,210.860 143.506,211.039 143.506 C 211.218 143.506,211.364 143.287,211.364 143.019 C 211.364 142.752,211.218 142.532,211.039 142.532 C 210.860 142.532,210.714 142.752,210.714 143.019 M80.927 143.182 C 76.217 144.264,77.086 152.249,81.915 152.268 C 83.985 152.276,86.232 150.451,85.537 149.326 C 85.245 148.855,84.416 148.975,84.416 149.489 C 84.416 150.159,82.839 151.299,81.912 151.299 C 79.512 151.299,78.169 146.801,80.018 144.953 C 81.113 143.858,82.878 143.864,83.900 144.968 C 84.876 146.021,85.803 146.076,85.427 145.059 C 84.881 143.584,82.855 142.739,80.927 143.182 M87.013 147.727 C 87.013 152.056,87.044 152.273,87.662 152.273 C 88.281 152.273,88.312 152.056,88.312 147.727 C 88.312 143.398,88.281 143.182,87.662 143.182 C 87.044 143.182,87.013 143.398,87.013 147.727 M103.247 143.831 C 103.247 144.264,103.463 144.481,103.896 144.481 C 104.329 144.481,104.545 144.264,104.545 143.831 C 104.545 143.398,104.329 143.182,103.896 143.182 C 103.463 143.182,103.247 143.398,103.247 143.831 M91.350 145.776 C 89.457 146.540,88.933 149.884,90.466 151.417 C 92.123 153.074,95.124 152.222,95.575 149.966 C 96.176 146.959,93.933 144.734,91.350 145.776 M97.484 145.938 C 95.878 147.097,96.518 148.519,99.021 149.351 C 100.108 149.712,100.487 150.005,100.487 150.487 C 100.487 151.448,98.563 151.588,97.989 150.669 C 97.553 149.971,96.918 149.795,96.614 150.287 C 96.151 151.036,97.768 152.273,99.212 152.273 C 102.581 152.273,103.044 149.387,99.838 148.377 C 98.062 147.817,97.620 147.437,98.088 146.873 C 98.581 146.278,99.974 146.307,100.207 146.916 C 100.399 147.416,101.623 147.610,101.623 147.140 C 101.623 145.822,98.787 144.998,97.484 145.938 M108.120 145.771 C 107.853 145.939,107.305 145.994,106.902 145.893 C 106.177 145.711,106.169 145.746,106.169 148.991 C 106.169 151.692,106.255 152.273,106.656 152.273 C 107.034 152.273,107.143 151.842,107.143 150.346 C 107.143 148.000,107.532 146.880,108.446 146.589 C 109.776 146.167,110.390 147.209,110.390 149.888 C 110.390 151.791,110.488 152.273,110.877 152.273 C 111.773 152.273,111.563 146.605,110.642 145.960 C 109.829 145.390,108.839 145.316,108.120 145.771 M113.819 146.167 C 111.321 148.315,113.287 153.024,116.251 151.991 C 117.089 151.699,117.208 151.733,117.208 152.266 C 117.208 153.818,115.441 154.342,114.012 153.216 C 113.207 152.581,113.142 152.574,113.032 153.118 C 112.763 154.454,115.222 155.317,116.994 154.510 C 118.199 153.961,118.506 152.878,118.506 149.186 L 118.506 145.805 117.614 145.812 C 117.123 145.816,116.269 145.724,115.718 145.608 C 114.935 145.443,114.518 145.565,113.819 146.167 M103.247 149.026 C 103.247 152.056,103.290 152.273,103.896 152.273 C 104.502 152.273,104.545 152.056,104.545 149.026 C 104.545 145.996,104.502 145.779,103.896 145.779 C 103.290 145.779,103.247 145.996,103.247 149.026 M93.831 147.078 C 95.092 148.338,94.336 151.305,92.758 151.294 C 90.821 151.280,90.050 148.663,91.492 146.997 C 92.141 146.247,93.031 146.278,93.831 147.078 M116.614 146.966 C 117.378 147.658,117.412 149.885,116.670 150.705 C 115.508 151.990,113.961 150.971,113.961 148.920 C 113.961 146.804,115.325 145.800,116.614 146.966 M172.588 148.237 C 172.028 148.797,171.916 149.351,172.363 149.351 C 172.520 149.351,172.830 149.131,173.052 148.864 C 173.556 148.257,174.159 148.241,174.641 148.822 C 175.137 149.420,174.793 150.211,173.922 150.477 C 173.235 150.687,173.240 150.702,174.079 151.014 C 175.116 151.398,175.443 152.094,174.987 152.946 C 174.552 153.759,173.492 153.747,172.977 152.922 C 172.461 152.096,172.078 152.091,172.078 152.911 C 172.078 154.179,174.475 154.690,175.437 153.627 C 176.018 152.985,176.162 151.454,175.671 151.150 C 175.504 151.046,175.454 150.432,175.559 149.783 C 175.851 147.982,173.873 146.953,172.588 148.237 M182.143 150.974 C 182.143 153.644,182.229 154.221,182.630 154.221 C 182.991 154.221,183.117 153.842,183.117 152.760 L 183.117 151.299 184.578 151.299 C 185.381 151.299,186.039 151.153,186.039 150.974 C 186.039 150.795,185.381 150.649,184.578 150.649 C 183.125 150.649,183.117 150.643,183.117 149.513 L 183.117 148.377 184.903 148.377 C 185.885 148.377,186.688 148.231,186.688 148.052 C 186.688 147.866,185.714 147.727,184.416 147.727 L 182.143 147.727 182.143 150.974 M187.662 148.214 C 187.662 148.482,187.808 148.701,187.987 148.701 C 188.166 148.701,188.312 148.482,188.312 148.214 C 188.312 147.946,188.166 147.727,187.987 147.727 C 187.808 147.727,187.662 147.946,187.662 148.214 M197.846 148.620 C 197.726 149.111,197.467 149.620,197.271 149.752 C 197.026 149.916,197.042 149.992,197.321 149.995 C 197.604 149.998,197.727 150.641,197.727 152.110 C 197.727 153.770,197.831 154.221,198.214 154.221 C 198.597 154.221,198.701 153.773,198.701 152.137 C 198.701 150.775,198.842 149.997,199.107 149.890 C 199.432 149.759,199.432 149.721,199.107 149.701 C 198.524 149.664,198.603 148.377,199.188 148.377 C 199.456 148.377,199.675 148.231,199.675 148.052 C 199.675 147.240,198.061 147.742,197.846 148.620 M216.558 150.974 C 216.558 154.384,217.013 155.387,217.283 152.573 C 217.597 149.312,219.481 149.084,219.481 152.307 C 219.481 153.792,219.590 154.221,219.968 154.221 C 220.346 154.221,220.455 153.789,220.455 152.280 C 220.455 150.047,219.655 149.132,218.054 149.533 C 217.278 149.728,217.208 149.662,217.208 148.736 C 217.208 148.181,217.062 147.727,216.883 147.727 C 216.688 147.727,216.558 149.026,216.558 150.974 M232.143 148.727 C 232.143 149.651,232.074 149.712,231.244 149.529 C 229.808 149.214,229.058 149.988,229.058 151.786 C 229.058 153.609,229.715 154.235,231.549 154.163 L 232.792 154.114 232.792 150.921 C 232.792 149.008,232.662 147.727,232.468 147.727 C 232.289 147.727,232.143 148.177,232.143 148.727 M226.948 148.682 C 226.948 149.029,226.795 149.407,226.608 149.523 C 226.382 149.662,226.375 149.863,226.588 150.120 C 226.765 150.333,226.954 151.306,227.010 152.283 C 227.101 153.896,227.184 154.069,227.921 154.173 C 228.703 154.283,228.712 154.265,228.165 153.660 C 227.490 152.915,227.372 150.145,228.003 149.890 C 228.328 149.759,228.328 149.721,228.003 149.701 C 227.780 149.687,227.597 149.310,227.597 148.864 C 227.597 148.417,227.451 148.052,227.273 148.052 C 227.094 148.052,226.948 148.336,226.948 148.682 M190.766 149.644 C 190.655 149.824,190.349 149.889,190.087 149.789 C 189.696 149.639,189.610 150.018,189.610 151.913 C 189.610 153.235,189.749 154.221,189.935 154.221 C 190.114 154.221,190.260 153.575,190.260 152.786 C 190.260 150.919,190.510 150.325,191.296 150.325 C 191.648 150.325,191.879 150.151,191.809 149.939 C 191.634 149.416,191.015 149.241,190.766 149.644 M193.407 149.711 C 191.904 150.586,192.108 153.696,193.694 154.094 C 194.742 154.357,196.087 153.994,196.320 153.385 C 196.612 152.626,196.173 152.434,195.512 153.032 C 194.809 153.668,194.112 153.722,193.571 153.182 C 192.742 152.352,193.146 151.948,194.805 151.948 C 196.310 151.948,196.429 151.890,196.429 151.155 C 196.429 149.790,194.696 148.962,193.407 149.711 M200.653 149.932 C 199.753 150.661,199.671 152.670,200.505 153.591 C 201.330 154.503,202.735 154.398,203.548 153.365 C 205.284 151.158,202.790 148.201,200.653 149.932 M212.581 149.701 C 211.437 150.368,211.981 151.613,213.636 152.114 C 215.112 152.561,215.222 153.571,213.796 153.571 C 213.369 153.571,212.877 153.317,212.703 153.006 C 212.529 152.695,212.271 152.556,212.130 152.697 C 211.658 153.169,212.554 154.057,213.609 154.162 C 214.852 154.285,215.584 153.765,215.584 152.759 C 215.584 152.060,215.224 151.818,213.231 151.177 C 212.918 151.077,212.662 150.839,212.662 150.649 C 212.662 150.092,213.529 149.920,214.288 150.326 C 215.205 150.817,215.606 150.407,214.791 149.811 C 214.056 149.273,213.374 149.239,212.581 149.701 M234.563 150.148 C 233.694 151.017,233.560 151.924,234.140 153.025 C 235.306 155.240,238.052 154.336,238.052 151.737 C 238.052 149.551,236.065 148.646,234.563 150.148 M247.107 149.650 C 246.856 149.810,246.454 149.865,246.215 149.773 C 245.876 149.643,245.779 150.117,245.779 151.913 C 245.779 153.235,245.918 154.221,246.104 154.221 C 246.282 154.221,246.429 153.422,246.429 152.446 C 246.429 150.986,246.547 150.609,247.099 150.314 C 248.176 149.737,248.701 150.446,248.701 152.475 C 248.701 153.435,248.847 154.221,249.026 154.221 C 249.691 154.221,249.413 150.056,248.723 149.687 C 247.962 149.280,247.702 149.274,247.107 149.650 M187.662 151.948 C 187.662 153.247,187.801 154.221,187.987 154.221 C 188.173 154.221,188.312 153.247,188.312 151.948 C 188.312 150.649,188.173 149.675,187.987 149.675 C 187.801 149.675,187.662 150.649,187.662 151.948 M205.497 150.618 C 206.338 151.799,206.341 151.766,205.319 153.106 C 204.646 153.988,204.577 154.221,204.986 154.221 C 205.271 154.221,205.744 153.856,206.036 153.409 C 206.329 152.963,206.673 152.597,206.801 152.597 C 206.929 152.597,207.229 152.963,207.468 153.409 C 207.706 153.856,208.096 154.221,208.334 154.221 C 208.924 154.221,208.867 153.881,208.117 152.922 C 207.311 151.891,207.314 151.582,208.140 150.531 C 208.964 149.484,208.230 149.303,207.305 150.325 L 206.717 150.974 206.262 150.325 C 206.012 149.968,205.587 149.675,205.317 149.675 C 204.920 149.675,204.955 149.857,205.497 150.618 M221.753 151.780 C 221.753 154.068,222.604 154.860,224.075 153.941 C 224.447 153.708,224.675 153.690,224.675 153.893 C 224.675 154.073,224.821 154.221,225.000 154.221 C 225.186 154.221,225.325 153.247,225.325 151.948 C 225.325 150.649,225.186 149.675,225.000 149.675 C 224.821 149.675,224.675 150.305,224.675 151.074 C 224.675 154.189,222.629 154.620,222.468 151.539 C 222.334 148.983,221.753 149.178,221.753 151.780 M238.722 150.081 C 238.808 150.304,239.142 151.327,239.466 152.354 C 240.192 154.660,240.724 154.722,241.242 152.563 C 241.676 150.754,242.026 150.887,242.383 152.997 C 242.687 154.799,243.353 154.499,244.126 152.210 C 244.890 149.948,244.931 149.675,244.506 149.675 C 244.341 149.675,244.030 150.223,243.814 150.893 C 243.198 152.803,243.072 152.848,242.694 151.296 C 242.183 149.195,241.452 149.223,240.862 151.366 L 240.389 153.084 239.938 151.380 C 239.662 150.337,239.309 149.675,239.027 149.675 C 238.774 149.675,238.637 149.858,238.722 150.081 M195.330 150.568 C 195.876 151.110,195.845 151.141,194.672 151.239 C 193.179 151.364,192.805 151.078,193.650 150.460 C 194.459 149.869,194.639 149.880,195.330 150.568 M202.904 150.466 C 203.444 151.116,203.200 152.947,202.516 153.375 C 201.698 153.887,200.835 153.246,200.713 152.037 C 200.554 150.455,202.022 149.402,202.904 150.466 M231.650 150.528 C 232.316 151.194,232.178 152.895,231.418 153.371 C 230.227 154.117,229.196 151.690,230.194 150.488 C 230.710 149.866,230.996 149.874,231.650 150.528 M236.845 150.528 C 237.514 151.196,237.372 152.896,236.607 153.375 C 235.774 153.896,234.924 153.238,234.799 151.975 C 234.628 150.241,235.758 149.441,236.845 150.528 M177.273 153.734 C 177.273 154.002,177.492 154.221,177.760 154.221 C 178.028 154.221,178.247 154.002,178.247 153.734 C 178.247 153.466,178.028 153.247,177.760 153.247 C 177.492 153.247,177.273 153.466,177.273 153.734 M319.156 160.065 C 319.156 162.013,319.286 163.312,319.481 163.312 C 319.659 163.312,319.805 162.654,319.805 161.851 L 319.805 160.390 321.429 160.390 C 323.494 160.390,323.560 159.808,321.510 159.677 C 319.000 159.516,319.139 157.678,321.672 157.532 C 324.109 157.391,323.783 156.818,321.266 156.818 L 319.156 156.818 319.156 160.065 M324.351 157.305 C 324.351 157.573,324.570 157.792,324.838 157.792 C 325.106 157.792,325.325 157.573,325.325 157.305 C 325.325 157.037,325.106 156.818,324.838 156.818 C 324.570 156.818,324.351 157.037,324.351 157.305 M334.869 157.386 C 334.772 157.699,334.560 158.203,334.399 158.508 C 334.217 158.849,334.226 159.136,334.422 159.257 C 334.597 159.365,334.740 160.322,334.740 161.383 C 334.740 162.452,334.885 163.312,335.065 163.312 C 335.248 163.312,335.390 162.392,335.390 161.201 C 335.390 159.436,335.479 159.091,335.939 159.091 C 336.430 159.091,336.425 159.045,335.889 158.653 C 335.248 158.185,335.449 157.468,336.220 157.468 C 336.478 157.468,336.688 157.321,336.688 157.143 C 336.688 156.564,335.056 156.782,334.869 157.386 M353.571 160.065 C 353.571 162.013,353.701 163.312,353.896 163.312 C 354.075 163.312,354.221 162.592,354.221 161.712 C 354.221 160.238,354.771 159.091,355.478 159.091 C 356.111 159.091,356.494 160.032,356.494 161.591 C 356.494 162.537,356.640 163.312,356.818 163.312 C 357.001 163.312,357.143 162.396,357.143 161.213 C 357.143 158.878,356.619 158.235,355.039 158.631 C 354.296 158.818,354.221 158.744,354.221 157.827 C 354.221 157.272,354.075 156.818,353.896 156.818 C 353.701 156.818,353.571 158.117,353.571 160.065 M369.156 157.827 C 369.156 158.753,369.086 158.819,368.310 158.624 C 366.885 158.267,365.909 159.165,365.909 160.834 C 365.909 162.648,366.598 163.302,368.435 163.228 L 369.805 163.174 369.805 159.996 C 369.805 158.094,369.675 156.818,369.481 156.818 C 369.302 156.818,369.156 157.272,369.156 157.827 M363.570 158.036 C 363.277 158.616,363.165 159.091,363.321 159.091 C 363.477 159.091,363.649 160.004,363.702 161.120 C 363.789 162.943,363.873 163.160,364.529 163.253 C 365.346 163.369,365.529 162.835,364.773 162.545 C 364.087 162.282,364.095 159.468,364.782 159.205 C 365.213 159.039,365.217 158.965,364.810 158.647 C 364.552 158.445,364.287 157.987,364.222 157.630 C 364.121 157.079,364.022 157.141,363.570 158.036 M327.354 158.673 C 326.680 158.801,326.623 158.986,326.623 161.062 C 326.623 163.773,327.200 164.082,327.338 161.445 C 327.425 159.776,327.515 159.567,328.184 159.472 C 328.596 159.413,328.879 159.203,328.813 159.005 C 328.668 158.569,328.320 158.490,327.354 158.673 M330.049 159.207 C 329.034 160.222,328.955 161.747,329.870 162.662 C 330.704 163.497,332.200 163.496,332.956 162.660 C 333.695 161.845,333.332 161.393,332.525 162.123 C 331.822 162.759,331.125 162.813,330.584 162.273 C 329.755 161.443,330.159 161.039,331.818 161.039 C 333.168 161.039,333.442 160.940,333.442 160.452 C 333.442 158.725,331.312 157.944,330.049 159.207 M337.567 159.096 C 335.853 160.444,336.767 163.312,338.911 163.312 C 340.122 163.312,340.909 162.398,340.909 160.994 C 340.909 158.840,339.157 157.845,337.567 159.096 M349.233 159.042 C 348.465 159.890,348.902 160.722,350.377 161.219 C 350.973 161.420,351.461 161.790,351.461 162.042 C 351.461 162.688,350.189 162.794,349.688 162.191 C 349.225 161.632,348.701 161.526,348.701 161.990 C 348.701 163.284,351.274 163.758,352.077 162.612 C 352.721 161.692,352.265 160.836,350.980 160.553 C 349.849 160.305,349.454 159.832,349.957 159.329 C 350.213 159.072,350.538 159.095,351.129 159.412 C 351.975 159.865,352.630 159.643,352.079 159.092 C 351.384 158.397,349.841 158.370,349.233 159.042 M372.078 158.667 C 369.891 159.448,370.520 163.312,372.834 163.312 C 375.150 163.312,375.884 159.910,373.804 158.815 C 373.043 158.414,372.834 158.397,372.078 158.667 M383.796 158.741 C 383.544 158.900,383.142 158.956,382.903 158.864 C 382.564 158.734,382.468 159.208,382.468 161.004 C 382.468 163.660,382.958 164.107,383.193 161.664 C 383.506 158.403,385.390 158.175,385.390 161.398 C 385.390 162.883,385.499 163.312,385.877 163.312 C 386.747 163.312,386.547 159.581,385.642 158.947 C 384.820 158.371,384.446 158.330,383.796 158.741 M324.351 161.039 C 324.351 162.843,324.451 163.312,324.838 163.312 C 325.224 163.312,325.325 162.843,325.325 161.039 C 325.325 159.235,325.224 158.766,324.838 158.766 C 324.451 158.766,324.351 159.235,324.351 161.039 M341.883 158.959 C 341.883 159.064,342.171 159.517,342.523 159.964 L 343.162 160.777 342.357 161.962 C 341.392 163.382,341.962 163.883,342.970 162.500 L 343.626 161.599 344.340 162.495 C 345.419 163.848,345.940 163.368,344.931 161.950 L 344.079 160.752 344.790 159.848 C 345.277 159.229,345.377 158.903,345.106 158.812 C 344.888 158.740,344.457 159.016,344.148 159.426 L 343.586 160.171 343.210 159.469 C 342.876 158.844,341.883 158.463,341.883 158.959 M358.442 160.675 C 358.442 162.966,358.775 163.326,360.823 163.236 L 362.338 163.170 362.338 160.968 C 362.338 158.158,361.460 157.709,361.299 160.437 C 361.117 163.548,359.091 163.298,359.091 160.165 C 359.091 159.396,358.945 158.766,358.766 158.766 C 358.587 158.766,358.442 159.619,358.442 160.675 M375.827 159.810 C 376.591 163.289,377.494 164.087,378.069 161.792 C 378.420 160.393,378.895 159.605,378.898 160.417 C 378.910 163.570,380.232 163.947,381.081 161.039 C 381.577 159.338,381.640 158.766,381.332 158.766 C 381.106 158.766,380.756 159.424,380.553 160.227 C 380.094 162.052,379.971 162.051,379.508 160.212 C 379.027 158.302,378.209 158.351,377.795 160.313 C 377.424 162.075,377.117 162.052,376.657 160.227 C 376.234 158.548,375.465 158.161,375.827 159.810 M332.343 159.659 C 332.889 160.201,332.858 160.232,331.685 160.330 C 330.241 160.451,329.949 160.265,330.513 159.586 C 331.052 158.936,331.640 158.960,332.343 159.659 M339.666 159.628 C 340.690 160.555,340.198 162.662,338.957 162.662 C 338.141 162.662,337.256 161.318,337.543 160.517 C 338.078 159.024,338.708 158.761,339.666 159.628 M368.816 160.142 C 369.694 161.700,368.144 163.469,366.948 162.273 C 366.391 161.716,366.467 160.203,367.083 159.587 C 367.743 158.926,368.216 159.078,368.816 160.142 M373.968 160.167 C 374.780 161.861,372.641 163.672,371.765 162.034 C 371.281 161.130,371.350 160.366,371.977 159.673 C 372.702 158.872,373.435 159.054,373.968 160.167 M12.338 175.974 C 12.338 180.097,13.215 180.873,13.379 176.894 L 13.474 174.568 15.019 176.894 C 17.182 180.152,17.532 180.024,17.532 175.974 C 17.532 171.861,16.655 171.073,16.491 175.038 L 16.396 177.349 14.819 175.038 C 12.636 171.839,12.338 171.951,12.338 175.974 M69.805 175.974 L 69.805 179.221 71.916 179.221 C 73.106 179.221,74.026 179.079,74.026 178.896 C 74.026 178.718,73.295 178.571,72.403 178.571 L 70.779 178.571 70.779 175.649 C 70.779 173.268,70.689 172.727,70.292 172.727 C 69.892 172.727,69.805 173.304,69.805 175.974 M67.532 173.682 C 67.532 174.029,67.379 174.407,67.192 174.523 C 66.966 174.662,66.960 174.863,67.173 175.120 C 67.349 175.333,67.539 176.306,67.594 177.283 C 67.682 178.841,67.784 179.071,68.425 179.162 C 69.242 179.278,69.426 178.744,68.669 178.454 C 67.964 178.184,67.994 175.376,68.704 175.104 C 69.185 174.919,69.185 174.880,68.704 174.611 C 68.417 174.450,68.182 174.033,68.182 173.685 C 68.182 173.337,68.036 173.052,67.857 173.052 C 67.679 173.052,67.532 173.336,67.532 173.682 M19.385 175.005 C 17.671 176.353,18.585 179.221,20.729 179.221 C 21.940 179.221,22.727 178.307,22.727 176.903 C 22.727 174.749,20.975 173.754,19.385 175.005 M26.506 174.951 C 25.738 175.799,26.175 176.631,27.649 177.128 C 28.246 177.329,28.734 177.699,28.734 177.951 C 28.734 178.597,27.462 178.704,26.961 178.100 C 26.497 177.541,25.974 177.435,25.974 177.899 C 25.974 179.193,28.546 179.667,29.349 178.521 C 29.994 177.601,29.538 176.745,28.253 176.462 C 27.121 176.214,26.726 175.741,27.230 175.238 C 27.486 174.981,27.811 175.004,28.402 175.321 C 29.248 175.774,29.903 175.553,29.351 175.001 C 28.656 174.306,27.114 174.279,26.506 174.951 M36.718 174.650 C 36.466 174.810,36.064 174.865,35.825 174.773 C 35.486 174.643,35.390 175.117,35.390 176.913 C 35.390 178.235,35.528 179.221,35.714 179.221 C 35.893 179.221,36.039 178.422,36.039 177.446 C 36.039 175.986,36.158 175.609,36.709 175.314 C 37.786 174.737,38.312 175.446,38.312 177.475 C 38.312 178.435,38.458 179.221,38.636 179.221 C 39.302 179.221,39.023 175.056,38.333 174.687 C 37.573 174.280,37.312 174.274,36.718 174.650 M41.021 174.828 C 39.219 176.091,40.105 179.203,42.271 179.216 C 43.208 179.221,44.505 177.876,43.791 177.638 C 43.585 177.570,43.284 177.751,43.121 178.042 C 42.421 179.294,40.909 178.398,40.909 176.732 C 40.909 175.368,41.958 174.674,42.829 175.461 C 43.535 176.100,43.831 176.111,43.831 175.498 C 43.831 174.475,42.111 174.065,41.021 174.828 M48.602 174.711 C 47.099 175.586,47.302 178.696,48.889 179.094 C 49.937 179.357,51.281 178.994,51.515 178.385 C 51.807 177.626,51.368 177.434,50.707 178.032 C 50.004 178.668,49.307 178.722,48.766 178.182 C 47.937 177.352,48.341 176.948,50.000 176.948 C 51.505 176.948,51.623 176.890,51.623 176.155 C 51.623 174.790,49.890 173.962,48.602 174.711 M58.442 174.576 C 56.266 175.354,56.915 179.221,59.221 179.221 C 60.415 179.221,61.698 178.167,61.017 177.746 C 60.795 177.609,60.501 177.734,60.331 178.039 C 59.953 178.714,58.965 178.724,58.299 178.058 C 57.529 177.288,57.976 176.948,59.759 176.948 C 61.625 176.948,61.855 176.436,60.567 175.148 C 59.773 174.354,59.368 174.245,58.442 174.576 M63.666 174.650 C 63.414 174.810,63.012 174.865,62.773 174.773 C 62.434 174.643,62.338 175.117,62.338 176.913 C 62.338 178.235,62.476 179.221,62.662 179.221 C 62.841 179.221,62.987 178.501,62.987 177.621 C 62.987 176.147,63.537 175.000,64.244 175.000 C 64.877 175.000,65.260 175.941,65.260 177.500 C 65.260 178.446,65.406 179.221,65.584 179.221 C 66.250 179.221,65.971 175.056,65.281 174.687 C 64.521 174.280,64.260 174.274,63.666 174.650 M75.328 174.932 C 74.428 175.661,74.347 177.670,75.180 178.591 C 76.005 179.503,77.411 179.398,78.223 178.365 C 79.959 176.158,77.466 173.201,75.328 174.932 M80.424 175.005 C 78.710 176.353,79.624 179.221,81.768 179.221 C 82.979 179.221,83.766 178.307,83.766 176.903 C 83.766 174.749,82.014 173.754,80.424 175.005 M85.622 174.584 L 84.717 174.721 84.810 177.864 C 84.899 180.879,85.435 182.218,85.652 179.969 C 85.725 179.221,85.884 178.981,86.221 179.111 C 88.345 179.926,89.694 176.833,88.050 174.919 C 87.564 174.354,87.348 174.324,85.622 174.584 M90.142 174.951 C 89.374 175.799,89.811 176.631,91.286 177.128 C 91.882 177.329,92.370 177.699,92.370 177.951 C 92.370 178.597,91.098 178.704,90.597 178.100 C 90.134 177.541,89.610 177.435,89.610 177.899 C 89.610 179.193,92.183 179.667,92.986 178.521 C 93.630 177.601,93.175 176.745,91.890 176.462 C 90.758 176.214,90.363 175.741,90.866 175.238 C 91.122 174.981,91.447 175.004,92.038 175.321 C 92.884 175.774,93.540 175.553,92.988 175.001 C 92.293 174.306,90.750 174.279,90.142 174.951 M30.519 174.830 C 30.519 174.915,30.879 175.941,31.319 177.109 C 32.127 179.257,32.121 180.195,31.296 180.195 C 30.799 180.195,30.684 180.707,31.121 180.977 C 31.788 181.389,34.416 176.454,34.416 174.788 C 34.416 174.065,33.540 175.187,33.094 176.481 C 32.636 177.813,32.500 177.975,32.295 177.435 C 31.455 175.233,31.165 174.675,30.861 174.675 C 30.673 174.675,30.519 174.745,30.519 174.830 M53.205 176.944 C 54.229 179.665,54.573 179.753,55.443 177.516 C 55.807 176.579,56.209 175.556,56.334 175.244 C 56.486 174.867,56.412 174.675,56.117 174.675 C 55.872 174.675,55.399 175.442,55.065 176.380 L 54.458 178.084 53.809 176.380 C 53.452 175.442,52.978 174.675,52.756 174.675 C 52.476 174.675,52.615 175.375,53.205 176.944 M21.484 175.537 C 22.508 176.464,22.016 178.571,20.775 178.571 C 19.959 178.571,19.074 177.228,19.361 176.426 C 19.896 174.933,20.526 174.670,21.484 175.537 M50.525 175.568 C 51.070 176.110,51.040 176.141,49.867 176.239 C 48.374 176.364,48.000 176.078,48.845 175.460 C 49.654 174.869,49.833 174.880,50.525 175.568 M60.000 175.390 C 60.653 176.043,60.443 176.299,59.253 176.299 C 58.628 176.299,58.117 176.182,58.117 176.039 C 58.117 175.660,58.838 175.000,59.253 175.000 C 59.450 175.000,59.786 175.175,60.000 175.390 M77.580 175.466 C 78.119 176.116,77.875 177.947,77.192 178.375 C 76.374 178.887,75.510 178.246,75.388 177.037 C 75.229 175.455,76.697 174.402,77.580 175.466 M82.523 175.537 C 83.547 176.464,83.055 178.571,81.814 178.571 C 80.998 178.571,80.113 177.228,80.400 176.426 C 80.935 174.933,81.565 174.670,82.523 175.537 M87.645 175.466 C 88.175 176.104,87.945 177.944,87.284 178.358 C 86.499 178.849,85.714 178.075,85.714 176.811 C 85.714 175.216,86.806 174.455,87.645 175.466 M44.481 176.948 C 44.481 177.127,44.992 177.273,45.617 177.273 C 46.242 177.273,46.753 177.127,46.753 176.948 C 46.753 176.769,46.242 176.623,45.617 176.623 C 44.992 176.623,44.481 176.769,44.481 176.948 M74.016 200.968 C 69.165 202.365,69.974 210.065,74.972 210.065 C 76.674 210.065,77.702 209.485,78.403 208.129 C 78.975 207.023,78.052 206.268,77.435 207.336 C 75.508 210.670,71.720 208.923,72.172 204.908 C 72.475 202.219,75.413 200.882,76.890 202.760 C 77.570 203.624,78.571 203.854,78.571 203.145 C 78.571 201.833,75.729 200.474,74.016 200.968 M107.468 205.519 C 107.468 209.343,107.545 210.065,107.955 210.065 C 108.364 210.065,108.442 209.343,108.442 205.519 C 108.442 201.696,108.364 200.974,107.955 200.974 C 107.545 200.974,107.468 201.696,107.468 205.519 M110.390 201.623 C 110.390 201.984,110.606 202.273,110.877 202.273 C 111.147 202.273,111.364 201.984,111.364 201.623 C 111.364 201.263,111.147 200.974,110.877 200.974 C 110.606 200.974,110.390 201.263,110.390 201.623 M81.529 203.529 C 80.408 203.843,79.601 205.112,80.341 205.396 C 80.694 205.531,81.056 205.362,81.370 204.913 C 81.941 204.098,83.184 204.009,83.905 204.731 C 84.366 205.192,84.596 205.844,84.298 205.844 C 83.540 205.844,80.643 206.581,80.308 206.859 C 78.931 208.002,80.112 210.065,82.143 210.065 C 82.702 210.065,83.442 209.914,83.788 209.729 C 84.220 209.497,84.416 209.497,84.416 209.729 C 84.416 209.914,84.682 210.065,85.007 210.065 C 85.543 210.065,85.586 209.803,85.466 207.224 C 85.293 203.489,84.461 202.708,81.529 203.529 M89.006 203.520 C 88.763 203.683,88.288 203.744,87.951 203.656 C 87.379 203.507,87.338 203.720,87.338 206.780 C 87.338 209.484,87.424 210.065,87.825 210.065 C 88.211 210.065,88.312 209.596,88.312 207.792 C 88.312 203.083,91.128 202.774,91.305 207.464 C 91.450 211.323,92.532 211.259,92.532 207.391 C 92.532 203.945,90.954 202.212,89.006 203.520 M94.975 203.977 C 93.516 205.244,93.461 208.094,94.870 209.407 C 96.282 210.721,99.602 209.818,99.289 208.205 C 99.125 207.356,98.516 207.390,98.115 208.271 C 97.275 210.113,95.130 208.972,95.130 206.683 C 95.130 204.505,96.653 203.504,97.890 204.870 C 98.573 205.626,99.351 205.725,99.351 205.056 C 99.351 203.510,96.361 202.773,94.975 203.977 M101.786 203.617 C 98.891 205.327,100.028 210.065,103.334 210.065 C 104.635 210.065,106.410 208.769,106.005 208.114 C 105.684 207.595,105.057 207.743,104.621 208.442 C 104.056 209.346,102.459 209.305,101.804 208.369 C 101.007 207.231,101.149 207.143,103.776 207.143 L 106.254 207.143 106.059 205.945 C 105.724 203.881,103.443 202.639,101.786 203.617 M114.938 203.563 C 114.671 203.731,114.123 203.786,113.720 203.685 C 112.995 203.503,112.987 203.538,112.987 206.783 C 112.987 209.848,113.030 210.065,113.636 210.065 C 114.227 210.065,114.286 209.848,114.286 207.680 C 114.286 204.827,114.948 203.826,116.397 204.487 C 117.163 204.836,117.208 204.999,117.208 207.461 C 117.208 209.848,117.262 210.065,117.857 210.065 C 118.525 210.065,118.820 206.559,118.312 204.666 C 118.008 203.534,116.015 202.882,114.938 203.563 M120.641 204.005 C 118.315 206.331,120.467 211.051,123.271 209.774 C 124.366 209.275,124.612 209.568,124.007 210.652 C 123.434 211.677,122.076 211.965,121.330 211.219 C 120.799 210.688,119.805 210.530,119.805 210.977 C 119.805 212.565,123.163 213.230,124.488 211.905 C 125.715 210.679,125.805 203.562,124.594 203.604 C 124.192 203.618,123.326 203.526,122.670 203.399 C 121.651 203.203,121.354 203.292,120.641 204.005 M110.390 206.818 C 110.390 209.488,110.476 210.065,110.877 210.065 C 111.277 210.065,111.364 209.488,111.364 206.818 C 111.364 204.149,111.277 203.571,110.877 203.571 C 110.476 203.571,110.390 204.149,110.390 206.818 M104.276 204.758 C 105.341 205.722,105.015 206.169,103.247 206.169 C 101.854 206.169,101.623 206.079,101.623 205.536 C 101.623 204.339,103.277 203.854,104.276 204.758 M123.701 204.870 C 124.959 206.128,124.162 209.091,122.565 209.091 C 121.687 209.091,120.779 207.854,120.779 206.656 C 120.779 205.458,121.687 204.221,122.565 204.221 C 122.833 204.221,123.344 204.513,123.701 204.870 M84.416 207.233 C 84.416 208.112,83.400 209.091,82.489 209.091 C 80.550 209.091,80.564 207.602,82.507 207.144 C 84.127 206.761,84.416 206.775,84.416 207.233 M105.519 228.896 C 105.519 232.723,106.097 233.323,106.236 229.641 L 106.331 227.139 107.955 229.637 C 110.136 232.993,110.390 232.916,110.390 228.896 C 110.390 226.948,110.260 225.649,110.065 225.649 C 109.879 225.649,109.740 226.623,109.740 227.922 C 109.740 230.736,109.607 230.736,107.792 227.922 C 105.785 224.809,105.519 224.923,105.519 228.896 M118.969 226.191 C 119.084 226.489,119.483 227.950,119.856 229.438 C 120.818 233.276,121.324 232.979,122.579 227.843 C 122.898 226.536,123.187 226.950,123.870 229.691 C 124.769 233.300,125.105 233.082,126.485 227.994 C 126.790 226.873,126.937 225.855,126.813 225.731 C 126.462 225.380,126.081 226.215,125.638 228.300 C 125.085 230.904,124.893 230.873,124.194 228.066 C 123.355 224.697,122.747 224.761,121.725 228.328 L 120.958 231.006 120.345 228.328 C 119.913 226.441,119.589 225.649,119.247 225.649 C 118.927 225.649,118.833 225.834,118.969 226.191 M135.714 228.896 C 135.714 231.929,136.195 233.431,136.424 231.113 C 136.565 229.686,137.112 229.642,137.843 230.998 C 138.182 231.628,138.645 232.143,138.873 232.143 C 139.474 232.143,139.388 231.794,138.443 230.405 L 137.601 229.165 138.338 228.381 C 139.375 227.277,138.438 227.355,137.274 228.470 L 136.364 229.342 136.364 227.496 C 136.364 226.480,136.218 225.649,136.039 225.649 C 135.844 225.649,135.714 226.948,135.714 228.896 M148.377 228.896 C 148.377 230.844,148.506 232.143,148.701 232.143 C 148.880 232.143,149.026 231.485,149.026 230.682 C 149.026 229.280,149.065 229.221,149.984 229.221 C 150.755 229.221,151.140 229.507,151.948 230.682 C 152.501 231.485,153.174 232.143,153.444 232.143 C 153.987 232.143,153.884 231.883,152.712 230.298 C 151.786 229.044,151.783 229.015,152.597 228.802 C 153.093 228.672,153.247 228.359,153.247 227.477 C 153.247 226.028,152.612 225.649,150.184 225.649 L 148.377 225.649 148.377 228.896 M159.983 226.542 C 159.768 227.033,159.442 227.542,159.260 227.674 C 159.050 227.825,159.077 227.914,159.334 227.917 C 159.617 227.921,159.740 228.563,159.740 230.032 C 159.740 231.692,159.844 232.143,160.227 232.143 C 160.610 232.143,160.714 231.695,160.714 230.056 C 160.714 228.342,160.816 227.943,161.282 227.821 C 161.824 227.680,161.824 227.671,161.282 227.635 C 160.595 227.589,160.498 226.299,161.182 226.299 C 161.439 226.299,161.740 226.153,161.851 225.974 C 161.965 225.790,161.689 225.649,161.213 225.649 C 160.611 225.649,160.265 225.900,159.983 226.542 M171.753 228.896 C 171.753 233.019,172.631 233.795,172.794 229.817 L 172.890 227.490 174.434 229.817 C 176.598 233.074,176.948 232.946,176.948 228.896 C 176.948 224.784,176.071 223.995,175.907 227.960 L 175.812 230.271 174.235 227.960 C 172.052 224.761,171.753 224.874,171.753 228.896 M188.312 226.136 C 188.312 226.404,188.458 226.623,188.636 226.623 C 188.815 226.623,188.961 226.404,188.961 226.136 C 188.961 225.869,188.815 225.649,188.636 225.649 C 188.458 225.649,188.312 225.869,188.312 226.136 M222.403 228.896 C 222.403 232.723,222.980 233.323,223.119 229.641 L 223.214 227.139 224.838 229.637 C 227.019 232.993,227.273 232.916,227.273 228.896 C 227.273 226.948,227.143 225.649,226.948 225.649 C 226.760 225.649,226.622 226.706,226.621 228.166 L 226.619 230.682 224.953 228.166 C 222.696 224.754,222.403 224.838,222.403 228.896 M279.870 228.896 L 279.870 232.143 281.818 232.143 C 282.900 232.143,283.766 231.999,283.766 231.818 C 283.766 231.640,283.109 231.494,282.305 231.494 L 280.844 231.494 280.844 228.571 C 280.844 226.190,280.754 225.649,280.357 225.649 C 279.957 225.649,279.870 226.227,279.870 228.896 M186.039 226.604 C 186.039 226.951,185.886 227.329,185.699 227.445 C 185.473 227.584,185.466 227.785,185.679 228.042 C 185.856 228.255,186.045 229.228,186.101 230.205 C 186.192 231.819,186.275 231.991,187.012 232.095 C 187.794 232.205,187.803 232.187,187.256 231.582 C 186.581 230.837,186.462 228.067,187.094 227.812 C 187.419 227.681,187.419 227.644,187.094 227.623 C 186.871 227.609,186.688 227.232,186.688 226.786 C 186.688 226.339,186.542 225.974,186.364 225.974 C 186.185 225.974,186.039 226.258,186.039 226.604 M277.597 226.604 C 277.597 226.951,277.444 227.329,277.257 227.445 C 277.031 227.584,277.025 227.785,277.238 228.042 C 277.414 228.255,277.604 229.228,277.659 230.205 C 277.751 231.819,277.834 231.991,278.571 232.095 C 279.352 232.205,279.361 232.187,278.814 231.582 C 278.140 230.837,278.021 228.067,278.653 227.812 C 278.977 227.681,278.977 227.644,278.653 227.623 C 278.429 227.609,278.247 227.232,278.247 226.786 C 278.247 226.339,278.101 225.974,277.922 225.974 C 277.744 225.974,277.597 226.258,277.597 226.604 M151.969 226.635 C 153.263 227.327,152.191 228.571,150.301 228.571 C 149.060 228.571,149.026 228.541,149.026 227.435 C 149.026 226.203,150.442 225.818,151.969 226.635 M112.341 227.854 C 111.441 228.583,111.360 230.592,112.193 231.513 C 113.018 232.425,114.424 232.320,115.236 231.287 C 116.972 229.080,114.479 226.123,112.341 227.854 M128.250 227.854 C 127.350 228.583,127.269 230.592,128.102 231.513 C 128.927 232.425,130.333 232.320,131.145 231.287 C 132.881 229.080,130.388 226.123,128.250 227.854 M133.523 227.504 C 132.849 227.632,132.792 227.817,132.792 229.893 C 132.792 232.604,133.369 232.913,133.507 230.276 C 133.594 228.607,133.684 228.398,134.353 228.303 C 134.765 228.244,135.048 228.034,134.982 227.836 C 134.837 227.401,134.488 227.321,133.523 227.504 M140.763 228.039 C 139.748 229.053,139.669 230.578,140.584 231.494 C 141.419 232.328,142.915 232.327,143.671 231.492 C 144.409 230.676,144.046 230.224,143.239 230.954 C 142.536 231.591,141.839 231.644,141.299 231.104 C 140.469 230.274,140.873 229.870,142.532 229.870 C 143.882 229.870,144.156 229.771,144.156 229.283 C 144.156 227.556,142.026 226.775,140.763 228.039 M146.275 227.583 C 146.169 227.754,145.869 227.811,145.606 227.711 C 145.215 227.561,145.130 227.940,145.130 229.835 C 145.130 231.157,145.269 232.143,145.455 232.143 C 145.633 232.143,145.779 231.641,145.779 231.028 C 145.779 229.414,146.270 228.365,147.134 228.129 C 147.762 227.957,147.807 227.868,147.403 227.602 C 146.786 227.198,146.516 227.193,146.275 227.583 M155.844 227.498 C 153.750 228.247,154.266 232.143,156.459 232.143 C 157.453 232.143,158.442 231.570,158.442 230.995 C 158.442 230.381,157.982 230.387,157.468 231.006 C 156.904 231.685,155.932 231.614,155.531 230.866 C 155.017 229.905,155.068 229.870,157.002 229.870 C 158.723 229.870,158.800 229.835,158.598 229.140 C 158.202 227.781,157.022 227.077,155.844 227.498 M162.553 227.753 C 161.554 228.752,161.953 229.502,163.799 230.097 C 164.334 230.270,164.773 230.616,164.773 230.867 C 164.773 231.555,163.671 231.625,162.961 230.983 C 162.227 230.319,161.717 230.625,162.220 231.428 C 162.644 232.106,164.478 232.332,165.135 231.787 C 165.992 231.076,165.553 229.805,164.305 229.388 C 163.691 229.182,163.131 228.841,163.061 228.630 C 162.874 228.070,163.890 227.784,164.441 228.241 C 165.023 228.724,165.655 228.556,165.314 228.008 C 164.880 227.310,163.156 227.150,162.553 227.753 M178.801 227.927 C 177.087 229.275,178.001 232.143,180.144 232.143 C 181.355 232.143,182.143 231.230,182.143 229.825 C 182.143 227.671,180.391 226.676,178.801 227.927 M191.588 227.572 C 191.336 227.732,190.934 227.787,190.695 227.695 C 190.356 227.565,190.260 228.040,190.260 229.835 C 190.260 231.157,190.398 232.143,190.584 232.143 C 190.763 232.143,190.909 231.423,190.909 230.543 C 190.909 227.386,192.641 227.015,192.791 230.139 C 192.922 232.841,193.831 233.066,193.831 230.397 C 193.831 228.417,194.432 227.533,195.292 228.247 C 195.615 228.514,195.779 229.241,195.779 230.397 C 195.779 231.357,195.925 232.143,196.104 232.143 C 196.286 232.143,196.429 231.236,196.429 230.072 C 196.429 227.619,195.944 226.946,194.615 227.551 C 194.050 227.808,193.604 227.823,193.185 227.599 C 192.443 227.202,192.180 227.198,191.588 227.572 M198.602 227.633 C 197.099 228.508,197.302 231.618,198.889 232.016 C 199.937 232.279,201.281 231.916,201.515 231.307 C 201.807 230.548,201.368 230.356,200.707 230.954 C 200.004 231.591,199.307 231.644,198.766 231.104 C 197.937 230.274,198.341 229.870,200.000 229.870 C 201.505 229.870,201.623 229.812,201.623 229.077 C 201.623 227.712,199.890 226.884,198.602 227.633 M203.250 227.854 C 202.350 228.583,202.269 230.592,203.102 231.513 C 203.927 232.425,205.333 232.320,206.145 231.287 C 207.881 229.080,205.388 226.123,203.250 227.854 M213.231 227.623 C 212.086 228.290,212.630 229.535,214.286 230.036 C 215.761 230.483,215.872 231.494,214.445 231.494 C 214.018 231.494,213.526 231.239,213.352 230.928 C 213.178 230.617,212.920 230.478,212.779 230.619 C 212.307 231.091,213.204 231.979,214.258 232.084 C 215.502 232.207,216.234 231.687,216.234 230.681 C 216.234 229.982,215.873 229.740,213.880 229.099 C 213.567 228.999,213.312 228.761,213.312 228.571 C 213.312 228.014,214.179 227.842,214.938 228.248 C 215.855 228.739,216.255 228.329,215.441 227.733 C 214.705 227.195,214.023 227.162,213.231 227.623 M229.870 227.498 C 227.683 228.280,228.312 232.143,230.626 232.143 C 232.942 232.143,233.676 228.741,231.596 227.646 C 230.835 227.246,230.627 227.228,229.870 227.498 M236.579 227.753 C 235.580 228.752,235.979 229.502,237.825 230.097 C 238.360 230.270,238.799 230.616,238.799 230.867 C 238.799 231.555,237.697 231.625,236.987 230.983 C 236.253 230.319,235.743 230.625,236.246 231.428 C 236.670 232.106,238.504 232.332,239.161 231.787 C 240.018 231.076,239.579 229.805,238.331 229.388 C 237.717 229.182,237.157 228.841,237.087 228.630 C 236.900 228.070,237.916 227.784,238.467 228.241 C 239.049 228.724,239.681 228.556,239.340 228.008 C 238.906 227.310,237.182 227.150,236.579 227.753 M246.753 227.595 C 246.485 227.767,246.011 227.828,245.698 227.730 C 245.194 227.574,245.130 227.812,245.130 229.848 C 245.130 231.671,245.230 232.143,245.617 232.143 C 245.989 232.143,246.104 231.732,246.104 230.397 C 246.104 228.566,246.593 227.756,247.492 228.101 C 248.078 228.326,248.366 229.249,248.372 230.925 C 248.375 231.595,248.523 232.143,248.701 232.143 C 248.881 232.143,249.026 231.285,249.026 230.218 C 249.026 227.722,248.143 226.703,246.753 227.595 M251.000 227.841 C 249.393 229.154,250.067 232.143,251.969 232.143 C 252.914 232.143,253.896 231.558,253.896 230.995 C 253.896 230.373,253.279 230.381,253.039 231.006 C 252.520 232.360,250.873 231.138,251.033 229.518 C 251.170 228.139,252.017 227.590,252.847 228.342 C 253.897 229.291,254.386 228.783,253.386 227.783 C 252.719 227.116,251.862 227.136,251.000 227.841 M258.296 228.039 C 257.281 229.053,257.202 230.578,258.117 231.494 C 258.951 232.328,260.447 232.327,261.203 231.492 C 261.941 230.676,261.579 230.224,260.772 230.954 C 260.069 231.591,259.372 231.644,258.831 231.104 C 258.001 230.274,258.406 229.870,260.065 229.870 C 261.415 229.870,261.688 229.771,261.688 229.283 C 261.688 227.556,259.559 226.775,258.296 228.039 M268.506 227.498 C 266.412 228.247,266.928 232.143,269.122 232.143 C 270.115 232.143,271.104 231.570,271.104 230.995 C 271.104 230.381,270.644 230.387,270.130 231.006 C 269.567 231.685,268.594 231.614,268.193 230.866 C 267.679 229.905,267.730 229.870,269.665 229.870 C 271.386 229.870,271.462 229.835,271.260 229.140 C 270.865 227.781,269.685 227.077,268.506 227.498 M273.731 227.572 C 273.479 227.732,273.077 227.787,272.838 227.695 C 272.499 227.565,272.403 228.040,272.403 229.835 C 272.403 231.157,272.541 232.143,272.727 232.143 C 272.906 232.143,273.052 231.344,273.052 230.369 C 273.052 228.908,273.171 228.531,273.722 228.236 C 274.799 227.659,275.325 228.368,275.325 230.397 C 275.325 231.357,275.471 232.143,275.649 232.143 C 276.315 232.143,276.036 227.978,275.346 227.609 C 274.586 227.202,274.325 227.196,273.731 227.572 M285.393 227.854 C 284.493 228.583,284.412 230.592,285.245 231.513 C 286.070 232.425,287.476 232.320,288.288 231.287 C 290.024 229.080,287.531 226.123,285.393 227.854 M290.909 227.498 C 288.722 228.280,289.351 232.143,291.665 232.143 C 293.981 232.143,294.715 228.741,292.635 227.646 C 291.874 227.246,291.666 227.228,290.909 227.498 M296.133 227.572 C 295.882 227.732,295.480 227.787,295.240 227.695 C 294.707 227.490,294.599 233.600,295.130 233.929 C 295.323 234.048,295.455 233.664,295.455 232.982 C 295.455 231.878,295.492 231.842,296.437 232.031 C 297.869 232.317,298.701 231.451,298.701 229.676 C 298.701 227.839,297.398 226.772,296.133 227.572 M300.215 227.753 C 299.217 228.752,299.615 229.502,301.461 230.097 C 301.997 230.270,302.435 230.616,302.435 230.867 C 302.435 231.555,301.333 231.625,300.623 230.983 C 299.890 230.319,299.379 230.625,299.882 231.428 C 300.307 232.106,302.140 232.332,302.797 231.787 C 303.655 231.076,303.215 229.805,301.968 229.388 C 301.353 229.182,300.793 228.841,300.723 228.630 C 300.536 228.070,301.552 227.784,302.104 228.241 C 302.686 228.724,303.317 228.556,302.977 228.008 C 302.543 227.310,300.818 227.150,300.215 227.753 M188.312 229.870 C 188.312 231.169,188.451 232.143,188.636 232.143 C 188.822 232.143,188.961 231.169,188.961 229.870 C 188.961 228.571,188.822 227.597,188.636 227.597 C 188.451 227.597,188.312 228.571,188.312 229.870 M207.792 229.481 C 207.792 231.484,208.154 232.143,209.253 232.143 C 209.628 232.143,210.110 231.968,210.325 231.753 C 210.628 231.450,210.714 231.450,210.714 231.753 C 210.714 231.968,210.860 232.143,211.039 232.143 C 211.224 232.143,211.364 231.169,211.364 229.870 C 211.364 228.571,211.224 227.597,211.039 227.597 C 210.860 227.597,210.714 228.310,210.714 229.181 C 210.714 232.257,208.686 232.338,208.506 229.269 C 208.371 226.979,207.792 227.151,207.792 229.481 M240.584 227.883 C 240.584 228.070,240.877 228.964,241.234 229.870 C 241.591 230.776,241.883 231.818,241.883 232.185 C 241.883 232.580,241.618 232.922,241.234 233.023 C 240.547 233.202,240.387 233.606,240.880 233.910 C 241.586 234.347,242.251 233.533,243.208 231.058 C 243.772 229.601,244.304 228.226,244.391 228.003 C 244.479 227.780,244.381 227.597,244.174 227.597 C 243.838 227.597,243.553 228.133,242.705 230.357 C 242.500 230.897,242.364 230.735,241.906 229.403 C 241.410 227.963,240.584 227.014,240.584 227.883 M263.152 229.746 C 263.597 230.928,263.961 231.951,263.961 232.019 C 263.961 232.432,264.888 232.042,265.020 231.575 C 265.108 231.262,265.488 230.239,265.864 229.302 C 266.409 227.946,266.456 227.597,266.093 227.597 C 265.834 227.597,265.404 228.299,265.097 229.221 C 264.801 230.114,264.509 230.844,264.448 230.844 C 264.387 230.844,264.095 230.114,263.799 229.221 C 263.491 228.294,263.063 227.597,262.801 227.597 C 262.442 227.597,262.518 228.062,263.152 229.746 M114.593 228.388 C 115.132 229.038,114.888 230.869,114.205 231.297 C 113.387 231.809,112.523 231.168,112.401 229.959 C 112.242 228.377,113.710 227.324,114.593 228.388 M130.502 228.388 C 131.041 229.038,130.797 230.869,130.114 231.297 C 129.296 231.809,128.432 231.168,128.310 229.959 C 128.151 228.377,129.619 227.324,130.502 228.388 M143.058 228.490 C 143.603 229.032,143.572 229.063,142.399 229.161 C 140.955 229.282,140.663 229.096,141.227 228.417 C 141.766 227.768,142.354 227.791,143.058 228.490 M157.474 228.417 C 158.038 229.096,157.746 229.282,156.302 229.161 C 155.129 229.063,155.098 229.032,155.644 228.490 C 156.347 227.791,156.935 227.768,157.474 228.417 M180.900 228.459 C 181.924 229.386,181.431 231.494,180.191 231.494 C 179.375 231.494,178.489 230.150,178.777 229.348 C 179.312 227.855,179.941 227.592,180.900 228.459 M200.525 228.490 C 201.070 229.032,201.040 229.063,199.867 229.161 C 198.374 229.286,198.000 229.001,198.845 228.383 C 199.654 227.791,199.833 227.803,200.525 228.490 M205.502 228.388 C 206.041 229.038,205.797 230.869,205.114 231.297 C 204.296 231.809,203.432 231.168,203.310 229.959 C 203.151 228.377,204.619 227.324,205.502 228.388 M231.761 228.999 C 232.572 230.692,230.434 232.504,229.557 230.866 C 229.073 229.962,229.142 229.197,229.769 228.504 C 230.494 227.703,231.227 227.885,231.761 228.999 M260.590 228.490 C 261.135 229.032,261.105 229.063,259.931 229.161 C 258.488 229.282,258.196 229.096,258.760 228.417 C 259.299 227.768,259.887 227.791,260.590 228.490 M270.136 228.417 C 270.700 229.096,270.409 229.282,268.965 229.161 C 267.791 229.063,267.761 229.032,268.306 228.490 C 269.009 227.791,269.598 227.768,270.136 228.417 M287.645 228.388 C 288.184 229.038,287.940 230.869,287.256 231.297 C 286.439 231.809,285.575 231.168,285.453 229.959 C 285.294 228.377,286.762 227.324,287.645 228.388 M292.800 228.999 C 293.611 230.692,291.472 232.504,290.596 230.866 C 290.112 229.962,290.181 229.197,290.808 228.504 C 291.533 227.703,292.266 227.885,292.800 228.999 M297.792 228.747 C 298.342 229.954,297.788 231.331,296.753 231.331 C 295.618 231.331,295.143 229.907,295.895 228.759 C 296.591 227.696,297.312 227.692,297.792 228.747 M254.545 229.870 C 254.545 230.049,255.057 230.195,255.682 230.195 C 256.307 230.195,256.818 230.049,256.818 229.870 C 256.818 229.692,256.307 229.545,255.682 229.545 C 255.057 229.545,254.545 229.692,254.545 229.870 M166.980 232.333 C 167.010 233.371,167.059 233.435,167.435 232.920 C 167.992 232.159,167.974 231.169,167.402 231.169 C 167.091 231.169,166.958 231.535,166.980 232.333 M217.628 232.285 C 217.646 232.899,217.777 233.328,217.921 233.240 C 218.280 233.018,218.252 231.169,217.889 231.169 C 217.728 231.169,217.611 231.671,217.628 232.285 M304.643 232.333 C 304.672 233.371,304.722 233.435,305.098 232.920 C 305.655 232.159,305.636 231.169,305.065 231.169 C 304.753 231.169,304.620 231.535,304.643 232.333 M105.519 239.610 C 105.519 243.437,106.097 244.037,106.236 240.355 L 106.331 237.853 107.955 240.351 C 110.136 243.708,110.390 243.631,110.390 239.610 C 110.390 237.662,110.260 236.364,110.065 236.364 C 109.879 236.364,109.740 237.338,109.740 238.636 C 109.740 241.451,109.607 241.451,107.792 238.636 C 105.785 235.523,105.519 235.637,105.519 239.610 M137.338 237.363 C 137.338 238.287,137.269 238.348,136.438 238.166 C 135.003 237.850,134.253 238.624,134.253 240.422 C 134.253 242.245,134.909 242.871,136.744 242.799 L 137.987 242.751 137.987 239.557 C 137.987 237.645,137.857 236.364,137.662 236.364 C 137.484 236.364,137.338 236.814,137.338 237.363 M139.286 236.851 C 139.286 237.119,139.505 237.338,139.773 237.338 C 140.041 237.338,140.260 237.119,140.260 236.851 C 140.260 236.583,140.041 236.364,139.773 236.364 C 139.505 236.364,139.286 236.583,139.286 236.851 M154.537 237.744 C 153.746 239.486,153.739 241.344,154.519 243.061 C 155.132 244.410,156.230 245.562,155.691 244.290 C 154.593 241.696,154.527 238.867,155.522 237.008 C 155.768 236.549,155.766 236.364,155.515 236.364 C 155.321 236.364,154.881 236.985,154.537 237.744 M182.468 239.610 C 182.468 241.558,182.597 242.857,182.792 242.857 C 182.987 242.857,183.117 241.558,183.117 239.610 C 183.117 237.662,182.987 236.364,182.792 236.364 C 182.597 236.364,182.468 237.662,182.468 239.610 M214.610 239.610 C 214.610 241.558,214.740 242.857,214.935 242.857 C 215.130 242.857,215.260 241.558,215.260 239.610 C 215.260 237.662,215.130 236.364,214.935 236.364 C 214.740 236.364,214.610 237.662,214.610 239.610 M224.351 237.330 C 224.351 238.212,224.273 238.280,223.450 238.115 C 222.265 237.878,221.299 238.915,221.299 240.422 C 221.299 242.041,222.170 242.838,223.903 242.803 L 225.325 242.775 225.325 239.569 C 225.325 236.936,225.238 236.364,224.838 236.364 C 224.514 236.364,224.351 236.687,224.351 237.330 M231.494 239.540 L 231.494 242.716 232.941 242.779 C 234.107 242.830,234.487 242.703,234.890 242.128 C 236.146 240.334,234.976 237.741,233.096 238.154 C 232.203 238.350,232.143 238.301,232.143 237.363 C 232.143 236.814,231.997 236.364,231.818 236.364 C 231.624 236.364,231.494 237.639,231.494 239.540 M259.740 236.467 C 259.740 236.545,259.959 237.134,260.227 237.775 C 260.892 239.366,260.827 241.765,260.074 243.425 C 259.729 244.184,259.583 244.805,259.750 244.805 C 261.092 244.805,261.940 239.719,260.925 237.756 C 260.458 236.853,259.740 236.072,259.740 236.467 M285.390 239.578 L 285.390 242.792 286.607 242.806 C 288.450 242.826,288.888 242.600,289.275 241.427 C 289.897 239.544,288.582 237.651,287.001 238.153 C 286.462 238.324,286.364 238.201,286.364 237.360 C 286.364 236.691,286.204 236.364,285.877 236.364 C 285.477 236.364,285.390 236.937,285.390 239.578 M290.584 239.610 C 290.584 241.558,290.714 242.857,290.909 242.857 C 291.104 242.857,291.234 241.558,291.234 239.610 C 291.234 237.662,291.104 236.364,290.909 236.364 C 290.714 236.364,290.584 237.662,290.584 239.610 M204.221 237.319 C 204.221 237.665,204.068 238.043,203.880 238.159 C 203.655 238.299,203.648 238.500,203.861 238.756 C 204.037 238.969,204.227 239.942,204.283 240.919 C 204.374 242.533,204.457 242.705,205.194 242.809 C 205.976 242.919,205.984 242.901,205.437 242.296 C 204.763 241.551,204.644 238.782,205.276 238.527 C 205.601 238.396,205.601 238.358,205.276 238.337 C 205.053 238.323,204.870 237.946,204.870 237.500 C 204.870 237.054,204.724 236.688,204.545 236.688 C 204.367 236.688,204.221 236.972,204.221 237.319 M112.341 238.568 C 111.441 239.297,111.360 241.307,112.193 242.228 C 113.018 243.139,114.424 243.035,115.236 242.002 C 116.972 239.795,114.479 236.837,112.341 238.568 M120.809 238.287 C 120.557 238.446,120.155 238.501,119.916 238.409 C 119.570 238.277,119.481 238.887,119.481 241.361 C 119.481 243.224,119.611 244.481,119.805 244.481 C 119.984 244.481,120.130 244.062,120.130 243.552 C 120.130 242.747,120.234 242.642,120.905 242.771 C 122.080 242.995,122.998 242.336,123.230 241.102 C 123.608 239.085,122.177 237.420,120.809 238.287 M125.226 238.348 C 123.722 239.222,123.926 242.332,125.512 242.730 C 126.561 242.993,127.905 242.631,128.138 242.022 C 128.430 241.262,127.991 241.070,127.330 241.669 C 126.627 242.305,125.930 242.359,125.390 241.818 C 124.560 240.989,124.964 240.584,126.623 240.584 C 128.128 240.584,128.247 240.527,128.247 239.791 C 128.247 238.426,126.514 237.598,125.226 238.348 M130.844 238.309 C 130.576 238.481,130.101 238.542,129.789 238.445 C 129.285 238.288,129.221 238.526,129.221 240.563 C 129.221 242.386,129.321 242.857,129.708 242.857 C 130.080 242.857,130.195 242.447,130.195 241.111 C 130.195 239.280,130.684 238.471,131.583 238.816 C 132.169 239.041,132.457 239.963,132.463 241.640 C 132.466 242.309,132.614 242.857,132.792 242.857 C 132.972 242.857,133.117 241.999,133.117 240.932 C 133.117 238.436,132.234 237.418,130.844 238.309 M142.857 238.309 C 142.589 238.481,142.114 238.542,141.802 238.445 C 141.298 238.288,141.234 238.526,141.234 240.563 C 141.234 242.386,141.334 242.857,141.721 242.857 C 142.093 242.857,142.208 242.447,142.208 241.111 C 142.208 239.280,142.697 238.471,143.596 238.816 C 144.182 239.041,144.470 239.963,144.476 241.640 C 144.479 242.309,144.627 242.857,144.805 242.857 C 144.985 242.857,145.130 241.999,145.130 240.932 C 145.130 238.436,144.247 237.418,142.857 238.309 M147.208 238.235 C 145.224 239.560,146.191 243.181,148.410 242.737 C 149.522 242.514,149.741 243.275,148.723 243.820 C 147.910 244.255,147.867 244.249,147.261 243.643 C 146.546 242.928,145.964 243.190,146.534 243.970 C 147.059 244.689,148.734 244.802,149.496 244.170 C 150.215 243.573,150.242 238.150,149.523 238.425 C 149.261 238.526,148.960 238.468,148.855 238.298 C 148.628 237.931,147.715 237.897,147.208 238.235 M158.146 238.287 C 157.895 238.446,157.493 238.501,157.253 238.409 C 156.915 238.279,156.818 238.754,156.818 240.550 C 156.818 243.206,157.309 243.652,157.543 241.210 C 157.857 237.948,159.740 237.720,159.740 240.944 C 159.740 242.428,159.849 242.857,160.227 242.857 C 161.098 242.857,160.898 239.126,159.993 238.492 C 159.171 237.917,158.796 237.875,158.146 238.287 M162.987 238.212 C 160.800 238.994,161.429 242.857,163.743 242.857 C 166.059 242.857,166.793 239.455,164.713 238.360 C 163.952 237.960,163.743 237.942,162.987 238.212 M168.028 238.298 C 167.923 238.468,167.622 238.526,167.360 238.425 C 166.968 238.275,166.883 238.654,166.883 240.550 C 166.883 241.872,167.022 242.857,167.208 242.857 C 167.386 242.857,167.532 242.355,167.532 241.742 C 167.532 240.129,168.023 239.080,168.887 238.843 C 169.515 238.671,169.560 238.582,169.156 238.317 C 168.539 237.912,168.269 237.907,168.028 238.298 M171.266 238.289 C 170.909 238.431,170.434 238.478,170.211 238.394 C 169.910 238.282,169.805 238.839,169.805 240.550 C 169.805 242.384,169.905 242.857,170.292 242.857 C 170.666 242.857,170.779 242.444,170.779 241.083 C 170.779 239.690,170.908 239.240,171.379 238.988 C 172.297 238.497,172.727 239.183,172.727 241.136 C 172.727 242.083,172.873 242.857,173.052 242.857 C 173.231 242.857,173.377 242.137,173.377 241.257 C 173.377 238.100,175.108 237.729,175.259 240.854 C 175.395 243.679,176.299 243.747,176.299 240.932 C 176.299 238.738,175.697 237.786,174.546 238.156 C 173.676 238.435,173.017 238.454,172.403 238.219 C 172.135 238.116,171.623 238.148,171.266 238.289 M177.877 238.608 C 177.455 238.950,177.219 239.339,177.352 239.472 C 177.485 239.606,177.876 239.459,178.221 239.147 C 178.955 238.483,179.982 238.580,180.126 239.328 C 180.198 239.707,179.821 239.952,178.749 240.222 C 175.808 240.962,176.736 242.808,180.036 242.781 L 181.339 242.770 181.164 240.686 C 180.935 237.955,179.669 237.155,177.877 238.608 M190.007 238.492 C 188.392 239.624,189.342 242.857,191.290 242.857 C 192.028 242.857,193.182 242.000,193.182 241.452 C 193.182 241.021,192.273 241.245,192.090 241.721 C 191.825 242.413,190.669 242.324,190.271 241.580 C 189.324 239.810,190.733 237.858,192.025 239.149 C 192.307 239.432,192.710 239.605,192.921 239.535 C 193.461 239.355,192.033 237.987,191.306 237.987 C 190.989 237.987,190.404 238.214,190.007 238.492 M194.484 238.568 C 193.584 239.297,193.503 241.307,194.336 242.228 C 195.161 243.139,196.566 243.035,197.379 242.002 C 199.115 239.795,196.622 236.837,194.484 238.568 M200.354 238.287 C 200.102 238.446,199.701 238.501,199.461 238.409 C 199.122 238.279,199.026 238.754,199.026 240.550 C 199.026 241.872,199.165 242.857,199.351 242.857 C 199.529 242.857,199.675 242.059,199.675 241.083 C 199.675 239.623,199.794 239.245,200.345 238.950 C 201.423 238.373,201.948 239.082,201.948 241.111 C 201.948 242.071,202.094 242.857,202.273 242.857 C 202.938 242.857,202.659 238.692,201.969 238.323 C 201.209 237.916,200.949 237.910,200.354 238.287 M207.649 238.280 C 207.538 238.461,207.232 238.526,206.970 238.425 C 206.579 238.275,206.494 238.654,206.494 240.550 C 206.494 241.872,206.632 242.857,206.818 242.857 C 206.997 242.857,207.143 242.212,207.143 241.423 C 207.143 239.555,207.393 238.961,208.179 238.961 C 208.532 238.961,208.763 238.788,208.692 238.575 C 208.518 238.053,207.898 237.877,207.649 238.280 M209.888 238.784 C 209.018 239.653,208.885 240.560,209.464 241.661 C 210.630 243.876,213.377 242.973,213.377 240.374 C 213.377 238.187,211.390 237.282,209.888 238.784 M227.597 238.212 C 225.422 238.990,226.071 242.857,228.377 242.857 C 229.570 242.857,230.854 241.803,230.173 241.383 C 229.951 241.245,229.657 241.370,229.487 241.675 C 229.109 242.351,228.121 242.360,227.455 241.695 C 226.685 240.924,227.132 240.584,228.915 240.584 C 230.781 240.584,231.011 240.072,229.723 238.784 C 228.929 237.990,228.524 237.881,227.597 238.212 M242.338 238.235 C 240.354 239.560,241.321 243.181,243.540 242.737 C 244.652 242.514,244.871 243.275,243.853 243.820 C 243.040 244.255,242.997 244.249,242.390 243.643 C 241.676 242.928,241.093 243.190,241.664 243.970 C 242.189 244.689,243.864 244.802,244.626 244.170 C 245.345 243.573,245.371 238.150,244.653 238.425 C 244.391 238.526,244.090 238.468,243.985 238.298 C 243.758 237.931,242.845 237.897,242.338 238.235 M246.993 238.551 C 245.459 240.246,246.572 243.217,248.555 242.720 C 249.132 242.575,249.351 242.653,249.351 243.002 C 249.351 243.798,248.238 244.203,247.529 243.667 C 246.732 243.063,246.429 243.066,246.429 243.677 C 246.429 244.126,247.623 244.805,248.413 244.805 C 248.588 244.805,249.089 244.447,249.528 244.008 C 250.475 243.061,250.767 238.312,249.878 238.312 C 249.633 238.312,249.008 238.227,248.491 238.124 C 247.810 237.987,247.396 238.105,246.993 238.551 M252.597 238.212 C 250.422 238.990,251.071 242.857,253.377 242.857 C 254.570 242.857,255.854 241.803,255.173 241.383 C 254.951 241.245,254.657 241.370,254.487 241.675 C 254.109 242.351,253.121 242.360,252.455 241.695 C 251.685 240.924,252.132 240.584,253.915 240.584 C 255.781 240.584,256.011 240.072,254.723 238.784 C 253.929 237.990,253.524 237.881,252.597 238.212 M257.639 238.298 C 257.533 238.468,257.232 238.526,256.970 238.425 C 256.579 238.275,256.494 238.654,256.494 240.550 C 256.494 241.872,256.632 242.857,256.818 242.857 C 256.997 242.857,257.143 242.355,257.143 241.742 C 257.143 240.129,257.633 239.080,258.498 238.843 C 259.125 238.671,259.171 238.582,258.766 238.317 C 258.150 237.912,257.880 237.907,257.639 238.298 M263.393 238.218 C 262.719 238.346,262.662 238.531,262.662 240.607 C 262.662 243.318,263.239 243.628,263.377 240.990 C 263.464 239.322,263.554 239.112,264.223 239.017 C 264.635 238.959,264.918 238.749,264.852 238.550 C 264.707 238.115,264.359 238.036,263.393 238.218 M271.783 238.287 C 271.531 238.446,271.129 238.501,270.890 238.409 C 270.551 238.279,270.455 238.754,270.455 240.550 C 270.455 243.206,270.945 243.652,271.180 241.210 C 271.493 237.948,273.377 237.720,273.377 240.944 C 273.377 242.428,273.486 242.857,273.864 242.857 C 274.734 242.857,274.534 239.126,273.629 238.492 C 272.807 237.917,272.433 237.875,271.783 238.287 M276.977 238.287 C 276.726 238.446,276.324 238.501,276.085 238.409 C 275.746 238.279,275.649 238.754,275.649 240.550 C 275.649 241.872,275.788 242.857,275.974 242.857 C 276.153 242.857,276.299 242.059,276.299 241.083 C 276.299 239.623,276.417 239.245,276.969 238.950 C 278.046 238.373,278.571 239.082,278.571 241.111 C 278.571 242.071,278.718 242.857,278.896 242.857 C 279.561 242.857,279.283 238.692,278.593 238.323 C 277.832 237.916,277.572 237.910,276.977 238.287 M281.440 238.205 C 280.885 238.353,280.373 239.247,280.672 239.547 C 280.765 239.639,281.122 239.459,281.467 239.147 C 282.215 238.470,283.229 238.585,283.379 239.363 C 283.462 239.791,283.178 239.969,282.153 240.133 C 279.276 240.593,279.700 242.899,282.639 242.772 L 284.415 242.695 284.415 240.851 C 284.416 238.326,283.629 237.626,281.440 238.205 M293.407 238.348 C 291.904 239.222,292.108 242.332,293.694 242.730 C 294.742 242.993,296.087 242.631,296.320 242.022 C 296.612 241.262,296.173 241.070,295.512 241.669 C 294.809 242.305,294.112 242.359,293.571 241.818 C 292.742 240.989,293.146 240.584,294.805 240.584 C 296.310 240.584,296.429 240.527,296.429 239.791 C 296.429 238.426,294.696 237.598,293.407 238.348 M297.971 238.338 C 296.826 239.004,297.371 240.249,299.026 240.751 C 300.501 241.198,300.612 242.208,299.185 242.208 C 298.758 242.208,298.266 241.953,298.092 241.642 C 297.918 241.331,297.661 241.192,297.520 241.333 C 297.047 241.806,297.944 242.694,298.999 242.798 C 300.242 242.921,300.974 242.401,300.974 241.396 C 300.974 240.696,300.614 240.454,298.620 239.813 C 298.308 239.713,298.052 239.475,298.052 239.286 C 298.052 238.729,298.919 238.556,299.678 238.962 C 300.595 239.453,300.996 239.043,300.181 238.447 C 299.446 237.910,298.764 237.876,297.971 238.338 M139.286 240.584 C 139.286 242.388,139.386 242.857,139.773 242.857 C 140.159 242.857,140.260 242.388,140.260 240.584 C 140.260 238.781,140.159 238.312,139.773 238.312 C 139.386 238.312,139.286 238.781,139.286 240.584 M236.364 240.074 C 236.364 242.312,236.863 242.864,238.814 242.779 L 240.260 242.716 240.260 240.514 C 240.260 237.916,239.786 237.590,239.502 239.992 C 239.151 242.953,237.555 243.092,237.403 240.175 C 237.267 237.578,236.364 237.490,236.364 240.074 M265.584 240.195 C 265.584 242.199,265.946 242.857,267.045 242.857 C 267.420 242.857,267.903 242.682,268.117 242.468 C 268.420 242.165,268.506 242.165,268.506 242.468 C 268.506 242.682,268.653 242.857,268.831 242.857 C 269.017 242.857,269.156 241.883,269.156 240.584 C 269.156 239.286,269.017 238.312,268.831 238.312 C 268.653 238.312,268.506 239.024,268.506 239.895 C 268.506 242.972,266.478 243.052,266.298 239.983 C 266.163 237.693,265.584 237.865,265.584 240.195 M114.593 239.102 C 115.132 239.752,114.888 241.583,114.205 242.011 C 113.387 242.523,112.523 241.882,112.401 240.674 C 112.242 239.091,113.710 238.039,114.593 239.102 M122.285 239.579 C 122.986 240.984,121.711 242.791,120.644 241.906 C 119.675 241.101,120.259 238.489,121.361 238.701 C 121.657 238.758,122.073 239.153,122.285 239.579 M127.149 239.205 C 127.694 239.746,127.663 239.777,126.490 239.875 C 124.997 240.000,124.623 239.715,125.468 239.097 C 126.277 238.505,126.457 238.517,127.149 239.205 M136.845 239.164 C 137.511 239.830,137.373 241.532,136.613 242.007 C 135.421 242.753,134.391 240.327,135.389 239.124 C 135.905 238.502,136.191 238.510,136.845 239.164 M148.961 239.026 C 149.507 239.572,149.447 241.399,148.868 241.880 C 147.674 242.870,146.287 240.857,147.202 239.461 C 147.792 238.561,148.356 238.421,148.961 239.026 M164.877 239.713 C 165.689 241.406,163.550 243.218,162.674 241.580 C 162.190 240.676,162.259 239.911,162.886 239.218 C 163.611 238.417,164.344 238.599,164.877 239.713 M196.736 239.102 C 197.275 239.752,197.031 241.583,196.347 242.011 C 195.530 242.523,194.666 241.882,194.544 240.674 C 194.385 239.091,195.853 238.039,196.736 239.102 M212.170 239.164 C 212.838 239.833,212.696 241.532,211.932 242.011 C 211.099 242.533,210.249 241.875,210.124 240.612 C 209.952 238.877,211.083 238.077,212.170 239.164 M224.008 239.102 C 224.538 239.741,224.309 241.580,223.647 241.994 C 222.863 242.485,222.078 241.711,222.078 240.447 C 222.078 238.852,223.170 238.091,224.008 239.102 M229.156 239.026 C 229.809 239.679,229.599 239.935,228.409 239.935 C 227.784 239.935,227.273 239.818,227.273 239.675 C 227.273 239.296,227.994 238.636,228.409 238.636 C 228.606 238.636,228.942 238.812,229.156 239.026 M234.147 239.174 C 235.143 240.076,234.686 242.208,233.495 242.208 C 232.190 242.208,231.629 240.170,232.653 239.147 C 233.291 238.508,233.414 238.511,234.147 239.174 M244.091 239.026 C 244.637 239.572,244.577 241.399,243.998 241.880 C 242.804 242.870,241.417 240.857,242.332 239.461 C 242.921 238.561,243.486 238.421,244.091 239.026 M249.233 239.579 C 249.667 240.448,249.395 241.520,248.616 242.011 C 247.865 242.485,247.078 241.684,247.078 240.447 C 247.078 238.610,248.471 238.049,249.233 239.579 M254.156 239.026 C 254.809 239.679,254.599 239.935,253.409 239.935 C 252.784 239.935,252.273 239.818,252.273 239.675 C 252.273 239.296,252.994 238.636,253.409 238.636 C 253.606 238.636,253.942 238.812,254.156 239.026 M288.294 239.102 C 288.824 239.741,288.594 241.580,287.933 241.994 C 287.149 242.485,286.364 241.711,286.364 240.447 C 286.364 238.852,287.455 238.091,288.294 239.102 M295.330 239.205 C 295.876 239.746,295.845 239.777,294.672 239.875 C 293.179 240.000,292.805 239.715,293.650 239.097 C 294.459 238.505,294.639 238.517,295.330 239.205 M180.195 241.032 C 180.195 241.658,179.360 242.282,178.695 242.153 C 177.828 241.985,177.787 241.265,178.625 240.929 C 179.719 240.491,180.195 240.522,180.195 241.032 M283.442 241.032 C 283.442 241.658,282.606 242.282,281.942 242.153 C 281.074 241.985,281.033 241.265,281.872 240.929 C 282.966 240.491,283.442 240.522,283.442 241.032 M184.836 242.999 C 184.854 243.613,184.985 244.043,185.129 243.954 C 185.488 243.732,185.459 241.883,185.097 241.883 C 184.936 241.883,184.819 242.385,184.836 242.999 M216.653 242.856 C 216.735 244.037,217.330 243.960,217.473 242.751 C 217.545 242.145,217.426 241.883,217.080 241.883 C 216.731 241.883,216.605 242.171,216.653 242.856 M82.468 263.636 C 82.468 267.460,82.545 268.182,82.955 268.182 C 83.320 268.182,83.442 267.791,83.442 266.615 C 83.442 265.382,83.607 264.893,84.218 264.319 L 84.995 263.589 86.572 265.875 C 87.873 267.761,88.306 268.163,89.045 268.172 L 89.940 268.182 88.211 265.828 C 87.260 264.533,86.368 263.283,86.229 263.049 C 86.060 262.763,86.601 262.047,87.875 260.872 C 89.761 259.131,89.767 259.120,88.807 259.106 C 88.040 259.094,87.388 259.541,85.641 261.274 L 83.442 263.457 83.442 261.274 C 83.442 259.550,83.339 259.091,82.955 259.091 C 82.545 259.091,82.468 259.812,82.468 263.636 M90.584 259.740 C 90.584 260.173,90.801 260.390,91.234 260.390 C 91.667 260.390,91.883 260.173,91.883 259.740 C 91.883 259.307,91.667 259.091,91.234 259.091 C 90.801 259.091,90.584 259.307,90.584 259.740 M93.506 263.636 C 93.506 267.460,93.584 268.182,93.994 268.182 C 94.403 268.182,94.481 267.460,94.481 263.636 C 94.481 259.812,94.403 259.091,93.994 259.091 C 93.584 259.091,93.506 259.812,93.506 263.636 M96.104 263.636 C 96.104 267.965,96.135 268.182,96.753 268.182 C 97.372 268.182,97.403 267.965,97.403 263.636 C 97.403 259.307,97.372 259.091,96.753 259.091 C 96.135 259.091,96.104 259.307,96.104 263.636 M99.026 259.740 C 99.026 260.173,99.242 260.390,99.675 260.390 C 100.108 260.390,100.325 260.173,100.325 259.740 C 100.325 259.307,100.108 259.091,99.675 259.091 C 99.242 259.091,99.026 259.307,99.026 259.740 M103.899 261.680 C 103.632 261.848,103.085 261.903,102.681 261.802 C 101.956 261.620,101.948 261.655,101.948 264.900 C 101.948 267.601,102.034 268.182,102.435 268.182 C 102.813 268.182,102.922 267.751,102.922 266.255 C 102.922 263.909,103.311 262.789,104.225 262.499 C 105.555 262.076,106.169 263.118,106.169 265.797 C 106.169 267.700,106.267 268.182,106.656 268.182 C 107.552 268.182,107.342 262.514,106.421 261.869 C 105.608 261.299,104.618 261.225,103.899 261.680 M109.598 262.076 C 107.100 264.224,109.067 268.933,112.030 267.900 C 112.868 267.608,112.987 267.642,112.987 268.176 C 112.987 269.727,111.220 270.251,109.791 269.125 C 108.986 268.490,108.921 268.483,108.811 269.028 C 108.542 270.363,111.001 271.226,112.774 270.419 C 113.978 269.870,114.286 268.788,114.286 265.095 L 114.286 261.714 113.393 261.721 C 112.902 261.725,112.049 261.633,111.497 261.517 C 110.714 261.352,110.297 261.474,109.598 262.076 M90.584 264.935 C 90.584 267.965,90.628 268.182,91.234 268.182 C 91.840 268.182,91.883 267.965,91.883 264.935 C 91.883 261.905,91.840 261.688,91.234 261.688 C 90.628 261.688,90.584 261.905,90.584 264.935 M99.026 264.935 C 99.026 267.965,99.069 268.182,99.675 268.182 C 100.281 268.182,100.325 267.965,100.325 264.935 C 100.325 261.905,100.281 261.688,99.675 261.688 C 99.069 261.688,99.026 261.905,99.026 264.935 M112.393 262.875 C 113.158 263.567,113.191 265.795,112.450 266.614 C 111.287 267.899,109.740 266.880,109.740 264.829 C 109.740 262.714,111.104 261.709,112.393 262.875 M84.091 321.429 L 84.091 325.974 86.212 325.974 C 90.332 325.974,91.734 324.614,91.494 320.848 C 91.295 317.728,90.270 316.883,86.683 316.883 L 84.091 316.883 84.091 321.429 M111.364 318.327 L 111.364 319.771 110.380 319.428 C 107.726 318.503,105.800 321.764,107.293 324.652 C 107.975 325.971,110.060 326.499,110.974 325.584 C 111.277 325.281,111.364 325.281,111.364 325.584 C 111.364 325.799,111.583 325.974,111.851 325.974 C 112.260 325.974,112.338 325.253,112.338 321.429 C 112.338 317.605,112.260 316.883,111.851 316.883 C 111.491 316.883,111.364 317.260,111.364 318.327 M88.739 318.235 C 91.754 319.841,90.562 324.675,87.152 324.675 L 85.390 324.675 85.390 321.266 L 85.390 317.857 86.710 317.857 C 87.436 317.857,88.349 318.027,88.739 318.235 M94.596 319.465 C 91.590 320.732,92.496 325.974,95.721 325.974 C 96.960 325.974,98.701 325.006,98.701 324.317 C 98.701 323.641,97.673 323.635,97.201 324.308 C 96.403 325.447,94.935 325.191,94.193 323.782 C 93.810 323.055,93.820 323.052,96.255 323.052 L 98.701 323.052 98.701 322.096 C 98.701 320.204,96.378 318.715,94.596 319.465 M101.308 319.501 C 100.448 319.862,100.013 320.370,100.005 321.023 C 99.997 321.649,100.765 321.504,101.403 320.759 C 102.089 319.958,103.498 320.017,104.026 320.870 C 104.483 321.609,103.843 322.066,102.339 322.073 C 101.130 322.079,99.675 323.287,99.675 324.286 C 99.675 325.709,102.014 326.483,103.658 325.603 C 104.179 325.324,104.383 325.324,104.476 325.603 C 104.544 325.807,104.843 325.974,105.141 325.975 C 105.784 325.975,105.650 320.453,104.991 319.795 C 104.472 319.277,102.260 319.101,101.308 319.501 M96.775 320.466 C 98.107 321.179,97.552 322.078,95.779 322.078 C 94.039 322.078,93.771 321.743,94.693 320.724 C 95.303 320.050,95.867 319.980,96.775 320.466 M110.714 320.779 C 112.056 322.121,111.255 325.000,109.539 325.000 C 108.617 325.000,108.117 324.131,108.117 322.531 C 108.117 320.449,109.471 319.536,110.714 320.779 M104.221 323.353 C 104.221 324.268,103.340 325.000,102.239 325.000 C 100.348 325.000,100.756 323.204,102.703 322.960 C 103.270 322.889,103.843 322.808,103.977 322.779 C 104.111 322.751,104.221 323.009,104.221 323.353 " stroke="none" fill="#282828" fill-rule="evenodd"></path><path id="path2" d="M61.839 31.818 C 61.839 40.657,61.881 44.274,61.932 39.854 C 61.983 35.434,61.983 28.202,61.932 23.782 C 61.881 19.363,61.839 22.979,61.839 31.818 M77.029 27.509 C 77.699 27.579,78.795 27.579,79.464 27.509 C 80.134 27.439,79.586 27.382,78.247 27.382 C 76.907 27.382,76.360 27.439,77.029 27.509 M102.403 27.726 C 102.308 27.975,102.288 28.742,102.359 29.430 C 102.484 30.638,102.490 30.629,102.543 29.163 C 102.584 28.019,102.737 27.608,103.166 27.497 C 103.698 27.357,103.697 27.346,103.155 27.310 C 102.837 27.290,102.499 27.477,102.403 27.726 M105.743 27.483 C 106.134 27.568,106.519 27.923,106.598 28.272 C 106.710 28.765,106.733 28.742,106.699 28.171 C 106.667 27.630,106.441 27.421,105.844 27.382 C 105.168 27.338,105.151 27.355,105.743 27.483 M78.003 28.795 C 78.316 28.877,78.827 28.877,79.140 28.795 C 79.452 28.714,79.196 28.647,78.571 28.647 C 77.946 28.647,77.691 28.714,78.003 28.795 M106.614 33.442 C 106.614 35.317,106.667 36.084,106.733 35.146 C 106.798 34.209,106.798 32.675,106.733 31.737 C 106.667 30.800,106.614 31.567,106.614 33.442 M312.094 176.379 L 312.013 321.427 225.731 321.510 L 139.448 321.592 225.741 321.673 C 294.536 321.737,312.065 321.671,312.187 321.347 C 312.272 321.124,312.304 255.779,312.258 176.136 L 312.175 31.331 312.094 176.379 M311.444 176.379 L 311.364 320.778 225.406 320.860 L 139.448 320.943 225.416 321.023 C 293.951 321.088,311.415 321.022,311.538 320.698 C 311.623 320.475,311.655 255.422,311.609 176.136 L 311.525 31.981 311.444 176.379 M79.541 48.619 L 97.718 48.707 97.811 58.769 L 97.904 68.831 97.897 58.685 L 97.890 48.539 79.627 48.535 L 61.364 48.531 79.541 48.619 M98.593 48.593 C 98.266 48.920,98.333 68.831,98.662 68.831 C 98.818 68.831,99.134 68.605,99.363 68.329 C 99.699 67.925,99.840 67.909,100.083 68.248 C 100.303 68.553,100.336 68.513,100.203 68.101 C 100.103 67.788,100.162 67.532,100.335 67.532 C 100.508 67.532,100.649 67.359,100.649 67.147 C 100.649 66.935,100.211 67.182,99.675 67.695 L 98.701 68.628 98.701 58.667 L 98.701 48.707 116.964 48.620 L 135.227 48.533 117.018 48.455 C 107.004 48.412,98.712 48.474,98.593 48.593 M121.383 58.523 C 121.319 59.103,121.350 60.601,121.452 61.851 C 121.631 64.029,121.641 63.985,121.696 60.795 C 121.753 57.509,121.610 56.472,121.383 58.523 M122.461 59.010 C 122.395 60.947,122.611 61.086,123.726 59.821 L 124.513 58.929 123.639 59.698 L 122.766 60.466 122.643 58.886 L 122.520 57.305 122.461 59.010 M196.219 60.227 C 196.218 61.834,196.273 62.533,196.341 61.779 C 196.409 61.026,196.410 59.711,196.343 58.857 C 196.276 58.004,196.220 58.620,196.219 60.227 M179.670 58.585 C 179.292 59.570,179.690 60.227,180.684 60.258 C 181.605 60.286,181.609 60.281,180.763 60.156 C 179.366 59.949,179.494 58.529,180.925 58.352 L 181.981 58.221 180.915 58.169 C 180.249 58.136,179.782 58.292,179.670 58.585 M135.140 59.416 C 135.140 60.041,135.207 60.296,135.289 59.984 C 135.370 59.671,135.370 59.160,135.289 58.847 C 135.207 58.535,135.140 58.791,135.140 59.416 M140.046 61.526 C 140.048 62.955,140.105 63.499,140.173 62.735 C 140.242 61.971,140.241 60.802,140.171 60.138 C 140.101 59.473,140.045 60.097,140.046 61.526 M188.080 60.552 C 188.082 61.445,188.145 61.772,188.220 61.278 C 188.295 60.784,188.293 60.054,188.216 59.655 C 188.138 59.255,188.077 59.659,188.080 60.552 M124.352 60.226 C 123.933 60.672,123.652 61.091,123.727 61.157 C 123.802 61.224,124.203 60.859,124.619 60.347 C 125.548 59.201,125.385 59.127,124.352 60.226 M189.070 61.688 C 189.070 63.028,189.128 63.575,189.198 62.906 C 189.268 62.236,189.268 61.140,189.198 60.471 C 189.128 59.801,189.070 60.349,189.070 61.688 M190.044 61.688 C 190.044 63.028,190.102 63.575,190.172 62.906 C 190.242 62.236,190.242 61.140,190.172 60.471 C 190.102 59.801,190.044 60.349,190.044 61.688 M154.643 61.688 C 154.643 62.670,154.704 63.072,154.778 62.581 C 154.852 62.090,154.852 61.287,154.778 60.795 C 154.704 60.304,154.643 60.706,154.643 61.688 M155.647 61.501 C 155.671 62.625,155.826 63.138,156.169 63.230 C 156.506 63.321,156.537 63.277,156.272 63.088 C 156.061 62.937,155.827 62.159,155.750 61.358 L 155.612 59.903 155.647 61.501 M135.153 62.662 C 135.153 63.466,135.217 63.795,135.294 63.393 C 135.371 62.991,135.371 62.334,135.294 61.932 C 135.217 61.530,135.153 61.859,135.153 62.662 M140.998 62.662 C 140.998 63.466,141.061 63.795,141.138 63.393 C 141.216 62.991,141.216 62.334,141.138 61.932 C 141.061 61.530,140.998 61.859,140.998 62.662 M179.634 62.662 C 179.634 63.466,179.697 63.795,179.775 63.393 C 179.852 62.991,179.852 62.334,179.775 61.932 C 179.697 61.530,179.634 61.859,179.634 62.662 M190.998 62.662 C 190.998 63.466,191.061 63.795,191.138 63.393 C 191.216 62.991,191.216 62.334,191.138 61.932 C 191.061 61.530,190.998 61.859,190.998 62.662 M122.529 62.152 C 122.431 62.407,122.406 62.954,122.472 63.369 C 122.561 63.924,122.637 63.802,122.757 62.906 C 122.927 61.645,122.837 61.348,122.529 62.152 M127.679 61.921 C 128.170 61.995,128.973 61.995,129.464 61.921 C 129.955 61.846,129.554 61.786,128.571 61.786 C 127.589 61.786,127.188 61.846,127.679 61.921 M158.691 61.924 C 159.274 61.996,160.151 61.994,160.639 61.920 C 161.127 61.846,160.649 61.787,159.578 61.789 C 158.506 61.791,158.107 61.851,158.691 61.924 M111.799 65.966 C 111.282 66.537,111.228 66.538,110.580 65.993 L 109.903 65.422 110.526 66.158 L 111.149 66.893 111.932 66.158 C 112.876 65.271,112.748 65.277,113.683 66.071 L 114.448 66.721 113.879 66.044 C 113.175 65.209,112.507 65.184,111.799 65.966 M119.916 65.966 C 119.399 66.537,119.345 66.538,118.697 65.993 L 118.019 65.422 118.643 66.158 L 119.266 66.893 120.049 66.158 C 120.479 65.753,120.881 65.422,120.942 65.422 C 121.002 65.422,121.404 65.753,121.835 66.158 L 122.618 66.893 123.241 66.158 L 123.864 65.422 123.186 65.993 C 122.538 66.538,122.484 66.537,121.967 65.966 C 121.669 65.637,121.208 65.368,120.942 65.368 C 120.675 65.368,120.214 65.637,119.916 65.966 M128.005 66.044 L 127.435 66.721 128.200 66.071 C 129.135 65.277,129.008 65.271,129.951 66.158 L 130.734 66.893 131.357 66.158 L 131.981 65.422 131.303 65.993 C 130.655 66.538,130.601 66.537,130.084 65.966 C 129.376 65.184,128.708 65.209,128.005 66.044 M136.175 65.985 L 135.552 66.721 136.230 66.150 C 136.878 65.604,136.932 65.606,137.449 66.177 C 138.156 66.959,138.825 66.933,139.528 66.098 L 140.097 65.422 139.333 66.071 C 138.398 66.866,138.525 66.872,137.581 65.985 L 136.798 65.250 136.175 65.985 M144.292 65.985 L 143.669 66.721 144.347 66.150 C 144.994 65.604,145.048 65.606,145.566 66.177 C 145.863 66.506,146.325 66.775,146.591 66.775 C 146.857 66.775,147.319 66.506,147.616 66.177 C 148.133 65.606,148.187 65.604,148.835 66.150 L 149.513 66.721 148.890 65.985 L 148.267 65.250 147.484 65.985 C 147.053 66.390,146.651 66.721,146.591 66.721 C 146.530 66.721,146.129 66.390,145.698 65.985 L 144.915 65.250 144.292 65.985 M152.409 65.985 L 151.786 66.721 152.464 66.150 C 153.111 65.604,153.165 65.606,153.682 66.177 C 153.980 66.506,154.441 66.775,154.708 66.775 C 154.974 66.775,155.436 66.506,155.733 66.177 C 156.250 65.606,156.304 65.604,156.952 66.150 L 157.630 66.721 157.007 65.985 L 156.384 65.250 155.601 65.985 C 155.170 66.390,154.768 66.721,154.708 66.721 C 154.647 66.721,154.245 66.390,153.815 65.985 L 153.032 65.250 152.409 65.985 M173.837 65.985 L 173.214 66.721 173.892 66.150 C 174.540 65.604,174.594 65.606,175.111 66.177 C 175.409 66.506,175.870 66.775,176.136 66.775 C 176.403 66.775,176.864 66.506,177.162 66.177 C 177.679 65.606,177.733 65.604,178.381 66.150 L 179.058 66.721 178.435 65.985 L 177.812 65.250 177.029 65.985 C 176.599 66.390,176.197 66.721,176.136 66.721 C 176.076 66.721,175.674 66.390,175.243 65.985 L 174.460 65.250 173.837 65.985 M181.954 65.985 L 181.331 66.721 182.009 66.150 C 182.657 65.604,182.711 65.606,183.228 66.177 C 183.525 66.506,183.987 66.775,184.253 66.775 C 184.520 66.775,184.981 66.506,185.279 66.177 C 185.796 65.606,185.850 65.604,186.498 66.150 L 187.175 66.721 186.552 65.985 L 185.929 65.250 185.146 65.985 C 184.716 66.390,184.314 66.721,184.253 66.721 C 184.193 66.721,183.791 66.390,183.360 65.985 L 182.577 65.250 181.954 65.985 M193.373 65.877 C 192.742 66.574,192.222 66.580,191.348 65.900 C 190.770 65.451,190.768 65.459,191.316 66.104 C 192.021 66.934,192.690 66.957,193.396 66.177 C 193.913 65.606,193.967 65.604,194.614 66.150 C 195.292 66.721,195.292 66.721,194.674 65.990 C 193.932 65.114,194.054 65.124,193.373 65.877 M200.760 65.966 C 200.243 66.537,200.189 66.538,199.541 65.993 L 198.864 65.422 199.487 66.158 L 200.110 66.893 200.893 66.158 C 201.837 65.271,201.709 65.277,202.644 66.071 L 203.409 66.721 202.840 66.044 C 202.137 65.209,201.468 65.184,200.760 65.966 M208.926 65.912 C 208.361 66.537,208.308 66.540,207.658 65.993 L 206.981 65.422 207.604 66.158 L 208.227 66.893 208.926 66.236 C 209.311 65.874,209.748 65.689,209.898 65.825 C 210.047 65.961,210.064 65.889,209.935 65.666 C 209.633 65.141,209.621 65.144,208.926 65.912 M166.966 66.098 C 167.279 66.471,167.753 66.775,168.019 66.775 C 168.286 66.775,168.760 66.471,169.073 66.098 L 169.643 65.422 168.878 66.071 C 168.458 66.429,168.071 66.721,168.019 66.721 C 167.968 66.721,167.581 66.429,167.161 66.071 L 166.396 65.422 166.966 66.098 M212.010 66.075 C 211.700 66.449,211.496 66.478,211.158 66.198 C 210.914 65.995,210.714 65.903,210.714 65.992 C 210.714 66.663,211.647 66.817,212.176 66.233 C 212.499 65.876,212.685 65.584,212.590 65.584 C 212.495 65.584,212.234 65.805,212.010 66.075 M61.688 89.773 L 61.688 105.844 98.295 105.764 L 134.903 105.685 98.458 105.601 L 62.013 105.517 62.013 89.773 L 62.013 74.029 98.458 73.945 L 134.903 73.861 98.295 73.781 L 61.688 73.701 61.688 89.773 M76.875 85.303 C 77.639 85.372,78.808 85.371,79.473 85.301 C 80.138 85.231,79.513 85.175,78.084 85.176 C 76.656 85.177,76.112 85.234,76.875 85.303 M106.068 85.275 C 106.459 85.360,106.843 85.715,106.923 86.064 C 107.035 86.557,107.057 86.535,107.024 85.963 C 106.992 85.422,106.766 85.213,106.169 85.174 C 105.493 85.130,105.476 85.147,106.068 85.275 M77.005 87.906 L 77.061 89.448 77.185 88.085 L 77.308 86.722 78.833 86.602 L 80.357 86.481 78.653 86.422 L 76.948 86.364 77.005 87.906 M85.823 89.935 C 85.823 91.274,85.881 91.822,85.951 91.153 C 86.021 90.483,86.021 89.387,85.951 88.718 C 85.881 88.048,85.823 88.596,85.823 89.935 M90.057 91.071 C 90.057 93.036,90.111 93.797,90.175 92.764 C 90.240 91.731,90.239 90.124,90.174 89.193 C 90.109 88.262,90.056 89.107,90.057 91.071 M106.938 91.234 C 106.938 93.109,106.992 93.876,107.058 92.938 C 107.123 92.001,107.123 90.467,107.058 89.529 C 106.992 88.592,106.938 89.359,106.938 91.234 M102.707 91.883 C 102.707 93.222,102.764 93.770,102.834 93.101 C 102.904 92.431,102.904 91.335,102.834 90.666 C 102.764 89.996,102.707 90.544,102.707 91.883 M97.184 92.045 C 97.186 93.295,97.245 93.767,97.315 93.093 C 97.385 92.420,97.384 91.397,97.312 90.821 C 97.241 90.244,97.183 90.795,97.184 92.045 M142.614 90.178 C 146.676 90.230,153.324 90.230,157.386 90.178 C 161.449 90.127,158.125 90.085,150.000 90.085 C 141.875 90.085,138.551 90.127,142.614 90.178 M92.964 92.370 C 92.965 93.620,93.024 94.092,93.094 93.418 C 93.164 92.744,93.163 91.722,93.091 91.145 C 93.020 90.569,92.962 91.120,92.964 92.370 M77.052 92.532 C 77.052 93.693,77.111 94.168,77.183 93.588 C 77.255 93.007,77.255 92.058,77.183 91.477 C 77.111 90.897,77.052 91.372,77.052 92.532 M97.804 116.372 L 97.727 126.412 96.917 125.651 C 96.471 125.232,96.008 124.987,95.889 125.107 C 95.769 125.227,95.850 125.325,96.069 125.325 C 96.295 125.325,96.366 125.500,96.233 125.731 C 96.105 125.954,96.121 126.026,96.269 125.892 C 96.417 125.758,96.807 125.891,97.135 126.188 C 98.063 127.028,98.067 126.986,97.971 116.364 L 97.880 106.331 97.804 116.372 M98.451 116.477 C 98.410 122.058,98.465 126.623,98.573 126.623 C 98.681 126.623,99.204 126.258,99.735 125.812 C 100.265 125.365,100.565 125.000,100.400 125.000 C 100.235 125.000,99.822 125.308,99.482 125.684 C 98.872 126.358,98.861 126.230,98.694 116.349 L 98.525 106.331 98.451 116.477 M60.834 118.506 C 60.834 120.381,60.888 121.149,60.954 120.211 C 61.019 119.274,61.019 117.739,60.954 116.802 C 60.888 115.864,60.834 116.631,60.834 118.506 M61.808 118.506 C 61.808 120.381,61.862 121.149,61.928 120.211 C 61.993 119.274,61.993 117.739,61.928 116.802 C 61.862 115.864,61.808 116.631,61.808 118.506 M64.062 119.643 C 64.063 120.714,64.124 121.113,64.196 120.530 C 64.269 119.946,64.267 119.070,64.193 118.582 C 64.119 118.094,64.060 118.571,64.062 119.643 M87.987 119.102 C 87.987 119.335,87.331 119.503,86.282 119.539 L 84.578 119.598 86.165 119.721 C 87.658 119.837,88.704 119.440,88.209 118.945 C 88.087 118.823,87.987 118.893,87.987 119.102 M57.549 119.713 C 58.040 119.787,58.843 119.787,59.334 119.713 C 59.825 119.639,59.424 119.578,58.442 119.578 C 57.459 119.578,57.058 119.639,57.549 119.713 M195.241 130.357 C 195.242 131.786,195.299 132.330,195.368 131.566 C 195.437 130.802,195.436 129.634,195.366 128.969 C 195.296 128.304,195.240 128.929,195.241 130.357 M226.218 129.450 C 226.619 129.527,227.277 129.527,227.679 129.450 C 228.080 129.373,227.752 129.309,226.948 129.309 C 226.144 129.309,225.816 129.373,226.218 129.450 M239.935 130.141 C 239.935 130.374,239.279 130.542,238.231 130.578 L 236.526 130.637 238.113 130.760 C 239.606 130.876,240.652 130.479,240.157 129.984 C 240.035 129.862,239.935 129.932,239.935 130.141 M196.192 131.494 C 196.192 132.297,196.256 132.626,196.333 132.224 C 196.410 131.822,196.410 131.165,196.333 130.763 C 196.256 130.361,196.192 130.690,196.192 131.494 M204.470 130.755 C 205.054 130.827,205.930 130.826,206.418 130.751 C 206.906 130.677,206.429 130.618,205.357 130.620 C 204.286 130.622,203.887 130.683,204.470 130.755 M61.766 147.646 L 61.844 163.799 61.932 147.810 L 62.019 131.821 98.461 131.737 L 134.903 131.653 98.295 131.573 L 61.688 131.494 61.766 147.646 M279.341 140.260 C 279.341 142.135,279.395 142.902,279.460 141.964 C 279.526 141.027,279.526 139.493,279.460 138.555 C 279.395 137.618,279.341 138.385,279.341 140.260 M280.315 140.260 C 280.315 142.135,280.369 142.902,280.434 141.964 C 280.500 141.027,280.500 139.493,280.434 138.555 C 280.369 137.618,280.315 138.385,280.315 140.260 M195.241 141.071 C 195.242 142.500,195.299 143.044,195.368 142.280 C 195.437 141.517,195.436 140.348,195.366 139.683 C 195.296 139.018,195.240 139.643,195.241 141.071 M242.954 141.234 C 242.954 142.216,243.015 142.618,243.090 142.127 C 243.164 141.636,243.164 140.832,243.090 140.341 C 243.015 139.850,242.954 140.252,242.954 141.234 M243.959 141.046 C 243.983 142.170,244.138 142.683,244.481 142.775 C 244.817 142.866,244.849 142.822,244.584 142.633 C 244.373 142.483,244.138 141.704,244.062 140.904 L 243.924 139.448 243.959 141.046 M226.075 141.721 C 226.076 142.792,226.137 143.191,226.209 142.608 C 226.282 142.024,226.280 141.148,226.206 140.660 C 226.132 140.172,226.073 140.649,226.075 141.721 M236.789 141.721 C 236.791 142.792,236.851 143.191,236.924 142.608 C 236.996 142.024,236.994 141.148,236.920 140.660 C 236.846 140.172,236.787 140.649,236.789 141.721 M235.812 141.883 C 235.812 142.865,235.872 143.267,235.947 142.776 C 236.021 142.285,236.021 141.481,235.947 140.990 C 235.872 140.499,235.812 140.901,235.812 141.883 M227.041 142.045 C 227.043 142.938,227.106 143.265,227.181 142.772 C 227.256 142.278,227.254 141.547,227.177 141.148 C 227.100 140.749,227.038 141.153,227.041 142.045 M196.192 142.208 C 196.192 143.011,196.256 143.340,196.333 142.938 C 196.410 142.537,196.410 141.879,196.333 141.477 C 196.256 141.075,196.192 141.404,196.192 142.208 M204.470 141.469 C 205.054 141.541,205.930 141.540,206.418 141.466 C 206.906 141.392,206.429 141.333,205.357 141.334 C 204.286 141.336,203.887 141.397,204.470 141.469 M216.964 141.466 C 217.455 141.541,218.259 141.541,218.750 141.466 C 219.241 141.392,218.839 141.331,217.857 141.331 C 216.875 141.331,216.473 141.392,216.964 141.466 M247.003 141.469 C 247.586 141.541,248.463 141.540,248.951 141.466 C 249.438 141.392,248.961 141.333,247.890 141.334 C 246.818 141.336,246.419 141.397,247.003 141.469 M283.042 141.469 C 283.625 141.541,284.502 141.540,284.990 141.466 C 285.477 141.392,285.000 141.333,283.929 141.334 C 282.857 141.336,282.458 141.397,283.042 141.469 M105.966 148.864 C 105.966 150.828,106.020 151.590,106.084 150.556 C 106.149 149.523,106.148 147.916,106.083 146.985 C 106.018 146.054,105.965 146.899,105.966 148.864 M111.477 149.675 C 111.477 151.193,111.533 151.814,111.601 151.055 C 111.670 150.296,111.670 149.054,111.601 148.295 C 111.533 147.537,111.477 148.157,111.477 149.675 M110.169 150.325 C 110.169 151.485,110.228 151.960,110.300 151.380 C 110.372 150.800,110.372 149.850,110.300 149.269 C 110.228 148.689,110.169 149.164,110.169 150.325 M188.423 151.786 C 188.424 153.214,188.481 153.758,188.550 152.995 C 188.618 152.231,188.617 151.062,188.548 150.397 C 188.478 149.732,188.422 150.357,188.423 151.786 M189.397 151.786 C 189.398 153.214,189.455 153.758,189.524 152.995 C 189.592 152.231,189.591 151.062,189.522 150.397 C 189.452 149.732,189.396 150.357,189.397 151.786 M224.444 150.812 C 224.446 151.705,224.509 152.031,224.584 151.538 C 224.658 151.044,224.656 150.314,224.579 149.914 C 224.502 149.515,224.441 149.919,224.444 150.812 M187.447 151.948 C 187.447 153.287,187.504 153.835,187.574 153.166 C 187.644 152.496,187.644 151.400,187.574 150.731 C 187.504 150.061,187.447 150.609,187.447 151.948 M225.434 151.948 C 225.434 153.287,225.491 153.835,225.561 153.166 C 225.631 152.496,225.631 151.400,225.561 150.731 C 225.491 150.061,225.434 150.609,225.434 151.948 M249.451 152.435 C 249.453 153.506,249.514 153.906,249.586 153.322 C 249.658 152.739,249.657 151.862,249.583 151.374 C 249.509 150.886,249.449 151.364,249.451 152.435 M248.474 152.597 C 248.474 153.580,248.535 153.981,248.609 153.490 C 248.684 152.999,248.684 152.196,248.609 151.705 C 248.535 151.213,248.474 151.615,248.474 152.597 M190.348 152.922 C 190.348 153.726,190.411 154.054,190.489 153.653 C 190.566 153.251,190.566 152.593,190.489 152.192 C 190.411 151.790,190.348 152.119,190.348 152.922 M194.080 152.183 C 194.664 152.256,195.541 152.254,196.029 152.180 C 196.516 152.106,196.039 152.047,194.968 152.049 C 193.896 152.050,193.497 152.111,194.080 152.183 M98.782 152.497 C 99.095 152.578,99.606 152.578,99.919 152.497 C 100.231 152.415,99.976 152.348,99.351 152.348 C 98.726 152.348,98.470 152.415,98.782 152.497 M318.951 160.065 C 318.951 161.940,319.005 162.707,319.071 161.769 C 319.136 160.832,319.136 159.298,319.071 158.360 C 319.005 157.423,318.951 158.190,318.951 160.065 M353.367 160.065 C 353.367 161.940,353.421 162.707,353.486 161.769 C 353.552 160.832,353.552 159.298,353.486 158.360 C 353.421 157.423,353.367 158.190,353.367 160.065 M354.296 157.792 C 354.296 158.417,354.363 158.673,354.445 158.360 C 354.526 158.048,354.526 157.537,354.445 157.224 C 354.363 156.912,354.296 157.167,354.296 157.792 M335.490 161.201 C 335.492 162.273,335.553 162.672,335.625 162.088 C 335.697 161.505,335.696 160.628,335.622 160.140 C 335.548 159.652,335.488 160.130,335.490 161.201 M333.442 160.660 C 333.442 160.893,332.786 161.061,331.737 161.097 L 330.032 161.156 331.620 161.279 C 333.113 161.396,334.159 160.998,333.663 160.503 C 333.541 160.381,333.442 160.452,333.442 160.660 M354.309 162.013 C 354.309 162.817,354.373 163.145,354.450 162.744 C 354.527 162.342,354.527 161.684,354.450 161.282 C 354.373 160.881,354.309 161.209,354.309 162.013 M97.727 174.245 L 97.727 184.204 96.917 183.443 C 96.471 183.024,96.008 182.779,95.889 182.899 C 95.769 183.019,95.837 183.117,96.040 183.117 C 96.242 183.117,96.364 183.300,96.309 183.523 C 96.255 183.746,96.275 183.808,96.354 183.661 C 96.434 183.514,96.848 183.722,97.275 184.124 L 98.052 184.853 98.052 174.570 C 98.052 168.913,97.979 164.286,97.890 164.286 C 97.800 164.286,97.727 168.767,97.727 174.245 M98.521 174.351 C 98.521 179.976,98.565 182.277,98.620 179.464 C 98.674 176.652,98.674 172.050,98.620 169.237 C 98.565 166.425,98.521 168.726,98.521 174.351 M62.122 176.948 C 62.122 178.287,62.179 178.835,62.250 178.166 C 62.320 177.496,62.320 176.400,62.250 175.731 C 62.179 175.061,62.122 175.609,62.122 176.948 M67.305 176.948 C 67.305 177.930,67.366 178.332,67.440 177.841 C 67.515 177.350,67.515 176.546,67.440 176.055 C 67.366 175.564,67.305 175.966,67.305 176.948 M68.309 176.760 C 68.334 177.885,68.489 178.397,68.831 178.490 C 69.168 178.580,69.200 178.536,68.935 178.347 C 68.724 178.197,68.489 177.419,68.413 176.618 L 68.274 175.162 68.309 176.760 M39.062 177.435 C 39.063 178.506,39.124 178.906,39.196 178.322 C 39.269 177.739,39.267 176.862,39.193 176.374 C 39.119 175.886,39.060 176.364,39.062 177.435 M38.084 177.597 C 38.084 178.580,38.145 178.981,38.220 178.490 C 38.294 177.999,38.294 177.196,38.220 176.705 C 38.145 176.213,38.084 176.615,38.084 177.597 M63.075 177.922 C 63.075 178.726,63.139 179.054,63.216 178.653 C 63.294 178.251,63.294 177.593,63.216 177.192 C 63.139 176.790,63.075 177.119,63.075 177.922 M49.275 177.183 C 49.859 177.256,50.735 177.254,51.223 177.180 C 51.711 177.106,51.234 177.047,50.162 177.049 C 49.091 177.050,48.692 177.111,49.275 177.183 M58.847 177.181 C 59.338 177.255,60.142 177.255,60.633 177.181 C 61.124 177.106,60.722 177.045,59.740 177.045 C 58.758 177.045,58.356 177.106,58.847 177.181 M51.755 181.899 L 51.136 182.630 51.867 182.011 C 52.585 181.403,52.610 181.403,53.328 182.011 L 54.058 182.630 53.440 181.899 C 53.100 181.498,52.721 181.169,52.597 181.169 C 52.474 181.169,52.095 181.498,51.755 181.899 M69.399 181.821 L 70.130 182.612 70.860 181.821 L 71.591 181.031 70.860 181.637 C 70.147 182.229,70.113 182.229,69.399 181.637 L 68.669 181.031 69.399 181.821 M77.516 181.821 L 78.247 182.612 78.977 181.821 L 79.708 181.031 78.977 181.637 C 78.264 182.229,78.230 182.229,77.516 181.637 L 76.786 181.031 77.516 181.821 M85.633 181.821 L 86.364 182.612 87.094 181.821 L 87.825 181.031 87.094 181.637 C 86.381 182.229,86.346 182.229,85.633 181.637 L 84.903 181.031 85.633 181.821 M98.376 188.718 C 98.377 188.851,106.668 188.928,116.802 188.887 C 126.936 188.846,132.305 188.774,128.734 188.725 C 112.005 188.500,98.376 188.496,98.376 188.718 M70.350 188.880 C 75.382 188.930,83.710 188.930,88.857 188.880 C 94.003 188.829,89.886 188.788,79.708 188.788 C 69.529 188.788,65.318 188.829,70.350 188.880 M61.839 205.519 C 61.839 214.359,61.881 217.975,61.932 213.555 C 61.983 209.136,61.983 201.903,61.932 197.484 C 61.881 193.064,61.839 196.680,61.839 205.519 M107.285 201.072 C 107.196 201.304,107.169 203.459,107.224 205.861 L 107.326 210.227 107.397 205.623 C 107.466 201.133,107.486 201.016,108.198 200.878 L 108.929 200.738 108.188 200.694 C 107.780 200.669,107.374 200.839,107.285 201.072 M110.186 201.126 C 110.086 201.388,110.079 201.789,110.171 202.019 C 110.263 202.248,110.350 202.117,110.364 201.728 C 110.378 201.340,110.645 200.955,110.958 200.873 C 111.490 200.734,111.490 200.722,110.948 200.687 C 110.629 200.666,110.287 200.864,110.186 201.126 M110.186 206.656 C 110.187 208.620,110.241 209.382,110.305 208.349 C 110.370 207.315,110.369 205.708,110.304 204.777 C 110.239 203.846,110.186 204.692,110.186 206.656 M140.696 203.466 C 140.816 203.587,140.585 204.062,140.183 204.521 C 139.588 205.200,139.648 205.178,140.504 204.404 C 141.720 203.304,141.745 203.247,141.017 203.247 C 140.720 203.247,140.575 203.345,140.696 203.466 M85.494 206.494 C 85.494 207.654,85.552 208.129,85.624 207.549 C 85.697 206.968,85.697 206.019,85.624 205.438 C 85.552 204.858,85.494 205.333,85.494 206.494 M92.639 207.630 C 92.640 208.880,92.699 209.351,92.769 208.678 C 92.840 208.004,92.839 206.981,92.767 206.405 C 92.695 205.829,92.638 206.380,92.639 207.630 M88.418 207.955 C 88.420 209.205,88.478 209.676,88.549 209.002 C 88.619 208.329,88.618 207.306,88.546 206.730 C 88.474 206.153,88.417 206.705,88.418 207.955 M140.206 206.599 C 140.596 207.014,140.841 207.428,140.750 207.519 C 140.659 207.610,140.808 207.684,141.080 207.684 C 141.434 207.684,141.324 207.421,140.695 206.764 C 140.210 206.258,139.742 205.844,139.655 205.844 C 139.568 205.844,139.816 206.184,140.206 206.599 M97.872 232.305 C 97.872 238.019,97.916 240.311,97.970 237.398 C 98.024 234.485,98.024 229.810,97.970 227.009 C 97.916 224.208,97.872 226.591,97.872 232.305 M98.521 232.468 C 98.521 238.093,98.565 240.394,98.620 237.581 C 98.674 234.769,98.674 230.166,98.620 227.354 C 98.565 224.541,98.521 226.843,98.521 232.468 M109.525 227.922 C 109.525 229.261,109.582 229.809,109.652 229.140 C 109.722 228.470,109.722 227.374,109.652 226.705 C 109.582 226.035,109.525 226.583,109.525 227.922 M110.510 228.896 C 110.510 230.771,110.563 231.538,110.629 230.601 C 110.695 229.663,110.695 228.129,110.629 227.192 C 110.563 226.254,110.510 227.021,110.510 228.896 M135.344 226.705 C 135.280 227.285,135.311 228.782,135.413 230.032 C 135.592 232.211,135.602 232.167,135.657 228.977 C 135.714 225.690,135.571 224.654,135.344 226.705 M136.422 227.192 C 136.356 229.129,136.572 229.268,137.687 228.003 L 138.474 227.110 137.601 227.879 L 136.727 228.648 136.604 227.068 L 136.481 225.487 136.422 227.192 M222.198 228.896 C 222.198 230.771,222.252 231.538,222.317 230.601 C 222.383 229.663,222.383 228.129,222.317 227.192 C 222.252 226.254,222.198 227.021,222.198 228.896 M149.151 226.767 C 148.773 227.752,149.171 228.408,150.165 228.439 C 151.086 228.468,151.090 228.463,150.244 228.338 C 148.846 228.131,148.974 226.711,150.406 226.534 L 151.461 226.403 150.396 226.351 C 149.729 226.318,149.263 226.474,149.151 226.767 M189.072 229.708 C 189.074 231.136,189.131 231.680,189.199 230.917 C 189.268 230.153,189.267 228.984,189.197 228.319 C 189.127 227.654,189.071 228.279,189.072 229.708 M207.571 229.221 C 207.571 230.381,207.630 230.856,207.702 230.276 C 207.774 229.696,207.774 228.746,207.702 228.166 C 207.630 227.585,207.571 228.060,207.571 229.221 M106.278 229.870 C 106.278 231.209,106.335 231.757,106.405 231.088 C 106.475 230.418,106.475 229.322,106.405 228.653 C 106.335 227.983,106.278 228.531,106.278 229.870 M138.313 228.408 C 137.894 228.854,137.613 229.273,137.688 229.339 C 137.763 229.406,138.165 229.041,138.580 228.529 C 139.509 227.382,139.346 227.308,138.313 228.408 M188.096 229.870 C 188.096 231.209,188.153 231.757,188.224 231.088 C 188.294 230.418,188.294 229.322,188.224 228.653 C 188.153 227.983,188.096 228.531,188.096 229.870 M190.044 229.870 C 190.044 231.209,190.102 231.757,190.172 231.088 C 190.242 230.418,190.242 229.322,190.172 228.653 C 190.102 227.983,190.044 228.531,190.044 229.870 M208.539 229.221 C 208.539 230.203,208.600 230.605,208.674 230.114 C 208.748 229.623,208.748 228.819,208.674 228.328 C 208.600 227.837,208.539 228.239,208.539 229.221 M196.532 230.195 C 196.532 231.356,196.591 231.830,196.663 231.250 C 196.735 230.670,196.735 229.720,196.663 229.140 C 196.591 228.559,196.532 229.034,196.532 230.195 M195.555 230.357 C 195.557 231.429,195.618 231.828,195.690 231.244 C 195.762 230.661,195.761 229.784,195.687 229.296 C 195.612 228.808,195.553 229.286,195.555 230.357 M276.075 230.357 C 276.076 231.429,276.137 231.828,276.209 231.244 C 276.282 230.661,276.280 229.784,276.206 229.296 C 276.132 228.808,276.073 229.286,276.075 230.357 M275.097 230.519 C 275.097 231.502,275.158 231.903,275.233 231.412 C 275.307 230.921,275.307 230.118,275.233 229.627 C 275.158 229.136,275.097 229.537,275.097 230.519 M144.156 229.491 C 144.156 229.724,143.500 229.893,142.451 229.929 L 140.747 229.987 142.334 230.111 C 143.827 230.227,144.873 229.830,144.378 229.334 C 144.256 229.212,144.156 229.283,144.156 229.491 M191.002 230.682 C 191.004 231.575,191.067 231.901,191.142 231.408 C 191.217 230.914,191.215 230.184,191.138 229.784 C 191.061 229.385,191.000 229.789,191.002 230.682 M261.688 229.491 C 261.688 229.724,261.033 229.893,259.984 229.929 L 258.279 229.987 259.867 230.111 C 261.360 230.227,262.405 229.830,261.910 229.334 C 261.788 229.212,261.688 229.283,261.688 229.491 M149.114 230.844 C 149.114 231.648,149.178 231.976,149.255 231.575 C 149.332 231.173,149.332 230.515,149.255 230.114 C 149.178 229.712,149.114 230.041,149.114 230.844 M136.490 230.334 C 136.392 230.588,136.367 231.136,136.433 231.551 C 136.522 232.106,136.598 231.983,136.718 231.088 C 136.888 229.827,136.798 229.530,136.490 230.334 M155.404 230.120 C 155.319 230.257,155.858 230.322,156.602 230.265 C 158.787 230.096,159.053 229.948,157.243 229.908 C 156.316 229.887,155.488 229.982,155.404 230.120 M199.275 230.105 C 199.859 230.178,200.735 230.176,201.223 230.102 C 201.711 230.028,201.234 229.969,200.162 229.971 C 199.091 229.973,198.692 230.033,199.275 230.105 M268.066 230.120 C 267.981 230.257,268.520 230.322,269.264 230.265 C 271.449 230.096,271.715 229.948,269.906 229.908 C 268.979 229.887,268.151 229.982,268.066 230.120 M267.019 234.167 L 266.396 234.903 267.074 234.332 C 267.722 233.786,267.776 233.787,268.293 234.359 C 269.000 235.141,269.669 235.115,270.372 234.280 L 270.942 233.604 270.177 234.253 C 269.242 235.048,269.369 235.054,268.425 234.167 L 267.642 233.431 267.019 234.167 M275.136 234.167 L 274.513 234.903 275.191 234.332 C 275.839 233.786,275.893 233.787,276.410 234.359 C 276.707 234.688,277.169 234.957,277.435 234.957 C 277.701 234.957,278.163 234.688,278.460 234.359 C 278.978 233.787,279.032 233.786,279.679 234.332 L 280.357 234.903 279.734 234.167 L 279.111 233.431 278.328 234.167 C 277.897 234.572,277.496 234.903,277.435 234.903 C 277.375 234.903,276.973 234.572,276.542 234.167 L 275.759 233.431 275.136 234.167 M283.253 234.167 L 282.630 234.903 283.308 234.332 C 283.955 233.786,284.009 233.787,284.527 234.359 C 284.824 234.688,285.286 234.957,285.552 234.957 C 285.818 234.957,286.280 234.688,286.577 234.359 C 287.094 233.787,287.148 233.786,287.796 234.332 L 288.474 234.903 287.851 234.167 L 287.228 233.431 286.445 234.167 C 286.014 234.572,285.612 234.903,285.552 234.903 C 285.491 234.903,285.090 234.572,284.659 234.167 L 283.876 233.431 283.253 234.167 M292.635 234.303 C 293.283 235.070,293.945 235.107,294.565 234.412 C 294.873 234.066,294.822 234.071,294.349 234.431 C 293.588 235.012,293.721 235.027,292.810 234.253 L 292.045 233.604 292.635 234.303 M109.525 238.636 C 109.525 239.976,109.582 240.524,109.652 239.854 C 109.722 239.184,109.722 238.088,109.652 237.419 C 109.582 236.749,109.525 237.297,109.525 238.636 M110.510 239.610 C 110.510 241.485,110.563 242.252,110.629 241.315 C 110.695 240.377,110.695 238.843,110.629 237.906 C 110.563 236.968,110.510 237.735,110.510 239.610 M182.263 239.610 C 182.263 241.485,182.317 242.252,182.382 241.315 C 182.448 240.377,182.448 238.843,182.382 237.906 C 182.317 236.968,182.263 237.735,182.263 239.610 M183.237 239.610 C 183.237 241.485,183.291 242.252,183.356 241.315 C 183.422 240.377,183.422 238.843,183.356 237.906 C 183.291 236.968,183.237 237.735,183.237 239.610 M231.289 239.610 C 231.289 241.485,231.343 242.252,231.408 241.315 C 231.474 240.377,231.474 238.843,231.408 237.906 C 231.343 236.968,231.289 237.735,231.289 239.610 M232.143 237.338 C 232.143 237.873,232.264 238.312,232.411 238.312 C 232.559 238.312,232.615 237.873,232.537 237.338 C 232.458 236.802,232.337 236.364,232.268 236.364 C 232.199 236.364,232.143 236.802,232.143 237.338 M290.380 239.610 C 290.380 241.485,290.434 242.252,290.499 241.315 C 290.565 240.377,290.565 238.843,290.499 237.906 C 290.434 236.968,290.380 237.735,290.380 239.610 M291.354 239.610 C 291.354 241.485,291.408 242.252,291.473 241.315 C 291.539 240.377,291.539 238.843,291.473 237.906 C 291.408 236.968,291.354 237.735,291.354 239.610 M206.280 240.422 C 206.281 241.851,206.338 242.395,206.407 241.631 C 206.476 240.867,206.475 239.699,206.405 239.034 C 206.335 238.369,206.279 238.994,206.280 240.422 M265.191 238.231 C 265.132 238.364,265.173 239.278,265.281 240.260 L 265.479 242.045 265.531 240.016 C 265.580 238.161,265.472 237.592,265.191 238.231 M106.278 240.584 C 106.278 241.924,106.335 242.472,106.405 241.802 C 106.475 241.132,106.475 240.037,106.405 239.367 C 106.335 238.697,106.278 239.245,106.278 240.584 M266.331 239.935 C 266.331 240.917,266.392 241.319,266.466 240.828 C 266.541 240.337,266.541 239.533,266.466 239.042 C 266.392 238.551,266.331 238.953,266.331 239.935 M172.503 241.071 C 172.505 242.143,172.566 242.542,172.638 241.958 C 172.710 241.375,172.709 240.498,172.635 240.010 C 172.561 239.523,172.501 240.000,172.503 241.071 M202.698 241.071 C 202.700 242.143,202.760 242.542,202.833 241.958 C 202.905 241.375,202.903 240.498,202.829 240.010 C 202.755 239.523,202.696 240.000,202.698 241.071 M279.321 241.071 C 279.323 242.143,279.384 242.542,279.456 241.958 C 279.528 241.375,279.527 240.498,279.453 240.010 C 279.379 239.523,279.320 240.000,279.321 241.071 M201.721 241.234 C 201.721 242.216,201.782 242.618,201.856 242.127 C 201.930 241.636,201.930 240.832,201.856 240.341 C 201.782 239.850,201.721 240.252,201.721 241.234 M278.344 241.234 C 278.344 242.216,278.405 242.618,278.479 242.127 C 278.554 241.636,278.554 240.832,278.479 240.341 C 278.405 239.850,278.344 240.252,278.344 241.234 M173.469 241.396 C 173.472 242.289,173.535 242.616,173.610 242.122 C 173.684 241.629,173.682 240.898,173.605 240.499 C 173.528 240.099,173.467 240.503,173.469 241.396 M207.231 241.558 C 207.231 242.362,207.295 242.691,207.372 242.289 C 207.449 241.887,207.449 241.230,207.372 240.828 C 207.295 240.426,207.231 240.755,207.231 241.558 M125.899 240.820 C 126.482 240.892,127.359 240.890,127.847 240.816 C 128.335 240.742,127.857 240.683,126.786 240.685 C 125.714 240.687,125.315 240.747,125.899 240.820 M228.003 240.817 C 228.494 240.891,229.298 240.891,229.789 240.817 C 230.280 240.743,229.878 240.682,228.896 240.682 C 227.914 240.682,227.512 240.743,228.003 240.817 M253.003 240.817 C 253.494 240.891,254.298 240.891,254.789 240.817 C 255.280 240.743,254.878 240.682,253.896 240.682 C 252.914 240.682,252.512 240.743,253.003 240.817 M294.080 240.820 C 294.664 240.892,295.541 240.890,296.029 240.816 C 296.516 240.742,296.039 240.683,294.968 240.685 C 293.896 240.687,293.497 240.747,294.080 240.820 M61.766 263.393 L 61.688 279.545 98.295 279.466 L 134.903 279.386 98.461 279.302 L 62.019 279.218 61.932 263.229 L 61.844 247.240 61.766 263.393 M93.904 258.969 C 94.392 259.114,94.476 259.717,94.567 263.740 L 94.672 268.344 94.657 263.640 C 94.644 259.181,94.609 258.933,93.994 258.870 C 93.505 258.820,93.483 258.845,93.904 258.969 M101.745 264.773 C 101.746 266.737,101.799 267.499,101.864 266.465 C 101.928 265.432,101.928 263.825,101.862 262.894 C 101.797 261.963,101.744 262.808,101.745 264.773 M107.256 265.584 C 107.256 267.102,107.312 267.723,107.381 266.964 C 107.449 266.205,107.449 264.963,107.381 264.205 C 107.312 263.446,107.256 264.067,107.256 265.584 M105.948 266.234 C 105.948 267.394,106.007 267.869,106.079 267.289 C 106.151 266.709,106.151 265.759,106.079 265.179 C 106.007 264.598,105.948 265.073,105.948 266.234 M79.541 280.112 L 97.718 280.200 97.811 290.263 L 97.904 300.325 97.897 290.179 L 97.890 280.032 79.627 280.028 L 61.364 280.024 79.541 280.112 M98.593 280.087 C 98.293 280.387,98.319 300.327,98.620 300.314 C 98.960 300.300,100.649 298.785,100.649 298.494 C 100.649 298.363,100.211 298.675,99.675 299.188 L 98.701 300.121 98.701 290.161 L 98.701 280.200 116.964 280.114 L 135.227 280.027 117.018 279.949 C 107.004 279.905,98.712 279.968,98.593 280.087 M61.688 321.266 L 61.688 337.338 98.295 337.258 L 134.903 337.178 98.458 337.094 L 62.013 337.010 62.013 321.266 L 62.013 305.522 98.458 305.438 L 134.903 305.354 98.295 305.275 L 61.688 305.195 61.688 321.266 M84.977 316.793 C 85.553 316.864,86.576 316.866,87.249 316.795 C 87.923 316.725,87.451 316.666,86.201 316.665 C 84.951 316.664,84.400 316.721,84.977 316.793 M111.169 317.011 C 111.074 317.260,111.054 318.027,111.125 318.716 C 111.250 319.924,111.256 319.914,111.309 318.449 C 111.350 317.305,111.504 316.894,111.932 316.782 C 112.464 316.643,112.464 316.631,111.922 316.596 C 111.604 316.575,111.265 316.762,111.169 317.011 " stroke="none" fill="#9d9d9d" fill-rule="evenodd"></path><path id="path3" d="M61.039 31.816 L 61.039 48.371 79.464 48.455 L 97.890 48.539 97.975 58.750 L 98.061 68.962 97.083 68.024 C 95.886 66.878,95.886 66.812,97.078 70.077 C 97.614 71.545,98.052 72.814,98.052 72.896 C 98.052 72.979,89.761 73.084,79.627 73.130 L 61.201 73.214 61.201 89.773 L 61.201 106.331 79.627 106.415 L 98.052 106.499 98.052 116.561 C 98.052 122.095,97.952 126.623,97.829 126.623 C 97.707 126.623,97.260 126.297,96.836 125.899 C 96.078 125.187,96.081 125.219,97.058 127.869 C 97.605 129.351,98.052 130.626,98.052 130.701 C 98.052 130.777,89.761 130.877,79.627 130.923 L 61.201 131.006 61.201 147.565 L 61.201 164.123 79.627 164.207 L 98.052 164.291 98.052 174.576 L 98.052 184.862 97.053 183.908 L 96.055 182.955 97.053 185.695 C 97.603 187.203,98.052 188.554,98.052 188.699 C 98.052 188.843,89.724 188.961,79.545 188.961 L 61.039 188.961 61.039 205.519 L 61.039 222.078 79.545 222.078 L 98.052 222.078 98.052 232.366 L 98.052 242.654 97.078 241.721 C 96.542 241.208,96.104 240.851,96.105 240.930 C 96.106 241.008,96.544 242.240,97.078 243.669 C 97.612 245.097,98.050 246.375,98.051 246.507 C 98.051 246.640,89.761 246.786,79.627 246.832 L 61.201 246.916 61.117 263.390 L 61.033 279.865 79.461 279.949 L 97.890 280.032 97.975 290.244 L 98.061 300.455 97.083 299.518 C 95.886 298.371,95.886 298.306,97.078 301.571 C 97.614 303.038,98.052 304.307,98.052 304.390 C 98.052 304.472,89.761 304.578,79.627 304.624 L 61.201 304.708 61.201 321.266 L 61.201 337.825 98.214 337.825 L 135.227 337.825 135.314 329.627 C 135.362 325.118,135.467 321.429,135.548 321.429 C 135.629 321.429,136.897 321.867,138.364 322.403 C 141.628 323.594,141.563 323.594,140.422 322.403 L 139.489 321.429 225.751 321.429 L 312.013 321.429 312.013 176.461 L 312.013 31.494 223.701 31.494 L 135.390 31.494 135.390 23.377 L 135.390 15.260 98.214 15.260 L 61.039 15.260 61.039 31.816 M134.740 31.818 L 134.740 47.727 98.214 47.727 L 61.688 47.727 61.688 31.818 L 61.688 15.909 98.214 15.909 L 134.740 15.909 134.740 31.818 M103.700 32.143 C 103.700 34.732,103.751 35.791,103.813 34.497 C 103.874 33.202,103.874 31.084,103.813 29.789 C 103.751 28.494,103.700 29.554,103.700 32.143 M105.334 30.300 C 105.243 30.537,105.217 32.108,105.277 33.791 L 105.385 36.851 105.452 33.547 C 105.510 30.707,105.599 30.222,106.088 30.094 C 106.620 29.955,106.620 29.943,106.077 29.908 C 105.759 29.887,105.425 30.064,105.334 30.300 M119.874 30.073 C 120.332 30.209,120.450 30.736,120.542 33.057 L 120.653 35.877 120.635 32.958 C 120.618 30.285,120.562 30.034,119.968 29.974 C 119.485 29.924,119.461 29.950,119.874 30.073 M311.608 176.542 L 311.526 320.942 225.507 321.023 L 139.488 321.105 140.421 320.130 C 141.563 318.939,141.629 318.939,138.364 320.130 C 136.897 320.666,135.629 321.104,135.548 321.104 C 135.467 321.104,135.362 317.415,135.314 312.906 L 135.227 304.708 116.802 304.624 C 106.668 304.578,98.377 304.478,98.377 304.401 C 98.377 304.325,98.812 303.130,99.345 301.747 C 100.394 299.024,100.422 298.670,99.515 299.673 C 98.425 300.877,98.367 300.357,98.453 290.179 L 98.539 280.032 116.964 279.949 L 135.390 279.865 135.390 263.309 L 135.390 246.753 116.883 246.753 C 106.705 246.753,98.377 246.690,98.377 246.613 C 98.377 246.536,98.815 245.284,99.351 243.831 C 100.549 240.581,100.549 240.573,99.346 241.725 L 98.367 242.663 98.453 232.452 L 98.539 222.240 116.964 222.156 L 135.390 222.073 135.390 205.517 L 135.390 188.961 116.883 188.961 C 106.705 188.961,98.377 188.892,98.377 188.808 C 98.377 188.724,98.814 187.457,99.349 185.992 C 100.398 183.116,100.425 182.759,99.515 183.764 C 98.435 184.957,98.377 184.473,98.377 174.351 L 98.377 164.286 116.886 164.286 L 135.396 164.286 135.311 147.646 L 135.227 131.006 116.802 130.923 C 106.668 130.877,98.377 130.803,98.378 130.760 C 98.378 130.717,98.813 129.521,99.343 128.102 C 100.388 125.303,100.415 124.978,99.515 125.972 C 98.435 127.165,98.377 126.681,98.377 116.561 L 98.377 106.499 116.802 106.415 L 135.227 106.331 135.314 98.133 L 135.401 89.935 150.006 89.935 L 164.610 89.935 164.610 147.565 L 164.610 205.195 152.054 205.195 L 139.497 205.195 140.284 204.331 C 140.749 203.821,140.872 203.535,140.584 203.632 C 137.851 204.555,135.715 205.382,135.717 205.517 C 135.718 205.607,136.975 206.144,138.510 206.709 L 141.302 207.736 140.395 206.790 L 139.489 205.844 152.375 205.844 L 165.262 205.844 165.179 147.646 L 165.097 89.448 150.244 89.364 L 135.390 89.279 135.390 81.166 L 135.390 73.052 116.883 73.052 C 106.705 73.052,98.377 73.007,98.377 72.952 C 98.377 72.897,98.827 71.618,99.377 70.111 C 100.365 67.402,100.368 67.379,99.599 68.101 C 99.172 68.502,98.720 68.831,98.595 68.831 C 98.470 68.831,98.406 64.265,98.453 58.685 L 98.539 48.539 116.964 48.455 L 135.390 48.371 135.390 40.257 L 135.390 32.143 223.539 32.143 L 311.689 32.143 311.608 176.542 M86.120 32.700 C 86.611 32.774,87.415 32.774,87.906 32.700 C 88.397 32.626,87.995 32.565,87.013 32.565 C 86.031 32.565,85.629 32.626,86.120 32.700 M78.332 33.025 C 78.826 33.100,79.556 33.098,79.956 33.021 C 80.355 32.944,79.951 32.883,79.058 32.885 C 78.166 32.888,77.839 32.951,78.332 33.025 M134.211 60.714 C 134.211 62.589,134.265 63.356,134.330 62.419 C 134.396 61.481,134.396 59.947,134.330 59.010 C 134.265 58.072,134.211 58.839,134.211 60.714 M178.690 60.552 C 178.691 62.338,178.745 63.027,178.811 62.083 C 178.877 61.140,178.876 59.679,178.810 58.837 C 178.743 57.994,178.689 58.766,178.690 60.552 M195.250 60.714 C 195.250 62.589,195.304 63.356,195.369 62.419 C 195.435 61.481,195.435 59.947,195.369 59.010 C 195.304 58.072,195.250 58.839,195.250 60.714 M135.795 58.341 C 136.108 58.422,136.619 58.422,136.932 58.341 C 137.244 58.259,136.989 58.192,136.364 58.192 C 135.739 58.192,135.483 58.259,135.795 58.341 M168.588 58.341 C 168.900 58.422,169.412 58.422,169.724 58.341 C 170.037 58.259,169.781 58.192,169.156 58.192 C 168.531 58.192,168.275 58.259,168.588 58.341 M118.642 59.531 C 118.549 59.773,118.525 60.905,118.590 62.047 L 118.706 64.123 118.769 61.797 C 118.809 60.290,118.974 59.412,119.237 59.306 C 119.555 59.178,119.553 59.137,119.227 59.117 C 118.998 59.102,118.735 59.289,118.642 59.531 M143.409 59.319 C 143.624 59.472,143.853 60.607,143.921 61.860 L 144.044 64.123 144.019 61.714 C 143.999 59.863,143.881 59.275,143.506 59.173 C 143.163 59.080,143.134 59.123,143.409 59.319 M185.198 59.538 C 185.103 59.784,185.082 60.697,185.149 61.567 L 185.273 63.149 185.331 61.310 C 185.367 60.190,185.548 59.406,185.795 59.306 C 186.113 59.178,186.111 59.137,185.785 59.117 C 185.556 59.102,185.292 59.292,185.198 59.538 M210.204 59.522 C 209.852 60.440,210.219 65.693,210.641 65.777 C 210.869 65.823,210.905 65.786,210.722 65.695 C 210.123 65.398,210.292 59.309,210.893 59.539 C 211.182 59.650,211.313 59.596,211.199 59.412 C 210.918 58.957,210.399 59.014,210.204 59.522 M193.932 62.175 C 193.934 63.247,193.994 63.646,194.066 63.062 C 194.139 62.479,194.137 61.602,194.063 61.114 C 193.989 60.626,193.930 61.104,193.932 62.175 M131.907 62.662 C 131.907 63.466,131.970 63.795,132.047 63.393 C 132.125 62.991,132.125 62.334,132.047 61.932 C 131.970 61.530,131.907 61.859,131.907 62.662 M197.164 63.220 C 197.657 63.295,198.388 63.293,198.787 63.216 C 199.186 63.138,198.782 63.077,197.890 63.080 C 196.997 63.082,196.670 63.145,197.164 63.220 M134.740 89.773 L 134.740 105.844 98.214 105.844 L 61.688 105.844 61.688 89.773 L 61.688 73.701 98.214 73.701 L 134.740 73.701 134.740 89.773 M84.551 88.102 C 84.458 88.344,84.435 89.477,84.499 90.619 L 84.615 92.695 84.678 90.365 C 84.729 88.451,84.842 88.008,85.308 87.886 C 85.841 87.747,85.840 87.735,85.298 87.700 C 84.980 87.679,84.644 87.860,84.551 88.102 M88.770 88.107 C 88.676 88.351,88.654 89.338,88.720 90.298 L 88.841 92.045 88.901 90.040 C 88.949 88.434,89.074 88.005,89.529 87.886 C 90.062 87.747,90.061 87.735,89.519 87.700 C 89.201 87.679,88.864 87.862,88.770 88.107 M91.698 88.093 C 91.607 88.329,91.581 89.900,91.640 91.583 L 91.748 94.643 91.816 91.339 C 91.874 88.499,91.963 88.014,92.451 87.886 C 92.984 87.747,92.983 87.735,92.441 87.700 C 92.123 87.679,91.788 87.856,91.698 88.093 M105.659 88.093 C 105.568 88.329,105.542 89.900,105.601 91.583 L 105.709 94.643 105.777 91.339 C 105.835 88.499,105.924 88.014,106.412 87.886 C 106.945 87.747,106.944 87.735,106.402 87.700 C 106.084 87.679,105.749 87.856,105.659 88.093 M120.199 87.865 C 120.657 88.001,120.775 88.528,120.867 90.849 L 120.978 93.669 120.960 90.750 C 120.943 88.077,120.887 87.827,120.292 87.766 C 119.810 87.717,119.786 87.742,120.199 87.865 M62.735 116.940 C 62.497 117.178,62.466 117.458,62.652 117.682 C 62.816 117.880,63.004 118.914,63.070 119.979 L 63.189 121.916 63.250 119.906 C 63.285 118.785,63.161 117.802,62.971 117.685 C 62.739 117.541,62.751 117.330,63.011 117.017 C 63.471 116.462,63.269 116.406,62.735 116.940 M199.123 127.922 C 199.123 128.904,199.184 129.306,199.259 128.815 C 199.333 128.324,199.333 127.520,199.259 127.029 C 199.184 126.538,199.123 126.940,199.123 127.922 M201.225 128.194 C 201.541 128.395,201.484 128.597,200.982 129.051 C 200.620 129.379,200.325 129.781,200.325 129.945 C 200.325 130.110,200.690 129.811,201.136 129.280 C 202.098 128.137,202.137 127.920,201.380 127.927 C 200.966 127.931,200.924 128.003,201.225 128.194 M207.928 128.362 C 207.835 128.604,207.811 129.736,207.875 130.878 L 207.992 132.955 208.054 130.628 C 208.095 129.121,208.260 128.243,208.523 128.137 C 208.841 128.009,208.838 127.968,208.513 127.948 C 208.284 127.934,208.021 128.120,207.928 128.362 M134.740 147.565 L 134.740 163.636 98.214 163.636 L 61.688 163.636 61.688 147.565 L 61.688 131.494 98.214 131.494 L 134.740 131.494 134.740 147.565 M199.123 138.636 C 199.123 139.619,199.184 140.020,199.259 139.529 C 199.333 139.038,199.333 138.235,199.259 137.744 C 199.184 137.252,199.123 137.654,199.123 138.636 M277.393 140.260 C 277.393 142.135,277.447 142.902,277.512 141.964 C 277.578 141.027,277.578 139.493,277.512 138.555 C 277.447 137.618,277.393 138.385,277.393 140.260 M289.361 137.987 C 289.361 138.612,289.428 138.868,289.510 138.555 C 289.591 138.243,289.591 137.731,289.510 137.419 C 289.428 137.106,289.361 137.362,289.361 137.987 M201.225 138.909 C 201.541 139.109,201.484 139.312,200.982 139.766 C 200.620 140.093,200.325 140.495,200.325 140.660 C 200.325 140.824,200.690 140.525,201.136 139.994 C 202.098 138.851,202.137 138.635,201.380 138.641 C 200.966 138.645,200.924 138.717,201.225 138.909 M207.928 139.076 C 207.835 139.318,207.811 140.451,207.875 141.593 L 207.992 143.669 208.054 141.342 C 208.095 139.835,208.260 138.957,208.523 138.851 C 208.841 138.723,208.838 138.682,208.513 138.662 C 208.284 138.648,208.021 138.834,207.928 139.076 M232.928 139.076 C 232.835 139.318,232.811 140.451,232.875 141.593 L 232.992 143.669 233.054 141.342 C 233.095 139.835,233.260 138.957,233.523 138.851 C 233.841 138.723,233.838 138.682,233.513 138.662 C 233.284 138.648,233.021 138.834,232.928 139.076 M258.902 139.076 C 258.809 139.318,258.785 140.451,258.849 141.593 L 258.966 143.669 259.028 141.342 C 259.069 139.835,259.234 138.957,259.497 138.851 C 259.815 138.723,259.812 138.682,259.487 138.662 C 259.258 138.648,258.995 138.834,258.902 139.076 M241.651 141.071 C 241.654 141.964,241.717 142.291,241.791 141.797 C 241.866 141.304,241.864 140.573,241.787 140.174 C 241.710 139.775,241.649 140.179,241.651 141.071 M221.192 142.208 C 221.192 143.011,221.256 143.340,221.333 142.938 C 221.410 142.537,221.410 141.879,221.333 141.477 C 221.256 141.075,221.192 141.404,221.192 142.208 M173.442 141.948 C 172.742 142.648,173.027 142.858,174.594 142.800 L 176.136 142.744 174.733 142.618 C 173.556 142.513,173.392 142.418,173.718 142.026 C 174.187 141.460,173.986 141.404,173.442 141.948 M217.283 148.701 C 217.283 149.326,217.350 149.582,217.432 149.269 C 217.513 148.957,217.513 148.446,217.432 148.133 C 217.350 147.821,217.283 148.076,217.283 148.701 M232.912 150.974 C 232.912 152.849,232.966 153.616,233.032 152.679 C 233.097 151.741,233.097 150.207,233.032 149.269 C 232.966 148.332,232.912 149.099,232.912 150.974 M107.247 150.000 C 107.247 151.161,107.306 151.636,107.378 151.055 C 107.450 150.475,107.450 149.525,107.378 148.945 C 107.306 148.364,107.247 148.839,107.247 150.000 M183.847 148.609 C 184.338 148.684,185.142 148.684,185.633 148.609 C 186.124 148.535,185.722 148.474,184.740 148.474 C 183.758 148.474,183.356 148.535,183.847 148.609 M221.561 149.798 C 221.467 150.044,221.445 150.957,221.513 151.827 L 221.636 153.409 221.695 151.569 C 221.730 150.450,221.912 149.665,222.159 149.566 C 222.477 149.437,222.475 149.396,222.149 149.376 C 221.920 149.362,221.656 149.552,221.561 149.798 M245.590 149.791 C 245.497 150.033,245.474 151.165,245.538 152.307 L 245.654 154.383 245.717 152.056 C 245.757 150.549,245.922 149.672,246.185 149.566 C 246.503 149.437,246.501 149.396,246.175 149.376 C 245.946 149.362,245.683 149.549,245.590 149.791 M226.618 151.882 L 226.775 153.734 226.881 152.146 C 226.940 151.273,226.869 150.440,226.724 150.295 C 226.579 150.149,226.532 150.864,226.618 151.882 M183.852 150.558 C 184.345 150.632,185.076 150.630,185.475 150.553 C 185.875 150.476,185.471 150.415,184.578 150.418 C 183.685 150.420,183.358 150.483,183.852 150.558 M217.296 152.922 C 217.296 153.726,217.360 154.054,217.437 153.653 C 217.514 153.251,217.514 152.593,217.437 152.192 C 217.360 151.790,217.296 152.119,217.296 152.922 M368.906 157.792 C 368.906 158.417,368.973 158.673,369.055 158.360 C 369.137 158.048,369.137 157.537,369.055 157.224 C 368.973 156.912,368.906 157.167,368.906 157.792 M364.388 157.767 C 364.421 158.199,364.667 158.612,364.935 158.684 C 365.257 158.771,365.297 158.725,365.054 158.547 C 364.851 158.400,364.605 157.987,364.507 157.630 C 364.366 157.118,364.341 157.147,364.388 157.767 M319.930 157.936 C 319.490 159.083,319.934 159.577,321.431 159.604 L 322.890 159.631 321.510 159.505 C 319.217 159.297,319.474 157.872,321.834 157.707 L 323.539 157.588 321.824 157.528 C 320.589 157.484,320.059 157.598,319.930 157.936 M334.164 158.499 C 333.926 158.737,333.894 159.016,334.080 159.241 C 334.245 159.438,334.433 160.472,334.498 161.537 L 334.617 163.474 334.679 161.464 C 334.713 160.344,334.590 159.361,334.400 159.244 C 334.167 159.100,334.180 158.888,334.440 158.575 C 334.900 158.021,334.697 157.965,334.164 158.499 M326.434 158.882 C 326.341 159.124,326.318 160.256,326.382 161.398 L 326.498 163.474 326.561 161.147 C 326.601 159.640,326.766 158.763,327.029 158.657 C 327.347 158.528,327.345 158.487,327.019 158.467 C 326.790 158.453,326.527 158.640,326.434 158.882 M358.663 158.666 C 358.874 158.816,359.108 159.594,359.185 160.395 L 359.323 161.851 359.288 160.253 C 359.264 159.128,359.109 158.616,358.766 158.523 C 358.430 158.433,358.398 158.477,358.663 158.666 M364.502 159.307 C 364.205 159.605,364.228 162.264,364.529 162.450 C 364.663 162.533,364.720 161.939,364.656 161.130 C 364.577 160.138,364.682 159.570,364.980 159.381 C 365.223 159.227,365.264 159.099,365.070 159.096 C 364.877 159.093,364.621 159.188,364.502 159.307 M357.243 161.526 C 357.245 162.597,357.306 162.997,357.378 162.413 C 357.450 161.829,357.449 160.953,357.375 160.465 C 357.301 159.977,357.242 160.455,357.243 161.526 M319.898 161.851 C 319.900 162.744,319.964 163.070,320.038 162.577 C 320.113 162.083,320.111 161.353,320.034 160.953 C 319.957 160.554,319.896 160.958,319.898 161.851 M383.205 162.013 C 383.205 162.817,383.269 163.145,383.346 162.744 C 383.423 162.342,383.423 161.684,383.346 161.282 C 383.269 160.881,383.205 161.209,383.205 162.013 M35.200 174.791 C 35.107 175.033,35.084 176.165,35.148 177.307 L 35.264 179.383 35.327 177.056 C 35.368 175.549,35.533 174.672,35.795 174.566 C 36.113 174.437,36.111 174.396,35.785 174.376 C 35.556 174.362,35.293 174.549,35.200 174.791 M66.010 177.435 C 66.012 178.506,66.072 178.906,66.144 178.322 C 66.217 177.739,66.215 176.862,66.141 176.374 C 66.067 175.886,66.008 176.364,66.010 177.435 M45.452 176.527 C 46.075 176.609,46.707 176.847,46.856 177.056 C 47.041 177.314,47.086 177.280,46.996 176.948 C 46.911 176.630,46.423 176.447,45.592 176.420 C 44.372 176.380,44.366 176.385,45.452 176.527 M71.510 178.479 C 72.001 178.554,72.804 178.554,73.295 178.479 C 73.787 178.405,73.385 178.344,72.403 178.344 C 71.420 178.344,71.019 178.405,71.510 178.479 M134.740 205.519 L 134.740 221.429 98.214 221.429 L 61.688 221.429 61.688 205.519 L 61.688 189.610 98.214 189.610 L 134.740 189.610 134.740 205.519 M108.571 205.519 C 108.571 208.109,108.621 209.168,108.683 207.873 C 108.744 206.579,108.744 204.460,108.683 203.166 C 108.621 201.871,108.571 202.930,108.571 205.519 M87.152 203.677 C 87.061 203.914,87.036 205.484,87.095 207.167 L 87.203 210.227 87.270 206.923 C 87.328 204.083,87.418 203.598,87.906 203.471 C 88.438 203.331,88.438 203.320,87.896 203.284 C 87.578 203.264,87.243 203.440,87.152 203.677 M110.784 203.449 C 111.252 203.588,111.359 204.133,111.452 206.841 L 111.562 210.066 111.544 206.742 C 111.527 203.662,111.478 203.412,110.877 203.350 C 110.393 203.301,110.369 203.326,110.784 203.449 M124.745 203.449 C 125.203 203.585,125.321 204.113,125.412 206.434 L 125.524 209.253 125.505 206.335 C 125.489 203.662,125.432 203.411,124.838 203.350 C 124.355 203.301,124.331 203.326,124.745 203.449 M102.354 206.077 C 102.845 206.151,103.649 206.151,104.140 206.077 C 104.631 206.002,104.229 205.941,103.247 205.941 C 102.265 205.941,101.863 206.002,102.354 206.077 M105.315 228.896 C 105.315 230.771,105.369 231.538,105.434 230.601 C 105.500 229.663,105.500 228.129,105.434 227.192 C 105.369 226.254,105.315 227.021,105.315 228.896 M148.171 228.734 C 148.171 230.519,148.226 231.209,148.292 230.265 C 148.357 229.322,148.357 227.861,148.290 227.018 C 148.224 226.176,148.170 226.948,148.171 228.734 M227.393 228.896 C 227.393 230.771,227.447 231.538,227.512 230.601 C 227.578 229.663,227.578 228.129,227.512 227.192 C 227.447 226.254,227.393 227.021,227.393 228.896 M132.603 227.713 C 132.510 227.955,132.487 229.087,132.551 230.229 L 132.667 232.305 132.730 229.978 C 132.770 228.471,132.935 227.594,133.198 227.488 C 133.516 227.359,133.514 227.318,133.188 227.298 C 132.959 227.284,132.696 227.471,132.603 227.713 M210.941 227.500 C 211.157 227.654,211.386 228.789,211.454 230.041 L 211.577 232.305 211.551 229.896 C 211.532 228.045,211.413 227.456,211.039 227.355 C 210.696 227.262,210.667 227.305,210.941 227.500 M223.163 229.708 C 223.164 231.136,223.222 231.680,223.290 230.917 C 223.359 230.153,223.358 228.984,223.288 228.319 C 223.218 227.654,223.162 228.279,223.163 229.708 M272.213 227.713 C 272.120 227.955,272.097 229.087,272.161 230.229 L 272.277 232.305 272.340 229.978 C 272.381 228.471,272.546 227.594,272.808 227.488 C 273.126 227.359,273.124 227.318,272.798 227.298 C 272.569 227.284,272.306 227.471,272.213 227.713 M185.709 229.804 L 185.866 231.656 185.972 230.068 C 186.031 229.195,185.960 228.362,185.815 228.217 C 185.670 228.071,185.623 228.786,185.709 229.804 M277.268 229.804 L 277.425 231.656 277.531 230.068 C 277.589 229.195,277.518 228.362,277.374 228.217 C 277.229 228.071,277.181 228.786,277.268 229.804 M248.145 230.682 C 248.147 231.575,248.210 231.901,248.285 231.408 C 248.360 230.914,248.358 230.184,248.280 229.784 C 248.203 229.385,248.142 229.789,248.145 230.682 M255.517 229.449 C 256.140 229.531,256.772 229.769,256.921 229.978 C 257.106 230.237,257.151 230.202,257.061 229.870 C 256.976 229.552,256.488 229.369,255.657 229.342 C 254.437 229.302,254.431 229.307,255.517 229.449 M145.868 230.844 C 145.868 231.648,145.931 231.976,146.008 231.575 C 146.086 231.173,146.086 230.515,146.008 230.114 C 145.931 229.712,145.868 230.041,145.868 230.844 M282.138 231.400 C 282.938 231.476,283.716 231.711,283.867 231.922 C 284.056 232.187,284.100 232.155,284.009 231.818 C 283.917 231.476,283.404 231.321,282.280 231.296 L 280.682 231.261 282.138 231.400 M295.536 232.955 C 295.540 233.669,295.607 233.923,295.684 233.519 C 295.762 233.115,295.759 232.531,295.678 232.220 C 295.596 231.910,295.533 232.240,295.536 232.955 M105.315 239.610 C 105.315 241.485,105.369 242.252,105.434 241.315 C 105.500 240.377,105.500 238.843,105.434 237.906 C 105.369 236.968,105.315 237.735,105.315 239.610 M138.107 239.610 C 138.107 241.485,138.161 242.252,138.226 241.315 C 138.292 240.377,138.292 238.843,138.226 237.906 C 138.161 236.968,138.107 237.735,138.107 239.610 M214.406 239.610 C 214.406 241.485,214.459 242.252,214.525 241.315 C 214.591 240.377,214.591 238.843,214.525 237.906 C 214.459 236.968,214.406 237.735,214.406 239.610 M119.295 238.419 C 118.942 239.336,119.310 244.589,119.732 244.673 C 119.960 244.719,119.996 244.682,119.813 244.591 C 119.214 244.294,119.383 238.205,119.984 238.436 C 120.273 238.546,120.404 238.492,120.290 238.308 C 120.009 237.853,119.490 237.910,119.295 238.419 M149.201 238.291 C 149.077 238.492,149.191 238.553,149.482 238.441 C 149.885 238.286,149.992 238.674,150.087 240.636 L 150.203 243.019 150.183 240.610 C 150.164 238.345,149.759 237.389,149.201 238.291 M198.837 238.427 C 198.744 238.669,198.720 239.801,198.784 240.943 L 198.901 243.019 198.963 240.693 C 199.004 239.186,199.169 238.308,199.432 238.202 C 199.750 238.074,199.747 238.033,199.422 238.013 C 199.193 237.999,198.930 238.185,198.837 238.427 M239.414 238.447 C 239.317 238.699,239.299 239.320,239.375 239.826 C 239.494 240.618,239.520 240.580,239.562 239.556 C 239.588 238.902,239.793 238.292,240.016 238.202 C 240.334 238.074,240.332 238.033,240.006 238.013 C 239.777 237.999,239.511 238.194,239.414 238.447 M244.331 238.291 C 244.207 238.492,244.321 238.553,244.612 238.441 C 245.015 238.286,245.122 238.674,245.217 240.636 L 245.333 243.019 245.313 240.610 C 245.293 238.345,244.889 237.389,244.331 238.291 M262.473 238.427 C 262.380 238.669,262.357 239.801,262.421 240.943 L 262.537 243.019 262.600 240.693 C 262.640 239.186,262.805 238.308,263.068 238.202 C 263.386 238.074,263.384 238.033,263.058 238.013 C 262.829 237.999,262.566 238.185,262.473 238.427 M268.734 238.215 C 268.949 238.368,269.178 239.503,269.246 240.756 L 269.369 243.019 269.344 240.610 C 269.324 238.759,269.205 238.171,268.831 238.069 C 268.488 237.977,268.459 238.019,268.734 238.215 M275.460 238.427 C 275.367 238.669,275.344 239.801,275.408 240.943 L 275.524 243.019 275.587 240.693 C 275.627 239.186,275.792 238.308,276.055 238.202 C 276.373 238.074,276.371 238.033,276.045 238.013 C 275.816 237.999,275.553 238.185,275.460 238.427 M203.891 240.518 L 204.048 242.370 204.154 240.783 C 204.212 239.909,204.142 239.076,203.997 238.931 C 203.852 238.786,203.804 239.500,203.891 240.518 M132.236 241.396 C 132.238 242.289,132.301 242.616,132.376 242.122 C 132.450 241.629,132.448 240.898,132.371 240.499 C 132.294 240.099,132.233 240.503,132.236 241.396 M144.249 241.396 C 144.251 242.289,144.314 242.616,144.389 242.122 C 144.463 241.629,144.461 240.898,144.384 240.499 C 144.307 240.099,144.246 240.503,144.249 241.396 M157.556 241.558 C 157.556 242.362,157.619 242.691,157.697 242.289 C 157.774 241.887,157.774 241.230,157.697 240.828 C 157.619 240.426,157.556 240.755,157.556 241.558 M167.621 241.558 C 167.621 242.362,167.684 242.691,167.762 242.289 C 167.839 241.887,167.839 241.230,167.762 240.828 C 167.684 240.426,167.621 240.755,167.621 241.558 M257.231 241.558 C 257.231 242.362,257.295 242.691,257.372 242.289 C 257.449 241.887,257.449 241.230,257.372 240.828 C 257.295 240.426,257.231 240.755,257.231 241.558 M271.192 241.558 C 271.192 242.362,271.256 242.691,271.333 242.289 C 271.410 241.887,271.410 241.230,271.333 240.828 C 271.256 240.426,271.192 240.755,271.192 241.558 M134.740 263.474 L 134.740 279.545 98.214 279.545 L 61.688 279.545 61.688 263.474 L 61.688 247.403 98.214 247.403 L 134.740 247.403 134.740 263.474 M82.272 263.636 C 82.272 266.226,82.322 267.285,82.384 265.990 C 82.446 264.696,82.446 262.577,82.384 261.282 C 82.322 259.988,82.272 261.047,82.272 263.636 M83.548 261.201 C 83.550 262.451,83.608 262.923,83.679 262.249 C 83.749 261.576,83.748 260.553,83.676 259.977 C 83.604 259.400,83.547 259.951,83.548 261.201 M93.311 263.636 C 93.311 266.226,93.361 267.285,93.423 265.990 C 93.485 264.696,93.485 262.577,93.423 261.282 C 93.361 259.988,93.311 261.047,93.311 263.636 M103.026 265.909 C 103.026 267.070,103.085 267.545,103.157 266.964 C 103.229 266.384,103.229 265.434,103.157 264.854 C 103.085 264.274,103.026 264.748,103.026 265.909 M83.539 266.558 C 83.539 267.541,83.600 267.942,83.674 267.451 C 83.748 266.960,83.748 266.157,83.674 265.666 C 83.600 265.175,83.539 265.576,83.539 266.558 M134.740 321.266 L 134.740 337.338 98.214 337.338 L 61.688 337.338 61.688 321.266 L 61.688 305.195 98.214 305.195 L 134.740 305.195 134.740 321.266 M112.467 321.429 C 112.467 324.018,112.517 325.077,112.579 323.782 C 112.640 322.488,112.640 320.369,112.579 319.075 C 112.517 317.780,112.467 318.839,112.467 321.429 M94.886 321.986 C 95.377 322.060,96.181 322.060,96.672 321.986 C 97.163 321.911,96.761 321.851,95.779 321.851 C 94.797 321.851,94.395 321.911,94.886 321.986 " stroke="none" fill="#7c7c7c" fill-rule="evenodd"></path><path id="path4" d="M105.344 66.133 C 106.126 66.987,106.159 66.993,106.806 66.407 C 107.446 65.828,107.489 65.828,108.120 66.399 C 108.753 66.972,108.796 66.969,109.515 66.293 L 110.257 65.596 110.912 66.251 L 111.567 66.906 112.170 66.240 L 112.772 65.574 113.526 66.282 C 114.256 66.969,114.299 66.972,114.932 66.399 C 115.563 65.828,115.606 65.828,116.245 66.406 C 116.889 66.989,116.924 66.986,117.610 66.300 L 118.315 65.596 119.005 66.245 C 119.695 66.893,119.696 66.893,120.292 66.234 L 120.889 65.574 121.591 66.234 L 122.293 66.893 122.890 66.234 L 123.486 65.574 124.240 66.282 C 124.970 66.969,125.013 66.972,125.646 66.399 C 126.277 65.828,126.320 65.828,126.951 66.399 C 127.585 66.972,127.627 66.969,128.358 66.282 L 129.111 65.574 129.708 66.234 C 130.304 66.893,130.305 66.893,130.995 66.245 L 131.685 65.596 132.390 66.300 C 133.076 66.986,133.111 66.989,133.755 66.406 C 134.394 65.828,134.437 65.828,135.068 66.399 C 135.701 66.972,135.744 66.969,136.474 66.282 L 137.228 65.574 137.825 66.234 C 138.421 66.893,138.422 66.893,139.112 66.245 L 139.802 65.596 140.507 66.300 C 141.193 66.986,141.228 66.989,141.872 66.406 C 142.511 65.828,142.554 65.828,143.185 66.399 C 143.818 66.972,143.861 66.969,144.591 66.282 L 145.345 65.574 145.942 66.234 C 146.538 66.893,146.538 66.893,147.229 66.245 L 147.919 65.596 148.623 66.300 C 149.310 66.986,149.345 66.989,149.989 66.406 C 150.628 65.828,150.671 65.828,151.302 66.399 C 151.935 66.972,151.978 66.969,152.708 66.282 L 153.462 65.574 154.058 66.234 C 154.655 66.893,154.655 66.893,155.346 66.245 L 156.036 65.596 156.740 66.300 C 157.426 66.986,157.462 66.989,158.105 66.406 C 158.745 65.828,158.788 65.828,159.419 66.399 C 160.053 66.973,160.095 66.968,160.879 66.232 C 161.827 65.341,161.673 64.879,160.716 65.745 C 160.087 66.314,160.043 66.314,159.412 65.744 C 158.779 65.171,158.737 65.174,158.006 65.861 L 157.253 66.569 156.656 65.909 L 156.059 65.250 155.357 65.909 L 154.655 66.569 154.058 65.909 C 153.462 65.250,153.462 65.250,152.771 65.898 L 152.081 66.547 151.373 65.839 L 150.665 65.131 149.901 65.850 L 149.136 66.569 148.539 65.909 L 147.942 65.250 147.240 65.909 L 146.538 66.569 145.942 65.909 C 145.345 65.250,145.345 65.250,144.654 65.898 L 143.964 66.547 143.260 65.843 C 142.574 65.157,142.538 65.154,141.895 65.736 C 141.255 66.315,141.212 66.315,140.581 65.744 C 139.948 65.171,139.906 65.174,139.175 65.861 L 138.421 66.569 137.825 65.909 C 137.228 65.250,137.228 65.250,136.537 65.898 L 135.847 66.547 135.143 65.843 C 134.457 65.157,134.421 65.154,133.778 65.736 C 133.139 66.315,133.095 66.315,132.464 65.744 C 131.831 65.171,131.789 65.174,131.058 65.861 L 130.305 66.569 129.708 65.909 C 129.111 65.250,129.111 65.250,128.421 65.898 L 127.730 66.547 127.026 65.843 C 126.340 65.157,126.305 65.154,125.661 65.736 C 125.022 66.315,124.979 66.315,124.347 65.744 C 123.714 65.171,123.672 65.174,122.941 65.861 L 122.188 66.569 121.591 65.909 C 120.994 65.250,120.994 65.250,120.304 65.898 L 119.613 66.547 118.909 65.843 C 118.223 65.157,118.188 65.154,117.544 65.736 C 116.905 66.315,116.862 66.315,116.230 65.744 C 115.597 65.171,115.555 65.174,114.824 65.861 L 114.071 66.569 113.474 65.909 C 112.877 65.250,112.877 65.250,112.187 65.898 L 111.496 66.547 110.792 65.843 C 110.106 65.157,110.071 65.154,109.427 65.736 C 108.788 66.315,108.745 66.315,108.113 65.744 C 107.481 65.171,107.438 65.174,106.719 65.850 C 105.978 66.546,105.976 66.546,105.261 65.904 C 104.745 65.440,104.768 65.505,105.344 66.133 M167.193 65.992 L 167.974 66.887 168.661 66.241 C 169.347 65.597,169.349 65.597,170.052 66.300 C 170.738 66.986,170.773 66.989,171.417 66.406 C 172.056 65.828,172.099 65.828,172.731 66.399 C 173.364 66.972,173.406 66.969,174.137 66.282 L 174.890 65.574 175.487 66.234 C 176.084 66.893,176.084 66.893,176.774 66.245 L 177.465 65.596 178.169 66.300 C 178.855 66.986,178.890 66.989,179.534 66.406 C 180.173 65.828,180.216 65.828,180.848 66.399 C 181.481 66.972,181.523 66.969,182.254 66.282 L 183.007 65.574 183.604 66.234 C 184.201 66.893,184.201 66.893,184.891 66.245 L 185.582 65.596 186.286 66.300 C 186.972 66.986,187.007 66.989,187.651 66.406 C 188.290 65.828,188.333 65.828,188.964 66.399 C 189.598 66.972,189.640 66.969,190.371 66.282 L 191.124 65.574 191.721 66.234 C 192.317 66.893,192.318 66.893,193.008 66.245 L 193.698 65.596 194.403 66.300 C 195.089 66.986,195.124 66.989,195.768 66.406 C 196.407 65.828,196.450 65.828,197.081 66.399 C 197.714 66.972,197.757 66.969,198.487 66.282 L 199.241 65.574 199.838 66.234 C 200.434 66.893,200.435 66.893,201.125 66.245 L 201.815 65.596 202.520 66.300 C 203.206 66.986,203.241 66.989,203.885 66.406 C 204.524 65.828,204.567 65.828,205.198 66.399 C 205.831 66.972,205.874 66.969,206.604 66.282 L 207.358 65.574 207.955 66.234 L 208.551 66.893 209.253 66.234 L 209.955 65.574 210.552 66.234 C 211.149 66.893,211.149 66.893,211.839 66.245 L 212.530 65.596 213.245 66.312 C 213.639 66.705,213.961 66.871,213.961 66.681 C 213.961 65.643,212.678 65.132,211.902 65.861 L 211.149 66.569 210.552 65.909 C 209.955 65.250,209.955 65.250,209.265 65.898 L 208.574 66.547 207.870 65.843 C 207.184 65.157,207.149 65.154,206.505 65.736 C 205.866 66.315,205.823 66.315,205.191 65.744 C 204.558 65.171,204.516 65.174,203.785 65.861 L 203.032 66.569 202.435 65.909 C 201.838 65.250,201.838 65.250,201.148 65.898 L 200.457 66.547 199.753 65.843 C 199.067 65.157,199.032 65.154,198.388 65.736 C 197.749 66.315,197.706 66.315,197.075 65.744 C 196.441 65.171,196.399 65.174,195.668 65.861 L 194.915 66.569 194.318 65.909 C 193.722 65.250,193.721 65.250,193.031 65.898 L 192.341 66.547 191.636 65.843 C 190.950 65.157,190.915 65.154,190.271 65.736 C 189.629 66.317,189.591 66.317,188.950 65.736 C 188.306 65.154,188.271 65.157,187.584 65.843 L 186.880 66.547 186.190 65.898 C 185.500 65.250,185.499 65.250,184.903 65.909 L 184.306 66.569 183.604 65.909 L 182.902 65.250 182.305 65.909 L 181.708 66.569 180.952 65.858 L 180.195 65.147 179.438 65.858 L 178.681 66.569 178.084 65.909 L 177.488 65.250 176.786 65.909 L 176.084 66.569 175.487 65.909 C 174.890 65.250,174.890 65.250,174.200 65.898 L 173.509 66.547 172.805 65.843 C 172.119 65.157,172.084 65.154,171.440 65.736 C 170.801 66.315,170.758 66.315,170.126 65.744 C 169.494 65.171,169.451 65.174,168.732 65.850 L 167.990 66.547 167.201 65.822 L 166.413 65.097 167.193 65.992 M47.729 181.658 L 48.493 182.471 49.192 181.815 L 49.890 181.159 50.487 181.818 L 51.084 182.478 51.849 181.759 L 52.613 181.041 53.321 181.748 L 54.029 182.456 54.719 181.807 C 55.410 181.159,55.410 181.159,56.006 181.818 L 56.603 182.478 57.305 181.818 L 58.007 181.159 58.604 181.818 L 59.201 182.478 59.957 181.767 L 60.714 181.056 61.471 181.767 L 62.228 182.478 62.825 181.818 L 63.421 181.159 64.123 181.818 L 64.825 182.478 65.422 181.818 C 66.019 181.159,66.019 181.159,66.709 181.807 L 67.400 182.456 68.104 181.752 C 68.790 181.066,68.825 181.063,69.469 181.645 C 70.108 182.224,70.151 182.224,70.783 181.653 C 71.416 181.080,71.458 181.083,72.189 181.770 L 72.942 182.478 73.539 181.818 C 74.136 181.159,74.136 181.159,74.826 181.807 L 75.517 182.456 76.221 181.752 C 76.907 181.066,76.942 181.063,77.586 181.645 C 78.225 182.224,78.268 182.224,78.900 181.653 C 79.533 181.080,79.575 181.083,80.306 181.770 L 81.059 182.478 81.656 181.818 L 82.253 181.159 82.951 181.815 L 83.650 182.471 84.438 181.579 C 85.146 180.779,85.152 180.750,84.497 181.303 C 83.815 181.877,83.726 181.883,83.172 181.381 C 82.846 181.086,82.456 180.844,82.305 180.844 C 82.155 180.844,81.764 181.086,81.438 181.381 C 80.884 181.882,80.800 181.879,80.195 181.331 C 79.568 180.764,79.523 180.764,78.896 181.331 C 78.269 181.898,78.224 181.898,77.597 181.331 C 76.971 180.764,76.925 180.764,76.299 181.331 C 75.693 181.879,75.609 181.882,75.056 181.381 C 74.729 181.086,74.339 180.844,74.188 180.844 C 74.038 180.844,73.648 181.086,73.321 181.381 C 72.768 181.882,72.683 181.879,72.078 181.331 C 71.451 180.764,71.406 180.764,70.779 181.331 C 70.153 181.898,70.107 181.898,69.481 181.331 C 68.854 180.764,68.808 180.764,68.182 181.331 C 67.577 181.879,67.492 181.882,66.939 181.381 C 66.612 181.086,66.222 180.844,66.071 180.844 C 65.921 180.844,65.531 181.086,65.204 181.381 C 64.651 181.882,64.566 181.879,63.961 181.331 C 63.334 180.764,63.289 180.764,62.662 181.331 C 62.036 181.898,61.990 181.898,61.364 181.331 C 60.737 180.764,60.692 180.764,60.065 181.331 C 59.460 181.879,59.375 181.882,58.822 181.381 C 58.495 181.086,58.105 180.844,57.955 180.844 C 57.804 180.844,57.414 181.086,57.087 181.381 C 56.534 181.882,56.449 181.879,55.844 181.331 C 55.218 180.764,55.172 180.764,54.545 181.331 C 53.919 181.898,53.873 181.898,53.247 181.331 C 52.620 180.764,52.575 180.764,51.948 181.331 C 51.343 181.879,51.258 181.882,50.705 181.381 C 49.967 180.714,49.547 180.703,49.019 181.339 C 48.651 181.783,48.551 181.783,48.061 181.339 C 47.164 180.528,46.903 180.778,47.729 181.658 M86.937 181.384 C 86.474 181.847,86.312 181.861,85.812 181.483 C 85.256 181.064,85.255 181.072,85.785 181.652 C 86.328 182.245,86.361 182.245,87.006 181.662 C 87.653 181.077,87.688 181.080,88.423 181.770 L 89.176 182.478 89.773 181.818 L 90.370 181.159 91.068 181.815 L 91.767 182.471 92.555 181.579 C 93.263 180.779,93.269 180.750,92.614 181.303 C 91.932 181.877,91.843 181.883,91.289 181.381 C 90.963 181.086,90.573 180.844,90.422 180.844 C 90.272 180.844,89.881 181.086,89.555 181.381 C 89.002 181.881,88.920 181.881,88.367 181.381 C 87.635 180.719,87.602 180.719,86.937 181.384 M257.143 233.659 C 257.143 234.684,258.431 235.188,259.202 234.464 L 259.955 233.756 260.552 234.416 C 261.149 235.075,261.149 235.075,261.839 234.426 L 262.530 233.778 263.234 234.482 C 263.920 235.168,263.955 235.171,264.599 234.588 C 265.238 234.010,265.281 234.010,265.912 234.581 C 266.545 235.154,266.588 235.151,267.307 234.475 L 268.049 233.778 268.704 234.433 L 269.359 235.088 269.962 234.422 L 270.564 233.756 271.318 234.464 C 272.048 235.150,272.091 235.154,272.724 234.581 C 273.355 234.010,273.398 234.010,274.029 234.581 C 274.662 235.154,274.705 235.150,275.436 234.464 L 276.189 233.756 276.786 234.416 C 277.382 235.075,277.383 235.075,278.073 234.426 L 278.763 233.778 279.468 234.482 C 280.154 235.168,280.189 235.171,280.833 234.588 C 281.472 234.010,281.515 234.010,282.146 234.581 C 282.779 235.154,282.822 235.150,283.552 234.464 L 284.306 233.756 284.903 234.416 C 285.499 235.075,285.500 235.075,286.190 234.426 L 286.880 233.778 287.584 234.482 C 288.271 235.168,288.306 235.171,288.950 234.588 C 289.589 234.010,289.632 234.010,290.263 234.581 C 290.896 235.154,290.938 235.151,291.658 234.475 L 292.400 233.778 293.055 234.433 L 293.710 235.088 294.328 234.346 C 294.936 233.615,294.936 233.612,294.323 234.168 C 293.730 234.705,293.666 234.698,292.958 234.033 C 292.237 233.356,292.195 233.353,291.562 233.925 C 290.931 234.497,290.888 234.497,290.256 233.925 C 289.623 233.353,289.581 233.356,288.850 234.043 L 288.097 234.750 287.500 234.091 L 286.903 233.431 286.201 234.091 L 285.499 234.750 284.903 234.091 C 284.306 233.432,284.306 233.432,283.615 234.080 L 282.925 234.729 282.217 234.021 L 281.510 233.313 280.756 234.021 L 280.003 234.729 279.348 234.074 L 278.693 233.419 278.090 234.084 L 277.488 234.750 276.786 234.091 L 276.084 233.431 275.487 234.091 L 274.890 234.750 274.137 234.043 C 273.406 233.356,273.364 233.353,272.731 233.925 C 272.100 234.497,272.056 234.497,271.425 233.925 C 270.792 233.353,270.750 233.356,270.019 234.043 L 269.266 234.750 268.669 234.091 C 268.072 233.432,268.072 233.432,267.382 234.080 L 266.691 234.729 265.987 234.024 C 265.301 233.338,265.266 233.336,264.622 233.918 C 263.983 234.497,263.940 234.497,263.308 233.925 C 262.675 233.353,262.633 233.356,261.914 234.032 L 261.172 234.729 260.517 234.074 L 259.862 233.419 259.259 234.084 L 258.656 234.750 257.900 234.039 C 257.483 233.648,257.143 233.477,257.143 233.659 M296.917 234.090 C 296.443 234.614,296.230 234.664,295.811 234.351 C 295.412 234.054,295.421 234.105,295.850 234.574 C 296.392 235.166,296.427 235.167,297.068 234.587 C 297.706 234.010,297.749 234.010,298.380 234.581 C 299.013 235.154,299.055 235.151,299.775 234.475 L 300.517 233.778 301.168 234.429 L 301.820 235.081 302.614 234.180 L 303.409 233.279 302.583 234.004 L 301.756 234.729 301.052 234.024 C 300.366 233.338,300.330 233.336,299.687 233.918 C 299.071 234.476,298.986 234.480,298.432 233.979 C 297.683 233.301,297.627 233.305,296.917 234.090 " stroke="none" fill="#e23333" fill-rule="evenodd"></path></g></svg> diff --git a/dom/docs/workersAndStorage/index.rst b/dom/docs/workersAndStorage/index.rst new file mode 100644 index 0000000000..8580f4b1ea --- /dev/null +++ b/dom/docs/workersAndStorage/index.rst @@ -0,0 +1,11 @@ +DOM Workers & Storage +===================== + +These linked pages contain design documents for the Workers & Storage implementations in Gecko. They live in-tree under the 'dom/docs/workerAndStorage' directory. + +.. toctree:: + :maxdepth: 1 + + CodeStyle + PerformanceTesting + WorkerLifeCycleAndWorkerRefs |