1. Why Spatial Data? The Importance of ‘Where’

As data scientists and statisticians, we are experts at extracting insights from data. We analyze trends, build predictive models, and uncover hidden patterns. Traditionally, we focus on the ‘what’ (the variables) and the ‘when’ (the time). Spatial statistics adds a critical third dimension: the ‘where’.

Whether you are tracking a disease outbreak, planning aid distribution, analyzing crime patterns, or modeling climate change, the location of your data points is not just another variable—it’s a fundamental part of the story. Events that happen close to each other are often related. This principle, known as spatial autocorrelation, is the cornerstone of spatial analysis.

This module will provide you with the foundational vocabulary and concepts to understand, classify, and work with spatial data. We will learn the different “shapes” spatial data can take and, most importantly, how to choose the right type for the right question.

2. The Two Foundational Models: Vector vs. Raster

Before diving into statistical types, we must understand the two fundamental ways computers store geographic information. All spatial data falls into one of these two models.

2.1 Vector Data: Drawing with Coordinates

Think of vector data as drawing with coordinates. It represents the world using discrete, precise geometric objects. Each object has associated attributes (e.g., the name of a hospital, the type of a road). There are three types of vector geometries:

  • Points: A single coordinate pair (x, y) representing a specific location.
    • When to use: For features that have a location but no meaningful area or length at your scale of analysis.
    • Somalia/Somaliland Example: The location of a specific hospital in Mogadishu, a water well in a rural village, or an IDP (Internally Displaced Persons) camp. Each is a distinct, single point.
  • Lines (or Polylines): A sequence of connected coordinate pairs.
    • When to use: For features that have length but not area, like networks or boundaries.
    • Somalia/Somaliland Example: The path of the Jubba River, the road network connecting Hargeisa and Berbera, or the administrative border between Puntland and Galmudug.
  • Polygons: A series of connected coordinate pairs that form a closed shape, representing an area.
    • When to use: For features that have a defined boundary and area.
    • Somalia/Somaliland Example: The boundary of the Banaadir region, the area of a national park, or the footprint of a specific neighborhood in Burao.

Vector data is ideal when you are interested in the features themselves and their relationships.

2.2 Raster Data: A Grid of Values

Think of raster data as a digital photograph or a grid. It represents the world as a continuous surface, divided into a matrix of equally sized cells (or pixels). Each cell has a single value representing the characteristic of that specific location.

  • When to use: For phenomena that vary continuously across a landscape, with no clear boundaries.
  • Somalia/Somaliland Examples:
    • Elevation Data (DEM): A grid where each cell’s value is its elevation above sea level. This is crucial for understanding topography and flood risk.
    • Climate Data: A grid where each cell’s value could be the average monthly rainfall, temperature, or a vegetation index (like NDVI) to monitor drought conditions.
    • Satellite Imagery: A picture from space where each pixel has a color value, used to identify land cover (urban, farm, desert).

Raster data is ideal when you are studying how a measurement varies over a surface.

Feature Vector Data Raster Data
Representation Discrete points, lines, polygons Continuous grid of cells (pixels)
Structure Coordinates and attributes Matrix of values
Best For Administrative boundaries, roads, locations Elevation, temperature, satellite imagery
Example A shapefile of Somalia’s regions A GeoTIFF file of rainfall in the Horn of Africa
Key Question What is where? (e.g., a hospital) How much of something is everywhere? (e.g., elevation)

3. The Three Classical Types of Spatial Data

Building on the vector/raster models, spatial statisticians classify data into three main types based on the nature of the spatial process being observed. Understanding this classification is key to choosing the correct statistical methods later on.

3.1 Areal (or Lattice) Data

What it is: Areal data consists of values that are aggregated over polygons. The domain is a fixed set of areas, and we have a summary statistic (like a count, average, or rate) for each one. This is perhaps the most common type of spatial data in public health and social sciences.

The Key Question it Answers: “How does a value or count vary from area to area, and are neighboring areas more similar than distant ones?”

When to Use It and Why: * Privacy: When individual-level data (like patient addresses) is too sensitive to share, aggregating to a district or regional level protects confidentiality. * Administrative Data: Data is often collected and reported by administrative units (e.g., census bureaus, ministries of health). * Stable Rates: Calculating rates (e.g., disease incidence) requires a denominator (population), which is usually available at an areal level.

Somalia/Somaliland Example: Mapping Malnutrition Cases by Region Imagine we have the number of severe acute malnutrition (SAM) cases reported by health facilities in each region of Somaliland. We want to see if there are regional hotspots.

# Load Somalia administrative boundaries (we'll use this as our base)
# Ensure "som_admbnda_adm1_ocha_20250108.shp" is in your working directory
som_adm1 <- st_read("som_admbnda_adm1_ocha_20250108.shp")
## Reading layer `som_admbnda_adm1_ocha_20250108' from data source 
##   `C:\Users\Admin\Desktop\Course Spatial Statistics for Data Science\som_admbnda_adm1_ocha_20250108.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 18 features and 10 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 40.99488 ymin: -1.664897 xmax: 51.41303 ymax: 11.9852
## Geodetic CRS:  WGS 84
# Filter for Somaliland regions
somaliland_regions <- som_adm1 %>%
  filter(ADM1_EN %in% c("Awdal", "Woqooyi Galbeed", "Togdheer", "Sanaag", "Sool"))

# Create some fictional malnutrition data to join
malnutrition_data <- data.frame(
  ADM1_EN = c("Awdal", "Woqooyi Galbeed", "Togdheer", "Sanaag", "Sool"),
  SAM_cases = c(150, 320, 210, 180, 250)
)

# Join the data to the spatial object
somaliland_map_data <- left_join(somaliland_regions, malnutrition_data, by = "ADM1_EN")

# Plot the areal data
ggplot(data = somaliland_map_data) +
  geom_sf(aes(fill = SAM_cases)) +
  geom_sf_text(aes(label = ADM1_EN), size = 3) +
  scale_fill_viridis_c(name = "SAM Cases") +
  ggtitle("Areal Data: Malnutrition Cases by Region in Somaliland") +
  theme_void()

