This page lists the stable releases of Gannet since v3.1.3. All
releases can be found on GitHub
here
and
here.
The development version of Gannet can be found
here.
For a more comprehensive list of changes to the current main version,
see the commits logged on GitHub
here.
3.5.3
2026-02-06
What’s changed
- Enhanced montage labeling in
GannetQuantify.m
- Updated MRIQC metrics to use median absolute deviation (MAD) and
improve robustness
Full changelog:
v3.5.2...v3.5.3
3.5.2
2026-01-30
What’s changed
- Added dynamic font size adjustment for R2025a+
- Refactored segmentation and QA metrics in
Seg.m
- Consolidated dependency update workflows
- Fixed spacing in MRIQC metrics comment
- Added linewidth parameter to
PaperPlot.m
- Removed blank issue template
- Added more labels to the image montage in GannetQuantify output
figure
- Updated
README.md: logo path, compatibility, and
contributors
- Updated
CoRegStandAlone.m settings and added
normalization to MNI space
- Added workflow to automerge Dependabot PRs
- Updated dependencies - bids-matlab, dic2nii, etc.
- Bumped actions/checkout from 5 to 6
- Bumped peter-evans/create-pull-request from 7 to 8
Full changelog:
v3.5.1...v3.5.2
3.5.1
2025-09-13
What’s changed
- Set figure theme to light for MATLAB R2025a and newer
- Minor bug fixes for MATLAB R2025a
Full changelog:
v3.5.0...v3.5.1
3.5.0
2025-09-11
New features
- Gannet is now compatible with
BIDS
bids-matlab,
a MATLAB toolkit for interfacing with BIDS datasets, is embedded in
Gannet, and users can now input BIDS datasets directly into
GannetLoad.m (see documentation
for usage instructions)
- Added image QA metrics based on
MRIQC
GannetSegment.m now calculates and saves the following
QA metrics for each anatomical image:
- Signal-to-noise ratio (SNR) of GM, WM, CSF, and the whole brain (two
variants: one using the median absolute deviation of the air background
based on
Dietrich et
al. (2007), and one using the standard deviation of the noise within
the tissue class)
- Contrast-to-noise ratio (CNR) between GM and WM
- Coefficient of variation (CV) of GM and WM
- Coefficient of joint variation (CJV) between GM and WM
- Entropy-focus criterion (EFC)
- Foreground-background energy ratio (FBER)
- WM to maximum intensity ratio (WM2MAX): the median intensity within
WM over the 95% percentile of the full intensity distribution, that
captures the existence of long tails due to hyper-intensity of the
carotid vessels and fat
- These metrics are saved in
MRS_struct.out.QA
- Added GitHub Actions for continuous integration with
bids-matlab, dicm2nii, and
export_fig to ensure compatibility with the latest versions
of these dependencies
- Added
dependabot.yml to automatically check for updates
to GitHub Actions
- Water-unfiltered (but aligned) spectra are now saved in
MRS_struct
- All version strings (e.g.,
MRS_struct.version.*) are
now stored under MRS_struct.info.version.*, and datetime
stamps for processing steps are added as
MRS_struct.info.datetime.*
Major changes
- When calculating GM, WM, and CSF fractions in
GannetSegment.m, the probabilistic tissue maps are now
thresholded at 0.9 before calculating the fractions. This should improve
the accuracy of tissue fraction estimates
Minor changes
- Modified
SiemensTWIXRead.m to use iceParam for
pointsBeforeEcho in MEGA-sLASER, aligning with MEGA-PRESS
handling for consistency
- Changed the naming convention for water residual fit results from
ResidWater to resid_water in
GannetFit.m for consistency
- Improved input argument validation and error messages, including
checks for cell array inputs and file existence, with clearer error
output for missing files
- Updated
export_fig to v3.52
- Updated
dicm2nii to v2025.08.21
- MANY COSMETIC CHANGES to improve code readability and
maintainability
Full changelog:
v3.4.0...v3.5.0
3.4.0
2025-03-30
New features
- Added support for fitting the 2.34 ppm Glu peak in the SUM
spectrum
- Added
DeIdentifyDisclaimer.m, which prints a disclaimer
that the developers provide no guarantee that the de-identification
functions will remove all human participants’ identifying information in
the data header of files
- The RF coil combination used is now stored in
MRS_struct.p.RFCoilCombination (note: this only applies to
raw data files that are not coil-combined during export from the
scanner)
- Data load time (
MRS_struct.loadtime) is now stored when
GannetLoad.m is run
- Re-added the option to choose the editing pulse order in
GannetPreInitialise.m:
MRS_struct.p.ON_OFF_order
- MRS voxel masks can now be normalized to MNI152 space; a flag in
GannetPreInitiliase.m has been added to do so (note that
this is only performed if GannetSegment has been run as the forward
deformation map needed for MNI normalization is created during SPM12’s
segmentation routine)
- Added
VoxelMaskOverlap.m, a function that will create a
voxel mask that indicates the degree of overlap of all datasets run in a
batch
- Added
ThreeLorentzModel.m
- Added
VoigtModel.m
Minor changes
- An “intro” message is printed whenever
GannetLoad.m is
run: the version number and a link to the software documentation website
is displayed
- Co-registration figure outputs now show the anatomical directions of
the displayed MR image (i.e., anterior/posterior [A/P], left/right
[L/R], and superior/inferior [S/I])
- Replaced file separators with
filesep so that they are
specific to users’ operating system
voxoff is now parsed in GERead.m instead
of in GannetMask_GE.m and
GannetMask_GE_nii.m
- Minor changes to rounding in
ExportToCSV.m
- Renamed
FitPeaksByFrames2.m to
FitPeaksByFrames.m
- Updated
export_fig to v3.48
- Updated
dicm2nii to v2024.08.21
- MANY COSMETIC CHANGES AND CLEANUP OF OLD UNUSED CODE
Bug fixes
- Updated
AlignSubSpectra.m to include Lac and GSH
editing
- Updated
AlignUsingPeak.m to fit the indexing approach
of Gannet 3
- Fixed issue with Siemens .RDA files in
CoRegStandAlone.m
- Added
MRS_struct.p.seqorig to
CoRegStandAlone.m
- Minor fix in
GannetMask_NIfTI.m for how voxel offset is
parsed from the NIfTI file
- Fixed an issue with
GannetFit.m when users choose to
fit a specific metabolite
- Corrected a bug in
PaperPlot.m for plotting model fits
for GABA+Glx
- Fixed an issue in
AlignUsingPeak.m when running more
than one file in a batch
3.3.2
2023-08-02
Major changes
- Rewrote
SiemensRead.m to reduce code length
Minor changes
- Updated
DICOMRead.m, including to support Siemens XA30
data
- Updated
SpectralRegistrationHERMES.m
- SNR limit is now estimated as in
RobustSpectralRegistration.m
- Bug fix for indexing for output saved from maximum likelihood
estimation
- Updated
dicm2nii to version 2023.03.16
- Updated
export_fig to v3.40
- Added Gannet documentation website URL to error dialog box
- Changed the way path names are printed in error dialog box
- Turned off iteration limit warning in
FitChoCr.m
- Updated
UpdateGannet.m to ensure all sub-directories
are added to the search path after updating
- Added issue templates (in
.github/ISSUE_TEMPLATE) for
blank issues, bug reports, and feature requests
- Refined alignment of text/logos in output figures
- The units used for displaying textual results are now normalized to
fit to any subplot dimension
- The textual results in the
GannetCoRegister,
GannetSegment, CoReg, and Seg
output figures are now correctly centered
- The weighted signal averaging method used is now saved in the
structure output
- The weighting factors calculated when applying weighted signal
averaging are also now saved in the output
- Updated
SavePDF.m such that when appending PDFs using
export_fig, the figure size will now be equivalent in
pixels on Windows and Mac systems
- Updated
NIfTIMRSRead.m
- Updated
README.md
- Updated
GannetFitPhantom.m
- Removed redundant global frequency shift in
RobustSpectralRegistration.m
- The z-standardized MSEs calculated in the spectral registration
subroutines are now saved in the structure output
- Updated
GannetVersion.m to also output version numbers
of Gannet modules
- A warning is now printed when users process Siemens .rda data
encouraging them to instead use TWIX (.dat) data
- Added support for GE P-file header revision 30
(#28)
- MANY COSMETIC CHANGES
Bug fixes
- Bug fix for special character
\ in Windows file path
names printed in the error dialog box
- Fixed bug in
GannetMask_NIfTI.m where the co-registered
MRS voxel was incorrectly flipped in the GannetCoRegister
output figure
- Fixed bug in
GannetQuantify.m where the alpha value was
incorrectly being printed multiple times when multiple were run in
batch
- Added fix in
VersionCheck.m so that when users have
limited or restricted internet access, an error is avoided
(#27)
- thanks @alexcraven!
3.3.1
2023-03-14
New features
- Compressed NIfTI files (*.nii.gz) are now fully supported
- Gannet now fully quantifies metabolite levels for Cr, Cho, and NAA
(estimated from the OFF spectrum)
Major changes
- Moved local signal model functions out of
GannetFit.m
and into their own files:
BaselineModel.m
CalcIU.m
DoubleGaussModel.m
EtOHModel.m
GABAGlxModel.m
GaussModel.m
LorentzGaussModel.m
LorentzGaussModelP.m
- Added
GetFullPath.m; Gannet now will find the full path
of input files by default
- Renamed some of the data-loading functions
Minor changes
- Added a check in
GannetQuantify.m for datasets without
water references; GannetQuantify.m will not run if no water
references are present
- Added a check in
GannetCoRegister.m to ensure all
structural image files can be found
- Updated
export_fig to v3.33
- Updated
dicm2nii to version 2023.03.08
- Updated
LICENSE and README.md
- Updated
ExportToCSV.m
- Updated
CoRegStandAlone functions
- Replaced use of
1i with complex()
- Removed unused variable
T1max
- Removed unnecessary
ones() parameter in
LorentzModel.m and TwoLorentzModel.m
- Philips *.spar file extension is no longer saved in the output
structure
- Removed calculation of
df in GannetLoad.m;
added dt in its place
- Exported CSV files will no longer be overwritten if a CSV file of
the same name already exists in the output directory; instead, a new
file is created and appended with an integer
- Added new output structure attribute
nrows_water
- Reordered structure subfields for metabolites in
GannetFit.m and ExportToCSV.m
- Shifted Gannet logo and version number in PDF outputs slightly to
the right
- Alpha values are now included in exported CSV files
- Replaced the Gannet logo with a PNG version
- MANY COSMETIC CHANGES
Bug fixes
- Added a check for letter case of *.dcm and *.ima files in
DICOMRead.m and SiemensDICOMRead.m
(dir() is case-sensitive in Linux)
- Added a fix to avoid an error where MATLAB tried to close figures
following an unrelated internal error, but no figures were created
- Fixed a bug in
NIfTIMRSRead.m that led to an error if
the Manufacturer field is not found in the data file
header
- If
export_fig.m cannot be found on the search path and
append has been flagged in
GannetPreInitialise.m, it is made clear to the user that
PDFs will be saved separately
- Fixed bugs in
AlignUsingH2O.m
- Fixed a bug in
SiemensDICOMRead.m where an error
occurred if centerFreq is not found in the data file
header
3.3.0
2022-10-22
New features
- Added functionality to read NIfTI-MRS files
(Clarke
et al., MRM, 2022) (
NIfTIMRSRead.m); includes
additional new function GannetMask_NIfTI.m for voxel
co-registration
- Added support for Utah Siemens MEGA-PRESS sequence (DICOM
files)
- Added support for CMRR PRESS data (DICOM files)
- Added support for Siemens XA30 sequence as provided by JHU
- Changed
README to README.md, which now
includes badges
Major changes
- Coil combination of GE, NIfTI-MRS, and Siemens TWIX files is now
performed using generalized least squares
(An
et al., JMRI, 2013); this approach has been shown to result in
optimal SNR and reduce spectral artifacts
- The Gannet logo has been reverted to the original image of a
gannet
Minor changes
- Added functionality for GE data in
AlignSubSpectra_PreAlignRef.m
- An error is presented if not enough inputs are given for any of the
Gannet modules
- CoRegStandAlone outputs can be hidden if
MRS_struct.p.hide is set to 1 in
CoRegStandAlone.m (default is 0)
- If the user has no internet connection,
VersionCheck.m
and UpdateGannet.m will not run
- Updated dicm2nii to latest version (version 2022.09.15)
- Updated mapVBVD functions to latest version
(https://github.com/pehses/mapVBVD)
- Turned off warnings of iteration limits in
SpectralRegistrationHERMES.m and
GannetFit.m
- Many cosmetic changes in the code
Bug fixes
- Fixed bug in error reporting in
GannetFit.m
- CoRegStandAlone routines now parse version numbers from the main
modules properly
- Variable
filesExist in GannetSegment.m may
not populate; it is now pre-initialized as a precaution
- Bug fix in
GannetMask_SiemensRDA.m
- Bug fixes for reading DICOM files
3.2.1
2022-06-07
Minor changes
PhaseCorrection.m now deals better with spectra that
have a non-zero baseline
- SPM12 now outputs forward deformation field (needed for normalizing
voxel masks to MNI space)
- Updated
export_fig to v3.27
CoRegStandAlone.m now exports a CSV file
- Various cosmetic changes
Bug fixes
- Fixed sub-spectra alignment for GE HERCULES data
- Fixed bug in
CoRegStandAlone.m
- Fixed bug in
read_dcm_header.m (thanks to Meredith
Reid)
3.2.0
2021-07-30
New features
- Added
GannetVersion.m, VersionCheck.m, and
UpdateGannet.m; these new functions let users know the
version of Gannet they have, if a newer release of Gannet is available,
and will allow them to automatically update if wanted
- Added
ToolboxCheck.m to check for missing MATLAB
toolboxes needed to run Gannet
- Error dialog boxes are displayed at the end of the analysis pipeline
if an error occurred (during a batch analysis, Gannet will skip to the
next dataset and continue running)
- Users can now choose to use weighted (the default) or conventional
signal averaging in
GannetPreInitialise.m (outlier scans
are removed when using conventional averaging, as before)
- Added a new (optional) method for robust, weighted signal averaging:
weighted averaging by criterion function minimization (WACFM) using the
generalized Cauchy distribution as the cost function; see
doi:10.1016/j.bbe.2015.06.002
for more details; additionally, instead of weighting difference pairs,
the subspectra of each editing subexperiment are weighted to generate
weighted subspectra, which are then subtracted; see
SignalAveraging.m
- Yair Altman’s
export_fig
toolbox is included as an optional toolbox that, if added to
MATLAB’s search path, Gannet will use to append all output PDFs from
each module into a single PDF (a flag must be set in
GannetPreInitialise.m to do this); this is very useful for
easy QA of lots of data; note that
Ghostscript
needs to be installed for the appending of PDFs to work (NB: macOS users
should use this
version or
use
Homebrew
to install Ghostscript)
- Implemented use of hyperlinks in info and error messages printed in
the command window so that users can: (1) directly run a certain
function (such as
UpdateGannet.m when
VersionCheck.m informs the user a new release is
available); (2) go straight to the line of code where an encountered
error can be fixed (such as errors in
GannetPreInitialise.m); or (3) go to a website by clicking
on the printed URL (such as to download SPM12); the relevant code has
been borrowed from export_fig
- Added an option in
GannetPreInitialise.m that allows
users, when using robust spectral registration, to use the averaged
pre-aligned subspectra as references for aligning the averaged
post-aligned subspectra (this may be helpful when robust spectral
registration makes the alignment of already good-quality pre-aligned
spectra worse)
PaperPlot.m now allows users to plot an exemplary voxel
mask co-registered to the respective structural image
- Added
GannetMask_GE_nii.m; GE users can now use NIfTI
images instead of DICOMs to co-register their MRS voxels to structural
images
- Added the ability to trim datasets
- Extended the ability to concatenate files, including over multiple
subjects
- Added a flag in
GannetPreInitialise.m
(MRS_struct.p.hide) to prevent output figures from
displaying (useful when processing a large batch of files)
Major changes
- The outdated manual PDF has been removed; up-to-date software
documentation will now be found online: https://markmikkelsen.github.io/Gannet-docs/index.html
- Gannet is now licensed under the BSD 3-Clause License
- Alpha tissue correction is now performed on a by-metabolite basis
rather than fixing the intrinsic WM:GM concentration to 1:2 (alpha) for
all metabolites (assuming for now the ratio is 1:2 for GABA and Glx and
1:1 for GSH, EtOH and Lac); the alpha that is assumed is displayed in
the GannetQuantify output figure
- Removed
MRS_struct.p.ON_OFF_order from
GannetPreInitialise.m; the order of editing pulses is now
determined automatically; the relevant code has been borrowed from
Osprey (this has only been tested to a limited extent so may require
further tweaking)
- The exception to this change is phantom data, where users will still
need to specify the order of editing pulses
Minor changes
- Datasets with differing number of averages can now be
batch-processed together
- Turned off the progress bar displayed when loading Siemens TWIX data
to reduce loading time
- Renamed some files for the sake of clarity and style; removed
obsolete
GannetMask.m
- Signal averaging and subtraction are now done in the new function
SignalAveraging.m
- Various improvements to
RobustSpectralRegistration.m
(formerly Robust_Spectral_Registration.m) for better
handling of data acquired using very strong water suppression
- The assumed concentration of pure water in
GannetFit.m
and GannetFitPhantom.m (PureWaterConc) has been changed
from 55 to 55.51 mol/kg; this puts it in line with the same constant
used in GannetQuantify.m
- Added edits from Ralph Noeske (GE Berlin) to
GERead.m
for better handling of data when nechoes == 1; also changed the scaling
factor if nechoes > 1 (hopefully this makes water-referenced
measurements consistent across all data encoding flavors)
- In
GERead.m and PhilipsRead_data.m,
instead of using the first point in the FID for signal weighting, the
most common point that is the max in the magnitude signal across all
FIDs is now used
- Some changes to
SiemensDICOMRead.m and
DICOMRead.m for smarter handling of data files: for each
dataset, metabolite and water data files should be stored in separate
folders
- Improved
ExportToCSV.m; a single .csv file is now
exported for HERMES datasets; useful variables such as signal areas and
Cr fit quality metrics are now also exported
- Rewrote
DiscernDataType.m (formerly
GannetDiscernDatatype.m)
- Minor changes and improvements to
PaperPlot.m
- Minor changes to
CoRegStandAlone.m functions
- Minor changes to
SignalFilter.m
- Simplified
EddyCurrentCorrection.m (formerly
phase_correction_fids.m)
- Set up SPM12 for batch tissue segmentation only when tissue
segmentation has not already been run and do it only once in a
batch
- AllFramesFT (for the last loaded dataset) is now also saved in
MRS_struct.spec
- When saving the
MRS_struct structure, the .mat file is
now saved using version 7.3 (for the rare case when the structure is
>= 2 GB on 64-bit computers)
- Removed
MRS_struct.p.sdat from
GannetPreInitialise.m and the corresponding code from
GannetLoad.m (this feature was never really used by users
afaik)
- Improved global zero-order phasing in
SpectralRegistrationHERMES.m
- Many cosmetic/aesthetic changes
- The module output figures now show information useful for reporting
acquisition parameters and results (in line with the
MRSinMRS
checklist)
- Co-registered/segmented voxel masks displayed in GannetCoRegister,
GannetSegment, and GannetQuantify output figures are now shown in yellow
rather than grayscale
- Smarter stacking of HERMES difference spectra in
PlotPrePostAlign.m and PlotPrePostAlign2.m
(formerly GannetPlotPrePostAlign.m and
GannetPlotPrePostAlign2.m)
- The Gannet documentation website URL is printed at the bottom of
every output figure
- Removed irrelevant messages from being printed in the command window
during the analysis pipeline, replacing them with more useful
messages
- Minor rearranging of results text in GannetSegment and
GannetQuantify output figures
- Slight change to the y-axis labels of the Cr frequency spectrogram
in the GannetLoad output figure
- Better reordering of
MRS_struct.out subfields created
in GannetFit.m
Bug fixes
- Frequency and phase offset estimates are now tracked correctly and
saved when running any of the spectral registration-based alignment
methods
- Removed old debugging conditional statement in
TWIXDeIdentify.m
- Explicitly specify color of water frequency trace in GannetLoad
output figure as there appears to be a bug since MATLAB R2019b when
using hold to overlay plots
- Added EtOH signal parameters to
GannetQuantify.m
- In
SiemensTwixRead.m, if no water reference is
provided, use the most common point that is the max in the magnitude
signal across all FIDs instead of just using the first point
- Fixed an orientation problem in
GannetMask_GE.m
- Removed unnecessary complex conjugate transpose during FFT of water
data in
GannetLoad.m
- Turned off warnings about legacy number generator in
RobustSpectralRegistration.m (for when rng and randn are
run in SignalFilter.m) if they are already turned on
3.1.5
2020-03-02
New features
- Smarter checking of incorrect settings in
GannetPreInitialise.m by CheckTargets.m
- Major changes to
GannetFitPhantom.m to bring it more in
line with GannetFit.m
- Added support for CMRR MEGA-sLASER sequence in
SiemensTwixRead.m
- In
SubSpectralAlign.m, if very strong water suppression
was used, use Cho instead of residual water to align subspectra of
GABA-, Lac-, and EtOH-edited datasets
Minor changes
- Noise estimation in
CalcNoise.m,
Robust_Spectral_Registration.m, and
SignalFilter.m is now performed between 8 and 10 ppm to
account for datasets that have shorter spectral widths
- Cleaned up code in
GannetFit.m
- Quantification of Lac now explicitly defined as Lac+MM
- Improved functionality of
PaperPlot.m
- In
SiemensTwixRead.m, when a water reference is
present, coil sensitivity and phase is based on the point index that is
at the top of the echo, rather than simply fixing it to the first
point
Bug fixes
- Minor bug fixes in CoRegStandAlone functions
- Corrected use of random number generation in
SignalFilter.m when performing noise replacement to ensure
the same results are reproduced each time it is run on a dataset
3.1.4
2019-10-03
Bug fix
- Fixed error in the calculation of
AvgDeltaF0 for
MEGA-PRESS data
3.1.3
2019-08-06
New features
- Major improvements to
Robust_Spectral_Registration.m
- Wavelet toolbox no longer required
- Raw data is now phase-corrected prior to alignment
GannetLoad.m and GannetFit.m no longer
crash if an error occurs during a batch analysis
- An error report is printed after the final dataset is loaded/fitted
so users can check which datasets failed
- Added support for GE revision header 20.007
Minor change
Water_Positive flag in
GannetPreInitialise.m removed
LS0tCnRpdGxlOiAiUmVsZWFzZSBub3RlcyIKZGF0ZTogIkxhc3QgdXBkYXRlZDogYHIgZm9ybWF0KFN5cy50aW1lKCksICclQiAlZCwgJVknKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiBUUlVFCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBGQUxTRQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKYGBgCgpgYGB7ciwgY2hpbGQgPSBjKCJqcy9iYWNrLXRvLXRvcC5odG1sIiwgImpzL2NvcHktdG8tY2xpcGJvYXJkLmh0bWwiLCAianMvdG9jaWZ5LW9mZnNldC5odG1sIil9CmBgYAoKPGJyPgoKVGhpcyBwYWdlIGxpc3RzIHRoZSBzdGFibGUgcmVsZWFzZXMgb2YgR2FubmV0IHNpbmNlIHYzLjEuMy4gQWxsIHJlbGVhc2VzIGNhbiBiZSBmb3VuZCBvbiBHaXRIdWIgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL21hcmttaWtrZWxzZW4vR2FubmV0L3JlbGVhc2VzIiB0YXJnZXQ9Il9ibGFuayI+aGVyZTwvYT4gYW5kIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9yaWNoYXJkZWRkZW4vR2FubmV0My4xL3JlbGVhc2VzIiB0YXJnZXQ9Il9ibGFuayI+aGVyZTwvYT4uIFRoZSBkZXZlbG9wbWVudCB2ZXJzaW9uIG9mIEdhbm5ldCBjYW4gYmUgZm91bmQgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL21hcmttaWtrZWxzZW4vR2FubmV0L3RyZWUvZGV2IiB0YXJnZXQ9Il9ibGFuayI+aGVyZTwvYT4uIEZvciBhIG1vcmUgY29tcHJlaGVuc2l2ZSBsaXN0IG9mIGNoYW5nZXMgdG8gdGhlIGN1cnJlbnQgbWFpbiB2ZXJzaW9uLCBzZWUgdGhlIGNvbW1pdHMgbG9nZ2VkIG9uIEdpdEh1YiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbWFya21pa2tlbHNlbi9HYW5uZXQvY29tbWl0cy9tYWluIiB0YXJnZXQ9Il9ibGFuayI+aGVyZTwvYT4uCgojIyAzLjUuMwo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDI2LTAyLTA2PC9zcGFuPgoKIyMjIFdoYXQncyBjaGFuZ2VkCgoqIEVuaGFuY2VkIG1vbnRhZ2UgbGFiZWxpbmcgaW4gYEdhbm5ldFF1YW50aWZ5Lm1gCiogVXBkYXRlZCBNUklRQyBtZXRyaWNzIHRvIHVzZSBtZWRpYW4gYWJzb2x1dGUgZGV2aWF0aW9uIChNQUQpIGFuZCBpbXByb3ZlIHJvYnVzdG5lc3MKCioqRnVsbCBjaGFuZ2Vsb2cqKjogPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL21hcmttaWtrZWxzZW4vR2FubmV0L2NvbXBhcmUvdjMuNS4yLi4udjMuNS4zIiB0YXJnZXQ9Il9ibGFuayI+YHYzLjUuMi4uLnYzLjUuM2A8L2E+CgojIyAzLjUuMgo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDI2LTAxLTMwPC9zcGFuPgoKIyMjIFdoYXQncyBjaGFuZ2VkCgoqIEFkZGVkIGR5bmFtaWMgZm9udCBzaXplIGFkanVzdG1lbnQgZm9yIFIyMDI1YSsKKiBSZWZhY3RvcmVkIHNlZ21lbnRhdGlvbiBhbmQgUUEgbWV0cmljcyBpbiBgU2VnLm1gCiogQ29uc29saWRhdGVkIGRlcGVuZGVuY3kgdXBkYXRlIHdvcmtmbG93cwoqIEZpeGVkIHNwYWNpbmcgaW4gTVJJUUMgbWV0cmljcyBjb21tZW50CiogQWRkZWQgbGluZXdpZHRoIHBhcmFtZXRlciB0byBgUGFwZXJQbG90Lm1gCiogUmVtb3ZlZCBibGFuayBpc3N1ZSB0ZW1wbGF0ZQoqIEFkZGVkIG1vcmUgbGFiZWxzIHRvIHRoZSBpbWFnZSBtb250YWdlIGluIEdhbm5ldFF1YW50aWZ5IG91dHB1dCBmaWd1cmUKKiBVcGRhdGVkIGBSRUFETUUubWRgOiBsb2dvIHBhdGgsIGNvbXBhdGliaWxpdHksIGFuZCBjb250cmlidXRvcnMKKiBVcGRhdGVkIGBDb1JlZ1N0YW5kQWxvbmUubWAgc2V0dGluZ3MgYW5kIGFkZGVkIG5vcm1hbGl6YXRpb24gdG8gTU5JIHNwYWNlCiogQWRkZWQgd29ya2Zsb3cgdG8gYXV0b21lcmdlIERlcGVuZGFib3QgUFJzCiogVXBkYXRlZCBkZXBlbmRlbmNpZXMgLSBiaWRzLW1hdGxhYiwgZGljMm5paSwgZXRjLgoqIEJ1bXBlZCBhY3Rpb25zL2NoZWNrb3V0IGZyb20gNSB0byA2CiogQnVtcGVkIHBldGVyLWV2YW5zL2NyZWF0ZS1wdWxsLXJlcXVlc3QgZnJvbSA3IHRvIDgKCioqRnVsbCBjaGFuZ2Vsb2cqKjogPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL21hcmttaWtrZWxzZW4vR2FubmV0L2NvbXBhcmUvdjMuNS4xLi4udjMuNS4yIiB0YXJnZXQ9Il9ibGFuayI+YHYzLjUuMS4uLnYzLjUuMmA8L2E+CgojIyAzLjUuMQo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDI1LTA5LTEzPC9zcGFuPgoKIyMjIFdoYXQncyBjaGFuZ2VkCgoqIFNldCBmaWd1cmUgdGhlbWUgdG8gbGlnaHQgZm9yIE1BVExBQiBSMjAyNWEgYW5kIG5ld2VyCiogTWlub3IgYnVnIGZpeGVzIGZvciBNQVRMQUIgUjIwMjVhCgoqKkZ1bGwgY2hhbmdlbG9nKio6IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrbWlra2Vsc2VuL0dhbm5ldC9jb21wYXJlL3YzLjUuMC4uLnYzLjUuMSIgdGFyZ2V0PSJfYmxhbmsiPmB2My41LjAuLi52My41LjFgPC9hPgoKIyMgMy41LjAKPHNwYW4gc3R5bGU9ImNvbG9yOiBncmV5OyI+MjAyNS0wOS0xMTwvc3Bhbj4KCiMjIyBOZXcgZmVhdHVyZXMKCi0gR2FubmV0IGlzIG5vdyBjb21wYXRpYmxlIHdpdGggPGEgaHJlZj0iaHR0cHM6Ly9iaWRzLXNwZWNpZmljYXRpb24ucmVhZHRoZWRvY3MuaW8vZW4vc3RhYmxlLyIgdGFyZ2V0PSJfYmxhbmsiPkJJRFM8L2E+CiAgLSBbYGJpZHMtbWF0bGFiYF0oaHR0cHM6Ly9iaWRzLW1hdGxhYi5yZWFkdGhlZG9jcy5pby9lbi9tYWluLyksIGEgTUFUTEFCIHRvb2xraXQgZm9yIGludGVyZmFjaW5nIHdpdGggQklEUyBkYXRhc2V0cywgaXMgZW1iZWRkZWQgaW4gR2FubmV0LCBhbmQgdXNlcnMgY2FuIG5vdyBpbnB1dCBCSURTIGRhdGFzZXRzIGRpcmVjdGx5IGludG8gYEdhbm5ldExvYWQubWAgKHNlZSBbZG9jdW1lbnRhdGlvbl0oLi9nZXR0aW5nLXN0YXJ0ZWQuaHRtbCNjb21wYXRpYmlsaXR5LXdpdGgtYmlkcykgZm9yIHVzYWdlIGluc3RydWN0aW9ucykKLSBBZGRlZCBpbWFnZSBRQSBtZXRyaWNzIGJhc2VkIG9uIDxhIGhyZWY9Imh0dHBzOi8vZG9pLm9yZy8xMC4xMzcxL2pvdXJuYWwucG9uZS4wMTg0NjYxIiB0YXJnZXQ9Il9ibGFuayI+TVJJUUM8L2E+CiAgLSBgR2FubmV0U2VnbWVudC5tYCBub3cgY2FsY3VsYXRlcyBhbmQgc2F2ZXMgdGhlIGZvbGxvd2luZyBRQSBtZXRyaWNzIGZvciBlYWNoIGFuYXRvbWljYWwgaW1hZ2U6CiAgICAtIFNpZ25hbC10by1ub2lzZSByYXRpbyAoU05SKSBvZiBHTSwgV00sIENTRiwgYW5kIHRoZSB3aG9sZSBicmFpbiAodHdvIHZhcmlhbnRzOiBvbmUgdXNpbmcgdGhlIG1lZGlhbiBhYnNvbHV0ZSBkZXZpYXRpb24gb2YgdGhlIGFpciBiYWNrZ3JvdW5kIGJhc2VkIG9uIDxhIGhyZWY9Imh0dHBzOi8vZG9pLm9yZy8xMC4xMDAyL2ptcmkuMjA5NjkiIHRhcmdldD0iX2JsYW5rIj5EaWV0cmljaCBldCBhbC4gKDIwMDcpPC9hPiwgYW5kIG9uZSB1c2luZyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBub2lzZSB3aXRoaW4gdGhlIHRpc3N1ZSBjbGFzcykKICAgIC0gQ29udHJhc3QtdG8tbm9pc2UgcmF0aW8gKENOUikgYmV0d2VlbiBHTSBhbmQgV00KICAgIC0gQ29lZmZpY2llbnQgb2YgdmFyaWF0aW9uIChDVikgb2YgR00gYW5kIFdNCiAgICAtIENvZWZmaWNpZW50IG9mIGpvaW50IHZhcmlhdGlvbiAoQ0pWKSBiZXR3ZWVuIEdNIGFuZCBXTQogICAgLSBFbnRyb3B5LWZvY3VzIGNyaXRlcmlvbiAoRUZDKQogICAgLSBGb3JlZ3JvdW5kLWJhY2tncm91bmQgZW5lcmd5IHJhdGlvIChGQkVSKQogICAgLSBXTSB0byBtYXhpbXVtIGludGVuc2l0eSByYXRpbyAoV00yTUFYKTogdGhlIG1lZGlhbiBpbnRlbnNpdHkgd2l0aGluIFdNIG92ZXIgdGhlIDk1JSBwZXJjZW50aWxlIG9mIHRoZSBmdWxsIGludGVuc2l0eSBkaXN0cmlidXRpb24sIHRoYXQgY2FwdHVyZXMgdGhlIGV4aXN0ZW5jZSBvZiBsb25nIHRhaWxzIGR1ZSB0byBoeXBlci1pbnRlbnNpdHkgb2YgdGhlIGNhcm90aWQgdmVzc2VscyBhbmQgZmF0CiAgLSBUaGVzZSBtZXRyaWNzIGFyZSBzYXZlZCBpbiBgTVJTX3N0cnVjdC5vdXQuUUFgCi0gQWRkZWQgR2l0SHViIEFjdGlvbnMgZm9yIGNvbnRpbnVvdXMgaW50ZWdyYXRpb24gd2l0aCBgYmlkcy1tYXRsYWJgLCBgZGljbTJuaWlgLCBhbmQgYGV4cG9ydF9maWdgIHRvIGVuc3VyZSBjb21wYXRpYmlsaXR5IHdpdGggdGhlIGxhdGVzdCB2ZXJzaW9ucyBvZiB0aGVzZSBkZXBlbmRlbmNpZXMKLSBBZGRlZCBgZGVwZW5kYWJvdC55bWxgIHRvIGF1dG9tYXRpY2FsbHkgY2hlY2sgZm9yIHVwZGF0ZXMgdG8gR2l0SHViIEFjdGlvbnMKLSBXYXRlci11bmZpbHRlcmVkIChidXQgYWxpZ25lZCkgc3BlY3RyYSBhcmUgbm93IHNhdmVkIGluIGBNUlNfc3RydWN0YAotIEFsbCB2ZXJzaW9uIHN0cmluZ3MgKGUuZy4sIGBNUlNfc3RydWN0LnZlcnNpb24uKmApIGFyZSBub3cgc3RvcmVkIHVuZGVyIGBNUlNfc3RydWN0LmluZm8udmVyc2lvbi4qYCwgYW5kIGRhdGV0aW1lIHN0YW1wcyBmb3IgcHJvY2Vzc2luZyBzdGVwcyBhcmUgYWRkZWQgYXMgYE1SU19zdHJ1Y3QuaW5mby5kYXRldGltZS4qYAoKIyMjIE1ham9yIGNoYW5nZXMKCi0gV2hlbiBjYWxjdWxhdGluZyBHTSwgV00sIGFuZCBDU0YgZnJhY3Rpb25zIGluIGBHYW5uZXRTZWdtZW50Lm1gLCB0aGUgcHJvYmFiaWxpc3RpYyB0aXNzdWUgbWFwcyBhcmUgbm93IHRocmVzaG9sZGVkIGF0IDAuOSBiZWZvcmUgY2FsY3VsYXRpbmcgdGhlIGZyYWN0aW9ucy4gVGhpcyBzaG91bGQgaW1wcm92ZSB0aGUgYWNjdXJhY3kgb2YgdGlzc3VlIGZyYWN0aW9uIGVzdGltYXRlcwoKIyMjIE1pbm9yIGNoYW5nZXMKCi0gTW9kaWZpZWQgYFNpZW1lbnNUV0lYUmVhZC5tYCB0byB1c2UgaWNlUGFyYW0gZm9yIGBwb2ludHNCZWZvcmVFY2hvYCBpbiBNRUdBLXNMQVNFUiwgYWxpZ25pbmcgd2l0aCBNRUdBLVBSRVNTIGhhbmRsaW5nIGZvciBjb25zaXN0ZW5jeQotIENoYW5nZWQgdGhlIG5hbWluZyBjb252ZW50aW9uIGZvciB3YXRlciByZXNpZHVhbCBmaXQgcmVzdWx0cyBmcm9tIGBSZXNpZFdhdGVyYCB0byBgcmVzaWRfd2F0ZXJgIGluIGBHYW5uZXRGaXQubWAgZm9yIGNvbnNpc3RlbmN5Ci0gSW1wcm92ZWQgaW5wdXQgYXJndW1lbnQgdmFsaWRhdGlvbiBhbmQgZXJyb3IgbWVzc2FnZXMsIGluY2x1ZGluZyBjaGVja3MgZm9yIGNlbGwgYXJyYXkgaW5wdXRzIGFuZCBmaWxlIGV4aXN0ZW5jZSwgd2l0aCBjbGVhcmVyIGVycm9yIG91dHB1dCBmb3IgbWlzc2luZyBmaWxlcwotIFVwZGF0ZWQgYGV4cG9ydF9maWdgIHRvIHYzLjUyCi0gVXBkYXRlZCBgZGljbTJuaWlgIHRvIHYyMDI1LjA4LjIxCi0gTUFOWSBDT1NNRVRJQyBDSEFOR0VTIHRvIGltcHJvdmUgY29kZSByZWFkYWJpbGl0eSBhbmQgbWFpbnRhaW5hYmlsaXR5CgoqKkZ1bGwgY2hhbmdlbG9nKio6IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrbWlra2Vsc2VuL0dhbm5ldC9jb21wYXJlL3YzLjQuMC4uLnYzLjUuMCIgdGFyZ2V0PSJfYmxhbmsiPmB2My40LjAuLi52My41LjBgPC9hPgoKIyMgMy40LjAKPHNwYW4gc3R5bGU9ImNvbG9yOiBncmV5OyI+MjAyNS0wMy0zMDwvc3Bhbj4KCiMjIyBOZXcgZmVhdHVyZXMKCi0gQWRkZWQgc3VwcG9ydCBmb3IgZml0dGluZyB0aGUgMi4zNCBwcG0gR2x1IHBlYWsgaW4gdGhlIFNVTSBzcGVjdHJ1bQotIEFkZGVkIGBEZUlkZW50aWZ5RGlzY2xhaW1lci5tYCwgd2hpY2ggcHJpbnRzIGEgZGlzY2xhaW1lciB0aGF0IHRoZSBkZXZlbG9wZXJzIHByb3ZpZGUgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIGRlLWlkZW50aWZpY2F0aW9uIGZ1bmN0aW9ucyB3aWxsIHJlbW92ZSBhbGwgaHVtYW4gcGFydGljaXBhbnRzJyBpZGVudGlmeWluZyBpbmZvcm1hdGlvbiBpbiB0aGUgZGF0YSBoZWFkZXIgb2YgZmlsZXMKLSBUaGUgUkYgY29pbCBjb21iaW5hdGlvbiB1c2VkIGlzIG5vdyBzdG9yZWQgaW4gYE1SU19zdHJ1Y3QucC5SRkNvaWxDb21iaW5hdGlvbmAgKG5vdGU6IHRoaXMgb25seSBhcHBsaWVzIHRvIHJhdyBkYXRhIGZpbGVzIHRoYXQgYXJlIG5vdCBjb2lsLWNvbWJpbmVkIGR1cmluZyBleHBvcnQgZnJvbSB0aGUgc2Nhbm5lcikKLSBEYXRhIGxvYWQgdGltZSAoYE1SU19zdHJ1Y3QubG9hZHRpbWVgKSBpcyBub3cgc3RvcmVkIHdoZW4gYEdhbm5ldExvYWQubWAgaXMgcnVuCi0gUmUtYWRkZWQgdGhlIG9wdGlvbiB0byBjaG9vc2UgdGhlIGVkaXRpbmcgcHVsc2Ugb3JkZXIgaW4gYEdhbm5ldFByZUluaXRpYWxpc2UubWA6IGBNUlNfc3RydWN0LnAuT05fT0ZGX29yZGVyYAotIE1SUyB2b3hlbCBtYXNrcyBjYW4gbm93IGJlIG5vcm1hbGl6ZWQgdG8gTU5JMTUyIHNwYWNlOyBhIGZsYWcgaW4gYEdhbm5ldFByZUluaXRpbGlhc2UubWAgaGFzIGJlZW4gYWRkZWQgdG8gZG8gc28gKG5vdGUgdGhhdCB0aGlzIGlzIG9ubHkgcGVyZm9ybWVkIGlmIEdhbm5ldFNlZ21lbnQgaGFzIGJlZW4gcnVuIGFzIHRoZSBmb3J3YXJkIGRlZm9ybWF0aW9uIG1hcCBuZWVkZWQgZm9yIE1OSSBub3JtYWxpemF0aW9uIGlzIGNyZWF0ZWQgZHVyaW5nIFNQTTEyJ3Mgc2VnbWVudGF0aW9uIHJvdXRpbmUpCi0gQWRkZWQgYFZveGVsTWFza092ZXJsYXAubWAsIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGNyZWF0ZSBhIHZveGVsIG1hc2sgdGhhdCBpbmRpY2F0ZXMgdGhlIGRlZ3JlZSBvZiBvdmVybGFwIG9mIGFsbCBkYXRhc2V0cyBydW4gaW4gYSBiYXRjaAotIEFkZGVkIGBUaHJlZUxvcmVudHpNb2RlbC5tYAotIEFkZGVkIGBWb2lndE1vZGVsLm1gCgojIyMgTWlub3IgY2hhbmdlcwoKLSBBbiAiaW50cm8iIG1lc3NhZ2UgaXMgcHJpbnRlZCB3aGVuZXZlciBgR2FubmV0TG9hZC5tYCBpcyBydW46IHRoZSB2ZXJzaW9uIG51bWJlciBhbmQgYSBsaW5rIHRvIHRoZSBzb2Z0d2FyZSBkb2N1bWVudGF0aW9uIHdlYnNpdGUgaXMgZGlzcGxheWVkCi0gQ28tcmVnaXN0cmF0aW9uIGZpZ3VyZSBvdXRwdXRzIG5vdyBzaG93IHRoZSBhbmF0b21pY2FsIGRpcmVjdGlvbnMgb2YgdGhlIGRpc3BsYXllZCBNUiBpbWFnZSAoaS5lLiwgYW50ZXJpb3IvcG9zdGVyaW9yIFtBL1BdLCBsZWZ0L3JpZ2h0IFtML1JdLCBhbmQgc3VwZXJpb3IvaW5mZXJpb3IgW1MvSV0pCi0gUmVwbGFjZWQgZmlsZSBzZXBhcmF0b3JzIHdpdGggYGZpbGVzZXBgIHNvIHRoYXQgdGhleSBhcmUgc3BlY2lmaWMgdG8gdXNlcnMnIG9wZXJhdGluZyBzeXN0ZW0KLSBgdm94b2ZmYCBpcyBub3cgcGFyc2VkIGluIGBHRVJlYWQubWAgaW5zdGVhZCBvZiBpbiBgR2FubmV0TWFza19HRS5tYCBhbmQgYEdhbm5ldE1hc2tfR0VfbmlpLm1gCi0gTWlub3IgY2hhbmdlcyB0byByb3VuZGluZyBpbiBgRXhwb3J0VG9DU1YubWAKLSBSZW5hbWVkIGBGaXRQZWFrc0J5RnJhbWVzMi5tYCB0byBgRml0UGVha3NCeUZyYW1lcy5tYAotIFVwZGF0ZWQgYGV4cG9ydF9maWdgIHRvIHYzLjQ4Ci0gVXBkYXRlZCBgZGljbTJuaWlgIHRvIHYyMDI0LjA4LjIxCi0gTUFOWSBDT1NNRVRJQyBDSEFOR0VTIEFORCBDTEVBTlVQIE9GIE9MRCBVTlVTRUQgQ09ERQoKIyMjIEJ1ZyBmaXhlcwoKLSBVcGRhdGVkIGBBbGlnblN1YlNwZWN0cmEubWAgdG8gaW5jbHVkZSBMYWMgYW5kIEdTSCBlZGl0aW5nCi0gVXBkYXRlZCBgQWxpZ25Vc2luZ1BlYWsubWAgdG8gZml0IHRoZSBpbmRleGluZyBhcHByb2FjaCBvZiBHYW5uZXQgMwotIEZpeGVkIGlzc3VlIHdpdGggU2llbWVucyAuUkRBIGZpbGVzIGluIGBDb1JlZ1N0YW5kQWxvbmUubWAKLSBBZGRlZCBgTVJTX3N0cnVjdC5wLnNlcW9yaWdgIHRvIGBDb1JlZ1N0YW5kQWxvbmUubWAKLSBNaW5vciBmaXggaW4gYEdhbm5ldE1hc2tfTklmVEkubWAgZm9yIGhvdyB2b3hlbCBvZmZzZXQgaXMgcGFyc2VkIGZyb20gdGhlIE5JZlRJIGZpbGUKLSBGaXhlZCBhbiBpc3N1ZSB3aXRoIGBHYW5uZXRGaXQubWAgd2hlbiB1c2VycyBjaG9vc2UgdG8gZml0IGEgc3BlY2lmaWMgbWV0YWJvbGl0ZQotIENvcnJlY3RlZCBhIGJ1ZyBpbiBgUGFwZXJQbG90Lm1gIGZvciBwbG90dGluZyBtb2RlbCBmaXRzIGZvciBHQUJBK0dseAotIEZpeGVkIGFuIGlzc3VlIGluIGBBbGlnblVzaW5nUGVhay5tYCB3aGVuIHJ1bm5pbmcgbW9yZSB0aGFuIG9uZSBmaWxlIGluIGEgYmF0Y2gKCiMjIDMuMy4yCjxzcGFuIHN0eWxlPSJjb2xvcjogZ3JleTsiPjIwMjMtMDgtMDI8L3NwYW4+CgojIyMgTWFqb3IgY2hhbmdlcwoKLSBSZXdyb3RlIGBTaWVtZW5zUmVhZC5tYCB0byByZWR1Y2UgY29kZSBsZW5ndGgKCiMjIyBNaW5vciBjaGFuZ2VzCgotIFVwZGF0ZWQgYERJQ09NUmVhZC5tYCwgaW5jbHVkaW5nIHRvIHN1cHBvcnQgU2llbWVucyBYQTMwIGRhdGEKLSBVcGRhdGVkIGBTcGVjdHJhbFJlZ2lzdHJhdGlvbkhFUk1FUy5tYAogIC0gU05SIGxpbWl0IGlzIG5vdyBlc3RpbWF0ZWQgYXMgaW4gYFJvYnVzdFNwZWN0cmFsUmVnaXN0cmF0aW9uLm1gCiAgLSBCdWcgZml4IGZvciBpbmRleGluZyBmb3Igb3V0cHV0IHNhdmVkIGZyb20gbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24KLSBVcGRhdGVkIGBkaWNtMm5paWAgdG8gdmVyc2lvbiAyMDIzLjAzLjE2Ci0gVXBkYXRlZCBgZXhwb3J0X2ZpZ2AgdG8gdjMuNDAKLSBBZGRlZCBHYW5uZXQgZG9jdW1lbnRhdGlvbiB3ZWJzaXRlIFVSTCB0byBlcnJvciBkaWFsb2cgYm94Ci0gQ2hhbmdlZCB0aGUgd2F5IHBhdGggbmFtZXMgYXJlIHByaW50ZWQgaW4gZXJyb3IgZGlhbG9nIGJveAotIFR1cm5lZCBvZmYgaXRlcmF0aW9uIGxpbWl0IHdhcm5pbmcgaW4gYEZpdENob0NyLm1gCi0gVXBkYXRlZCBgVXBkYXRlR2FubmV0Lm1gIHRvIGVuc3VyZSBhbGwgc3ViLWRpcmVjdG9yaWVzIGFyZSBhZGRlZCB0byB0aGUgc2VhcmNoIHBhdGggYWZ0ZXIgdXBkYXRpbmcKLSBBZGRlZCBpc3N1ZSB0ZW1wbGF0ZXMgKGluIGAuZ2l0aHViL0lTU1VFX1RFTVBMQVRFYCkgZm9yIGJsYW5rIGlzc3VlcywgYnVnIHJlcG9ydHMsIGFuZCBmZWF0dXJlIHJlcXVlc3RzCi0gUmVmaW5lZCBhbGlnbm1lbnQgb2YgdGV4dC9sb2dvcyBpbiBvdXRwdXQgZmlndXJlcwogIC0gVGhlIHVuaXRzIHVzZWQgZm9yIGRpc3BsYXlpbmcgdGV4dHVhbCByZXN1bHRzIGFyZSBub3cgbm9ybWFsaXplZCB0byBmaXQgdG8gYW55IHN1YnBsb3QgZGltZW5zaW9uCiAgLSBUaGUgdGV4dHVhbCByZXN1bHRzIGluIHRoZSBgR2FubmV0Q29SZWdpc3RlcmAsIGBHYW5uZXRTZWdtZW50YCwgYENvUmVnYCwgYW5kIGBTZWdgIG91dHB1dCBmaWd1cmVzIGFyZSBub3cgY29ycmVjdGx5IGNlbnRlcmVkCi0gVGhlIHdlaWdodGVkIHNpZ25hbCBhdmVyYWdpbmcgbWV0aG9kIHVzZWQgaXMgbm93IHNhdmVkIGluIHRoZSBzdHJ1Y3R1cmUgb3V0cHV0Ci0gVGhlIHdlaWdodGluZyBmYWN0b3JzIGNhbGN1bGF0ZWQgd2hlbiBhcHBseWluZyB3ZWlnaHRlZCBzaWduYWwgYXZlcmFnaW5nIGFyZSBhbHNvIG5vdyBzYXZlZCBpbiB0aGUgb3V0cHV0Ci0gVXBkYXRlZCBgU2F2ZVBERi5tYCBzdWNoIHRoYXQgd2hlbiBhcHBlbmRpbmcgUERGcyB1c2luZyBgZXhwb3J0X2ZpZ2AsIHRoZSBmaWd1cmUgc2l6ZSB3aWxsIG5vdyBiZSBlcXVpdmFsZW50IGluIHBpeGVscyBvbiBXaW5kb3dzIGFuZCBNYWMgc3lzdGVtcwotIFVwZGF0ZWQgYE5JZlRJTVJTUmVhZC5tYAotIFVwZGF0ZWQgYFJFQURNRS5tZGAKLSBVcGRhdGVkIGBHYW5uZXRGaXRQaGFudG9tLm1gCi0gUmVtb3ZlZCByZWR1bmRhbnQgZ2xvYmFsIGZyZXF1ZW5jeSBzaGlmdCBpbiBgUm9idXN0U3BlY3RyYWxSZWdpc3RyYXRpb24ubWAKLSBUaGUgei1zdGFuZGFyZGl6ZWQgTVNFcyBjYWxjdWxhdGVkIGluIHRoZSBzcGVjdHJhbCByZWdpc3RyYXRpb24gc3Vicm91dGluZXMgYXJlIG5vdyBzYXZlZCBpbiB0aGUgc3RydWN0dXJlIG91dHB1dAotIFVwZGF0ZWQgYEdhbm5ldFZlcnNpb24ubWAgdG8gYWxzbyBvdXRwdXQgdmVyc2lvbiBudW1iZXJzIG9mIEdhbm5ldCBtb2R1bGVzCi0gQSB3YXJuaW5nIGlzIG5vdyBwcmludGVkIHdoZW4gdXNlcnMgcHJvY2VzcyBTaWVtZW5zIC5yZGEgZGF0YSBlbmNvdXJhZ2luZyB0aGVtIHRvIGluc3RlYWQgdXNlIFRXSVggKC5kYXQpIGRhdGEKLSBBZGRlZCBzdXBwb3J0IGZvciBHRSBQLWZpbGUgaGVhZGVyIHJldmlzaW9uIDMwICg8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbWFya21pa2tlbHNlbi9HYW5uZXQvaXNzdWVzLzI4IiB0YXJnZXQ9Il9ibGFuayI+IzI4PC9hPikKLSBNQU5ZIENPU01FVElDIENIQU5HRVMKCiMjIyBCdWcgZml4ZXMKCi0gQnVnIGZpeCBmb3Igc3BlY2lhbCBjaGFyYWN0ZXIgYFxgIGluIFdpbmRvd3MgZmlsZSBwYXRoIG5hbWVzIHByaW50ZWQgaW4gdGhlIGVycm9yIGRpYWxvZyBib3gKLSBGaXhlZCBidWcgaW4gYEdhbm5ldE1hc2tfTklmVEkubWAgd2hlcmUgdGhlIGNvLXJlZ2lzdGVyZWQgTVJTIHZveGVsIHdhcyBpbmNvcnJlY3RseSBmbGlwcGVkIGluIHRoZSBgR2FubmV0Q29SZWdpc3RlcmAgb3V0cHV0IGZpZ3VyZQotIEZpeGVkIGJ1ZyBpbiBgR2FubmV0UXVhbnRpZnkubWAgd2hlcmUgdGhlIGFscGhhIHZhbHVlIHdhcyBpbmNvcnJlY3RseSBiZWluZyBwcmludGVkIG11bHRpcGxlIHRpbWVzIHdoZW4gbXVsdGlwbGUgd2VyZSBydW4gaW4gYmF0Y2gKLSBBZGRlZCBmaXggaW4gYFZlcnNpb25DaGVjay5tYCBzbyB0aGF0IHdoZW4gdXNlcnMgaGF2ZSBsaW1pdGVkIG9yIHJlc3RyaWN0ZWQgaW50ZXJuZXQgYWNjZXNzLCBhbiBlcnJvciBpcyBhdm9pZGVkICg8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbWFya21pa2tlbHNlbi9HYW5uZXQvcHVsbC8yNyIgdGFyZ2V0PSJfYmxhbmsiPiMyNzwvYT4pIC0gdGhhbmtzIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9hbGV4Y3JhdmVuIiB0YXJnZXQ9Il9ibGFuayI+QGFsZXhjcmF2ZW48L2E+IQoKIyMgMy4zLjEKPHNwYW4gc3R5bGU9ImNvbG9yOiBncmV5OyI+MjAyMy0wMy0xNDwvc3Bhbj4KCiMjIyBOZXcgZmVhdHVyZXMKCi0gQ29tcHJlc3NlZCBOSWZUSSBmaWxlcyAoXCoubmlpLmd6KSBhcmUgbm93IGZ1bGx5IHN1cHBvcnRlZAotIEdhbm5ldCBub3cgZnVsbHkgcXVhbnRpZmllcyBtZXRhYm9saXRlIGxldmVscyBmb3IgQ3IsIENobywgYW5kIE5BQSAoZXN0aW1hdGVkIGZyb20gdGhlIE9GRgogIHNwZWN0cnVtKQoKIyMjIE1ham9yIGNoYW5nZXMKCi0gTW92ZWQgbG9jYWwgc2lnbmFsIG1vZGVsIGZ1bmN0aW9ucyBvdXQgb2YgYEdhbm5ldEZpdC5tYCBhbmQgaW50byB0aGVpciBvd24gZmlsZXM6CiAgLSBgQmFzZWxpbmVNb2RlbC5tYAogIC0gYENhbGNJVS5tYAogIC0gYERvdWJsZUdhdXNzTW9kZWwubWAKICAtIGBFdE9ITW9kZWwubWAKICAtIGBHQUJBR2x4TW9kZWwubWAKICAtIGBHYXVzc01vZGVsLm1gCiAgLSBgTG9yZW50ekdhdXNzTW9kZWwubWAKICAtIGBMb3JlbnR6R2F1c3NNb2RlbFAubWAKLSBBZGRlZCBgR2V0RnVsbFBhdGgubWA7IEdhbm5ldCBub3cgd2lsbCBmaW5kIHRoZSBmdWxsIHBhdGggb2YgaW5wdXQgZmlsZXMgYnkgZGVmYXVsdAotIFJlbmFtZWQgc29tZSBvZiB0aGUgZGF0YS1sb2FkaW5nIGZ1bmN0aW9ucwoKIyMjIE1pbm9yIGNoYW5nZXMKCi0gQWRkZWQgYSBjaGVjayBpbiBgR2FubmV0UXVhbnRpZnkubWAgZm9yIGRhdGFzZXRzIHdpdGhvdXQgd2F0ZXIgcmVmZXJlbmNlczsgYEdhbm5ldFF1YW50aWZ5Lm1gIHdpbGwKICBub3QgcnVuIGlmIG5vIHdhdGVyIHJlZmVyZW5jZXMgYXJlIHByZXNlbnQKLSBBZGRlZCBhIGNoZWNrIGluIGBHYW5uZXRDb1JlZ2lzdGVyLm1gIHRvIGVuc3VyZSBhbGwgc3RydWN0dXJhbCBpbWFnZSBmaWxlcyBjYW4gYmUgZm91bmQKLSBVcGRhdGVkIGBleHBvcnRfZmlnYCB0byB2My4zMwotIFVwZGF0ZWQgYGRpY20ybmlpYCB0byB2ZXJzaW9uIDIwMjMuMDMuMDgKLSBVcGRhdGVkIGBMSUNFTlNFYCBhbmQgYFJFQURNRS5tZGAKLSBVcGRhdGVkIGBFeHBvcnRUb0NTVi5tYAotIFVwZGF0ZWQgYENvUmVnU3RhbmRBbG9uZWAgZnVuY3Rpb25zCi0gUmVwbGFjZWQgdXNlIG9mIGAxaWAgd2l0aCBgY29tcGxleCgpYAotIFJlbW92ZWQgdW51c2VkIHZhcmlhYmxlIGBUMW1heGAKLSBSZW1vdmVkIHVubmVjZXNzYXJ5IGBvbmVzKClgIHBhcmFtZXRlciBpbiBgTG9yZW50ek1vZGVsLm1gIGFuZCBgVHdvTG9yZW50ek1vZGVsLm1gCi0gUGhpbGlwcyBcKi5zcGFyIGZpbGUgZXh0ZW5zaW9uIGlzIG5vIGxvbmdlciBzYXZlZCBpbiB0aGUgb3V0cHV0IHN0cnVjdHVyZQotIFJlbW92ZWQgY2FsY3VsYXRpb24gb2YgYGRmYCBpbiBgR2FubmV0TG9hZC5tYDsgYWRkZWQgYGR0YCBpbiBpdHMgcGxhY2UKLSBFeHBvcnRlZCBDU1YgZmlsZXMgd2lsbCBubyBsb25nZXIgYmUgb3ZlcndyaXR0ZW4gaWYgYSBDU1YgZmlsZSBvZiB0aGUgc2FtZSBuYW1lIGFscmVhZHkgZXhpc3RzIGluCiAgdGhlIG91dHB1dCBkaXJlY3Rvcnk7IGluc3RlYWQsIGEgbmV3IGZpbGUgaXMgY3JlYXRlZCBhbmQgYXBwZW5kZWQgd2l0aCBhbiBpbnRlZ2VyCi0gQWRkZWQgbmV3IG91dHB1dCBzdHJ1Y3R1cmUgYXR0cmlidXRlIGBucm93c193YXRlcmAKLSBSZW9yZGVyZWQgc3RydWN0dXJlIHN1YmZpZWxkcyBmb3IgbWV0YWJvbGl0ZXMgaW4gYEdhbm5ldEZpdC5tYCBhbmQgYEV4cG9ydFRvQ1NWLm1gCi0gU2hpZnRlZCBHYW5uZXQgbG9nbyBhbmQgdmVyc2lvbiBudW1iZXIgaW4gUERGIG91dHB1dHMgc2xpZ2h0bHkgdG8gdGhlIHJpZ2h0Ci0gQWxwaGEgdmFsdWVzIGFyZSBub3cgaW5jbHVkZWQgaW4gZXhwb3J0ZWQgQ1NWIGZpbGVzCi0gUmVwbGFjZWQgdGhlIEdhbm5ldCBsb2dvIHdpdGggYSBQTkcgdmVyc2lvbgotIE1BTlkgQ09TTUVUSUMgQ0hBTkdFUwoKIyMjIEJ1ZyBmaXhlcwoKLSBBZGRlZCBhIGNoZWNrIGZvciBsZXR0ZXIgY2FzZSBvZiBcKi5kY20gYW5kIFwqLmltYSBmaWxlcyBpbiBgRElDT01SZWFkLm1gIGFuZCBgU2llbWVuc0RJQ09NUmVhZC5tYAogIChgZGlyKClgIGlzIGNhc2Utc2Vuc2l0aXZlIGluIExpbnV4KQotIEFkZGVkIGEgZml4IHRvIGF2b2lkIGFuIGVycm9yIHdoZXJlIE1BVExBQiB0cmllZCB0byBjbG9zZSBmaWd1cmVzIGZvbGxvd2luZyBhbiB1bnJlbGF0ZWQgaW50ZXJuYWwKICBlcnJvciwgYnV0IG5vIGZpZ3VyZXMgd2VyZSBjcmVhdGVkCi0gRml4ZWQgYSBidWcgaW4gYE5JZlRJTVJTUmVhZC5tYCB0aGF0IGxlZCB0byBhbiBlcnJvciBpZiB0aGUgYE1hbnVmYWN0dXJlcmAgZmllbGQgaXMgbm90IGZvdW5kIGluCiAgdGhlIGRhdGEgZmlsZSBoZWFkZXIKLSBJZiBgZXhwb3J0X2ZpZy5tYCBjYW5ub3QgYmUgZm91bmQgb24gdGhlIHNlYXJjaCBwYXRoIGFuZCBgYXBwZW5kYCBoYXMgYmVlbiBmbGFnZ2VkIGluCiAgYEdhbm5ldFByZUluaXRpYWxpc2UubWAsIGl0IGlzIG1hZGUgY2xlYXIgdG8gdGhlIHVzZXIgdGhhdCBQREZzIHdpbGwgYmUgc2F2ZWQgc2VwYXJhdGVseQotIEZpeGVkIGJ1Z3MgaW4gYEFsaWduVXNpbmdIMk8ubWAKLSBGaXhlZCBhIGJ1ZyBpbiBgU2llbWVuc0RJQ09NUmVhZC5tYCB3aGVyZSBhbiBlcnJvciBvY2N1cnJlZCBpZiBgY2VudGVyRnJlcWAgaXMgbm90IGZvdW5kIGluIHRoZQogIGRhdGEgZmlsZSBoZWFkZXIKCiMjIDMuMy4wCjxzcGFuIHN0eWxlPSJjb2xvcjogZ3JleTsiPjIwMjItMTAtMjI8L3NwYW4+CgojIyMgTmV3IGZlYXR1cmVzCi0gQWRkZWQgZnVuY3Rpb25hbGl0eSB0byByZWFkIE5JZlRJLU1SUyBmaWxlcyAoPGEgaHJlZj0iaHR0cHM6Ly9vbmxpbmVsaWJyYXJ5LndpbGV5LmNvbS9kb2kvMTAuMTAwMi9tcm0uMjk0MTgiIHRhcmdldD0iX2JsYW5rIj5DbGFya2UgZXQgYWwuLCBNUk0sIDIwMjI8L2E+KSAoYE5JZlRJTVJTUmVhZC5tYCk7IGluY2x1ZGVzIGFkZGl0aW9uYWwgbmV3IGZ1bmN0aW9uIGBHYW5uZXRNYXNrX05JZlRJLm1gIGZvciB2b3hlbCBjby1yZWdpc3RyYXRpb24KLSBBZGRlZCBzdXBwb3J0IGZvciBVdGFoIFNpZW1lbnMgTUVHQS1QUkVTUyBzZXF1ZW5jZSAoRElDT00gZmlsZXMpCi0gQWRkZWQgc3VwcG9ydCBmb3IgQ01SUiBQUkVTUyBkYXRhIChESUNPTSBmaWxlcykKLSBBZGRlZCBzdXBwb3J0IGZvciBTaWVtZW5zIFhBMzAgc2VxdWVuY2UgYXMgcHJvdmlkZWQgYnkgSkhVCi0gQ2hhbmdlZCBgUkVBRE1FYCB0byBgUkVBRE1FLm1kYCwgd2hpY2ggbm93IGluY2x1ZGVzIGJhZGdlcwoKIyMjIE1ham9yIGNoYW5nZXMKLSBDb2lsIGNvbWJpbmF0aW9uIG9mIEdFLCBOSWZUSS1NUlMsIGFuZCBTaWVtZW5zIFRXSVggZmlsZXMgaXMgbm93IHBlcmZvcm1lZCB1c2luZyBnZW5lcmFsaXplZCBsZWFzdCBzcXVhcmVzICg8YSBocmVmPSJodHRwczovL29ubGluZWxpYnJhcnkud2lsZXkuY29tL2RvaS8xMC4xMDAyL2ptcmkuMjM5NDEiIHRhcmdldD0iX2JsYW5rIj5BbiBldCBhbC4sIEpNUkksIDIwMTM8L2E+KTsgdGhpcyBhcHByb2FjaCBoYXMgYmVlbiBzaG93biB0byByZXN1bHQgaW4gb3B0aW1hbCBTTlIgYW5kIHJlZHVjZSBzcGVjdHJhbCBhcnRpZmFjdHMKLSBUaGUgR2FubmV0IGxvZ28gaGFzIGJlZW4gcmV2ZXJ0ZWQgdG8gdGhlIG9yaWdpbmFsIGltYWdlIG9mIGEgZ2FubmV0CgojIyMgTWlub3IgY2hhbmdlcwotIEFkZGVkIGZ1bmN0aW9uYWxpdHkgZm9yIEdFIGRhdGEgaW4gYEFsaWduU3ViU3BlY3RyYV9QcmVBbGlnblJlZi5tYAotIEFuIGVycm9yIGlzIHByZXNlbnRlZCBpZiBub3QgZW5vdWdoIGlucHV0cyBhcmUgZ2l2ZW4gZm9yIGFueSBvZiB0aGUgR2FubmV0IG1vZHVsZXMKLSBDb1JlZ1N0YW5kQWxvbmUgb3V0cHV0cyBjYW4gYmUgaGlkZGVuIGlmIGBNUlNfc3RydWN0LnAuaGlkZWAgaXMgc2V0IHRvIGAxYCBpbiBgQ29SZWdTdGFuZEFsb25lLm1gIChkZWZhdWx0IGlzIGAwYCkKLSBJZiB0aGUgdXNlciBoYXMgbm8gaW50ZXJuZXQgY29ubmVjdGlvbiwgYFZlcnNpb25DaGVjay5tYCBhbmQgYFVwZGF0ZUdhbm5ldC5tYCB3aWxsIG5vdCBydW4KLSBVcGRhdGVkIGRpY20ybmlpIHRvIGxhdGVzdCB2ZXJzaW9uICh2ZXJzaW9uIDIwMjIuMDkuMTUpCi0gVXBkYXRlZCBtYXBWQlZEIGZ1bmN0aW9ucyB0byBsYXRlc3QgdmVyc2lvbiAoPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3BlaHNlcy9tYXBWQlZEIiB0YXJnZXQ9Il9ibGFuayI+aHR0cHM6Ly9naXRodWIuY29tL3BlaHNlcy9tYXBWQlZEPC9hPikKLSBUdXJuZWQgb2ZmIHdhcm5pbmdzIG9mIGl0ZXJhdGlvbiBsaW1pdHMgaW4gYFNwZWN0cmFsUmVnaXN0cmF0aW9uSEVSTUVTLm1gIGFuZCBgR2FubmV0Rml0Lm1gCi0gTWFueSBjb3NtZXRpYyBjaGFuZ2VzIGluIHRoZSBjb2RlCgojIyMgQnVnIGZpeGVzCi0gRml4ZWQgYnVnIGluIGVycm9yIHJlcG9ydGluZyBpbiBgR2FubmV0Rml0Lm1gCi0gQ29SZWdTdGFuZEFsb25lIHJvdXRpbmVzIG5vdyBwYXJzZSB2ZXJzaW9uIG51bWJlcnMgZnJvbSB0aGUgbWFpbiBtb2R1bGVzIHByb3Blcmx5Ci0gVmFyaWFibGUgYGZpbGVzRXhpc3RgIGluIGBHYW5uZXRTZWdtZW50Lm1gIG1heSBub3QgcG9wdWxhdGU7IGl0IGlzIG5vdyBwcmUtaW5pdGlhbGl6ZWQgYXMgYSBwcmVjYXV0aW9uCi0gQnVnIGZpeCBpbiBgR2FubmV0TWFza19TaWVtZW5zUkRBLm1gCi0gQnVnIGZpeGVzIGZvciByZWFkaW5nIERJQ09NIGZpbGVzCgojIyAzLjIuMQo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDIyLTA2LTA3PC9zcGFuPgoKIyMjIE1pbm9yIGNoYW5nZXMKLSBgUGhhc2VDb3JyZWN0aW9uLm1gIG5vdyBkZWFscyBiZXR0ZXIgd2l0aCBzcGVjdHJhIHRoYXQgaGF2ZSBhIG5vbi16ZXJvIGJhc2VsaW5lCi0gU1BNMTIgbm93IG91dHB1dHMgZm9yd2FyZCBkZWZvcm1hdGlvbiBmaWVsZCAobmVlZGVkIGZvciBub3JtYWxpemluZyB2b3hlbCBtYXNrcyB0byBNTkkgc3BhY2UpCi0gVXBkYXRlZCBgZXhwb3J0X2ZpZ2AgdG8gdjMuMjcKLSBgQ29SZWdTdGFuZEFsb25lLm1gIG5vdyBleHBvcnRzIGEgQ1NWIGZpbGUKLSBWYXJpb3VzIGNvc21ldGljIGNoYW5nZXMKCiMjIyBCdWcgZml4ZXMKLSBGaXhlZCBzdWItc3BlY3RyYSBhbGlnbm1lbnQgZm9yIEdFIEhFUkNVTEVTIGRhdGEKLSBGaXhlZCBidWcgaW4gYENvUmVnU3RhbmRBbG9uZS5tYAotIEZpeGVkIGJ1ZyBpbiBgcmVhZF9kY21faGVhZGVyLm1gICh0aGFua3MgdG8gTWVyZWRpdGggUmVpZCkKCiMjIDMuMi4wCjxzcGFuIHN0eWxlPSJjb2xvcjogZ3JleTsiPjIwMjEtMDctMzA8L3NwYW4+CgojIyMgTmV3IGZlYXR1cmVzCgotIEFkZGVkIGBHYW5uZXRWZXJzaW9uLm1gLCBgVmVyc2lvbkNoZWNrLm1gLCBhbmQgYFVwZGF0ZUdhbm5ldC5tYDsgdGhlc2UgbmV3IGZ1bmN0aW9ucyBsZXQgdXNlcnMga25vdyB0aGUgdmVyc2lvbiBvZiBHYW5uZXQgdGhleSBoYXZlLCBpZiBhIG5ld2VyIHJlbGVhc2Ugb2YgR2FubmV0IGlzIGF2YWlsYWJsZSwgYW5kIHdpbGwgYWxsb3cgdGhlbSB0byBhdXRvbWF0aWNhbGx5IHVwZGF0ZSBpZiB3YW50ZWQKLSBBZGRlZCBgVG9vbGJveENoZWNrLm1gIHRvIGNoZWNrIGZvciBtaXNzaW5nIE1BVExBQiB0b29sYm94ZXMgbmVlZGVkIHRvIHJ1biBHYW5uZXQKLSBFcnJvciBkaWFsb2cgYm94ZXMgYXJlIGRpc3BsYXllZCBhdCB0aGUgZW5kIG9mIHRoZSBhbmFseXNpcyBwaXBlbGluZSBpZiBhbiBlcnJvciBvY2N1cnJlZCAoZHVyaW5nIGEgYmF0Y2ggYW5hbHlzaXMsIEdhbm5ldCB3aWxsIHNraXAgdG8gdGhlIG5leHQgZGF0YXNldCBhbmQgY29udGludWUgcnVubmluZykKLSBVc2VycyBjYW4gbm93IGNob29zZSB0byB1c2Ugd2VpZ2h0ZWQgKHRoZSBkZWZhdWx0KSBvciBjb252ZW50aW9uYWwgc2lnbmFsIGF2ZXJhZ2luZyBpbiBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCAob3V0bGllciBzY2FucyBhcmUgcmVtb3ZlZCB3aGVuIHVzaW5nIGNvbnZlbnRpb25hbCBhdmVyYWdpbmcsIGFzIGJlZm9yZSkKLSBBZGRlZCBhIG5ldyAob3B0aW9uYWwpIG1ldGhvZCBmb3Igcm9idXN0LCB3ZWlnaHRlZCBzaWduYWwgYXZlcmFnaW5nOiB3ZWlnaHRlZCBhdmVyYWdpbmcgYnkgY3JpdGVyaW9uIGZ1bmN0aW9uIG1pbmltaXphdGlvbiAoV0FDRk0pIHVzaW5nIHRoZSBnZW5lcmFsaXplZCBDYXVjaHkgZGlzdHJpYnV0aW9uIGFzIHRoZSBjb3N0IGZ1bmN0aW9uOyBzZWUgZG9pOjxhIGhyZWY9Imh0dHBzOi8vZHguZG9pLm9yZy8xMC4xMDE2L2ouYmJlLjIwMTUuMDYuMDAyIiB0YXJnZXQ9Il9ibGFuayI+MTAuMTAxNi9qLmJiZS4yMDE1LjA2LjAwMjwvYT4gZm9yIG1vcmUgZGV0YWlsczsgYWRkaXRpb25hbGx5LCBpbnN0ZWFkIG9mIHdlaWdodGluZyBkaWZmZXJlbmNlIHBhaXJzLCB0aGUgc3Vic3BlY3RyYSBvZiBlYWNoIGVkaXRpbmcgc3ViZXhwZXJpbWVudCBhcmUgd2VpZ2h0ZWQgdG8gZ2VuZXJhdGUgd2VpZ2h0ZWQgc3Vic3BlY3RyYSwgd2hpY2ggYXJlIHRoZW4gc3VidHJhY3RlZDsgc2VlIGBTaWduYWxBdmVyYWdpbmcubWAKLSBZYWlyIEFsdG1hbidzIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9hbHRtYW55L2V4cG9ydF9maWciIHRhcmdldD0iX2JsYW5rIj5leHBvcnRfZmlnIHRvb2xib3g8L2E+IGlzIGluY2x1ZGVkIGFzIGFuIG9wdGlvbmFsIHRvb2xib3ggdGhhdCwgaWYgYWRkZWQgdG8gTUFUTEFCJ3Mgc2VhcmNoIHBhdGgsIEdhbm5ldCB3aWxsIHVzZSB0byBhcHBlbmQgYWxsIG91dHB1dCBQREZzIGZyb20gZWFjaCBtb2R1bGUgaW50byBhIHNpbmdsZSBQREYgKGEgZmxhZyBtdXN0IGJlIHNldCBpbiBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCB0byBkbyB0aGlzKTsgdGhpcyBpcyB2ZXJ5IHVzZWZ1bCBmb3IgZWFzeSBRQSBvZiBsb3RzIG9mIGRhdGE7IG5vdGUgdGhhdCA8YSBocmVmPSJodHRwczovL3d3dy5naG9zdHNjcmlwdC5jb20vIiB0YXJnZXQ9Il9ibGFuayI+R2hvc3RzY3JpcHQ8L2E+IG5lZWRzIHRvIGJlIGluc3RhbGxlZCBmb3IgdGhlIGFwcGVuZGluZyBvZiBQREZzIHRvIHdvcmsgKE5COiBtYWNPUyB1c2VycyBzaG91bGQgdXNlIHRoaXMgPGEgaHJlZj0iaHR0cHM6Ly9wYWdlcy51b3JlZ29uLmVkdS9rb2NoLyIgdGFyZ2V0PSJfYmxhbmsiPnZlcnNpb248L2E+IG9yIHVzZSA8YSBocmVmPSJodHRwczovL2Zvcm11bGFlLmJyZXcuc2gvZm9ybXVsYS9naG9zdHNjcmlwdCIgdGFyZ2V0PSJfYmxhbmsiPkhvbWVicmV3PC9hPiB0byBpbnN0YWxsIEdob3N0c2NyaXB0KQotIEltcGxlbWVudGVkIHVzZSBvZiBoeXBlcmxpbmtzIGluIGluZm8gYW5kIGVycm9yIG1lc3NhZ2VzIHByaW50ZWQgaW4gdGhlIGNvbW1hbmQgd2luZG93IHNvIHRoYXQgdXNlcnMgY2FuOiAoMSkgZGlyZWN0bHkgcnVuIGEgY2VydGFpbiBmdW5jdGlvbiAoc3VjaCBhcyBgVXBkYXRlR2FubmV0Lm1gIHdoZW4gYFZlcnNpb25DaGVjay5tYCBpbmZvcm1zIHRoZSB1c2VyIGEgbmV3IHJlbGVhc2UgaXMgYXZhaWxhYmxlKTsgKDIpIGdvIHN0cmFpZ2h0IHRvIHRoZSBsaW5lIG9mIGNvZGUgd2hlcmUgYW4gZW5jb3VudGVyZWQgZXJyb3IgY2FuIGJlIGZpeGVkIChzdWNoIGFzIGVycm9ycyBpbiBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCk7IG9yICgzKSBnbyB0byBhIHdlYnNpdGUgYnkgY2xpY2tpbmcgb24gdGhlIHByaW50ZWQgVVJMIChzdWNoIGFzIHRvIGRvd25sb2FkIFNQTTEyKTsgdGhlIHJlbGV2YW50IGNvZGUgaGFzIGJlZW4gYm9ycm93ZWQgZnJvbSBleHBvcnRfZmlnCi0gQWRkZWQgYW4gb3B0aW9uIGluIGBHYW5uZXRQcmVJbml0aWFsaXNlLm1gIHRoYXQgYWxsb3dzIHVzZXJzLCB3aGVuIHVzaW5nIHJvYnVzdCBzcGVjdHJhbCByZWdpc3RyYXRpb24sIHRvIHVzZSB0aGUgYXZlcmFnZWQgcHJlLWFsaWduZWQgc3Vic3BlY3RyYSBhcyByZWZlcmVuY2VzIGZvciBhbGlnbmluZyB0aGUgYXZlcmFnZWQgcG9zdC1hbGlnbmVkIHN1YnNwZWN0cmEgKHRoaXMgbWF5IGJlIGhlbHBmdWwgd2hlbiByb2J1c3Qgc3BlY3RyYWwgcmVnaXN0cmF0aW9uIG1ha2VzIHRoZSBhbGlnbm1lbnQgb2YgYWxyZWFkeSBnb29kLXF1YWxpdHkgcHJlLWFsaWduZWQgc3BlY3RyYSB3b3JzZSkKLSBgUGFwZXJQbG90Lm1gIG5vdyBhbGxvd3MgdXNlcnMgdG8gcGxvdCBhbiBleGVtcGxhcnkgdm94ZWwgbWFzayBjby1yZWdpc3RlcmVkIHRvIHRoZSByZXNwZWN0aXZlIHN0cnVjdHVyYWwgaW1hZ2UKLSBBZGRlZCBgR2FubmV0TWFza19HRV9uaWkubWA7IEdFIHVzZXJzIGNhbiBub3cgdXNlIE5JZlRJIGltYWdlcyBpbnN0ZWFkIG9mIERJQ09NcyB0byBjby1yZWdpc3RlciB0aGVpciBNUlMgdm94ZWxzIHRvIHN0cnVjdHVyYWwgaW1hZ2VzCi0gQWRkZWQgdGhlIGFiaWxpdHkgdG8gdHJpbSBkYXRhc2V0cwotIEV4dGVuZGVkIHRoZSBhYmlsaXR5IHRvIGNvbmNhdGVuYXRlIGZpbGVzLCBpbmNsdWRpbmcgb3ZlciBtdWx0aXBsZSBzdWJqZWN0cwotIEFkZGVkIGEgZmxhZyBpbiBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCAoYE1SU19zdHJ1Y3QucC5oaWRlYCkgdG8gcHJldmVudCBvdXRwdXQgZmlndXJlcyBmcm9tIGRpc3BsYXlpbmcgKHVzZWZ1bCB3aGVuIHByb2Nlc3NpbmcgYSBsYXJnZSBiYXRjaCBvZiBmaWxlcykKCiMjIyBNYWpvciBjaGFuZ2VzCgotIFRoZSBvdXRkYXRlZCBtYW51YWwgUERGIGhhcyBiZWVuIHJlbW92ZWQ7IHVwLXRvLWRhdGUgc29mdHdhcmUgZG9jdW1lbnRhdGlvbiB3aWxsIG5vdyBiZSBmb3VuZCBvbmxpbmU6IGh0dHBzOi8vbWFya21pa2tlbHNlbi5naXRodWIuaW8vR2FubmV0LWRvY3MvaW5kZXguaHRtbAotIEdhbm5ldCBpcyBub3cgbGljZW5zZWQgdW5kZXIgdGhlIEJTRCAzLUNsYXVzZSBMaWNlbnNlCi0gQWxwaGEgdGlzc3VlIGNvcnJlY3Rpb24gaXMgbm93IHBlcmZvcm1lZCBvbiBhIGJ5LW1ldGFib2xpdGUgYmFzaXMgcmF0aGVyIHRoYW4gZml4aW5nIHRoZSBpbnRyaW5zaWMgV006R00gY29uY2VudHJhdGlvbiB0byAxOjIgKGFscGhhKSBmb3IgYWxsIG1ldGFib2xpdGVzIChhc3N1bWluZyBmb3Igbm93IHRoZSByYXRpbyBpcyAxOjIgZm9yIEdBQkEgYW5kIEdseCBhbmQgMToxIGZvciBHU0gsIEV0T0ggYW5kIExhYyk7IHRoZSBhbHBoYSB0aGF0IGlzIGFzc3VtZWQgaXMgZGlzcGxheWVkIGluIHRoZSBHYW5uZXRRdWFudGlmeSBvdXRwdXQgZmlndXJlCi0gUmVtb3ZlZCBgTVJTX3N0cnVjdC5wLk9OX09GRl9vcmRlcmAgZnJvbSBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYDsgdGhlIG9yZGVyIG9mIGVkaXRpbmcgcHVsc2VzIGlzIG5vdyBkZXRlcm1pbmVkIGF1dG9tYXRpY2FsbHk7IHRoZSByZWxldmFudCBjb2RlIGhhcyBiZWVuIGJvcnJvd2VkIGZyb20gT3NwcmV5ICh0aGlzIGhhcyBvbmx5IGJlZW4gdGVzdGVkIHRvIGEgbGltaXRlZCBleHRlbnQgc28gbWF5IHJlcXVpcmUgZnVydGhlciB0d2Vha2luZykKLSBUaGUgZXhjZXB0aW9uIHRvIHRoaXMgY2hhbmdlIGlzIHBoYW50b20gZGF0YSwgd2hlcmUgdXNlcnMgd2lsbCBzdGlsbCBuZWVkIHRvIHNwZWNpZnkgdGhlIG9yZGVyIG9mIGVkaXRpbmcgcHVsc2VzCgojIyMgTWlub3IgY2hhbmdlcwoKLSBEYXRhc2V0cyB3aXRoIGRpZmZlcmluZyBudW1iZXIgb2YgYXZlcmFnZXMgY2FuIG5vdyBiZSBiYXRjaC1wcm9jZXNzZWQgdG9nZXRoZXIKLSBUdXJuZWQgb2ZmIHRoZSBwcm9ncmVzcyBiYXIgZGlzcGxheWVkIHdoZW4gbG9hZGluZyBTaWVtZW5zIFRXSVggZGF0YSB0byByZWR1Y2UgbG9hZGluZyB0aW1lCi0gUmVuYW1lZCBzb21lIGZpbGVzIGZvciB0aGUgc2FrZSBvZiBjbGFyaXR5IGFuZCBzdHlsZTsgcmVtb3ZlZCBvYnNvbGV0ZSBgR2FubmV0TWFzay5tYAotIFNpZ25hbCBhdmVyYWdpbmcgYW5kIHN1YnRyYWN0aW9uIGFyZSBub3cgZG9uZSBpbiB0aGUgbmV3IGZ1bmN0aW9uIGBTaWduYWxBdmVyYWdpbmcubWAKLSBWYXJpb3VzIGltcHJvdmVtZW50cyB0byBgUm9idXN0U3BlY3RyYWxSZWdpc3RyYXRpb24ubWAgKGZvcm1lcmx5IGBSb2J1c3RfU3BlY3RyYWxfUmVnaXN0cmF0aW9uLm1gKSBmb3IgYmV0dGVyIGhhbmRsaW5nIG9mIGRhdGEgYWNxdWlyZWQgdXNpbmcgdmVyeSBzdHJvbmcgd2F0ZXIgc3VwcHJlc3Npb24KLSBUaGUgYXNzdW1lZCBjb25jZW50cmF0aW9uIG9mIHB1cmUgd2F0ZXIgaW4gYEdhbm5ldEZpdC5tYCBhbmQgYEdhbm5ldEZpdFBoYW50b20ubWAgKFB1cmVXYXRlckNvbmMpIGhhcyBiZWVuIGNoYW5nZWQgZnJvbSA1NSB0byA1NS41MSBtb2wva2c7IHRoaXMgcHV0cyBpdCBpbiBsaW5lIHdpdGggdGhlIHNhbWUgY29uc3RhbnQgdXNlZCBpbiBgR2FubmV0UXVhbnRpZnkubWAKLSBBZGRlZCBlZGl0cyBmcm9tIFJhbHBoIE5vZXNrZSAoR0UgQmVybGluKSB0byBgR0VSZWFkLm1gIGZvciBiZXR0ZXIgaGFuZGxpbmcgb2YgZGF0YSB3aGVuIG5lY2hvZXMgPT0gMTsgYWxzbyBjaGFuZ2VkIHRoZSBzY2FsaW5nIGZhY3RvciBpZiBuZWNob2VzID4gMSAoaG9wZWZ1bGx5IHRoaXMgbWFrZXMgd2F0ZXItcmVmZXJlbmNlZCBtZWFzdXJlbWVudHMgY29uc2lzdGVudCBhY3Jvc3MgYWxsIGRhdGEgZW5jb2RpbmcgZmxhdm9ycykKLSBJbiBgR0VSZWFkLm1gIGFuZCBgUGhpbGlwc1JlYWRfZGF0YS5tYCwgaW5zdGVhZCBvZiB1c2luZyB0aGUgZmlyc3QgcG9pbnQgaW4gdGhlIEZJRCBmb3Igc2lnbmFsIHdlaWdodGluZywgdGhlIG1vc3QgY29tbW9uIHBvaW50IHRoYXQgaXMgdGhlIG1heCBpbiB0aGUgbWFnbml0dWRlIHNpZ25hbCBhY3Jvc3MgYWxsIEZJRHMgaXMgbm93IHVzZWQKLSBTb21lIGNoYW5nZXMgdG8gYFNpZW1lbnNESUNPTVJlYWQubWAgYW5kIGBESUNPTVJlYWQubWAgZm9yIHNtYXJ0ZXIgaGFuZGxpbmcgb2YgZGF0YSBmaWxlczogZm9yIGVhY2ggZGF0YXNldCwgbWV0YWJvbGl0ZSBhbmQgd2F0ZXIgZGF0YSBmaWxlcyBzaG91bGQgYmUgc3RvcmVkIGluIHNlcGFyYXRlIGZvbGRlcnMKLSBJbXByb3ZlZCBgRXhwb3J0VG9DU1YubWA7IGEgc2luZ2xlIC5jc3YgZmlsZSBpcyBub3cgZXhwb3J0ZWQgZm9yIEhFUk1FUyBkYXRhc2V0czsgdXNlZnVsIHZhcmlhYmxlcyBzdWNoIGFzIHNpZ25hbCBhcmVhcyBhbmQgQ3IgZml0IHF1YWxpdHkgbWV0cmljcyBhcmUgbm93IGFsc28gZXhwb3J0ZWQKLSBSZXdyb3RlIGBEaXNjZXJuRGF0YVR5cGUubWAgKGZvcm1lcmx5IGBHYW5uZXREaXNjZXJuRGF0YXR5cGUubWApCi0gTWlub3IgY2hhbmdlcyBhbmQgaW1wcm92ZW1lbnRzIHRvIGBQYXBlclBsb3QubWAKLSBNaW5vciBjaGFuZ2VzIHRvIGBDb1JlZ1N0YW5kQWxvbmUubWAgZnVuY3Rpb25zCi0gTWlub3IgY2hhbmdlcyB0byBgU2lnbmFsRmlsdGVyLm1gCi0gU2ltcGxpZmllZCBgRWRkeUN1cnJlbnRDb3JyZWN0aW9uLm1gIChmb3JtZXJseSBgcGhhc2VfY29ycmVjdGlvbl9maWRzLm1gKQotIFNldCB1cCBTUE0xMiBmb3IgYmF0Y2ggdGlzc3VlIHNlZ21lbnRhdGlvbiBvbmx5IHdoZW4gdGlzc3VlIHNlZ21lbnRhdGlvbiBoYXMgbm90IGFscmVhZHkgYmVlbiBydW4gYW5kIGRvIGl0IG9ubHkgb25jZSBpbiBhIGJhdGNoCi0gQWxsRnJhbWVzRlQgKGZvciB0aGUgbGFzdCBsb2FkZWQgZGF0YXNldCkgaXMgbm93IGFsc28gc2F2ZWQgaW4gYE1SU19zdHJ1Y3Quc3BlY2AKLSBXaGVuIHNhdmluZyB0aGUgYE1SU19zdHJ1Y3RgIHN0cnVjdHVyZSwgdGhlIC5tYXQgZmlsZSBpcyBub3cgc2F2ZWQgdXNpbmcgdmVyc2lvbiA3LjMgKGZvciB0aGUgcmFyZSBjYXNlIHdoZW4gdGhlIHN0cnVjdHVyZSBpcyA+PSAyIEdCIG9uIDY0LWJpdCBjb21wdXRlcnMpCi0gUmVtb3ZlZCBgTVJTX3N0cnVjdC5wLnNkYXRgIGZyb20gYEdhbm5ldFByZUluaXRpYWxpc2UubWAgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGNvZGUgZnJvbSBgR2FubmV0TG9hZC5tYCAodGhpcyBmZWF0dXJlIHdhcyBuZXZlciByZWFsbHkgdXNlZCBieSB1c2VycyBhZmFpaykKLSBJbXByb3ZlZCBnbG9iYWwgemVyby1vcmRlciBwaGFzaW5nIGluIGBTcGVjdHJhbFJlZ2lzdHJhdGlvbkhFUk1FUy5tYAotIE1hbnkgY29zbWV0aWMvYWVzdGhldGljIGNoYW5nZXMKICAtIFRoZSBtb2R1bGUgb3V0cHV0IGZpZ3VyZXMgbm93IHNob3cgaW5mb3JtYXRpb24gdXNlZnVsIGZvciByZXBvcnRpbmcgYWNxdWlzaXRpb24gcGFyYW1ldGVycyBhbmQgcmVzdWx0cyAoaW4gbGluZSB3aXRoIHRoZSA8YSBocmVmPSJodHRwczovL29ubGluZWxpYnJhcnkud2lsZXkuY29tL2RvaS8xMC4xMDAyL25ibS40NDg0IiB0YXJnZXQ9Il9ibGFuayI+TVJTaW5NUlM8L2E+IGNoZWNrbGlzdCkKICAtIENvLXJlZ2lzdGVyZWQvc2VnbWVudGVkIHZveGVsIG1hc2tzIGRpc3BsYXllZCBpbiBHYW5uZXRDb1JlZ2lzdGVyLCBHYW5uZXRTZWdtZW50LCBhbmQgR2FubmV0UXVhbnRpZnkgb3V0cHV0IGZpZ3VyZXMgYXJlIG5vdyBzaG93biBpbiB5ZWxsb3cgcmF0aGVyIHRoYW4gZ3JheXNjYWxlCiAgLSBTbWFydGVyIHN0YWNraW5nIG9mIEhFUk1FUyBkaWZmZXJlbmNlIHNwZWN0cmEgaW4gYFBsb3RQcmVQb3N0QWxpZ24ubWAgYW5kIGBQbG90UHJlUG9zdEFsaWduMi5tYCAoZm9ybWVybHkgYEdhbm5ldFBsb3RQcmVQb3N0QWxpZ24ubWAgYW5kIGBHYW5uZXRQbG90UHJlUG9zdEFsaWduMi5tYCkKICAtIFRoZSBHYW5uZXQgZG9jdW1lbnRhdGlvbiB3ZWJzaXRlIFVSTCBpcyBwcmludGVkIGF0IHRoZSBib3R0b20gb2YgZXZlcnkgb3V0cHV0IGZpZ3VyZQogIC0gUmVtb3ZlZCBpcnJlbGV2YW50IG1lc3NhZ2VzIGZyb20gYmVpbmcgcHJpbnRlZCBpbiB0aGUgY29tbWFuZCB3aW5kb3cgZHVyaW5nIHRoZSBhbmFseXNpcyBwaXBlbGluZSwgcmVwbGFjaW5nIHRoZW0gd2l0aCBtb3JlIHVzZWZ1bCBtZXNzYWdlcwogIC0gTWlub3IgcmVhcnJhbmdpbmcgb2YgcmVzdWx0cyB0ZXh0IGluIEdhbm5ldFNlZ21lbnQgYW5kIEdhbm5ldFF1YW50aWZ5IG91dHB1dCBmaWd1cmVzCiAgLSBTbGlnaHQgY2hhbmdlIHRvIHRoZSB5LWF4aXMgbGFiZWxzIG9mIHRoZSBDciBmcmVxdWVuY3kgc3BlY3Ryb2dyYW0gaW4gdGhlIEdhbm5ldExvYWQgb3V0cHV0IGZpZ3VyZQogIC0gQmV0dGVyIHJlb3JkZXJpbmcgb2YgYE1SU19zdHJ1Y3Qub3V0YCBzdWJmaWVsZHMgY3JlYXRlZCBpbiBgR2FubmV0Rml0Lm1gCgojIyMgQnVnIGZpeGVzCgotIEZyZXF1ZW5jeSBhbmQgcGhhc2Ugb2Zmc2V0IGVzdGltYXRlcyBhcmUgbm93IHRyYWNrZWQgY29ycmVjdGx5IGFuZCBzYXZlZCB3aGVuIHJ1bm5pbmcgYW55IG9mIHRoZSBzcGVjdHJhbCByZWdpc3RyYXRpb24tYmFzZWQgYWxpZ25tZW50IG1ldGhvZHMKLSBSZW1vdmVkIG9sZCBkZWJ1Z2dpbmcgY29uZGl0aW9uYWwgc3RhdGVtZW50IGluIGBUV0lYRGVJZGVudGlmeS5tYAotIEV4cGxpY2l0bHkgc3BlY2lmeSBjb2xvciBvZiB3YXRlciBmcmVxdWVuY3kgdHJhY2UgaW4gR2FubmV0TG9hZCBvdXRwdXQgZmlndXJlIGFzIHRoZXJlIGFwcGVhcnMgdG8gYmUgYSBidWcgc2luY2UgTUFUTEFCIFIyMDE5YiB3aGVuIHVzaW5nIGhvbGQgdG8gb3ZlcmxheSBwbG90cwotIEFkZGVkIEV0T0ggc2lnbmFsIHBhcmFtZXRlcnMgdG8gYEdhbm5ldFF1YW50aWZ5Lm1gCi0gSW4gYFNpZW1lbnNUd2l4UmVhZC5tYCwgaWYgbm8gd2F0ZXIgcmVmZXJlbmNlIGlzIHByb3ZpZGVkLCB1c2UgdGhlIG1vc3QgY29tbW9uIHBvaW50IHRoYXQgaXMgdGhlIG1heCBpbiB0aGUgbWFnbml0dWRlIHNpZ25hbCBhY3Jvc3MgYWxsIEZJRHMgaW5zdGVhZCBvZiBqdXN0IHVzaW5nIHRoZSBmaXJzdCBwb2ludAotIEZpeGVkIGFuIG9yaWVudGF0aW9uIHByb2JsZW0gaW4gYEdhbm5ldE1hc2tfR0UubWAKLSBSZW1vdmVkIHVubmVjZXNzYXJ5IGNvbXBsZXggY29uanVnYXRlIHRyYW5zcG9zZSBkdXJpbmcgRkZUIG9mIHdhdGVyIGRhdGEgaW4gYEdhbm5ldExvYWQubWAKLSBUdXJuZWQgb2ZmIHdhcm5pbmdzIGFib3V0IGxlZ2FjeSBudW1iZXIgZ2VuZXJhdG9yIGluIGBSb2J1c3RTcGVjdHJhbFJlZ2lzdHJhdGlvbi5tYCAoZm9yIHdoZW4gcm5nIGFuZCByYW5kbiBhcmUgcnVuIGluIGBTaWduYWxGaWx0ZXIubWApIGlmIHRoZXkgYXJlIGFscmVhZHkgdHVybmVkIG9uCgojIyAzLjEuNQo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDIwLTAzLTAyPC9zcGFuPgoKIyMjIE5ldyBmZWF0dXJlcwoKLSBTbWFydGVyIGNoZWNraW5nIG9mIGluY29ycmVjdCBzZXR0aW5ncyBpbiBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCBieSBgQ2hlY2tUYXJnZXRzLm1gCi0gTWFqb3IgY2hhbmdlcyB0byBgR2FubmV0Rml0UGhhbnRvbS5tYCB0byBicmluZyBpdCBtb3JlIGluIGxpbmUgd2l0aCBgR2FubmV0Rml0Lm1gCi0gQWRkZWQgc3VwcG9ydCBmb3IgQ01SUiBNRUdBLXNMQVNFUiBzZXF1ZW5jZSBpbiBgU2llbWVuc1R3aXhSZWFkLm1gCi0gSW4gYFN1YlNwZWN0cmFsQWxpZ24ubWAsIGlmIHZlcnkgc3Ryb25nIHdhdGVyIHN1cHByZXNzaW9uIHdhcyB1c2VkLCB1c2UgQ2hvIGluc3RlYWQgb2YgcmVzaWR1YWwgd2F0ZXIgdG8gYWxpZ24gc3Vic3BlY3RyYSBvZiBHQUJBLSwgTGFjLSwgYW5kIEV0T0gtZWRpdGVkIGRhdGFzZXRzCgojIyMgTWlub3IgY2hhbmdlcwoKLSBOb2lzZSBlc3RpbWF0aW9uIGluIGBDYWxjTm9pc2UubWAsIGBSb2J1c3RfU3BlY3RyYWxfUmVnaXN0cmF0aW9uLm1gLCBhbmQgYFNpZ25hbEZpbHRlci5tYCBpcyBub3cgcGVyZm9ybWVkIGJldHdlZW4gOCBhbmQgMTAgcHBtIHRvIGFjY291bnQgZm9yIGRhdGFzZXRzIHRoYXQgaGF2ZSBzaG9ydGVyIHNwZWN0cmFsIHdpZHRocwotIENsZWFuZWQgdXAgY29kZSBpbiBgR2FubmV0Rml0Lm1gCi0gUXVhbnRpZmljYXRpb24gb2YgTGFjIG5vdyBleHBsaWNpdGx5IGRlZmluZWQgYXMgTGFjK01NCi0gSW1wcm92ZWQgZnVuY3Rpb25hbGl0eSBvZiBgUGFwZXJQbG90Lm1gCi0gSW4gYFNpZW1lbnNUd2l4UmVhZC5tYCwgd2hlbiBhIHdhdGVyIHJlZmVyZW5jZSBpcyBwcmVzZW50LCBjb2lsIHNlbnNpdGl2aXR5IGFuZCBwaGFzZSBpcyBiYXNlZCBvbiB0aGUgcG9pbnQgaW5kZXggdGhhdCBpcyBhdCB0aGUgdG9wIG9mIHRoZSBlY2hvLCByYXRoZXIgdGhhbiBzaW1wbHkgZml4aW5nIGl0IHRvIHRoZSBmaXJzdCBwb2ludAoKIyMjIEJ1ZyBmaXhlcwoKLSBNaW5vciBidWcgZml4ZXMgaW4gQ29SZWdTdGFuZEFsb25lIGZ1bmN0aW9ucwotIENvcnJlY3RlZCB1c2Ugb2YgcmFuZG9tIG51bWJlciBnZW5lcmF0aW9uIGluIGBTaWduYWxGaWx0ZXIubWAgd2hlbiBwZXJmb3JtaW5nIG5vaXNlIHJlcGxhY2VtZW50IHRvIGVuc3VyZSB0aGUgc2FtZSByZXN1bHRzIGFyZSByZXByb2R1Y2VkIGVhY2ggdGltZSBpdCBpcyBydW4gb24gYSBkYXRhc2V0CgojIyAzLjEuNAo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDE5LTEwLTAzPC9zcGFuPgoKIyMjIEJ1ZyBmaXgKCi0gRml4ZWQgZXJyb3IgaW4gdGhlIGNhbGN1bGF0aW9uIG9mIGBBdmdEZWx0YUYwYCBmb3IgTUVHQS1QUkVTUyBkYXRhCgojIyAzLjEuMwo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDE5LTA4LTA2PC9zcGFuPgoKIyMjIE5ldyBmZWF0dXJlcwoKLSBNYWpvciBpbXByb3ZlbWVudHMgdG8gYFJvYnVzdF9TcGVjdHJhbF9SZWdpc3RyYXRpb24ubWAKLSBXYXZlbGV0IHRvb2xib3ggbm8gbG9uZ2VyIHJlcXVpcmVkCi0gUmF3IGRhdGEgaXMgbm93IHBoYXNlLWNvcnJlY3RlZCBwcmlvciB0byBhbGlnbm1lbnQKLSBgR2FubmV0TG9hZC5tYCBhbmQgYEdhbm5ldEZpdC5tYCBubyBsb25nZXIgY3Jhc2ggaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBhIGJhdGNoIGFuYWx5c2lzCi0gQW4gZXJyb3IgcmVwb3J0IGlzIHByaW50ZWQgYWZ0ZXIgdGhlIGZpbmFsIGRhdGFzZXQgaXMgbG9hZGVkL2ZpdHRlZCBzbyB1c2VycyBjYW4gY2hlY2sgd2hpY2ggZGF0YXNldHMgZmFpbGVkCi0gQWRkZWQgc3VwcG9ydCBmb3IgR0UgcmV2aXNpb24gaGVhZGVyIDIwLjAwNwoKIyMjIE1pbm9yIGNoYW5nZQoKLSBgV2F0ZXJfUG9zaXRpdmVgIGZsYWcgaW4gYEdhbm5ldFByZUluaXRpYWxpc2UubWAgcmVtb3ZlZAoKCgoKCg==
Built with
R Markdown in
RStudio
Copyright © 2020–2026, Mark Mikkelsen