diff --git a/.markdownlint.yml b/.markdownlint.yml
index a2fbcaa7afb759390347b5069e8f571df1b3dd1f..865f20520620c71b0e67c7548fb53c390cc1e6a8 100644
--- a/.markdownlint.yml
+++ b/.markdownlint.yml
@@ -14,3 +14,12 @@ MD013:
   heading_line_length: 100
   # Number of characters for code blocks
   code_block_line_length: 100
+  # Exclude tables
+  tables: false
+  # Exclude code blocks
+  code_blocks: false
+
+# MD033/no-inline-html - Inline HTML
+MD033:
+  # Allowed elements
+  allowed_elements: [ br, sup ]
diff --git a/docs/About-the-NSHMP.md b/docs/About-the-NSHMP.md
new file mode 100644
index 0000000000000000000000000000000000000000..0e1c508a2b349865f66321b14697f7b35167182f
--- /dev/null
+++ b/docs/About-the-NSHMP.md
@@ -0,0 +1,23 @@
+# About the NSHMP
+
+The National Seismic Hazard Model Project (NSHMP) produces national seismic hazard models (NSHMs)
+for the United States and territories. The project came into existence following passage of the
+Earthquake Hazards Reduction Act of 1977, as amended:
+
+>3A: "Conduct a systematic assessment of the seismic risks in each region of the Nation prone to
+>earthquakes..."
+>
+>J: "Maintain suitable seismic hazard maps in support of building codes for structures and
+>lifelines, including additional maps needed for performance-based design approaches."
+
+The NSHMP primarily produces long-term NSHMs that are used in U.S. building codes and numerous
+other seismic design requirements. The models are used is site-specific analyses and also for
+defining likely earthquake scenarios for emergency planning. NSHMs are considered reference
+(or baseline) models used by the risk, insurance and reinsurance industries, and they are also
+considered in other industries such as real estate lending. A 9-member steering committee of
+academic and industry experts provides technical oversight and recommendations to the NSHMP.
+
+An NSHM defines the set of likely earthquake sources and their rates in a particular region. Given
+parameters of the earhtquake source and a site of interest, ground motion models (GMMs) are used
+to estimate ground shaking from the set of earthquakes. The NSHMP routinely updates NSHMs for the
+U.S. and its territories to consider the best available science.
diff --git a/docs/Building-&-Running.md b/docs/Building-&-Running.md
new file mode 100644
index 0000000000000000000000000000000000000000..2184c25f133d3b1789c83d9e00905c377765a83d
--- /dev/null
+++ b/docs/Building-&-Running.md
@@ -0,0 +1,146 @@
+# Building & Running
+
+## Related Pages
+
+TODO
+
+## Build & Run Options
+
+* [Build and run locally](#build-and-run-locally)
+* [Run with Docker](#run-with-docker)
+
+## Build and Run Locally
+
+Building and running *nshmp-haz* requires prior installation of Git and Java. Please see the
+[developer basics](developer-basics) page for system configuration guidance.  
+
+### Building
+
+Navigate to a location on your system where you want *nshmp-haz* code to reside, clone the
+repository, and compile:
+
+```bash
+cd /path/to/project/directory
+git clone https://code.usgs.gov/ghsc/nshmp/nshmp-haz.git
+cd nshmp-haz
+./gradlew assemble
+```
+
+This creates a single file, `build/libs/nshmp-haz.jar` that may be used for hazard calculations.
+`./gradlew` executes the Gradle Wrapper script (there is a `gradlew.bat` equivalent for Windows
+users using the native command prompt). This executes any tasks (e.g. `assemble`) after
+downloading all required dependencies, including Gradle itself.
+
+### Computing Hazard
+
+The `HazardCalc` program computes hazard curves at one or more sites for a variety of intensity
+measures. For example:
+
+```bash
+java -cp path/to/nshmp-haz.jar gov.usgs.earthquake.nshmp.HazardCalc model sites [config]
+```
+
+At a minimum, the hazard source [model](hazard-model) and the [site](site-specification)(s) at
+which to perform calculations must be specified. The source model should specified a path to a
+directory. A single site may be specified with a string; multiple sites must be specified using
+either a comma-delimited (CSV) or [GeoJSON](http://geojson.org) file. The path to a custom
+[configuration](calculation-configuration) file containing user-specific settings may optionally
+be supplied as a third argument. It can be used to override any calculation settings; if absent
+[default](calculation-configuration) values are used.
+
+See the [examples](/ghsc/nshmp/nshmp-haz-v2/-/tree/master/etc/examples) directory for more details.
+
+### Computing Disaggregations
+
+Like `HazardCalc`, the `DisaggCalc` program performs disaggregations at one or more sites for a
+variety of intensity measures, but requires an additional `returnPeriod` argument, in years. For
+example:
+
+```bash
+java -cp nshmp-haz.jar gov.usgs.earthquake.nshmp.DisaggCalc model sites returnPeriod [config]
+```
+
+Disaggregations build on and output `HazardCalc` results along with other disaggregation specific
+files. Disaggregations also have some independent
+[configuration](calculation-configuration#config-disagg) options.
+
+## Run with [Docker](https://docs.docker.com/install/)
+
+To ensure you are have the latest *nshmp-haz* update, always first pull the image from Docker:
+
+```bash
+docker pull usgs/nshmp-haz
+```
+
+### Docker Memory on Mac
+
+By default, Docker Desktop for Mac is set to use 2 GB runtime memory. To run *nshmp-haz*, the
+memory available to Docker must be [increased](https://docs.docker.com/docker-for-mac/#advanced)
+to a minimum of 4 GB.
+
+### Running
+
+The *nshmp-haz* application may be run as a Docker container which mitigates the need to install
+Git, Java, or other dependencies besides Docker. A public image is available on
+Docker hub at [https://hub.docker.com/r/usgs/nshmp-haz](https://hub.docker.com/r/usgs/nshmp-haz)
+which can be run with:
+
+```bash
+docker run \
+    -e PROGRAM=<disagg | hazard | rate> \
+    -e MODEL=<CONUS-2018 | HAWAII-2021> \
+    -e RETURN_PERIOD=<RETURN_PERIOD> \
+    -v /absolute/path/to/sites/file:/app/sites.<geojson | csv> \
+    -v /absolute/path/to/config/file:/app/config.json \
+    -v /absolute/path/to/output:/app/output \
+    usgs/nshmp-haz
+
+# Example
+docker run \
+    -e PROGRAM=hazard \
+    -e MODEL=CONUS-2018 \
+    -v $(pwd)/sites.geojson:/app/sites.geojson \
+    -v $(pwd)/config.json:/app/config.json \
+    -v $(pwd)/hazout:/app/output \
+    usgs/nshmp-haz
+```
+
+Where: (TODO links below need checking)
+
+* `PROGRAM` is the nshmp-haz program to run:
+  * disagg = `DisaggCalc`
+  * hazard = `HazardCalc`
+  * rate = `RateCalc`
+
+* `MODEL` is the [USGS model (NSHM)](usgs-models) to run:
+  * CONUS-2018: [Conterminous U.S. 2018](https://github.com/usgs/nshm-conus)
+  * HAWAII-2021: [Hawaii 2021](https://code.usgs.gov/ghsc/nshmp/nshm-hawaii)
+
+* `RETURN_PERIOD`, in years, is only required when running a disaggregation
+
+* Other arguments:
+  * (required) The absolute path to a GeoJSON or CSV [site(s)](site-specification) file
+    * CSV example: `$(pwd)/my-csv-sites.csv:/app/sites.csv`
+    * GeoJSON example: `$(pwd)/my-geojson-sites.geojson:/app/sites.geojson`
+  * (optional) The absolute path to a [configuration](calculation-configuration) file
+    * Example: `$(pwd)/my-custom-config.json:/app/config.json`
+  * (required) The absolute path to an output directory
+    * Example: `$(pwd)/my-hazard-output:/app/output`
+
+### Run Customization
+
+When running *nshmp-haz* with Docker the initial (Xms) and maximum (Xmx) JVM memory sizes can
+be set with the environment flag (-e, -env):
+
+```bash
+docker run \
+    -e JAVA_XMS=<JAVA_XMS> \
+    -e JAVA_XMX=<JAVA_XMX> \
+    ...
+    usgs/nshmp-haz
+```
+
+Where:
+
+* `JAVA_XMS` is the intial memory for the JVM (default: system)
+* `JAVA_XMX` is the maximum memory for the JVM (default: 8g)
diff --git a/docs/Calculation-Configuration.md b/docs/Calculation-Configuration.md
new file mode 100644
index 0000000000000000000000000000000000000000..e79851b26cd95b484107fa663ea93ad3c7608b8f
--- /dev/null
+++ b/docs/Calculation-Configuration.md
@@ -0,0 +1,95 @@
+# Calculation Configuration
+
+A `calc-config.json` file _may_ reside at the root of every [hazard model](hazard-model). This
+file, if present, will override any built-in default calculation configuration parameters, as
+listed below. See the [examples](/usgs/nshmp-haz/tree/master/etc/examples) directory, or any
+[USGS model](usgs-models), for concrete examples (TODO decide if last sentence needed and check
+links).
+
+## Calculation Configuration Parameters
+
+Calculation configuration parameters are optional (i.e. defaults are used for missing values) and
+may be overridden. See [building and running](building-&-running) and the
+[examples](/usgs/nshmp-haz/tree/master/etc/examples) for details.
+
+(TODO needs updated javadoc links)
+
+Parameter | Type | Default | Notes |
+--------- | ---- | ------- | ----- |
+__`hazard`__
+&nbsp;&nbsp;&nbsp;`.exceedanceModel`       |`String`   | `TRUNCATION_3SIGMA_UPPER` | [`ExceedanceModel`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/calc/ExceedanceModel.html)
+&nbsp;&nbsp;&nbsp;`.truncationLevel`       |`Double`   | `3.0`                     | [1](notes)
+&nbsp;&nbsp;&nbsp;`.imts`                  |`String[]` | `[ PGV, PGA, SA0P01, SA0P02, SA0P03, SA0P05, SA0P075, SA0P1, SA0P15, SA0P2, SA0P25, SA0P3, SA0P4, SA0P5, SA0P75, SA1P0, SA1P5, SA2P0, SA3P0, SA4P0, SA5P0, SA7P5, SA10P0 ]` | [`Imt`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/gmm/Imt.html)
+&nbsp;&nbsp;&nbsp;`.customImls`            |`Map<String, Double[]>`  | `{}` (empty object)     | [2](#notes)
+&nbsp;&nbsp;&nbsp;`.gmmUncertainty`        |`Boolean`  | `false`                   | [3](#notes)
+&nbsp;&nbsp;&nbsp;`.valueFormat`           |`String`   | `ANNUAL_RATE`             | [`ValueFormat`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/calc/ValueFormat.html)
+__`deagg`__
+&nbsp;&nbsp;&nbsp;`.bins`                  |`Object`   |                           | [4](#notes)
+&nbsp;&nbsp;&nbsp;`.contributorLimit`      |`Double`   | `0.1`                     | [5](#notes)
+__`rate`__
+&nbsp;&nbsp;&nbsp;`.bins`                  |`Object`   |                           | [6](#notes)
+&nbsp;&nbsp;&nbsp;`.distance`              |`Double`   | `20` km
+&nbsp;&nbsp;&nbsp;`.distributionFormat`    |`String`   | `INCREMENTAL`             | [`DistributionFormat`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/calc/DistributionFormat.html)
+&nbsp;&nbsp;&nbsp;`.timespan`              |`Double`   | `30` years
+&nbsp;&nbsp;&nbsp;`.valueFormat`           |`String`   | `ANNUAL_RATE`             | [`ValueFormat`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/calc/ValueFormat.html)
+__`site`__
+&nbsp;&nbsp;&nbsp;`.vs30`                  |`Double`   | `760.0`                   | [`Site`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/calc/Site.html)
+&nbsp;&nbsp;&nbsp;`.vsInferred`            |`Boolean`  | `true`
+&nbsp;&nbsp;&nbsp;`.z1p0`                  |`Double`   | `null`                    | [7](#notes)
+&nbsp;&nbsp;&nbsp;`.z2p5`                  |`Double`   | `null`                    | [7](#notes)
+__`output`__                               |
+&nbsp;&nbsp;&nbsp;`.directory`             |`String`   | `hazout`
+&nbsp;&nbsp;&nbsp;`.dataTypes`             |`String[]` | `[ TOTAL ]`               | [`DataType`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/calc/DataType.html)
+__`performance`__
+&nbsp;&nbsp;&nbsp;`.optimizeGrids`         |`Boolean`  | `true`                    | [8](#notes)
+&nbsp;&nbsp;&nbsp;`.smoothGrids`           |`Boolean`  | `true`                    | [9](#notes)
+&nbsp;&nbsp;&nbsp;`.systemPartition`       |`Integer`  | `1000`                    | [10](#notes)
+&nbsp;&nbsp;&nbsp;`.threadCount`           |`String`   | `ALL`                     | [`ThreadCount`](http://usgs.github.io/nshmp-haz/javadoc/index.html?gov/usgs/earthquake/nshmp/calc/ThreadCount.html)
+
+## Notes
+
+1. `hazard.truncationLevel`: This value is only used if the `hazard.exceedanceModel` requires a
+   limit (e.g. `TRUNCATION_UPPER_ONLY`)
+2. `hazard.gmmUncertainty`: If values for additional epistemic uncertainty on ground motion have
+   been defined, this value en/disables this feature.
+3. `hazard.customImls`: Hazard is computed at default intensity measure levels (IMLs) for every
+   supported intenisty measure type (IMT), but a user can specify different IMLs as needed (see
+   this [example](/usgs/nshmp-haz/blob/master/etc/examples/2-custom-config/config.json) and the
+   table of default IMLs, below).
+4. `disagg.bins`: This field maps to a data container that specifies the following default ranges
+   and intervals for distance, magnitude, and epsilon binning: `"bins": { "rMin": 0.0, "rMax":
+   1000.0, "Δr": 20.0, "mMin": 4.4, "mMax": 9.4, "Δm": 0.2, "εMin": -3.0, "εMax": 3.0, "Δε": 0.5 }`.
+   The `bins` object must be fully specified; partial overrides do not apply to nested JSON objects.
+5. `disagg.contributorLimit`: Specifies the cutoff (in %) below which contributing sources are not
+   listed in disaggregation results.
+6. `rate.bins`: This field maps to a data container that specifies the following default magnitude
+   binning range and interval: `"bins": { "mMin": 4.2, "mMax": 9.4, "Δm": 0.1 }`. The `bins` object
+   must be fully specified; partial overrides do not apply to nested JSON objects.
+7. `site.z1p0` and `site.z2p5`: Basin terms may be specified as `null` or `NaN` (both unquoted).
+   `null` is preferred as `NaN` does not conform to the JSON spec. When trying to override default
+   values, however, a `null` term will be ignored whereas `NaN` will override any existing value.
+8. `performance.optimizeGrids`: Gridded seismicity source optimizations are currently implemented
+   for any non-fixed strike grid source. For any site, rates across all azimuths are aggregated
+   in tables of distance and magnitude.
+9. `performance.smoothGrids`: Resample gridded seismicity sources close to a site.
+10. `performance.systemPartition`: The number of ruptures in a fault-system source to process
+    concurrently.
+
+## Default Intensity Measure Levels (IMLs)
+
+Units of PGV IMLs are cm/s; all other IMTs are in units of g. Spectral acceleration IMTs that are
+not listed use the values of the next highest spectral period.
+
+IMT        | IMLs
+-----------|-----
+PGV        | 0.237, 0.355, 0.532, 0.798, 1.19, 1.80, 2.69, 4.04, 6.06, 9.09, 13.6, 20.5, 30.7, 46.0, 69.0, 103.0, 155.0, 233.0, 349.0, 525.0
+PGA        | 0.00233, 0.00350, 0.00524, 0.00786, 0.0118, 0.0177, 0.0265, 0.0398, 0.0597, 0.0896, 0.134, 0.202, 0.302, 0.454, 0.680, 1.02, 1.53, 2.30, 3.44, 5.17
+T ≤ 0.01 s | 0.00233, 0.00350, 0.00524, 0.00786, 0.0118, 0.0177, 0.0265, 0.0398, 0.0597, 0.0896, 0.134, 0.202, 0.302, 0.454, 0.680, 1.02, 1.53, 2.30, 3.44, 5.17
+T ≤ 0.02 s | 0.00283, 0.00424, 0.00637, 0.00955, 0.0143, 0.0215, 0.0322, 0.0483, 0.0725, 0.109, 0.163, 0.245, 0.367, 0.551, 0.826, 1.24, 1.86, 2.79, 4.18, 6.27
+T ≤ 0.05 s | 0.00333, 0.00499, 0.00749, 0.0112, 0.0169, 0.0253, 0.0379, 0.0569, 0.0853, 0.128, 0.192, 0.288, 0.432, 0.648, 0.972, 1.46, 2.19, 3.28, 4.92, 7.38
+T ≤ 2 s    | 0.00250, 0.00375, 0.00562, 0.00843, 0.0126, 0.0190, 0.0284, 0.0427, 0.0640, 0.0960, 0.144, 0.216, 0.324, 0.486, 0.729, 1.09, 1.64, 2.46, 3.69, 5.54
+T ≤ 3 s    | 0.00200, 0.00300, 0.00449, 0.00674, 0.0101, 0.0152, 0.0228, 0.0341, 0.0512, 0.0768, 0.115, 0.173, 0.259, 0.389, 0.583, 0.875, 1.31, 1.97, 2.95, 4.43
+T ≤ 4 s    | 0.00133, 0.00200, 0.00300, 0.00449, 0.00674, 0.0101, 0.0152, 0.0228, 0.0341, 0.0512, 0.0768, 0.115, 0.173, 0.259, 0.389, 0.583, 0.875, 1.31, 1.97, 2.95
+T ≤ 5 s    | 0.000999, 0.00150, 0.00225, 0.00337, 0.00506, 0.00758, 0.0114, 0.0171, 0.0256, 0.0384, 0.0576, 0.0864, 0.130, 0.194, 0.292, 0.437, 0.656, 0.984, 1.48, 2.21
+T ≤ 7.5 s  | 0.000499, 0.000749, 0.00112, 0.00169, 0.00253, 0.00379, 0.00569, 0.00853, 0.0128, 0.0192, 0.0288, 0.0432, 0.0648, 0.0972, 0.146, 0.219, 0.328, 0.492, 0.738, 1.11
+T ≤ 10 s   | 0.000333, 0.000499, 0.000749, 0.00112, 0.00169, 0.00253, 0.00379, 0.00569, 0.00853, 0.0128, 0.0192, 0.0288, 0.0432, 0.0648, 0.0972, 0.146, 0.219, 0.328, 0.492, 0.738
diff --git a/docs/Developer-Basics.md b/docs/Developer-Basics.md
new file mode 100644
index 0000000000000000000000000000000000000000..51cf8c2cd7fbc357d0704d57e9afde3c02c9b4c2
--- /dev/null
+++ b/docs/Developer-Basics.md
@@ -0,0 +1,60 @@
+# Developer Basics
+
+The following provides basic guidance on how to set up command-line use of nshmp-haz.
+
+## Required Software
+
+* Java 11 JDK: [Oracle](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html) or
+  [Amazon Corretto](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html)
+* [Git](https://git-scm.com/downloads)  
+  * Git is a distributed version control system. The USGS uses a [GitLab](https://docs.gitlab.com)
+    [instance](https://code.usgs.gov/) to host projects and facilitate sharing and collaborative
+    development of code. Git is included in the macOS
+    [developer tools](https://developer.apple.com/xcode/).  
+  * Windows users may want to consider [Git for Windows](https://git-for-windows.github.io) or
+    [GitHub Desktop](https://desktop.github.com), both of which include a linux-like terminal
+    (Git BASH) in which subsequent commands listed here will work.  
+
+Other project dependencies are managed with [Gradle](https://gradle.org/), which does not
+require a separate installation. Gradle is clever about finding Java, but some users may have to
+explicitly define a `JAVA_HOME` environment variable. For example, on Unix-like systems with
+`bash` as the default shell, one might add the following to `~/.bash_profile`:
+
+```bash
+# macOS
+export JAVA_HOME="$(/usr/libexec/java_home -v 11)"
+# Linux
+export JAVA_HOME=/usr/lib/jvm/jdk-11.0.6.jdk
+```
+
+On Windows systems, environment variables are set through the `System Properties > Advanced >
+Environment Variables...` control panel. Depending on where Java is installed, `JAVA_HOME`
+might be:
+
+```bash
+JAVA_HOME     C:\Program Files\Java\jdk-11.0.6.jdk
+```
+
+## Set Up Git
+
+Follow the [GitLab instructions](https://docs.gitlab.com/ee/topics/git/). Some users may find it
+easier to use [Git for Windows](https://git-for-windows.github.io) or
+[GitHub Desktop](https://desktop.github.com). These desktop applications install required system
+components and are helpful for managing communication between local and remote repositories and
+viewing file diffs as one makes changes.
+
+## Get the Code
+
+```bash
+cd /directory/for/code
+git clone https://code.usgs.gov/ghsc/nshmp/nshmp-haz.git
+```
+
+## Eclipse Integration (Optional)
+
+Eclipse provides automatic compilation, syntax highlighting, and integration with Git, among
+other useful features. To build or modify *nshmp-haz* using [Eclipse](http://www.eclipse.org/),
+install the [Eclipse IDE for Java Developers](https://www.eclipse.org/downloads/packages/) or
+[Eclipse IDE for Enterprise Java and Web Developers](https://www.eclipse.org/downloads/packages/),
+if you plan on developing web services. Import the project into Eclipse: `File > Import >
+Gradle > Existing Gradle Project`
diff --git a/docs/Functional-PSHA.md b/docs/Functional-PSHA.md
new file mode 100644
index 0000000000000000000000000000000000000000..726864a1de39589eabe9931a7021604ad2cbdf5d
--- /dev/null
+++ b/docs/Functional-PSHA.md
@@ -0,0 +1,160 @@
+# Functional PSHA
+
+## Abstract
+
+Probabilistic seismic hazard analysis (PSHA; Cornell, 1968) is elegant in its relative simplicity.
+However, in the more than 40-years since its publication, the methodology has come to be applied
+to increasingly complex and non-standard source and ground motion models. For example, the third
+Uniform California Earthquake Rupture Forecast ([UCERF3](http://pubs.usgs.gov/of/2013/1165/))
+upended the notion of discrete faults as independent sources, and the USGS national seismic hazard
+model uses temporally clustered sources. Moreover, as the logic trees typically employed in PSHAs
+to capture epistemic uncertainty grow larger, so too does the demand for a more complete
+understanding of uncertainty. At the USGS, there are additional requirements to support source
+model mining, deaggregation, and map-making, often through the use of dynamic web-applications.
+Implementations of the PSHA methodology commonly iterate over all sources that influence the
+hazard at a site and sequentially build a single hazard curve. Such a linear PSHA computational
+pipeline, however, proves difficult to maintain and modify to support the additional complexity of
+new models, hazard products, and analyses. The functional programming paradigm offers some relief.
+The functional approach breaks calculations down into their component parts or steps, storing
+intermediate results as immutable objects, making it easier to: chain actions together; preserve
+intermediate data or results that may still be relevant (e.g. as in a deaggregation); and leverage
+the concurrency supported by many modern programming languages.
+
+## Traditional PSHA formulation (after Baker, 2013)
+
+![image](images/psha-formula.png "PSHA formulation of Baker (2013)")
+Briefly, the rate, *λ*, of exceeding an intensity measure, *IM*, level may be computed as a
+summation of the rate of exceeding such a level for all relevant earthquake sources (discretized
+in magnitude, *M*, and distance, *R*). This formulation relies on models of ground motion that
+give the probability that an intensity measure level of interest will be exceeded conditioned on
+the occurrence of a particular earthquake. Such models are commonly referred to as:
+
+* __Intensity measure relationships__
+* __Attenuation relationships__
+* __Ground motion prediction equations (GMPEs)__
+* __Ground motion models (GMMs)__
+
+The parameterization of modern models (e.g. NGA-West2; Bozorgnia et al., 2014) extends to much
+more than magnitude and distance, including, but not limited to:
+
+* __Multiple distance metrics__ (e.g. rJB, rRup, rX, rY)
+* __Fault geometry__ (e.g. dip, width, rupture depth, hypocentral depth)
+* __Site characteristics__ (e.g. basin depth terms, site type or Vs30 value)
+
+## Simple, yes, but used for so much more…
+
+While this formulation is relatively straightforward and is typically presented with examples for
+a single site, using a single GMM, and a nominal number of sources, modern PSHAs commonly include:
+
+* Multiple thousands of sources (e.g. the 2014 USGS NSHM in the Central & Eastern US includes all
+  smoothed seismicity sources out to 1000km from a site).
+* Different source types, the relative contributions of which are important, and the GMM
+  parameterizations of which may be different.
+* Sources (and associated ruptures – source filling or floating) represented by logic trees of
+  magnitude-frequency distributions (MFDs).
+* Source MFDs subject to logic trees of uncertainty on Mmax, total rate (for the individual source,
+  or over a region, e.g. as in UCERF3) or other properties of the distribution.
+* Logic trees of magnitude scaling relations for each source.
+* Source models that do not adhere to the traditional formulation (e.g. cluster models of the NSHM).
+* Logic trees of ground motion models.
+
+## And further extended to support…
+
+* Response Spectra, Conditional Mean Spectra – multiple intensity measure types (IMTs; e.g. PGA,
+  PGD, PGV, multiple SAs)
+* Deaggregation
+* Banded deaggregation (multiple deaggregations at varying IMLs)
+* Maps – many thousands of sites
+* Uncertainty analyses
+
+## How are such calculations managed?
+
+* PSHA codes typically compute hazard in a linear fashion, looping over all relevant sources for
+  a site.
+* Adding additional GMMs, logic trees, IMT’s, and sites is addressed with more, outer loops:
+
+```PHP
+foreach IMT {
+    foreach Site {
+        foreach SourceType {
+            foreach GMM {
+                foreach Source {
+                    // do something
+                }
+            }
+        }   
+    }
+}
+```
+
+* Support for secondary analyses, such as deaggregation is supplied by a separate code or codes
+  and can require repeating many of the steps performed to generate an initial hazard curve.
+
+## What about scaleability, maintenance, and performance?
+
+* Although scaleability can be addressed for secondary products, such as maps, by distributing
+  individual site calculations over multiple processors and threads, it is often difficult to
+  leverage multi-core systems for individual site calculations. This hampers one’s ability to
+  leverage multi-core systems in the face of ever more complex source and ground motion models and
+  their respective logic trees.
+* A linear pipeline complicates testing, requiring end to end tests rather than tests of discrete
+  calculations.
+* Multiple codes repeating identical tasks invite error and complicate maintenance by multiple
+  individuals.
+
+## Enter functional programming…
+
+* <http://en.wikipedia.org/wiki/Functional_programming>
+* Functional programming languages have been around for some time (e.g. Haskell, Lisp, R), and
+  fundamental aspects of functional programming/design are common in many languages. For example,
+  a cornerstone of the functional paradigm is the anonymous (or lambda) function; in Matlab, one
+  may write [sqr = @(x) x.^2;].
+* In Matlab, one may pass function ‘handles’ (references) to other functions as arguments. This
+  is also possible in Javascript, where such handles serve as callbacks. Given the rise in
+  popularity of the functional style, Java 8 recently added constructs in the form of the function
+  and streaming APIs, and libraries exists for other languages.
+
+## How do PSHA and related calculations leverage such an approach?
+
+Break the traditional PSHA formulation down into discrete steps and preserve the data associated
+with each step:
+
+* **[1]** Source & Site parameterization
+* **[2]** Ground motion calculation (mean and standard deviation only)
+* **[3]** Exceedance curve calculation (per source)
+* **[4]** Recombine
+
+Whereas the traditional pipeline looks something like this:
+
+![image](images/psha-linear.png "PSHA linear pipeline")
+
+The functional pipeline can be processed stepwise:
+
+![image](images/psha-functional.png "PSHA functional pipeline")
+
+**Need a deagreggation?** Revisit and parse the results of steps 1 and 2
+
+**Need a response spectra?** Spawn more calculations, one for each IMT, at step 2.
+
+## Benefits
+
+* It’s possible to build a single calculation pipeline that will handle a standard hazard curve
+  calculation and all of its extensions without repetition.
+* Pipeline performance scales with available hardware.
+* No redundant code.
+* Can add or remove transforms or data at any point in the pipeline, or build new pipelines
+  without adversely affecting existing code.
+
+## Drawbacks
+
+* Greater memory requirements.
+* Additional (processor) work to manage the flow of calculation steps.
+
+## References
+
+* Baker J.W. (2013). An Introduction to Probabilistic Seismic Hazard Analysis (PSHA), White Paper,
+  Version 2.0, 79 pp.
+* Bozorgnia, Y., et al. (2014) NGA-West2 Research Project, *Earthquake Spectra*, Vol. 30, No. 3,
+  pp. 973-987.
+* Cornell, C.A., 1968, Engineering seismic risk analysis, *Bulletin of the Seismological Society
+  of America*, Vol. 58, No. 5, pp. 1583-1606.
diff --git a/docs/Ground-Motion-Models.md b/docs/Ground-Motion-Models.md
new file mode 100644
index 0000000000000000000000000000000000000000..82f109b620244bdb64d376606c9b01ddb01ecac8
--- /dev/null
+++ b/docs/Ground-Motion-Models.md
@@ -0,0 +1,160 @@
+# Ground Motion Models (GMMs)
+
+Ground motion models (GMMs) forecast the range of ground motions that may occur conditioned on
+the occurrence of various earthquakes. The following tables list the GMMs supported in NSHMs. It
+is not uncommon for a GMM to have multiple concrete implementations. For instance, most subduction
+GMMs, as published, support both interface and intraslab events.
+
+[[_TOC_]]
+
+* How to add links to javadocs? ...not possible in wiki (separate repo)? except with external
+  http gitlab urls?
+* include NSHM that used each model?
+* save horizontal space in table by moving notes to table footnotes. this has to be done manually
+  (see NGA-East model IDs), since markdown footnotes always appear at the bottom of the page
+
+**gmm-config.json** Required adjacent to any `gmm-tree.json`. This file specifies the applicability
+distance of the associated GMM's and any additional epistemic uncertainty model and properties to
+apply to median ground motions derived from the GMM's. This uncertainty is distinct from the
+built-in aleatory variability (standard deviation or sigma) of the GMM's themselves. Use `null`
+values to indicate that no additional uncertainty model should be applied. Supported uncertainty
+models are detailed in the [ground motion models](ground-motion-models) section. For example:
+
+```json
+{
+  "max-distance": 300.0,
+  "epistemic-model": null,
+  "epistemic-tree": null
+}
+```
+
+## GMM Configuration
+
+A `gmm-config.json` file governs how GMMs are applied in a NSHM. It specifies a maximum distance
+at which a GMM is applicable. It may also specify a model of additional epistemic uncertainty and
+the logic tree used to apply it. If no such model is required, the `epistemic-model` and
+`epistemic-tree` members must be `null`. See [Uncertainties in NSHMs](uncertainties-in-nshms) for
+details on additional epistemic uncertainty in GMMs.
+
+```json
+{
+  "max-distance": 300.0,
+  "epistemic-model": "NGA_WEST2",
+  "epistemic-tree": [
+    { "id": "epi+", "weight": 0.185, "value": 1.0 },
+    { "id": "none", "weight": 0.63, "value": 0.0 },
+    { "id": "epi-", "weight": 0.185, "value": -1.0 }
+  ]
+}
+```
+
+## GMM Uncertainty Models
+
+TODO
+
+## GMM Post Processors
+
+TODO
+
+## Active Crust GMMs
+
+| Reference | ID | Component | Notes |
+|:---------:|:--:|:---------:|:------|
+| **NGA-West 2** | | |
+| [Abrahamson et al., 2014](http://dx.doi.org/10.1193/070913EQS198M) | ASK_14<br>ASK_14_BASIN | RotD50 |  |
+| [Boore et al., 2014](http://dx.doi.org/10.1193/070113EQS184M) | BSSA_14<br>BSSA_14_BASIN | RotD50 |  |
+| [Campbell & Bozorgnia, 2014](http://dx.doi.org/10.1193/062913EQS175M)| CB_14<br>CB_14_BASIN | RotD50 |  |
+| [Chiou & Youngs, 2014](http://dx.doi.org/10.1193/072813EQS219M) | CY_14<br>CY_14_BASIN | RotD50 |  |
+| [Idriss, 2014](http://dx.doi.org/10.1193/070613EQS195M) | IDRISS_14 | RotD50 |  |
+| **NGA-West 1** | | | |
+| [Boore & Anderson, 2008](http://dx.doi.org/10.1193/1.2830434) | BA_08 | GMRotI50 |  |
+| [Campbell & Bozorgnia, 2008](http://dx.doi.org/10.1193/1.2857546) | CB_08 | GMRotI50 |  |
+| [Chiou & Youngs, 2008](http://dx.doi.org/10.1193/1.2894832) | CY_08 | GMRotI50 |  |
+| **Other** | | | |
+| [Abrahamson & Silva, 1997](http://dx.doi.org/10.1785/gssrl.68.1.94) | AS_97 | Average horizontal | |
+| [Boore et al., 1997](http://dx.doi.org/10.1785/gssrl.68.1.128)<br>[Boore, 2005](http://dx.doi.org/10.1785/gssrl.76.3.368) | BJF_97 | Random horizontal | Soft rock sites only (Vs30 760 m/s) |
+| [Campbell, 1997](http://dx.doi.org/10.1785/gssrl.68.1.154)<br>[errata, 2000](http://dx.doi.org/10.1785/gssrl.71.3.352)<br>[errata, 2001](http://dx.doi.org/10.1785/gssrl.72.4.474) | CAMPBELL_97 | Geometric mean of two horizontal components | Soft rock sites only (Vs30 760 m/s) |
+| [Campbell & Bozorgnia, 2003](http://dx.doi.org/10.1785/0120020029)<br>[errata, 2003](http://dx.doi.org/10.1785/0120030099)<br>[errata, 2003](http://dx.doi.org/10.1785/0120030143) | CB_03 | Average horizontal | Soft rock sites only (Vs30 760 m/s) |
+| [McVerry et al., 2000](http://doi.org/10.5459/BNZSEE.39.1.1-58) | MCVERRY_00_CRUSTAL<br>MCVERRY_00_VOLCANIC | Max-horizontal implemented, model also supports geometric mean | New Zealand, does not correspond directly with US site class model |
+| [Sadigh et al., 1997](http://dx.doi.org/10.1785/gssrl.68.1.180) | SADIGH_97 | Geometric mean of two horizontal components | Also used for interface sources in 2007 Alaska NSHM |
+| [Zhao et al., 2016](http://dx.doi.org/10.1785/0120150063) | ZHAO_16_SHALLOW_CRUST<br>ZHAO_16_UPPER_MANTLE | Geometric mean of two randomly oriented horizontal components |  |
+
+## Stable Crust GMMs
+
+| Reference | ID | Component | Notes |
+|:---------:|:--:|:---------:|:------|
+| [Atkinson, 2008](http://dx.doi.org/10.1785/0120070199)<br>[Atkinson & Boore, 2011](http://dx.doi.org/10.1785/0120100270) | ATKINSON_08_PRIME | horizontal | Mean values clamped |
+| [Atkinson & Boore, 2006](http://dx.doi.org/10.1785/0120050245) | AB_06_140BAR<br>AB_06_200BAR<br>AB_06_140BAR_AB<br>AB_06_200BAR_AB<br>AB_06_140BAR_J<br>AB_06_200BAR_J | horizontal | Mean values clamped |
+| [Atkinson & Boore, 2006](http://dx.doi.org/10.1785/0120050245)<br>[Atkinson & Boore, 2011](http://dx.doi.org/10.1785/0120100270) | AB_06_PRIME | horizontal | Mean values clamped |
+| [Campbell, 2003](http://dx.doi.org/10.1785/0120020002) | CAMPBELL_03<br>CAMPBELL_03_AB<br>CAMPBELL_03_J | Geometric mean of two horizontal components | Mean values clamped |
+| [Frankel et al., 1996](https://pubs.usgs.gov/of/1996/532/) | FRANKEL_96<br>FRANKEL_96_AB<br>FRANKEL_96_J | not specified | Mean values clamped |
+| [Graizer & Kalkan, 2015](http://dx.doi.org/10.3133/ofr20151009)<br>[Graizer & Kalkan, 2016](http://dx.doi.org/10.1785/0120150194) | GK_15 | Geometric mean of two randomly oriented horizontal components |  |
+| NGA-East<br>[Goulet et al., 2017](https://peer.berkeley.edu/sites/default/files/christine-a-goulet-yousef-bozorgnia-2017_03_0.pdf) | NGA_EAST_USGS [:one:](#one-nga-east-median-model-ids)<br>NGA_EAST_USGS_SEEDS[:two:](#two-nga-east-seed-model-ids) | RotD50 (average horizontal) | Mean values are not clamped |
+| [Pezeshk et al., 2011](http://dx.doi.org/10.1785/0120100144) | PEZESHK_11 | GMRotI50 | Mean values clamped |
+| [Shahjouei and Pezeshk, 2016](http://dx.doi.org/10.1785/0120140367) | NGA_EAST_SEED_SP16 | RotD50 | NGA-East Seed |
+| [Silva et al., 2002](http://www.pacificengineering.org/CEUS/Development%20of%20Regional%20Hard_ABC.pdf) | SILVA_02<br>SILVA_02_AB<br>SILVA_02_J | average horizontal component | Mean values clamped |
+| [Somerville et al., 2001](https://earthquake.usgs.gov/static/lfs/nshm/conterminous/2008/99HQGR0098.pdf) | SOMERVILLE_01 | not specified | Mean values clamped |
+| [Tavakoli & Pezeshk, 2005](http://dx.doi.org/10.1785/0120050030) | TP_05<br>TP_05_AB<br>TP_05_J | not specified | Mean values clamped |
+| [Toro et al., 1997](http://dx.doi.org/10.1785/gssrl.68.1.41)<br>[Toro, 2002](http://www.ce.memphis.edu/7137/PDFs/attenuations/Toro_2001_(modification_1997).pdf) | TORO_97_MB<br>TORO_97_MW | not specified | Mean values clamped |
+
+1. NGA-East Median Model IDs: NGA_EAST_USGS_1, NGA_EAST_USGS_2, NGA_EAST_USGS_3, NGA_EAST_USGS_4,
+   NGA_EAST_USGS_5, NGA_EAST_USGS_6, NGA_EAST_USGS_7, NGA_EAST_USGS_8, NGA_EAST_USGS_9,
+   NGA_EAST_USGS_10, NGA_EAST_USGS_11, NGA_EAST_USGS_12, NGA_EAST_USGS_13, NGA_EAST_USGS_14,
+   NGA_EAST_USGS_15, NGA_EAST_USGS_16, NGA_EAST_USGS_17
+2. NGA-East Seed Model IDs: NGA_EAST_SEED_1CCSP, NGA_EAST_SEED_1CVSP, NGA_EAST_SEED_2CCSP,
+   NGA_EAST_SEED_2CVSP, NGA_EAST_SEED_B_A04, NGA_EAST_SEED_B_AB14, NGA_EAST_SEED_B_AB95,
+   NGA_EAST_SEED_B_BCA10D, NGA_EAST_SEED_B_BS11, NGA_EAST_SEED_B_SGD02, NGA_EAST_SEED_FRANKEL,
+   NGA_EAST_SEED_GRAIZER, NGA_EAST_SEED_GRAIZER16, NGA_EAST_SEED_GRAIZER17, NGA_EAST_SEED_HA15,
+   NGA_EAST_SEED_PEER_EX, NGA_EAST_SEED_PEER_GP, NGA_EAST_SEED_PZCT15_M1SS,
+   NGA_EAST_SEED_PZCT15_M2ES, NGA_EAST_SEED_SP15, NGA_EAST_SEED_SP16, NGA_EAST_SEED_YA15
+
+## Subduction GMMs  
+
+| Reference | ID | Component | Notes |
+|:---------:|:--:|:---------:|:------|
+| [Atkinson & Boore, 2003](http://dx.doi.org/10.1785/0120020156) | AB_03_GLOBAL_INTERFACE<br>AB_03_GLOBAL_SLAB<br>AB_03_GLOBAL_SLAB_LOW_SAT<br>AB_03_CASCADIA_INTERFACE<br>AB_03_CASCADIA_SLAB<br>AB_03_CASCADIA_SLAB_LOW_SAT | horizontal |  |
+| [Atkinson & Macias, 2009](http://dx.doi.org/10.1785/0120080147) | AM_09_INTERFACE<br>AM_09_INTERFACE_BASIN | Geometric mean of two horizontal components | Interface only |
+| BC Hydro<br>[Abrahamson et al., 2016](http://dx.doi.org/10.1193/051712EQS188MR) | BCHYDRO_12_INTERFACE<br>BCHYDRO_12_INTERFACE_BACKARC<br>BCHYDRO_12_INTERFACE_BASIN<br>BCHYDRO_12_INTERFACE_BASIN_BACKARC<br>BCHYDRO_12_SLAB<br>BCHYDRO_12_SLAB_BACKARC<br>BCHYDRO_12_SLAB_BASIN<br>BCHYDRO_12_SLAB_BASIN_BACKARC | Geometric mean of two horizontal components |  |
+| [McVerry et al., 2000](http://doi.org/10.5459/BNZSEE.39.1.1-58) | MCVERRY_00_INTERFACE<br>MCVERRY_00_SLAB<br>MCVERRY_00_VOLCANIC | Max-horizontal implemented, model also supports geometric mean | New Zealand, does not correspond directly with US site class model |
+| NGA-Subduction<br>[Abrahamson et al., 2018](https://peer.berkeley.edu/sites/default/files/2018_02_abrahamson_9.10.18.pdf) | NGA_SUB_USGS_INTERFACE<br>NGA_SUB_USGS_INTERFACE_NO_EPI<br>NGA_SUB_USGS_SLAB<br>NGA_SUB_USGS_SLAB_NO_EPI | Geometric mean of two horizontal components | **Likely to be superseded by final EQS paper**<br>Calibrated for Cascadia use only |
+| [Youngs et al., 1997](http://dx.doi.org/10.1785/gssrl.68.1.58) | YOUNGS_97_INTERFACE<br>YOUNGS_97_SLAB | Geometric mean of two horizontal components |  |
+| [Zhao et al., 2006](http://dx.doi.org/10.1785/0120050122) | ZHAO_06_INTERFACE<br>ZHAO_06_INTERFACE_BASIN<br>ZHAO_06_SLAB<br>ZHAO_06_SLAB_BASIN | Geometric mean of two horizontal components |  |
+| [Zhao et al., 2016](http://dx.doi.org/10.1785/0120150034)<br>[Zhao et al., 2016](http://dx.doi.org/10.1785/0120150056) | ZHAO_16_INTERFACE<br>ZHAO_16_SLAB<br>*ZHAO_16_UPPER_MANTLE* | Geometric mean of two randomly oriented horizontal components | Subduction Slab and Interface |
+
+## Regional and Specialized GMMs
+
+| Reference | ID | Component | Notes |
+|:---------:|:--:|:---------:|:------|
+| **Hawaii** | | | |
+| [Atkinson, 2010](http://dx.doi.org/10.1785/0120090098) | ATKINSON_10 | geometric mean of two horizontal components |  |
+| [Munson & Thurber, 1997](https://pubs.geoscienceworld.org/ssa/srl/article-abstract/68/1/41/142160/Model-of-Strong-Ground-Motions-from-Earthquakes-in) | MT_97 | Larger of two horizontal | PGA and 0.2 seconds, additional term applied for M > 7 |
+| [Wong et al., 2015](http://doi.org/10.1193/012012EQS015M) | WONG_15 | average horizontal |  |
+| **New Zealand** | | | |
+| [McVerry et al., 2000](http://doi.org/10.5459/BNZSEE.39.1.1-58) | MCVERRY_00_CRUSTAL<br>MCVERRY_00_VOLCANIC<br>MCVERRY_00_INTERFACE<br>MCVERRY_00_SLAB | Max-horizontal implemented, model also supports geometric mean | New Zealand, does not correspond directly with US site class model. |
+| **Induced Seismicity** | | | |
+| [Atkinson, 2015](http://dx.doi.org/10.1785/0120140142) | ATKINSON_15 | orientation-independent horizontal |  |
+<!--
+## Hawaii GMMs
+
+| Reference | ID | Component | Notes |
+|:---------:|:--:|:---------:|:------|
+| [Atkinson, 2010](http://dx.doi.org/10.1785/0120090098) | ATKINSON_10 | geometric mean of two horizontal components | Hawaii |
+| [Munson & Thurber, 1997](https://pubs.geoscienceworld.org/ssa/srl/article-abstract/68/1/41/142160/Model-of-Strong-Ground-Motions-from-Earthquakes-in) | MT_97 | Larger of two horizontal | PGA and 0.2 seconds, additional term applied for M > 7 |
+| [Wong et al., 2015](http://doi.org/10.1193/012012EQS015M) | WONG_15 | average horizontal |  |
+
+## Induced Seismicity GMMs
+
+| Reference | ID | Component | Notes |
+|:---------:|:--:|:---------:|:------|
+| [Atkinson, 2015](http://dx.doi.org/10.1785/0120140142) | ATKINSON_15 | orientation-independent horizontal |  |
+-->
+
+## Auxilliary Models
+
+Auxilliary models are not used directly, they can be used by concrete implementations of GMMs to
+modify model output.
+
+| Reference | Purpose | Component | Notes |
+|:---------:|:-------:|:---------:|:------|
+| [Rezaeian et al., 2014](http://dx.doi.org/10.1193/100512EQS298M) | Damping scaling factor | Average horizontal component | No effect if supplied damping ratio is 5% |
+| USGS PGV | Conditional PGV for crustal earthquakes | Horizontal component | Conditional model for vertical component not yet implemented |
diff --git a/docs/Hazard-Model.md b/docs/Hazard-Model.md
new file mode 100644
index 0000000000000000000000000000000000000000..005e738f1dc657d18a8de313c3d8eb902b78feb3
--- /dev/null
+++ b/docs/Hazard-Model.md
@@ -0,0 +1,33 @@
+# Hazard Model
+
+A USGS seismic hazard model defines earthquake sources, the different rupture scenarios for each,
+and the ground motion models to use with each scenario. Earthquake sources are representations of
+geologic structures on which earthquake ruptures occur with some rate. They can be well defined
+faults with a specific geometry, or uniformely distributed point source representations with rates
+derived from historic earthquake catalogs. In either case, there may be multiple source geometries,
+or earthquake sizes and rates, associated with a given source.
+
+Epistemic uncertainty in source and ground motion models is represented with logic trees. The model
+file formats and structure adopted here leverage the heirarchical organization of file systems to
+support modeling of complex logic trees.
+
+## Related Pages
+
+* [Model Structure](model-structure)  
+* [Model Files](model-files)  
+* [Source Types](source-types)  
+* [Magnitude-Frequency Distributions (MFDs)](magnitude-frequency-distributions-mfds)  
+* [Rupture-Scaling Relations](magnitude-scaling-relations)  
+* [Ground Motion Models (GMMs)](ground-motion-models-gmms)  
+
+## Model Applicability
+
+* NOTE FOR HAZARD CURVE DATA: While the gridded hazard curve data includes ground motions at long
+  return periods, the USGS does not recommend using hazard values below 10<sup>-5</sup> (100,000
+  years), and cautions users using values below 10<sup>-4</sup> (10,000 years). These models were
+  developed for building codes concerned with return periods of 10<sup>-4</sup> and above.
+
+* Important considerations when using NSHMs: NSHMs are only applicable to U.S. and it's
+  territories. Although hazard close to the borders can be useful for comparison to other models,
+  the further one drifts from the U.S. border, the more incomplete the underlying earthquake
+  source model will be.
diff --git a/docs/Logic-Trees-&-Uncertainty.md b/docs/Logic-Trees-&-Uncertainty.md
new file mode 100644
index 0000000000000000000000000000000000000000..5b51aaec28e62bc8dd34fa0f4491448115fb4877
--- /dev/null
+++ b/docs/Logic-Trees-&-Uncertainty.md
@@ -0,0 +1,124 @@
+# USGS Models: Logic Trees & Uncertainty
+
+The following page details the logic trees of epistemic uncertainty considered in NSHMs supported
+by *nshmp-haz*. Logic trees are represented in a NSHM using files ending in `-tree.json`.
+
+[[_TOC_]]
+
+## Terminology
+
+**Epistemic Uncertainty**: Uncertainty due to limited data and knowledge. Characterized by
+alternative models.  
+**Aleatory Variability**: Inherent uncertainty due to random variability.
+
+## Stable Crust Ground Motion Models
+
+| Description | 2008  | 2014 | 2018 |
+|:----------- |:----- |:---- |:---- |
+| CEUS   | __0.1__ : AB_06 (140 bar)<br />__0.1__ : AB_06 (200 bar)<br />__0.1__ : CAMPBELL_03<br />__0.1__ : FRANKEL_96<br />__0.1__ : SILVA_02<br />__0.2__ : SOMERVILLE_01<br />__0.2__ : TORO_97<br />__0.1__ : TP_05 | __0.22__ : AB_06'<br />__0.08__ : ATKINSON_08'<br />__0.11__ : CAMPBELL_03<br />__0.06__ : FRANKEL_96<br />__0.15__ : PEZESHK_11<br />__0.06__ : SILVA_02<br />__0.10__ : SOMERVILLE_01<br />__0.11__ : TORO_97<br />__0.11__ : TP_05 | __0.667__ : NGA_EAST_USGS (17)<br />__0.333__ : NGA_EAST_SEEDS (14)<br />(common aleatory variability) |
+| Sigma Epistemic | _(none)_ | _(no change)_ | __0.2__ : USGS Panel<br />__0.8__ : EPRI |
+| Site Aleatory | _(none)_ | _(no change)_ | __0.185, 0.63, 0.185__ : Site ± σ |
+
+---
+
+## Active Crustal Ground Motion Models
+
+| Description | 2008  | 2014 | 2018 |
+|:----------- |:----- |:---- |:---- |
+| WUS | __0.3333__ : BA_08<br />__0.3333__ : CB_08<br />__0.3334__ : CY_08 | __0.22__ : ASK_14<br />__0.22__ : BSSA_14<br />__0.22__ : CB_14<br />__0.22__ : CY_14<br />__0.22__ : IDRISS_14 | __0.25__ : ASK_14<br />__0.25__ : BSSA_14<br />__0.25__ : CB_14<br />__0.25__ : CY_14 |
+| Mean Epistemic | NGA-West1 (M,R)<br />__0.185__ : epi+<br />__0.630__ : off<br />__0.185__ : epi- | NGA-West2 (M,R)<br />__0.185__ : epi+<br />__0.630__ : off<br />__0.185__ : epi- | _(no change)_  |
+
+---
+
+## Subduction Ground Motion Models
+
+| Description | 2008  | 2014 | 2018 |
+|:----------- |:----- |:---- |:---- |
+| Cascadia<br />(interface) | __0.25__ : AB_03 (global)<br />__0.25__ : YOUNGS_97<br />__0.50__ : ZHAO_06 | __0.1__ : AB_03 (global)<br />__0.3__ : AM_09<br />__0.3__ : BCHYDRO_12<br />__0.3__ : ZHAO_06 | __0.3333__ : AM_09<br />__0.3334__ : BCHYDRO_12<br />__0.3333__ : ZHAO_06 |
+| Cascadia<br />(slab) | __0.25__ : AB_03 (global)<br />__0.25__ : AB_03 (cascadia)<br />__0.50__ : YOUNGS_97 | __0.1665__ : AB_03 (global, mod)<br />__0.1665__ : AB_03 (cascadia, mod)<br />__0.3330__ : BCHYDRO_12<br />__0.3340__ : ZHAO_06 | __0.5__ : BCHYDRO_12<br />__0.5__ : ZHAO_06 |
+
+---
+
+## Fault Source Model (CEUS)
+
+| Model | Description | 2008 | 2014 | 2018 |
+|:----- |:----------- |:---- |:---- |:---- |
+| Deformation |  | __1.0__ : GEO | __0.1__ : BIRD<br />__0.8__ : GEO<br />__0.1__ : ZENG | _(no change)_  |
+| Rupture |  | __0.5__ : Full<br /> __0.5__ : Partial | _(no change)_ | _(no change)_ |
+| Magnitude Scaling |  | __1.0__ : Somerville-01 (area) | _(no change)_  | _(no change)_  |
+| Maximum M¹ | Partial: epistemic | __0.2, 0.6, 0.2__ : M ± 0.2 | _(no change)_  | _(no change)_  |
+|           | Full : epistemic   | __0.2, 0.6, 0.2__ : M ± 0.2 | _(no change)_  | _(no change)_  |
+|           | Full : aleatory    |  M ± 0.24 (±2σ normal PDF)  | _(no change)_  | _(no change)_  |
+
+¹ There are a very limited number of fault sources in CEUS
+
+---
+
+## Fault Source Model (WUS)
+
+| Model | Description | 2008 | 2014 | 2018 |
+|:----- |:----------- |:---- |:---- |:---- |
+| Deformation |  | __1.0__ : GEO | __0.1__ : BIRD<br />__0.8__ : GEO<br />__0.1__ : ZENG | _(no change)_  |
+| Rupture | Partial | __0.333__ : IMW, __0.5__ : PNW | _(no change)_ | _(no change)_ |
+|         | Full    | __0.667__ : IMW, __0.5__ : PNW | _(no change)_ | _(no change)_ |
+| Magnitude Scaling |  | __1.0__ : WC_94 (length) | _(no change)_  | _(no change)_  |
+| Maximum M | Partial: epistemic | __0.2, 0.6, 0.2__ : M ± 0.2 | _(no change)_  | _(no change)_  |
+|           | Full : epistemic   | __0.2, 0.6, 0.2__ : M ± 0.2 | _(no change)_  | _(no change)_  |
+|           | Full : aleatory    |  M ± 0.24 (±2σ normal PDF)  | _(no change)_  | _(no change)_  |
+| Dip | Reverse & Strike-Slip | __1.0__ : assigned | _(no change)_ | _(no change)_ |
+|     | Normal | __0.2, 0.6, 0.2__ : 50 ± 10° | __0.2, 0.6, 0.2__ : 50±15° | _(no change)_ |
+
+---
+
+## Grid Source Model
+
+| Model | Description | 2008 | 2014 | 2018 |
+|:----- |:----------- |:---- |:---- |:---- |
+| Maximum M | WUS (exceptions) | __1.0__ : 7.0 | __0.9__ : 7.5 (truncated)<br />__0.1__ : 8.0 (tapered) | _(no change)_  |
+|           | CEUS (craton) | __0.1__ : 6.6<br />__0.2__ : 6.8<br />__0.5__ : 7.0<br />__0.2__ : 7.2 | __0.2__ : 6.5<br />__0.5__ : 7.0<br />__0.2__ : 7.5<br />__0.1__ : 8.0 | _(no change)_  |
+| Smoothing |  | __1.0__ : Fixed |__0.4__ : Adaptive<br />__0.6__ : Fixed | _(no change)_  |
+| Magnitude Scaling | CEUS & WUS | __1.0__ : WC_94 (length) | _(no change)_  | _(no change)_  |
+| Focal Mechanisms | Spatially Varying | __1.0__ : assigned | _(no change)_  | _(no change)_  |
+| Depth (zTor) | WUS, M < 6.5 | __1.0__ : 5.0 km | _(no change)_  | _(no change)_  |
+|              | WUS, M ≥ 6.5 | __1.0__ : 1.0 km | _(no change)_  | _(no change)_  |
+|              | CEUS, All M  | __1.0__ : 5.0 km | _(no change)_  | _(no change)_  |
+
+---
+
+## Fault Source Model (CA, UCERF3)
+
+| Model | 2014 | 2018 |
+|:----- |:---- |:---- |
+| Fault | __0.5__ : FM3.1<br /> __0.5__ : FM3.2 | _(no change)_ |
+| Deformation | __0.1__ : ABM<br />__0.3__ : BIRD<br />__0.3__ : GEO<br />__0.3__ : ZENG | _(no change)_  |
+| Scaling Relationship<br />(mag-area & slip-length)| __0.2__ : ELLS_B<br />__0.2__ : ELLS_B (sqrt-L)<br />__0.2__ : HB_08<br />__0.2__ : SHAW_09<br />__0.2__ : SHAW_09 (csd) | _(no change)_  |
+| Slip Distribution | __0.5__ : Tapered<br />__0.5__ : Boxcar | _(no change)_ |
+| M ≥ 5 rate (yr⁻¹) | __0.1__ : 6.5<br />__0.6__ : 7.9<br />__0.3__ : 9.6 | _(no change)_  |
+| Inversion Constraint | __1.0__ : UCERF2 (CH) | _(no change)_  |
+| Fault Mo Rate | __1.0__ : off |  _(no change)_  |
+
+---
+
+## Grid Source Model (CA, UCERF3)
+
+| Model | 2014 | 2018 |
+|:----- |:---- |:---- |
+| Grid: Maximum M | __0.1__ : 7.3<br />__0.8__ : 7.6<br />__0.1__ : 7.9 | _(no change)_  |
+| Grid: Smoothing | __0.5__ : Adaptive<br />__0.5__ : Fixed | _(no change)_  |
+| Grid: Focal Mechanisms | __1.0__ : assigned | _(no change)_  |
+| Magnitude Scaling | __1.0__ : WC_94 (length) | _(no change)_  |
+
+---
+
+## Subduction seismic source model
+
+| Model | 2008 | 2014 | 2018 |
+|:----- |:---- |:---- |:---- |
+| Rupture | __0.67__ : Full<br />__0.33__ : Partial | __1.0__ : Full<br />__0.5__ : Partial (segmented)<br />__0.5__ : Partial (unsegmented) | _(no change)_ |
+| Magnitude Scaling | __1.0__ : Youngs et al. (length) | __0.334__ : Strasser et al. (2010)<br />__0.333__ : Murotani et al. (2008)<br />__0.333__ : Papazachos et al. (2004)  | _(no change)_  |
+| Magnitude Uncertainty | __0.2, 0.6, 0.2__ : M±0.2 | _(none)_  | _(no change)_  |
+| Depth | __0.5__ : Base<br />__0.2__ : Bottom<br />__0.2__ : Middle<br />__0.1__ : Top | __0.3__ : Bottom<br />__0.5__ : Middle<br />__0.2__ : Top | _(no change)_ |
+| Slab: Maximum M | __1.0__ : 7.2 | __0.9__ : 7.5<br />__0.1__ : 8.0 | _(no change)_ |
+
+* Full: a.k.a. 'characteristic'
+* Partial: a.k.a. 'Gutenberg-Richter' or 'floating'
diff --git a/docs/Magnitude-Frequency-Distributions.md b/docs/Magnitude-Frequency-Distributions.md
new file mode 100644
index 0000000000000000000000000000000000000000..660adb59fca2dae9615e63619014ba7fcca7b2ee
--- /dev/null
+++ b/docs/Magnitude-Frequency-Distributions.md
@@ -0,0 +1,283 @@
+# Magnitude-Frequency Distributions (MFDs)
+
+An earthquake source requires a description of the sizes and rates of all earthquakes it is
+capable of generating, otherwise known as a magnitude-frequency distribution (MFD). The different
+types of MFDs supported in a hazard model are described below. Unless otherwise noted, all the
+members listed in the JSON examples below are required.
+
+[[_TOC_]]
+
+MFD types:
+
+* [Single](#single-magnitude-mfd)
+* [Gutenberg-Richter](#gutenberg-richter-mfd)
+* [Tapered Gutenberg-Richter](#tapered-gutenberg-richter-mfd)
+* [Incremental](#incremental-mfd)
+
+## Single
+
+A single MFD represents an earthquake of a specific magnitude size and rate. The `rate` member
+is optional when a logic tree of rates is also present in a model. Example:
+
+```json
+  {
+    "type": "SINGLE",
+    "m": 7.0,
+    "rate": 0.0001
+  }
+```
+
+## Gutenberg–Richter
+
+A [Gutenberg–Richter](http://en.wikipedia.org/wiki/Gutenberg–Richter_law) MFD represents a range
+of evenly discretized magnitude events with systematically varying rates. Specifically, a
+Gutneberg–Richter MFD is a doubly-truncated exponential distribution with limits at `mMin` and
+`mMax`, a y-intercept of `a`, and a slope of `b`. The `a`-value member is optional when a logic
+tree of rates for a source is also present in a model. Example:
+
+```json
+  {
+    "type": "GR",
+    "a": 1.0,
+    "b": 0.8,
+    "mMin": 6.55,
+    "mMax": 6.95,
+    "Δm": 0.1
+  }
+```
+
+## Tapered Gutenberg–Richter
+
+A [tapered Gutenberg-Richter](http://scec.ess.ucla.edu/~ykagan/moms_index.html) MFD is similar to
+Gutenberg-Richter, above, but with an exponential taper applied with a corner magnitude of `mCut`.
+The `a`-value member is optional when a logic tree of rates for a source is also present in a
+model. Example:
+
+```json
+  {
+    "type": "GR_TAPER",
+    "a": 1.0,
+    "b": 0.8,
+    "mCut": 6.5,
+    "mMin": 5.0,
+    "mMax": 7.0,
+    "Δm": 0.1
+  }
+```
+
+## Incremental
+
+A general purpose MFD that represents defined by explicit arrays of magnitudes and rates. Example:
+
+```json
+  {
+    "type": "INCR",
+    "magnitudes": [5.05, 5.15, ...],
+    "rates": [1.0e-2, 0.9e-2, ...]
+  }
+```
+
+## MFD Construction
+
+Construction of MFDs from their declaration in a tree _may_ also depend on the following files:
+
+**mfd-map.json:** If an `mfd-tree` value is a string, then that value must map to an actual logic
+tree in a `mfd-map.json` file that is typically located high in the source model heirarchy. For
+example:
+
+```json
+{
+  "mfd-tree-1": [
+    { "id": "M1","weight": 0.5, "value": { "type": "SINGLE", "m": 7.0}},
+    { "id": "M2","weight": 0.5, "value": { "type": "SINGLE", "m": 7.5}}
+  ],
+  "mfd-tree-2": [
+    { "id": "M1","weight": 0.5, "value": { "type": "SINGLE", "m": 7.3}},
+    { "id": "M2","weight": 0.5, "value": { "type": "SINGLE", "m": 7.8}}
+  ],
+}
+```
+
+**mfd-config.json:**
+
+MFD confguration files:
+
+* mfd-map.json
+* mfd-config.json
+* rate-tree.json
+* Rate files (*.csv)
+
+For instance, the final MFDs used in a hazard may be modified by an epistemic or aleatory
+uncertainty model specified in `mfd-config.json`. Single and Gutenberg-Richter MFDs that do not
+have their `rate` or `a`-value members defined rely on the presence of a `rate-tree.json` file.
+A rate-tree defines a logic tree of rates or pointers to CSV rate files with spatially varying
+rate data.
+
+### `mfd-map.json`
+
+A mfd-map defines multiple mfd-trees common to multiple branches of a source-tree.
+
+### `mfd-config.json`
+
+Additional uncertainty in MFDs is often considered when building hazard models and is defined
+in a `mfd-config.json` file. Application of uncertainty models is MFD type-dependent.  The
+`epistemic-tree` member, if non-null, is used to create 3-branches for single and Gutenberg-Richter
+MFDs. For a single MFD, a moment-balanced three-point distribution of magnitudes (± 0.2 magnitude
+units) is created. For a Gutenberg-Richter MFD, three maximum magnidue branches are created, also
+moment-balanced. The `aleatory-properties` member is only applicable to single MFDs and may be
+applied on top of an epistemic-tree. In the example below, `aleatory-properties` defines an
+eleven-point, moment-balanced normal distribution with a width of ±2σ of magnitudes about a
+central magnitude. If no additional uncertainty model is desired,  `epistemic-tree` and
+`aleatory-properties` should be set to null.
+
+TODO is aleatory uncertainty in MFD ALWAYS moment-balanced???
+
+```json
+{
+  "epistemic-tree": [
+    { "id": "+epi", "weight": 0.2, "value": -0.2 },
+    { "id": "----", "weight": 0.6, "value": 0.0 },
+    { "id": "-epi", "weight": 0.2, "value": 0.2 }
+  ],
+  "aleatory-properties": {
+    "count": 11,
+    "momentBalanced": true,
+    "σSize": 2,
+    "σ": 0.12
+  },
+  "minimum-magnitude": 6.5
+}
+```
+
+### `rate-tree.json`
+
+A rate-tree defines each branch `value` in years (recurrence or return period):
+
+```json
+[
+  {
+    "id": "R1",
+    "weight": 0.2,
+    "value" : 10000
+  },
+  {
+    "id": "R2",
+    "weight": 0.8,
+    "value" : 2000
+  }
+]
+```
+
+or with pointers to rate files, in the case of grid sources:
+
+```json
+[
+  {
+    "id": "fixed",
+    "weight": 0.6,
+    "value" : "fixed.csv"
+  },
+  {
+    "id": "adaptive",
+    "weight": 0.4,
+    "value" : "adaptive.csv"
+  }
+]
+```
+
+**mfd-config.json:** Controls properties of the MFD and possible additional epistemic or aleatory
+uncertainty. For example:
+
+```json
+{
+  "epistemic-tree": [
+    { "id": "+uâ‚‘", "weight": 0.2, "value": -0.2 },
+    { "id": "~uâ‚‘", "weight": 0.6, "value": 0.0 },
+    { "id": "-uâ‚‘", "weight": 0.2, "value": 0.2 }
+  ],
+  "aleatory-properties": {
+    "size": 11,
+    "nσ": 2,
+    "σ": 0.12
+  },
+  "minimum-magnitude": 6.5,
+  "nshm-bin-model": false
+}
+```
+
+**rate-tree.json:** Defines each branch `value` in annual rate (1 / return period in years).
+For example:
+
+```json
+[
+  {
+    "id": "R1",
+    "weight": 0.2,
+    "value" : 0.002
+  },
+  {
+    "id": "R2",
+    "weight": 0.8,
+    "value" : 0.05
+  }
+]
+```
+
+From Model Files:
+
+### Magnitude Frequency Distributions (MFDs)
+
+`mfd-tree`, `mfd-map.json`, `mfd-config.json`, and `rate-tree.json`
+
+A `mfd-tree` property is common to all source types and defines a logic tree of magnitude
+frequency distributions (MFDs). The `mfd-tree` element may be an array of mfd branches defined
+inline or a string reference to a top-level member of an `mfd-map.json` that contains one or
+more mfd-trees shared across a source-tree. The branches of a mfd-tree commonly have the generic
+ID's: `[M1, M2, M3, ...]` to support mfd-tree matching across source-tree branches.
+
+```json
+"mfd-tree": [
+  { "id": "M1", "weight": 0.3, "value": { "type": "SINGLE", "m": 6.8, "rate": 0.001 }},
+  { "id": "M2", "weight": 0.3, "value": { "type": "SINGLE", "m": 7.0, "rate": 0.001 }},
+  { "id": "M3", "weight": 0.3, "value": { "type": "SINGLE", "m": 7.2, "rate": 0.001 }},
+  { "id": "M4", "weight": 0.1, "value": { "type": "SINGLE", "m": 7.4, "rate": 0.001 }}
+]
+```
+
+How MFDs are actually built depends on the settings in a `mfd-config.json` file and rates. For more
+details on MFDs and their configuration see the
+[magnitude frequency distributions](magnitude-frequency-distributions) section.
+
+An `mfd-config.json` is currently only required for finite fault sources. It can be located
+anywhere in the file heirarchy and may be overridden in nested directories.
+
+Depending on the types of MFDs being modeled, a rate file may contain Gutenberg-Richter a-values
+or magnitude-specific rates. The branches of a rate-tree commonly have the generic ID's:
+`[R1, R2, R3, ...]` to support matching rate-trees across source-tree branches.
+
+```xml
+        <!-- (optional) A magnitude uncertainty model that will be
+             applied to every source:
+               - <Epistemic/> varies mMax and scales variant rates by
+                 the supplied weights; it is only ever applied to SINGLE
+                 and GR MFDs.
+               - 'cutoff' is magnitude below which uncertainty will be
+                 disabled.
+               - <Aleatory/> applies a (possibly moment-balanced) ±2σ
+                 Gaussian distribution to mMax; it is only ever applied
+                 to SINGLE MFDs (possibly in conjunction with epistemic).
+               - 'count' is the number of magnitude bins spanned by
+                 the distribution.
+               - <Aleatory/> or '<Epistemic/>', or the entire block
+                 may be omitted. -->
+        <MagUncertainty>
+            <Epistemic cutoff="6.5" 
+                deltas="[-0.2, 0.0, 0.2]" weights="[0.2, 0.6, 0.2]" />
+            <Aleatory cutoff="6.5" 
+                moBalance="true" sigma="0.12" count="11" />
+        </MagUncertainty>
+
+        <SourceProperties ruptureScaling="NSHM_FAULT_WC94_LENGTH" />
+
+    </Settings>
+```
diff --git a/docs/Model Editions.md b/docs/Model Editions.md
new file mode 100644
index 0000000000000000000000000000000000000000..e4524a35cd4b794875e8006ba0cf361435d4d679
--- /dev/null
+++ b/docs/Model Editions.md	
@@ -0,0 +1,99 @@
+# USGS Models: Editions
+
+USGS hazard models are created and updated in response to user needs. In some cases a model is
+updated in response to cyclic updates to the U.S. Building Code. In other cases, enough time has
+passed that there have been significant advancements in the science, availability of relevant
+data, or modeling procedures that warrant a model update. Every model the USGS produces is
+associated with a USGS Open-File report or refereed journal article and supporting datasets.
+However, layered on top of any given model release are bug-fixes and model improvements.
+
+With the update to a new codebase, [nshmp-haz](https://github.com/usgs/nshmp-haz), the NSHMP has
+adopted [semantic versioning](http://semver.org) to keep track of different hazard models. For
+any given model region, the first number (or major version) corresponds to a particular release
+or update year. For example, we consider the initial
+[1996 conterminous U.S. NSHM](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#1996)
+to be v1.0.0. The second number (or minor version) reflects updates to a particular release that
+likely causes small changes to hazard values. The third number reflects non-hazard altering
+changes; for instance, a change to the model file format that has no consequence on computed
+hazard.
+
+The USGS NSHMP is committed to supporting current and prior model releases in any given region
+via web services. The table below provides a summary of all NSHM releases and their corresponding
+version numbers.
+
+Region | Year | Version | Static | Dynamic | Notes |
+-------|:----:|:-------:|:------:|:-------:|-------|
+Conterminous U.S. | [2014](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2014) | [v4.2.0](https://github.com/usgs/nshmp-model-cous-2014/releases/tag/v4.2.0)<sup>†</sup> | |:small_blue_diamond:| |
+Conterminous U.S. | [2014](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2014) | [v4.1.4](https://github.com/usgs/nshmp-model-cous-2014/releases/tag/v4.1.4)<sup>†</sup> | |:small_blue_diamond:| |
+Conterminous U.S. | [2014](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2014) | [v4.0.0](https://github.com/usgs/nshmp-haz-fortran/releases/tag/nshm2014r1) |:small_blue_diamond:| | ASCE7-16 |
+Conterminous U.S. | [2008](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2008) | v3.3.3 | |:small_blue_diamond:| |
+Conterminous U.S. | [2008](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2008) | [v3.2.0](https://github.com/usgs/nshmp-haz-fortran/releases/tag/nshm2008r3) |:small_blue_diamond:| | |
+Conterminous U.S. | [2008](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2008) | v3.1.0 |:small_blue_diamond:| | ASCE7-10 |
+Conterminous U.S. | [2008](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2008) | v3.0.0 | | | |
+Conterminous U.S. | [2002](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2002) | v2.0.0 | | | |
+Conterminous U.S. | [1996](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#1996) | v1.0.0 | | | |
+Alaska            | [2007](https://earthquake.usgs.gov/hazards/hazmaps/ak/index.php#2007) | v2.1.0 | |:small_blue_diamond:| |
+Alaska            | [2007](https://earthquake.usgs.gov/hazards/hazmaps/ak/index.php#2007) | v2.0.0 |:small_blue_diamond:| | ASCE7-10 |
+Alaska            | [1999](https://earthquake.usgs.gov/hazards/hazmaps/ak/index.php#1999) | v1.0.0 | | | |
+American Samoa    | [2012](https://earthquake.usgs.gov/hazards/hazmaps/islands.php#samoapacific) | v1.0.0 | | | |
+Guam              | [2012](https://pubs.usgs.gov/of/2012/1015/) | v1.0.0 | | | |
+Hawaii            | [2018](https://earthquake.usgs.gov/hazards/hazmaps/islands.php#hi) | v2.0.0 | | TBD | |
+Hawaii            | [1998](https://earthquake.usgs.gov/hazards/hazmaps/islands.php#hi) | v1.1.0 | | TBD | |
+Hawaii            | [1998](https://earthquake.usgs.gov/hazards/hazmaps/islands.php#hi) | v1.0.0 |:small_blue_diamond:| | ASCE7-10 |
+Puerto Rico & <br/> U.S. Virgin Islands | [2003](https://earthquake.usgs.gov/hazards/hazmaps/islands.php#prvi) | v1.0.0 | | | |
+
+<sup>†</sup> __Note on the 2014 Conterminous U.S. NSHM:__ Initial publication of the
+[2014 model](https://earthquake.usgs.gov/hazards/hazmaps/conterminous/index.php#2014) included
+data to support updates to the U.S. Building Code, specifically hazard curves for peak ground
+acceleration (PGA), and 0.2 and 1.0 second spectral accelerations, all at a BC boundary site
+class with Vs30 = 760 m/s. Some time later, the model was deployed to the Unified Hazard Tool
+(UHT) and included support in the Wester U.S. for calculations at sites other than Vs30 = 760 m/s,
+consistent with dynamic calculations using the 2008 model. Subsequently, we updated the 2014
+model with [addional periods and site classes](https://pubs.er.usgs.gov/publication/ofr20181111).
+Doing so required dropping several ground motion models (GMMs) and a redistribution of logic-tree
+weights. Specifically, the Idriss (2014) model is inappropriate for use at soft soil sites and
+the Atkinson & Boore (2003) model does not support long periods (see the
+[open-file report](https://pubs.er.usgs.gov/publication/ofr20181111) for more information).
+Moving forward, we will continue to include the original dynamic version of the 2014 model
+(v4.1.4) in the UHT. However, we recommend that users consider the updated model (4.2.0).
+
+## Static vs. Dynamic
+
+Historically, the USGS NSHMP has produced static datasets of hazard curves that accompany the
+'official' release or update to a model. In the context of providing interactive web services,
+such static datasets can be quickly retreived and provide most users with the data they seek.
+More complex analyses, such as deaggregations, require that a complete hazard calculation be
+performed on demand. Historically, USGS deaggregation services were provided for particular model
+years and regions, each located at a unique web address and supported by a unique codebase.
+However, it has proven too difficult to maintain numerous isolated services, and we therefore
+developed a single codebase that supports all current and prior models.
+
+Moreover, as time goes by, there may be more customization options we want to expose to users.
+However, with each additional level of customization, it quickly becomes too difficult to produce
+and version corresponding static datasets. We therefore identify model versions that support
+deaggregations and other calculations as 'dynamic'. At present, only the most current versions
+of a particular model region and year are supported via 'dynamic' calculations.
+
+In practice, this leads to results produced by 'dynamic' caluculations being somewhat different
+than those stored in static datasets of prior model minor versions, although usually not by much.
+The release notes for each model version detail the changes that give rise to changes in hazard
+between between versions. There are also differences that arise from different modeling
+assumptions between past and current codebases that are detailed below.
+
+It is important for users to know which edition they should be using. For instance if one is
+bound to use those values adopted by the U.S. building code, one of the editions marked `ASCE7-*`
+is probably most appropriate. However, if one is bound to use the most up to date source model,
+one of the dynamic editions is likely better.
+
+Dynamic editions are supported through web-services provided by the `nshmp-haz-ws` library
+(this repository). Static editions are supported via a separate set of services. Both are
+documented on the [web services](web-services) page.
+
+## Region specific changes
+
+Changes between editions in model regions are documented in the release notes of the individual
+model repositories.
+
+* [Conterminous US (2014)](/usgs/nshmp-model-cous-2014/wiki)  
+* [Conterminous US (2008)](/usgs/nshmp-model-cous-2008/wiki)  
+* [Alaska (2007)](/usgs/nshmp-model-ak-2007/wiki)  
diff --git a/docs/Model-Files.md b/docs/Model-Files.md
new file mode 100644
index 0000000000000000000000000000000000000000..f6433e2a2588aa02f62db33d0b86ac31c35a27e2
--- /dev/null
+++ b/docs/Model-Files.md
@@ -0,0 +1,185 @@
+# Model Files
+
+A variety of logic tree, configuration, and data files that are common to all models and source
+types are described below and on related pages for specific model components, for example, ground
+motion models (GMMs) or magnitude-frequency distributions (MFDs).
+
+[[_TOC_]]
+
+## Model and Calculation Configuration
+
+**model-info.json:** Required model identifying metadata. Currently the model name and
+definitions of Vs30 values for each NEHRP site class that were used when computing design ground
+motions from the model.
+
+```json
+{
+  "name": "NSHM Conterminous U.S. 2018",
+  "site-class-vs30": {
+    "AB": 1500,
+    "B": 1080,
+    "BC": 760,
+    "C": 530,
+    "CD": 365,
+    "D": 260,
+    "DE": 185,
+    "E": 150
+  }
+}
+```
+
+**calc-config.json:** Optional calculation configuration file specifies the default
+calculation settings used for a NSHM. This file overrides any built in default values. See
+the [calculation configuration](calculation-configuration) page for more details.
+
+## Logic Trees
+
+Any file or JSON member name containing `-tree` implies that the file contents or member value
+will be an array of logic tree branches. Branches are defined with an `id`, `weight`, and `value`.
+Depending on context, value can be a number, string, or object. For example:
+
+ ```json
+ [
+  {
+    "id": "string",
+    "value": "number | string | object",
+    "weight": 0.4
+  }, {
+    "id": "string",
+    "value": "number | string | object",
+    "weight": 0.6
+  }
+]
+```
+
+If the `value` member is absent, then the branch `id` is also the `value`. Logic tree weights must
+sum to one. Examples of logic trees present in a hazard model are described below. An `id` or
+`value` member value in ALL_CAPS indicates the value is one of a fixed number of options commonly
+referred to as an enum.
+
+### Source Model Logic Trees
+
+**source-tree.json:** Defines a single logic tree branching point where each branch `value` points
+to a subdirectory of nested branches. Source-tree weights are used to scale hazard curves when
+computing mean hazard and for source event-set selection. When loading a model, a source-tree
+governs all subsequent processing of nested directories. Only those resources required by the tree
+or its children will be processed; any standalone sources will be ignored. For example:
+
+```json
+[
+  {
+    "id": "segmented",
+    "weight": 0.5
+  },
+  {
+    "id": "unsegmented",
+    "weight": 0.5
+  }
+]
+```
+
+**source-group.json:** A specialized form of logic tree that describes model branches that are
+additivd and therefore does not include weights. Examples from the NSHM for the Conterminous U.S.
+NSHM include the Cascadia segmented partial-rupture models and the New Madrid 1500-yr cluster
+branches. The branch objects in a source group _may_ include an optional `scale` member that can
+be used to impose a probability of occurrence or other scaling requred by a NSHM. If absent, the
+`scale` value is one.
+
+```json
+[
+  {
+    "id": "all",
+    "scale": 0.2
+  },
+  {
+    "id": "center-south",
+    "scale": 1.5
+  }
+]
+```
+
+### GMM Logic Trees
+
+**gmm-tree.json:** Defines the logic tree of ground motion models to use in each tectonic setting.
+For example:
+
+```json
+[
+  { "id": "ASK_14", "weight": 0.25 },
+  { "id": "BSSA_14", "weight": 0.25 },
+  { "id": "CB_14", "weight": 0.25 },
+  { "id": "CY_14", "weight": 0.25 }
+]
+```
+
+See the [ground motion models](ground-motion-models) page for details on GMMs supported in
+_nshmp-haz_ and the related `gmm-config.json` files that governs GMM behavior.
+
+### MFD Logic Trees
+
+MFD logic trees are typically defined as JSON members nested in other files. For example:
+
+```json
+"mfd-tree": [
+  { "id": "M1", "weight": 0.3, "value": { "type": "SINGLE", "m": 6.8, "rate": 0.001 }},
+  { "id": "M2", "weight": 0.3, "value": { "type": "SINGLE", "m": 7.0, "rate": 0.001 }},
+  { "id": "M3", "weight": 0.3, "value": { "type": "SINGLE", "m": 7.2, "rate": 0.001 }},
+  { "id": "M4", "weight": 0.1, "value": { "type": "SINGLE", "m": 7.4, "rate": 0.001 }}
+]
+```
+
+An `mfd-tree` may be included as a `properties` member of a GeoJSON feature or as a member of a
+`rupture-set.json` file. In both cases the tree may alternatively be identified with a string, in
+which case the `mfd-tree` will be pulled from the collection of trees defined in a `mfd-map.json`
+file. A `mfd-map.json` file is typicaly located high in the source tree heirarchy and faciltates
+using the same MFDs on multiple branches of a source tree.
+
+How MFDs are intialized (or realized) depends on the presence and contents of `mfd-config.json` and
+`rate-tree.json` files. See the
+[magnitude frequency distributions](magnitude-frequency-distributions) page for details on these
+files and the types of MFDs supported in _nshmp-haz_.
+
+## Rupture Sets
+
+**rupture-set.json**: A `rupture-set` is the terminal file of a source-tree branch and defines the
+fault sections and MFD's required to intialize a source.
+
+```json
+{
+  "name": "New Madrid - USGS (center)",
+  "id": 3023,
+  "sections": [3020, 3021, 3022],
+  "mfd-tree": "usgs-hi-mag"
+}
+```
+
+In the example above, one set of New Madrid ruptures is assigned the specified numeric `id`. The
+fault geometry of the rupture-set is constructed by stitching the specified fault `sections`
+together, and earthquake magnitudes and rates are governed by the specified `mfd-tree`. In this
+case, `mfd-tree` points to a named tree that will be present in an `mfd-map.json` accompanying
+the source-tree. The `sections` member may be absent. In this case, the `id` of the rupture-set
+is the same as the single, associated fault section.
+
+**cluster-set.json**: A specialized form of a rupture set. Fault sources also support cluster
+models where the total hazard is computed from the probability of exceeding some ground motion
+level is conditioned on the occurrence of 2 or more, roughly contemporaneous events. A cluster-set
+is composed of an array of rupture-sets.
+
+```json
+{
+  "name": "New Madrid - USGS (center, center-south)",
+  "id": 3025,
+  "rupture-sets": [
+    {
+      "name": "USGS (center, center)",
+      "id": 3021,
+      "mfd-tree": "usgs-hi-mag"
+    },
+    {
+      "name": "USGS (center, south)",
+      "id": 3022,
+      "mfd-tree": "usgs-hi-mag"
+    }
+  ]
+}
+```
diff --git a/docs/Model-Structure.md b/docs/Model-Structure.md
new file mode 100644
index 0000000000000000000000000000000000000000..c4fdfc6ca4b802f60716c0a1467f171207f5b421
--- /dev/null
+++ b/docs/Model-Structure.md
@@ -0,0 +1,195 @@
+# Model Structure
+
+Earthquake source models are specified using [JSON](https://www.json.org),
+[GeoJSON](https://geojson.org), and CSV files. The files in a model directory tree are largely
+self describing and represent logic trees and other relationships between source model ingredients
+(JSON), source geometry (GeoJSON features), and earthquake rate data (CSV). JSON is well-suited
+for representing model data and relationships and is supported in most programming languages.
+
+[[_TOC_]]
+
+## Directory Structure
+
+Earthquake source files are organized by tectonic setting: `active-crust`, `stable-crust`,
+`subduction-interface`, `subduction-slab`, and `volcanic` with the two crustal and the volcanic
+settings supporting the nested source types: `fault-sources`, `grid-sources`, and `zone-sources`.
+The `volcanic` tectonic setting also supports `decollement-sources`.
+
+The root of a model must include `model-info.json` and _may_ include a `calc-config.json` that
+specifies any custom default [calculation configuration](calculation-configuration) settings
+for the model. Top level tectonic setting directories must include `gmm-tree.json` and
+`gmm-config.json` files. Source directories are loaded recursively, permitting configuration files
+deeper in the heirarchy to override those defined higher in the heirarchy, as needed and as
+specified for each source type. Nested directories support associations between groups of sources,
+their configuration and initialization, and ground motion models. If there are a large number of
+sources in a model, sources are typically further organized by region or other grouping. Example
+model top-level directory tree:
+
+```text
+model-directory/
+  ├─ model-info.json              (required)
+  ├─ calc-config.json             (optional, overrides defaults)
+  │
+  ├─ active-crust/
+  │   ├─ gmm-config.json          (required, can override)
+  │   ├─ gmm-tree.json            (required, can override)
+  │   │
+  │   ├─ fault-sources/
+  │   │   └─ ...
+  │   │
+  │   ├─ grid-sources/
+  │   │   └─ ...
+  │   │
+  │   └─ zone-sources/
+  │       └─ ...
+  │
+  ├─ stable-crust/...             Same structure as 'active-crust'
+  │   └─ ...
+  │
+  ├─ subduction-interface/        Similar structure to 'fault-sources'
+  │   └─ ...
+  │
+  └─ subduction-slab/             Similar structure to 'grid-sources'
+      └─ ...
+```
+
+The following sections describe each source type, associated configuration and source definition
+files, and any other requirements.
+
+## Crustal Finite Fault Sources
+
+Finite fault sources may either be defined as a single source (commonly with associated logic
+trees of MFDs, slip rates, or dip variations) or a more complex logic tree of source model
+variants. GeoJSON feature files define fault sections using a `LineString` representing the
+surface trace of the section. The coordinate order of the trace must adhere to the U.S. structural
+geology right-hand rule.
+
+```text
+fault-sources/
+  ├─ fault-config.json            (required, can override)
+  ├─ mfd-config.json              (required, can override)
+  ├─ mfd-map.json                 (optional) Map of shared mfd-trees
+  │
+  ├─ single-fault-sources/
+  │   ├─ source-1.geojson
+  │   ├─ source-2.geojson
+  │   └─ nested-sources/
+  │       └─ ...
+  │
+  └─ tree-based-fault-source/     Nested directories may have any name
+      ├─ source-tree.json         Source logic tree; when present, governs
+      │                             subsequent processing; includes pointers
+      │                             to branch directories below
+      │
+      ├─ features/                (required) Directory of fault features
+      │   ├─ section-1.geojson
+      │   ├─ section-2.geojson
+      │   └─ ...
+      │
+      ├─ branch-1/
+      │   └─ rupture-set.json     Fault source logic tree branching always
+      │                             ends at a 'rupture-set'
+      └─ branch-2/
+          ├─ source-tree.json
+          ├─ branch-3/
+          └─ branch-4/
+```
+
+See also: [Finite Fault Source Type](source-types#finite-fault-sources)
+
+## Crustal Grid Sources
+
+TODO this isn't quite right, needs conus-2018 refactor for verification
+
+Grid sources are based on smoothed seismicity or other spatially varying rate model and may be
+defined as either single source features, each within its own directory, or as more complex logic
+trees of source model variants. Grid sources are modeled as point sources of varying complexity.
+Multiple GeoJSON `Polygon`s may be used to accomodate spatial variations in source properties.
+
+```text
+grid-sources/
+  ├─ grid-config.json             (required, can override)
+  ├─ mfd-map.json                 (optional) Map of shared mfd-trees
+  ├─ features/                    (required) Directory of grid feature bounds
+  ├─ grid-data/                   (required) Directory of all spatial PDFs
+  │
+  ├─ single-grid-source/
+  │   ├─ grid-source.geojson
+  │   └─ rate-tree.json           Optional tree of rates
+  │
+  └─ tree-based-grid-source/
+      ├─ source-tree.json         Source logic tree
+      │
+      ├─ branch-1/
+      │   └─ grid-source.geojson  Grid source logic tree branching always
+      ├─ branch-2/                     ends at a *.geojson file
+      │   └─ ...
+      └─ ...
+```
+
+See also: [Grid Source Type](source-types#grid-sources)
+
+## Crustal Zone (Area) Sources
+
+Zone sources specify a single rate that is distributed over a GeoJSON `Polygon` using point source
+rupture models. Presently, there is a 1:1 mapping of source zones to their associated rate files.
+*__Note:__ The rate file approach will be discouraged and/or deprecated in the near future in favor
+of dynamically computing rates over a zone from a single value or `rate-tree.json` when the loading
+a model.*
+
+```text
+zone-sources/
+  ├─ zone-config.json             (required, can override)
+  ├─ mfd-config.json              (required)
+  ├─ mfd-map.json                 (optional) Map of shared mfd-trees
+  │
+  ├─ single-zone-source/
+  │   ├─ zone-source.geojson
+  │   ├─ zone-source.csv          (required) File of rate data    (current)
+  │   └─ [rate-tree.json]         (optional) Tree of rates        (future)
+  │
+  └─ tree-based-zone-source/
+      ├─ source-tree.json         Source logic tree
+      └─ branch-1/
+          ├─ zone-source.geojson  Grid source branching ends at a *.geojson file
+          ├─ zone-source.csv      (required) file of rate data    (current)
+          └─ [rate-tree.json]     (optional) tree of rates        (future)
+```
+
+See also: [Zone Source Type](source-types#zone-sources)
+
+## Subduction Interface Sources
+
+Subduction interface sources are modeled in a similar manner as crustal fault sources; they may
+be a single source or a more complex logic tree of source model variants. GeoJSON feature files
+define interface sections using a `MultiLineString` of multple traces at increasing depths. The
+coordinate order of each trace must adhere to the U.S. structural geology right-hand rule.
+
+```text
+subduction-interface
+  ├─ gmm-config.json              (required)
+  ├─ gmm-tree.json                (required)
+  ├─ interface-config.json        (required)
+  ├─ mfd-config.json              (required)
+  └─ ...
+```
+
+See also: [Subduction Interface Source Type](source-types#subduction-interface-sources)
+
+## Subduction Intraslab Sources
+
+Subduction intraslab sources are modeled in a similar manner as crustal grid sources. Slab sources
+typically have spatially varying rates, but their depths also vary. In contrast to grid sources,
+rate files (`*.csv`) are stored adjacent to their corresponding feature file (`*.geojson`);
+_this may change in a future release_.
+
+```text
+subduction-slab
+  ├─ gmm-config.json              (required)
+  ├─ gmm-tree.json                (required)
+  ├─ slab-config.json             (required)
+  ├─ mfd-config.json              (required)
+  └─ ...
+```
+
+See also: [Subduction Intraslab Source Type](source-types#subduction-intraslab-sources)
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3df0badcbca381d9d8a4359193898fd1fffbb0c7
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,42 @@
+# Documentation: nshmp-haz
+
+***nshmp-haz*** is a USGS developed software stack that supports probabilistic seismic hazard
+(PSHA) and related analyses. It is maintained by the National Seismic Hazard Model Project
+([NSHMP](https://earthquake.usgs.gov/hazards/)) within the U.S. Geological Survey's
+([USGS](https://www.usgs.gov)) earthquake hazards program ([EHP](http://earthquake.usgs.gov)).
+
+*nshmp-haz* supports high performance seismic hazard calculations required to generate detailed
+maps over large areas and supports a variety of USGS web services and applications related to
+seismic hazards research and the dissemination of hazard data. This documentation explains how
+to use *nshmp-haz* as well as underlying model implementation details.
+
+## Table of Contents
+
+* [About the NSHMP](about-the-nshmp)
+* [Building & Running](building-&-running)
+  * [Developer Basics](developer-basics)
+  * [Calculation Configuration](calculation-configuration)
+  * [Site Specification](site-specification)
+  * [Examples](/ghsc/nshmp/nshmp-haz/-/tree/master/etc/examples)
+* [Hazard Model](hazard-model)
+  * [Model Structure](model-structure)
+  * [Model Files](model-files)
+  * [Source Types](source-types)
+  * [Magnitude Frequency Distributions (MFDs)](magnitude-frequency-distributions-mfds)
+  * [Rupture Scaling Relations](rupture-scaling-relations)
+  * [Ground Motion Models (GMMs)](ground-motion-models-gmms)
+* [USGS Models](usgs-models)
+  * [Model Editions](model-editions)
+  * [Logic Trees & Uncertainty](logic-trees-&-uncertainty)
+
+## Other Pages & References
+
+* [nshmp-lib](/ghsc/nshmp/nshmp-lib): USGS hazard modeling library
+* [Functional PSHA](functional-psha)
+* [Probabilistic Seismic Hazard Analysis, a Primer
+  [PDF]](http://www.opensha.org/sites/opensha.org/files/PSHA_Primer_v2_0.pdf)
+  by Edward Field  
+* [An Introduction to Probabilistic Seismic Hazard Analysis
+  [PDF]](http://web.stanford.edu/~bakerjw/Publications/Baker_(2015)_Intro_to_PSHA.pdf)
+  by Jack Baker  
+* [License](../LICENSE.md)
diff --git a/docs/Rupture-Scaling-Relations.md b/docs/Rupture-Scaling-Relations.md
new file mode 100644
index 0000000000000000000000000000000000000000..0a79a5e4f6e0abdcd037bf2dfbdc8ce4521cd417
--- /dev/null
+++ b/docs/Rupture-Scaling-Relations.md
@@ -0,0 +1,69 @@
+# Rupture-Scaling Relations
+
+Rupture scaling models describe relationships between rupture geometry and magnitude. Such models
+are used in a NSHM to:
+
+* Compute an expected magnitude from a rupture geometry.
+* Compute the size (length or area) of a rupture from a magnitude.
+* Compute point-source distance corrections (optimization for unknown strike)
+
+Rupture scaling model implementations typically impose restrictions on rupture aspect ratio.
+
+## Magnitude-Scaling Relationships
+
+| Region             | Reference                  | Tectonic Setting | Type         |
+|:------------------ |:-------------------------  |:------------ |:---------------- |
+| WellsCoppersmith-L | Wells & Coppersmith (1994) | active crust | magnitude-length |
+| EllsworthB         | WGCEP (2002)               | active crust | magnitude-area   |
+| EllsworthB-SqrtL¹  | Shaw (2013b)               | active crust | magnitude-area   |
+| HanksBakun-08      | Hanks & Bakun (2008)       | active crust | magnitude-area   |
+| Shaw09mod          | Shaw (2013a, 2013b)        | active crust | magnitude-area   |
+| Shaw09mod-CSD¹     | Shaw (2013a, 2013b)        | active crust | magnitude-area   |
+| Somerville-01      | Somerville et al. (2001)   | stable crust | magnitude-area   |
+| Strasser-10        | Strasser et al. (2010)     | subduction   | magnitude-length |
+| Murotani-08        | Murotani et al. (2008)     | subduction   | magnitude-length |
+| Papazachos-04      | Papazachos et al. (2004)   | subduction   | magnitude-length |
+| Youngs-97          | Youngs et al. (1997)       | subduction   | magnitude-length |
+
+¹ UCERF3 uses rupture scaling relationships to also balance slip rate when computing rupture
+rates. These models consider alternative slip-length scaling relations relative to the default
+computed from rupture area and moment; see Field et al. (2014) for details.
+
+² Also referred to as the 'Geomatrix' relation
+
+## References
+
+Hanks TC, and Bakun WH (2008) M- log A observations of recent large earthquakes. Bulletin of the
+Seismological Society of America 98(1): 490–494.
+
+Murotani S, Miyake H, Koketsu K (2008) Scaling of characterized slip models for plate-boundary
+earthquakes. Earth, Planets, and Space 60(?): 987–981.
+
+Papazachos BC, Scordilis EM, Panagiotopoulos DG, Papazachos CB, and Karakaisis GF (2004) Global
+relations between seismic fault parameters and moment magnitudes of earthquakes. Bulletin of the
+Geological Society of Greece 36(?): 1482–1489.
+
+Shaw BE (2013a) Earthquake surface slip-length data is fit by constant stress drop and is useful
+for seismic hazard analysis, Bulletin of the Seismological Society of America 103(2A): 876-893.
+
+Shaw BE (2013b) Appendix E: Evaluation of magnitude-scaling relationships and depth of rupture:
+Recommendation for UCERF3, U.S. Geol. Surv. Open-File Rept. 2013-1165-E, and California Geol.
+Surv. Special Rept. 228-E.
+
+Somerville P, Collins N, Abrahamson NA, Graves R, and Saikia C (2001) Ground motion attenuation
+relations for the Central and Eastern United States—Final report, June 30, 2001: Report to U.S.
+Geological Survey for award 99HQGR0098, 38 p.
+
+Strasser FO, Arango MC, and Bommer JJ (2010) Scaling of the source dimensions of interface and
+intraslab subduction-zone earthquakes with moment magnitude: Seismological Research Letters
+81(?): 941–950.
+
+Wells DL and Coppersmith KJ (1994) New empirical relationships among magnitude, rupture length,
+rupture width, and surface displacements: Bulletin of the Seismological Society of America,
+84(?): 974–1002.
+
+Working Group on California Earthquake Probabilities (WGCEP) (2003). Earthquake probabilities in
+the San Francisco Bay region: 2002– 2031, U.S. Geol. Surv. Open-File Report 2003-214.
+
+Youngs RR, Chiou B-SJ, Silva WJ, and Humphrey JR (1997) Strong ground motion attenuation
+relationships for subduction zone earthquakes. Seismological Research Letters 68(?): 58–73.
diff --git a/docs/Site-Specification.md b/docs/Site-Specification.md
new file mode 100644
index 0000000000000000000000000000000000000000..c2a27fa42b90f59556bd3498d6bca3d04009d293
--- /dev/null
+++ b/docs/Site-Specification.md
@@ -0,0 +1,110 @@
+# Site Specification
+
+(TODO update etc and/or javadoc links)
+
+The sites at which to perform hazard and related calculations may be defined in a variety of
+ways. Examples of the file formats described below are available in the resource directory:
+[`etc/nshm`](/usgs/nshmp-haz/tree/master/etc/nshm).
+
+__Note on Coordinates:__ *nshmp-haz* supports longitude and latitude values in the closed
+ranges `[-360° ‥ 360°]` and `[-90° ‥ 90°]`. Note, however, that mixing site and/or source
+coordinates across the antimeridian (the -180° to 180° transition) will yield unexpected results.
+For Pacific models and calculations, always use positive or negative longitudes exclusively.
+
+## Site String
+
+For the case of running a single site of interest, most *nshmp-haz* programs accept a
+comma-delimited string of the form: `name,lon,lat[,vs30,vsInf[,z1p0,z2p5]]`, where `vs30`, `vsInf`,
+`z1p0`, and `z2p5` are optional. Note that if `vs30` is supplied, so too must `vsInf`. Likewise if
+`z1p0` is supplied, so too must `z2p5`. If the string contains any spaces, escape them or wrap the
+entire string in double quotes.
+
+For any site parameter values that are not supplied on the command line or in the file formats
+below, the following defaults are used (see the `site` member of the
+[configuration](calculation-configuration) file):
+
+```text
+    name: Unnamed
+    vs30: 760.0
+   vsInf: true
+    z1p0: null (GMM will use default basin depth model)
+    z2p5: null (GMM will use default basin depth model)
+```
+
+For basin depth parameters `z1p0` and `z2p5`, a `null` value indicates that a GMM should use
+it's 'default' basin depth scale factor.
+
+## Comma-Delimited Format (\*.csv)
+
+* Header row must identify columns.
+* Valid and [optional] column names are:
+  `[name,] lon, lat [, vs30] [, vsInf] [, z1p0] [, z2p5]`  
+* At a minimum, `lon` and `lat` must be defined.
+* Columns can be in any order and any missing fields will be populated with the default values
+  listed above.
+* If a site `name` is supplied, it is included in the first column of any output curve files.
+
+## GeoJSON Format (\*.geojson)
+
+Although more verbose than the comma-delimited format, [GeoJSON](http://geojson.org) is a more
+versatile format for encoding geographic data. *nshmp-haz* uses GeoJSON for both lists of sites
+and to define map regions. If you encounter problems when formatting JSON files, use
+[JSONLint](http://jsonlint.com) or [GeoJSONLint](http://geojsonlint.com) for validation.
+
+### Site Lists
+
+A site list is expected as a `FeatureCollection` of `Point` features. For example:
+
+```json
+{
+  "type": "FeatureCollection",
+  "features": [
+    {
+      "type": "Feature",
+      "geometry": {
+        "type": "Point",
+        "coordinates": [-122.25, 37.80]
+      },
+      "properties": {
+        "title": "Oakland CA",
+        "vs30": 760.0,
+        "vsInf": true,
+        "z1p0": 0.048,
+        "z2p5": 0.607
+      }
+    }
+  ]
+}
+```
+
+As with the CSV format, the minimum required data is a `geometry` `coordinates` array. All
+`properties` are optional. When using GeoJSON, the `title` property maps to the name of the site.
+Additional properties, if present, are ignored by *nshmp-haz* but permitted as they may be
+relevant for other applications. For example, [styling
+properties](https://help.github.com/articles/mapping-geojson-files-on-github/#styling-features)
+may be used to improve rendering in mapping applications. For a fully fledged example, see the
+[NSHM test sites](/usgs/nshmp-haz/blob/master/etc/nshm/sites-nshmp.geojson) file.
+
+### Map Regions
+
+GeoJSON is also used to define *nshmp-haz* map regions. For example, see the file that defines a
+region commonly used when creating hazard and other maps for the
+[Los Angeles basin](/usgs/nshmp-haz/blob/master/etc/nshm/map-la-basin.geojson).
+
+A map region is expected as a `Polygon` `FeatureCollection`. Currently, *nshmp-haz* only supports
+a `FeatureCollection` with 1 or 2 polygons. When a single polygon is defined, it must consist of a
+single, simple closed loop. Additional arrays that define holes in the polygon (per the GeoJSON
+spec) are not processed and results are undefined for self-intersecting coordinate arrays. This
+polygon feature supports the same (optional and/or extra) `properties` as the `Point` features
+described above. The site properties are applied to all sites in the defined region. In addition,
+this feature *must* define a `spacing` property with a value in decimal degrees that governs the
+site density within the region. This polygon defines the area over which hazard calculations are
+to be performed.
+
+A second polygon may be used to define a map region. This polygon *must* be defined first, *must*
+have a feature `id` of `Extents`, and *must* be rectangular (in a mercator projection) with edges
+parallel to lines of latitude and longitude. Any points in the 'calculation' polygon outside the
+'extents' polygon are ignored; hazard values at any points within the 'extents' polygon but
+outside the 'calculation' polygon are set to zero. For an example, see the
+[NSHMP Western US](/usgs/nshmp-haz/blob/master/etc/nshm/map-wus.geojson) map site file.
+(TODO This needs updating; link to conus-2018 active crust map-region.geojson).
diff --git a/docs/Source-Types.md b/docs/Source-Types.md
new file mode 100644
index 0000000000000000000000000000000000000000..86278011bd04619138aed3f597341cc61487efb1
--- /dev/null
+++ b/docs/Source-Types.md
@@ -0,0 +1,346 @@
+# Source Types
+
+Earthquake source representations take a variety of forms in a NSHM. They may be well-defined
+finite fault surfaces or distributed grids of more general geometry with uniform or spatially
+varying rates, as are used to represent earthquakes of unknown location. Both classes of geometry
+are used in all tectonic settings. For instance, finite source geometries are used for crustal
+faults in active and stable continental regions, as well as to define the ruptures surfaces of
+possible subduction interface earthquakes. Distributed grids of sources are commonly used to
+represent models of smoothed seismicity in both crustal and subduction intraslab settings but
+may also be used for fault zones where there is a history of large earthquakes but the fault
+geometry itself is unknown or very poorly defined.
+
+[[_TOC_]]
+
+Source models for use with *nshmp-haz* are defined using [JSON](https://www.json.org) and
+[GeoJSON](https://geojson.org). *nshmp-haz* makes determinations about how to represent a source
+based on a GeoJSON geometry type in conjunction with supporting JSON configuration files. Example
+source configuration files, `*-config.json`, are provided with each source type description.
+Configuration files must be fully specified with `null` JSON member values used to specify 'do
+nothing' where appropriate. Any configuration member value in ALL_CAPS indicates the value is one
+of a fixed number of options commonly referred to as an enum.
+
+__Note on Coordinates:__ *nshmp-haz* supports longitude and latitude values in the closed ranges
+`[-360°‥360°]` and `[-90°‥90°]`. Note, however, that mixing site and/or source coordinates across
+the antimeridian (the -180° to 180° transition) will yield unexpected results. For Pacific models
+and calculations, always use positive or negative longitudes exclusively.
+
+## Grid Sources
+
+Grid, or smoothed seismicity, sources are used to represent earthquakes that may occur but that
+are not, as yet, associated with a known active fault. Such source models are typically developed
+through the declustering and smoothing of earthquake catalogs given that past earthquakes are good
+indicators of future activity. Declustering removes spatial bias from aftershock sequences.
+
+Grid sources are modeled as uniformely dsitributed grids of points where pseudo faults are used
+for rupture geometry. Truncated Gutenberg-Richter MFDs are used to model grid source rupture
+magnitudes and rates with logic trees of varying a-value, b-value and maximum magnitude. For grid
+sources the relative rate at each grid node is defined using a spatial PDF (see notes on
+spatial PDFs, [below](#spatial-pdfs)). When realizing each source the spatial PDF value is scaled
+by each regional rate in a rate-tree.
+
+Grid sources are represented in a model using a logic tree with a `rupture-set.json` defining the
+ruptures on each branch. Because gridded seismicity models may be govered by regionally
+varying MFD properties (e.g. `mMax`), rupture sets for grids are defined in a JSON array.
+
+**rupture-set.json**: The `feature` member points to the ID of a geojson feature (in the
+`grid-sources/features` directory) that defines the bounds of the gridded seismicity source.
+
+```json
+[
+  {
+    "name": "Summit Grid Source",
+    "id": 5111,
+    "feature": 5100,
+    "mfd-tree": "summit-deep-r85",
+    "spatial-pdf": "summit-deep-r85-pdf.csv"
+  }
+]
+```
+
+**grid-config.json**: A `grid-depth-map` defines a mapping of magnitude ranges to logic trees of
+depth distributions. The map can use arbitrary names as keys, but the magnitude ranges defined by
+each member must be non-overlapping. The magnitude ranges are interpreted as closed (inclusive) –
+open (exclusive), e.g. [mMin..mMax). `maxDepth` constrains the maximum depth of any pseudo fault
+rupture representations.
+
+```json
+{
+  "grid-spacing": 0.1,
+  "point-source-type": "FINITE",
+  "rupture-scaling": "NSHM_POINT_WC94_LENGTH",
+  "max-depth": 22.0,
+  "focal-mech-tree": [
+    { "id": "STRIKE_SLIP", "weight": 1.0 }
+  ],
+  "grid-depth-map": {
+    "small-magnitude": {
+      "mMin": 4.5,
+      "mMax": 6.5,
+      "depth-tree": [
+        { "id": "5 km", "weight": 1.0, "value": 5.0 }
+      ]
+    },
+    "large-magnitude": {
+      "mMin": 6.5,
+      "mMax": 9.5,
+      "depth-tree": [
+        { "id": "1 km", "weight": 1.0, "value": 1.0 }
+      ]
+    }
+  }
+}
+```
+
+### Spatial PDFs
+
+Grid source spatial PDFs are stored in `grid-sources/grid-data/`. The PDFs are stored in
+comma-delimited files that are usually sorted by increasing longitude then latitude (lower-left
+to upper-right). While most gridded rate files contain columns of longitude, latitude, and pdf,
+some may contain depth values (intraslab sources), maximum magnitude caps, or other values.
+
+## Zone Sources
+
+Zone (or area) sources are similar to [Grid Sources](#grid-sources) except that a single rate
+applies over a polygonal region with rate of individual point sources proportionally scaled to the
+relative area represented by each grid node. Zone sources are represented using GeoJSONs
+directly.
+
+```json
+{
+  "type": "Feature",
+  "id": 720,
+  "geometry": {
+    "type": "Polygon",
+    "coordinates": [[
+      [-86.72464, 39.34245],
+      [-87.87724, 37.67532],
+      [-88.10853, 37.69013],
+      [-88.25009, 37.67544],
+      [-88.42465, 37.70361],
+      [-88.68714, 37.75289],
+      [-87.42964, 39.67601],
+      [-86.72464, 39.34245]
+    ]]
+  },
+  "properties": {
+    "name": "Fault Zone Name",
+    "state": ["IL", "IN"],
+    "rate": "wabash.csv",
+    "strike": 26.639674,
+    "mfd-tree": [
+      { "id": "M1", "weight": 0.05, "value": { "type": "SINGLE", "properties": { "m": 6.75, "rate": 0.001 }}},
+      { "id": "M2", "weight": 0.25, "value": { "type": "SINGLE", "properties": { "m": 7.00, "rate": 0.001 }}},
+      { "id": "M3", "weight": 0.35, "value": { "type": "SINGLE", "properties": { "m": 7.25, "rate": 0.001 }}},
+      { "id": "M4", "weight": 0.35, "value": { "type": "SINGLE", "properties": { "m": 7.50, "rate": 0.001 }}}
+    ]
+  }
+}
+```
+
+**zone-config.json:** Zone source model configuration is identical to a grid source configuration.
+
+```json
+{
+  "grid-spacing": 0.1,
+  "point-source-type": "FIXED_STRIKE",
+  "rupture-scaling": "NSHM_POINT_WC94_LENGTH",
+  "max-depth": 22.0,
+  "focal-mech-tree": [
+    { "id": "STRIKE_SLIP", "weight": 1.0 }
+  ],
+  "grid-depth-map": {
+    "all": {
+      "mMin": 4.5,
+      "mMax": 9.5,
+      "depth-tree": [
+        { "id": "5 km", "weight": 1.0, "value": 5.0 }
+      ]
+    }
+  }
+}
+```
+
+## Fault Sources
+
+Finite fault source representation. The geometry, properties and rupture MFDs of a fault source
+are defined by one or more GeoJSONs and associated configuration. Depending on the complexity of
+the source, it may be represented using a single GeoJSON or result from stitching together
+multiple GeoJSONs (see note on fault section stitching, [below](#fault-section-stitching)). If a
+fault source is represented with a logic treek then `rupture-set.json` defines the ruptures for
+each branch. Depending on the MFDs and scaling relations used to determine a rupture size, some
+ruptures may fill the entire source model while smaller events are modeled as 'floating' ruptures;
+they occur in multiple locations on the fault surface with appropriately scaled rates. MFDs
+associated with finite fault models may be explicitely defined or or derived from slip rates.
+Fault rupture rates may be modeled using explicitely defined MFDs or logic trees of slip rate.
+
+**fault-source.geojson**: Defines the geometry and properties of a single source. In the example
+below the presence of a `rate-map` property indicates MFDs should be constructed from the supplied
+slip rates and using the weights defined in a `rate-tree.json`.
+
+```json
+{
+  "type": "Feature",
+  "id": 2529,
+  "geometry": {
+    "type": "LineString",
+    "coordinates": [
+      [-122.9297, 45.72241],
+      [-122.86196, 45.65791],
+      [-122.77095, 45.58227],
+      [-122.69764, 45.52423],
+      [-122.67841, 45.51561],
+      [-122.62029, 45.43556],
+      [-122.58902, 45.40475],
+      [-122.57195, 45.39478],
+      [-122.56611, 45.38561],
+      [-122.5405, 45.37375]
+    ]
+  },
+  "properties": {
+    "name": "Portland Hills",
+    "state": "OR",
+    "upper-depth": 0.0,
+    "lower-depth": 15.0,
+    "dip": 60.0,
+    "rake": 90.0,
+    "rate-type": "VERTICAL_SLIP",
+    "length": 49.72484,
+    "rate-map": {
+      "BIRD": {
+        "rate": 0.07
+      },
+      "GEO": {
+        "rate": 0.1
+      },
+      "ZENG": {
+        "rate": 0.15
+      }
+    }
+  }
+}
+```
+
+**fault-config.json**: Controls the point spacing on a gridded surface used to realize the fault
+geometry as well as define the models to use for magnitude scaling and rupture floating. Dip
+variations and an associated slip-rate scaling model are also supported for normal faults.
+
+```json
+{
+  "surface-spacing": 1.0,
+  "rupture-scaling": "NSHM_FAULT_WC94_LENGTH",
+  "rupture-floating": "NSHM",
+  "dip-slip-model": "FIXED",
+  "normal-fault-dip-tree": null
+}
+```
+
+### Fault Section Stitching
+
+When multiple sections are defined for a rupture, the ruptures must be defined in an order that
+preserves the U.S. structural geology right-hand-rule. When stitched together, repeated locations
+at the enpoints of adjacent sections, if present, are removed. The properties of the first section
+govern the properties of the stitched fault, however, a rupture-set _may_ include a properties
+member, the contents of which will override the properties of the first stitched section. Although
+it would be better to have geometric properties of stitched sections be calculated dynamically,
+the current approach preserves support for past models. A rupture-set _may_ also include a
+`coordinates` member that can be used to represent a smoothed trace geometry where stitched
+sections do not share common endpoints.
+
+### Fault Cluster Sources
+
+These specialized fault sources are composed of two or more fault sources that rupture
+independently but very closely spaced in time. Ground motions from cluster sources are modeled
+as the joint probability of exceeding ground motions from each independent event. A source in
+a cluster may only have an mfd-tree composed of `Mfd.Type.SINGLE` MFDs and the mfd-trees must
+match across all sources in a cluster (i.e. each mfd-tree has the same IDs and weights).
+
+**cluster-set.json** A specialized type of rupture set, this file defines the array of fault
+rupture sets that make up a 'cluster'.
+
+```json
+{
+  "name": "New Madrid - USGS (center, center-south)",
+  "id": 3025,
+  "rupture-sets": [
+    {
+      "name": "USGS (center, center)",
+      "id": 3021,
+      "mfd-tree": "usgs-hi-mag",
+      "properties": {
+        "width": 15.0
+      }
+    },
+    {
+      "name": "USGS (center, south)",
+      "id": 3022,
+      "mfd-tree": "usgs-hi-mag",
+      "width": 15.0
+    }
+  ]
+}
+```
+
+### Fault System Sources
+
+This specialized fault source type supports inversion based rupture rate estimates, or solutions,
+on a fault network such as that used for UCERF3 in the 2014 and 2018 NSHMs for the conterminous
+U.S. Fault system source sets require three files: `rupture_set.json`, `sections.geojson`, and
+`ruptures.csv` that are placed together within folders defining branches of a fault system
+logic tree. Note that system sources _may_ have complementary gridded seismicity source models
+with matching logic trees.
+
+**rupture_set.json**: Provides identifying information for the ruptures defined in the adjacant
+sections and ruptures files.
+
+**sections.geojson**: defines a feature collection of the fault sections in a fault network.
+Because fault sections are derived by dividing larger faults into subsections, section features
+contain several properties that differ from standalone fault section source models (e.g.
+`dip-direction`).
+
+```json
+{
+  "type": "FeatureCollection",
+  "features": [
+    {
+      "type": "Feature",
+      "id": 310000,
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [-117.74953, 35.74054],
+          [-117.76365, 35.81038]
+        ]
+      },
+      "properties": {
+        "name": "Airport Lake (0)",
+        "state": "CA",
+        "index": 0,
+        "parent-id": 1,
+        "upper-depth": 0.0,
+        "lower-depth": 13.0,
+        "dip": 50.0,
+        "dip-direction": 89.459,
+        "aseismicity": 0.1
+      }
+    },
+    ...
+  ]
+}
+```
+
+**ruptures.csv**: Defines the properties of every rupture. The last column in a rupture file
+defines the ordered array of participating fault section IDs using the shorthand
+`1127:1131-2411:2412`. Colons denote continous ranges of sections and hyphens denote breaks.
+
+## Subduction Interface Sources
+
+Subduction interface sources are currently specified the same way as
+[fault sources](#fault-sources) in crustal tectonic settings. Source model properties are defined
+using an `interface-config.json` file.
+
+## Subduction Intraslab Sources
+
+Subduction intraslab sources are currently specified the same way as
+[grid sources](#grid-sources) in curstal tectonic settings. Source model properties are defined
+using an `slab-config.json` file.
diff --git a/docs/USGS-Models.md b/docs/USGS-Models.md
new file mode 100644
index 0000000000000000000000000000000000000000..7db49c8f70b3e61646fd2a11826107c631594d05
--- /dev/null
+++ b/docs/USGS-Models.md
@@ -0,0 +1,37 @@
+# USGS Models
+
+USGS National Seismic Hazard Models (NSHMs) are updated every so often to incorporate
+best-available science. For the conterminous U.S., updates historically occurred about every six
+years. This window is narrowing, however, and updates are also being undertaken to update the
+models for states and territories outside the conterminous U.S. These pages describe the models
+that are available and some of the history and versions of each. The models are intended for use
+with the  USGS probabilistic earthquake hazard codebase:
+[*nshmp-haz*](https://github.com/usgs/nshmp-haz).
+
+As specified in this documentation, NSHM files are organized by tectonic setting and then further
+by source type. For larger models, such as that of the conterminous U.S., sources are commonly
+grouped in folders by state. Documentation of each model is usually published as one or more
+journal articles or a USGS Open-File report with accompanying data releases of model ingrediants
+and hazard curves and maps. See the
+[USGS Seismic Hazard Maps](https://www.usgs.gov/natural-hazards/earthquake-hazards/seismic-hazard-maps-and-site-specific-data)
+page for links to all published models.
+
+Each model region has a dedicated repository with version tags marking different model editions:
+
+* [Conterminous U.S.](/ghsc/nshmp/nshm-conus)
+* [Hawaii](/ghsc/nshmp/nshm-hawaii)  
+* Alaska - _update not yet published_
+* Guam & Marianas - _update not yet published_  
+* Puerto Rico & U.S. Virgin Islands - _update not yet published_  
+* Samoa & Pacific Islands - _update not yet published_  
+
+## Related Pages
+
+* [Model Editions](model-editions)
+* [Logic Trees & Uncertainty](logic-trees-&-uncertainty)
+
+[**Documentation Index**](readme)
+
+---
+![USGS logo](images/usgs-icon.png) &nbsp;[U.S. Geological Survey](https://www.usgs.gov)
+National Seismic Hazard Mapping Project ([NSHMP](https://earthquake.usgs.gov/hazards/))
diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md
new file mode 100644
index 0000000000000000000000000000000000000000..62cef14112021542232f4fe7ff56344b7d084d4e
--- /dev/null
+++ b/docs/_Sidebar.md
@@ -0,0 +1,20 @@
+# Sidebar
+
+[Home](home)  
+[Building & Running](building-&-running)  
+&nbsp;&nbsp;&nbsp;– [Configuration](calculation-configuration)  
+&nbsp;&nbsp;&nbsp;– [Site Specification](site-specification)  
+[Source Model Files](model-files)  
+&nbsp;&nbsp;&nbsp;– [Source Types](source-types)  
+&nbsp;&nbsp;&nbsp;– [Ground Motion Models](ground-motion-models)  
+&nbsp;&nbsp;&nbsp;– [USGS Models](usgs-models)  
+&nbsp;&nbsp;&nbsp;– [Uncertainties](uncertainties-in-nshms)  
+[Examples](https://github.com/usgs/nshmp-haz/tree/master/etc/examples)  
+[Dependencies](developer-tools) and [Development](developer-basics)  
+[Functional PSHA](functional-psha)  
+[API Docs](http://usgs.github.io/nshmp-haz/javadoc)  
+[License](https://github.com/usgs/nshmp-haz/blob/master/LICENSE.md)
+
+![USGS logo](images/usgs-icon.png) &nbsp;[U.S. Geological Survey](https://www.usgs.gov)
+
+National Seismic Hazard Mapping Project ([NSHMP](https://earthquake.usgs.gov/hazards/))
diff --git a/docs/images/psha-formula.png b/docs/images/psha-formula.png
new file mode 100644
index 0000000000000000000000000000000000000000..7198c0b58ebb4ea311e34dd0de67bf97338d65cc
Binary files /dev/null and b/docs/images/psha-formula.png differ
diff --git a/docs/images/psha-functional.png b/docs/images/psha-functional.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc17e39dd08c830768b271b12dae925d88b7ac81
Binary files /dev/null and b/docs/images/psha-functional.png differ
diff --git a/docs/images/psha-linear.png b/docs/images/psha-linear.png
new file mode 100644
index 0000000000000000000000000000000000000000..121c9b7c6416cd5de38c7e5474115d604fa51f73
Binary files /dev/null and b/docs/images/psha-linear.png differ
diff --git a/docs/images/usgs-icon.png b/docs/images/usgs-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..034fdba1d046f4da94dc04fb034f6f5b55a76c49
Binary files /dev/null and b/docs/images/usgs-icon.png differ
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/services/MaxDirection.java b/src/main/java/gov/usgs/earthquake/nshmp/www/services/MaxDirection.java
index 9f377c661a6e11135d1a7cec63c6be7c805691bd..e35c59355037416482937ce865aeee59400af2cf 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/services/MaxDirection.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/services/MaxDirection.java
@@ -23,41 +23,43 @@ import static gov.usgs.earthquake.nshmp.gmm.Imt.SA4P0;
 import static gov.usgs.earthquake.nshmp.gmm.Imt.SA5P0;
 import static gov.usgs.earthquake.nshmp.gmm.Imt.SA7P5;
 
+import java.util.Collections;
 import java.util.EnumMap;
 import java.util.Map;
 
 import gov.usgs.earthquake.nshmp.gmm.Imt;
 
 /*
- * Max direction factors derived from Shahi and Baker (2012) and used in the
- * BSSC.
+ * Max direction map derived from Shahi and Baker (2012) and used in the BSSC.
  */
 class MaxDirection {
 
-  static final Map<Imt, Double> FACTORS = new EnumMap<>(Imt.class);
+  static final Map<Imt, Double> FACTORS;
 
   static {
-    FACTORS.put(PGA, 1.0);
-    FACTORS.put(SA0P01, 1.200);
-    FACTORS.put(SA0P02, 1.200);
-    FACTORS.put(SA0P03, 1.200);
-    FACTORS.put(SA0P05, 1.200);
-    FACTORS.put(SA0P075, 1.200);
-    FACTORS.put(SA0P1, 1.200);
-    FACTORS.put(SA0P15, 1.200);
-    FACTORS.put(SA0P2, 1.200);
-    FACTORS.put(SA0P25, 1.203);
-    FACTORS.put(SA0P3, 1.206);
-    FACTORS.put(SA0P4, 1.213);
-    FACTORS.put(SA0P5, 1.219);
-    FACTORS.put(SA0P75, 1.234);
-    FACTORS.put(SA1P0, 1.250);
-    FACTORS.put(SA1P5, 1.253);
-    FACTORS.put(SA2P0, 1.256);
-    FACTORS.put(SA3P0, 1.261);
-    FACTORS.put(SA4P0, 1.267);
-    FACTORS.put(SA5P0, 1.272);
-    FACTORS.put(SA7P5, 1.286);
-    FACTORS.put(SA10P0, 1.300);
+    Map<Imt, Double> map = new EnumMap<>(Imt.class);
+    map.put(PGA, 1.0);
+    map.put(SA0P01, 1.200);
+    map.put(SA0P02, 1.200);
+    map.put(SA0P03, 1.200);
+    map.put(SA0P05, 1.200);
+    map.put(SA0P075, 1.200);
+    map.put(SA0P1, 1.200);
+    map.put(SA0P15, 1.200);
+    map.put(SA0P2, 1.200);
+    map.put(SA0P25, 1.203);
+    map.put(SA0P3, 1.206);
+    map.put(SA0P4, 1.213);
+    map.put(SA0P5, 1.219);
+    map.put(SA0P75, 1.234);
+    map.put(SA1P0, 1.250);
+    map.put(SA1P5, 1.253);
+    map.put(SA2P0, 1.256);
+    map.put(SA3P0, 1.261);
+    map.put(SA4P0, 1.267);
+    map.put(SA5P0, 1.272);
+    map.put(SA7P5, 1.286);
+    map.put(SA10P0, 1.300);
+    FACTORS = Collections.unmodifiableMap(map);
   }
 }