Node v15.1.0 (Current)
Michaël Zasso
Notable Changes
Diagnostics channel (experimental module)
diagnostics_channel
is a new experimental module that provides an API to create named channels to report arbitrary message data for diagnostics purposes.
With diagnostics_channel
, Node.js core and module authors can publish contextual data about what they are doing at a given time. This could be the hostname and query string of a mysql query, for example. Just create a named channel with dc.channel(name)
and call channel.publish(data)
to send the data to any listeners to that channel.
const dc = require('diagnostics_channel');
const channel = dc.channel('mysql.query');
MySQL.prototype.query = function query(queryString, values, callback) {
// Broadcast query information whenever a query is made
channel.publish({
query: queryString,
host: this.hostname,
});
this.doQuery(queryString, values, callback);
};
Channels are like one big global event emitter but are split into separate objects to ensure they get the best performance. If nothing is listening to the channel, the publishing overhead should be as close to zero as possible. Consuming channel data is as easy as using channel.subscribe(listener)
to run a function whenever a message is published to that channel.
const dc = require('diagnostics_channel');
const channel = dc.channel('mysql.query');
channel.subscribe(({ query, host }) => {
console.log(`mysql query to ${host}: ${query}`);
});
The data captured can be used to provide context for what an app is doing at a given time. This can be used for things like augmenting tracing data, tracking network and filesystem activity, logging queries, and many other things. It's also a very useful data source for diagnostics tools to provide a clearer picture of exactly what the application is doing at a given point in the data they are presenting.
Contributed by Stephen Belanger #34895.
'spawn'
event
New child process Instances of ChildProcess
now emit a new 'spawn'
event once the child process has spawned successfully.
If emitted, the 'spawn'
event comes before all other events and before any data is received via stdout
or stderr
.
The 'spawn'
event will fire regardless of whether an error occurs within the spawned process.
For example, if bash some-command
spawns successfully, the 'spawn'
event will fire, though bash
may fail to spawn some-command
.
This caveat also applies when using { shell: true }
.
Contributed by Matthew Francis Brunetti #35369.
Set the local address for DNS resolution
It is now possible to set the local IP address used by a Resolver
instance to send its requests.
This allows programs to specify outbound interfaces when used on multi-homed
systems.
The resolver will use the v4 local address when making requests to IPv4 DNS servers, and the v6 local address when making requests to IPv6 DNS servers.
const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setLocalAddress('10.1.2.3');
// Equivalent to: resolver.setLocalAddress('10.1.2.3', '::0');
Contributed by Josh Dague #34824.
Control V8 coverage at runtime
The v8
module includes two new methods to control the V8 coverage started by the NODE_V8_COVERAGE
environment variable.
With v8.takeCoverage()
, it is possible to write a coverage report to disk on demand. This can be done multiple times during the lifetime of the process, and the execution counter will be reset on each call.
When the process is about to exit, one last coverage will still be written to disk, unless v8.stopCoverage()
was invoked before.
The v8.stopCoverage()
method allows to stop the coverage collection, so that V8 can release the execution counters and optimize code.
Contributed by Joyee Cheung #33807.
Analyze Worker's event loop utilization
Worker
instances now have a performance
property, with a single eventLoopUtilization
method that can be used to gather information about the worker's event loop utilization between the 'online'
and 'exit'
events.
The method works the same way as perf_hooks
eventLoopUtilization()
.
Contributed by Trevor Norris #35664.
Take a V8 heap snapshot just before running out of memory (experimental)
With the new --heapsnapshot-near-heap-limit=max_count
experimental command line flag, it is now possible to automatically generate a heap snapshot when the V8 heap usage is approaching the heap limit. count
should be a non-negative integer (in which case Node.js will write no more than max_count
snapshots to disk).
When generating snapshots, garbage collection may be triggered and bring the heap usage down, therefore multiple snapshots may be written to disk before the Node.js instance finally runs out of memory. These heap snapshots can be compared to determine what objects are being allocated during the time consecutive snapshots are taken.
Generating V8 snapshots takes time and memory (both memory managed by the V8 heap and native memory outside the V8 heap). The bigger the heap is, the more resources it needs. Node.js will adjust the V8 heap to accommondate the additional V8 heap memory overhead, and try its best to avoid using up all the memory avialable to the process.
$ node --max-old-space-size=100 --heapsnapshot-near-heap-limit=3 index.js
Wrote snapshot to Heap.20200430.100036.49580.0.001.heapsnapshot
Wrote snapshot to Heap.20200430.100037.49580.0.002.heapsnapshot
Wrote snapshot to Heap.20200430.100038.49580.0.003.heapsnapshot
<--- Last few GCs --->
[49580:0x110000000] 4826 ms: Mark-sweep 130.6 (147.8) -> 130.5 (147.8) MB, 27.4 / 0.0 ms (average mu = 0.126, current mu = 0.034) allocation failure scavenge might not succeed
[49580:0x110000000] 4845 ms: Mark-sweep 130.6 (147.8) -> 130.6 (147.8) MB, 18.8 / 0.0 ms (average mu = 0.088, current mu = 0.031) allocation failure scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
....
Contributed by Joyee Cheung #33010.
Commits
Semver-minor commits
- [
8169902b40
] - (SEMVER-MINOR) child_process: add ChildProcess 'spawn' event (Matthew Francis Brunetti) #35369 - [
548f91af2c
] - (SEMVER-MINOR) dns: add setLocalAddress to Resolver (Josh Dague) #34824 - [
f861733bac
] - (SEMVER-MINOR) http: report request start and end with diagnostics_channel (Stephen Belanger) #34895 - [
883ed4b7f1
] - (SEMVER-MINOR) http2: add updateSettings to both http2 servers (Vincent Boivin) #35383 - [
b38a43d5d9
] - (SEMVER-MINOR) lib: create diagnostics_channel module (Stephen Belanger) #34895 - [
a7f37bc725
] - (SEMVER-MINOR) src: add --heapsnapshot-near-heap-limit option (Joyee Cheung) #33010 - [
7bfa872013
] - (SEMVER-MINOR) v8: implement v8.stopCoverage() (Joyee Cheung) #33807 - [
15ffed5319
] - (SEMVER-MINOR) v8: implement v8.takeCoverage() (Joyee Cheung) #33807 - [
221e28311f
] - (SEMVER-MINOR) worker: add eventLoopUtilization() (Trevor Norris) #35664
Semver-patch commits
- [
d95013f399
] - assert,repl: enable ecmaVersion 2021 in acorn parser (Michaël Zasso) #35827 - [
b11c7378e3
] - build: fix lint-js-fix target (Antoine du Hamel) #35927 - [
a5fa849631
] - build: add vcbuilt test-doc target (Antoine du Hamel) #35708 - [
34281cdaba
] - build: turn off Codecov comments (bcoe) #35800 - [
a9c09246bb
] - build: add license-builder GitHub Action (Tierney Cyren) #35712 - [
4447ff1162
] - build,tools: gitHub Actions: use Node.js Fermium (Antoine du Hamel) #35840 - [
273e147017
] - build,tools: add lint-js-doc target (Antoine du Hamel) #35708 - [
0ebf44b466
] - crypto: pass empty passphrases to OpenSSL properly (Tobias Nießen) #35914 - [
644c416389
] - crypto: rename check to createJob (Daniel Bevenius) #35858 - [
79a8fb62e6
] - crypto: fixup scrypt regressions (James M Snell) #35821 - [
abd7c9447c
] - crypto: fix webcrypto ECDH JWK import (Filip Skokan) #35855 - [
d3f1cde908
] - deps: upgrade npm to 7.0.8 (Myles Borins) #35953 - [
55adee0947
] - deps: upgrade npm to 7.0.7 (Luigi Pinca) #35908 - [
5cb77f2e79
] - deps: upgrade to cjs-module-lexer@1.0.0 (Guy Bedford) #35928 - [
1303a1fca8
] - deps: update to cjs-module-lexer@0.5.2 (Guy Bedford) #35901 - [
20accb08fa
] - deps: upgrade to cjs-module-lexer@0.5.0 (Guy Bedford) #35871 - [
52a77db759
] - deps: update acorn to v8.0.4 (Michaël Zasso) #35791 - [
e0a1541260
] - deps: update to cjs-module-lexer@0.4.3 (Guy Bedford) #35745 - [
894419c1f4
] - deps: V8: backport 4263f8a5e8e0 (Brian 'bdougie' Douglas) #35650 - [
564aadedac
] - doc,src,test: revise C++ code for linter update (Rich Trott) #35719 - [
7c8b5e5e0e
] - errors: do not call resolve on URLs with schemes (bcoe) #35903 - [
1cdfaa80f8
] - events: add a few tests (Benjamin Gruenbaum) #35806 - [
f08e2c0213
] - events: make abort_controller event trusted (Benjamin Gruenbaum) #35811 - [
438d9debfd
] - events: make eventTarget.removeAllListeners() return this (Luigi Pinca) #35805 - [
b6b7a3b86a
] - http: lazy create IncomingMessage.headers (Robert Nagy) #35281 - [
86ed87b6b7
] - http2: fix reinjection check (Momtchil Momtchev) #35678 - [
5833007eb0
] - http2: reinject data received before http2 is attached (Momtchil Momtchev) #35678 - [
cfe61b8714
] - http2: remove unsupported %.* specifier (Momtchil Momtchev) #35694 - [
d2f574b5be
] - lib: let abort_controller target be EventTarget (Daijiro Wachi) #35869 - [
b1e531a70b
] - lib: use primordials when calling methods of Error (Antoine du Hamel) #35837 - [
0f5a8c55c2
] - module: runtime deprecate subpath folder mappings (Guy Bedford) #35747 - [
d16e2fa69a
] - n-api: napi_make_callback emit async init with resource of async_context (legendecas) #32930 - [
0c17dbd201
] - n-api: revert change to finalization (Michael Dawson) #35777 - [
fb7196434e
] - src: remove redundant OpenSSLBuffer (James M Snell) #35663 - [
c9225789d3
] - src: remove ERR prefix in WebCryptoKeyExportStatus (Daniel Bevenius) #35639 - [
4128eefcb3
] - src: remove ignore GCC -Wcast-function-type for v8 (Daniel Bevenius) #35768 - [
4b8b5fee6a
] - src: use MaybeLocal.ToLocal instead of IsEmpty (Daniel Bevenius) #35716 - [
01d7c46776
] - Revert "src: ignore GCC -Wcast-function-type for v8.h" (Daniel Bevenius) #35758 - [
2868f52a5c
] - stream: fix regression on duplex end (Momtchil Momtchev) #35941 - [
70c41a830d
] - stream: remove redundant context from comments (Yash Ladha) #35728 - [
88eb6191e4
] - stream: fix duplicate logic in stream destroy (Yash Ladha) #35727 - [
a41e3ebc3a
] - timers: correct explanation in comment (Turner Jabbour) #35437 - [
ee15142fef
] - tls: allow reading data into a static buffer (Andrey Pechkurov) #35753 - [
102d7dfe02
] - zlib: test BrotliCompress throws invalid arg value (raisinten) #35830
Documentation commits
- [
7937fbe3bc
] - doc: update tables in README files for linting changes (Rich Trott) #35905 - [
c5b94220c5
] - doc: temporarily disable list-item-bullet-indent (Nick Schonning) #35647 - [
59b36af8d5
] - doc: disable no-undefined-references workarounds (Nick Schonning) #35647 - [
eb55462a75
] - doc: adjust table alignment for remark v13 (Nick Schonning) #35647 - [
0ac4a6ab16
] - doc: update crypto.createSecretKey history (Ben Turner) #35874 - [
4899998855
] - doc: move bnoordhuis to emeritus (Ben Noordhuis) #35865 - [
337bfcf614
] - doc: add on statement in the APIs docs (Pooja D.P) #35610 - [
9703219fdb
] - doc: fix a typo in CHANGELOG_V15 (Takuya Noguchi) #35804 - [
c14889bcc1
] - doc: move ronkorving to emeritus (Rich Trott) #35828 - [
8c2b17926c
] - doc: recommend test-doc instead of lint-md (Antoine du Hamel) #35708 - [
0580258449
] - doc: fix reference to googletest test fixture (Tobias Nießen) #35813 - [
d291e3abd9
] - doc: stabilize packages features (Myles Borins) #35742 - [
5e8d821b4c
] - doc: add conditional example for setBreakpoint() (Chris Opperwall) #35823 - [
8074f69f82
] - doc: make small improvements to REPL doc (Rich Trott) #35808 - [
4e76a3c106
] - doc: update MessagePort documentation for EventTarget inheritance (Anna Henningsen) #35839 - [
3db4354cc8
] - doc: use case-sensitive in the example (Pooja D.P) #35624 - [
b07f4a3f7a
] - doc: consolidate and clarify breakOnSigInt text (Rich Trott) #35787 - [
c2e6a4b081
] - doc: fix _construct example params order (Alejandro Oviedo) #35790 - [
6513a589fe
] - doc: add a subsystems header in pull-requests.md (Pooja D.P) #35718 - [
c365867c60
] - doc: fix typo in BUILDING.md (raisinten) #35807 - [
6211ffd2f7
] - doc: add require statement in the example (Pooja D.P) #35554 - [
7b3743d8dd
] - doc: modified memory set statement set size (Pooja D.P) #35517 - [
afbe23d800
] - doc: use kbd element in readline doc prose (Rich Trott) #35737 - [
c0a4fac040
] - doc: fix a typo in CHANGELOG_V12 (Shubham Parihar) #35786 - [
0e9acf83f7
] - doc: fix header level in fs.md (ax1) #35771 - [
f49afb5e10
] - doc: remove stability warning in v8 module doc (Rich Trott) #35774 - [
368ae952b2
] - doc: mark optional parameters in timers.md (Vse Mozhe Buty) #35764 - [
f6aa7c82c5
] - doc: add a example code to API doc property (Pooja D.P) #35738 - [
55b7a6cea3
] - doc: document changes for\*/promises
alias modules (ExE Boss) #34002 - [
4b7708a316
] - doc: update console.error example (Lee, Bonggi) #34964 - [
292b529dfa
] - doc: add missing link in Node.js 14 Changelog (Antoine du Hamel) #35782 - [
890b03ecd6
] - doc: improve text for breakOnSigint (Rich Trott) #35692 - [
1892532ee8
] - doc: this prints replaced with this is printed (Pooja D.P) #35515 - [
6590f8cb4a
] - doc: update package.json field definitions (Myles Borins) #35741 - [
f269c6cbe2
] - doc: add Installing Node.js header in BUILDING.md (Pooja D.P) #35710 - [
05a888a8c3
] - doc,esm: document experimental warning removal (Antoine du Hamel) #35750 - [
092c6c4f8f
] - doc,test: update v8 method doc and comment (Rich Trott) #35795
Other commits
- [
76ebae4c05
] - benchmark: make the benchmark tool work with Node 10 (Joyee Cheung) #35817 - [
9b549c1691
] - benchmark: add startup benchmark for loading public modules (Joyee Cheung) #35816 - [
5d61e3db4b
] - test: add missing ref comments to parallel.status (Rich Trott) #35896 - [
231af88001
] - test: correct test-worker-eventlooputil (Gerhard Stoebich) #35891 - [
da612dfc20
] - test: integrate abort_controller tests from wpt (Daijiro Wachi) #35869 - [
66ad4be2c1
] - test: add test to fs/promises setImmediate (tyankatsu) #35852 - [
830b789299
] - test: mark test-worker-eventlooputil flaky (Myles Borins) #35886 - [
7691b673dc
] - test: mark test-http2-respond-file-error-pipe-offset flaky (Myles Borins) #35883 - [
de3dcd7356
] - test: fix reference to WPT testharness.js (Tobias Nießen) #35814 - [
8958af4aa0
] - test: add onerror test cases to policy (Daijiro Wachi) #35797 - [
dd3cbb455a
] - test: add upstream test cases to encoding (Daijiro Wachi) #35794 - [
76991c039f
] - test: add upstream test cases to urlsearchparam (Daijiro Wachi) #35792 - [
110ef8aa50
] - test: refactor coverage logic (bcoe) #35767 - [
0c5e8ed651
] - test: add additional deprecation warning tests for rmdir recursive (Ian Sutherland) #35683 - [
11eca36e83
] - test: add windows and C++ coverage (Benjamin Coe) #35670 - [
fd027cd61a
] - tools: bump remark-lint-preset-node to 2.0.0 (Rich Trott) #35905 - [
c09fdba786
] - tools: refloat 7 Node.js patches to cpplint.py (Rich Trott) #35866 - [
3955ccd305
] - tools: bump cpplint to 1.5.1 (Rich Trott) #35866 - [
a07d1af4ea
] - tools: update ESLint to 7.12.1 (cjihrig) #35799 - [
d20b318c58
] - tools: update ESLint to 7.12.0 (cjihrig) #35799 - [
31753ec8aa
] - tools: add msvc /P output to .gitignore (Jiawen Geng) #35735 - [
afb3e24cb0
] - tools: add update-npm script (Myles Borins) #35822 - [
66da122d46
] - tools: refloat 7 Node.js patches to cpplint.py (Rich Trott) #35719 - [
042d4dd71c
] - tools: bump cpplint to 1.5.0 (Rich Trott) #35719
Windows 32-bit Installer: https://nodejs.org/dist/v15.1.0/node-v15.1.0-x86.msi
Windows 64-bit Installer: https://nodejs.org/dist/v15.1.0/node-v15.1.0-x64.msi
Windows 32-bit Binary: https://nodejs.org/dist/v15.1.0/win-x86/node.exe
Windows 64-bit Binary: https://nodejs.org/dist/v15.1.0/win-x64/node.exe
macOS 64-bit Installer: https://nodejs.org/dist/v15.1.0/node-v15.1.0.pkg
macOS 64-bit Binary: https://nodejs.org/dist/v15.1.0/node-v15.1.0-darwin-x64.tar.gz
Linux 64-bit Binary: https://nodejs.org/dist/v15.1.0/node-v15.1.0-linux-x64.tar.xz
Linux PPC LE 64-bit Binary: https://nodejs.org/dist/v15.1.0/node-v15.1.0-linux-ppc64le.tar.xz
Linux s390x 64-bit Binary: https://nodejs.org/dist/v15.1.0/node-v15.1.0-linux-s390x.tar.xz
AIX 64-bit Binary: https://nodejs.org/dist/v15.1.0/node-v15.1.0-aix-ppc64.tar.gz
ARMv7 32-bit Binary: https://nodejs.org/dist/v15.1.0/node-v15.1.0-linux-armv7l.tar.xz
ARMv8 64-bit Binary: https://nodejs.org/dist/v15.1.0/node-v15.1.0-linux-arm64.tar.xz
Source Code: https://nodejs.org/dist/v15.1.0/node-v15.1.0.tar.gz
Other release files: https://nodejs.org/dist/v15.1.0/
Documentation: https://nodejs.org/docs/v15.1.0/api/
SHASUMS
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
39b7152a34b5d391355c86b4081639b09795853e3fb1b91b3e86ec3eb78a8d07 node-v15.1.0-aix-ppc64.tar.gz
af4d2208a577501464cf39bff4de4d756b2e15b62ba83ab424ac0b5aa3e45c24 node-v15.1.0-darwin-x64.tar.gz
0e4d8469e92d5257c71aa07a5b108c97c7812df8f1afad06e75ac469dc1fc003 node-v15.1.0-darwin-x64.tar.xz
163bc179c76ff60468a137966859446748273db7853c3e11551023c7e425505a node-v15.1.0-headers.tar.gz
ac86696dd9fe6481f9d9e524bade9055637e684f943402474cbe4db450e4a021 node-v15.1.0-headers.tar.xz
292a5ed3db3ae2acc7cc88bf965c8fca3c39068e867f473f1e2c355549d653b3 node-v15.1.0-linux-arm64.tar.gz
992f640323ba10bfb9c43a464f2be9047568883e127761244a97d0f9a00260dc node-v15.1.0-linux-arm64.tar.xz
268495b91a6fdc86681f8b890c51c4a6606e5de028c179582c655317707ffbaa node-v15.1.0-linux-armv7l.tar.gz
6b21bd317158ff790d7a7d035315a48bcffcf7d1ec2cce029ffd3d4ebd58ce1b node-v15.1.0-linux-armv7l.tar.xz
56a8ccf54cf60208b3b9c082a8589ff5f023c2995243b60b9fb46e6ed87352a0 node-v15.1.0-linux-ppc64le.tar.gz
f0aa31faf68ab3b6dc255aef271e207dcba01b7d35d73ea42897d0c7b223246f node-v15.1.0-linux-ppc64le.tar.xz
03afd980583cd00b32168585a792bb68b22898f3f1c846dd1eb3899af1727c81 node-v15.1.0-linux-s390x.tar.gz
89f34b9f7a42e6d21919e3a7fe5e6dbe9891a2bc1a86f62b1b967a05bf45b51d node-v15.1.0-linux-s390x.tar.xz
f7f5d9d313462771095fe121c0dbb95b229a6a8119cb75cace433df748438f20 node-v15.1.0-linux-x64.tar.gz
d049437db2e7b90c3d5afb53fc8dc33dc6069fb43aa05e59c985867fc3813ba6 node-v15.1.0-linux-x64.tar.xz
d3096be91b5268e1ff746e61ea287ec4ee15242a12fae6b73a79948864a26445 node-v15.1.0.pkg
b44e4ac58b0660909e41390c3380a14669480c3f947d078d78d356ce3d1ba4bc node-v15.1.0.tar.gz
7353d73f06f263b2c90f77a0a189e3ffeb9ea6c0277800e419e9566acd64a0b9 node-v15.1.0.tar.xz
2c179da92d9d03cbe4fac46596abca46d9bd73f66ca577ffaa85794669023142 node-v15.1.0-win-x64.7z
51f172afa35e6bff7096062819e5600672536f26f490f97ee782b30b3cf9c9ba node-v15.1.0-win-x64.zip
72b4e7be280e92678f8e6d90d7db55d085b5b0e00a8b6e115eb47ddd5c395c82 node-v15.1.0-win-x86.7z
c8dbb260c45b003f43cd838d3a53838f0b7f2e6016ce2aed00e800a58b904200 node-v15.1.0-win-x86.zip
5f98b3247de94a5104da88295152b3a9fe9ea22410d1c2d10ac123fe58bb8050 node-v15.1.0-x64.msi
70302f55f1e9c2ab24e01dd8ef1739f4b760582ad65c2e6f15fc7b14f43c19e2 node-v15.1.0-x86.msi
b3169ae0bf61e3c3276ba4b909b5f8924dec176e86e12c61681638dd17a1015b win-x64/node.exe
0668ebb22765d3e797c4401f36587f5cc4ada69611e2793cb79209625aca0931 win-x64/node.lib
05275d94016b6dfc12e26ffe94ff05fe3f24fce7d6641842f738a388baa98d12 win-x64/node_pdb.7z
898fd2d6305edb0b45a163bd065ecd92602c2cab1a1afe5128234275b2b446ed win-x64/node_pdb.zip
09014714b7d1a60a9cd84b782ab41b2f0b3a51a75d8bbe854a7f632fdfcffb85 win-x86/node.exe
3cbb6fca39edc95246ed5169ac8fb1c7e575e45be873dbae255577f66f4d2b2b win-x86/node.lib
ed3a33829caeb80d9bbd95c6c150f028b292a3c66222db8520ee389033fc9eb2 win-x86/node_pdb.7z
9011efc48fb164347a5514b5c957aa8fdfaeafed38f38f8208f2d30acc2b53ec win-x86/node_pdb.zip
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEj8yhP+8dDC6RAI4Jdw96mlrhVgAFAl+jFEYACgkQdw96mlrh
VgDTmxAAinKXK6o1QeSIwHB4SRZ6WW3crwcfdVn8BQcGP/X6HdS/wUzAAR/fXTXh
X/eKqMO2tNo54l/s65//NifBLJBWK0C8qZpHl+sFT5TlAk+szVHKFHXP8VFdpspm
2aZC4k3f16tg7RmbvlSXGFvIY/mbHlDTvrYrbqiVYGjlOJVIQL8ciXsRLBwaUtrx
m5fMhMh06jE1zwpuc5NFdsnJd7JoqhTrDq9QFPct9SS9GyEpLRB84QBiXnjoI0ho
s3OBsNZFQ+0KLEWF9yxQgYn8kFOSqhYXLioMMQMADb4aKkUYK0YLtYkmNRYGMv9c
GNM9AStUYFe9qhTZuaH6qbiSKQ6luWgvnH7vX0b/ayl7ej9XOCr/RdhqZ0ijoI0g
0zbC0TRDaWIMDiRMrpu5yHe4aPobS8BZwSf8f3SAlcc+BFsD4qGiKlytdpgXSKao
O7PZvcFHhX5ICRjCZzEKUzr2dDS2VNZv6g4R1yI0vNpXK69voSubnTP/Duh5gYyV
xLdIsWQ8t8VX4Ff14Z0RLq5TXgiuTXvYkYiTTaOIuSxko+ogWtG56UqCaRnKpWkw
32lRLZS4gqlDKbQxljcIsGofcb0nfHF2D9QdT5eXWH8iS+o7lUcsAk9eJZsSDa0W
7h+POihA7uLxnQ7L/Il7BgzY0oyVBXS5YP/65yUXPqo3skyNXps=
=fXhD
-----END PGP SIGNATURE-----