In this short tutrial I am scripting a workflow for working with LiDAR data downloaded from Scottish Remote Sensing Portal. The aim is to process the raw LAZ files, produce visualizations and take simple measurments solely relaying on R programming language. I am looking at a 12th century motte in Cally Forrest, Galloway, in south-west Scotland. This mound was actually surveyed by Rubicon Heritage in 2012 clik here to read about the fieldwork. Now lets see how it compares with work of an armchair archaeologist

LAZ

Next, I am reading the LAZ files and clipping the point cloud to the extent of immidiate area around the motte.

grab and rotate the model !

Transect

In order to represent the height values and get idea about the profile I will draw a line across the motte.

Line

Package mapedit allows to interactively draw the line and save it as sf object.

Going 3D

And a cherry on the top by amazing rayshader package

grab and rotate the model !

## R version 4.0.0 (2020-04-24)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Mojave 10.14.6
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
## 
## attached base packages:
## [1] grid      stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] shiny_1.4.0.2    ggplot2_3.3.0    dplyr_0.8.5      smoothr_0.1.2   
##  [5] tmaptools_3.0    tmap_3.0         mapview_2.7.8    mapedit_0.6.0   
##  [9] sf_0.9-2         rgl_0.100.54     rayshader_0.15.1 lidR_2.2.3      
## [13] raster_3.1-5     sp_1.4-1        
## 
## loaded via a namespace (and not attached):
##  [1] jsonlite_1.6.1          viridisLite_0.3.0       foreach_1.5.0          
##  [4] assertthat_0.2.1        stats4_4.0.0            yaml_2.2.1             
##  [7] progress_1.2.2          pillar_1.4.3            lattice_0.20-41        
## [10] glue_1.4.0              digest_0.6.25           manipulateWidget_0.10.1
## [13] RColorBrewer_1.1-2      promises_1.1.0          leaflet.providers_1.9.0
## [16] colorspace_1.4-1        htmltools_0.4.0         httpuv_1.5.2           
## [19] XML_3.99-0.3            pkgconfig_2.0.3         magick_2.3             
## [22] stars_0.4-1             purrr_0.3.4             xtable_1.8-4           
## [25] scales_1.1.0            webshot_0.5.2           satellite_1.0.2        
## [28] later_1.0.0             leaflet.extras_1.0.0    tibble_3.0.1           
## [31] farver_2.0.3            ellipsis_0.3.0          withr_2.2.0            
## [34] lazyeval_0.2.2          leafsync_0.1.0          magrittr_1.5           
## [37] crayon_1.3.4            mime_0.9                evaluate_0.14          
## [40] doParallel_1.0.15       lwgeom_0.2-3            class_7.3-16           
## [43] tools_4.0.0             data.table_1.12.8       prettyunits_1.1.1      
## [46] hms_0.5.3               rlas_1.3.5              lifecycle_0.2.0        
## [49] stringr_1.4.0           munsell_0.5.0           compiler_4.0.0         
## [52] e1071_1.7-3             rlang_0.4.5             classInt_0.4-3         
## [55] units_0.6-6             dichromat_2.0-0         iterators_1.0.12       
## [58] htmlwidgets_1.5.1       crosstalk_1.1.0.1       miniUI_0.1.1.1         
## [61] leafem_0.1.1            base64enc_0.1-3         rmarkdown_2.1          
## [64] gtable_0.3.0            codetools_0.2-16        abind_1.4-5            
## [67] DBI_1.1.0               markdown_1.1            R6_2.4.1               
## [70] rgdal_1.4-8             knitr_1.28              rgeos_0.5-2            
## [73] fastmap_1.0.1           KernSmooth_2.23-16      stringi_1.4.6          
## [76] parallel_4.0.0          Rcpp_1.0.4.6            vctrs_0.2.4            
## [79] png_0.1-7               tidyselect_1.0.0        leaflet_2.0.3          
## [82] xfun_0.13
 

