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.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
LS0tCnRpdGxlOiAiUmVsZWFzZSBub3RlcyIKZGF0ZTogIkxhc3QgdXBkYXRlZDogYHIgZm9ybWF0KFN5cy50aW1lKCksICclQiAlZCwgJVknKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiBUUlVFCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBGQUxTRQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKYGBgCgpgYGB7ciwgY2hpbGQgPSAianMvYmFjay10by10b3AuanMifQpgYGAKCjxicj4KClRoaXMgcGFnZSBsaXN0cyB0aGUgc3RhYmxlIHJlbGVhc2VzIG9mIEdhbm5ldCBzaW5jZSB2My4xLjMuIEFsbCByZWxlYXNlcyBjYW4gYmUgZm91bmQgb24gR2l0SHViIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrbWlra2Vsc2VuL0dhbm5ldC9yZWxlYXNlcyIgdGFyZ2V0PSJfYmxhbmsiPmhlcmU8L2E+IGFuZCA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vcmljaGFyZGVkZGVuL0dhbm5ldDMuMS9yZWxlYXNlcyIgdGFyZ2V0PSJfYmxhbmsiPmhlcmU8L2E+LiBUaGUgZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiBHYW5uZXQgY2FuIGJlIGZvdW5kIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrbWlra2Vsc2VuL0dhbm5ldC90cmVlL2RldiIgdGFyZ2V0PSJfYmxhbmsiPmhlcmU8L2E+LiBGb3IgYSBtb3JlIGNvbXByZWhlbnNpdmUgbGlzdCBvZiBjaGFuZ2VzIHRvIHRoZSBjdXJyZW50IG1haW4gdmVyc2lvbiwgc2VlIHRoZSBjb21taXRzIGxvZ2dlZCBvbiBHaXRIdWIgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL21hcmttaWtrZWxzZW4vR2FubmV0L2NvbW1pdHMvbWFpbiIgdGFyZ2V0PSJfYmxhbmsiPmhlcmU8L2E+LgoKIyMgMy4zLjIKPHNwYW4gc3R5bGU9ImNvbG9yOiBncmV5OyI+MjAyMy0wOC0wMjwvc3Bhbj4KCiMjIyBNYWpvciBjaGFuZ2VzCgotIFJld3JvdGUgYFNpZW1lbnNSZWFkLm1gIHRvIHJlZHVjZSBjb2RlIGxlbmd0aAoKIyMjIE1pbm9yIGNoYW5nZXMKCi0gVXBkYXRlZCBgRElDT01SZWFkLm1gLCBpbmNsdWRpbmcgdG8gc3VwcG9ydCBTaWVtZW5zIFhBMzAgZGF0YQotIFVwZGF0ZWQgYFNwZWN0cmFsUmVnaXN0cmF0aW9uSEVSTUVTLm1gCiAgLSBTTlIgbGltaXQgaXMgbm93IGVzdGltYXRlZCBhcyBpbiBgUm9idXN0U3BlY3RyYWxSZWdpc3RyYXRpb24ubWAKICAtIEJ1ZyBmaXggZm9yIGluZGV4aW5nIGZvciBvdXRwdXQgc2F2ZWQgZnJvbSBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbgotIFVwZGF0ZWQgYGRpY20ybmlpYCB0byB2ZXJzaW9uIDIwMjMuMDMuMTYKLSBVcGRhdGVkIGBleHBvcnRfZmlnYCB0byB2My40MAotIEFkZGVkIEdhbm5ldCBkb2N1bWVudGF0aW9uIHdlYnNpdGUgVVJMIHRvIGVycm9yIGRpYWxvZyBib3gKLSBDaGFuZ2VkIHRoZSB3YXkgcGF0aCBuYW1lcyBhcmUgcHJpbnRlZCBpbiBlcnJvciBkaWFsb2cgYm94Ci0gVHVybmVkIG9mZiBpdGVyYXRpb24gbGltaXQgd2FybmluZyBpbiBgRml0Q2hvQ3IubWAKLSBVcGRhdGVkIGBVcGRhdGVHYW5uZXQubWAgdG8gZW5zdXJlIGFsbCBzdWItZGlyZWN0b3JpZXMgYXJlIGFkZGVkIHRvIHRoZSBzZWFyY2ggcGF0aCBhZnRlciB1cGRhdGluZwotIEFkZGVkIGlzc3VlIHRlbXBsYXRlcyAoaW4gYC5naXRodWIvSVNTVUVfVEVNUExBVEVgKSBmb3IgYmxhbmsgaXNzdWVzLCBidWcgcmVwb3J0cywgYW5kIGZlYXR1cmUgcmVxdWVzdHMKLSBSZWZpbmVkIGFsaWdubWVudCBvZiB0ZXh0L2xvZ29zIGluIG91dHB1dCBmaWd1cmVzCiAgLSBUaGUgdW5pdHMgdXNlZCBmb3IgZGlzcGxheWluZyB0ZXh0dWFsIHJlc3VsdHMgYXJlIG5vdyBub3JtYWxpemVkIHRvIGZpdCB0byBhbnkgc3VicGxvdCBkaW1lbnNpb24KICAtIFRoZSB0ZXh0dWFsIHJlc3VsdHMgaW4gdGhlIGBHYW5uZXRDb1JlZ2lzdGVyYCwgYEdhbm5ldFNlZ21lbnRgLCBgQ29SZWdgLCBhbmQgYFNlZ2Agb3V0cHV0IGZpZ3VyZXMgYXJlIG5vdyBjb3JyZWN0bHkgY2VudGVyZWQKLSBUaGUgd2VpZ2h0ZWQgc2lnbmFsIGF2ZXJhZ2luZyBtZXRob2QgdXNlZCBpcyBub3cgc2F2ZWQgaW4gdGhlIHN0cnVjdHVyZSBvdXRwdXQKLSBUaGUgd2VpZ2h0aW5nIGZhY3RvcnMgY2FsY3VsYXRlZCB3aGVuIGFwcGx5aW5nIHdlaWdodGVkIHNpZ25hbCBhdmVyYWdpbmcgYXJlIGFsc28gbm93IHNhdmVkIGluIHRoZSBvdXRwdXQKLSBVcGRhdGVkIGBTYXZlUERGLm1gIHN1Y2ggdGhhdCB3aGVuIGFwcGVuZGluZyBQREZzIHVzaW5nIGBleHBvcnRfZmlnYCwgdGhlIGZpZ3VyZSBzaXplIHdpbGwgbm93IGJlIGVxdWl2YWxlbnQgaW4gcGl4ZWxzIG9uIFdpbmRvd3MgYW5kIE1hYyBzeXN0ZW1zCi0gVXBkYXRlZCBgTklmVElNUlNSZWFkLm1gCi0gVXBkYXRlZCBgUkVBRE1FLm1kYAotIFVwZGF0ZWQgYEdhbm5ldEZpdFBoYW50b20ubWAKLSBSZW1vdmVkIHJlZHVuZGFudCBnbG9iYWwgZnJlcXVlbmN5IHNoaWZ0IGluIGBSb2J1c3RTcGVjdHJhbFJlZ2lzdHJhdGlvbi5tYAotIFRoZSB6LXN0YW5kYXJkaXplZCBNU0VzIGNhbGN1bGF0ZWQgaW4gdGhlIHNwZWN0cmFsIHJlZ2lzdHJhdGlvbiBzdWJyb3V0aW5lcyBhcmUgbm93IHNhdmVkIGluIHRoZSBzdHJ1Y3R1cmUgb3V0cHV0Ci0gVXBkYXRlZCBgR2FubmV0VmVyc2lvbi5tYCB0byBhbHNvIG91dHB1dCB2ZXJzaW9uIG51bWJlcnMgb2YgR2FubmV0IG1vZHVsZXMKLSBBIHdhcm5pbmcgaXMgbm93IHByaW50ZWQgd2hlbiB1c2VycyBwcm9jZXNzIFNpZW1lbnMgLnJkYSBkYXRhIGVuY291cmFnaW5nIHRoZW0gdG8gaW5zdGVhZCB1c2UgVFdJWCAoLmRhdCkgZGF0YQotIEFkZGVkIHN1cHBvcnQgZm9yIEdFIFAtZmlsZSBoZWFkZXIgcmV2aXNpb24gMzAgKDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrbWlra2Vsc2VuL0dhbm5ldC9pc3N1ZXMvMjgiIHRhcmdldD0iX2JsYW5rIj4jMjg8L2E+KQotIE1BTlkgQ09TTUVUSUMgQ0hBTkdFUwoKIyMjIEJ1ZyBmaXhlcwoKLSBCdWcgZml4IGZvciBzcGVjaWFsIGNoYXJhY3RlciBgXGAgaW4gV2luZG93cyBmaWxlIHBhdGggbmFtZXMgcHJpbnRlZCBpbiB0aGUgZXJyb3IgZGlhbG9nIGJveAotIEZpeGVkIGJ1ZyBpbiBgR2FubmV0TWFza19OSWZUSS5tYCB3aGVyZSB0aGUgY28tcmVnaXN0ZXJlZCBNUlMgdm94ZWwgd2FzIGluY29ycmVjdGx5IGZsaXBwZWQgaW4gdGhlIGBHYW5uZXRDb1JlZ2lzdGVyYCBvdXRwdXQgZmlndXJlCi0gRml4ZWQgYnVnIGluIGBHYW5uZXRRdWFudGlmeS5tYCB3aGVyZSB0aGUgYWxwaGEgdmFsdWUgd2FzIGluY29ycmVjdGx5IGJlaW5nIHByaW50ZWQgbXVsdGlwbGUgdGltZXMgd2hlbiBtdWx0aXBsZSB3ZXJlIHJ1biBpbiBiYXRjaAotIEFkZGVkIGZpeCBpbiBgVmVyc2lvbkNoZWNrLm1gIHNvIHRoYXQgd2hlbiB1c2VycyBoYXZlIGxpbWl0ZWQgb3IgcmVzdHJpY3RlZCBpbnRlcm5ldCBhY2Nlc3MsIGFuIGVycm9yIGlzIGF2b2lkZWQgKDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrbWlra2Vsc2VuL0dhbm5ldC9wdWxsLzI3IiB0YXJnZXQ9Il9ibGFuayI+IzI3PC9hPikgLSB0aGFua3MgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2FsZXhjcmF2ZW4iIHRhcmdldD0iX2JsYW5rIj5AYWxleGNyYXZlbjwvYT4hCgojIyAzLjMuMQo8c3BhbiBzdHlsZT0iY29sb3I6IGdyZXk7Ij4yMDIzLTAzLTE0PC9zcGFuPgoKIyMjIE5ldyBmZWF0dXJlcwoKLSBDb21wcmVzc2VkIE5JZlRJIGZpbGVzIChcKi5uaWkuZ3opIGFyZSBub3cgZnVsbHkgc3VwcG9ydGVkCi0gR2FubmV0IG5vdyBmdWxseSBxdWFudGlmaWVzIG1ldGFib2xpdGUgbGV2ZWxzIGZvciBDciwgQ2hvLCBhbmQgTkFBIChlc3RpbWF0ZWQgZnJvbSB0aGUgT0ZGCiAgc3BlY3RydW0pCgojIyMgTWFqb3IgY2hhbmdlcwoKLSBNb3ZlZCBsb2NhbCBzaWduYWwgbW9kZWwgZnVuY3Rpb25zIG91dCBvZiBgR2FubmV0Rml0Lm1gIGFuZCBpbnRvIHRoZWlyIG93biBmaWxlczoKICAtIGBCYXNlbGluZU1vZGVsLm1gCiAgLSBgQ2FsY0lVLm1gCiAgLSBgRG91YmxlR2F1c3NNb2RlbC5tYAogIC0gYEV0T0hNb2RlbC5tYAogIC0gYEdBQkFHbHhNb2RlbC5tYAogIC0gYEdhdXNzTW9kZWwubWAKICAtIGBMb3JlbnR6R2F1c3NNb2RlbC5tYAogIC0gYExvcmVudHpHYXVzc01vZGVsUC5tYAotIEFkZGVkIGBHZXRGdWxsUGF0aC5tYDsgR2FubmV0IG5vdyB3aWxsIGZpbmQgdGhlIGZ1bGwgcGF0aCBvZiBpbnB1dCBmaWxlcyBieSBkZWZhdWx0Ci0gUmVuYW1lZCBzb21lIG9mIHRoZSBkYXRhLWxvYWRpbmcgZnVuY3Rpb25zCgojIyMgTWlub3IgY2hhbmdlcwoKLSBBZGRlZCBhIGNoZWNrIGluIGBHYW5uZXRRdWFudGlmeS5tYCBmb3IgZGF0YXNldHMgd2l0aG91dCB3YXRlciByZWZlcmVuY2VzOyBgR2FubmV0UXVhbnRpZnkubWAgd2lsbAogIG5vdCBydW4gaWYgbm8gd2F0ZXIgcmVmZXJlbmNlcyBhcmUgcHJlc2VudAotIEFkZGVkIGEgY2hlY2sgaW4gYEdhbm5ldENvUmVnaXN0ZXIubWAgdG8gZW5zdXJlIGFsbCBzdHJ1Y3R1cmFsIGltYWdlIGZpbGVzIGNhbiBiZSBmb3VuZAotIFVwZGF0ZWQgYGV4cG9ydF9maWdgIHRvIHYzLjMzCi0gVXBkYXRlZCBgZGljbTJuaWlgIHRvIHZlcnNpb24gMjAyMy4wMy4wOAotIFVwZGF0ZWQgYExJQ0VOU0VgIGFuZCBgUkVBRE1FLm1kYAotIFVwZGF0ZWQgYEV4cG9ydFRvQ1NWLm1gCi0gVXBkYXRlZCBgQ29SZWdTdGFuZEFsb25lYCBmdW5jdGlvbnMKLSBSZXBsYWNlZCB1c2Ugb2YgYDFpYCB3aXRoIGBjb21wbGV4KClgCi0gUmVtb3ZlZCB1bnVzZWQgdmFyaWFibGUgYFQxbWF4YAotIFJlbW92ZWQgdW5uZWNlc3NhcnkgYG9uZXMoKWAgcGFyYW1ldGVyIGluIGBMb3JlbnR6TW9kZWwubWAgYW5kIGBUd29Mb3JlbnR6TW9kZWwubWAKLSBQaGlsaXBzIFwqLnNwYXIgZmlsZSBleHRlbnNpb24gaXMgbm8gbG9uZ2VyIHNhdmVkIGluIHRoZSBvdXRwdXQgc3RydWN0dXJlCi0gUmVtb3ZlZCBjYWxjdWxhdGlvbiBvZiBgZGZgIGluIGBHYW5uZXRMb2FkLm1gOyBhZGRlZCBgZHRgIGluIGl0cyBwbGFjZQotIEV4cG9ydGVkIENTViBmaWxlcyB3aWxsIG5vIGxvbmdlciBiZSBvdmVyd3JpdHRlbiBpZiBhIENTViBmaWxlIG9mIHRoZSBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMgaW4KICB0aGUgb3V0cHV0IGRpcmVjdG9yeTsgaW5zdGVhZCwgYSBuZXcgZmlsZSBpcyBjcmVhdGVkIGFuZCBhcHBlbmRlZCB3aXRoIGFuIGludGVnZXIKLSBBZGRlZCBuZXcgb3V0cHV0IHN0cnVjdHVyZSBhdHRyaWJ1dGUgYG5yb3dzX3dhdGVyYAotIFJlb3JkZXJlZCBzdHJ1Y3R1cmUgc3ViZmllbGRzIGZvciBtZXRhYm9saXRlcyBpbiBgR2FubmV0Rml0Lm1gIGFuZCBgRXhwb3J0VG9DU1YubWAKLSBTaGlmdGVkIEdhbm5ldCBsb2dvIGFuZCB2ZXJzaW9uIG51bWJlciBpbiBQREYgb3V0cHV0cyBzbGlnaHRseSB0byB0aGUgcmlnaHQKLSBBbHBoYSB2YWx1ZXMgYXJlIG5vdyBpbmNsdWRlZCBpbiBleHBvcnRlZCBDU1YgZmlsZXMKLSBSZXBsYWNlZCB0aGUgR2FubmV0IGxvZ28gd2l0aCBhIFBORyB2ZXJzaW9uCi0gTUFOWSBDT1NNRVRJQyBDSEFOR0VTCgojIyMgQnVnIGZpeGVzCgotIEFkZGVkIGEgY2hlY2sgZm9yIGxldHRlciBjYXNlIG9mIFwqLmRjbSBhbmQgXCouaW1hIGZpbGVzIGluIGBESUNPTVJlYWQubWAgYW5kIGBTaWVtZW5zRElDT01SZWFkLm1gCiAgKGBkaXIoKWAgaXMgY2FzZS1zZW5zaXRpdmUgaW4gTGludXgpCi0gQWRkZWQgYSBmaXggdG8gYXZvaWQgYW4gZXJyb3Igd2hlcmUgTUFUTEFCIHRyaWVkIHRvIGNsb3NlIGZpZ3VyZXMgZm9sbG93aW5nIGFuIHVucmVsYXRlZCBpbnRlcm5hbAogIGVycm9yLCBidXQgbm8gZmlndXJlcyB3ZXJlIGNyZWF0ZWQKLSBGaXhlZCBhIGJ1ZyBpbiBgTklmVElNUlNSZWFkLm1gIHRoYXQgbGVkIHRvIGFuIGVycm9yIGlmIHRoZSBgTWFudWZhY3R1cmVyYCBmaWVsZCBpcyBub3QgZm91bmQgaW4KICB0aGUgZGF0YSBmaWxlIGhlYWRlcgotIElmIGBleHBvcnRfZmlnLm1gIGNhbm5vdCBiZSBmb3VuZCBvbiB0aGUgc2VhcmNoIHBhdGggYW5kIGBhcHBlbmRgIGhhcyBiZWVuIGZsYWdnZWQgaW4KICBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCwgaXQgaXMgbWFkZSBjbGVhciB0byB0aGUgdXNlciB0aGF0IFBERnMgd2lsbCBiZSBzYXZlZCBzZXBhcmF0ZWx5Ci0gRml4ZWQgYnVncyBpbiBgQWxpZ25Vc2luZ0gyTy5tYAotIEZpeGVkIGEgYnVnIGluIGBTaWVtZW5zRElDT01SZWFkLm1gIHdoZXJlIGFuIGVycm9yIG9jY3VycmVkIGlmIGBjZW50ZXJGcmVxYCBpcyBub3QgZm91bmQgaW4gdGhlCiAgZGF0YSBmaWxlIGhlYWRlcgoKIyMgMy4zLjAKPHNwYW4gc3R5bGU9ImNvbG9yOiBncmV5OyI+MjAyMi0xMC0yMjwvc3Bhbj4KCiMjIyBOZXcgZmVhdHVyZXMKLSBBZGRlZCBmdW5jdGlvbmFsaXR5IHRvIHJlYWQgTklmVEktTVJTIGZpbGVzICg8YSBocmVmPSJodHRwczovL29ubGluZWxpYnJhcnkud2lsZXkuY29tL2RvaS8xMC4xMDAyL21ybS4yOTQxOCIgdGFyZ2V0PSJfYmxhbmsiPkNsYXJrZSBldCBhbC4sIE1STSwgMjAyMjwvYT4pIChgTklmVElNUlNSZWFkLm1gKTsgaW5jbHVkZXMgYWRkaXRpb25hbCBuZXcgZnVuY3Rpb24gYEdhbm5ldE1hc2tfTklmVEkubWAgZm9yIHZveGVsIGNvLXJlZ2lzdHJhdGlvbgotIEFkZGVkIHN1cHBvcnQgZm9yIFV0YWggU2llbWVucyBNRUdBLVBSRVNTIHNlcXVlbmNlIChESUNPTSBmaWxlcykKLSBBZGRlZCBzdXBwb3J0IGZvciBDTVJSIFBSRVNTIGRhdGEgKERJQ09NIGZpbGVzKQotIEFkZGVkIHN1cHBvcnQgZm9yIFNpZW1lbnMgWEEzMCBzZXF1ZW5jZSBhcyBwcm92aWRlZCBieSBKSFUKLSBDaGFuZ2VkIGBSRUFETUVgIHRvIGBSRUFETUUubWRgLCB3aGljaCBub3cgaW5jbHVkZXMgYmFkZ2VzCgojIyMgTWFqb3IgY2hhbmdlcwotIENvaWwgY29tYmluYXRpb24gb2YgR0UsIE5JZlRJLU1SUywgYW5kIFNpZW1lbnMgVFdJWCBmaWxlcyBpcyBub3cgcGVyZm9ybWVkIHVzaW5nIGdlbmVyYWxpemVkIGxlYXN0IHNxdWFyZXMgKDxhIGhyZWY9Imh0dHBzOi8vb25saW5lbGlicmFyeS53aWxleS5jb20vZG9pLzEwLjEwMDIvam1yaS4yMzk0MSIgdGFyZ2V0PSJfYmxhbmsiPkFuIGV0IGFsLiwgSk1SSSwgMjAxMzwvYT4pOyB0aGlzIGFwcHJvYWNoIGhhcyBiZWVuIHNob3duIHRvIHJlc3VsdCBpbiBvcHRpbWFsIFNOUiBhbmQgcmVkdWNlIHNwZWN0cmFsIGFydGlmYWN0cwotIFRoZSBHYW5uZXQgbG9nbyBoYXMgYmVlbiByZXZlcnRlZCB0byB0aGUgb3JpZ2luYWwgaW1hZ2Ugb2YgYSBnYW5uZXQKCiMjIyBNaW5vciBjaGFuZ2VzCi0gQWRkZWQgZnVuY3Rpb25hbGl0eSBmb3IgR0UgZGF0YSBpbiBgQWxpZ25TdWJTcGVjdHJhX1ByZUFsaWduUmVmLm1gCi0gQW4gZXJyb3IgaXMgcHJlc2VudGVkIGlmIG5vdCBlbm91Z2ggaW5wdXRzIGFyZSBnaXZlbiBmb3IgYW55IG9mIHRoZSBHYW5uZXQgbW9kdWxlcwotIENvUmVnU3RhbmRBbG9uZSBvdXRwdXRzIGNhbiBiZSBoaWRkZW4gaWYgYE1SU19zdHJ1Y3QucC5oaWRlYCBpcyBzZXQgdG8gYDFgIGluIGBDb1JlZ1N0YW5kQWxvbmUubWAgKGRlZmF1bHQgaXMgYDBgKQotIElmIHRoZSB1c2VyIGhhcyBubyBpbnRlcm5ldCBjb25uZWN0aW9uLCBgVmVyc2lvbkNoZWNrLm1gIGFuZCBgVXBkYXRlR2FubmV0Lm1gIHdpbGwgbm90IHJ1bgotIFVwZGF0ZWQgZGljbTJuaWkgdG8gbGF0ZXN0IHZlcnNpb24gKHZlcnNpb24gMjAyMi4wOS4xNSkKLSBVcGRhdGVkIG1hcFZCVkQgZnVuY3Rpb25zIHRvIGxhdGVzdCB2ZXJzaW9uICg8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vcGVoc2VzL21hcFZCVkQiIHRhcmdldD0iX2JsYW5rIj5odHRwczovL2dpdGh1Yi5jb20vcGVoc2VzL21hcFZCVkQ8L2E+KQotIFR1cm5lZCBvZmYgd2FybmluZ3Mgb2YgaXRlcmF0aW9uIGxpbWl0cyBpbiBgU3BlY3RyYWxSZWdpc3RyYXRpb25IRVJNRVMubWAgYW5kIGBHYW5uZXRGaXQubWAKLSBNYW55IGNvc21ldGljIGNoYW5nZXMgaW4gdGhlIGNvZGUKCiMjIyBCdWcgZml4ZXMKLSBGaXhlZCBidWcgaW4gZXJyb3IgcmVwb3J0aW5nIGluIGBHYW5uZXRGaXQubWAKLSBDb1JlZ1N0YW5kQWxvbmUgcm91dGluZXMgbm93IHBhcnNlIHZlcnNpb24gbnVtYmVycyBmcm9tIHRoZSBtYWluIG1vZHVsZXMgcHJvcGVybHkKLSBWYXJpYWJsZSBgZmlsZXNFeGlzdGAgaW4gYEdhbm5ldFNlZ21lbnQubWAgbWF5IG5vdCBwb3B1bGF0ZTsgaXQgaXMgbm93IHByZS1pbml0aWFsaXplZCBhcyBhIHByZWNhdXRpb24KLSBCdWcgZml4IGluIGBHYW5uZXRNYXNrX1NpZW1lbnNSREEubWAKLSBCdWcgZml4ZXMgZm9yIHJlYWRpbmcgRElDT00gZmlsZXMKCiMjIDMuMi4xCjxzcGFuIHN0eWxlPSJjb2xvcjogZ3JleTsiPjIwMjItMDYtMDc8L3NwYW4+CgojIyMgTWlub3IgY2hhbmdlcwotIGBQaGFzZUNvcnJlY3Rpb24ubWAgbm93IGRlYWxzIGJldHRlciB3aXRoIHNwZWN0cmEgdGhhdCBoYXZlIGEgbm9uLXplcm8gYmFzZWxpbmUKLSBTUE0xMiBub3cgb3V0cHV0cyBmb3J3YXJkIGRlZm9ybWF0aW9uIGZpZWxkIChuZWVkZWQgZm9yIG5vcm1hbGl6aW5nIHZveGVsIG1hc2tzIHRvIE1OSSBzcGFjZSkKLSBVcGRhdGVkIGBleHBvcnRfZmlnYCB0byB2My4yNwotIGBDb1JlZ1N0YW5kQWxvbmUubWAgbm93IGV4cG9ydHMgYSBDU1YgZmlsZQotIFZhcmlvdXMgY29zbWV0aWMgY2hhbmdlcwoKIyMjIEJ1ZyBmaXhlcwotIEZpeGVkIHN1Yi1zcGVjdHJhIGFsaWdubWVudCBmb3IgR0UgSEVSQ1VMRVMgZGF0YQotIEZpeGVkIGJ1ZyBpbiBgQ29SZWdTdGFuZEFsb25lLm1gCi0gRml4ZWQgYnVnIGluIGByZWFkX2RjbV9oZWFkZXIubWAgKHRoYW5rcyB0byBNZXJlZGl0aCBSZWlkKQoKPGJyPgoKIyMgMy4yLjAKPHNwYW4gc3R5bGU9ImNvbG9yOiBncmV5OyI+MjAyMS0wNy0zMDwvc3Bhbj4KCiMjIyBOZXcgZmVhdHVyZXMKCi0gQWRkZWQgYEdhbm5ldFZlcnNpb24ubWAsIGBWZXJzaW9uQ2hlY2subWAsIGFuZCBgVXBkYXRlR2FubmV0Lm1gOyB0aGVzZSBuZXcgZnVuY3Rpb25zIGxldCB1c2VycyBrbm93IHRoZSB2ZXJzaW9uIG9mIEdhbm5ldCB0aGV5IGhhdmUsIGlmIGEgbmV3ZXIgcmVsZWFzZSBvZiBHYW5uZXQgaXMgYXZhaWxhYmxlLCBhbmQgd2lsbCBhbGxvdyB0aGVtIHRvIGF1dG9tYXRpY2FsbHkgdXBkYXRlIGlmIHdhbnRlZAotIEFkZGVkIGBUb29sYm94Q2hlY2subWAgdG8gY2hlY2sgZm9yIG1pc3NpbmcgTUFUTEFCIHRvb2xib3hlcyBuZWVkZWQgdG8gcnVuIEdhbm5ldAotIEVycm9yIGRpYWxvZyBib3hlcyBhcmUgZGlzcGxheWVkIGF0IHRoZSBlbmQgb2YgdGhlIGFuYWx5c2lzIHBpcGVsaW5lIGlmIGFuIGVycm9yIG9jY3VycmVkIChkdXJpbmcgYSBiYXRjaCBhbmFseXNpcywgR2FubmV0IHdpbGwgc2tpcCB0byB0aGUgbmV4dCBkYXRhc2V0IGFuZCBjb250aW51ZSBydW5uaW5nKQotIFVzZXJzIGNhbiBub3cgY2hvb3NlIHRvIHVzZSB3ZWlnaHRlZCAodGhlIGRlZmF1bHQpIG9yIGNvbnZlbnRpb25hbCBzaWduYWwgYXZlcmFnaW5nIGluIGBHYW5uZXRQcmVJbml0aWFsaXNlLm1gIChvdXRsaWVyIHNjYW5zIGFyZSByZW1vdmVkIHdoZW4gdXNpbmcgY29udmVudGlvbmFsIGF2ZXJhZ2luZywgYXMgYmVmb3JlKQotIEFkZGVkIGEgbmV3IChvcHRpb25hbCkgbWV0aG9kIGZvciByb2J1c3QsIHdlaWdodGVkIHNpZ25hbCBhdmVyYWdpbmc6IHdlaWdodGVkIGF2ZXJhZ2luZyBieSBjcml0ZXJpb24gZnVuY3Rpb24gbWluaW1pemF0aW9uIChXQUNGTSkgdXNpbmcgdGhlIGdlbmVyYWxpemVkIENhdWNoeSBkaXN0cmlidXRpb24gYXMgdGhlIGNvc3QgZnVuY3Rpb247IHNlZSBkb2k6PGEgaHJlZj0iaHR0cHM6Ly9keC5kb2kub3JnLzEwLjEwMTYvai5iYmUuMjAxNS4wNi4wMDIiIHRhcmdldD0iX2JsYW5rIj4xMC4xMDE2L2ouYmJlLjIwMTUuMDYuMDAyPC9hPiBmb3IgbW9yZSBkZXRhaWxzOyBhZGRpdGlvbmFsbHksIGluc3RlYWQgb2Ygd2VpZ2h0aW5nIGRpZmZlcmVuY2UgcGFpcnMsIHRoZSBzdWJzcGVjdHJhIG9mIGVhY2ggZWRpdGluZyBzdWJleHBlcmltZW50IGFyZSB3ZWlnaHRlZCB0byBnZW5lcmF0ZSB3ZWlnaHRlZCBzdWJzcGVjdHJhLCB3aGljaCBhcmUgdGhlbiBzdWJ0cmFjdGVkOyBzZWUgYFNpZ25hbEF2ZXJhZ2luZy5tYAotIFlhaXIgQWx0bWFuJ3MgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2FsdG1hbnkvZXhwb3J0X2ZpZyIgdGFyZ2V0PSJfYmxhbmsiPmV4cG9ydF9maWcgdG9vbGJveDwvYT4gaXMgaW5jbHVkZWQgYXMgYW4gb3B0aW9uYWwgdG9vbGJveCB0aGF0LCBpZiBhZGRlZCB0byBNQVRMQUIncyBzZWFyY2ggcGF0aCwgR2FubmV0IHdpbGwgdXNlIHRvIGFwcGVuZCBhbGwgb3V0cHV0IFBERnMgZnJvbSBlYWNoIG1vZHVsZSBpbnRvIGEgc2luZ2xlIFBERiAoYSBmbGFnIG11c3QgYmUgc2V0IGluIGBHYW5uZXRQcmVJbml0aWFsaXNlLm1gIHRvIGRvIHRoaXMpOyB0aGlzIGlzIHZlcnkgdXNlZnVsIGZvciBlYXN5IFFBIG9mIGxvdHMgb2YgZGF0YTsgbm90ZSB0aGF0IDxhIGhyZWY9Imh0dHBzOi8vd3d3Lmdob3N0c2NyaXB0LmNvbS8iIHRhcmdldD0iX2JsYW5rIj5HaG9zdHNjcmlwdDwvYT4gbmVlZHMgdG8gYmUgaW5zdGFsbGVkIGZvciB0aGUgYXBwZW5kaW5nIG9mIFBERnMgdG8gd29yayAoTkI6IG1hY09TIHVzZXJzIHNob3VsZCB1c2UgdGhpcyA8YSBocmVmPSJodHRwczovL3BhZ2VzLnVvcmVnb24uZWR1L2tvY2gvIiB0YXJnZXQ9Il9ibGFuayI+dmVyc2lvbjwvYT4gb3IgdXNlIDxhIGhyZWY9Imh0dHBzOi8vZm9ybXVsYWUuYnJldy5zaC9mb3JtdWxhL2dob3N0c2NyaXB0IiB0YXJnZXQ9Il9ibGFuayI+SG9tZWJyZXc8L2E+IHRvIGluc3RhbGwgR2hvc3RzY3JpcHQpCi0gSW1wbGVtZW50ZWQgdXNlIG9mIGh5cGVybGlua3MgaW4gaW5mbyBhbmQgZXJyb3IgbWVzc2FnZXMgcHJpbnRlZCBpbiB0aGUgY29tbWFuZCB3aW5kb3cgc28gdGhhdCB1c2VycyBjYW46ICgxKSBkaXJlY3RseSBydW4gYSBjZXJ0YWluIGZ1bmN0aW9uIChzdWNoIGFzIGBVcGRhdGVHYW5uZXQubWAgd2hlbiBgVmVyc2lvbkNoZWNrLm1gIGluZm9ybXMgdGhlIHVzZXIgYSBuZXcgcmVsZWFzZSBpcyBhdmFpbGFibGUpOyAoMikgZ28gc3RyYWlnaHQgdG8gdGhlIGxpbmUgb2YgY29kZSB3aGVyZSBhbiBlbmNvdW50ZXJlZCBlcnJvciBjYW4gYmUgZml4ZWQgKHN1Y2ggYXMgZXJyb3JzIGluIGBHYW5uZXRQcmVJbml0aWFsaXNlLm1gKTsgb3IgKDMpIGdvIHRvIGEgd2Vic2l0ZSBieSBjbGlja2luZyBvbiB0aGUgcHJpbnRlZCBVUkwgKHN1Y2ggYXMgdG8gZG93bmxvYWQgU1BNMTIpOyB0aGUgcmVsZXZhbnQgY29kZSBoYXMgYmVlbiBib3Jyb3dlZCBmcm9tIGV4cG9ydF9maWcKLSBBZGRlZCBhbiBvcHRpb24gaW4gYEdhbm5ldFByZUluaXRpYWxpc2UubWAgdGhhdCBhbGxvd3MgdXNlcnMsIHdoZW4gdXNpbmcgcm9idXN0IHNwZWN0cmFsIHJlZ2lzdHJhdGlvbiwgdG8gdXNlIHRoZSBhdmVyYWdlZCBwcmUtYWxpZ25lZCBzdWJzcGVjdHJhIGFzIHJlZmVyZW5jZXMgZm9yIGFsaWduaW5nIHRoZSBhdmVyYWdlZCBwb3N0LWFsaWduZWQgc3Vic3BlY3RyYSAodGhpcyBtYXkgYmUgaGVscGZ1bCB3aGVuIHJvYnVzdCBzcGVjdHJhbCByZWdpc3RyYXRpb24gbWFrZXMgdGhlIGFsaWdubWVudCBvZiBhbHJlYWR5IGdvb2QtcXVhbGl0eSBwcmUtYWxpZ25lZCBzcGVjdHJhIHdvcnNlKQotIGBQYXBlclBsb3QubWAgbm93IGFsbG93cyB1c2VycyB0byBwbG90IGFuIGV4ZW1wbGFyeSB2b3hlbCBtYXNrIGNvLXJlZ2lzdGVyZWQgdG8gdGhlIHJlc3BlY3RpdmUgc3RydWN0dXJhbCBpbWFnZQotIEFkZGVkIGBHYW5uZXRNYXNrX0dFX25paS5tYDsgR0UgdXNlcnMgY2FuIG5vdyB1c2UgTklmVEkgaW1hZ2VzIGluc3RlYWQgb2YgRElDT01zIHRvIGNvLXJlZ2lzdGVyIHRoZWlyIE1SUyB2b3hlbHMgdG8gc3RydWN0dXJhbCBpbWFnZXMKLSBBZGRlZCB0aGUgYWJpbGl0eSB0byB0cmltIGRhdGFzZXRzCi0gRXh0ZW5kZWQgdGhlIGFiaWxpdHkgdG8gY29uY2F0ZW5hdGUgZmlsZXMsIGluY2x1ZGluZyBvdmVyIG11bHRpcGxlIHN1YmplY3RzCi0gQWRkZWQgYSBmbGFnIGluIGBHYW5uZXRQcmVJbml0aWFsaXNlLm1gIChgTVJTX3N0cnVjdC5wLmhpZGVgKSB0byBwcmV2ZW50IG91dHB1dCBmaWd1cmVzIGZyb20gZGlzcGxheWluZyAodXNlZnVsIHdoZW4gcHJvY2Vzc2luZyBhIGxhcmdlIGJhdGNoIG9mIGZpbGVzKQoKIyMjIE1ham9yIGNoYW5nZXMKCi0gVGhlIG91dGRhdGVkIG1hbnVhbCBQREYgaGFzIGJlZW4gcmVtb3ZlZDsgdXAtdG8tZGF0ZSBzb2Z0d2FyZSBkb2N1bWVudGF0aW9uIHdpbGwgbm93IGJlIGZvdW5kIG9ubGluZTogaHR0cHM6Ly9tYXJrbWlra2Vsc2VuLmdpdGh1Yi5pby9HYW5uZXQtZG9jcy9pbmRleC5odG1sCi0gR2FubmV0IGlzIG5vdyBsaWNlbnNlZCB1bmRlciB0aGUgQlNEIDMtQ2xhdXNlIExpY2Vuc2UKLSBBbHBoYSB0aXNzdWUgY29ycmVjdGlvbiBpcyBub3cgcGVyZm9ybWVkIG9uIGEgYnktbWV0YWJvbGl0ZSBiYXNpcyByYXRoZXIgdGhhbiBmaXhpbmcgdGhlIGludHJpbnNpYyBXTTpHTSBjb25jZW50cmF0aW9uIHRvIDE6MiAoYWxwaGEpIGZvciBhbGwgbWV0YWJvbGl0ZXMgKGFzc3VtaW5nIGZvciBub3cgdGhlIHJhdGlvIGlzIDE6MiBmb3IgR0FCQSBhbmQgR2x4IGFuZCAxOjEgZm9yIEdTSCwgRXRPSCBhbmQgTGFjKTsgdGhlIGFscGhhIHRoYXQgaXMgYXNzdW1lZCBpcyBkaXNwbGF5ZWQgaW4gdGhlIEdhbm5ldFF1YW50aWZ5IG91dHB1dCBmaWd1cmUKLSBSZW1vdmVkIGBNUlNfc3RydWN0LnAuT05fT0ZGX29yZGVyYCBmcm9tIGBHYW5uZXRQcmVJbml0aWFsaXNlLm1gOyB0aGUgb3JkZXIgb2YgZWRpdGluZyBwdWxzZXMgaXMgbm93IGRldGVybWluZWQgYXV0b21hdGljYWxseTsgdGhlIHJlbGV2YW50IGNvZGUgaGFzIGJlZW4gYm9ycm93ZWQgZnJvbSBPc3ByZXkgKHRoaXMgaGFzIG9ubHkgYmVlbiB0ZXN0ZWQgdG8gYSBsaW1pdGVkIGV4dGVudCBzbyBtYXkgcmVxdWlyZSBmdXJ0aGVyIHR3ZWFraW5nKQotIFRoZSBleGNlcHRpb24gdG8gdGhpcyBjaGFuZ2UgaXMgcGhhbnRvbSBkYXRhLCB3aGVyZSB1c2VycyB3aWxsIHN0aWxsIG5lZWQgdG8gc3BlY2lmeSB0aGUgb3JkZXIgb2YgZWRpdGluZyBwdWxzZXMKCiMjIyBNaW5vciBjaGFuZ2VzCgotIERhdGFzZXRzIHdpdGggZGlmZmVyaW5nIG51bWJlciBvZiBhdmVyYWdlcyBjYW4gbm93IGJlIGJhdGNoLXByb2Nlc3NlZCB0b2dldGhlcgotIFR1cm5lZCBvZmYgdGhlIHByb2dyZXNzIGJhciBkaXNwbGF5ZWQgd2hlbiBsb2FkaW5nIFNpZW1lbnMgVFdJWCBkYXRhIHRvIHJlZHVjZSBsb2FkaW5nIHRpbWUKLSBSZW5hbWVkIHNvbWUgZmlsZXMgZm9yIHRoZSBzYWtlIG9mIGNsYXJpdHkgYW5kIHN0eWxlOyByZW1vdmVkIG9ic29sZXRlIGBHYW5uZXRNYXNrLm1gCi0gU2lnbmFsIGF2ZXJhZ2luZyBhbmQgc3VidHJhY3Rpb24gYXJlIG5vdyBkb25lIGluIHRoZSBuZXcgZnVuY3Rpb24gYFNpZ25hbEF2ZXJhZ2luZy5tYAotIFZhcmlvdXMgaW1wcm92ZW1lbnRzIHRvIGBSb2J1c3RTcGVjdHJhbFJlZ2lzdHJhdGlvbi5tYCAoZm9ybWVybHkgYFJvYnVzdF9TcGVjdHJhbF9SZWdpc3RyYXRpb24ubWApIGZvciBiZXR0ZXIgaGFuZGxpbmcgb2YgZGF0YSBhY3F1aXJlZCB1c2luZyB2ZXJ5IHN0cm9uZyB3YXRlciBzdXBwcmVzc2lvbgotIFRoZSBhc3N1bWVkIGNvbmNlbnRyYXRpb24gb2YgcHVyZSB3YXRlciBpbiBgR2FubmV0Rml0Lm1gIGFuZCBgR2FubmV0Rml0UGhhbnRvbS5tYCAoUHVyZVdhdGVyQ29uYykgaGFzIGJlZW4gY2hhbmdlZCBmcm9tIDU1IHRvIDU1LjUxIG1vbC9rZzsgdGhpcyBwdXRzIGl0IGluIGxpbmUgd2l0aCB0aGUgc2FtZSBjb25zdGFudCB1c2VkIGluIGBHYW5uZXRRdWFudGlmeS5tYAotIEFkZGVkIGVkaXRzIGZyb20gUmFscGggTm9lc2tlIChHRSBCZXJsaW4pIHRvIGBHRVJlYWQubWAgZm9yIGJldHRlciBoYW5kbGluZyBvZiBkYXRhIHdoZW4gbmVjaG9lcyA9PSAxOyBhbHNvIGNoYW5nZWQgdGhlIHNjYWxpbmcgZmFjdG9yIGlmIG5lY2hvZXMgPiAxIChob3BlZnVsbHkgdGhpcyBtYWtlcyB3YXRlci1yZWZlcmVuY2VkIG1lYXN1cmVtZW50cyBjb25zaXN0ZW50IGFjcm9zcyBhbGwgZGF0YSBlbmNvZGluZyBmbGF2b3JzKQotIEluIGBHRVJlYWQubWAgYW5kIGBQaGlsaXBzUmVhZF9kYXRhLm1gLCBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBmaXJzdCBwb2ludCBpbiB0aGUgRklEIGZvciBzaWduYWwgd2VpZ2h0aW5nLCB0aGUgbW9zdCBjb21tb24gcG9pbnQgdGhhdCBpcyB0aGUgbWF4IGluIHRoZSBtYWduaXR1ZGUgc2lnbmFsIGFjcm9zcyBhbGwgRklEcyBpcyBub3cgdXNlZAotIFNvbWUgY2hhbmdlcyB0byBgU2llbWVuc0RJQ09NUmVhZC5tYCBhbmQgYERJQ09NUmVhZC5tYCBmb3Igc21hcnRlciBoYW5kbGluZyBvZiBkYXRhIGZpbGVzOiBmb3IgZWFjaCBkYXRhc2V0LCBtZXRhYm9saXRlIGFuZCB3YXRlciBkYXRhIGZpbGVzIHNob3VsZCBiZSBzdG9yZWQgaW4gc2VwYXJhdGUgZm9sZGVycwotIEltcHJvdmVkIGBFeHBvcnRUb0NTVi5tYDsgYSBzaW5nbGUgLmNzdiBmaWxlIGlzIG5vdyBleHBvcnRlZCBmb3IgSEVSTUVTIGRhdGFzZXRzOyB1c2VmdWwgdmFyaWFibGVzIHN1Y2ggYXMgc2lnbmFsIGFyZWFzIGFuZCBDciBmaXQgcXVhbGl0eSBtZXRyaWNzIGFyZSBub3cgYWxzbyBleHBvcnRlZAotIFJld3JvdGUgYERpc2Nlcm5EYXRhVHlwZS5tYCAoZm9ybWVybHkgYEdhbm5ldERpc2Nlcm5EYXRhdHlwZS5tYCkKLSBNaW5vciBjaGFuZ2VzIGFuZCBpbXByb3ZlbWVudHMgdG8gYFBhcGVyUGxvdC5tYAotIE1pbm9yIGNoYW5nZXMgdG8gYENvUmVnU3RhbmRBbG9uZS5tYCBmdW5jdGlvbnMKLSBNaW5vciBjaGFuZ2VzIHRvIGBTaWduYWxGaWx0ZXIubWAKLSBTaW1wbGlmaWVkIGBFZGR5Q3VycmVudENvcnJlY3Rpb24ubWAgKGZvcm1lcmx5IGBwaGFzZV9jb3JyZWN0aW9uX2ZpZHMubWApCi0gU2V0IHVwIFNQTTEyIGZvciBiYXRjaCB0aXNzdWUgc2VnbWVudGF0aW9uIG9ubHkgd2hlbiB0aXNzdWUgc2VnbWVudGF0aW9uIGhhcyBub3QgYWxyZWFkeSBiZWVuIHJ1biBhbmQgZG8gaXQgb25seSBvbmNlIGluIGEgYmF0Y2gKLSBBbGxGcmFtZXNGVCAoZm9yIHRoZSBsYXN0IGxvYWRlZCBkYXRhc2V0KSBpcyBub3cgYWxzbyBzYXZlZCBpbiBgTVJTX3N0cnVjdC5zcGVjYAotIFdoZW4gc2F2aW5nIHRoZSBgTVJTX3N0cnVjdGAgc3RydWN0dXJlLCB0aGUgLm1hdCBmaWxlIGlzIG5vdyBzYXZlZCB1c2luZyB2ZXJzaW9uIDcuMyAoZm9yIHRoZSByYXJlIGNhc2Ugd2hlbiB0aGUgc3RydWN0dXJlIGlzID49IDIgR0Igb24gNjQtYml0IGNvbXB1dGVycykKLSBSZW1vdmVkIGBNUlNfc3RydWN0LnAuc2RhdGAgZnJvbSBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgY29kZSBmcm9tIGBHYW5uZXRMb2FkLm1gICh0aGlzIGZlYXR1cmUgd2FzIG5ldmVyIHJlYWxseSB1c2VkIGJ5IHVzZXJzIGFmYWlrKQotIEltcHJvdmVkIGdsb2JhbCB6ZXJvLW9yZGVyIHBoYXNpbmcgaW4gYFNwZWN0cmFsUmVnaXN0cmF0aW9uSEVSTUVTLm1gCi0gTWFueSBjb3NtZXRpYy9hZXN0aGV0aWMgY2hhbmdlcwogIC0gVGhlIG1vZHVsZSBvdXRwdXQgZmlndXJlcyBub3cgc2hvdyBpbmZvcm1hdGlvbiB1c2VmdWwgZm9yIHJlcG9ydGluZyBhY3F1aXNpdGlvbiBwYXJhbWV0ZXJzIGFuZCByZXN1bHRzIChpbiBsaW5lIHdpdGggdGhlIDxhIGhyZWY9Imh0dHBzOi8vb25saW5lbGlicmFyeS53aWxleS5jb20vZG9pLzEwLjEwMDIvbmJtLjQ0ODQiIHRhcmdldD0iX2JsYW5rIj5NUlNpbk1SUzwvYT4gY2hlY2tsaXN0KQogIC0gQ28tcmVnaXN0ZXJlZC9zZWdtZW50ZWQgdm94ZWwgbWFza3MgZGlzcGxheWVkIGluIEdhbm5ldENvUmVnaXN0ZXIsIEdhbm5ldFNlZ21lbnQsIGFuZCBHYW5uZXRRdWFudGlmeSBvdXRwdXQgZmlndXJlcyBhcmUgbm93IHNob3duIGluIHllbGxvdyByYXRoZXIgdGhhbiBncmF5c2NhbGUKICAtIFNtYXJ0ZXIgc3RhY2tpbmcgb2YgSEVSTUVTIGRpZmZlcmVuY2Ugc3BlY3RyYSBpbiBgUGxvdFByZVBvc3RBbGlnbi5tYCBhbmQgYFBsb3RQcmVQb3N0QWxpZ24yLm1gIChmb3JtZXJseSBgR2FubmV0UGxvdFByZVBvc3RBbGlnbi5tYCBhbmQgYEdhbm5ldFBsb3RQcmVQb3N0QWxpZ24yLm1gKQogIC0gVGhlIEdhbm5ldCBkb2N1bWVudGF0aW9uIHdlYnNpdGUgVVJMIGlzIHByaW50ZWQgYXQgdGhlIGJvdHRvbSBvZiBldmVyeSBvdXRwdXQgZmlndXJlCiAgLSBSZW1vdmVkIGlycmVsZXZhbnQgbWVzc2FnZXMgZnJvbSBiZWluZyBwcmludGVkIGluIHRoZSBjb21tYW5kIHdpbmRvdyBkdXJpbmcgdGhlIGFuYWx5c2lzIHBpcGVsaW5lLCByZXBsYWNpbmcgdGhlbSB3aXRoIG1vcmUgdXNlZnVsIG1lc3NhZ2VzCiAgLSBNaW5vciByZWFycmFuZ2luZyBvZiByZXN1bHRzIHRleHQgaW4gR2FubmV0U2VnbWVudCBhbmQgR2FubmV0UXVhbnRpZnkgb3V0cHV0IGZpZ3VyZXMKICAtIFNsaWdodCBjaGFuZ2UgdG8gdGhlIHktYXhpcyBsYWJlbHMgb2YgdGhlIENyIGZyZXF1ZW5jeSBzcGVjdHJvZ3JhbSBpbiB0aGUgR2FubmV0TG9hZCBvdXRwdXQgZmlndXJlCiAgLSBCZXR0ZXIgcmVvcmRlcmluZyBvZiBgTVJTX3N0cnVjdC5vdXRgIHN1YmZpZWxkcyBjcmVhdGVkIGluIGBHYW5uZXRGaXQubWAKCiMjIyBCdWcgZml4ZXMKCi0gRnJlcXVlbmN5IGFuZCBwaGFzZSBvZmZzZXQgZXN0aW1hdGVzIGFyZSBub3cgdHJhY2tlZCBjb3JyZWN0bHkgYW5kIHNhdmVkIHdoZW4gcnVubmluZyBhbnkgb2YgdGhlIHNwZWN0cmFsIHJlZ2lzdHJhdGlvbi1iYXNlZCBhbGlnbm1lbnQgbWV0aG9kcwotIFJlbW92ZWQgb2xkIGRlYnVnZ2luZyBjb25kaXRpb25hbCBzdGF0ZW1lbnQgaW4gYFRXSVhEZUlkZW50aWZ5Lm1gCi0gRXhwbGljaXRseSBzcGVjaWZ5IGNvbG9yIG9mIHdhdGVyIGZyZXF1ZW5jeSB0cmFjZSBpbiBHYW5uZXRMb2FkIG91dHB1dCBmaWd1cmUgYXMgdGhlcmUgYXBwZWFycyB0byBiZSBhIGJ1ZyBzaW5jZSBNQVRMQUIgUjIwMTliIHdoZW4gdXNpbmcgaG9sZCB0byBvdmVybGF5IHBsb3RzCi0gQWRkZWQgRXRPSCBzaWduYWwgcGFyYW1ldGVycyB0byBgR2FubmV0UXVhbnRpZnkubWAKLSBJbiBgU2llbWVuc1R3aXhSZWFkLm1gLCBpZiBubyB3YXRlciByZWZlcmVuY2UgaXMgcHJvdmlkZWQsIHVzZSB0aGUgbW9zdCBjb21tb24gcG9pbnQgdGhhdCBpcyB0aGUgbWF4IGluIHRoZSBtYWduaXR1ZGUgc2lnbmFsIGFjcm9zcyBhbGwgRklEcyBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgdGhlIGZpcnN0IHBvaW50Ci0gRml4ZWQgYW4gb3JpZW50YXRpb24gcHJvYmxlbSBpbiBgR2FubmV0TWFza19HRS5tYAotIFJlbW92ZWQgdW5uZWNlc3NhcnkgY29tcGxleCBjb25qdWdhdGUgdHJhbnNwb3NlIGR1cmluZyBGRlQgb2Ygd2F0ZXIgZGF0YSBpbiBgR2FubmV0TG9hZC5tYAotIFR1cm5lZCBvZmYgd2FybmluZ3MgYWJvdXQgbGVnYWN5IG51bWJlciBnZW5lcmF0b3IgaW4gYFJvYnVzdFNwZWN0cmFsUmVnaXN0cmF0aW9uLm1gIChmb3Igd2hlbiBybmcgYW5kIHJhbmRuIGFyZSBydW4gaW4gYFNpZ25hbEZpbHRlci5tYCkgaWYgdGhleSBhcmUgYWxyZWFkeSB0dXJuZWQgb24KCjxicj4KCiMjIDMuMS41CjxzcGFuIHN0eWxlPSJjb2xvcjogZ3JleTsiPjIwMjAtMDMtMDI8L3NwYW4+CgojIyMgTmV3IGZlYXR1cmVzCgotIFNtYXJ0ZXIgY2hlY2tpbmcgb2YgaW5jb3JyZWN0IHNldHRpbmdzIGluIGBHYW5uZXRQcmVJbml0aWFsaXNlLm1gIGJ5IGBDaGVja1RhcmdldHMubWAKLSBNYWpvciBjaGFuZ2VzIHRvIGBHYW5uZXRGaXRQaGFudG9tLm1gIHRvIGJyaW5nIGl0IG1vcmUgaW4gbGluZSB3aXRoIGBHYW5uZXRGaXQubWAKLSBBZGRlZCBzdXBwb3J0IGZvciBDTVJSIE1FR0Etc0xBU0VSIHNlcXVlbmNlIGluIGBTaWVtZW5zVHdpeFJlYWQubWAKLSBJbiBgU3ViU3BlY3RyYWxBbGlnbi5tYCwgaWYgdmVyeSBzdHJvbmcgd2F0ZXIgc3VwcHJlc3Npb24gd2FzIHVzZWQsIHVzZSBDaG8gaW5zdGVhZCBvZiByZXNpZHVhbCB3YXRlciB0byBhbGlnbiBzdWJzcGVjdHJhIG9mIEdBQkEtLCBMYWMtLCBhbmQgRXRPSC1lZGl0ZWQgZGF0YXNldHMKCiMjIyBNaW5vciBjaGFuZ2VzCgotIE5vaXNlIGVzdGltYXRpb24gaW4gYENhbGNOb2lzZS5tYCwgYFJvYnVzdF9TcGVjdHJhbF9SZWdpc3RyYXRpb24ubWAsIGFuZCBgU2lnbmFsRmlsdGVyLm1gIGlzIG5vdyBwZXJmb3JtZWQgYmV0d2VlbiA4IGFuZCAxMCBwcG0gdG8gYWNjb3VudCBmb3IgZGF0YXNldHMgdGhhdCBoYXZlIHNob3J0ZXIgc3BlY3RyYWwgd2lkdGhzCi0gQ2xlYW5lZCB1cCBjb2RlIGluIGBHYW5uZXRGaXQubWAKLSBRdWFudGlmaWNhdGlvbiBvZiBMYWMgbm93IGV4cGxpY2l0bHkgZGVmaW5lZCBhcyBMYWMrTU0KLSBJbXByb3ZlZCBmdW5jdGlvbmFsaXR5IG9mIGBQYXBlclBsb3QubWAKLSBJbiBgU2llbWVuc1R3aXhSZWFkLm1gLCB3aGVuIGEgd2F0ZXIgcmVmZXJlbmNlIGlzIHByZXNlbnQsIGNvaWwgc2Vuc2l0aXZpdHkgYW5kIHBoYXNlIGlzIGJhc2VkIG9uIHRoZSBwb2ludCBpbmRleCB0aGF0IGlzIGF0IHRoZSB0b3Agb2YgdGhlIGVjaG8sIHJhdGhlciB0aGFuIHNpbXBseSBmaXhpbmcgaXQgdG8gdGhlIGZpcnN0IHBvaW50CgojIyMgQnVnIGZpeGVzCgotIE1pbm9yIGJ1ZyBmaXhlcyBpbiBDb1JlZ1N0YW5kQWxvbmUgZnVuY3Rpb25zCi0gQ29ycmVjdGVkIHVzZSBvZiByYW5kb20gbnVtYmVyIGdlbmVyYXRpb24gaW4gYFNpZ25hbEZpbHRlci5tYCB3aGVuIHBlcmZvcm1pbmcgbm9pc2UgcmVwbGFjZW1lbnQgdG8gZW5zdXJlIHRoZSBzYW1lIHJlc3VsdHMgYXJlIHJlcHJvZHVjZWQgZWFjaCB0aW1lIGl0IGlzIHJ1biBvbiBhIGRhdGFzZXQKCjxicj4KCiMjIDMuMS40CjxzcGFuIHN0eWxlPSJjb2xvcjogZ3JleTsiPjIwMTktMTAtMDM8L3NwYW4+CgojIyMgQnVnIGZpeAoKLSBGaXhlZCBlcnJvciBpbiB0aGUgY2FsY3VsYXRpb24gb2YgYEF2Z0RlbHRhRjBgIGZvciBNRUdBLVBSRVNTIGRhdGEKCjxicj4KCiMjIDMuMS4zCjxzcGFuIHN0eWxlPSJjb2xvcjogZ3JleTsiPjIwMTktMDgtMDY8L3NwYW4+CgojIyMgTmV3IGZlYXR1cmVzCgotIE1ham9yIGltcHJvdmVtZW50cyB0byBgUm9idXN0X1NwZWN0cmFsX1JlZ2lzdHJhdGlvbi5tYAotIFdhdmVsZXQgdG9vbGJveCBubyBsb25nZXIgcmVxdWlyZWQKLSBSYXcgZGF0YSBpcyBub3cgcGhhc2UtY29ycmVjdGVkIHByaW9yIHRvIGFsaWdubWVudAotIGBHYW5uZXRMb2FkLm1gIGFuZCBgR2FubmV0Rml0Lm1gIG5vIGxvbmdlciBjcmFzaCBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGEgYmF0Y2ggYW5hbHlzaXMKLSBBbiBlcnJvciByZXBvcnQgaXMgcHJpbnRlZCBhZnRlciB0aGUgZmluYWwgZGF0YXNldCBpcyBsb2FkZWQvZml0dGVkIHNvIHVzZXJzIGNhbiBjaGVjayB3aGljaCBkYXRhc2V0cyBmYWlsZWQKLSBBZGRlZCBzdXBwb3J0IGZvciBHRSByZXZpc2lvbiBoZWFkZXIgMjAuMDA3CgojIyMgTWlub3IgY2hhbmdlCgotIGBXYXRlcl9Qb3NpdGl2ZWAgZmxhZyBpbiBgR2FubmV0UHJlSW5pdGlhbGlzZS5tYCByZW1vdmVkCgoKCgoK


Built with R Markdown in RStudio

Copyright © 2020–2024, Mark Mikkelsen