3.2 Geostatistical Data

What it is: Geostatistical data consists of measurements of a continuous phenomenon taken at specific point locations. We assume the underlying phenomenon (e.g., temperature, pollution) exists everywhere, but we can only afford to sample it at a finite number of sites.

The Key Question it Answers: “Given these sample points, can we predict the value of the phenomenon at un-sampled locations? (This is called interpolation or kriging).”

When to Use It and Why: * Environmental Monitoring: It’s impossible to measure air quality or soil contamination everywhere. We use monitoring stations (points) to sample the continuous field. * Resource Exploration: Geologists drill at specific locations (points) to infer the extent of an underground oil reserve (a continuous field). * When the underlying process is truly continuous.

Somalia/Somaliland Example: Measuring Water Salinity at Wells Imagine we are monitoring the salinity of groundwater at several wells along the Shabelle River to check for saltwater intrusion. We want to create a continuous map of salinity from these point measurements.

# Create a fictional dataset of well locations and salinity measurements
wells_data <- data.frame(
  well_id = c("W1", "W2", "W3", "W4", "W5"),
  longitude = c(45.0, 45.2, 45.5, 45.8, 46.1),
  latitude = c(2.2, 2.5, 2.9, 3.2, 3.5),
  salinity_ppm = c(800, 950, 1100, 1500, 2200) # Parts Per Million
)

# Convert the data frame to a spatial sf object
wells_sf <- st_as_sf(wells_data, coords = c("longitude", "latitude"), crs = 4326)

# Plot the points on the map of Somalia
ggplot() +
  geom_sf(data = som_adm1, fill = "khaki", color = "grey") + # Base map
  geom_sf(data = wells_sf, aes(color = salinity_ppm), size = 4) +
  scale_color_viridis_c(name = "Salinity (PPM)") +
  ggtitle("Geostatistical Data: Water Salinity at Wells") +
  theme_bw()

3.3 Point Pattern Data

What it is: In a point pattern, the locations of the events are the data themselves. We are not interested in a value at the point, but rather in the spatial arrangement of the points. The underlying process is what generates the locations.

The Key Question it Answers: “Are the events clustered, randomly distributed, or regularly spaced? What process might be generating this pattern?”

When to Use It and Why: * Epidemiology: To see if disease cases are clustered around a source of infection (e.g., a contaminated water pump). * Criminology: To identify crime hotspots. * Ecology: To study the territorial patterns of plants or animals.

Somalia/Somaliland Example: Mapping Security Incidents in Mogadishu An NGO is analyzing the locations of reported security incidents in the Banaadir region (which contains Mogadishu) to understand if they are concentrated in specific areas.

# Get the polygon for the Banadir region
banadir_region <- som_adm1 %>% filter(ADM1_EN == "Banadir")

# Generate 100 random points *within* the Banadir polygon to simulate incidents
# In a real analysis, these would be actual coordinates of incidents
set.seed(123) # for reproducibility
incident_points <- st_sample(banadir_region, size = 100)

# Plot the point pattern
ggplot() +
  geom_sf(data = banadir_region, fill = "grey80") +
  geom_sf(data = incident_points, color = "red", alpha = 0.6, size = 2) +
  ggtitle("Point Pattern: Simulated Security Incidents in Banadir") +
  theme_bw()

4. Summary and A Glimpse Ahead

Understanding these data types is the first and most important step in any spatial analysis. Choosing the wrong classification can lead to using inappropriate methods and drawing incorrect conclusions.

Data Type What it Represents Key Question Somalia/Somaliland Example Common Goal
Areal Aggregated values in polygons How do values vary by area? Cholera cases per district Disease mapping, hotspot detection
Geostatistical Samples of a continuous field Can we predict values everywhere? Rainfall at weather stations Interpolation (Kriging), surface creation
Point Pattern Locations of events Is there clustering? Locations of IDP camps Cluster analysis, density estimation