A work by Michal Michalski

 

LS0tCnRpdGxlOiAiTGlEQVIgaW4gUmNoZW9sb2d5IgphdXRob3I6ICJNaWNoYWwgTWljaGFsc2tpIgpkYXRlOiAiMjkvMDUvMjAyMCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGZsYXRseQogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICAKLS0tCjxzdHlsZT4KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNEM0QzRDM7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9Cjwvc3R5bGU+CjxkaXYgY2xhc3MgPSAiYmx1ZSI+CkluIHRoaXMgc2hvcnQgdHV0cmlhbCBJIGFtIHNjcmlwdGluZyBhICB3b3JrZmxvdyBmb3Igd29ya2luZyB3aXRoIExpREFSIGRhdGEgZG93bmxvYWRlZCBmcm9tICBbU2NvdHRpc2ggUmVtb3RlIFNlbnNpbmcgUG9ydGFsXShodHRwczovL3JlbW90ZXNlbnNpbmdkYXRhLmdvdi5zY290LykuIFRoZSBhaW0gaXMgdG8gcHJvY2VzcyB0aGUgcmF3IExBWiBmaWxlcywgcHJvZHVjZSAgdmlzdWFsaXphdGlvbnMgYW5kIHRha2Ugc2ltcGxlIG1lYXN1cm1lbnRzIHNvbGVseSByZWxheWluZyBvbiBSIHByb2dyYW1taW5nIGxhbmd1YWdlLiAKSSBhbSBsb29raW5nIGF0ICBhIDEydGggY2VudHVyeSBtb3R0ZSBpbiBDYWxseSBGb3JyZXN0LCBHYWxsb3dheSwgaW4gc291dGgtd2VzdCBTY290bGFuZC4KVGhpcyBtb3VuZCB3YXMgYWN0dWFsbHkgc3VydmV5ZWQgYnkgUnViaWNvbiBIZXJpdGFnZSBpbiAyMDEyIFsgY2xpayBoZXJlIHRvIHJlYWQgYWJvdXQgdGhlIGZpZWxkd29ya10oaHR0cDovL3d3dy5ydWJpY29uaGVyaXRhZ2UuY29tLzIwMTIvMTAvMTAvY2FsbHktZm9yZXN0LW1vdHRlLXN1cnZleS1hLWxvdmVseS1zaGFkeS1sdW1wLykuCk5vdyBsZXRzIHNlZSBob3cgaXQgY29tcGFyZXMgd2l0aCB3b3JrIG9mIGFuIDxpPmFybWNoYWlyIGFyY2hhZW9sb2dpc3Q8L2k+CjwvZGl2PgoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMgUGFja2FnZXMKRmlyc3QsIEkgYW0gbG9hZGluZyBhbGwgcGFja2FnZXMgbmVjZXNzYXJ5IGZvciB0aGUgZm9sbG93aW5nIGFuYWx5c2lzLgpgYGB7ciBwYWNrYWdlcywgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KbGlicmFyeShsaWRSKSAjIHByb2Nlc3MgTEFaIGZpbGVzCmxpYnJhcnkocmFzdGVyKSMgZGVhbCB3aXRoIHJhc3RlcgpsaWJyYXJ5KHJheXNoYWRlcikgIyAzRCB2aXoKbGlicmFyeShyZ2wpICMgaW50ZXJhY3RpdmUgcGxvdApsaWJyYXJ5KHNmKSAjIHNwYXRpYWwgY2xhc3MKbGlicmFyeShtYXBlZGl0KSAjIGludGVyYWN0aXZlIG1hcCBlZGl0aW5nCmxpYnJhcnkobWFwdmlldykgIyBpbnRlcmFjdGl2ZSBtYXAgdmlld2luZwpsaWJyYXJ5KHRtYXApICMgY2FydG9ncmFwaHkKbGlicmFyeSh0bWFwdG9vbHMpICMgbGl0dGxlIGhlbHBlcnMKbGlicmFyeShzbW9vdGhyKSAjIHNtb290aCBjb250b3VycwpsaWJyYXJ5KGRwbHlyKSAjIG1hbmlwdWxhdGUKbGlicmFyeShnZ3Bsb3QyKSAjIHBsb3QKbGlicmFyeShncmlkKSAjIGNvbWJpbmVzIHBsb3RzCgpgYGAKCiMjIExBWgpOZXh0LCBJIGFtIHJlYWRpbmcgdGhlIExBWiBmaWxlcyBhbmQgY2xpcHBpbmcgdGhlIHBvaW50IGNsb3VkIHRvIHRoZSBleHRlbnQgb2YgaW1taWRpYXRlIGFyZWEgYXJvdW5kIHRoZSBtb3R0ZS4KYGBge3IgbGFzfQojcmVhZCBsYXogZmlsZXMKbGFzID0gcmVhZExBUygiZGF0YS9OWDYwNTVfNFBQTV9MQVNfUEhBU0UzLmxheiIpCgojIHJlYWQgYSBzaGFwZWZpbGUgb2YgYXJlYSBhcm91bmQgdGhlIG1vdHRlCm1vdHRlX2FyZWEgPSBzdF9yZWFkKCJkYXRhL21vdHRlX2FyZWEuc2hwIiwgcXVpZXQgPSBUUlVFKQoKI2NsaXAgdGhlIGxheiBmaWxlIHRvIHRoZSBleHRlbmQgb2YgYW9pCm1vdHRlID0gbGFzY2xpcChsYXMsIG1vdHRlX2FyZWEpCgojcGxvdCBsaWRhciBwb2ludCBjbG91ZApwbG90KG1vdHRlLCBiZyA9ICJ3aGl0ZSIpCgpyZ2x3aWRnZXQoKQoKCgpgYGAKCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij5ncmFiIGFuZCByb3RhdGUgdGhlIG1vZGVsICEgPC9hPjwvcD4KCiMjIERpZ2l0YWwgRWxldmV0aW9uIE1vZGVsCgojIyMgRFRNIGFuZCBEU00KCkluIHRoaXMgc3RlcCBJIGFtIHJ1bm5pbmcgc3RhbmRhcmQgYWxnaG9yaXRtcyBmcm9tIExpRFIgcGFja2FnZSB0byBjb21wdXRlIERpZ2l0YWwgU3VyZmFjZSBNb2RlbCAoRFNNKSBhbmQgRGlnaXRpYWwgVGVycmFpbiBNb2RlbCAoRFRNKS4KYGBge3J9CnJnbC5jbGVhcigpCiMgY3JlYXRlIGRzbSBhbmQgZHRtCmRzbSA9IGdyaWRfY2Fub3B5KG1vdHRlLCAwLjUsIHBpdGZyZWUoKSkKCiMgYXNzaWduIGNvb3JkaW5hdGUgc3lzdGVtCmNycyhkc20pID0gQ1JTKCIraW5pdD1lcHNnOjI3NzAwIikKCiMgY3JlYXRlIGR0bQpkdG0gPSBncmlkX3RlcnJhaW4obW90dGUsIDAuNSwgYWxnb3JpdGhtID0ga25uaWR3KGsgPSA2TCwgcCA9IDIpKQoKIyBhZGRpZ24gY29vcmRpbmF0ZSBzeXN0ZW0KY3JzKGR0bSkgPSBDUlMoIitpbml0PWVwc2c6Mjc3MDAiKQoKcGFyKG1mcm93ID0gYygxLDIpKQpwbG90KGR0bSwgbWFpbiA9ICJEVE0iLCBjb2wgPSBoZWlnaHQuY29sb3JzKDUwKSwgbGVnZW5kID0gRkFMU0UpCnBsb3QoZHNtLCBtYWluID0gIkRTTSIsY29sID0gaGVpZ2h0LmNvbG9ycyg1MCkpCgpgYGAKCiMjIyBIaWxsc2hhZGUKClRoZXJlIGFyZSBkb3plbnMgb2YgYWxnaG9yaXRtcyB0byB2aXN1YWxpemUgb3IgZXh0cmFjdCBjaGFyYWN0ZXJpc3RpY3MgZnJvbSBEaWdpdGFsIEVsZXZhdGlvbnMgTW9kZWxzLiBUaGUgbW9zdCBjb21tb24gaXMgaGlsbHNoYWRlIGRldGVybWluZWQgYnkgdGhlIGFzcGVjdHMgYW5kIHNsb3BlIG9mIHRoZSB0ZXJyYWluIGFzIHdlbGwgYXMgbGlnaHQgc291cmNlLgpgYGB7ciBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFfQoKIyBkc20Kc2xvcGVfZHNtID0gdGVycmFpbihkc20sIG9wdCA9ICdzbG9wZScpCmFzcGVjdF9kc20gPSB0ZXJyYWluKGRzbSwgb3B0ID0gJ2FzcGVjdCcpCmhpbGxfZHNtID0gaGlsbFNoYWRlKHNsb3BlX2RzbSwgYXNwZWN0X2RzbSwgYW5nbGUgPSA0MCwgZGlyZWN0aW9uID0gMjcwKQoKIyBkdG0Kc2xvcGVfZHRtID0gdGVycmFpbihkdG0sIG9wdCA9ICdzbG9wZScpCmFzcGVjdF9kdG0gPSB0ZXJyYWluKGR0bSwgb3B0ID0gJ2FzcGVjdCcpCmhpbGxfZHRtID0gaGlsbFNoYWRlKHNsb3BlX2R0bSwgYXNwZWN0X2R0bSwgYW5nbGUgPSA1LCBkaXJlY3Rpb24gPSAyNzApCgojcGxvdApwYXIobWZyb3cgPSBjKDEsMikpCnBsb3QoaGlsbF9kdG0sIG1haW4gPSAiRFRNIEhpbHNoYWRlIiwgY29sID0gZ3JleS5jb2xvcnMoMTAwLCBzdGFydCA9IDAsIGVuZCA9IDEpLCAKICAgICBsZWdlbmQgPSBGQUxTRSkKcGxvdChoaWxsX2RzbSwgbWFpbiA9ICJEU00gSGlsbHNoYWRlIiwgY29sID0gZ3JleS5jb2xvcnMoMTAwLCBzdGFydCA9IDAsIGVuZCA9IDEpKQoKCmBgYAoKCiMjIFRyYW5zZWN0CkluIG9yZGVyIHRvIHJlcHJlc2VudCB0aGUgaGVpZ2h0IHZhbHVlcyBhbmQgZ2V0IGlkZWEgYWJvdXQgdGhlIHByb2ZpbGUgSSB3aWxsIGRyYXcgYSBsaW5lIGFjcm9zcyB0aGUgKm1vdHRlKi4KCiMjIyBMaW5lCgpQYWNrYWdlICptYXBlZGl0KiBhbGxvd3MgIHRvIGludGVyYWN0aXZlbHkgIGRyYXcgdGhlIGxpbmUgYW5kIHNhdmUgaXQgYXMgc2Ygb2JqZWN0LgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9Cm1hcHZpZXdPcHRpb25zKHJhc3Rlci5wYWxldHRlID0gZ3JleS5jb2xvcnMpCgppbnRlcmFjdGl2ZV9tYXAgPC0gbWFwdmlldyhoaWxsX2R0bSkgJT4lCiAgZWRpdE1hcCgpCgp0cmFuc2VjdC5zZiA9IGludGVyYWN0aXZlX21hcCRmaW5pc2hlZAoKYGBgCgoKYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0gNDAwLCBmaWcuY2FwPSIiLCBmaWcuYWxpZ249J2NlbnRlcid9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJwcm9maWxlLmdpZiIpCmBgYAoKCiMjIyBFbGV2YXRpb24KCkluIHRoZSBmb2xsb3dpbmcgY29kZSBJIHVzZSB0aGUgbGluZSBzZWxlY3RvciB0byBleHRyYWN0IHRoZSB6LXZhbHVlcyBmcm9tIHRoZSByYXN0ZXIuIEkgbmVlZCB0byBnaXZlIGNyZWRpdCBmb3IgdGhlIGlkZWEgdG8gdGhlICBib29rIFtHZW9jb21wdXRhdGlvbiB3aXRoIFJdKGh0dHBzOi8vZ2VvY29tcHIucm9iaW5sb3ZlbGFjZS5uZXQvZ2VvbWV0cmljLW9wZXJhdGlvbnMuaHRtbCkuIEFsdGhvdWdoIEkgaGFkIHRvIGFtZW5kIHRoZSBjb2RlIHRvIHdvcmsgaW4gcHJvamVjdGVkIGNvb3JkaW5hdGUgc3lzdGVtLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9Cgp0cmFuc2VjdCA9IHJhc3Rlcjo6ZXh0cmFjdChkdG0sIHRyYW5zZWN0LnNmLCBhbG9uZyA9IFRSVUUsIGNlbGxudW1iZXJzID0gVFJVRSkKdHJhbnNlY3RfZGYgPSBwdXJycjo6bWFwX2Rmcih0cmFuc2VjdCwgYXNfZGF0YV9mcmFtZSwgLmlkID0gIklEIikKdHJhbnNlY3RfY29vcmRzID0geHlGcm9tQ2VsbChkdG0sIHRyYW5zZWN0X2RmJGNlbGwpCnBhaXJfZGlzdCA9IHBvaW50RGlzdGFuY2UodHJhbnNlY3RfY29vcmRzLGxhZyh0cmFuc2VjdF9jb29yZHMpLCBsb25sYXQ9RkFMU0UpCnRyYW5zZWN0X2RmJGRpc3QgPSBjKDAsIGN1bXN1bShuYS5vbWl0KHBhaXJfZGlzdCkpKSAKYGBgCgojIyMgVHJhbnNlY3QgUGxvdAoKTm93IEkgY2FuIHBsb3QgdGhlIGRhdGEgZnJhbWUgd2l0aCBoZWlnaHRzIGFsb25nIHRoZSB0cmFuc2VjdCBsaW5lLiBUaGUgdGlwIGlzIHRvIHVzZSBmaXhlZCAqYXNwZWN0IHJhdGlvKiBpbiBvcmRlciB0byBwcmVzZXJ2ZSBwaHlzaWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGF0YSB1bml0cyBvbiB0aGUgYXhlcy4KCmBgYHtyfQpwcm9maWxlID0gZ2dwbG90KHRyYW5zZWN0X2RmKSArCiAgZ2VvbV9hcmVhKGFlcyh4ID0gZGlzdCwgeSA9IFopLCAgYWxwaGE9MC42ICwgc2l6ZT0xLCBjb2xvdXI9IiNBRjAwMkEiLCBmaWxsID0gIiNBRjAwMkEiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSg0MCwgNTAsIGJ5ID0gNSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgYnkgPSAxMCkpICsKICBjb29yZF9maXhlZCh5bGltID0gYyg0MCw1MCkpICsKICBsYWJzKHRpdGxlID0gIlByb2ZpbGUiLAogICAgICAgeCA9ICJEaXN0YW5jZSAobSkiLAogICAgICAgeSA9ICJFbGV2YXRpb24gKG0pIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkKcHJvZmlsZQoKYGBgCgojIyBNYXAKCiBMZXRzIGNyZWF0ZSBhIHRvcG9ncmFwaGljIG1hcCBvZiB0aGUgKm1vdHRlKiBhbmQgcGxvdCB0aGUgbG9jYXRpb24gb2YgdGhlIHRyYW5zZWN0LgoKYGBge3J9CiNsb2FkIGNhbm9tcmUgYXJlYQp0b3BvX2NvbnRvdXIgPC0gcmFzdGVyVG9Db250b3VyKGR0bSwgbmxldmVscyA9IDEwKSAlPiUgCiAgc3RfYXNfc2YoKSAlPiUgCiAgc3RfY2FzdCgiTElORVNUUklORyIpICU+JSAKICBkcm9wX2NydW1icygyMCkKCiMgY29sb3IgcGFsZXR0ZQpicmV3ZXJfZ3JleSA9IGdldF9icmV3ZXJfcGFsKCJHcmV5cyIsIG4gPSAxMCwgY29udHJhc3QgPSBjKDAuMjIsIDAuODIpLCBwbG90ID0gRkFMU0UpCgptYXAgPSB0bV9zaGFwZShkdG0sIHVuaXQgPSAibSIpICsKICB0bV9yYXN0ZXIoc3R5bGU9ICJwcmV0dHkiLCBuID0gMTAsIHBhbGV0dGUgPSBicmV3ZXJfZ3JleSwgbGVnZW5kLnNob3c9RiwgYWxwaGEgPSAwLjc1KSArCnRtX3NoYXBlKHRvcG9fY29udG91cikgKwogIHRtX2xpbmVzKGNvbCA9ICJsZXZlbCIsCiAgICAgICAgICAgcGFsZXR0ZSA9ICJHcmV5cyIsCiAgICAgICAgICAgbGVnZW5kLmNvbC5zaG93ID0gRikgKwogIHRtX3RleHQodGV4dCA9ICJsZXZlbCIsCiAgICAgICAgICBzaXplID0gLjUsCiAgICAgICAgICBjb2wgPSAibGV2ZWwiLAogICAgICAgICAgcGFsZXR0ZSA9ICItR3JleXMiLAogICAgICAgICAgYWxvbmcubGluZXMgPSBGLCAKICAgICAgICAgIG92ZXJ3cml0ZS5saW5lcyA9IFQsCiAgICAgICAgICBsZWdlbmQuY29sLnNob3cgPSBGKSArCnRtX3NoYXBlKHRyYW5zZWN0LnNmKSArCiAgdG1fbGluZXMoY29sID0gIiNBRjAwMkEiLAogICAgICAgICAgIGx0eSA9ICJkYXNoZWQiLAogICAgICAgICAgIGx3ZCA9IDIpICsKdG1fY29tcGFzcyhwb3NpdGlvbiA9IGMoImxlZnQiLCAiYm90dG9tIikpICsKdG1fc2NhbGVfYmFyKGJyZWFrcyA9IGMoMCw1LDEwKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gYygibGVmdCIsICJib3R0b20iKSkgKwp0bV9jcmVkaXRzKCJAdG9wb2dyYXBob3MyIikgKwp0bV9sYXlvdXQoCiAgICBtYWluLnRpdGxlID0gIkNhbGx5IEZvcnJlc3QgTW90dGUiLAogICAgZnJhbWUgPSBGKQoKbWFwCgpgYGAKCiMjIEZpbmFsIEdyYXBoaWMKCkZpbmFsbHksIEkgY2FuIGNvbWJpbmUgdGhlIHR3byBncmFwaGljcy4KCmBgYHtyfQojIHBsb3QgdXNpbmcgZ3JpZApsaWJyYXJ5KGdyaWQpCgpncmlkLm5ld3BhZ2UoKQojIHNldCB1cCB0aGUgbGF5b3V0CnB1c2hWaWV3cG9ydCh2aWV3cG9ydChsYXlvdXQ9Z3JpZC5sYXlvdXQoMSwyKSkpCiMgcGxvdCB1c2luZyB0aGUgcHJpbnQgY29tbWFuZApwcmludChtYXAsIHZwPXZpZXdwb3J0KGxheW91dC5wb3MuY29sID0gMSwgaGVpZ2h0ICA9IDIwKSkKcHJpbnQocHJvZmlsZSwgdnA9dmlld3BvcnQobGF5b3V0LnBvcy5jb2wgPSAyLCBoZWlnaHQgPSAyMCkpCgpgYGAKCiMjIEdvaW5nIDNECgpBbmQgYSAqY2hlcnJ5IG9uIHRoZSB0b3AqIGJ5IGFtYXppbmcgKnJheXNoYWRlciogcGFja2FnZQoKYGBge3J9CgojQW5kIGNvbnZlcnQgaXQgdG8gYSBtYXRyaXg6CmVsbWF0ID0gcmFzdGVyX3RvX21hdHJpeChkdG0pCgplbG1hdCAlPiUKICBzcGhlcmVfc2hhZGUodGV4dHVyZSA9ICJpbWhvZjEiKSAlPiUKICBhZGRfc2hhZG93KHJheV9zaGFkZShlbG1hdCwgenNjYWxlID0gMC41LCBzdW5hbHRpdHVkZSA9IDMwLGxhbWJlcnQgPSBUUlVFKSwKICAgICAgICAgICAgIG1heF9kYXJrZW4gPSAxKSAlPiUKICBhZGRfc2hhZG93KGxhbWJfc2hhZGUoZWxtYXQsenNjYWxlID0gMC41LHN1bmFsdGl0dWRlID0gMzApLCBtYXhfZGFya2VuID0gMC4yKSAlPiUKICBhZGRfc2hhZG93KGFtYmllbnRfc2hhZGUoZWxtYXQsIHpzY2FsZSA9IDAuNSksIG1heF9kYXJrZW4gPSAwLjIpICU+JQogIHBsb3RfM2QoZWxtYXQsIHpzY2FsZSA9IDAuNSx3aW5kb3dzaXplID0gYygxMDAwLDEwMDApLAogICAgICAgICAgcGhpID0gNDAsIHRoZXRhID0gMTgwLCB6b29tID0gMC44LCBmb3YgPSAxKQpyZ2x3aWRnZXQoKQpgYGAKCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij5ncmFiIGFuZCByb3RhdGUgdGhlIG1vZGVsICEgPC9hPjwvcD4KCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoKCiZuYnNwOwo8aHIgLz4KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPkEgd29yayBieSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vdG9wb2dyYXBob3MvIj5NaWNoYWwgTWljaGFsc2tpPC9hPjwvcD4KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjogIzgwODA4MDsiPjxlbT5taWNoYWwubS5taWNoYWxza2lAZHVyaGFtLmFjLnVrPC9lbT48L3NwYW4+PC9wPgoKPCEtLSBBZGQgaWNvbiBsaWJyYXJ5IC0tPgo8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2ZvbnQtYXdlc29tZS80LjcuMC9jc3MvZm9udC1hd2Vzb21lLm1pbi5jc3MiPgoKPCEtLSBBZGQgZm9udCBhd2Vzb21lIGljb25zIC0tPgo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+CiAgICA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL3RvcG9ncmFwaG9zMiIgY2xhc3M9ImZhIGZhLXR3aXR0ZXIiPjwvYT4KICAgIDxhIGhyZWY9Imh0dHBzOi8vdG9wb2dyYXBob3MucmJpbmQuaW8vIiBjbGFzcz0iZmEgZmEtZ2xvYmUiPjwvYT4KICAgIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS90b3BvZ3JhcGhvcy8iIGNsYXNzPSJmYSBmYS1naXRodWIiPjwvYT4KPC9wPgoKJm5ic3A7Cg==