In the upcoming modules, we will learn how to use R packages like sf and terra to manipulate these data types and then apply powerful statistical techniques to answer these key questions. We will also touch upon more advanced concepts like spatio-temporal data, which tracks these patterns over time—for example, mapping the spread of a measles outbreak across districts over several months. ```

LS0tDQp0aXRsZTogIk1vZHVsZSBJOiBUaGUgTGFuZ3VhZ2Ugb2YgU3BhdGlhbCBEYXRhIg0Kc3VidGl0bGU6ICJBIEZvdW5kYXRpb24gZm9yIFNwYXRpYWwgU3RhdGlzdGljcyBhbmQgRGF0YSBTY2llbmNlIg0KYXV0aG9yOiAiQWJkaXNhbGFtIEhhc3NhbiBNdXNlLCBQaEQiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdGhlbWU6IHVuaXRlZA0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQ0KIyBMb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcyBmb3IgdGhlIGVudGlyZSBkb2N1bWVudA0KbGlicmFyeShzZikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpgYGANCg0KIyMgMS4gV2h5IFNwYXRpYWwgRGF0YT8gVGhlIEltcG9ydGFuY2Ugb2YgJ1doZXJlJw0KDQpBcyBkYXRhIHNjaWVudGlzdHMgYW5kIHN0YXRpc3RpY2lhbnMsIHdlIGFyZSBleHBlcnRzIGF0IGV4dHJhY3RpbmcgaW5zaWdodHMgZnJvbSBkYXRhLiBXZSBhbmFseXplIHRyZW5kcywgYnVpbGQgcHJlZGljdGl2ZSBtb2RlbHMsIGFuZCB1bmNvdmVyIGhpZGRlbiBwYXR0ZXJucy4gVHJhZGl0aW9uYWxseSwgd2UgZm9jdXMgb24gdGhlICoqJ3doYXQnKiogKHRoZSB2YXJpYWJsZXMpIGFuZCB0aGUgKiond2hlbicqKiAodGhlIHRpbWUpLiBTcGF0aWFsIHN0YXRpc3RpY3MgYWRkcyBhIGNyaXRpY2FsIHRoaXJkIGRpbWVuc2lvbjogdGhlICoqJ3doZXJlJyoqLg0KDQpXaGV0aGVyIHlvdSBhcmUgdHJhY2tpbmcgYSBkaXNlYXNlIG91dGJyZWFrLCBwbGFubmluZyBhaWQgZGlzdHJpYnV0aW9uLCBhbmFseXppbmcgY3JpbWUgcGF0dGVybnMsIG9yIG1vZGVsaW5nIGNsaW1hdGUgY2hhbmdlLCB0aGUgbG9jYXRpb24gb2YgeW91ciBkYXRhIHBvaW50cyBpcyBub3QganVzdCBhbm90aGVyIHZhcmlhYmxl4oCUaXQncyBhIGZ1bmRhbWVudGFsIHBhcnQgb2YgdGhlIHN0b3J5LiBFdmVudHMgdGhhdCBoYXBwZW4gY2xvc2UgdG8gZWFjaCBvdGhlciBhcmUgb2Z0ZW4gcmVsYXRlZC4gVGhpcyBwcmluY2lwbGUsIGtub3duIGFzICoqc3BhdGlhbCBhdXRvY29ycmVsYXRpb24qKiwgaXMgdGhlIGNvcm5lcnN0b25lIG9mIHNwYXRpYWwgYW5hbHlzaXMuDQoNClRoaXMgbW9kdWxlIHdpbGwgcHJvdmlkZSB5b3Ugd2l0aCB0aGUgZm91bmRhdGlvbmFsIHZvY2FidWxhcnkgYW5kIGNvbmNlcHRzIHRvIHVuZGVyc3RhbmQsIGNsYXNzaWZ5LCBhbmQgd29yayB3aXRoIHNwYXRpYWwgZGF0YS4gV2Ugd2lsbCBsZWFybiB0aGUgZGlmZmVyZW50ICJzaGFwZXMiIHNwYXRpYWwgZGF0YSBjYW4gdGFrZSBhbmQsIG1vc3QgaW1wb3J0YW50bHksIGhvdyB0byBjaG9vc2UgdGhlIHJpZ2h0IHR5cGUgZm9yIHRoZSByaWdodCBxdWVzdGlvbi4NCg0KIyMgMi4gVGhlIFR3byBGb3VuZGF0aW9uYWwgTW9kZWxzOiBWZWN0b3IgdnMuIFJhc3Rlcg0KDQpCZWZvcmUgZGl2aW5nIGludG8gc3RhdGlzdGljYWwgdHlwZXMsIHdlIG11c3QgdW5kZXJzdGFuZCB0aGUgdHdvIGZ1bmRhbWVudGFsIHdheXMgY29tcHV0ZXJzIHN0b3JlIGdlb2dyYXBoaWMgaW5mb3JtYXRpb24uIEFsbCBzcGF0aWFsIGRhdGEgZmFsbHMgaW50byBvbmUgb2YgdGhlc2UgdHdvIG1vZGVscy4NCg0KIyMjIyAyLjEgVmVjdG9yIERhdGE6IERyYXdpbmcgd2l0aCBDb29yZGluYXRlcw0KDQpUaGluayBvZiB2ZWN0b3IgZGF0YSBhcyAqKmRyYXdpbmcgd2l0aCBjb29yZGluYXRlcyoqLiBJdCByZXByZXNlbnRzIHRoZSB3b3JsZCB1c2luZyBkaXNjcmV0ZSwgcHJlY2lzZSBnZW9tZXRyaWMgb2JqZWN0cy4gRWFjaCBvYmplY3QgaGFzIGFzc29jaWF0ZWQgYXR0cmlidXRlcyAoZS5nLiwgdGhlIG5hbWUgb2YgYSBob3NwaXRhbCwgdGhlIHR5cGUgb2YgYSByb2FkKS4gVGhlcmUgYXJlIHRocmVlIHR5cGVzIG9mIHZlY3RvciBnZW9tZXRyaWVzOg0KDQoqICAgKipQb2ludHM6KiogQSBzaW5nbGUgY29vcmRpbmF0ZSBwYWlyICh4LCB5KSByZXByZXNlbnRpbmcgYSBzcGVjaWZpYyBsb2NhdGlvbi4NCiAgICAqICAgKipXaGVuIHRvIHVzZToqKiBGb3IgZmVhdHVyZXMgdGhhdCBoYXZlIGEgbG9jYXRpb24gYnV0IG5vIG1lYW5pbmdmdWwgYXJlYSBvciBsZW5ndGggYXQgeW91ciBzY2FsZSBvZiBhbmFseXNpcy4NCiAgICAqICAgKipTb21hbGlhL1NvbWFsaWxhbmQgRXhhbXBsZToqKiBUaGUgbG9jYXRpb24gb2YgYSBzcGVjaWZpYyBob3NwaXRhbCBpbiBNb2dhZGlzaHUsIGEgd2F0ZXIgd2VsbCBpbiBhIHJ1cmFsIHZpbGxhZ2UsIG9yIGFuIElEUCAoSW50ZXJuYWxseSBEaXNwbGFjZWQgUGVyc29ucykgY2FtcC4gRWFjaCBpcyBhIGRpc3RpbmN0LCBzaW5nbGUgcG9pbnQuDQoNCiogICAqKkxpbmVzIChvciBQb2x5bGluZXMpOioqIEEgc2VxdWVuY2Ugb2YgY29ubmVjdGVkIGNvb3JkaW5hdGUgcGFpcnMuDQogICAgKiAgICoqV2hlbiB0byB1c2U6KiogRm9yIGZlYXR1cmVzIHRoYXQgaGF2ZSBsZW5ndGggYnV0IG5vdCBhcmVhLCBsaWtlIG5ldHdvcmtzIG9yIGJvdW5kYXJpZXMuDQogICAgKiAgICoqU29tYWxpYS9Tb21hbGlsYW5kIEV4YW1wbGU6KiogVGhlIHBhdGggb2YgdGhlIEp1YmJhIFJpdmVyLCB0aGUgcm9hZCBuZXR3b3JrIGNvbm5lY3RpbmcgSGFyZ2Vpc2EgYW5kIEJlcmJlcmEsIG9yIHRoZSBhZG1pbmlzdHJhdGl2ZSBib3JkZXIgYmV0d2VlbiBQdW50bGFuZCBhbmQgR2FsbXVkdWcuDQoNCiogICAqKlBvbHlnb25zOioqIEEgc2VyaWVzIG9mIGNvbm5lY3RlZCBjb29yZGluYXRlIHBhaXJzIHRoYXQgZm9ybSBhIGNsb3NlZCBzaGFwZSwgcmVwcmVzZW50aW5nIGFuIGFyZWEuDQogICAgKiAgICoqV2hlbiB0byB1c2U6KiogRm9yIGZlYXR1cmVzIHRoYXQgaGF2ZSBhIGRlZmluZWQgYm91bmRhcnkgYW5kIGFyZWEuDQogICAgKiAgICoqU29tYWxpYS9Tb21hbGlsYW5kIEV4YW1wbGU6KiogVGhlIGJvdW5kYXJ5IG9mIHRoZSBCYW5hYWRpciByZWdpb24sIHRoZSBhcmVhIG9mIGEgbmF0aW9uYWwgcGFyaywgb3IgdGhlIGZvb3RwcmludCBvZiBhIHNwZWNpZmljIG5laWdoYm9yaG9vZCBpbiBCdXJhby4NCg0KKipWZWN0b3IgZGF0YSBpcyBpZGVhbCB3aGVuIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiB0aGUgZmVhdHVyZXMgdGhlbXNlbHZlcyBhbmQgdGhlaXIgcmVsYXRpb25zaGlwcy4qKg0KDQojIyMjIDIuMiBSYXN0ZXIgRGF0YTogQSBHcmlkIG9mIFZhbHVlcw0KDQpUaGluayBvZiByYXN0ZXIgZGF0YSBhcyBhICoqZGlnaXRhbCBwaG90b2dyYXBoIG9yIGEgZ3JpZCoqLiBJdCByZXByZXNlbnRzIHRoZSB3b3JsZCBhcyBhIGNvbnRpbnVvdXMgc3VyZmFjZSwgZGl2aWRlZCBpbnRvIGEgbWF0cml4IG9mIGVxdWFsbHkgc2l6ZWQgY2VsbHMgKG9yIHBpeGVscykuIEVhY2ggY2VsbCBoYXMgYSBzaW5nbGUgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBjaGFyYWN0ZXJpc3RpYyBvZiB0aGF0IHNwZWNpZmljIGxvY2F0aW9uLg0KDQoqICAgKipXaGVuIHRvIHVzZToqKiBGb3IgcGhlbm9tZW5hIHRoYXQgdmFyeSBjb250aW51b3VzbHkgYWNyb3NzIGEgbGFuZHNjYXBlLCB3aXRoIG5vIGNsZWFyIGJvdW5kYXJpZXMuDQoqICAgKipTb21hbGlhL1NvbWFsaWxhbmQgRXhhbXBsZXM6KioNCiAgICAqICAgKipFbGV2YXRpb24gRGF0YSAoREVNKToqKiBBIGdyaWQgd2hlcmUgZWFjaCBjZWxsJ3MgdmFsdWUgaXMgaXRzIGVsZXZhdGlvbiBhYm92ZSBzZWEgbGV2ZWwuIFRoaXMgaXMgY3J1Y2lhbCBmb3IgdW5kZXJzdGFuZGluZyB0b3BvZ3JhcGh5IGFuZCBmbG9vZCByaXNrLg0KICAgICogICAqKkNsaW1hdGUgRGF0YToqKiBBIGdyaWQgd2hlcmUgZWFjaCBjZWxsJ3MgdmFsdWUgY291bGQgYmUgdGhlIGF2ZXJhZ2UgbW9udGhseSByYWluZmFsbCwgdGVtcGVyYXR1cmUsIG9yIGEgdmVnZXRhdGlvbiBpbmRleCAobGlrZSBORFZJKSB0byBtb25pdG9yIGRyb3VnaHQgY29uZGl0aW9ucy4NCiAgICAqICAgKipTYXRlbGxpdGUgSW1hZ2VyeToqKiBBIHBpY3R1cmUgZnJvbSBzcGFjZSB3aGVyZSBlYWNoIHBpeGVsIGhhcyBhIGNvbG9yIHZhbHVlLCB1c2VkIHRvIGlkZW50aWZ5IGxhbmQgY292ZXIgKHVyYmFuLCBmYXJtLCBkZXNlcnQpLg0KDQoqKlJhc3RlciBkYXRhIGlzIGlkZWFsIHdoZW4geW91IGFyZSBzdHVkeWluZyBob3cgYSBtZWFzdXJlbWVudCB2YXJpZXMgb3ZlciBhIHN1cmZhY2UuKioNCg0KfCBGZWF0dXJlIHwgVmVjdG9yIERhdGEgfCBSYXN0ZXIgRGF0YSB8DQp8IDotLS0gfCA6LS0tIHwgOi0tLSB8DQp8ICoqUmVwcmVzZW50YXRpb24qKiB8IERpc2NyZXRlIHBvaW50cywgbGluZXMsIHBvbHlnb25zIHwgQ29udGludW91cyBncmlkIG9mIGNlbGxzIChwaXhlbHMpIHwNCnwgKipTdHJ1Y3R1cmUqKiB8IENvb3JkaW5hdGVzIGFuZCBhdHRyaWJ1dGVzIHwgTWF0cml4IG9mIHZhbHVlcyB8DQp8ICoqQmVzdCBGb3IqKiB8IEFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMsIHJvYWRzLCBsb2NhdGlvbnMgfCBFbGV2YXRpb24sIHRlbXBlcmF0dXJlLCBzYXRlbGxpdGUgaW1hZ2VyeSB8DQp8ICoqRXhhbXBsZSoqIHwgQSBzaGFwZWZpbGUgb2YgU29tYWxpYSdzIHJlZ2lvbnMgfCBBIEdlb1RJRkYgZmlsZSBvZiByYWluZmFsbCBpbiB0aGUgSG9ybiBvZiBBZnJpY2EgfA0KfCAqKktleSBRdWVzdGlvbioqIHwgKldoYXQqIGlzICp3aGVyZSo/IChlLmcuLCBhIGhvc3BpdGFsKSB8ICpIb3cgbXVjaCogb2Ygc29tZXRoaW5nIGlzICpldmVyeXdoZXJlKj8gKGUuZy4sIGVsZXZhdGlvbikgfA0KDQotLS0NCg0KIyMgMy4gVGhlIFRocmVlIENsYXNzaWNhbCBUeXBlcyBvZiBTcGF0aWFsIERhdGENCg0KQnVpbGRpbmcgb24gdGhlIHZlY3Rvci9yYXN0ZXIgbW9kZWxzLCBzcGF0aWFsIHN0YXRpc3RpY2lhbnMgY2xhc3NpZnkgZGF0YSBpbnRvIHRocmVlIG1haW4gdHlwZXMgYmFzZWQgb24gdGhlIG5hdHVyZSBvZiB0aGUgc3BhdGlhbCBwcm9jZXNzIGJlaW5nIG9ic2VydmVkLiBVbmRlcnN0YW5kaW5nIHRoaXMgY2xhc3NpZmljYXRpb24gaXMga2V5IHRvIGNob29zaW5nIHRoZSBjb3JyZWN0IHN0YXRpc3RpY2FsIG1ldGhvZHMgbGF0ZXIgb24uDQoNCiMjIyAzLjEgQXJlYWwgKG9yIExhdHRpY2UpIERhdGENCg0KKipXaGF0IGl0IGlzOioqIEFyZWFsIGRhdGEgY29uc2lzdHMgb2YgdmFsdWVzIHRoYXQgYXJlICoqYWdncmVnYXRlZCBvdmVyIHBvbHlnb25zKiouIFRoZSBkb21haW4gaXMgYSBmaXhlZCBzZXQgb2YgYXJlYXMsIGFuZCB3ZSBoYXZlIGEgc3VtbWFyeSBzdGF0aXN0aWMgKGxpa2UgYSBjb3VudCwgYXZlcmFnZSwgb3IgcmF0ZSkgZm9yIGVhY2ggb25lLiBUaGlzIGlzIHBlcmhhcHMgdGhlIG1vc3QgY29tbW9uIHR5cGUgb2Ygc3BhdGlhbCBkYXRhIGluIHB1YmxpYyBoZWFsdGggYW5kIHNvY2lhbCBzY2llbmNlcy4NCg0KKipUaGUgS2V5IFF1ZXN0aW9uIGl0IEFuc3dlcnM6KiogIkhvdyBkb2VzIGEgdmFsdWUgb3IgY291bnQgdmFyeSBmcm9tIGFyZWEgdG8gYXJlYSwgYW5kIGFyZSBuZWlnaGJvcmluZyBhcmVhcyBtb3JlIHNpbWlsYXIgdGhhbiBkaXN0YW50IG9uZXM/Ig0KDQoqKldoZW4gdG8gVXNlIEl0IGFuZCBXaHk6KioNCiogICAqKlByaXZhY3k6KiogV2hlbiBpbmRpdmlkdWFsLWxldmVsIGRhdGEgKGxpa2UgcGF0aWVudCBhZGRyZXNzZXMpIGlzIHRvbyBzZW5zaXRpdmUgdG8gc2hhcmUsIGFnZ3JlZ2F0aW5nIHRvIGEgZGlzdHJpY3Qgb3IgcmVnaW9uYWwgbGV2ZWwgcHJvdGVjdHMgY29uZmlkZW50aWFsaXR5Lg0KKiAgICoqQWRtaW5pc3RyYXRpdmUgRGF0YToqKiBEYXRhIGlzIG9mdGVuIGNvbGxlY3RlZCBhbmQgcmVwb3J0ZWQgYnkgYWRtaW5pc3RyYXRpdmUgdW5pdHMgKGUuZy4sIGNlbnN1cyBidXJlYXVzLCBtaW5pc3RyaWVzIG9mIGhlYWx0aCkuDQoqICAgKipTdGFibGUgUmF0ZXM6KiogQ2FsY3VsYXRpbmcgcmF0ZXMgKGUuZy4sIGRpc2Vhc2UgaW5jaWRlbmNlKSByZXF1aXJlcyBhIGRlbm9taW5hdG9yIChwb3B1bGF0aW9uKSwgd2hpY2ggaXMgdXN1YWxseSBhdmFpbGFibGUgYXQgYW4gYXJlYWwgbGV2ZWwuDQoNCioqU29tYWxpYS9Tb21hbGlsYW5kIEV4YW1wbGU6IE1hcHBpbmcgTWFsbnV0cml0aW9uIENhc2VzIGJ5IFJlZ2lvbioqDQpJbWFnaW5lIHdlIGhhdmUgdGhlIG51bWJlciBvZiBzZXZlcmUgYWN1dGUgbWFsbnV0cml0aW9uIChTQU0pIGNhc2VzIHJlcG9ydGVkIGJ5IGhlYWx0aCBmYWNpbGl0aWVzIGluIGVhY2ggcmVnaW9uIG9mIFNvbWFsaWxhbmQuIFdlIHdhbnQgdG8gc2VlIGlmIHRoZXJlIGFyZSByZWdpb25hbCBob3RzcG90cy4NCg0KYGBge3IgYXJlYWxfZXhhbXBsZX0NCiMgTG9hZCBTb21hbGlhIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMgKHdlJ2xsIHVzZSB0aGlzIGFzIG91ciBiYXNlKQ0KIyBFbnN1cmUgInNvbV9hZG1ibmRhX2FkbTFfb2NoYV8yMDI1MDEwOC5zaHAiIGlzIGluIHlvdXIgd29ya2luZyBkaXJlY3RvcnkNCnNvbV9hZG0xIDwtIHN0X3JlYWQoInNvbV9hZG1ibmRhX2FkbTFfb2NoYV8yMDI1MDEwOC5zaHAiKQ0KDQojIEZpbHRlciBmb3IgU29tYWxpbGFuZCByZWdpb25zDQpzb21hbGlsYW5kX3JlZ2lvbnMgPC0gc29tX2FkbTEgJT4lDQogIGZpbHRlcihBRE0xX0VOICVpbiUgYygiQXdkYWwiLCAiV29xb295aSBHYWxiZWVkIiwgIlRvZ2RoZWVyIiwgIlNhbmFhZyIsICJTb29sIikpDQoNCiMgQ3JlYXRlIHNvbWUgZmljdGlvbmFsIG1hbG51dHJpdGlvbiBkYXRhIHRvIGpvaW4NCm1hbG51dHJpdGlvbl9kYXRhIDwtIGRhdGEuZnJhbWUoDQogIEFETTFfRU4gPSBjKCJBd2RhbCIsICJXb3Fvb3lpIEdhbGJlZWQiLCAiVG9nZGhlZXIiLCAiU2FuYWFnIiwgIlNvb2wiKSwNCiAgU0FNX2Nhc2VzID0gYygxNTAsIDMyMCwgMjEwLCAxODAsIDI1MCkNCikNCg0KIyBKb2luIHRoZSBkYXRhIHRvIHRoZSBzcGF0aWFsIG9iamVjdA0Kc29tYWxpbGFuZF9tYXBfZGF0YSA8LSBsZWZ0X2pvaW4oc29tYWxpbGFuZF9yZWdpb25zLCBtYWxudXRyaXRpb25fZGF0YSwgYnkgPSAiQURNMV9FTiIpDQoNCiMgUGxvdCB0aGUgYXJlYWwgZGF0YQ0KZ2dwbG90KGRhdGEgPSBzb21hbGlsYW5kX21hcF9kYXRhKSArDQogIGdlb21fc2YoYWVzKGZpbGwgPSBTQU1fY2FzZXMpKSArDQogIGdlb21fc2ZfdGV4dChhZXMobGFiZWwgPSBBRE0xX0VOKSwgc2l6ZSA9IDMpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MobmFtZSA9ICJTQU0gQ2FzZXMiKSArDQogIGdndGl0bGUoIkFyZWFsIERhdGE6IE1hbG51dHJpdGlvbiBDYXNlcyBieSBSZWdpb24gaW4gU29tYWxpbGFuZCIpICsNCiAgdGhlbWVfdm9pZCgpDQpgYGANCg0KIyMjIDMuMiBHZW9zdGF0aXN0aWNhbCBEYXRhDQoNCioqV2hhdCBpdCBpczoqKiBHZW9zdGF0aXN0aWNhbCBkYXRhIGNvbnNpc3RzIG9mIG1lYXN1cmVtZW50cyBvZiBhICoqY29udGludW91cyBwaGVub21lbm9uIHRha2VuIGF0IHNwZWNpZmljIHBvaW50IGxvY2F0aW9ucyoqLiBXZSBhc3N1bWUgdGhlIHVuZGVybHlpbmcgcGhlbm9tZW5vbiAoZS5nLiwgdGVtcGVyYXR1cmUsIHBvbGx1dGlvbikgZXhpc3RzIGV2ZXJ5d2hlcmUsIGJ1dCB3ZSBjYW4gb25seSBhZmZvcmQgdG8gc2FtcGxlIGl0IGF0IGEgZmluaXRlIG51bWJlciBvZiBzaXRlcy4NCg0KKipUaGUgS2V5IFF1ZXN0aW9uIGl0IEFuc3dlcnM6KiogIkdpdmVuIHRoZXNlIHNhbXBsZSBwb2ludHMsIGNhbiB3ZSBwcmVkaWN0IHRoZSB2YWx1ZSBvZiB0aGUgcGhlbm9tZW5vbiBhdCB1bi1zYW1wbGVkIGxvY2F0aW9ucz8gKFRoaXMgaXMgY2FsbGVkIGludGVycG9sYXRpb24gb3Iga3JpZ2luZykuIg0KDQoqKldoZW4gdG8gVXNlIEl0IGFuZCBXaHk6KioNCiogICAqKkVudmlyb25tZW50YWwgTW9uaXRvcmluZzoqKiBJdCdzIGltcG9zc2libGUgdG8gbWVhc3VyZSBhaXIgcXVhbGl0eSBvciBzb2lsIGNvbnRhbWluYXRpb24gZXZlcnl3aGVyZS4gV2UgdXNlIG1vbml0b3Jpbmcgc3RhdGlvbnMgKHBvaW50cykgdG8gc2FtcGxlIHRoZSBjb250aW51b3VzIGZpZWxkLg0KKiAgICoqUmVzb3VyY2UgRXhwbG9yYXRpb246KiogR2VvbG9naXN0cyBkcmlsbCBhdCBzcGVjaWZpYyBsb2NhdGlvbnMgKHBvaW50cykgdG8gaW5mZXIgdGhlIGV4dGVudCBvZiBhbiB1bmRlcmdyb3VuZCBvaWwgcmVzZXJ2ZSAoYSBjb250aW51b3VzIGZpZWxkKS4NCiogICAqKldoZW4gdGhlIHVuZGVybHlpbmcgcHJvY2VzcyBpcyB0cnVseSBjb250aW51b3VzLioqDQoNCioqU29tYWxpYS9Tb21hbGlsYW5kIEV4YW1wbGU6IE1lYXN1cmluZyBXYXRlciBTYWxpbml0eSBhdCBXZWxscyoqDQpJbWFnaW5lIHdlIGFyZSBtb25pdG9yaW5nIHRoZSBzYWxpbml0eSBvZiBncm91bmR3YXRlciBhdCBzZXZlcmFsIHdlbGxzIGFsb25nIHRoZSBTaGFiZWxsZSBSaXZlciB0byBjaGVjayBmb3Igc2FsdHdhdGVyIGludHJ1c2lvbi4gV2Ugd2FudCB0byBjcmVhdGUgYSBjb250aW51b3VzIG1hcCBvZiBzYWxpbml0eSBmcm9tIHRoZXNlIHBvaW50IG1lYXN1cmVtZW50cy4NCg0KYGBge3IgZ2Vvc3RhdGlzdGljYWxfZXhhbXBsZX0NCiMgQ3JlYXRlIGEgZmljdGlvbmFsIGRhdGFzZXQgb2Ygd2VsbCBsb2NhdGlvbnMgYW5kIHNhbGluaXR5IG1lYXN1cmVtZW50cw0Kd2VsbHNfZGF0YSA8LSBkYXRhLmZyYW1lKA0KICB3ZWxsX2lkID0gYygiVzEiLCAiVzIiLCAiVzMiLCAiVzQiLCAiVzUiKSwNCiAgbG9uZ2l0dWRlID0gYyg0NS4wLCA0NS4yLCA0NS41LCA0NS44LCA0Ni4xKSwNCiAgbGF0aXR1ZGUgPSBjKDIuMiwgMi41LCAyLjksIDMuMiwgMy41KSwNCiAgc2FsaW5pdHlfcHBtID0gYyg4MDAsIDk1MCwgMTEwMCwgMTUwMCwgMjIwMCkgIyBQYXJ0cyBQZXIgTWlsbGlvbg0KKQ0KDQojIENvbnZlcnQgdGhlIGRhdGEgZnJhbWUgdG8gYSBzcGF0aWFsIHNmIG9iamVjdA0Kd2VsbHNfc2YgPC0gc3RfYXNfc2Yod2VsbHNfZGF0YSwgY29vcmRzID0gYygibG9uZ2l0dWRlIiwgImxhdGl0dWRlIiksIGNycyA9IDQzMjYpDQoNCiMgUGxvdCB0aGUgcG9pbnRzIG9uIHRoZSBtYXAgb2YgU29tYWxpYQ0KZ2dwbG90KCkgKw0KICBnZW9tX3NmKGRhdGEgPSBzb21fYWRtMSwgZmlsbCA9ICJraGFraSIsIGNvbG9yID0gImdyZXkiKSArICMgQmFzZSBtYXANCiAgZ2VvbV9zZihkYXRhID0gd2VsbHNfc2YsIGFlcyhjb2xvciA9IHNhbGluaXR5X3BwbSksIHNpemUgPSA0KSArDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYyhuYW1lID0gIlNhbGluaXR5IChQUE0pIikgKw0KICBnZ3RpdGxlKCJHZW9zdGF0aXN0aWNhbCBEYXRhOiBXYXRlciBTYWxpbml0eSBhdCBXZWxscyIpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNCiMjIyAzLjMgUG9pbnQgUGF0dGVybiBEYXRhDQoNCioqV2hhdCBpdCBpczoqKiBJbiBhIHBvaW50IHBhdHRlcm4sIHRoZSAqKmxvY2F0aW9ucyBvZiB0aGUgZXZlbnRzIGFyZSB0aGUgZGF0YSB0aGVtc2VsdmVzKiouIFdlIGFyZSBub3QgaW50ZXJlc3RlZCBpbiBhIHZhbHVlICphdCogdGhlIHBvaW50LCBidXQgcmF0aGVyIGluIHRoZSBzcGF0aWFsIGFycmFuZ2VtZW50IG9mIHRoZSBwb2ludHMuIFRoZSB1bmRlcmx5aW5nIHByb2Nlc3MgaXMgd2hhdCBnZW5lcmF0ZXMgdGhlIGxvY2F0aW9ucy4NCg0KKipUaGUgS2V5IFF1ZXN0aW9uIGl0IEFuc3dlcnM6KiogIkFyZSB0aGUgZXZlbnRzIGNsdXN0ZXJlZCwgcmFuZG9tbHkgZGlzdHJpYnV0ZWQsIG9yIHJlZ3VsYXJseSBzcGFjZWQ/IFdoYXQgcHJvY2VzcyBtaWdodCBiZSBnZW5lcmF0aW5nIHRoaXMgcGF0dGVybj8iDQoNCioqV2hlbiB0byBVc2UgSXQgYW5kIFdoeToqKg0KKiAgICoqRXBpZGVtaW9sb2d5OioqIFRvIHNlZSBpZiBkaXNlYXNlIGNhc2VzIGFyZSBjbHVzdGVyZWQgYXJvdW5kIGEgc291cmNlIG9mIGluZmVjdGlvbiAoZS5nLiwgYSBjb250YW1pbmF0ZWQgd2F0ZXIgcHVtcCkuDQoqICAgKipDcmltaW5vbG9neToqKiBUbyBpZGVudGlmeSBjcmltZSBob3RzcG90cy4NCiogICAqKkVjb2xvZ3k6KiogVG8gc3R1ZHkgdGhlIHRlcnJpdG9yaWFsIHBhdHRlcm5zIG9mIHBsYW50cyBvciBhbmltYWxzLg0KDQoqKlNvbWFsaWEvU29tYWxpbGFuZCBFeGFtcGxlOiBNYXBwaW5nIFNlY3VyaXR5IEluY2lkZW50cyBpbiBNb2dhZGlzaHUqKg0KQW4gTkdPIGlzIGFuYWx5emluZyB0aGUgbG9jYXRpb25zIG9mIHJlcG9ydGVkIHNlY3VyaXR5IGluY2lkZW50cyBpbiB0aGUgQmFuYWFkaXIgcmVnaW9uICh3aGljaCBjb250YWlucyBNb2dhZGlzaHUpIHRvIHVuZGVyc3RhbmQgaWYgdGhleSBhcmUgY29uY2VudHJhdGVkIGluIHNwZWNpZmljIGFyZWFzLg0KDQpgYGB7ciBwb2ludF9wYXR0ZXJuX2V4YW1wbGV9DQojIEdldCB0aGUgcG9seWdvbiBmb3IgdGhlIEJhbmFkaXIgcmVnaW9uDQpiYW5hZGlyX3JlZ2lvbiA8LSBzb21fYWRtMSAlPiUgZmlsdGVyKEFETTFfRU4gPT0gIkJhbmFkaXIiKQ0KDQojIEdlbmVyYXRlIDEwMCByYW5kb20gcG9pbnRzICp3aXRoaW4qIHRoZSBCYW5hZGlyIHBvbHlnb24gdG8gc2ltdWxhdGUgaW5jaWRlbnRzDQojIEluIGEgcmVhbCBhbmFseXNpcywgdGhlc2Ugd291bGQgYmUgYWN0dWFsIGNvb3JkaW5hdGVzIG9mIGluY2lkZW50cw0Kc2V0LnNlZWQoMTIzKSAjIGZvciByZXByb2R1Y2liaWxpdHkNCmluY2lkZW50X3BvaW50cyA8LSBzdF9zYW1wbGUoYmFuYWRpcl9yZWdpb24sIHNpemUgPSAxMDApDQoNCiMgUGxvdCB0aGUgcG9pbnQgcGF0dGVybg0KZ2dwbG90KCkgKw0KICBnZW9tX3NmKGRhdGEgPSBiYW5hZGlyX3JlZ2lvbiwgZmlsbCA9ICJncmV5ODAiKSArDQogIGdlb21fc2YoZGF0YSA9IGluY2lkZW50X3BvaW50cywgY29sb3IgPSAicmVkIiwgYWxwaGEgPSAwLjYsIHNpemUgPSAyKSArDQogIGdndGl0bGUoIlBvaW50IFBhdHRlcm46IFNpbXVsYXRlZCBTZWN1cml0eSBJbmNpZGVudHMgaW4gQmFuYWRpciIpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNCiMjIDQuIFN1bW1hcnkgYW5kIEEgR2xpbXBzZSBBaGVhZA0KDQpVbmRlcnN0YW5kaW5nIHRoZXNlIGRhdGEgdHlwZXMgaXMgdGhlIGZpcnN0IGFuZCBtb3N0IGltcG9ydGFudCBzdGVwIGluIGFueSBzcGF0aWFsIGFuYWx5c2lzLiBDaG9vc2luZyB0aGUgd3JvbmcgY2xhc3NpZmljYXRpb24gY2FuIGxlYWQgdG8gdXNpbmcgaW5hcHByb3ByaWF0ZSBtZXRob2RzIGFuZCBkcmF3aW5nIGluY29ycmVjdCBjb25jbHVzaW9ucy4NCg0KfCBEYXRhIFR5cGUgfCBXaGF0IGl0IFJlcHJlc2VudHMgfCBLZXkgUXVlc3Rpb24gfCBTb21hbGlhL1NvbWFsaWxhbmQgRXhhbXBsZSB8IENvbW1vbiBHb2FsIHwNCnwgOi0tLSB8IDotLS0gfCA6LS0tIHwgOi0tLSB8IDotLS0gfA0KfCAqKkFyZWFsKiogfCBBZ2dyZWdhdGVkIHZhbHVlcyBpbiBwb2x5Z29ucyB8IEhvdyBkbyB2YWx1ZXMgdmFyeSBieSBhcmVhPyB8IENob2xlcmEgY2FzZXMgcGVyIGRpc3RyaWN0IHwgRGlzZWFzZSBtYXBwaW5nLCBob3RzcG90IGRldGVjdGlvbiB8DQp8ICoqR2Vvc3RhdGlzdGljYWwqKnwgU2FtcGxlcyBvZiBhIGNvbnRpbnVvdXMgZmllbGQgfCBDYW4gd2UgcHJlZGljdCB2YWx1ZXMgZXZlcnl3aGVyZT8gfCBSYWluZmFsbCBhdCB3ZWF0aGVyIHN0YXRpb25zIHwgSW50ZXJwb2xhdGlvbiAoS3JpZ2luZyksIHN1cmZhY2UgY3JlYXRpb24gfA0KfCAqKlBvaW50IFBhdHRlcm4qKnwgTG9jYXRpb25zIG9mIGV2ZW50cyB8IElzIHRoZXJlIGNsdXN0ZXJpbmc/IHwgTG9jYXRpb25zIG9mIElEUCBjYW1wcyB8IENsdXN0ZXIgYW5hbHlzaXMsIGRlbnNpdHkgZXN0aW1hdGlvbiB8DQoNCkluIHRoZSB1cGNvbWluZyBtb2R1bGVzLCB3ZSB3aWxsIGxlYXJuIGhvdyB0byB1c2UgUiBwYWNrYWdlcyBsaWtlIGBzZmAgYW5kIGB0ZXJyYWAgdG8gbWFuaXB1bGF0ZSB0aGVzZSBkYXRhIHR5cGVzIGFuZCB0aGVuIGFwcGx5IHBvd2VyZnVsIHN0YXRpc3RpY2FsIHRlY2huaXF1ZXMgdG8gYW5zd2VyIHRoZXNlIGtleSBxdWVzdGlvbnMuIFdlIHdpbGwgYWxzbyB0b3VjaCB1cG9uIG1vcmUgYWR2YW5jZWQgY29uY2VwdHMgbGlrZSAqKnNwYXRpby10ZW1wb3JhbCBkYXRhKiosIHdoaWNoIHRyYWNrcyB0aGVzZSBwYXR0ZXJucyBvdmVyIHRpbWXigJRmb3IgZXhhbXBsZSwgbWFwcGluZyB0aGUgc3ByZWFkIG9mIGEgbWVhc2xlcyBvdXRicmVhayBhY3Jvc3MgZGlzdHJpY3RzIG92ZXIgc2V2ZXJhbCBtb250aHMuDQpgYGA=