diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+0.0.0.0
+=======
+
+Initial release.
+* Tested with GHC 9.4.8 - 9.12.4.
+
+_Andreas Abel, 2026-04-08_
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+BSD 3-Clause License
+
+Copyright (c) 2025, Andreas Abel
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,264 @@
+# stacker
+
+Bump snapshots (aka resolvers) in `stack*.yaml` files.
+
+The `stacker` tools goes through the given files (or all `stack*.yaml` files in the current directory),
+inspects the value of the `snapshot:` (or `resolver:`) field and upgrades it in the following way:
+
+1. If the value is pointing to a LTS snapshot, e.g., `lts-24.10`,
+   it will bump it to the latest version of this LTS
+   (at the time of writing this is `lts-24.36`).
+
+2. If the value is pointing to a nightly release and this nightly
+   belongs to a GHC major version for which an LTS exists,
+   it will bump it to the latest LTS for this GHC version.
+   For instance, `nightly-2024-12-15` is for GHC 9.10.1,
+   but there is LTS series 24 for GHC 9.10,
+   so the snapshot will be bumped to `lts-24.36`,
+   the latest of the LTS series 24.
+
+3. If the value is pointing to a nightly release for a GHC major version
+   that has no LTS yet, it will be bumped to the latest nightly snapshot
+   for this GHC major version.
+   For instance, snapshot `nightly-2025-10-10` is for GHC 9.12.2,
+   and there is no LTS series for GHC 9.12 yet (at the time of writing),
+   so the snapshot value will be bumped to `nightly-2026-04-01`,
+   the latest nightly (at the time of writing this).
+
+## Example
+
+```
+$ stacker
+
+stack-8.10.yaml     lts-18.28                ✓ up to date
+stack-8.2.yaml      lts-11.22                ✓ up to date
+stack-8.4.yaml      lts-12.26                ✓ up to date
+stack-8.6.yaml      lts-14.27                ✓ up to date
+stack-8.8.yaml      lts-16.31                ✓ up to date
+stack-9.0.yaml      lts-19.33                ✓ up to date
+stack-9.10.yaml     lts-24.28                → bump to lts-24.36
+stack-9.12.yaml     nightly-2025-10-14       → bump to nightly-2026-04-01
+stack-9.2.yaml      lts-20.26                ✓ up to date
+stack-9.4.yaml      lts-21.25                ✓ up to date
+stack-9.6.yaml      lts-22.44                ✓ up to date
+stack-9.8.yaml      lts-23.28                ✓ up to date
+stack.yaml          nightly-2025-10-14       = symlink to stack-9.12.yaml
+```
+```
+$ stacker bump
+
+Updating stack-9.10.yaml
+Updating stack-9.12.yaml
+```
+
+## Synopsis
+
+`stacker` understands the following essential commands:
+
+| Command              | Description                                                                      |
+|----------------------|----------------------------------------------------------------------------------|
+| `bump [FILES...]`    | Updates FILES (all `stack*.yaml` files if none specified)                        |
+| `dry-run [FILES...]` | Shows what updates would be performed by the respective `bump` (default command) |
+| `config`             | Configures `stacker`                                                             |
+| `update`             | Updates its database of Stackage snapshots                                       |
+| `info`               | Prints table mapping GHC major versions to their latest snapshots                |
+
+These can be modified with the following option(s):
+
+| Option        | Values                  | Description                                                        |
+|---------------|-------------------------|--------------------------------------------------------------------|
+| `--color`     | `always`,`never`,`auto` | Colored output? (Default: `auto`)                                  |
+| `--recursive` | (flag)                  | Search for `stack*.yaml` files in all subdirectories (short: `-r`) |
+
+When `--color=auto` is used (the default), colors are disabled
+if the `NO_COLOR` environment variable is set to any value,
+following the standard described at https://no-color.org.
+Colors can still be forced on with `--color=always` even when `NO_COLOR` is set.
+
+**Note:** The `--recursive` flag can only be used with `bump` and `dry-run` commands
+when no explicit FILES are specified. If you provide explicit file arguments,
+you cannot use the `--recursive` flag.
+
+It also has the following inessential commands (standard options) that just give information about itself:
+
+| Command           | Alternatives        | Description                                                                         |
+|-------------------|---------------------|-------------------------------------------------------------------------------------|
+| `version`         | `--version`, `-V`   | Prints version and copyright info                                                   |
+| `numeric-version` | `--numeric-version` | Prints just the version number                                                      |
+| `license`         | `--license`         | Prints the license text (BSD 3-clause)                                              |
+| `help`            | `--help`, `-h`      | Prints `--version`, one paragraph description of functionality, and list of options |
+
+`stacker` runs on the 3 major platforms Linux, macOS, and Windows.
+
+## Data files
+
+`stacker` comes with 3 data files that are copied into its
+XDG-conform application directory (`$XDG_STATE_HOME/stacker`)
+whenever the program is invoked and they do not exist there yet.
+
+1. `lts.csv` containing a map from LTS version to GHC version, e.g.
+   ```
+   ...
+   22.42,9.6.6
+   22.43,9.6.6
+   22.44,9.6.7
+   23.1,9,8.4
+   23.2,9.8.4
+   ...
+   23.28,9.8.4
+   24.1,9.10.1
+   ...
+   ```
+
+2. `nightly.csv` containing a map from nightly version to GHC version, e.g.
+   ```
+   ...
+   2024-01-01,9.8.1
+   ...
+   2025-07-07,9.10.2
+   ...
+   2025-12-08,9.12.2
+   2025-12-09,9.12.2
+   ```
+
+3. `ghc.csv` containing a map from GHC version to its latest LTS or nightly snapshot, e.g.
+   ```
+   ...
+   9.2.8,lts-20.26
+   9.4.5,lts-21.7
+   ...
+   9.4.8,lts-21.25
+   9.6.3,lts-22.6
+   ...
+   9.6.6,lts-22.43
+   9.6.7,lts-22.44
+   ...
+   9.10.3,lts-24.36
+   9.12.4,nightly-2026-04-01
+   ```
+
+These data files determine the results of `bump` (and its preview by `dry-run`).
+
+## `bump` command
+
+`stacker bump` looks for all `stack*.yaml` files in the current directory and updates them as described above.
+
+Alternatively, you can specify specific files to bump:
+```
+stacker bump stack-9.6.yaml stack-9.8.yaml
+```
+
+To search for `stack*.yaml` files recursively in all subdirectories:
+```
+stacker bump --recursive
+```
+or
+```
+stacker bump -r
+```
+
+Only the content of the `snapshot:` and `resolver:` fields will be updated,
+everything else will remain literally the same, including comments and whitespace.
+
+## `dry-run` command
+
+This command is also run if no command is given to `stacker`.
+It prints a table with all `stack*.yaml` files in the current directory,
+their `snapshot` (which can also be given in the `resolver` field), and what action to take (if any).
+
+Alternatively, you can specify specific files to check:
+```
+stacker dry-run stack-9.6.yaml stack-9.8.yaml
+```
+
+To search for `stack*.yaml` files recursively in all subdirectories:
+```
+stacker dry-run --recursive
+```
+or
+```
+stacker dry-run -r
+```
+
+Example output:
+```
+stack-9.2.yaml    lts-20.26            ✓ up to date
+stack-9.4.yaml    lts-21.25            ✓ up to date
+stack-9.6.yaml    lts-22.43            → bump to lts-22.44
+stack-9.8.yaml    lts-23.1             → bump to lts-23.28
+stack-9.10.yaml   nightly-2024-07-07   → bump to lts-24.36
+stack-9.12.yaml   nightly-2025-10-03   → bump to nightly-2026-04-01
+```
+When coloring is on, the `stack*.yml` column is printed in bold, `✓ up to date` in green and any bump action in bright yellow.
+
+Internally, `bump` and `dry-run` share the analysis phase that reads the `stack*.yaml` and creates for each an action plan,
+yet `dry-run` just pretty-prints this plan as detailed above whereas `bump` executes it.
+
+## Configuration (optional)
+
+`stacker update` regenerates its information about GHC versions and Stackage snapshots from the repository
+https://github.com/commercialhaskell/stackage-snapshots .
+
+If you have a clone of this repository already, you might want to configure `stacker` to use it
+so it does not make its own clone (which takes ~2GB of disk space).
+
+By default, `stacker` stores information about the Stackage snapshots
+in its XDG-conform application directory (`$XDG_STATE_HOME/stacker`),
+by creating a shallow git clone of said repository there
+(typically `$XDG_STATE_HOME/stacker/stackage-snapshots`).
+
+With the command
+```
+   stacker config repo path/to/dir
+```
+the stackage-snapshots repository will be instead searched for in `path/to/dir`.
+The effect of the `config` command is to write file `config.yaml`
+in the XDG-conform configuration directory (`$XDG_CONFIG_HOME/stacker`)
+with the following content:
+```yaml
+# stacker configuration
+
+repo: /absolute/path/to/dir
+```
+where `/absolute/path/to/dir` is the `path/to/dir` turned into an absolute path.
+
+Whenever `stacker` is started with an essential command,
+it will attempt to read this configuration file and extract the value of `repo`, if it is given.
+We shall refer to this value as `$REPO`.
+It defaults to `$XDG_STATE_HOME/stacker/stackage-snapshots` if not configured.
+
+## `update` command
+
+`stacker update` first prints the path to the repo (value of `$REPO`).
+If the repo does not exist,
+it will be created as a shallow git clone of https://github.com/commercialhaskell/stackage-snapshots .
+
+Once created, it will only be updated by `stacker update`, and then only if its `master` branch is checked out.
+If another branch is checked out, the `update` command exits with an error.
+
+The `update` command then regenerates then three files `lts.csv`, `nightly.csv` and `ghc.csv` in `$XDG_STATE_HOME/stacker/`.
+
+## `info` command
+
+`stacker info` prints the following things in YAML format:
+1. `repo: $REPO`
+2. A map between each latest major GHC version and its corresponding latest LTS or nightly snapshot,
+   as read from `ghc.csv`.  Example:
+   ```yaml
+   snapshots:
+     ...
+     9.2.8: lts-20.26
+     9.4.8: lts-21.25
+     9.6.7: lts-22.44
+     9.8.4: lts-23.28
+     9.10.3: lts-24.36
+     9.12.4: nightly-2026-04-01
+   ```
+
+## Testing
+
+This project is accompanied by a golden value testsuite (framework `tasty-golden`) that tests the `dry-run` and `bump` commands.
+
+## License
+
+BSD 3-clause.
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,9 @@
+module Main where
+
+import Options (parseOptions)
+import Commands (runCommand)
+
+main :: IO ()
+main = do
+  opts <- parseOptions
+  runCommand opts
diff --git a/data/ghc.csv b/data/ghc.csv
new file mode 100644
--- /dev/null
+++ b/data/ghc.csv
@@ -0,0 +1,59 @@
+7.8.3,lts-0.7
+7.8.4,lts-2.22
+7.10.1,nightly-2015-08-04
+7.10.2,lts-3.22
+7.10.3,lts-6.35
+8.0.1,lts-7.24
+8.0.2,lts-9.21
+8.2.1,nightly-2017-11-24
+8.2.2,lts-11.22
+8.4.1,nightly-2018-04-21
+8.4.2,nightly-2018-05-30
+8.4.3,lts-12.14
+8.4.4,lts-12.26
+8.6.1,nightly-2018-11-11
+8.6.2,nightly-2018-12-17
+8.6.3,lts-13.11
+8.6.4,lts-13.19
+8.6.5,lts-14.27
+8.8.1,nightly-2020-01-21
+8.8.2,lts-15.3
+8.8.3,lts-16.11
+8.8.4,lts-16.31
+8.10.1,nightly-2020-08-16
+8.10.2,nightly-2020-12-14
+8.10.3,lts-17.2
+8.10.4,lts-18.6
+8.10.6,lts-18.8
+8.10.7,lts-18.28
+9.0.1,nightly-2022-01-06
+9.0.2,lts-19.33
+9.2.2,nightly-2022-06-06
+9.2.3,nightly-2022-07-31
+9.2.4,nightly-2022-11-12
+9.2.5,lts-20.11
+9.2.6,lts-20.12
+9.2.7,lts-20.24
+9.2.8,lts-20.26
+9.4.3,nightly-2022-12-26
+9.4.4,nightly-2023-04-24
+9.4.5,lts-21.7
+9.4.6,lts-21.11
+9.4.7,lts-21.21
+9.4.8,lts-21.25
+9.6.2,nightly-2023-09-30
+9.6.3,lts-22.6
+9.6.4,lts-22.20
+9.6.5,lts-22.27
+9.6.6,lts-22.43
+9.6.7,lts-22.44
+9.8.1,nightly-2024-03-07
+9.8.2,nightly-2024-10-21
+9.8.3,nightly-2024-12-04
+9.8.4,lts-23.28
+9.10.1,nightly-2025-05-05
+9.10.2,lts-24.11
+9.10.3,lts-24.36
+9.12.2,nightly-2025-12-30
+9.12.3,nightly-2026-03-28
+9.12.4,nightly-2026-04-07
diff --git a/data/lts.csv b/data/lts.csv
new file mode 100644
--- /dev/null
+++ b/data/lts.csv
@@ -0,0 +1,610 @@
+0.0,7.8.3
+0.1,7.8.3
+0.2,7.8.3
+0.3,7.8.3
+0.4,7.8.3
+0.5,7.8.3
+0.6,7.8.3
+0.7,7.8.3
+1.0,7.8.4
+1.1,7.8.4
+1.2,7.8.4
+1.4,7.8.4
+1.5,7.8.4
+1.7,7.8.4
+1.8,7.8.4
+1.9,7.8.4
+1.10,7.8.4
+1.11,7.8.4
+1.12,7.8.4
+1.13,7.8.4
+1.14,7.8.4
+1.15,7.8.4
+2.0,7.8.4
+2.1,7.8.4
+2.2,7.8.4
+2.3,7.8.4
+2.4,7.8.4
+2.5,7.8.4
+2.6,7.8.4
+2.7,7.8.4
+2.8,7.8.4
+2.9,7.8.4
+2.10,7.8.4
+2.11,7.8.4
+2.12,7.8.4
+2.13,7.8.4
+2.14,7.8.4
+2.15,7.8.4
+2.16,7.8.4
+2.17,7.8.4
+2.18,7.8.4
+2.19,7.8.4
+2.20,7.8.4
+2.21,7.8.4
+2.22,7.8.4
+3.0,7.10.2
+3.1,7.10.2
+3.2,7.10.2
+3.3,7.10.2
+3.4,7.10.2
+3.5,7.10.2
+3.6,7.10.2
+3.7,7.10.2
+3.8,7.10.2
+3.9,7.10.2
+3.10,7.10.2
+3.11,7.10.2
+3.12,7.10.2
+3.13,7.10.2
+3.14,7.10.2
+3.15,7.10.2
+3.16,7.10.2
+3.17,7.10.2
+3.18,7.10.2
+3.19,7.10.2
+3.20,7.10.2
+3.21,7.10.2
+3.22,7.10.2
+4.0,7.10.3
+4.1,7.10.3
+4.2,7.10.3
+5.0,7.10.3
+5.1,7.10.3
+5.2,7.10.3
+5.3,7.10.3
+5.4,7.10.3
+5.5,7.10.3
+5.6,7.10.3
+5.7,7.10.3
+5.8,7.10.3
+5.9,7.10.3
+5.10,7.10.3
+5.11,7.10.3
+5.12,7.10.3
+5.13,7.10.3
+5.14,7.10.3
+5.15,7.10.3
+5.16,7.10.3
+5.17,7.10.3
+5.18,7.10.3
+6.0,7.10.3
+6.1,7.10.3
+6.2,7.10.3
+6.3,7.10.3
+6.4,7.10.3
+6.5,7.10.3
+6.6,7.10.3
+6.7,7.10.3
+6.8,7.10.3
+6.9,7.10.3
+6.10,7.10.3
+6.11,7.10.3
+6.12,7.10.3
+6.13,7.10.3
+6.14,7.10.3
+6.15,7.10.3
+6.16,7.10.3
+6.17,7.10.3
+6.18,7.10.3
+6.19,7.10.3
+6.20,7.10.3
+6.21,7.10.3
+6.22,7.10.3
+6.23,7.10.3
+6.24,7.10.3
+6.25,7.10.3
+6.26,7.10.3
+6.27,7.10.3
+6.28,7.10.3
+6.29,7.10.3
+6.30,7.10.3
+6.31,7.10.3
+6.32,7.10.3
+6.33,7.10.3
+6.34,7.10.3
+6.35,7.10.3
+7.0,8.0.1
+7.1,8.0.1
+7.2,8.0.1
+7.3,8.0.1
+7.4,8.0.1
+7.5,8.0.1
+7.6,8.0.1
+7.7,8.0.1
+7.8,8.0.1
+7.9,8.0.1
+7.10,8.0.1
+7.11,8.0.1
+7.12,8.0.1
+7.13,8.0.1
+7.14,8.0.1
+7.15,8.0.1
+7.16,8.0.1
+7.17,8.0.1
+7.18,8.0.1
+7.19,8.0.1
+7.20,8.0.1
+7.21,8.0.1
+7.22,8.0.1
+7.23,8.0.1
+7.24,8.0.1
+8.0,8.0.2
+8.1,8.0.2
+8.2,8.0.2
+8.3,8.0.2
+8.4,8.0.2
+8.5,8.0.2
+8.6,8.0.2
+8.7,8.0.2
+8.8,8.0.2
+8.9,8.0.2
+8.10,8.0.2
+8.11,8.0.2
+8.12,8.0.2
+8.13,8.0.2
+8.14,8.0.2
+8.15,8.0.2
+8.16,8.0.2
+8.17,8.0.2
+8.18,8.0.2
+8.19,8.0.2
+8.20,8.0.2
+8.21,8.0.2
+8.22,8.0.2
+8.23,8.0.2
+8.24,8.0.2
+9.0,8.0.2
+9.1,8.0.2
+9.2,8.0.2
+9.3,8.0.2
+9.4,8.0.2
+9.5,8.0.2
+9.6,8.0.2
+9.7,8.0.2
+9.8,8.0.2
+9.9,8.0.2
+9.10,8.0.2
+9.11,8.0.2
+9.12,8.0.2
+9.13,8.0.2
+9.14,8.0.2
+9.15,8.0.2
+9.16,8.0.2
+9.17,8.0.2
+9.18,8.0.2
+9.19,8.0.2
+9.20,8.0.2
+9.21,8.0.2
+10.0,8.2.2
+10.1,8.2.2
+10.2,8.2.2
+10.3,8.2.2
+10.4,8.2.2
+10.5,8.2.2
+10.6,8.2.2
+10.7,8.2.2
+10.8,8.2.2
+10.9,8.2.2
+10.10,8.2.2
+11.0,8.2.2
+11.1,8.2.2
+11.2,8.2.2
+11.3,8.2.2
+11.4,8.2.2
+11.5,8.2.2
+11.6,8.2.2
+11.7,8.2.2
+11.8,8.2.2
+11.9,8.2.2
+11.10,8.2.2
+11.11,8.2.2
+11.12,8.2.2
+11.13,8.2.2
+11.14,8.2.2
+11.15,8.2.2
+11.16,8.2.2
+11.17,8.2.2
+11.18,8.2.2
+11.19,8.2.2
+11.20,8.2.2
+11.21,8.2.2
+11.22,8.2.2
+12.0,8.4.3
+12.1,8.4.3
+12.2,8.4.3
+12.3,8.4.3
+12.4,8.4.3
+12.5,8.4.3
+12.6,8.4.3
+12.7,8.4.3
+12.8,8.4.3
+12.9,8.4.3
+12.10,8.4.3
+12.11,8.4.3
+12.12,8.4.3
+12.13,8.4.3
+12.14,8.4.3
+12.15,8.4.4
+12.16,8.4.4
+12.17,8.4.4
+12.18,8.4.4
+12.19,8.4.4
+12.20,8.4.4
+12.21,8.4.4
+12.22,8.4.4
+12.23,8.4.4
+12.24,8.4.4
+12.25,8.4.4
+12.26,8.4.4
+13.0,8.6.3
+13.1,8.6.3
+13.2,8.6.3
+13.3,8.6.3
+13.4,8.6.3
+13.5,8.6.3
+13.6,8.6.3
+13.7,8.6.3
+13.8,8.6.3
+13.9,8.6.3
+13.10,8.6.3
+13.11,8.6.3
+13.12,8.6.4
+13.13,8.6.4
+13.14,8.6.4
+13.15,8.6.4
+13.16,8.6.4
+13.17,8.6.4
+13.18,8.6.4
+13.19,8.6.4
+13.20,8.6.5
+13.21,8.6.5
+13.22,8.6.5
+13.23,8.6.5
+13.24,8.6.5
+13.25,8.6.5
+13.26,8.6.5
+13.27,8.6.5
+13.28,8.6.5
+13.29,8.6.5
+13.30,8.6.5
+14.0,8.6.5
+14.1,8.6.5
+14.2,8.6.5
+14.3,8.6.5
+14.4,8.6.5
+14.5,8.6.5
+14.6,8.6.5
+14.7,8.6.5
+14.8,8.6.5
+14.9,8.6.5
+14.10,8.6.5
+14.11,8.6.5
+14.12,8.6.5
+14.13,8.6.5
+14.14,8.6.5
+14.15,8.6.5
+14.16,8.6.5
+14.17,8.6.5
+14.18,8.6.5
+14.19,8.6.5
+14.20,8.6.5
+14.21,8.6.5
+14.22,8.6.5
+14.23,8.6.5
+14.24,8.6.5
+14.25,8.6.5
+14.26,8.6.5
+14.27,8.6.5
+15.0,8.8.2
+15.1,8.8.2
+15.2,8.8.2
+15.3,8.8.2
+15.4,8.8.3
+15.5,8.8.3
+15.6,8.8.3
+15.7,8.8.3
+15.8,8.8.3
+15.9,8.8.3
+15.10,8.8.3
+15.11,8.8.3
+15.12,8.8.3
+15.13,8.8.3
+15.14,8.8.3
+15.15,8.8.3
+15.16,8.8.3
+16.0,8.8.3
+16.1,8.8.3
+16.2,8.8.3
+16.3,8.8.3
+16.4,8.8.3
+16.5,8.8.3
+16.6,8.8.3
+16.7,8.8.3
+16.8,8.8.3
+16.9,8.8.3
+16.10,8.8.3
+16.11,8.8.3
+16.12,8.8.4
+16.13,8.8.4
+16.14,8.8.4
+16.15,8.8.4
+16.16,8.8.4
+16.17,8.8.4
+16.18,8.8.4
+16.19,8.8.4
+16.20,8.8.4
+16.21,8.8.4
+16.22,8.8.4
+16.23,8.8.4
+16.24,8.8.4
+16.25,8.8.4
+16.26,8.8.4
+16.27,8.8.4
+16.28,8.8.4
+16.29,8.8.4
+16.30,8.8.4
+16.31,8.8.4
+17.0,8.10.3
+17.1,8.10.3
+17.2,8.10.3
+17.3,8.10.4
+17.4,8.10.4
+17.5,8.10.4
+17.6,8.10.4
+17.7,8.10.4
+17.8,8.10.4
+17.9,8.10.4
+17.10,8.10.4
+17.11,8.10.4
+17.12,8.10.4
+17.13,8.10.4
+17.14,8.10.4
+17.15,8.10.4
+18.0,8.10.4
+18.1,8.10.4
+18.2,8.10.4
+18.3,8.10.4
+18.4,8.10.4
+18.5,8.10.4
+18.6,8.10.4
+18.7,8.10.6
+18.8,8.10.6
+18.9,8.10.7
+18.10,8.10.7
+18.11,8.10.7
+18.12,8.10.7
+18.13,8.10.7
+18.14,8.10.7
+18.15,8.10.7
+18.16,8.10.7
+18.17,8.10.7
+18.18,8.10.7
+18.19,8.10.7
+18.20,8.10.7
+18.21,8.10.7
+18.22,8.10.7
+18.23,8.10.7
+18.24,8.10.7
+18.25,8.10.7
+18.26,8.10.7
+18.27,8.10.7
+18.28,8.10.7
+19.0,9.0.2
+19.1,9.0.2
+19.2,9.0.2
+19.3,9.0.2
+19.4,9.0.2
+19.5,9.0.2
+19.6,9.0.2
+19.7,9.0.2
+19.8,9.0.2
+19.9,9.0.2
+19.10,9.0.2
+19.11,9.0.2
+19.12,9.0.2
+19.13,9.0.2
+19.14,9.0.2
+19.15,9.0.2
+19.16,9.0.2
+19.17,9.0.2
+19.18,9.0.2
+19.19,9.0.2
+19.20,9.0.2
+19.21,9.0.2
+19.22,9.0.2
+19.23,9.0.2
+19.24,9.0.2
+19.25,9.0.2
+19.26,9.0.2
+19.27,9.0.2
+19.28,9.0.2
+19.29,9.0.2
+19.30,9.0.2
+19.31,9.0.2
+19.32,9.0.2
+19.33,9.0.2
+20.0,9.2.5
+20.1,9.2.5
+20.2,9.2.5
+20.3,9.2.5
+20.4,9.2.5
+20.5,9.2.5
+20.6,9.2.5
+20.7,9.2.5
+20.8,9.2.5
+20.9,9.2.5
+20.10,9.2.5
+20.11,9.2.5
+20.12,9.2.6
+20.13,9.2.7
+20.14,9.2.7
+20.15,9.2.7
+20.16,9.2.7
+20.17,9.2.7
+20.18,9.2.7
+20.19,9.2.7
+20.20,9.2.7
+20.21,9.2.7
+20.22,9.2.7
+20.23,9.2.7
+20.24,9.2.7
+20.25,9.2.8
+20.26,9.2.8
+21.0,9.4.5
+21.1,9.4.5
+21.2,9.4.5
+21.3,9.4.5
+21.4,9.4.5
+21.5,9.4.5
+21.6,9.4.5
+21.7,9.4.5
+21.8,9.4.6
+21.9,9.4.6
+21.10,9.4.6
+21.11,9.4.6
+21.12,9.4.7
+21.13,9.4.7
+21.14,9.4.7
+21.15,9.4.7
+21.16,9.4.7
+21.17,9.4.7
+21.18,9.4.7
+21.19,9.4.7
+21.20,9.4.7
+21.21,9.4.7
+21.22,9.4.8
+21.23,9.4.8
+21.24,9.4.8
+21.25,9.4.8
+22.0,9.6.3
+22.1,9.6.3
+22.2,9.6.3
+22.3,9.6.3
+22.4,9.6.3
+22.5,9.6.3
+22.6,9.6.3
+22.7,9.6.4
+22.8,9.6.4
+22.9,9.6.4
+22.10,9.6.4
+22.11,9.6.4
+22.12,9.6.4
+22.13,9.6.4
+22.14,9.6.4
+22.15,9.6.4
+22.16,9.6.4
+22.17,9.6.4
+22.18,9.6.4
+22.19,9.6.4
+22.20,9.6.4
+22.21,9.6.5
+22.22,9.6.5
+22.23,9.6.5
+22.24,9.6.5
+22.25,9.6.5
+22.26,9.6.5
+22.27,9.6.5
+22.28,9.6.6
+22.29,9.6.6
+22.30,9.6.6
+22.31,9.6.6
+22.32,9.6.6
+22.33,9.6.6
+22.34,9.6.6
+22.35,9.6.6
+22.36,9.6.6
+22.37,9.6.6
+22.38,9.6.6
+22.39,9.6.6
+22.40,9.6.6
+22.41,9.6.6
+22.42,9.6.6
+22.43,9.6.6
+22.44,9.6.7
+23.0,9.8.4
+23.1,9.8.4
+23.2,9.8.4
+23.3,9.8.4
+23.4,9.8.4
+23.5,9.8.4
+23.6,9.8.4
+23.7,9.8.4
+23.8,9.8.4
+23.9,9.8.4
+23.10,9.8.4
+23.11,9.8.4
+23.12,9.8.4
+23.13,9.8.4
+23.14,9.8.4
+23.15,9.8.4
+23.16,9.8.4
+23.17,9.8.4
+23.18,9.8.4
+23.19,9.8.4
+23.20,9.8.4
+23.21,9.8.4
+23.22,9.8.4
+23.23,9.8.4
+23.24,9.8.4
+23.25,9.8.4
+23.26,9.8.4
+23.27,9.8.4
+23.28,9.8.4
+24.0,9.10.2
+24.1,9.10.2
+24.2,9.10.2
+24.3,9.10.2
+24.4,9.10.2
+24.5,9.10.2
+24.6,9.10.2
+24.7,9.10.2
+24.8,9.10.2
+24.9,9.10.2
+24.10,9.10.2
+24.11,9.10.2
+24.12,9.10.3
+24.13,9.10.3
+24.14,9.10.3
+24.15,9.10.3
+24.16,9.10.3
+24.17,9.10.3
+24.18,9.10.3
+24.19,9.10.3
+24.20,9.10.3
+24.21,9.10.3
+24.22,9.10.3
+24.23,9.10.3
+24.24,9.10.3
+24.25,9.10.3
+24.26,9.10.3
+24.27,9.10.3
+24.28,9.10.3
+24.29,9.10.3
+24.30,9.10.3
+24.31,9.10.3
+24.32,9.10.3
+24.33,9.10.3
+24.34,9.10.3
+24.35,9.10.3
+24.36,9.10.3
diff --git a/data/nightly.csv b/data/nightly.csv
new file mode 100644
--- /dev/null
+++ b/data/nightly.csv
@@ -0,0 +1,3096 @@
+2014-12-14,7.8.3
+2014-12-16,7.8.3
+2014-12-20,7.8.3
+2014-12-24,7.8.4
+2015-01-01,7.8.4
+2015-01-03,7.8.4
+2015-01-12,7.8.4
+2015-01-17,7.8.4
+2015-01-20,7.8.4
+2015-01-22,7.8.4
+2015-02-02,7.8.4
+2015-02-05,7.8.4
+2015-02-10,7.8.4
+2015-02-12,7.8.4
+2015-02-18,7.8.4
+2015-02-27,7.8.4
+2015-03-05,7.8.4
+2015-03-11,7.8.4
+2015-03-13,7.8.4
+2015-03-16,7.8.4
+2015-03-17,7.8.4
+2015-03-19,7.8.4
+2015-03-24,7.8.4
+2015-03-25,7.8.4
+2015-03-29,7.8.4
+2015-03-30,7.8.4
+2015-04-01,7.8.4
+2015-04-02,7.8.4
+2015-04-17,7.8.4
+2015-04-18,7.8.4
+2015-04-19,7.8.4
+2015-04-22,7.8.4
+2015-04-23,7.8.4
+2015-04-24,7.8.4
+2015-04-25,7.8.4
+2015-04-27,7.8.4
+2015-04-28,7.8.4
+2015-04-29,7.8.4
+2015-04-30,7.8.4
+2015-05-01,7.8.4
+2015-05-02,7.8.4
+2015-05-03,7.8.4
+2015-05-04,7.8.4
+2015-05-05,7.10.1
+2015-05-06,7.10.1
+2015-05-07,7.10.1
+2015-05-08,7.10.1
+2015-05-09,7.10.1
+2015-05-11,7.10.1
+2015-05-13,7.10.1
+2015-05-14,7.10.1
+2015-05-15,7.10.1
+2015-05-16,7.10.1
+2015-05-17,7.10.1
+2015-05-18,7.10.1
+2015-05-19,7.10.1
+2015-05-21,7.10.1
+2015-05-22,7.10.1
+2015-05-25,7.10.1
+2015-05-26,7.10.1
+2015-05-27,7.10.1
+2015-05-28,7.10.1
+2015-05-29,7.10.1
+2015-05-31,7.10.1
+2015-06-01,7.10.1
+2015-06-02,7.10.1
+2015-06-03,7.10.1
+2015-06-04,7.10.1
+2015-06-05,7.10.1
+2015-06-07,7.10.1
+2015-06-08,7.10.1
+2015-06-09,7.10.1
+2015-06-10,7.10.1
+2015-06-11,7.10.1
+2015-06-12,7.10.1
+2015-06-13,7.10.1
+2015-06-14,7.10.1
+2015-06-15,7.10.1
+2015-06-16,7.10.1
+2015-06-17,7.10.1
+2015-06-18,7.10.1
+2015-06-19,7.10.1
+2015-06-21,7.10.1
+2015-06-22,7.10.1
+2015-06-23,7.10.1
+2015-06-24,7.10.1
+2015-06-25,7.10.1
+2015-06-26,7.10.1
+2015-06-28,7.10.1
+2015-06-29,7.10.1
+2015-06-30,7.10.1
+2015-07-01,7.10.1
+2015-07-02,7.10.1
+2015-07-03,7.10.1
+2015-07-05,7.10.1
+2015-07-06,7.10.1
+2015-07-07,7.10.1
+2015-07-08,7.10.1
+2015-07-09,7.10.1
+2015-07-10,7.10.1
+2015-07-11,7.10.1
+2015-07-12,7.10.1
+2015-07-13,7.10.1
+2015-07-14,7.10.1
+2015-07-15,7.10.1
+2015-07-17,7.10.1
+2015-07-18,7.10.1
+2015-07-19,7.10.1
+2015-07-21,7.10.1
+2015-07-22,7.10.1
+2015-07-23,7.10.1
+2015-07-24,7.10.1
+2015-07-25,7.10.1
+2015-07-26,7.10.1
+2015-07-27,7.10.1
+2015-07-28,7.10.1
+2015-07-29,7.10.1
+2015-07-30,7.10.1
+2015-08-03,7.10.1
+2015-08-04,7.10.1
+2015-08-06,7.10.2
+2015-08-07,7.10.2
+2015-08-08,7.10.2
+2015-08-09,7.10.2
+2015-08-10,7.10.2
+2015-08-11,7.10.2
+2015-08-12,7.10.2
+2015-08-13,7.10.2
+2015-08-14,7.10.2
+2015-08-15,7.10.2
+2015-08-16,7.10.2
+2015-08-17,7.10.2
+2015-08-18,7.10.2
+2015-08-19,7.10.2
+2015-08-20,7.10.2
+2015-08-21,7.10.2
+2015-08-24,7.10.2
+2015-08-25,7.10.2
+2015-08-26,7.10.2
+2015-08-27,7.10.2
+2015-08-30,7.10.2
+2015-08-31,7.10.2
+2015-09-01,7.10.2
+2015-09-02,7.10.2
+2015-09-03,7.10.2
+2015-09-04,7.10.2
+2015-09-05,7.10.2
+2015-09-06,7.10.2
+2015-09-07,7.10.2
+2015-09-09,7.10.2
+2015-09-10,7.10.2
+2015-09-11,7.10.2
+2015-09-12,7.10.2
+2015-09-13,7.10.2
+2015-09-17,7.10.2
+2015-09-18,7.10.2
+2015-09-19,7.10.2
+2015-09-20,7.10.2
+2015-09-21,7.10.2
+2015-09-24,7.10.2
+2015-09-25,7.10.2
+2015-09-26,7.10.2
+2015-09-27,7.10.2
+2015-09-28,7.10.2
+2015-09-29,7.10.2
+2015-09-30,7.10.2
+2015-10-01,7.10.2
+2015-10-04,7.10.2
+2015-10-05,7.10.2
+2015-10-06,7.10.2
+2015-10-07,7.10.2
+2015-10-08,7.10.2
+2015-10-09,7.10.2
+2015-10-12,7.10.2
+2015-10-13,7.10.2
+2015-10-14,7.10.2
+2015-10-15,7.10.2
+2015-10-17,7.10.2
+2015-10-18,7.10.2
+2015-10-19,7.10.2
+2015-10-20,7.10.2
+2015-10-21,7.10.2
+2015-10-22,7.10.2
+2015-10-23,7.10.2
+2015-10-24,7.10.2
+2015-10-25,7.10.2
+2015-10-26,7.10.2
+2015-10-27,7.10.2
+2015-10-28,7.10.2
+2015-10-30,7.10.2
+2015-10-31,7.10.2
+2015-11-01,7.10.2
+2015-11-02,7.10.2
+2015-11-03,7.10.2
+2015-11-04,7.10.2
+2015-11-06,7.10.2
+2015-11-08,7.10.2
+2015-11-09,7.10.2
+2015-11-10,7.10.2
+2015-11-11,7.10.2
+2015-11-12,7.10.2
+2015-11-13,7.10.2
+2015-11-14,7.10.2
+2015-11-15,7.10.2
+2015-11-16,7.10.2
+2015-11-17,7.10.2
+2015-11-18,7.10.2
+2015-11-19,7.10.2
+2015-11-21,7.10.2
+2015-11-22,7.10.2
+2015-11-23,7.10.2
+2015-11-24,7.10.2
+2015-11-25,7.10.2
+2015-11-26,7.10.2
+2015-11-27,7.10.2
+2015-11-28,7.10.2
+2015-11-29,7.10.2
+2015-11-30,7.10.2
+2015-12-01,7.10.2
+2015-12-02,7.10.2
+2015-12-03,7.10.2
+2015-12-04,7.10.2
+2015-12-05,7.10.2
+2015-12-06,7.10.2
+2015-12-07,7.10.2
+2015-12-08,7.10.2
+2015-12-09,7.10.2
+2015-12-10,7.10.2
+2015-12-11,7.10.2
+2015-12-12,7.10.2
+2015-12-13,7.10.2
+2015-12-14,7.10.2
+2015-12-16,7.10.3
+2015-12-17,7.10.3
+2015-12-18,7.10.3
+2015-12-19,7.10.3
+2015-12-20,7.10.3
+2015-12-21,7.10.3
+2015-12-22,7.10.3
+2015-12-24,7.10.3
+2015-12-25,7.10.3
+2015-12-26,7.10.3
+2015-12-27,7.10.3
+2015-12-28,7.10.3
+2015-12-29,7.10.3
+2015-12-30,7.10.3
+2015-12-31,7.10.3
+2016-01-01,7.10.3
+2016-01-02,7.10.3
+2016-01-03,7.10.3
+2016-01-04,7.10.3
+2016-01-05,7.10.3
+2016-01-06,7.10.3
+2016-01-07,7.10.3
+2016-01-08,7.10.3
+2016-01-09,7.10.3
+2016-01-10,7.10.3
+2016-01-11,7.10.3
+2016-01-14,7.10.3
+2016-01-16,7.10.3
+2016-01-19,7.10.3
+2016-01-22,7.10.3
+2016-01-23,7.10.3
+2016-01-24,7.10.3
+2016-01-26,7.10.3
+2016-01-27,7.10.3
+2016-01-29,7.10.3
+2016-01-30,7.10.3
+2016-01-31,7.10.3
+2016-02-01,7.10.3
+2016-02-02,7.10.3
+2016-02-03,7.10.3
+2016-02-04,7.10.3
+2016-02-05,7.10.3
+2016-02-08,7.10.3
+2016-02-09,7.10.3
+2016-02-10,7.10.3
+2016-02-11,7.10.3
+2016-02-13,7.10.3
+2016-02-14,7.10.3
+2016-02-15,7.10.3
+2016-02-16,7.10.3
+2016-02-17,7.10.3
+2016-02-18,7.10.3
+2016-02-19,7.10.3
+2016-02-20,7.10.3
+2016-02-22,7.10.3
+2016-02-23,7.10.3
+2016-02-24,7.10.3
+2016-02-25,7.10.3
+2016-02-26,7.10.3
+2016-02-27,7.10.3
+2016-02-28,7.10.3
+2016-02-29,7.10.3
+2016-03-01,7.10.3
+2016-03-02,7.10.3
+2016-03-03,7.10.3
+2016-03-04,7.10.3
+2016-03-06,7.10.3
+2016-03-07,7.10.3
+2016-03-08,7.10.3
+2016-03-09,7.10.3
+2016-03-10,7.10.3
+2016-03-11,7.10.3
+2016-03-12,7.10.3
+2016-03-13,7.10.3
+2016-03-14,7.10.3
+2016-03-15,7.10.3
+2016-03-16,7.10.3
+2016-03-17,7.10.3
+2016-03-18,7.10.3
+2016-03-19,7.10.3
+2016-03-20,7.10.3
+2016-03-21,7.10.3
+2016-03-22,7.10.3
+2016-03-23,7.10.3
+2016-03-24,7.10.3
+2016-03-25,7.10.3
+2016-03-27,7.10.3
+2016-03-28,7.10.3
+2016-03-29,7.10.3
+2016-03-30,7.10.3
+2016-03-31,7.10.3
+2016-04-01,7.10.3
+2016-04-02,7.10.3
+2016-04-03,7.10.3
+2016-04-04,7.10.3
+2016-04-05,7.10.3
+2016-04-06,7.10.3
+2016-04-07,7.10.3
+2016-04-08,7.10.3
+2016-04-09,7.10.3
+2016-04-10,7.10.3
+2016-04-12,7.10.3
+2016-04-13,7.10.3
+2016-04-14,7.10.3
+2016-04-15,7.10.3
+2016-04-16,7.10.3
+2016-04-17,7.10.3
+2016-04-18,7.10.3
+2016-04-19,7.10.3
+2016-04-20,7.10.3
+2016-04-25,7.10.3
+2016-04-26,7.10.3
+2016-04-27,7.10.3
+2016-04-28,7.10.3
+2016-04-29,7.10.3
+2016-04-30,7.10.3
+2016-05-01,7.10.3
+2016-05-02,7.10.3
+2016-05-03,7.10.3
+2016-05-04,7.10.3
+2016-05-05,7.10.3
+2016-05-06,7.10.3
+2016-05-07,7.10.3
+2016-05-08,7.10.3
+2016-05-12,7.10.3
+2016-05-13,7.10.3
+2016-05-16,7.10.3
+2016-05-17,7.10.3
+2016-05-18,7.10.3
+2016-05-19,7.10.3
+2016-05-20,7.10.3
+2016-05-21,7.10.3
+2016-05-23,7.10.3
+2016-05-24,7.10.3
+2016-05-25,7.10.3
+2016-05-26,8.0.1
+2016-05-27,8.0.1
+2016-05-28,8.0.1
+2016-05-29,8.0.1
+2016-05-30,8.0.1
+2016-05-31,8.0.1
+2016-06-01,8.0.1
+2016-06-02,8.0.1
+2016-06-03,8.0.1
+2016-06-04,8.0.1
+2016-06-05,8.0.1
+2016-06-06,8.0.1
+2016-06-07,8.0.1
+2016-06-08,8.0.1
+2016-06-09,8.0.1
+2016-06-10,8.0.1
+2016-06-11,8.0.1
+2016-06-12,8.0.1
+2016-06-13,8.0.1
+2016-06-14,8.0.1
+2016-06-15,8.0.1
+2016-06-16,8.0.1
+2016-06-17,8.0.1
+2016-06-18,8.0.1
+2016-06-19,8.0.1
+2016-06-20,8.0.1
+2016-06-21,8.0.1
+2016-06-22,8.0.1
+2016-06-26,8.0.1
+2016-06-27,8.0.1
+2016-06-28,8.0.1
+2016-06-29,8.0.1
+2016-06-30,8.0.1
+2016-07-01,8.0.1
+2016-07-02,8.0.1
+2016-07-03,8.0.1
+2016-07-04,8.0.1
+2016-07-05,8.0.1
+2016-07-06,8.0.1
+2016-07-07,8.0.1
+2016-07-08,8.0.1
+2016-07-09,8.0.1
+2016-07-10,8.0.1
+2016-07-11,8.0.1
+2016-07-13,8.0.1
+2016-07-14,8.0.1
+2016-07-15,8.0.1
+2016-07-16,8.0.1
+2016-07-17,8.0.1
+2016-07-18,8.0.1
+2016-07-19,8.0.1
+2016-07-26,8.0.1
+2016-07-27,8.0.1
+2016-07-28,8.0.1
+2016-07-29,8.0.1
+2016-07-30,8.0.1
+2016-07-31,8.0.1
+2016-08-01,8.0.1
+2016-08-02,8.0.1
+2016-08-04,8.0.1
+2016-08-05,8.0.1
+2016-08-06,8.0.1
+2016-08-11,8.0.1
+2016-08-12,8.0.1
+2016-08-13,8.0.1
+2016-08-14,8.0.1
+2016-08-15,8.0.1
+2016-08-16,8.0.1
+2016-08-17,8.0.1
+2016-08-18,8.0.1
+2016-08-19,8.0.1
+2016-08-20,8.0.1
+2016-08-21,8.0.1
+2016-08-22,8.0.1
+2016-08-23,8.0.1
+2016-08-24,8.0.1
+2016-08-25,8.0.1
+2016-08-26,8.0.1
+2016-08-27,8.0.1
+2016-08-28,8.0.1
+2016-08-29,8.0.1
+2016-08-30,8.0.1
+2016-08-31,8.0.1
+2016-09-01,8.0.1
+2016-09-02,8.0.1
+2016-09-03,8.0.1
+2016-09-04,8.0.1
+2016-09-07,8.0.1
+2016-09-08,8.0.1
+2016-09-09,8.0.1
+2016-09-10,8.0.1
+2016-09-11,8.0.1
+2016-09-12,8.0.1
+2016-09-13,8.0.1
+2016-09-14,8.0.1
+2016-09-15,8.0.1
+2016-09-16,8.0.1
+2016-09-17,8.0.1
+2016-09-18,8.0.1
+2016-09-19,8.0.1
+2016-09-20,8.0.1
+2016-09-21,8.0.1
+2016-09-22,8.0.1
+2016-09-23,8.0.1
+2016-09-24,8.0.1
+2016-09-26,8.0.1
+2016-09-27,8.0.1
+2016-09-28,8.0.1
+2016-09-29,8.0.1
+2016-09-30,8.0.1
+2016-10-01,8.0.1
+2016-10-02,8.0.1
+2016-10-03,8.0.1
+2016-10-04,8.0.1
+2016-10-05,8.0.1
+2016-10-06,8.0.1
+2016-10-07,8.0.1
+2016-10-10,8.0.1
+2016-10-11,8.0.1
+2016-10-13,8.0.1
+2016-10-14,8.0.1
+2016-10-15,8.0.1
+2016-10-16,8.0.1
+2016-10-17,8.0.1
+2016-10-18,8.0.1
+2016-10-19,8.0.1
+2016-10-20,8.0.1
+2016-10-21,8.0.1
+2016-10-22,8.0.1
+2016-10-23,8.0.1
+2016-10-24,8.0.1
+2016-10-25,8.0.1
+2016-10-26,8.0.1
+2016-10-27,8.0.1
+2016-10-28,8.0.1
+2016-10-29,8.0.1
+2016-10-30,8.0.1
+2016-10-31,8.0.1
+2016-11-01,8.0.1
+2016-11-02,8.0.1
+2016-11-03,8.0.1
+2016-11-04,8.0.1
+2016-11-05,8.0.1
+2016-11-06,8.0.1
+2016-11-07,8.0.1
+2016-11-08,8.0.1
+2016-11-09,8.0.1
+2016-11-10,8.0.1
+2016-11-11,8.0.1
+2016-11-12,8.0.1
+2016-11-13,8.0.1
+2016-11-15,8.0.1
+2016-11-16,8.0.1
+2016-11-17,8.0.1
+2016-11-18,8.0.1
+2016-11-19,8.0.1
+2016-11-22,8.0.1
+2016-11-23,8.0.1
+2016-11-24,8.0.1
+2016-11-25,8.0.1
+2016-11-26,8.0.1
+2016-11-28,8.0.1
+2016-11-29,8.0.1
+2016-11-30,8.0.1
+2016-12-01,8.0.1
+2016-12-02,8.0.1
+2016-12-03,8.0.1
+2016-12-04,8.0.1
+2016-12-05,8.0.1
+2016-12-06,8.0.1
+2016-12-07,8.0.1
+2016-12-08,8.0.1
+2016-12-09,8.0.1
+2016-12-10,8.0.1
+2016-12-11,8.0.1
+2016-12-12,8.0.1
+2016-12-13,8.0.1
+2016-12-14,8.0.1
+2016-12-15,8.0.1
+2016-12-16,8.0.1
+2016-12-17,8.0.1
+2016-12-18,8.0.1
+2016-12-19,8.0.1
+2016-12-20,8.0.1
+2016-12-21,8.0.1
+2016-12-22,8.0.1
+2016-12-23,8.0.1
+2016-12-27,8.0.1
+2016-12-28,8.0.1
+2016-12-29,8.0.1
+2016-12-30,8.0.1
+2016-12-31,8.0.1
+2017-01-06,8.0.1
+2017-01-07,8.0.1
+2017-01-09,8.0.1
+2017-01-10,8.0.1
+2017-01-12,8.0.1
+2017-01-13,8.0.1
+2017-01-14,8.0.1
+2017-01-16,8.0.1
+2017-01-17,8.0.1
+2017-01-25,8.0.2
+2017-01-26,8.0.2
+2017-01-27,8.0.2
+2017-01-28,8.0.2
+2017-01-29,8.0.2
+2017-01-30,8.0.2
+2017-01-31,8.0.2
+2017-02-01,8.0.2
+2017-02-02,8.0.2
+2017-02-03,8.0.2
+2017-02-05,8.0.2
+2017-02-06,8.0.2
+2017-02-07,8.0.2
+2017-02-08,8.0.2
+2017-02-09,8.0.2
+2017-02-10,8.0.2
+2017-02-11,8.0.2
+2017-02-12,8.0.2
+2017-02-13,8.0.2
+2017-02-16,8.0.2
+2017-02-18,8.0.2
+2017-02-19,8.0.2
+2017-02-20,8.0.2
+2017-02-21,8.0.2
+2017-02-22,8.0.2
+2017-02-23,8.0.2
+2017-02-24,8.0.2
+2017-02-25,8.0.2
+2017-02-26,8.0.2
+2017-02-28,8.0.2
+2017-03-01,8.0.2
+2017-03-02,8.0.2
+2017-03-03,8.0.2
+2017-03-04,8.0.2
+2017-03-05,8.0.2
+2017-03-06,8.0.2
+2017-03-07,8.0.2
+2017-03-08,8.0.2
+2017-03-09,8.0.2
+2017-03-10,8.0.2
+2017-03-11,8.0.2
+2017-03-12,8.0.2
+2017-03-13,8.0.2
+2017-03-14,8.0.2
+2017-03-15,8.0.2
+2017-03-17,8.0.2
+2017-03-19,8.0.2
+2017-03-20,8.0.2
+2017-03-23,8.0.2
+2017-03-24,8.0.2
+2017-03-25,8.0.2
+2017-03-27,8.0.2
+2017-03-28,8.0.2
+2017-03-29,8.0.2
+2017-03-30,8.0.2
+2017-03-31,8.0.2
+2017-04-01,8.0.2
+2017-04-02,8.0.2
+2017-04-05,8.0.2
+2017-04-06,8.0.2
+2017-04-07,8.0.2
+2017-04-08,8.0.2
+2017-04-09,8.0.2
+2017-04-10,8.0.2
+2017-04-11,8.0.2
+2017-04-12,8.0.2
+2017-04-13,8.0.2
+2017-04-14,8.0.2
+2017-04-17,8.0.2
+2017-04-18,8.0.2
+2017-04-19,8.0.2
+2017-04-21,8.0.2
+2017-04-22,8.0.2
+2017-04-23,8.0.2
+2017-04-24,8.0.2
+2017-04-26,8.0.2
+2017-04-27,8.0.2
+2017-04-28,8.0.2
+2017-04-30,8.0.2
+2017-05-01,8.0.2
+2017-05-02,8.0.2
+2017-05-03,8.0.2
+2017-05-05,8.0.2
+2017-05-06,8.0.2
+2017-05-07,8.0.2
+2017-05-10,8.0.2
+2017-05-11,8.0.2
+2017-05-12,8.0.2
+2017-05-13,8.0.2
+2017-05-14,8.0.2
+2017-05-15,8.0.2
+2017-05-16,8.0.2
+2017-05-17,8.0.2
+2017-05-18,8.0.2
+2017-05-19,8.0.2
+2017-05-20,8.0.2
+2017-05-22,8.0.2
+2017-05-23,8.0.2
+2017-05-24,8.0.2
+2017-05-25,8.0.2
+2017-05-26,8.0.2
+2017-05-27,8.0.2
+2017-05-28,8.0.2
+2017-05-30,8.0.2
+2017-06-01,8.0.2
+2017-06-02,8.0.2
+2017-06-10,8.0.2
+2017-06-11,8.0.2
+2017-06-12,8.0.2
+2017-06-13,8.0.2
+2017-06-14,8.0.2
+2017-06-15,8.0.2
+2017-06-16,8.0.2
+2017-06-18,8.0.2
+2017-06-19,8.0.2
+2017-06-20,8.0.2
+2017-06-21,8.0.2
+2017-06-22,8.0.2
+2017-06-23,8.0.2
+2017-06-26,8.0.2
+2017-06-28,8.0.2
+2017-06-29,8.0.2
+2017-06-30,8.0.2
+2017-07-02,8.0.2
+2017-07-03,8.0.2
+2017-07-04,8.0.2
+2017-07-05,8.0.2
+2017-07-06,8.0.2
+2017-07-09,8.0.2
+2017-07-10,8.0.2
+2017-07-11,8.0.2
+2017-07-12,8.0.2
+2017-07-13,8.0.2
+2017-07-14,8.0.2
+2017-07-15,8.0.2
+2017-07-16,8.0.2
+2017-07-17,8.0.2
+2017-07-18,8.0.2
+2017-07-19,8.0.2
+2017-07-20,8.0.2
+2017-07-21,8.0.2
+2017-07-25,8.0.2
+2017-07-31,8.2.1
+2017-08-01,8.2.1
+2017-08-02,8.2.1
+2017-08-03,8.2.1
+2017-08-04,8.2.1
+2017-08-05,8.2.1
+2017-08-06,8.2.1
+2017-08-07,8.2.1
+2017-08-08,8.2.1
+2017-08-09,8.2.1
+2017-08-10,8.2.1
+2017-08-11,8.2.1
+2017-08-12,8.2.1
+2017-08-13,8.2.1
+2017-08-14,8.2.1
+2017-08-15,8.2.1
+2017-08-17,8.2.1
+2017-08-19,8.2.1
+2017-08-20,8.2.1
+2017-08-24,8.2.1
+2017-08-25,8.2.1
+2017-08-28,8.2.1
+2017-08-29,8.2.1
+2017-08-30,8.2.1
+2017-08-31,8.2.1
+2017-09-01,8.2.1
+2017-09-02,8.2.1
+2017-09-03,8.2.1
+2017-09-04,8.2.1
+2017-09-05,8.2.1
+2017-09-06,8.2.1
+2017-09-07,8.2.1
+2017-09-09,8.2.1
+2017-09-10,8.2.1
+2017-09-13,8.2.1
+2017-09-14,8.2.1
+2017-09-15,8.2.1
+2017-09-16,8.2.1
+2017-09-17,8.2.1
+2017-09-18,8.2.1
+2017-09-19,8.2.1
+2017-09-20,8.2.1
+2017-09-25,8.2.1
+2017-09-26,8.2.1
+2017-09-28,8.2.1
+2017-09-29,8.2.1
+2017-10-02,8.2.1
+2017-10-03,8.2.1
+2017-10-04,8.2.1
+2017-10-05,8.2.1
+2017-10-06,8.2.1
+2017-10-07,8.2.1
+2017-10-08,8.2.1
+2017-10-09,8.2.1
+2017-10-10,8.2.1
+2017-10-11,8.2.1
+2017-10-12,8.2.1
+2017-10-13,8.2.1
+2017-10-17,8.2.1
+2017-10-18,8.2.1
+2017-10-19,8.2.1
+2017-10-20,8.2.1
+2017-10-21,8.2.1
+2017-10-22,8.2.1
+2017-10-23,8.2.1
+2017-10-25,8.2.1
+2017-10-26,8.2.1
+2017-10-27,8.2.1
+2017-10-28,8.2.1
+2017-10-30,8.2.1
+2017-10-31,8.2.1
+2017-11-01,8.2.1
+2017-11-02,8.2.1
+2017-11-03,8.2.1
+2017-11-04,8.2.1
+2017-11-05,8.2.1
+2017-11-06,8.2.1
+2017-11-07,8.2.1
+2017-11-08,8.2.1
+2017-11-09,8.2.1
+2017-11-10,8.2.1
+2017-11-13,8.2.1
+2017-11-14,8.2.1
+2017-11-15,8.2.1
+2017-11-16,8.2.1
+2017-11-17,8.2.1
+2017-11-18,8.2.1
+2017-11-19,8.2.1
+2017-11-20,8.2.1
+2017-11-21,8.2.1
+2017-11-22,8.2.1
+2017-11-23,8.2.1
+2017-11-24,8.2.1
+2017-11-25,8.2.2
+2017-11-27,8.2.2
+2017-11-28,8.2.2
+2017-11-29,8.2.2
+2017-11-30,8.2.2
+2017-12-01,8.2.2
+2017-12-05,8.2.2
+2017-12-06,8.2.2
+2017-12-07,8.2.2
+2017-12-08,8.2.2
+2017-12-09,8.2.2
+2017-12-10,8.2.2
+2017-12-13,8.2.2
+2017-12-14,8.2.2
+2017-12-15,8.2.2
+2017-12-16,8.2.2
+2017-12-18,8.2.2
+2017-12-19,8.2.2
+2017-12-20,8.2.2
+2017-12-21,8.2.2
+2017-12-22,8.2.2
+2017-12-23,8.2.2
+2017-12-24,8.2.2
+2017-12-27,8.2.2
+2017-12-28,8.2.2
+2017-12-29,8.2.2
+2017-12-30,8.2.2
+2017-12-31,8.2.2
+2018-01-01,8.2.2
+2018-01-02,8.2.2
+2018-01-03,8.2.2
+2018-01-04,8.2.2
+2018-01-05,8.2.2
+2018-01-06,8.2.2
+2018-01-07,8.2.2
+2018-01-09,8.2.2
+2018-01-14,8.2.2
+2018-01-15,8.2.2
+2018-01-16,8.2.2
+2018-01-17,8.2.2
+2018-01-18,8.2.2
+2018-01-21,8.2.2
+2018-01-24,8.2.2
+2018-01-25,8.2.2
+2018-01-26,8.2.2
+2018-01-27,8.2.2
+2018-01-29,8.2.2
+2018-02-07,8.2.2
+2018-02-08,8.2.2
+2018-02-09,8.2.2
+2018-02-10,8.2.2
+2018-02-11,8.2.2
+2018-02-16,8.2.2
+2018-02-17,8.2.2
+2018-02-18,8.2.2
+2018-02-20,8.2.2
+2018-02-21,8.2.2
+2018-02-22,8.2.2
+2018-02-23,8.2.2
+2018-02-24,8.2.2
+2018-02-26,8.2.2
+2018-02-27,8.2.2
+2018-02-28,8.2.2
+2018-03-01,8.2.2
+2018-03-04,8.2.2
+2018-03-05,8.2.2
+2018-03-06,8.2.2
+2018-03-07,8.2.2
+2018-03-10,8.2.2
+2018-03-12,8.2.2
+2018-03-13,8.4.1
+2018-03-14,8.4.1
+2018-03-15,8.4.1
+2018-03-16,8.4.1
+2018-03-17,8.4.1
+2018-03-18,8.4.1
+2018-03-19,8.4.1
+2018-03-20,8.4.1
+2018-03-21,8.4.1
+2018-03-22,8.4.1
+2018-03-23,8.4.1
+2018-03-24,8.4.1
+2018-03-25,8.4.1
+2018-03-26,8.4.1
+2018-03-28,8.4.1
+2018-03-29,8.4.1
+2018-03-30,8.4.1
+2018-03-31,8.4.1
+2018-04-01,8.4.1
+2018-04-02,8.4.1
+2018-04-03,8.4.1
+2018-04-04,8.4.1
+2018-04-05,8.4.1
+2018-04-08,8.4.1
+2018-04-09,8.4.1
+2018-04-10,8.4.1
+2018-04-11,8.4.1
+2018-04-12,8.4.1
+2018-04-13,8.4.1
+2018-04-14,8.4.1
+2018-04-15,8.4.1
+2018-04-16,8.4.1
+2018-04-17,8.4.1
+2018-04-18,8.4.1
+2018-04-19,8.4.1
+2018-04-20,8.4.1
+2018-04-21,8.4.1
+2018-04-23,8.4.2
+2018-04-24,8.4.2
+2018-04-25,8.4.2
+2018-04-26,8.4.2
+2018-04-27,8.4.2
+2018-04-28,8.4.2
+2018-04-29,8.4.2
+2018-04-30,8.4.2
+2018-05-01,8.4.2
+2018-05-02,8.4.2
+2018-05-03,8.4.2
+2018-05-04,8.4.2
+2018-05-05,8.4.2
+2018-05-06,8.4.2
+2018-05-08,8.4.2
+2018-05-09,8.4.2
+2018-05-10,8.4.2
+2018-05-11,8.4.2
+2018-05-12,8.4.2
+2018-05-13,8.4.2
+2018-05-14,8.4.2
+2018-05-15,8.4.2
+2018-05-16,8.4.2
+2018-05-17,8.4.2
+2018-05-18,8.4.2
+2018-05-19,8.4.2
+2018-05-20,8.4.2
+2018-05-21,8.4.2
+2018-05-22,8.4.2
+2018-05-23,8.4.2
+2018-05-25,8.4.2
+2018-05-26,8.4.2
+2018-05-27,8.4.2
+2018-05-28,8.4.2
+2018-05-29,8.4.2
+2018-05-30,8.4.2
+2018-06-01,8.4.3
+2018-06-02,8.4.3
+2018-06-05,8.4.3
+2018-06-06,8.4.3
+2018-06-07,8.4.3
+2018-06-08,8.4.3
+2018-06-09,8.4.3
+2018-06-10,8.4.3
+2018-06-11,8.4.3
+2018-06-12,8.4.3
+2018-06-13,8.4.3
+2018-06-14,8.4.3
+2018-06-15,8.4.3
+2018-06-16,8.4.3
+2018-06-17,8.4.3
+2018-06-18,8.4.3
+2018-06-19,8.4.3
+2018-06-20,8.4.3
+2018-06-21,8.4.3
+2018-06-22,8.4.3
+2018-06-23,8.4.3
+2018-06-24,8.4.3
+2018-06-25,8.4.3
+2018-06-26,8.4.3
+2018-06-27,8.4.3
+2018-06-28,8.4.3
+2018-06-29,8.4.3
+2018-07-04,8.4.3
+2018-07-05,8.4.3
+2018-07-06,8.4.3
+2018-07-08,8.4.3
+2018-07-09,8.4.3
+2018-07-10,8.4.3
+2018-07-11,8.4.3
+2018-07-12,8.4.3
+2018-07-13,8.4.3
+2018-07-14,8.4.3
+2018-07-16,8.4.3
+2018-07-17,8.4.3
+2018-07-18,8.4.3
+2018-07-19,8.4.3
+2018-07-20,8.4.3
+2018-07-21,8.4.3
+2018-07-24,8.4.3
+2018-07-25,8.4.3
+2018-07-26,8.4.3
+2018-07-28,8.4.3
+2018-07-29,8.4.3
+2018-07-30,8.4.3
+2018-07-31,8.4.3
+2018-08-01,8.4.3
+2018-08-02,8.4.3
+2018-08-03,8.4.3
+2018-08-04,8.4.3
+2018-08-05,8.4.3
+2018-08-06,8.4.3
+2018-08-07,8.4.3
+2018-08-08,8.4.3
+2018-08-09,8.4.3
+2018-08-10,8.4.3
+2018-08-11,8.4.3
+2018-08-12,8.4.3
+2018-08-13,8.4.3
+2018-08-14,8.4.3
+2018-08-15,8.4.3
+2018-08-16,8.4.3
+2018-08-17,8.4.3
+2018-08-20,8.4.3
+2018-08-21,8.4.3
+2018-08-29,8.4.3
+2018-08-30,8.4.3
+2018-08-31,8.4.3
+2018-09-01,8.4.3
+2018-09-02,8.4.3
+2018-09-03,8.4.3
+2018-09-05,8.4.3
+2018-09-06,8.4.3
+2018-09-07,8.4.3
+2018-09-09,8.4.3
+2018-09-13,8.4.3
+2018-09-14,8.4.3
+2018-09-15,8.4.3
+2018-09-16,8.4.3
+2018-09-17,8.4.3
+2018-09-18,8.4.3
+2018-09-20,8.4.3
+2018-09-21,8.4.3
+2018-09-22,8.4.3
+2018-09-23,8.4.3
+2018-09-25,8.4.3
+2018-09-26,8.4.3
+2018-09-27,8.4.3
+2018-09-28,8.4.3
+2018-09-29,8.6.1
+2018-09-30,8.6.1
+2018-10-01,8.6.1
+2018-10-02,8.6.1
+2018-10-03,8.6.1
+2018-10-04,8.6.1
+2018-10-05,8.6.1
+2018-10-06,8.6.1
+2018-10-07,8.6.1
+2018-10-08,8.6.1
+2018-10-09,8.6.1
+2018-10-10,8.6.1
+2018-10-11,8.6.1
+2018-10-12,8.6.1
+2018-10-13,8.6.1
+2018-10-14,8.6.1
+2018-10-15,8.6.1
+2018-10-16,8.6.1
+2018-10-17,8.6.1
+2018-10-18,8.6.1
+2018-10-19,8.6.1
+2018-10-20,8.6.1
+2018-10-21,8.6.1
+2018-10-22,8.6.1
+2018-10-23,8.6.1
+2018-10-24,8.6.1
+2018-10-25,8.6.1
+2018-10-26,8.6.1
+2018-10-28,8.6.1
+2018-10-29,8.6.1
+2018-10-30,8.6.1
+2018-10-31,8.6.1
+2018-11-01,8.6.1
+2018-11-02,8.6.1
+2018-11-05,8.6.1
+2018-11-06,8.6.1
+2018-11-07,8.6.1
+2018-11-08,8.6.1
+2018-11-09,8.6.1
+2018-11-10,8.6.1
+2018-11-11,8.6.1
+2018-11-12,8.6.2
+2018-11-13,8.6.2
+2018-11-14,8.6.2
+2018-11-15,8.6.2
+2018-11-16,8.6.2
+2018-11-17,8.6.2
+2018-11-18,8.6.2
+2018-11-19,8.6.2
+2018-11-20,8.6.2
+2018-11-21,8.6.2
+2018-11-22,8.6.2
+2018-11-23,8.6.2
+2018-11-24,8.6.2
+2018-11-27,8.6.2
+2018-11-28,8.6.2
+2018-11-29,8.6.2
+2018-11-30,8.6.2
+2018-12-01,8.6.2
+2018-12-02,8.6.2
+2018-12-03,8.6.2
+2018-12-04,8.6.2
+2018-12-05,8.6.2
+2018-12-06,8.6.2
+2018-12-07,8.6.2
+2018-12-08,8.6.2
+2018-12-09,8.6.2
+2018-12-10,8.6.2
+2018-12-11,8.6.2
+2018-12-12,8.6.2
+2018-12-13,8.6.2
+2018-12-14,8.6.2
+2018-12-15,8.6.2
+2018-12-17,8.6.2
+2018-12-18,8.6.3
+2018-12-19,8.6.3
+2018-12-20,8.6.3
+2018-12-21,8.6.3
+2018-12-22,8.6.3
+2018-12-23,8.6.3
+2018-12-24,8.6.3
+2018-12-25,8.6.3
+2018-12-26,8.6.3
+2018-12-27,8.6.3
+2018-12-28,8.6.3
+2018-12-29,8.6.3
+2018-12-31,8.6.3
+2019-01-03,8.6.3
+2019-01-04,8.6.3
+2019-01-05,8.6.3
+2019-01-06,8.6.3
+2019-01-07,8.6.3
+2019-01-09,8.6.3
+2019-01-10,8.6.3
+2019-01-11,8.6.3
+2019-01-12,8.6.3
+2019-01-13,8.6.3
+2019-01-14,8.6.3
+2019-01-15,8.6.3
+2019-01-16,8.6.3
+2019-01-17,8.6.3
+2019-01-18,8.6.3
+2019-01-19,8.6.3
+2019-01-20,8.6.3
+2019-01-21,8.6.3
+2019-01-22,8.6.3
+2019-01-23,8.6.3
+2019-01-24,8.6.3
+2019-01-25,8.6.3
+2019-01-26,8.6.3
+2019-01-27,8.6.3
+2019-01-28,8.6.3
+2019-01-29,8.6.3
+2019-01-30,8.6.3
+2019-02-02,8.6.3
+2019-02-04,8.6.3
+2019-02-05,8.6.3
+2019-02-06,8.6.3
+2019-02-07,8.6.3
+2019-02-08,8.6.3
+2019-02-09,8.6.3
+2019-02-11,8.6.3
+2019-02-12,8.6.3
+2019-02-13,8.6.3
+2019-02-14,8.6.3
+2019-02-15,8.6.3
+2019-02-16,8.6.3
+2019-02-17,8.6.3
+2019-02-18,8.6.3
+2019-02-19,8.6.3
+2019-02-20,8.6.3
+2019-02-22,8.6.3
+2019-02-23,8.6.3
+2019-02-24,8.6.3
+2019-02-25,8.6.3
+2019-02-26,8.6.3
+2019-02-27,8.6.3
+2019-03-02,8.6.3
+2019-03-03,8.6.3
+2019-03-04,8.6.3
+2019-03-05,8.6.3
+2019-03-06,8.6.3
+2019-03-07,8.6.4
+2019-03-08,8.6.4
+2019-03-09,8.6.4
+2019-03-10,8.6.4
+2019-03-11,8.6.4
+2019-03-12,8.6.4
+2019-03-13,8.6.4
+2019-03-14,8.6.4
+2019-03-15,8.6.4
+2019-03-16,8.6.4
+2019-03-17,8.6.4
+2019-03-18,8.6.4
+2019-03-19,8.6.4
+2019-03-20,8.6.4
+2019-03-21,8.6.4
+2019-03-22,8.6.4
+2019-03-23,8.6.4
+2019-03-24,8.6.4
+2019-03-25,8.6.4
+2019-03-26,8.6.4
+2019-03-27,8.6.4
+2019-03-28,8.6.4
+2019-03-29,8.6.4
+2019-03-30,8.6.4
+2019-03-31,8.6.4
+2019-04-01,8.6.4
+2019-04-02,8.6.4
+2019-04-03,8.6.4
+2019-04-04,8.6.4
+2019-04-05,8.6.4
+2019-04-08,8.6.4
+2019-04-09,8.6.4
+2019-04-10,8.6.4
+2019-04-11,8.6.4
+2019-04-12,8.6.4
+2019-04-14,8.6.4
+2019-04-15,8.6.4
+2019-04-16,8.6.4
+2019-04-18,8.6.4
+2019-04-19,8.6.4
+2019-04-21,8.6.4
+2019-04-22,8.6.4
+2019-04-23,8.6.4
+2019-04-24,8.6.4
+2019-04-25,8.6.4
+2019-04-26,8.6.4
+2019-04-27,8.6.4
+2019-04-28,8.6.4
+2019-04-30,8.6.5
+2019-05-01,8.6.5
+2019-05-03,8.6.5
+2019-05-04,8.6.5
+2019-05-05,8.6.5
+2019-05-06,8.6.5
+2019-05-07,8.6.5
+2019-05-08,8.6.5
+2019-05-09,8.6.5
+2019-05-10,8.6.5
+2019-05-11,8.6.5
+2019-05-12,8.6.5
+2019-05-13,8.6.5
+2019-05-15,8.6.5
+2019-05-16,8.6.5
+2019-05-17,8.6.5
+2019-05-18,8.6.5
+2019-05-20,8.6.5
+2019-05-21,8.6.5
+2019-05-22,8.6.5
+2019-05-23,8.6.5
+2019-05-24,8.6.5
+2019-05-25,8.6.5
+2019-05-26,8.6.5
+2019-05-27,8.6.5
+2019-05-28,8.6.5
+2019-05-29,8.6.5
+2019-05-30,8.6.5
+2019-05-31,8.6.5
+2019-06-01,8.6.5
+2019-06-02,8.6.5
+2019-06-03,8.6.5
+2019-06-04,8.6.5
+2019-06-05,8.6.5
+2019-06-06,8.6.5
+2019-06-08,8.6.5
+2019-06-09,8.6.5
+2019-06-10,8.6.5
+2019-06-11,8.6.5
+2019-06-12,8.6.5
+2019-06-17,8.6.5
+2019-06-19,8.6.5
+2019-06-20,8.6.5
+2019-06-21,8.6.5
+2019-06-26,8.6.5
+2019-06-27,8.6.5
+2019-06-28,8.6.5
+2019-07-02,8.6.5
+2019-07-03,8.6.5
+2019-07-04,8.6.5
+2019-07-05,8.6.5
+2019-07-06,8.6.5
+2019-07-07,8.6.5
+2019-07-10,8.6.5
+2019-07-11,8.6.5
+2019-07-12,8.6.5
+2019-07-13,8.6.5
+2019-07-14,8.6.5
+2019-07-15,8.6.5
+2019-07-16,8.6.5
+2019-07-17,8.6.5
+2019-07-18,8.6.5
+2019-07-19,8.6.5
+2019-07-20,8.6.5
+2019-07-21,8.6.5
+2019-07-22,8.6.5
+2019-07-23,8.6.5
+2019-07-24,8.6.5
+2019-07-25,8.6.5
+2019-07-26,8.6.5
+2019-07-27,8.6.5
+2019-07-29,8.6.5
+2019-07-30,8.6.5
+2019-07-31,8.6.5
+2019-08-01,8.6.5
+2019-08-02,8.6.5
+2019-08-03,8.6.5
+2019-08-04,8.6.5
+2019-08-06,8.6.5
+2019-08-07,8.6.5
+2019-08-11,8.6.5
+2019-08-12,8.6.5
+2019-08-16,8.6.5
+2019-08-17,8.6.5
+2019-08-18,8.6.5
+2019-08-19,8.6.5
+2019-08-20,8.6.5
+2019-08-22,8.6.5
+2019-08-23,8.6.5
+2019-08-24,8.6.5
+2019-08-25,8.6.5
+2019-08-26,8.6.5
+2019-08-27,8.6.5
+2019-08-28,8.6.5
+2019-08-29,8.6.5
+2019-08-30,8.6.5
+2019-08-31,8.6.5
+2019-09-01,8.6.5
+2019-09-02,8.6.5
+2019-09-04,8.6.5
+2019-09-08,8.6.5
+2019-09-11,8.6.5
+2019-09-12,8.6.5
+2019-09-13,8.6.5
+2019-09-14,8.6.5
+2019-09-15,8.6.5
+2019-09-16,8.6.5
+2019-09-17,8.6.5
+2019-09-18,8.6.5
+2019-09-19,8.6.5
+2019-09-20,8.6.5
+2019-09-21,8.6.5
+2019-09-26,8.8.1
+2019-09-27,8.8.1
+2019-09-28,8.8.1
+2019-09-29,8.8.1
+2019-09-30,8.8.1
+2019-10-02,8.8.1
+2019-10-04,8.8.1
+2019-10-05,8.8.1
+2019-10-06,8.8.1
+2019-10-07,8.8.1
+2019-10-10,8.8.1
+2019-10-13,8.8.1
+2019-10-14,8.8.1
+2019-10-15,8.8.1
+2019-10-18,8.8.1
+2019-10-19,8.8.1
+2019-10-20,8.8.1
+2019-10-21,8.8.1
+2019-10-22,8.8.1
+2019-10-23,8.8.1
+2019-10-24,8.8.1
+2019-10-25,8.8.1
+2019-10-26,8.8.1
+2019-10-27,8.8.1
+2019-10-28,8.8.1
+2019-10-29,8.8.1
+2019-10-30,8.8.1
+2019-10-31,8.8.1
+2019-11-01,8.8.1
+2019-11-02,8.8.1
+2019-11-04,8.8.1
+2019-11-05,8.8.1
+2019-11-06,8.8.1
+2019-11-07,8.8.1
+2019-11-08,8.8.1
+2019-11-09,8.8.1
+2019-11-10,8.8.1
+2019-11-11,8.8.1
+2019-11-17,8.8.1
+2019-11-19,8.8.1
+2019-11-20,8.8.1
+2019-11-21,8.8.1
+2019-11-24,8.8.1
+2019-11-25,8.8.1
+2019-11-28,8.8.1
+2019-11-29,8.8.1
+2019-12-05,8.8.1
+2019-12-06,8.8.1
+2019-12-07,8.8.1
+2019-12-08,8.8.1
+2019-12-09,8.8.1
+2019-12-10,8.8.1
+2019-12-11,8.8.1
+2019-12-12,8.8.1
+2019-12-13,8.8.1
+2019-12-15,8.8.1
+2019-12-16,8.8.1
+2019-12-17,8.8.1
+2019-12-18,8.8.1
+2019-12-19,8.8.1
+2019-12-20,8.8.1
+2019-12-21,8.8.1
+2019-12-22,8.8.1
+2019-12-23,8.8.1
+2019-12-24,8.8.1
+2019-12-25,8.8.1
+2019-12-26,8.8.1
+2019-12-27,8.8.1
+2019-12-28,8.8.1
+2019-12-29,8.8.1
+2019-12-30,8.8.1
+2019-12-31,8.8.1
+2020-01-01,8.8.1
+2020-01-02,8.8.1
+2020-01-03,8.8.1
+2020-01-04,8.8.1
+2020-01-05,8.8.1
+2020-01-06,8.8.1
+2020-01-07,8.8.1
+2020-01-08,8.8.1
+2020-01-15,8.8.1
+2020-01-16,8.8.1
+2020-01-17,8.8.1
+2020-01-19,8.8.1
+2020-01-21,8.8.1
+2020-01-24,8.8.2
+2020-01-25,8.8.2
+2020-01-29,8.8.2
+2020-01-30,8.8.2
+2020-01-31,8.8.2
+2020-02-02,8.8.2
+2020-02-03,8.8.2
+2020-02-04,8.8.2
+2020-02-06,8.8.2
+2020-02-07,8.8.2
+2020-02-08,8.8.2
+2020-02-11,8.8.2
+2020-02-12,8.8.2
+2020-02-13,8.8.2
+2020-02-14,8.8.2
+2020-02-15,8.8.2
+2020-02-16,8.8.2
+2020-02-17,8.8.2
+2020-02-19,8.8.2
+2020-02-20,8.8.2
+2020-02-21,8.8.2
+2020-02-22,8.8.2
+2020-02-23,8.8.2
+2020-02-24,8.8.2
+2020-02-25,8.8.2
+2020-02-26,8.8.2
+2020-02-27,8.8.2
+2020-02-28,8.8.2
+2020-02-29,8.8.2
+2020-03-01,8.8.2
+2020-03-02,8.8.2
+2020-03-03,8.8.2
+2020-03-04,8.8.2
+2020-03-06,8.8.2
+2020-03-07,8.8.2
+2020-03-08,8.8.2
+2020-03-09,8.8.2
+2020-03-10,8.8.3
+2020-03-11,8.8.3
+2020-03-12,8.8.3
+2020-03-13,8.8.3
+2020-03-14,8.8.3
+2020-03-16,8.8.3
+2020-03-17,8.8.3
+2020-03-18,8.8.3
+2020-03-21,8.8.3
+2020-03-22,8.8.3
+2020-03-23,8.8.3
+2020-03-24,8.8.3
+2020-03-25,8.8.3
+2020-03-26,8.8.3
+2020-03-28,8.8.3
+2020-03-29,8.8.3
+2020-03-30,8.8.3
+2020-04-01,8.8.3
+2020-04-02,8.8.3
+2020-04-03,8.8.3
+2020-04-04,8.8.3
+2020-04-05,8.8.3
+2020-04-07,8.8.3
+2020-04-08,8.8.3
+2020-04-09,8.8.3
+2020-04-10,8.8.3
+2020-04-11,8.8.3
+2020-04-12,8.8.3
+2020-04-13,8.8.3
+2020-04-15,8.8.3
+2020-04-16,8.8.3
+2020-04-17,8.8.3
+2020-04-18,8.8.3
+2020-04-21,8.8.3
+2020-04-22,8.8.3
+2020-04-23,8.8.3
+2020-04-24,8.8.3
+2020-04-25,8.8.3
+2020-04-26,8.8.3
+2020-04-27,8.8.3
+2020-04-28,8.8.3
+2020-04-29,8.8.3
+2020-04-30,8.8.3
+2020-05-01,8.8.3
+2020-05-03,8.8.3
+2020-05-04,8.8.3
+2020-05-05,8.8.3
+2020-05-06,8.8.3
+2020-05-07,8.8.3
+2020-05-10,8.8.3
+2020-05-11,8.8.3
+2020-05-12,8.8.3
+2020-05-13,8.8.3
+2020-05-14,8.8.3
+2020-05-15,8.8.3
+2020-05-16,8.8.3
+2020-05-19,8.8.3
+2020-05-22,8.8.3
+2020-05-23,8.8.3
+2020-05-26,8.8.3
+2020-05-30,8.8.3
+2020-05-31,8.8.3
+2020-06-01,8.8.3
+2020-06-02,8.8.3
+2020-06-03,8.8.3
+2020-06-04,8.8.3
+2020-06-05,8.8.3
+2020-06-06,8.8.3
+2020-06-08,8.8.3
+2020-06-09,8.8.3
+2020-06-10,8.8.3
+2020-06-11,8.8.3
+2020-06-12,8.8.3
+2020-06-13,8.8.3
+2020-06-15,8.8.3
+2020-06-16,8.8.3
+2020-06-17,8.10.1
+2020-06-18,8.10.1
+2020-06-19,8.10.1
+2020-06-20,8.10.1
+2020-06-21,8.10.1
+2020-06-22,8.10.1
+2020-06-24,8.10.1
+2020-06-25,8.10.1
+2020-06-26,8.10.1
+2020-06-27,8.10.1
+2020-06-28,8.10.1
+2020-06-29,8.10.1
+2020-07-04,8.10.1
+2020-07-06,8.10.1
+2020-07-07,8.10.1
+2020-07-08,8.10.1
+2020-07-09,8.10.1
+2020-07-10,8.10.1
+2020-07-11,8.10.1
+2020-07-12,8.10.1
+2020-07-13,8.10.1
+2020-07-14,8.10.1
+2020-07-15,8.10.1
+2020-07-16,8.10.1
+2020-07-17,8.10.1
+2020-07-18,8.10.1
+2020-07-19,8.10.1
+2020-07-21,8.10.1
+2020-07-22,8.10.1
+2020-07-23,8.10.1
+2020-07-24,8.10.1
+2020-07-27,8.10.1
+2020-07-28,8.10.1
+2020-07-29,8.10.1
+2020-07-30,8.10.1
+2020-07-31,8.10.1
+2020-08-01,8.10.1
+2020-08-02,8.10.1
+2020-08-03,8.10.1
+2020-08-08,8.10.1
+2020-08-09,8.10.1
+2020-08-10,8.10.1
+2020-08-11,8.10.1
+2020-08-12,8.10.1
+2020-08-13,8.10.1
+2020-08-14,8.10.1
+2020-08-15,8.10.1
+2020-08-16,8.10.1
+2020-08-17,8.10.2
+2020-08-18,8.10.2
+2020-08-19,8.10.2
+2020-08-20,8.10.2
+2020-08-21,8.10.2
+2020-08-22,8.10.2
+2020-08-23,8.10.2
+2020-08-25,8.10.2
+2020-08-26,8.10.2
+2020-08-27,8.10.2
+2020-08-28,8.10.2
+2020-08-29,8.10.2
+2020-08-30,8.10.2
+2020-08-31,8.10.2
+2020-09-01,8.10.2
+2020-09-02,8.10.2
+2020-09-03,8.10.2
+2020-09-05,8.10.2
+2020-09-06,8.10.2
+2020-09-07,8.10.2
+2020-09-09,8.10.2
+2020-09-10,8.10.2
+2020-09-13,8.10.2
+2020-09-14,8.10.2
+2020-09-15,8.10.2
+2020-09-16,8.10.2
+2020-09-17,8.10.2
+2020-09-18,8.10.2
+2020-09-19,8.10.2
+2020-09-20,8.10.2
+2020-09-21,8.10.2
+2020-09-22,8.10.2
+2020-09-23,8.10.2
+2020-09-24,8.10.2
+2020-09-25,8.10.2
+2020-09-26,8.10.2
+2020-09-27,8.10.2
+2020-09-28,8.10.2
+2020-09-29,8.10.2
+2020-10-02,8.10.2
+2020-10-03,8.10.2
+2020-10-05,8.10.2
+2020-10-06,8.10.2
+2020-10-07,8.10.2
+2020-10-08,8.10.2
+2020-10-09,8.10.2
+2020-10-10,8.10.2
+2020-10-11,8.10.2
+2020-10-12,8.10.2
+2020-10-13,8.10.2
+2020-10-14,8.10.2
+2020-10-15,8.10.2
+2020-10-16,8.10.2
+2020-10-17,8.10.2
+2020-10-18,8.10.2
+2020-10-19,8.10.2
+2020-10-20,8.10.2
+2020-10-22,8.10.2
+2020-10-23,8.10.2
+2020-10-25,8.10.2
+2020-10-26,8.10.2
+2020-10-27,8.10.2
+2020-10-28,8.10.2
+2020-10-29,8.10.2
+2020-10-30,8.10.2
+2020-10-31,8.10.2
+2020-11-01,8.10.2
+2020-11-03,8.10.2
+2020-11-04,8.10.2
+2020-11-06,8.10.2
+2020-11-08,8.10.2
+2020-11-10,8.10.2
+2020-11-11,8.10.2
+2020-11-15,8.10.2
+2020-11-16,8.10.2
+2020-11-17,8.10.2
+2020-11-18,8.10.2
+2020-11-19,8.10.2
+2020-11-20,8.10.2
+2020-11-21,8.10.2
+2020-11-22,8.10.2
+2020-11-23,8.10.2
+2020-11-27,8.10.2
+2020-11-28,8.10.2
+2020-12-01,8.10.2
+2020-12-02,8.10.2
+2020-12-03,8.10.2
+2020-12-04,8.10.2
+2020-12-05,8.10.2
+2020-12-06,8.10.2
+2020-12-07,8.10.2
+2020-12-08,8.10.2
+2020-12-09,8.10.2
+2020-12-10,8.10.2
+2020-12-12,8.10.2
+2020-12-13,8.10.2
+2020-12-14,8.10.2
+2021-01-01,8.10.3
+2021-01-02,8.10.3
+2021-01-03,8.10.3
+2021-01-04,8.10.3
+2021-01-05,8.10.3
+2021-01-09,8.10.3
+2021-01-10,8.10.3
+2021-01-11,8.10.3
+2021-01-13,8.10.3
+2021-01-14,8.10.3
+2021-01-15,8.10.3
+2021-01-16,8.10.3
+2021-01-17,8.10.3
+2021-01-19,8.10.3
+2021-01-20,8.10.3
+2021-01-25,8.10.3
+2021-01-26,8.10.3
+2021-01-27,8.10.3
+2021-01-28,8.10.3
+2021-01-29,8.10.3
+2021-01-30,8.10.3
+2021-02-01,8.10.3
+2021-02-02,8.10.3
+2021-02-03,8.10.3
+2021-02-04,8.10.3
+2021-02-05,8.10.3
+2021-02-06,8.10.3
+2021-02-09,8.10.3
+2021-02-10,8.10.3
+2021-02-11,8.10.4
+2021-02-12,8.10.4
+2021-02-23,8.10.4
+2021-02-24,8.10.4
+2021-02-25,8.10.4
+2021-02-27,8.10.4
+2021-02-28,8.10.4
+2021-03-01,8.10.4
+2021-03-05,8.10.4
+2021-03-06,8.10.4
+2021-03-07,8.10.4
+2021-03-09,8.10.4
+2021-03-10,8.10.4
+2021-03-11,8.10.4
+2021-03-12,8.10.4
+2021-03-13,8.10.4
+2021-03-14,8.10.4
+2021-03-17,8.10.4
+2021-03-18,8.10.4
+2021-03-19,8.10.4
+2021-03-20,8.10.4
+2021-03-21,8.10.4
+2021-03-24,8.10.4
+2021-03-25,8.10.4
+2021-03-26,8.10.4
+2021-03-27,8.10.4
+2021-03-28,8.10.4
+2021-03-29,8.10.4
+2021-03-30,8.10.4
+2021-03-31,8.10.4
+2021-04-01,8.10.4
+2021-04-02,8.10.4
+2021-04-06,8.10.4
+2021-04-14,8.10.4
+2021-04-15,8.10.4
+2021-04-19,8.10.4
+2021-04-22,8.10.4
+2021-04-23,8.10.4
+2021-04-24,8.10.4
+2021-04-25,8.10.4
+2021-04-26,8.10.4
+2021-04-27,8.10.4
+2021-04-28,8.10.4
+2021-04-29,8.10.4
+2021-04-30,8.10.4
+2021-05-01,8.10.4
+2021-05-02,8.10.4
+2021-05-03,8.10.4
+2021-05-04,8.10.4
+2021-05-05,8.10.4
+2021-05-06,8.10.4
+2021-05-07,8.10.4
+2021-05-08,8.10.4
+2021-05-09,8.10.4
+2021-05-10,8.10.4
+2021-05-14,8.10.4
+2021-05-15,8.10.4
+2021-05-16,8.10.4
+2021-05-19,8.10.4
+2021-05-20,8.10.4
+2021-05-23,8.10.4
+2021-05-25,8.10.4
+2021-05-26,8.10.4
+2021-05-27,8.10.4
+2021-05-28,8.10.4
+2021-05-31,8.10.4
+2021-06-01,8.10.4
+2021-06-10,8.10.4
+2021-06-14,8.10.4
+2021-06-19,9.0.1
+2021-06-20,9.0.1
+2021-06-21,9.0.1
+2021-06-24,9.0.1
+2021-06-29,9.0.1
+2021-06-30,9.0.1
+2021-07-01,9.0.1
+2021-07-02,9.0.1
+2021-07-03,9.0.1
+2021-07-04,9.0.1
+2021-07-06,9.0.1
+2021-07-07,9.0.1
+2021-07-08,9.0.1
+2021-07-09,9.0.1
+2021-07-11,9.0.1
+2021-07-12,9.0.1
+2021-07-13,9.0.1
+2021-07-14,9.0.1
+2021-07-15,9.0.1
+2021-07-16,9.0.1
+2021-07-17,9.0.1
+2021-07-18,9.0.1
+2021-07-19,9.0.1
+2021-07-20,9.0.1
+2021-07-21,9.0.1
+2021-07-22,9.0.1
+2021-07-23,9.0.1
+2021-07-28,9.0.1
+2021-07-29,9.0.1
+2021-07-30,9.0.1
+2021-07-31,9.0.1
+2021-08-01,9.0.1
+2021-08-03,9.0.1
+2021-08-04,9.0.1
+2021-08-05,9.0.1
+2021-08-06,9.0.1
+2021-08-07,9.0.1
+2021-08-08,9.0.1
+2021-08-13,9.0.1
+2021-08-14,9.0.1
+2021-08-15,9.0.1
+2021-08-16,9.0.1
+2021-08-17,9.0.1
+2021-08-19,9.0.1
+2021-08-20,9.0.1
+2021-08-21,9.0.1
+2021-08-22,9.0.1
+2021-08-23,9.0.1
+2021-08-24,9.0.1
+2021-08-25,9.0.1
+2021-08-26,9.0.1
+2021-08-27,9.0.1
+2021-08-28,9.0.1
+2021-08-29,9.0.1
+2021-09-01,9.0.1
+2021-09-02,9.0.1
+2021-09-06,9.0.1
+2021-09-07,9.0.1
+2021-09-08,9.0.1
+2021-09-09,9.0.1
+2021-09-10,9.0.1
+2021-09-11,9.0.1
+2021-09-12,9.0.1
+2021-09-16,9.0.1
+2021-09-17,9.0.1
+2021-09-18,9.0.1
+2021-09-29,9.0.1
+2021-09-30,9.0.1
+2021-10-01,9.0.1
+2021-10-02,9.0.1
+2021-10-05,9.0.1
+2021-10-07,9.0.1
+2021-10-12,9.0.1
+2021-10-13,9.0.1
+2021-10-18,9.0.1
+2021-10-19,9.0.1
+2021-10-20,9.0.1
+2021-10-21,9.0.1
+2021-10-22,9.0.1
+2021-10-23,9.0.1
+2021-10-24,9.0.1
+2021-10-25,9.0.1
+2021-10-26,9.0.1
+2021-10-27,9.0.1
+2021-10-29,9.0.1
+2021-11-06,9.0.1
+2021-11-12,9.0.1
+2021-11-14,9.0.1
+2021-11-15,9.0.1
+2021-11-19,9.0.1
+2021-11-26,9.0.1
+2021-11-27,9.0.1
+2021-11-28,9.0.1
+2021-12-03,9.0.1
+2021-12-04,9.0.1
+2021-12-06,9.0.1
+2021-12-07,9.0.1
+2021-12-08,9.0.1
+2021-12-10,9.0.1
+2021-12-11,9.0.1
+2021-12-12,9.0.1
+2021-12-13,9.0.1
+2021-12-14,9.0.1
+2021-12-15,9.0.1
+2021-12-16,9.0.1
+2021-12-17,9.0.1
+2021-12-18,9.0.1
+2021-12-19,9.0.1
+2021-12-20,9.0.1
+2021-12-21,9.0.1
+2021-12-22,9.0.1
+2021-12-23,9.0.1
+2021-12-24,9.0.1
+2021-12-25,9.0.1
+2021-12-26,9.0.1
+2021-12-29,9.0.1
+2021-12-30,9.0.1
+2022-01-02,9.0.1
+2022-01-03,9.0.1
+2022-01-04,9.0.1
+2022-01-05,9.0.1
+2022-01-06,9.0.1
+2022-01-10,9.0.2
+2022-01-13,9.0.2
+2022-01-14,9.0.2
+2022-01-15,9.0.2
+2022-01-19,9.0.2
+2022-01-20,9.0.2
+2022-01-22,9.0.2
+2022-01-23,9.0.2
+2022-01-24,9.0.2
+2022-01-25,9.0.2
+2022-01-26,9.0.2
+2022-01-27,9.0.2
+2022-01-31,9.0.2
+2022-02-01,9.0.2
+2022-02-05,9.0.2
+2022-02-07,9.0.2
+2022-02-10,9.0.2
+2022-02-11,9.0.2
+2022-02-12,9.0.2
+2022-02-14,9.0.2
+2022-02-15,9.0.2
+2022-02-16,9.0.2
+2022-02-17,9.0.2
+2022-02-18,9.0.2
+2022-02-19,9.0.2
+2022-02-24,9.0.2
+2022-02-25,9.0.2
+2022-02-26,9.0.2
+2022-02-27,9.0.2
+2022-03-02,9.0.2
+2022-03-03,9.0.2
+2022-03-09,9.0.2
+2022-03-10,9.0.2
+2022-03-12,9.0.2
+2022-03-13,9.0.2
+2022-03-14,9.0.2
+2022-03-15,9.0.2
+2022-03-16,9.0.2
+2022-03-17,9.0.2
+2022-03-19,9.2.2
+2022-03-20,9.2.2
+2022-03-21,9.2.2
+2022-03-22,9.2.2
+2022-03-23,9.2.2
+2022-03-24,9.2.2
+2022-03-25,9.2.2
+2022-03-26,9.2.2
+2022-03-27,9.2.2
+2022-03-28,9.2.2
+2022-03-29,9.2.2
+2022-03-30,9.2.2
+2022-03-31,9.2.2
+2022-04-01,9.2.2
+2022-04-02,9.2.2
+2022-04-03,9.2.2
+2022-04-04,9.2.2
+2022-04-05,9.2.2
+2022-04-06,9.2.2
+2022-04-07,9.2.2
+2022-04-08,9.2.2
+2022-04-09,9.2.2
+2022-04-10,9.2.2
+2022-04-11,9.2.2
+2022-04-12,9.2.2
+2022-04-13,9.2.2
+2022-04-14,9.2.2
+2022-04-15,9.2.2
+2022-04-16,9.2.2
+2022-04-18,9.2.2
+2022-04-19,9.2.2
+2022-04-20,9.2.2
+2022-04-21,9.2.2
+2022-04-22,9.2.2
+2022-04-23,9.2.2
+2022-04-24,9.2.2
+2022-04-25,9.2.2
+2022-04-26,9.2.2
+2022-04-27,9.2.2
+2022-04-28,9.2.2
+2022-05-03,9.2.2
+2022-05-05,9.2.2
+2022-05-11,9.2.2
+2022-05-12,9.2.2
+2022-05-14,9.2.2
+2022-05-18,9.2.2
+2022-05-19,9.2.2
+2022-05-20,9.2.2
+2022-05-25,9.2.2
+2022-05-26,9.2.2
+2022-05-27,9.2.2
+2022-05-28,9.2.2
+2022-05-29,9.2.2
+2022-05-30,9.2.2
+2022-05-31,9.2.2
+2022-06-01,9.2.2
+2022-06-02,9.2.2
+2022-06-03,9.2.2
+2022-06-04,9.2.2
+2022-06-05,9.2.2
+2022-06-06,9.2.2
+2022-06-08,9.2.3
+2022-06-09,9.2.3
+2022-06-10,9.2.3
+2022-06-11,9.2.3
+2022-06-12,9.2.3
+2022-06-13,9.2.3
+2022-06-14,9.2.3
+2022-06-15,9.2.3
+2022-06-17,9.2.3
+2022-06-18,9.2.3
+2022-06-19,9.2.3
+2022-06-20,9.2.3
+2022-06-21,9.2.3
+2022-06-22,9.2.3
+2022-06-24,9.2.3
+2022-06-25,9.2.3
+2022-06-26,9.2.3
+2022-06-27,9.2.3
+2022-06-28,9.2.3
+2022-06-29,9.2.3
+2022-06-30,9.2.3
+2022-07-01,9.2.3
+2022-07-03,9.2.3
+2022-07-04,9.2.3
+2022-07-05,9.2.3
+2022-07-06,9.2.3
+2022-07-07,9.2.3
+2022-07-10,9.2.3
+2022-07-11,9.2.3
+2022-07-12,9.2.3
+2022-07-13,9.2.3
+2022-07-14,9.2.3
+2022-07-15,9.2.3
+2022-07-16,9.2.3
+2022-07-17,9.2.3
+2022-07-18,9.2.3
+2022-07-19,9.2.3
+2022-07-20,9.2.3
+2022-07-21,9.2.3
+2022-07-23,9.2.3
+2022-07-26,9.2.3
+2022-07-27,9.2.3
+2022-07-28,9.2.3
+2022-07-29,9.2.3
+2022-07-30,9.2.3
+2022-07-31,9.2.3
+2022-08-01,9.2.4
+2022-08-02,9.2.4
+2022-08-03,9.2.4
+2022-08-04,9.2.4
+2022-08-14,9.2.4
+2022-08-15,9.2.4
+2022-08-16,9.2.4
+2022-08-17,9.2.4
+2022-08-18,9.2.4
+2022-08-19,9.2.4
+2022-08-24,9.2.4
+2022-08-26,9.2.4
+2022-08-29,9.2.4
+2022-08-30,9.2.4
+2022-09-01,9.2.4
+2022-09-02,9.2.4
+2022-09-03,9.2.4
+2022-09-04,9.2.4
+2022-09-05,9.2.4
+2022-09-06,9.2.4
+2022-09-07,9.2.4
+2022-09-08,9.2.4
+2022-09-09,9.2.4
+2022-09-10,9.2.4
+2022-09-11,9.2.4
+2022-09-12,9.2.4
+2022-09-14,9.2.4
+2022-09-15,9.2.4
+2022-09-16,9.2.4
+2022-09-17,9.2.4
+2022-09-19,9.2.4
+2022-09-20,9.2.4
+2022-09-21,9.2.4
+2022-09-22,9.2.4
+2022-09-23,9.2.4
+2022-09-24,9.2.4
+2022-09-25,9.2.4
+2022-09-26,9.2.4
+2022-09-27,9.2.4
+2022-09-28,9.2.4
+2022-09-29,9.2.4
+2022-09-30,9.2.4
+2022-10-05,9.2.4
+2022-10-06,9.2.4
+2022-10-07,9.2.4
+2022-10-08,9.2.4
+2022-10-10,9.2.4
+2022-10-11,9.2.4
+2022-10-17,9.2.4
+2022-10-18,9.2.4
+2022-10-22,9.2.4
+2022-10-23,9.2.4
+2022-10-24,9.2.4
+2022-10-25,9.2.4
+2022-10-26,9.2.4
+2022-10-27,9.2.4
+2022-10-28,9.2.4
+2022-10-29,9.2.4
+2022-10-30,9.2.4
+2022-10-31,9.2.4
+2022-11-01,9.2.4
+2022-11-02,9.2.4
+2022-11-03,9.2.4
+2022-11-04,9.2.4
+2022-11-05,9.2.4
+2022-11-07,9.2.4
+2022-11-08,9.2.4
+2022-11-11,9.2.4
+2022-11-12,9.2.4
+2022-11-14,9.2.5
+2022-11-15,9.2.5
+2022-11-16,9.2.5
+2022-11-17,9.2.5
+2022-11-19,9.4.3
+2022-11-20,9.4.3
+2022-11-21,9.4.3
+2022-11-22,9.4.3
+2022-11-23,9.4.3
+2022-11-24,9.4.3
+2022-11-25,9.4.3
+2022-11-26,9.4.3
+2022-11-28,9.4.3
+2022-11-29,9.4.3
+2022-11-30,9.4.3
+2022-12-01,9.4.3
+2022-12-02,9.4.3
+2022-12-03,9.4.3
+2022-12-04,9.4.3
+2022-12-05,9.4.3
+2022-12-06,9.4.3
+2022-12-07,9.4.3
+2022-12-08,9.4.3
+2022-12-09,9.4.3
+2022-12-12,9.4.3
+2022-12-16,9.4.3
+2022-12-17,9.4.3
+2022-12-21,9.4.3
+2022-12-22,9.4.3
+2022-12-23,9.4.3
+2022-12-25,9.4.3
+2022-12-26,9.4.3
+2023-01-01,9.4.4
+2023-01-02,9.4.4
+2023-01-03,9.4.4
+2023-01-05,9.4.4
+2023-01-06,9.4.4
+2023-01-08,9.4.4
+2023-01-10,9.4.4
+2023-01-11,9.4.4
+2023-01-12,9.4.4
+2023-01-13,9.4.4
+2023-01-14,9.4.4
+2023-01-15,9.4.4
+2023-01-18,9.4.4
+2023-01-20,9.4.4
+2023-01-21,9.4.4
+2023-01-22,9.4.4
+2023-01-23,9.4.4
+2023-01-24,9.4.4
+2023-01-25,9.4.4
+2023-01-28,9.4.4
+2023-01-29,9.4.4
+2023-01-30,9.4.4
+2023-01-31,9.4.4
+2023-02-03,9.4.4
+2023-02-04,9.4.4
+2023-02-05,9.4.4
+2023-02-06,9.4.4
+2023-02-07,9.4.4
+2023-02-08,9.4.4
+2023-02-09,9.4.4
+2023-02-12,9.4.4
+2023-02-13,9.4.4
+2023-02-14,9.4.4
+2023-02-23,9.4.4
+2023-02-27,9.4.4
+2023-03-03,9.4.4
+2023-03-04,9.4.4
+2023-03-05,9.4.4
+2023-03-06,9.4.4
+2023-03-07,9.4.4
+2023-03-08,9.4.4
+2023-03-09,9.4.4
+2023-03-10,9.4.4
+2023-03-11,9.4.4
+2023-03-12,9.4.4
+2023-03-13,9.4.4
+2023-03-14,9.4.4
+2023-03-15,9.4.4
+2023-03-16,9.4.4
+2023-03-17,9.4.4
+2023-03-18,9.4.4
+2023-03-19,9.4.4
+2023-03-20,9.4.4
+2023-03-22,9.4.4
+2023-03-23,9.4.4
+2023-03-24,9.4.4
+2023-03-26,9.4.4
+2023-03-27,9.4.4
+2023-03-28,9.4.4
+2023-03-29,9.4.4
+2023-03-30,9.4.4
+2023-03-31,9.4.4
+2023-04-01,9.4.4
+2023-04-02,9.4.4
+2023-04-03,9.4.4
+2023-04-04,9.4.4
+2023-04-05,9.4.4
+2023-04-09,9.4.4
+2023-04-13,9.4.4
+2023-04-14,9.4.4
+2023-04-15,9.4.4
+2023-04-16,9.4.4
+2023-04-17,9.4.4
+2023-04-18,9.4.4
+2023-04-19,9.4.4
+2023-04-20,9.4.4
+2023-04-21,9.4.4
+2023-04-23,9.4.4
+2023-04-24,9.4.4
+2023-04-25,9.4.5
+2023-04-28,9.4.5
+2023-04-29,9.4.5
+2023-04-30,9.4.5
+2023-05-01,9.4.5
+2023-05-02,9.4.5
+2023-05-03,9.4.5
+2023-05-04,9.4.5
+2023-05-05,9.4.5
+2023-05-06,9.4.5
+2023-05-07,9.4.5
+2023-05-08,9.4.5
+2023-05-10,9.4.5
+2023-05-11,9.4.5
+2023-05-12,9.4.5
+2023-05-13,9.4.5
+2023-05-14,9.4.5
+2023-05-15,9.4.5
+2023-05-16,9.4.5
+2023-05-17,9.4.5
+2023-05-19,9.4.5
+2023-05-20,9.4.5
+2023-05-21,9.4.5
+2023-05-22,9.4.5
+2023-05-23,9.4.5
+2023-05-24,9.4.5
+2023-05-25,9.4.5
+2023-05-26,9.4.5
+2023-05-27,9.4.5
+2023-05-28,9.4.5
+2023-05-29,9.4.5
+2023-05-30,9.4.5
+2023-05-31,9.4.5
+2023-06-03,9.4.5
+2023-06-04,9.4.5
+2023-06-08,9.4.5
+2023-06-10,9.4.5
+2023-06-11,9.4.5
+2023-06-12,9.4.5
+2023-06-13,9.4.5
+2023-06-14,9.4.5
+2023-06-15,9.4.5
+2023-06-16,9.4.5
+2023-06-17,9.4.5
+2023-06-18,9.4.5
+2023-06-19,9.4.5
+2023-06-20,9.4.5
+2023-06-21,9.4.5
+2023-06-22,9.6.2
+2023-06-23,9.6.2
+2023-06-24,9.6.2
+2023-06-25,9.6.2
+2023-06-26,9.6.2
+2023-06-27,9.6.2
+2023-06-29,9.6.2
+2023-06-30,9.6.2
+2023-07-01,9.6.2
+2023-07-03,9.6.2
+2023-07-04,9.6.2
+2023-07-05,9.6.2
+2023-07-06,9.6.2
+2023-07-07,9.6.2
+2023-07-09,9.6.2
+2023-07-10,9.6.2
+2023-07-13,9.6.2
+2023-07-14,9.6.2
+2023-07-15,9.6.2
+2023-07-16,9.6.2
+2023-07-17,9.6.2
+2023-07-18,9.6.2
+2023-07-19,9.6.2
+2023-07-20,9.6.2
+2023-07-21,9.6.2
+2023-07-22,9.6.2
+2023-07-24,9.6.2
+2023-07-25,9.6.2
+2023-07-26,9.6.2
+2023-07-27,9.6.2
+2023-07-28,9.6.2
+2023-07-29,9.6.2
+2023-08-01,9.6.2
+2023-08-02,9.6.2
+2023-08-04,9.6.2
+2023-08-05,9.6.2
+2023-08-06,9.6.2
+2023-08-09,9.6.2
+2023-08-10,9.6.2
+2023-08-11,9.6.2
+2023-08-12,9.6.2
+2023-08-13,9.6.2
+2023-08-14,9.6.2
+2023-08-15,9.6.2
+2023-08-16,9.6.2
+2023-08-17,9.6.2
+2023-08-19,9.6.2
+2023-08-20,9.6.2
+2023-08-21,9.6.2
+2023-08-22,9.6.2
+2023-08-23,9.6.2
+2023-08-24,9.6.2
+2023-08-25,9.6.2
+2023-08-26,9.6.2
+2023-08-27,9.6.2
+2023-08-28,9.6.2
+2023-08-29,9.6.2
+2023-09-03,9.6.2
+2023-09-08,9.6.2
+2023-09-09,9.6.2
+2023-09-13,9.6.2
+2023-09-14,9.6.2
+2023-09-15,9.6.2
+2023-09-16,9.6.2
+2023-09-17,9.6.2
+2023-09-18,9.6.2
+2023-09-19,9.6.2
+2023-09-20,9.6.2
+2023-09-21,9.6.2
+2023-09-22,9.6.2
+2023-09-24,9.6.2
+2023-09-25,9.6.2
+2023-09-26,9.6.2
+2023-09-27,9.6.2
+2023-09-30,9.6.2
+2023-10-01,9.6.3
+2023-10-02,9.6.3
+2023-10-03,9.6.3
+2023-10-04,9.6.3
+2023-10-09,9.6.3
+2023-10-13,9.6.3
+2023-10-14,9.6.3
+2023-10-15,9.6.3
+2023-10-16,9.6.3
+2023-10-17,9.6.3
+2023-10-18,9.6.3
+2023-10-19,9.6.3
+2023-10-20,9.6.3
+2023-10-21,9.6.3
+2023-10-22,9.6.3
+2023-10-23,9.6.3
+2023-10-24,9.6.3
+2023-10-25,9.6.3
+2023-10-26,9.6.3
+2023-10-27,9.6.3
+2023-10-28,9.6.3
+2023-10-29,9.6.3
+2023-10-30,9.6.3
+2023-10-31,9.6.3
+2023-11-01,9.6.3
+2023-11-02,9.6.3
+2023-11-03,9.6.3
+2023-11-04,9.6.3
+2023-11-05,9.6.3
+2023-11-06,9.6.3
+2023-11-07,9.6.3
+2023-11-08,9.6.3
+2023-11-09,9.6.3
+2023-11-10,9.6.3
+2023-11-13,9.6.3
+2023-11-14,9.6.3
+2023-11-15,9.6.3
+2023-11-16,9.6.3
+2023-11-17,9.6.3
+2023-11-18,9.6.3
+2023-11-19,9.6.3
+2023-11-20,9.6.3
+2023-11-21,9.6.3
+2023-11-22,9.6.3
+2023-11-23,9.6.3
+2023-11-24,9.6.3
+2023-11-25,9.6.3
+2023-11-26,9.6.3
+2023-11-27,9.6.3
+2023-11-28,9.6.3
+2023-11-29,9.6.3
+2023-11-30,9.6.3
+2023-12-01,9.6.3
+2023-12-02,9.6.3
+2023-12-03,9.6.3
+2023-12-04,9.6.3
+2023-12-05,9.6.3
+2023-12-06,9.6.3
+2023-12-07,9.6.3
+2023-12-08,9.6.3
+2023-12-09,9.6.3
+2023-12-10,9.6.3
+2023-12-11,9.6.3
+2023-12-12,9.6.3
+2023-12-13,9.6.3
+2023-12-14,9.6.3
+2023-12-15,9.6.3
+2023-12-16,9.6.3
+2023-12-17,9.6.3
+2023-12-18,9.6.3
+2023-12-19,9.6.3
+2023-12-22,9.6.3
+2023-12-23,9.6.3
+2023-12-25,9.6.3
+2023-12-26,9.6.3
+2023-12-27,9.8.1
+2023-12-28,9.8.1
+2023-12-29,9.8.1
+2023-12-30,9.8.1
+2023-12-31,9.8.1
+2024-01-01,9.8.1
+2024-01-02,9.8.1
+2024-01-03,9.8.1
+2024-01-04,9.8.1
+2024-01-05,9.8.1
+2024-01-06,9.8.1
+2024-01-07,9.8.1
+2024-01-08,9.8.1
+2024-01-09,9.8.1
+2024-01-10,9.8.1
+2024-01-11,9.8.1
+2024-01-12,9.8.1
+2024-01-13,9.8.1
+2024-01-14,9.8.1
+2024-01-15,9.8.1
+2024-01-16,9.8.1
+2024-01-17,9.8.1
+2024-01-19,9.8.1
+2024-01-20,9.8.1
+2024-01-21,9.8.1
+2024-01-22,9.8.1
+2024-01-23,9.8.1
+2024-01-26,9.8.1
+2024-01-29,9.8.1
+2024-01-30,9.8.1
+2024-01-31,9.8.1
+2024-02-01,9.8.1
+2024-02-02,9.8.1
+2024-02-03,9.8.1
+2024-02-04,9.8.1
+2024-02-05,9.8.1
+2024-02-06,9.8.1
+2024-02-07,9.8.1
+2024-02-08,9.8.1
+2024-02-09,9.8.1
+2024-02-10,9.8.1
+2024-02-11,9.8.1
+2024-02-12,9.8.1
+2024-02-15,9.8.1
+2024-02-16,9.8.1
+2024-02-17,9.8.1
+2024-02-18,9.8.1
+2024-02-19,9.8.1
+2024-02-20,9.8.1
+2024-02-21,9.8.1
+2024-02-22,9.8.1
+2024-02-24,9.8.1
+2024-02-25,9.8.1
+2024-02-26,9.8.1
+2024-02-27,9.8.1
+2024-02-28,9.8.1
+2024-02-29,9.8.1
+2024-03-01,9.8.1
+2024-03-05,9.8.1
+2024-03-06,9.8.1
+2024-03-07,9.8.1
+2024-03-08,9.8.2
+2024-03-10,9.8.2
+2024-03-11,9.8.2
+2024-03-12,9.8.2
+2024-03-13,9.8.2
+2024-03-14,9.8.2
+2024-03-19,9.8.2
+2024-03-20,9.8.2
+2024-03-23,9.8.2
+2024-03-24,9.8.2
+2024-03-26,9.8.2
+2024-03-27,9.8.2
+2024-03-28,9.8.2
+2024-03-29,9.8.2
+2024-03-30,9.8.2
+2024-03-31,9.8.2
+2024-04-01,9.8.2
+2024-04-02,9.8.2
+2024-04-03,9.8.2
+2024-04-04,9.8.2
+2024-04-05,9.8.2
+2024-04-06,9.8.2
+2024-04-07,9.8.2
+2024-04-08,9.8.2
+2024-04-10,9.8.2
+2024-04-11,9.8.2
+2024-04-12,9.8.2
+2024-04-14,9.8.2
+2024-04-17,9.8.2
+2024-04-18,9.8.2
+2024-04-19,9.8.2
+2024-04-20,9.8.2
+2024-04-21,9.8.2
+2024-04-22,9.8.2
+2024-04-24,9.8.2
+2024-04-25,9.8.2
+2024-04-26,9.8.2
+2024-04-27,9.8.2
+2024-04-29,9.8.2
+2024-04-30,9.8.2
+2024-05-01,9.8.2
+2024-05-02,9.8.2
+2024-05-03,9.8.2
+2024-05-04,9.8.2
+2024-05-05,9.8.2
+2024-05-06,9.8.2
+2024-05-10,9.8.2
+2024-05-11,9.8.2
+2024-05-13,9.8.2
+2024-05-14,9.8.2
+2024-05-15,9.8.2
+2024-05-16,9.8.2
+2024-05-18,9.8.2
+2024-05-19,9.8.2
+2024-05-20,9.8.2
+2024-05-21,9.8.2
+2024-05-22,9.8.2
+2024-05-23,9.8.2
+2024-05-24,9.8.2
+2024-05-25,9.8.2
+2024-05-26,9.8.2
+2024-05-27,9.8.2
+2024-05-28,9.8.2
+2024-05-29,9.8.2
+2024-05-30,9.8.2
+2024-05-31,9.8.2
+2024-06-01,9.8.2
+2024-06-02,9.8.2
+2024-06-03,9.8.2
+2024-06-04,9.8.2
+2024-06-07,9.8.2
+2024-06-08,9.8.2
+2024-06-09,9.8.2
+2024-06-10,9.8.2
+2024-06-12,9.8.2
+2024-06-13,9.8.2
+2024-06-14,9.8.2
+2024-06-15,9.8.2
+2024-06-16,9.8.2
+2024-06-17,9.8.2
+2024-06-18,9.8.2
+2024-06-19,9.8.2
+2024-06-20,9.8.2
+2024-06-21,9.8.2
+2024-06-22,9.8.2
+2024-06-28,9.8.2
+2024-06-30,9.8.2
+2024-07-01,9.8.2
+2024-07-02,9.8.2
+2024-07-03,9.8.2
+2024-07-04,9.8.2
+2024-07-05,9.8.2
+2024-07-08,9.8.2
+2024-07-09,9.8.2
+2024-07-11,9.8.2
+2024-07-12,9.8.2
+2024-07-13,9.8.2
+2024-07-15,9.8.2
+2024-07-16,9.8.2
+2024-07-17,9.8.2
+2024-07-18,9.8.2
+2024-07-19,9.8.2
+2024-07-20,9.8.2
+2024-07-21,9.8.2
+2024-07-22,9.8.2
+2024-07-23,9.8.2
+2024-07-24,9.8.2
+2024-07-25,9.8.2
+2024-07-26,9.8.2
+2024-07-27,9.8.2
+2024-07-28,9.8.2
+2024-07-29,9.8.2
+2024-07-30,9.8.2
+2024-08-02,9.8.2
+2024-08-08,9.8.2
+2024-08-09,9.8.2
+2024-08-10,9.8.2
+2024-08-11,9.8.2
+2024-08-12,9.8.2
+2024-08-13,9.8.2
+2024-08-16,9.8.2
+2024-08-17,9.8.2
+2024-08-18,9.8.2
+2024-08-19,9.8.2
+2024-08-20,9.8.2
+2024-08-21,9.8.2
+2024-08-22,9.8.2
+2024-08-23,9.8.2
+2024-08-24,9.8.2
+2024-08-25,9.8.2
+2024-08-26,9.8.2
+2024-09-02,9.8.2
+2024-09-03,9.8.2
+2024-09-04,9.8.2
+2024-09-07,9.8.2
+2024-09-08,9.8.2
+2024-09-09,9.8.2
+2024-09-10,9.8.2
+2024-09-11,9.8.2
+2024-09-12,9.8.2
+2024-09-13,9.8.2
+2024-09-14,9.8.2
+2024-09-15,9.8.2
+2024-09-16,9.8.2
+2024-09-17,9.8.2
+2024-09-18,9.8.2
+2024-09-19,9.8.2
+2024-09-20,9.8.2
+2024-09-22,9.8.2
+2024-09-23,9.8.2
+2024-09-24,9.8.2
+2024-09-25,9.8.2
+2024-09-26,9.8.2
+2024-09-29,9.8.2
+2024-09-30,9.8.2
+2024-10-01,9.8.2
+2024-10-02,9.8.2
+2024-10-03,9.8.2
+2024-10-04,9.8.2
+2024-10-05,9.8.2
+2024-10-06,9.8.2
+2024-10-07,9.8.2
+2024-10-08,9.8.2
+2024-10-09,9.8.2
+2024-10-10,9.8.2
+2024-10-11,9.8.2
+2024-10-21,9.8.2
+2024-10-22,9.8.3
+2024-10-23,9.8.3
+2024-10-24,9.8.3
+2024-10-25,9.8.3
+2024-10-26,9.8.3
+2024-10-27,9.8.3
+2024-10-28,9.8.3
+2024-10-29,9.8.3
+2024-10-30,9.8.3
+2024-10-31,9.8.3
+2024-11-01,9.8.3
+2024-11-02,9.8.3
+2024-11-03,9.8.3
+2024-11-04,9.8.3
+2024-11-05,9.8.3
+2024-11-06,9.8.3
+2024-11-07,9.8.3
+2024-11-08,9.8.3
+2024-11-09,9.8.3
+2024-11-10,9.8.3
+2024-11-11,9.8.3
+2024-11-12,9.8.3
+2024-11-18,9.8.3
+2024-11-19,9.8.3
+2024-11-20,9.8.3
+2024-11-21,9.8.3
+2024-11-22,9.8.3
+2024-11-23,9.8.3
+2024-11-24,9.8.3
+2024-11-25,9.8.3
+2024-11-26,9.8.3
+2024-11-27,9.8.3
+2024-11-28,9.8.3
+2024-11-29,9.8.3
+2024-11-30,9.8.3
+2024-12-03,9.8.3
+2024-12-04,9.8.3
+2024-12-05,9.8.4
+2024-12-07,9.8.4
+2024-12-08,9.8.4
+2024-12-09,9.8.4
+2024-12-11,9.10.1
+2024-12-12,9.10.1
+2024-12-13,9.10.1
+2024-12-15,9.10.1
+2024-12-16,9.10.1
+2024-12-17,9.10.1
+2024-12-18,9.10.1
+2024-12-19,9.10.1
+2024-12-20,9.10.1
+2024-12-21,9.10.1
+2024-12-22,9.10.1
+2024-12-23,9.10.1
+2024-12-24,9.10.1
+2024-12-25,9.10.1
+2024-12-26,9.10.1
+2024-12-27,9.10.1
+2024-12-28,9.10.1
+2024-12-29,9.10.1
+2024-12-30,9.10.1
+2024-12-31,9.10.1
+2025-01-01,9.10.1
+2025-01-02,9.10.1
+2025-01-03,9.10.1
+2025-01-04,9.10.1
+2025-01-05,9.10.1
+2025-01-06,9.10.1
+2025-01-08,9.10.1
+2025-01-10,9.10.1
+2025-01-11,9.10.1
+2025-01-12,9.10.1
+2025-01-13,9.10.1
+2025-01-14,9.10.1
+2025-01-15,9.10.1
+2025-01-16,9.10.1
+2025-01-17,9.10.1
+2025-01-18,9.10.1
+2025-01-19,9.10.1
+2025-01-20,9.10.1
+2025-01-21,9.10.1
+2025-01-23,9.10.1
+2025-01-25,9.10.1
+2025-01-27,9.10.1
+2025-01-29,9.10.1
+2025-01-30,9.10.1
+2025-01-31,9.10.1
+2025-02-01,9.10.1
+2025-02-02,9.10.1
+2025-02-03,9.10.1
+2025-02-04,9.10.1
+2025-02-05,9.10.1
+2025-02-06,9.10.1
+2025-02-07,9.10.1
+2025-02-08,9.10.1
+2025-02-09,9.10.1
+2025-02-10,9.10.1
+2025-02-11,9.10.1
+2025-02-12,9.10.1
+2025-02-13,9.10.1
+2025-02-14,9.10.1
+2025-02-15,9.10.1
+2025-02-16,9.10.1
+2025-02-17,9.10.1
+2025-02-18,9.10.1
+2025-02-19,9.10.1
+2025-02-20,9.10.1
+2025-02-23,9.10.1
+2025-02-24,9.10.1
+2025-02-25,9.10.1
+2025-02-26,9.10.1
+2025-02-27,9.10.1
+2025-02-28,9.10.1
+2025-03-01,9.10.1
+2025-03-05,9.10.1
+2025-03-06,9.10.1
+2025-03-07,9.10.1
+2025-03-09,9.10.1
+2025-03-10,9.10.1
+2025-03-11,9.10.1
+2025-03-13,9.10.1
+2025-03-14,9.10.1
+2025-03-15,9.10.1
+2025-03-16,9.10.1
+2025-03-17,9.10.1
+2025-03-19,9.10.1
+2025-03-20,9.10.1
+2025-03-22,9.10.1
+2025-03-23,9.10.1
+2025-03-24,9.10.1
+2025-03-25,9.10.1
+2025-03-26,9.10.1
+2025-03-27,9.10.1
+2025-03-28,9.10.1
+2025-03-29,9.10.1
+2025-03-30,9.10.1
+2025-03-31,9.10.1
+2025-04-01,9.10.1
+2025-04-02,9.10.1
+2025-04-03,9.10.1
+2025-04-04,9.10.1
+2025-04-05,9.10.1
+2025-04-06,9.10.1
+2025-04-07,9.10.1
+2025-04-08,9.10.1
+2025-04-09,9.10.1
+2025-04-10,9.10.1
+2025-04-11,9.10.1
+2025-04-12,9.10.1
+2025-04-13,9.10.1
+2025-04-14,9.10.1
+2025-04-15,9.10.1
+2025-04-16,9.10.1
+2025-04-17,9.10.1
+2025-04-18,9.10.1
+2025-04-19,9.10.1
+2025-04-20,9.10.1
+2025-04-21,9.10.1
+2025-04-22,9.10.1
+2025-04-23,9.10.1
+2025-04-24,9.10.1
+2025-04-30,9.10.1
+2025-05-01,9.10.1
+2025-05-02,9.10.1
+2025-05-03,9.10.1
+2025-05-04,9.10.1
+2025-05-05,9.10.1
+2025-05-06,9.10.2
+2025-05-07,9.10.2
+2025-05-08,9.10.2
+2025-05-09,9.10.2
+2025-05-10,9.10.2
+2025-05-11,9.10.2
+2025-05-13,9.10.2
+2025-05-14,9.10.2
+2025-05-15,9.10.2
+2025-05-16,9.10.2
+2025-05-17,9.10.2
+2025-05-18,9.10.2
+2025-05-19,9.10.2
+2025-05-20,9.10.2
+2025-05-21,9.10.2
+2025-05-22,9.10.2
+2025-05-23,9.10.2
+2025-05-24,9.10.2
+2025-05-25,9.10.2
+2025-05-26,9.10.2
+2025-05-27,9.10.2
+2025-05-28,9.10.2
+2025-06-11,9.10.2
+2025-06-12,9.10.2
+2025-06-13,9.10.2
+2025-06-14,9.10.2
+2025-06-15,9.10.2
+2025-06-16,9.10.2
+2025-06-17,9.10.2
+2025-06-18,9.10.2
+2025-06-29,9.10.2
+2025-07-01,9.10.2
+2025-07-02,9.10.2
+2025-07-03,9.10.2
+2025-07-04,9.10.2
+2025-07-05,9.10.2
+2025-07-06,9.10.2
+2025-07-07,9.10.2
+2025-07-08,9.10.2
+2025-07-09,9.10.2
+2025-07-10,9.10.2
+2025-07-11,9.10.2
+2025-07-12,9.10.2
+2025-07-13,9.10.2
+2025-07-14,9.10.2
+2025-07-15,9.12.2
+2025-07-16,9.12.2
+2025-07-17,9.12.2
+2025-07-18,9.12.2
+2025-07-19,9.12.2
+2025-07-20,9.12.2
+2025-07-21,9.12.2
+2025-07-22,9.12.2
+2025-07-23,9.12.2
+2025-07-24,9.12.2
+2025-07-25,9.12.2
+2025-07-26,9.12.2
+2025-07-28,9.12.2
+2025-07-29,9.12.2
+2025-07-30,9.12.2
+2025-07-31,9.12.2
+2025-08-01,9.12.2
+2025-08-02,9.12.2
+2025-08-03,9.12.2
+2025-08-04,9.12.2
+2025-08-05,9.12.2
+2025-08-06,9.12.2
+2025-08-07,9.12.2
+2025-08-08,9.12.2
+2025-08-11,9.12.2
+2025-08-12,9.12.2
+2025-08-13,9.12.2
+2025-08-14,9.12.2
+2025-08-15,9.12.2
+2025-08-16,9.12.2
+2025-08-17,9.12.2
+2025-08-18,9.12.2
+2025-08-19,9.12.2
+2025-08-20,9.12.2
+2025-08-21,9.12.2
+2025-08-22,9.12.2
+2025-08-23,9.12.2
+2025-08-27,9.12.2
+2025-08-28,9.12.2
+2025-08-29,9.12.2
+2025-08-30,9.12.2
+2025-08-31,9.12.2
+2025-09-01,9.12.2
+2025-09-02,9.12.2
+2025-09-03,9.12.2
+2025-09-04,9.12.2
+2025-09-05,9.12.2
+2025-09-06,9.12.2
+2025-09-09,9.12.2
+2025-09-10,9.12.2
+2025-09-11,9.12.2
+2025-09-12,9.12.2
+2025-09-13,9.12.2
+2025-09-14,9.12.2
+2025-09-15,9.12.2
+2025-09-16,9.12.2
+2025-09-18,9.12.2
+2025-09-19,9.12.2
+2025-09-20,9.12.2
+2025-09-21,9.12.2
+2025-09-22,9.12.2
+2025-09-23,9.12.2
+2025-09-24,9.12.2
+2025-09-25,9.12.2
+2025-09-26,9.12.2
+2025-09-28,9.12.2
+2025-09-29,9.12.2
+2025-09-30,9.12.2
+2025-10-01,9.12.2
+2025-10-02,9.12.2
+2025-10-04,9.12.2
+2025-10-05,9.12.2
+2025-10-06,9.12.2
+2025-10-07,9.12.2
+2025-10-08,9.12.2
+2025-10-09,9.12.2
+2025-10-10,9.12.2
+2025-10-11,9.12.2
+2025-10-12,9.12.2
+2025-10-13,9.12.2
+2025-10-14,9.12.2
+2025-10-15,9.12.2
+2025-10-16,9.12.2
+2025-10-17,9.12.2
+2025-10-18,9.12.2
+2025-10-19,9.12.2
+2025-10-20,9.12.2
+2025-10-21,9.12.2
+2025-10-22,9.12.2
+2025-10-23,9.12.2
+2025-10-24,9.12.2
+2025-10-25,9.12.2
+2025-10-26,9.12.2
+2025-10-29,9.12.2
+2025-10-30,9.12.2
+2025-10-31,9.12.2
+2025-11-01,9.12.2
+2025-11-03,9.12.2
+2025-11-04,9.12.2
+2025-11-06,9.12.2
+2025-11-07,9.12.2
+2025-11-08,9.12.2
+2025-11-09,9.12.2
+2025-11-10,9.12.2
+2025-11-11,9.12.2
+2025-11-12,9.12.2
+2025-11-13,9.12.2
+2025-11-14,9.12.2
+2025-11-15,9.12.2
+2025-11-16,9.12.2
+2025-11-17,9.12.2
+2025-11-18,9.12.2
+2025-11-19,9.12.2
+2025-11-21,9.12.2
+2025-11-22,9.12.2
+2025-11-23,9.12.2
+2025-11-24,9.12.2
+2025-11-25,9.12.2
+2025-11-26,9.12.2
+2025-11-27,9.12.2
+2025-11-28,9.12.2
+2025-11-29,9.12.2
+2025-11-30,9.12.2
+2025-12-01,9.12.2
+2025-12-02,9.12.2
+2025-12-03,9.12.2
+2025-12-04,9.12.2
+2025-12-05,9.12.2
+2025-12-06,9.12.2
+2025-12-07,9.12.2
+2025-12-08,9.12.2
+2025-12-09,9.12.2
+2025-12-10,9.12.2
+2025-12-14,9.12.2
+2025-12-15,9.12.2
+2025-12-16,9.12.2
+2025-12-17,9.12.2
+2025-12-18,9.12.2
+2025-12-19,9.12.2
+2025-12-20,9.12.2
+2025-12-21,9.12.2
+2025-12-22,9.12.2
+2025-12-23,9.12.2
+2025-12-24,9.12.2
+2025-12-25,9.12.2
+2025-12-26,9.12.2
+2025-12-28,9.12.2
+2025-12-29,9.12.2
+2025-12-30,9.12.2
+2025-12-31,9.12.3
+2026-01-01,9.12.3
+2026-01-02,9.12.3
+2026-01-03,9.12.3
+2026-01-04,9.12.3
+2026-01-05,9.12.3
+2026-01-06,9.12.3
+2026-01-07,9.12.3
+2026-01-08,9.12.3
+2026-01-09,9.12.3
+2026-01-10,9.12.3
+2026-01-11,9.12.3
+2026-01-12,9.12.3
+2026-01-13,9.12.3
+2026-01-14,9.12.3
+2026-01-15,9.12.3
+2026-01-16,9.12.3
+2026-01-17,9.12.3
+2026-01-18,9.12.3
+2026-01-19,9.12.3
+2026-01-20,9.12.3
+2026-01-21,9.12.3
+2026-01-22,9.12.3
+2026-01-23,9.12.3
+2026-01-24,9.12.3
+2026-01-25,9.12.3
+2026-01-26,9.12.3
+2026-02-05,9.12.3
+2026-02-06,9.12.3
+2026-02-07,9.12.3
+2026-02-08,9.12.3
+2026-02-09,9.12.3
+2026-02-10,9.12.3
+2026-02-14,9.12.3
+2026-02-15,9.12.3
+2026-02-16,9.12.3
+2026-02-17,9.12.3
+2026-02-18,9.12.3
+2026-02-19,9.12.3
+2026-02-20,9.12.3
+2026-02-21,9.12.3
+2026-02-22,9.12.3
+2026-02-23,9.12.3
+2026-02-24,9.12.3
+2026-02-27,9.12.3
+2026-03-02,9.12.3
+2026-03-03,9.12.3
+2026-03-04,9.12.3
+2026-03-05,9.12.3
+2026-03-06,9.12.3
+2026-03-07,9.12.3
+2026-03-08,9.12.3
+2026-03-09,9.12.3
+2026-03-10,9.12.3
+2026-03-11,9.12.3
+2026-03-12,9.12.3
+2026-03-13,9.12.3
+2026-03-14,9.12.3
+2026-03-15,9.12.3
+2026-03-16,9.12.3
+2026-03-17,9.12.3
+2026-03-18,9.12.3
+2026-03-19,9.12.3
+2026-03-20,9.12.3
+2026-03-22,9.12.3
+2026-03-23,9.12.3
+2026-03-24,9.12.3
+2026-03-25,9.12.3
+2026-03-27,9.12.3
+2026-03-28,9.12.3
+2026-03-29,9.12.4
+2026-03-30,9.12.4
+2026-03-31,9.12.4
+2026-04-01,9.12.4
+2026-04-02,9.12.4
+2026-04-03,9.12.4
+2026-04-04,9.12.4
+2026-04-05,9.12.4
+2026-04-06,9.12.4
+2026-04-07,9.12.4
diff --git a/src/Analysis.hs b/src/Analysis.hs
new file mode 100644
--- /dev/null
+++ b/src/Analysis.hs
@@ -0,0 +1,134 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Analysis
+  ( analyzeStackYaml
+  , analyzeAllStackYamls
+  , analyzeStackYamls
+  ) where
+
+import Prelude hiding (min, span)
+
+import Control.Monad (filterM)
+import Data.Functor ((<&>))
+import Data.List (maximumBy)
+import Data.Map.Strict qualified as Map
+import Data.Maybe (catMaybes)
+import Data.Ord (comparing)
+import Data.Text (Text)
+import Data.Text qualified as T
+import System.Directory (doesFileExist)
+import Text.Printf (printf)
+
+import Types (Action(..), SnapshotDB(..), LTSVersion(..), NightlyVersion(..), GHCVersion(..), Snapshot(..))
+import StackYaml (parseStackYaml, findStackYamlFiles, findStackYamlFilesRecursive, getSymlinkMap)
+
+-- | Analyze a single stack.yaml file
+analyzeStackYaml :: SnapshotDB -> Map.Map FilePath FilePath -> FilePath -> IO (Maybe Action)
+analyzeStackYaml db symlinkMap file = do
+  -- Check if this file is a symlink to another stack*.yaml file in our list
+  let symlinkTarget = Map.lookup file symlinkMap
+
+  parseStackYaml file <&> \case
+    Nothing -> Nothing
+    Just (oldSnap, isResolver, span) -> do
+      let newSnap = determineNewSnapshot db oldSnap
+      Just $ Action file oldSnap newSnap isResolver span symlinkTarget
+
+-- | Analyze specific stack*.yaml files, or all if empty list
+-- If recursive is True, search recursively in all subdirectories
+analyzeStackYamls :: SnapshotDB -> [FilePath] -> Bool -> IO [Action]
+analyzeStackYamls db files recursive = do
+  -- Get files to analyze: either auto-discover or use provided list
+  -- Non-existent files are silently filtered out
+  filesToAnalyze <- 
+    if null files 
+      then if recursive
+           then findStackYamlFilesRecursive
+           else findStackYamlFiles
+      else filterM doesFileExist files
+  symlinkMap <- getSymlinkMap filesToAnalyze
+  results <- mapM (analyzeStackYaml db symlinkMap) filesToAnalyze
+  return $ catMaybes results
+
+-- | Analyze all stack*.yaml files in the current directory
+analyzeAllStackYamls :: SnapshotDB -> IO [Action]
+analyzeAllStackYamls db = analyzeStackYamls db [] False
+
+-- | Determine the new snapshot for a given old snapshot
+determineNewSnapshot :: SnapshotDB -> Text -> Maybe Text
+determineNewSnapshot db oldSnap
+  | T.isPrefixOf "lts-" oldSnap = determineLTSBump db oldSnap
+  | T.isPrefixOf "nightly-" oldSnap = determineNightlyBump db oldSnap
+  | otherwise = Nothing
+
+-- | Determine bump for LTS snapshot
+determineLTSBump :: SnapshotDB -> Text -> Maybe Text
+determineLTSBump db oldSnap = do
+  oldVersion <- parseLTSSnapshot oldSnap
+  -- Find the latest LTS with the same major version
+  let sameMajor = filter (\(LTSVersion maj _, _) -> maj == ltsMajor oldVersion) $ Map.toList (dbLTS db)
+  if null sameMajor
+    then Nothing
+    else do
+      let (latestVersion, _) = maximumBy (comparing fst) sameMajor
+      let newSnap = formatSnapshot (LTS latestVersion)
+      if newSnap == oldSnap
+        then Nothing  -- Already up to date
+        else Just newSnap
+
+-- | Determine bump for nightly snapshot
+determineNightlyBump :: SnapshotDB -> Text -> Maybe Text
+determineNightlyBump db oldSnap = do
+  oldVersion <- parseNightlySnapshot oldSnap
+  oldGHC <- Map.lookup oldVersion (dbNightly db)
+  -- Get GHC major version (e.g., (9,6) from GHCVersion 9 6 1)
+  let ghcMajor = getGHCMajor oldGHC
+  -- Find if there's an LTS for this GHC major version
+  let ltsForGHC = filter (\(_, ghc) -> getGHCMajor ghc == ghcMajor) $ Map.toList (dbLTS db)
+  if not (null ltsForGHC)
+    then do
+      -- Bump to latest LTS for this GHC major
+      let (latestLTS, _) = maximumBy (comparing fst) ltsForGHC
+      return $ formatSnapshot (LTS latestLTS)
+    else do
+      -- Bump to latest nightly for this GHC major
+      let nightliesForGHC = filter (\(_, ghc) -> getGHCMajor ghc == ghcMajor) $ Map.toList (dbNightly db)
+      if null nightliesForGHC
+        then Nothing
+        else do
+          let (latestNightly, _) = maximumBy (comparing fst) nightliesForGHC
+          let newSnap = formatSnapshot (Nightly latestNightly)
+          if newSnap == oldSnap
+            then Nothing
+            else Just newSnap
+
+-- | Get GHC major version from full version (e.g., (9,6) from GHCVersion 9 6 1)
+getGHCMajor :: GHCVersion -> (Int, Int)
+getGHCMajor (GHCVersion maj1 maj2 _) = (maj1, maj2)
+
+-- | Parse LTS snapshot string
+parseLTSSnapshot :: Text -> Maybe LTSVersion
+parseLTSSnapshot snap =
+  case T.splitOn "." (T.drop 4 snap) of  -- Remove "lts-"
+    [majStr, minStr] ->
+      case (reads $ T.unpack majStr, reads $ T.unpack minStr) of
+        ([(maj, "")], [(min, "")]) -> Just $ LTSVersion maj min
+        _ -> Nothing
+    _ -> Nothing
+
+-- | Parse nightly snapshot string
+parseNightlySnapshot :: Text -> Maybe NightlyVersion
+parseNightlySnapshot snap =
+  case T.splitOn "-" (T.drop 8 snap) of  -- Remove "nightly-"
+    [yearStr, monthStr, dayStr] ->
+      case (reads $ T.unpack yearStr, reads $ T.unpack monthStr, reads $ T.unpack dayStr) of
+        ([(year, "")], [(month, "")], [(day, "")]) -> Just $ NightlyVersion year month day
+        _ -> Nothing
+    _ -> Nothing
+
+-- | Format a snapshot as a string
+formatSnapshot :: Snapshot -> Text
+formatSnapshot (LTS (LTSVersion maj min)) =
+  "lts-" <> T.pack (show maj) <> "." <> T.pack (show min)
+formatSnapshot (Nightly (NightlyVersion year month day)) =
+  T.pack $ "nightly-" ++ printf "%d-%02d-%02d" year month day
diff --git a/src/CSV.hs b/src/CSV.hs
new file mode 100644
--- /dev/null
+++ b/src/CSV.hs
@@ -0,0 +1,322 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module CSV
+  ( generateCSVs
+  , loadSnapshotDB
+  , ensureCSVFiles
+  ) where
+
+import Prelude hiding (lines, min)
+
+import Control.Monad (unless)
+import Data.List (sortBy, sortOn)
+import Data.Map.Strict (Map)
+import Data.Map.Strict qualified as Map
+import Data.Ord (comparing)
+import Data.Text (Text)
+import Data.Text qualified as T
+import Data.Text.IO qualified as TIO
+import System.Directory (listDirectory, doesFileExist, createDirectoryIfMissing)
+import System.FilePath (takeExtension)
+import PathUtil ((</>))
+import Data.Yaml qualified as Yaml
+import Data.Yaml ((.:))
+import Data.Aeson qualified as Aeson
+import Text.Printf (printf)
+import Types (LTSVersion(..), NightlyVersion(..), GHCVersion(..), Snapshot(..), SnapshotDB(..))
+import XDG (getStateDir)
+import System.IO (stderr)
+import Paths_stacker (getDataDir)
+import System.Directory qualified as Dir
+
+-- Helper functions for parsing
+parseGHCVersionText :: Text -> Maybe GHCVersion
+parseGHCVersionText txt =
+  case T.splitOn "." txt of
+    [maj1Str, maj2Str, minStr] ->
+      case (reads $ T.unpack maj1Str, reads $ T.unpack maj2Str, reads $ T.unpack minStr) of
+        ([(maj1, "")], [(maj2, "")], [(minV, "")]) -> Just $ GHCVersion maj1 maj2 minV
+        _ -> Nothing
+    _ -> Nothing
+
+parseNightlyVersionText :: Text -> Maybe NightlyVersion
+parseNightlyVersionText txt =
+  case T.splitOn "-" txt of
+    [yearStr, monthStr, dayStr] ->
+      case (reads $ T.unpack yearStr, reads $ T.unpack monthStr, reads $ T.unpack dayStr) of
+        ([(year, "")], [(month, "")], [(day, "")]) -> Just $ NightlyVersion year month day
+        _ -> Nothing
+    _ -> Nothing
+
+-- Helper functions for formatting
+formatGHCVersion :: GHCVersion -> Text
+formatGHCVersion (GHCVersion maj1 maj2 minV) =
+  T.pack $ show maj1 ++ "." ++ show maj2 ++ "." ++ show minV
+
+formatNightlyVersion :: NightlyVersion -> Text
+formatNightlyVersion (NightlyVersion year month day) =
+  T.pack $ printf "%d-%02d-%02d" year month day
+
+-- | Ensure CSV files exist in state directory, copying from data directory if needed
+ensureCSVFiles :: IO ()
+ensureCSVFiles = do
+  stateDir <- getStateDir
+  createDirectoryIfMissing True stateDir
+
+  dataDir <- getDataDir
+
+  -- Check if any CSV file is missing
+  ghcExists <- doesFileExist (stateDir </> "ghc.csv")
+  ltsExists <- doesFileExist (stateDir </> "lts.csv")
+  nightlyExists <- doesFileExist (stateDir </> "nightly.csv")
+
+  unless (ghcExists && ltsExists && nightlyExists) $ do
+    TIO.hPutStrLn stderr "Copying CSV files from data directory..."
+    -- Copy all three CSV files from data directory
+    Dir.copyFile (dataDir </> "ghc.csv") (stateDir </> "ghc.csv")
+    Dir.copyFile (dataDir </> "lts.csv") (stateDir </> "lts.csv")
+    Dir.copyFile (dataDir </> "nightly.csv") (stateDir </> "nightly.csv")
+
+-- | Generate CSV files from the stackage-snapshots repository
+generateCSVs :: FilePath -> IO ()
+generateCSVs repoPath = do
+  stateDir <- getStateDir
+  createDirectoryIfMissing True stateDir
+
+  TIO.hPutStrLn stderr $ "Processing snapshot database.  This might take a couple of minutes..."
+
+  -- Process LTS snapshots
+  TIO.hPutStrLn stderr $ "Processing LTSs..."
+  ltsMap <- processLTSSnapshots (repoPath </> "lts")
+  writeLTSCSV (stateDir </> "lts.csv") ltsMap
+
+  -- Process nightly snapshots
+  TIO.hPutStrLn stderr $ "Processing nightlys..."
+  nightlyMap <- processNightlySnapshots (repoPath </> "nightly")
+  writeNightlyCSV (stateDir </> "nightly.csv") nightlyMap
+
+  -- Generate GHC version map
+  TIO.hPutStrLn stderr $ "Computing latest snapshot per GHC version..."
+  let ghcMap = generateGHCMap ltsMap nightlyMap
+  writeGHCCSV (stateDir </> "ghc.csv") ghcMap
+
+  TIO.hPutStrLn stderr $ "Done processing snapshot database."
+
+-- | Process LTS snapshots (structure: lts/major/minor.yaml)
+processLTSSnapshots :: FilePath -> IO [(LTSVersion, GHCVersion)]
+processLTSSnapshots ltsDir = do
+  majorDirs <- listDirectory ltsDir
+  let sortedMajors = sortOn (\s -> read s :: Int) $ filter (all (`elem` ("0123456789" :: String))) majorDirs
+  concat <$> mapM (processMajor ltsDir) sortedMajors
+  where
+    processMajor dir majorStr = do
+      case reads majorStr of
+        [(major, "")] -> do
+          let majorPath = dir </> majorStr
+          minorFiles <- listDirectory majorPath
+          let sortedMinors = sortOn (\s -> read (take (length s - 5) s) :: Int) $
+                             filter (\s -> takeExtension s == ".yaml") minorFiles
+          mapM (processMinor majorPath major) sortedMinors
+        _ -> return []
+    processMinor dir major fname
+      | takeExtension fname == ".yaml" = do
+          let minorStr = take (length fname - 5) fname
+          case reads minorStr of
+            [(minor, "")] -> do
+              ghc <- extractGHCVersion (dir </> fname)
+              return (LTSVersion major minor, ghc)
+            _ -> error $ "Invalid minor version format in " ++ fname ++
+                        ": expected integer, got '" ++ minorStr ++ "'"
+      | otherwise = error $ "Unexpected file in LTS directory: " ++ fname ++
+                           " (expected .yaml extension)"
+
+-- | Process nightly snapshots (structure: nightly/year/month/day.yaml)
+processNightlySnapshots :: FilePath -> IO [(NightlyVersion, GHCVersion)]
+processNightlySnapshots nightlyDir = do
+  yearDirs <- listDirectory nightlyDir
+  let sortedYears = sortOn (\s -> read s :: Int) $ filter (all (`elem` ("0123456789" :: String))) yearDirs
+  concat <$> mapM (processYear nightlyDir) sortedYears
+  where
+    processYear dir yearStr = do
+      case reads yearStr of
+        [(year, "")] -> do
+          let yearPath = dir </> yearStr
+          monthDirs <- listDirectory yearPath
+          let sortedMonths = sortOn (\s -> read s :: Int) $ filter (all (`elem` ("0123456789" :: String))) monthDirs
+          months <- mapM (processMonth yearPath year) sortedMonths
+          return $ concat months
+        _ -> return []
+    processMonth dir year monthStr = do
+      case reads monthStr of
+        [(month, "")] -> do
+          let monthPath = dir </> monthStr
+          dayFiles <- listDirectory monthPath
+          let sortedDays = sortOn (\s -> read (take (length s - 5) s) :: Int) $
+                           filter (\s -> takeExtension s == ".yaml") dayFiles
+          mapM (processDay monthPath year month) sortedDays
+        _ -> return []
+    processDay dir year month fname
+      | takeExtension fname == ".yaml" = do
+          case reads $ take (length fname - 5) fname of
+            [(day, "")] -> do
+              ghc <- extractGHCVersion (dir </> fname)
+              return (NightlyVersion year month day, ghc)
+            _ -> error $ "Invalid day in " ++ fname
+      | otherwise = error $ "Unexpected file in nightly directory: " ++ fname ++
+                           " (expected .yaml extension)"
+
+-- | Extract GHC version from a snapshot YAML file
+extractGHCVersion :: FilePath -> IO GHCVersion
+extractGHCVersion file = do
+  result <- Yaml.decodeFileEither file
+  case result of
+    Left err -> error $ "Failed to parse " ++ file ++ ": " ++ show err
+    Right (Aeson.Object obj) ->
+      -- Try new format first (nested under resolver)
+      case Yaml.parseMaybe (.: "resolver") obj of
+        Just (Aeson.Object resolverObj) ->
+          case Yaml.parseMaybe (.: "compiler") resolverObj of
+            Just (Aeson.String compiler) ->
+              parseCompiler compiler
+            _ -> error $ "No compiler field in resolver in " ++ file
+        _ ->
+          -- Try old format (compiler at top level)
+          case Yaml.parseMaybe (.: "compiler") obj of
+            Just (Aeson.String compiler) ->
+              parseCompiler compiler
+            _ -> error $ "No compiler field in " ++ file
+    _ -> error $ "Invalid YAML in " ++ file
+  where
+    parseCompiler compiler =
+      case parseGHCVersionText (T.drop 4 compiler) of
+        Just ghc -> return ghc
+        Nothing -> error $ "Invalid GHC version format in " ++ file ++ ": " ++ T.unpack compiler
+
+-- | Write LTS CSV file
+writeLTSCSV :: FilePath -> [(LTSVersion, GHCVersion)] -> IO ()
+writeLTSCSV path entries = do
+  let sorted = sortBy (comparing fst) entries
+  let lines = map formatLTSEntry sorted
+  TIO.writeFile path $ T.unlines lines
+  where
+    formatLTSEntry (LTSVersion maj min, ghc) =
+      T.pack (show maj) <> "." <> T.pack (show min) <> "," <> formatGHCVersion ghc
+
+-- | Write nightly CSV file
+writeNightlyCSV :: FilePath -> [(NightlyVersion, GHCVersion)] -> IO ()
+writeNightlyCSV path entries = do
+  let sorted = sortBy (comparing fst) entries
+  let lines = map formatNightlyEntry sorted
+  TIO.writeFile path $ T.unlines lines
+  where
+    formatNightlyEntry (nightly, ghc) =
+      formatNightlyVersion nightly <> "," <> formatGHCVersion ghc
+
+-- | Generate GHC version map from LTS and nightly maps
+generateGHCMap :: [(LTSVersion, GHCVersion)] -> [(NightlyVersion, GHCVersion)] -> Map GHCVersion Snapshot
+generateGHCMap ltsEntries nightlyEntries =
+  let ltsMap = foldr insertLTS Map.empty ltsEntries
+      nightlyMap = foldr insertNightly Map.empty nightlyEntries
+  in Map.union ltsMap nightlyMap
+  where
+    insertLTS (lts, ghc) m =
+      Map.insertWith (\_ old -> old) ghc (LTS lts) m
+    insertNightly (nightly, ghc) m =
+      Map.insertWith (\_ old -> old) ghc (Nightly nightly) m
+
+-- | Write GHC CSV file
+writeGHCCSV :: FilePath -> Map GHCVersion Snapshot -> IO ()
+writeGHCCSV path ghcMap = do
+  let sorted = sortBy (comparing fst) $ Map.toList ghcMap
+  let lines = map formatGHCEntry sorted
+  TIO.writeFile path $ T.unlines lines
+  where
+    formatGHCEntry (ghc, LTS (LTSVersion maj min)) =
+      formatGHCVersion ghc <> ",lts-" <> T.pack (show maj) <> "." <> T.pack (show min)
+    formatGHCEntry (ghc, Nightly nightly) =
+      formatGHCVersion ghc <> ",nightly-" <> formatNightlyVersion nightly
+
+-- | Load snapshot database from CSV files
+loadSnapshotDB :: IO SnapshotDB
+loadSnapshotDB = do
+  stateDir <- getStateDir
+
+  ltsMap <- readLTSCSV (stateDir </> "lts.csv")
+  nightlyMap <- readNightlyCSV (stateDir </> "nightly.csv")
+  ghcMap <- readGHCCSV (stateDir </> "ghc.csv")
+
+  return $ SnapshotDB ltsMap nightlyMap ghcMap
+
+-- | Read LTS CSV file
+readLTSCSV :: FilePath -> IO (Map LTSVersion GHCVersion)
+readLTSCSV path = do
+  exists <- doesFileExist path
+  if not exists
+    then return Map.empty
+    else do
+      content <- TIO.readFile path
+      let entries = map parseLTSLine $ T.lines content
+      return $ Map.fromList $ concat entries
+  where
+    parseLTSLine line =
+      case T.splitOn "," line of
+        [ver, ghcText] ->
+          case T.splitOn "." ver of
+            [majStr, minStr] ->
+              case (reads $ T.unpack majStr, reads $ T.unpack minStr, parseGHCVersionText ghcText) of
+                ([(maj, "")], [(min, "")], Just ghc) ->
+                  [(LTSVersion maj min, ghc)]
+                _ -> []
+            _ -> []
+        _ -> []
+
+-- | Read nightly CSV file
+readNightlyCSV :: FilePath -> IO (Map NightlyVersion GHCVersion)
+readNightlyCSV path = do
+  exists <- doesFileExist path
+  if not exists
+    then return Map.empty
+    else do
+      content <- TIO.readFile path
+      let entries = map parseNightlyLine $ T.lines content
+      return $ Map.fromList $ concat entries
+  where
+    parseNightlyLine line =
+      case T.splitOn "," line of
+        [dateText, ghcText] ->
+          case (parseNightlyVersionText dateText, parseGHCVersionText ghcText) of
+            (Just nightly, Just ghc) -> [(nightly, ghc)]
+            _ -> []
+        _ -> []
+
+-- | Read GHC CSV file
+readGHCCSV :: FilePath -> IO (Map GHCVersion Snapshot)
+readGHCCSV path = do
+  exists <- doesFileExist path
+  if not exists
+    then return Map.empty
+    else do
+      content <- TIO.readFile path
+      let entries = map parseGHCLine $ T.lines content
+      return $ Map.fromList $ concat entries
+  where
+    parseGHCLine line =
+      case T.splitOn "," line of
+        [ghcText, snap] ->
+          case (parseGHCVersionText ghcText, parseSnapshot snap) of
+            (Just ghc, Just s) -> [(ghc, s)]
+            _ -> []
+        _ -> []
+    parseSnapshot snap
+      | T.isPrefixOf "lts-" snap =
+          case T.splitOn "." (T.drop 4 snap) of
+            [majStr, minStr] ->
+              case (reads $ T.unpack majStr, reads $ T.unpack minStr) of
+                ([(maj, "")], [(min, "")]) -> Just $ LTS $ LTSVersion maj min
+                _ -> Nothing
+            _ -> Nothing
+      | T.isPrefixOf "nightly-" snap =
+          case parseNightlyVersionText (T.drop 8 snap) of
+            Just nightly -> Just $ Nightly nightly
+            Nothing -> Nothing
+      | otherwise = Nothing
diff --git a/src/ColorOption.hs b/src/ColorOption.hs
new file mode 100644
--- /dev/null
+++ b/src/ColorOption.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module ColorOption
+  ( ColorWhen(..)
+  , shouldUseColor
+  ) where
+
+import Types (ColorWhen(..))
+import System.IO (hIsTerminalDevice, stdout)
+import System.Environment (lookupEnv)
+
+-- | Determine if color should be used based on the color option
+shouldUseColor :: ColorWhen -> IO Bool
+shouldUseColor Always = return True
+shouldUseColor Never = return False
+shouldUseColor Auto = do
+  -- Respect NO_COLOR environment variable per https://no-color.org
+  noColor <- lookupEnv "NO_COLOR"
+  case noColor of
+    Just _ -> return False  -- NO_COLOR is set, disable colors
+    Nothing -> hIsTerminalDevice stdout  -- Check if stdout is a terminal
diff --git a/src/Commands.hs b/src/Commands.hs
new file mode 100644
--- /dev/null
+++ b/src/Commands.hs
@@ -0,0 +1,213 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Commands
+  ( runCommand
+  ) where
+
+import Control.Monad (forM_, when)
+import Data.List (sortBy)
+import Data.Map.Strict qualified as Map
+import Data.Ord (comparing)
+import Data.Text (Text)
+import Data.Text qualified as T
+import System.Console.ANSI
+import System.Directory (makeAbsolute)
+import System.Exit (die)
+import Text.Printf (printf)
+import Types
+import Config
+import CSV
+import Git
+import Analysis
+import StackYaml
+import ColorOption
+import License (licenseText)
+import XDG qualified
+
+-- | Run a command
+runCommand :: Options -> IO ()
+runCommand opts = do
+  useColor <- shouldUseColor (optColor opts)
+  case optCommand opts of
+    Version -> printVersion
+    NumericVersion -> putStrLn appVersion
+    PrintLicense -> putStrLn licenseText
+    Help -> do
+      -- Manually render help text
+      -- While not ideal, this ensures help works. The structure mirrors optparse-applicative's output.
+      putStrLn $ "stacker version " ++ appVersion
+      putStrLn ""
+      putStrLn "Usage: stacker [COMMAND | (-V|--version) | --numeric-version |"
+      putStrLn "                --license | (-h|--help)] [--color WHEN]"
+      putStrLn ""
+      putStrLn "  A tool to bump snapshots (resolvers) in stack*.yaml files"
+      putStrLn ""
+      putStrLn "Available commands:"
+      putStrLn "  bump [FILES...]          Update FILES (or all stack*.yaml files in current directory if none specified)"
+      putStrLn "                           Use --recursive/-r to search subdirectories"
+      putStrLn "  dry-run [FILES...]       Show what would be updated by 'bump' (default)"
+      putStrLn "                           Use --recursive/-r to search subdirectories"
+      putStrLn "  update                   Update stackage snapshots database"
+      putStrLn "  info                     Print GHC version to snapshot mapping"
+      putStrLn "  config                   Configure stacker"
+      putStrLn ""
+      putStrLn "Available options:"
+      putStrLn "  --color WHEN             Use colored output (always, never, auto)"
+      putStrLn "  -r,--recursive           Search subdirectories for stack*.yaml files"
+      putStrLn "                           (commands bump and dry-run)"
+      putStrLn ""
+      putStrLn "Inessential commands:"
+      putStrLn "  version                  Print version information (also: -V, --version)"
+      putStrLn "  numeric-version          Print version number (also: --numeric-version)"
+      putStrLn "  license                  Print license text (also: --license)"
+      putStrLn "  help                     Print this help (also: -h, --help)"
+      putStrLn ""
+      putStrLn "Option form of inessential commands:"
+      putStrLn "  -V,--version             Print version information"
+      putStrLn "  --numeric-version        Print version number"
+      putStrLn "  --license                Print license text"
+      putStrLn "  -h,--help                Print help"
+      putStrLn ""
+      putStrLn "For more information, see the README"
+    Config configCmd -> runConfig configCmd  -- Handle config first!
+    cmd -> runEssentialCommand useColor cmd
+
+-- | Run an essential command (requires CSV files)
+runEssentialCommand :: Bool -> Command -> IO ()
+runEssentialCommand useColor cmd = do
+  -- Ensure CSV files exist (copy from data dir if needed)
+  ensureCSVFiles
+
+  case cmd of
+    DryRun files recursive -> runDryRun useColor files recursive
+    Bump files recursive -> runBump files recursive
+    Update -> do
+      -- Only for Update command, ensure repo exists and update it
+      repoPath <- getRepoPath
+      ensureRepo repoPath
+      runUpdate repoPath
+    Info -> do
+      -- Info command shows the repo path
+      repoPath <- getRepoPath
+      runInfo repoPath
+    _ -> return ()
+
+-- | Print version information
+printVersion :: IO ()
+printVersion = do
+  putStrLn $ appName ++ " version " ++ appVersion
+  putStrLn copyright
+
+-- | Print text with optional color formatting
+withColor :: Bool -> [SGR] -> IO () -> IO ()
+withColor useColor sgr action = do
+  when useColor $ setSGR sgr
+  action
+  when useColor $ setSGR [Reset]
+
+-- | Run dry-run command
+runDryRun :: Bool -> [FilePath] -> Bool -> IO ()
+runDryRun useColor files recursive = do
+  -- Validate: recursive cannot be used with explicit files
+  when (recursive && not (null files)) $
+    die "Error: --recursive cannot be used with explicit file arguments"
+  
+  db <- loadSnapshotDB
+  actions <- analyzeStackYamls db files recursive
+
+  -- Sort actions by filename
+  let sortedActions = sortBy (comparing actionFile) actions
+  
+  -- Calculate the maximum filename length for proper alignment (add 2 for padding)
+  let maxFileLen = case sortedActions of
+        [] -> 20
+        acts -> max 20 (maximum (map (length . actionFile) acts) + 2)
+
+  forM_ sortedActions $ \action -> do
+    printActionWithWidth useColor maxFileLen action
+
+-- | Print an action with a specified column width for filenames
+printActionWithWidth :: Bool -> Int -> Action -> IO ()
+printActionWithWidth useColor fileWidth action = do
+  let file = actionFile action
+  let oldSnap = actionOldSnapshot action
+  let newSnap = actionNewSnapshot action
+  let symlinkTarget = actionSymlinkTarget action
+
+  -- Print with proper alignment (file padded to fileWidth chars, oldSnap to 25 chars)
+  withColor useColor [SetConsoleIntensity BoldIntensity] $
+    putStr $ padRight fileWidth file
+
+  putStr $ padRight 25 (T.unpack oldSnap)
+
+  case symlinkTarget of
+    Just target -> do
+      -- This is a symlink to another stack*.yaml file
+      withColor useColor [SetColor Foreground Dull White] $ do
+        putStr "= symlink to "
+        putStr target
+    Nothing ->
+      case newSnap of
+        Nothing -> do
+          withColor useColor [SetColor Foreground Vivid Green] $
+            putStr "✓ up to date"
+        Just new -> do
+          withColor useColor [SetColor Foreground Vivid Yellow] $ do
+            putStr "→ bump to "
+            putStr $ T.unpack new
+
+  putStrLn ""
+
+-- | Pad string to the right
+padRight :: Int -> String -> String
+padRight n s = take n (s ++ repeat ' ')
+
+-- | Run bump command
+runBump :: [FilePath] -> Bool -> IO ()
+runBump files recursive = do
+  -- Validate: recursive cannot be used with explicit files
+  when (recursive && not (null files)) $
+    die "Error: --recursive cannot be used with explicit file arguments"
+  
+  db <- loadSnapshotDB
+  actions <- analyzeStackYamls db files recursive
+  mapM_ (applyAction True) actions
+
+-- | Run update command
+runUpdate :: FilePath -> IO ()
+runUpdate repoPath = do
+  putStrLn $ "Repository: " ++ repoPath
+  updateRepo repoPath
+  generateCSVs repoPath
+
+-- | Run info command
+runInfo :: FilePath -> IO ()
+runInfo repoPath = do
+  putStrLn $ "repo: " ++ repoPath
+  db <- loadSnapshotDB
+  putStrLn "snapshots:"
+
+  let ghcEntries = Map.toAscList (dbGHC db)
+  forM_ ghcEntries $ \(ghc, snapshot) -> do
+    putStrLn $ "  " ++ formatGHCVersionText ghc ++ ": " ++ T.unpack (formatSnapshotText snapshot)
+
+-- | Format GHC version as text
+formatGHCVersionText :: GHCVersion -> String
+formatGHCVersionText (GHCVersion maj1 maj2 minV) =
+  show maj1 ++ "." ++ show maj2 ++ "." ++ show minV
+
+-- | Format snapshot as text
+formatSnapshotText :: Snapshot -> Text
+formatSnapshotText (LTS (LTSVersion major minor)) =
+  "lts-" <> T.pack (show major) <> "." <> T.pack (show minor)
+formatSnapshotText (Nightly (NightlyVersion year month day)) =
+  T.pack $ "nightly-" ++ printf "%d-%02d-%02d" year month day
+
+-- | Run config command
+runConfig :: ConfigCmd -> IO ()
+runConfig (SetRepo path) = do
+  absPath <- makeAbsolute path
+  saveConfig $ AppConfig (Just absPath)
+  putStrLn $ "Repository path set to: " ++ absPath
+  configFile <- XDG.getConfigFile
+  putStrLn $ "Configuration saved to: " ++ configFile
diff --git a/src/Config.hs b/src/Config.hs
new file mode 100644
--- /dev/null
+++ b/src/Config.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
+
+module Config
+  ( loadConfig
+  , saveConfig
+  , getRepoPath
+  ) where
+
+import Data.Yaml (decodeFileEither, encodeFile, FromJSON(..), ToJSON(..), (.:?), (.=), object, withObject)
+import System.Directory (createDirectoryIfMissing, doesFileExist)
+import System.FilePath (takeDirectory)
+import Types (AppConfig(..))
+import XDG (getConfigFile, getRepoDir)
+
+instance FromJSON AppConfig where
+  parseJSON = withObject "AppConfig" $ \v ->
+    AppConfig <$> v .:? "repo"
+
+instance ToJSON AppConfig where
+  toJSON (AppConfig repo) = object ["repo" .= repo]
+
+-- | Load configuration from the config file
+loadConfig :: IO AppConfig
+loadConfig = do
+  configFile <- getConfigFile
+  exists <- doesFileExist configFile
+  if exists
+    then do
+      result <- decodeFileEither configFile
+      case result of
+        Left _ -> return $ AppConfig Nothing
+        Right config -> return config
+    else return $ AppConfig Nothing
+
+-- | Save configuration to the config file
+saveConfig :: AppConfig -> IO ()
+saveConfig config = do
+  configFile <- getConfigFile
+  createDirectoryIfMissing True (takeDirectory configFile)
+  encodeFile configFile config
+
+-- | Get the repository path, either from config or default
+getRepoPath :: IO FilePath
+getRepoPath = do
+  config <- loadConfig
+  case configRepo config of
+    Just repo -> return repo
+    Nothing -> getRepoDir
diff --git a/src/Git.hs b/src/Git.hs
new file mode 100644
--- /dev/null
+++ b/src/Git.hs
@@ -0,0 +1,56 @@
+module Git
+  ( ensureRepo
+  , updateRepo
+  , getCurrentBranch
+  ) where
+
+import System.Directory (doesDirectoryExist, createDirectoryIfMissing)
+import System.FilePath (takeDirectory)
+import System.Process (readProcess, callProcess)
+import System.Exit (exitFailure)
+import Control.Exception (catch, SomeException)
+import Control.Monad (unless)
+
+stackageSnapshotsUrl :: String
+stackageSnapshotsUrl = "https://github.com/commercialhaskell/stackage-snapshots"
+
+-- | Ensure the repository exists, cloning it if necessary
+ensureRepo :: FilePath -> IO ()
+ensureRepo repoPath = do
+  exists <- doesDirectoryExist repoPath
+  unless exists $ cloneRepo repoPath
+
+-- | Clone the stackage-snapshots repository
+cloneRepo :: FilePath -> IO ()
+cloneRepo repoPath = do
+  createDirectoryIfMissing True (takeDirectory repoPath)
+  putStrLn $ "Downloading repo " ++ stackageSnapshotsUrl ++ " as shallow clone to " ++ repoPath ++ "..."
+  callProcess "git" ["clone", "--depth", "1", stackageSnapshotsUrl, repoPath]
+  putStrLn "Clone complete."
+
+-- | Get the current branch name
+getCurrentBranch :: FilePath -> IO String
+getCurrentBranch repoPath = do
+  trim <$> readProcess "git" ["-C", repoPath, "rev-parse", "--abbrev-ref", "HEAD"] ""
+
+-- | Update the repository by pulling
+updateRepo :: FilePath -> IO ()
+updateRepo repoPath = do
+  branch <- getCurrentBranch repoPath
+  if branch /= "master"
+    then do
+      putStrLn $ "Error: Repository is on branch '" ++ branch ++ "', not 'master'."
+      putStrLn "Cannot update repository when not on master branch."
+      exitFailure
+    else do
+      putStrLn $ "Updating repository at " ++ repoPath ++ "..."
+      catch
+        (callProcess "git" ["-C", repoPath, "pull"])
+        (\(e :: SomeException) -> do
+          putStrLn $ "Warning: Failed to update repository: " ++ show e
+          return ())
+      putStrLn "Update complete."
+
+-- | Trim whitespace from a string
+trim :: String -> String
+trim = reverse . dropWhile (`elem` " \t\n\r") . reverse . dropWhile (`elem` " \t\n\r")
diff --git a/src/License.hs b/src/License.hs
new file mode 100644
--- /dev/null
+++ b/src/License.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module License (licenseText) where
+
+import Data.FileEmbed (embedStringFile)
+
+-- | BSD-3-Clause license text embedded from LICENSE file
+licenseText :: String
+licenseText = $(embedStringFile "LICENSE")
diff --git a/src/Options.hs b/src/Options.hs
new file mode 100644
--- /dev/null
+++ b/src/Options.hs
@@ -0,0 +1,110 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Options
+  ( parseOptions
+  , optionsParserInfo
+  , Options(..)
+  ) where
+
+import Data.Char (toLower)
+import Options.Applicative
+import Types
+
+-- | Parse command-line options
+parseOptions :: IO Options
+parseOptions = customExecParser (prefs showHelpOnEmpty) optionsParserInfo
+
+-- | Parser info (exported for help rendering)
+optionsParserInfo :: ParserInfo Options
+optionsParserInfo = info (optionsParser <**> helper)
+  ( fullDesc
+ <> progDesc "A tool to bump snapshots (resolvers) in stack*.yaml files"
+ <> header ("stacker version " ++ appVersion)
+ <> footer "For more information, see the README" )
+
+-- | Options parser
+-- The parser tries subcommand parsing first (which includes color options),
+-- then falls back to top-level options (for version/help flags and default).
+-- This allows --color to be specified either before the subcommand
+-- (e.g., "stacker --color=never dry-run") or within the subcommand
+-- (e.g., "stacker dry-run --color=never file.yaml").
+-- Precedence: Subcommand parsers take priority, so "stacker dry-run --color=never"
+-- will be parsed by the subcommand parser, not the top-level parser.
+optionsParser :: Parser Options
+optionsParser = subcommandWithOptions <|> topLevelOptions
+  where
+    -- Helper to combine a command parser with the color option, creating an Options value
+    withColorOption :: Parser Command -> Parser Options
+    withColorOption cmdParser = Options <$> cmdParser <*> colorOption
+    
+    -- Subcommand parser that includes color options for each command
+    subcommandWithOptions = subparser
+      ( command "bump" (info (withColorOption bumpParser) (progDesc "Update stack*.yaml files (optionally specify files, or use --recursive/-r to search subdirectories)"))
+     <> command "dry-run" (info (withColorOption dryRunParser) (progDesc "Show what would be updated (default, optionally specify files, or use --recursive/-r to search subdirectories)"))
+     <> command "update" (info (withColorOption (pure Update)) (progDesc "Update stackage snapshots database"))
+     <> command "info" (info (withColorOption (pure Info)) (progDesc "Print GHC version to snapshot mapping"))
+     <> command "config" (info (withColorOption configParser) (progDesc "Configure stacker"))
+     <> command "version" (info (withColorOption (pure Version)) (progDesc "Print version information (also: -V, --version)"))
+     <> command "numeric-version" (info (withColorOption (pure NumericVersion)) (progDesc "Print version number (also: --numeric-version)"))
+     <> command "license" (info (withColorOption (pure PrintLicense)) (progDesc "Print license text (also: --license)"))
+     <> command "help" (info (withColorOption (pure Help)) (progDesc "Print this help (also: -h, --help)"))
+      )
+    
+    -- Top-level parser for version/help flags and default command when no subcommand is specified
+    topLevelOptions = Options
+      <$> commandParserTopLevel
+      <*> colorOption
+    
+    -- Top-level command parser (for flags)
+    commandParserTopLevel = 
+      flag' Version (long "version" <> short 'V' <> help "Print version information")
+      <|> flag' NumericVersion (long "numeric-version" <> help "Print version number")
+      <|> flag' PrintLicense (long "license" <> help "Print license text")
+      <|> flag' Help (long "help" <> short 'h' <> help "Print help")
+      <|> (DryRun [] <$> recursiveOption)
+
+-- | Config command parser
+configParser :: Parser Command
+configParser = Config <$> subparser
+  ( command "repo" (info repoParser (progDesc "Set repository path"))
+  )
+
+-- | Repo config parser
+repoParser :: Parser ConfigCmd
+repoParser = SetRepo <$> argument str (metavar "PATH")
+
+-- | Helper to parse file arguments with optional recursive flag
+filesParser :: ([FilePath] -> Bool -> Command) -> Parser Command
+filesParser cmd = cmd 
+  <$> many (argument str (metavar "FILES..." <> action "file"))
+  <*> recursiveOption
+
+-- | Recursive option parser
+recursiveOption :: Parser Bool
+recursiveOption = switch
+  ( long "recursive"
+ <> short 'r'
+ <> help "Search for stack*.yaml files recursively in all subdirectories" )
+
+-- | Bump command parser
+bumpParser :: Parser Command
+bumpParser = filesParser Bump
+
+-- | Dry-run command parser
+dryRunParser :: Parser Command
+dryRunParser = filesParser DryRun
+
+-- | Color option parser
+colorOption :: Parser ColorWhen
+colorOption = option readColorWhen
+  ( long "color"
+ <> metavar "WHEN"
+ <> value Auto
+ <> help "Use colored output (always, never, auto)" )
+  where
+    readColorWhen = maybeReader $ \s ->
+      case map toLower s of
+        "always" -> Just Always
+        "never" -> Just Never
+        "auto" -> Just Auto
+        _ -> Nothing
diff --git a/src/PathUtil.hs b/src/PathUtil.hs
new file mode 100644
--- /dev/null
+++ b/src/PathUtil.hs
@@ -0,0 +1,98 @@
+-- | Path utilities for cross-platform compatibility
+-- 
+-- This module provides path utilities that use forward slash (/) as the 
+-- path separator on all platforms, including Windows. While Windows primarily
+-- uses backslash (\), it also accepts forward slash for relative paths,
+-- which is what this tool deals with.
+--
+-- This approach ensures consistent path handling and output across all platforms,
+-- avoiding the path separator issues that can occur when using System.FilePath's
+-- platform-specific path combinators.
+module PathUtil
+  ( (</>)
+  , normalizeFilePath
+  , splitPath
+  , joinPath
+  , collapseDots
+  , takeDirectory
+  , takeFileName
+  , toForwardSlashes
+  ) where
+
+import Data.List (stripPrefix)
+
+-- | Cross-platform path combination using forward slash
+-- This ensures consistent behavior across Linux, macOS, and Windows
+-- for relative paths (which is what this tool processes).
+--
+-- Note: This is specifically designed for combining relative path components.
+-- For absolute paths or complex path manipulations, System.FilePath should be used.
+(</>) :: FilePath -> FilePath -> FilePath
+"" </> b = b
+a </> "" = a
+a </> b = a ++ "/" ++ b
+
+-- | Normalize a file path by removing "./" prefix
+-- This is used to ensure consistent output format where paths
+-- don't have a leading "./" component.
+normalizeFilePath :: FilePath -> FilePath
+normalizeFilePath path =
+  case stripPrefix "./" path of
+    Just rest -> rest
+    Nothing -> path
+
+-- | Split a path into components using forward slash as separator
+-- Works consistently across all platforms
+splitPath :: FilePath -> [String]
+splitPath "" = []
+splitPath path = split path
+  where
+    split "" = []
+    split s = case break (== '/') s of
+      (comp, "") -> [comp]
+      (comp, _:rest) -> comp : split rest
+
+-- | Join path components using forward slash
+-- Works consistently across all platforms
+joinPath :: [String] -> FilePath
+joinPath [] = ""
+joinPath [x] = x
+joinPath (x:xs) = x ++ "/" ++ joinPath xs
+
+-- | Collapse ".." and "." components in a path
+-- This normalizes paths like "a/b/../c" to "a/c"
+collapseDots :: FilePath -> FilePath
+collapseDots path = joinPath $ reverse $ foldl collapseDir [] (splitPath path)
+  where
+    collapseDir :: [String] -> String -> [String]
+    collapseDir acc "." = acc
+    collapseDir (prev:rest) ".." | prev /= ".." = rest
+    collapseDir acc ".." = ".." : acc
+    collapseDir acc dir = dir : acc
+
+-- | Get the directory part of a file path
+-- Uses forward slash as separator on all platforms
+-- Examples: takeDirectory "a/b/c" = "a/b", takeDirectory "file.txt" = "."
+takeDirectory :: FilePath -> FilePath
+takeDirectory "" = "."
+takeDirectory path =
+  case reverse (filter (not . null) (splitPath path)) of
+    [] -> "."
+    [_] -> "."
+    (_:dirs) -> joinPath (reverse dirs)
+
+-- | Get the file name part of a file path
+-- Uses forward slash as separator on all platforms
+-- Examples: takeFileName "a/b/c.txt" = "c.txt", takeFileName "file.txt" = "file.txt"
+takeFileName :: FilePath -> FilePath
+takeFileName "" = ""
+takeFileName path =
+  case reverse (filter (not . null) (splitPath path)) of
+    [] -> ""
+    (name:_) -> name
+
+-- | Convert backslashes to forward slashes
+-- This is needed to normalize paths returned by Windows system calls
+-- to use forward slashes consistently
+toForwardSlashes :: FilePath -> FilePath
+toForwardSlashes = map (\c -> if c == '\\' then '/' else c)
diff --git a/src/StackYaml.hs b/src/StackYaml.hs
new file mode 100644
--- /dev/null
+++ b/src/StackYaml.hs
@@ -0,0 +1,139 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module StackYaml
+  ( findStackYamlFiles
+  , findStackYamlFilesRecursive
+  , parseStackYaml
+  , applyAction
+  , isStackYaml
+  , getSymlinkMap
+  ) where
+
+import Control.Monad (filterM, when)
+import Data.List (isPrefixOf, isSuffixOf, sort)
+import Data.Map.Strict qualified as Map
+import Data.Maybe (catMaybes)
+import Data.Text (Text)
+import Data.Text qualified as T
+import Data.Text.IO qualified as TIO
+import System.Directory (listDirectory, doesFileExist, pathIsSymbolicLink, getSymbolicLinkTarget, doesDirectoryExist)
+import PathUtil ((</>), normalizeFilePath, collapseDots, takeDirectory, takeFileName, toForwardSlashes)
+import Types (Action(..))
+
+-- | Check if a filename is a stack*.yaml file
+isStackYaml :: FilePath -> Bool
+isStackYaml name =
+  let fname = takeFileName name
+  in "stack" `isPrefixOf` fname && ".yaml" `isSuffixOf` fname
+
+-- | Find all stack*.yaml files in the current directory
+findStackYamlFiles :: IO [FilePath]
+findStackYamlFiles = do
+  files <- listDirectory "."
+  let candidates = filter isStackYaml files
+  sort <$> filterM doesFileExist candidates
+
+-- | Find all stack*.yaml files recursively in all subdirectories
+findStackYamlFilesRecursive :: IO [FilePath]
+findStackYamlFilesRecursive = findStackYamlFilesInDir "."
+
+-- | Helper function to find stack*.yaml files recursively in a directory
+findStackYamlFilesInDir :: FilePath -> IO [FilePath]
+findStackYamlFilesInDir dir = do
+  entries <- listDirectory dir
+  -- Use custom </> to ensure consistent path output with "/" separator on all platforms
+  let fullPaths = map (dir </>) entries
+  
+  -- Process files and directories separately
+  files <- filterM doesFileExist fullPaths
+  dirs <- filterM doesDirectoryExist fullPaths
+  
+  -- Find stack*.yaml files in current directory, normalize to remove "./" prefix
+  let stackYamls = map normalizeFilePath $ filter isStackYaml files
+  
+  -- Recursively search subdirectories
+  subResults <- mapM findStackYamlFilesInDir dirs
+  
+  -- Combine and sort all results (all paths are already normalized)
+  return $ sort (stackYamls ++ concat subResults)
+
+-- | Get a map of symlinks to their targets (only for symlinks pointing to other stack*.yaml files in the list)
+getSymlinkMap :: [FilePath] -> IO (Map.Map FilePath FilePath)
+getSymlinkMap files = do
+  -- Find symlinks in the list
+  symlinks <- filterM pathIsSymbolicLink files
+
+  -- For each symlink, check if it points to another file in the list
+  results <- mapM checkSymlink symlinks
+
+  return $ Map.fromList $ catMaybes results
+  where
+    checkSymlink :: FilePath -> IO (Maybe (FilePath, FilePath))
+    checkSymlink link = do
+      target <- getSymbolicLinkTarget link
+      -- Convert backslashes to forward slashes (Windows compatibility)
+      let normalizedTarget = toForwardSlashes target
+      -- Resolve the target relative to the symlink's directory
+      let symlinkDir = takeDirectory link
+      let targetPath = symlinkDir </> normalizedTarget
+      -- Normalize and collapse .. components using our custom functions
+      let resolvedTarget = normalizeFilePath $ collapseDots targetPath
+      -- Check if the target is in our file list
+      if resolvedTarget `elem` files
+        then return $ Just (link, resolvedTarget)
+        else return Nothing
+
+-- | Parse a stack.yaml file to extract the snapshot field
+parseStackYaml :: FilePath -> IO (Maybe (Text, Bool, (Int, Int)))
+parseStackYaml file = do
+  content <- TIO.readFile file
+  return $ findSnapshot (T.unpack content) 0
+  where
+    findSnapshot s pos =
+      case findField "snapshot:" s pos of
+        Just (value, start, end) -> Just (T.pack value, False, (start, end))
+        Nothing ->
+          case findField "resolver:" s pos of
+            Just (value, start, end) -> Just (T.pack value, True, (start, end))
+            Nothing -> Nothing
+
+    findField :: String -> String -> Int -> Maybe (String, Int, Int)
+    findField field s pos =
+      findFieldHelper field s pos s
+
+    findFieldHelper :: String -> String -> Int -> String -> Maybe (String, Int, Int)
+    findFieldHelper _field _orig _pos [] = Nothing
+    findFieldHelper field orig pos s@(_:cs)
+      | field `isPrefixOf` s =
+          let afterField = drop (length field) s
+              trimmed = dropWhile (\c -> c `elem` (" \t" :: String)) afterField
+              value = takeWhile (`notElem` ("\n\r" :: String)) trimmed
+              valueStart = pos + (length orig - length s) + length field + (length afterField - length trimmed)
+              valueEnd = valueStart + length value
+          in if null value
+               then Nothing
+               else Just (value, valueStart, valueEnd)
+      | otherwise = findFieldHelper field orig pos cs
+
+-- | Apply an action to update a stack.yaml file
+applyAction :: Bool -> Action -> IO ()
+applyAction verbose action = do
+  -- Skip symlinks that point to other stack*.yaml files in the list
+  case actionSymlinkTarget action of
+    Just _ -> return ()  -- Skip symlinks
+    Nothing ->
+      case actionNewSnapshot action of
+        Nothing -> return ()  -- No update needed
+        Just newSnap -> do
+          when verbose $ putStrLn $ "Updating " ++ actionFile action
+          content <- TIO.readFile (actionFile action)
+          let (before, after) = splitAtSpan (actionSpan action) content
+          let updated = before <> newSnap <> after
+          TIO.writeFile (actionFile action) updated
+
+-- | Split text at a character span
+splitAtSpan :: (Int, Int) -> Text -> (Text, Text)
+splitAtSpan (start, end) text =
+  let before = T.take start text
+      after = T.drop end text
+  in (before, after)
diff --git a/src/Types.hs b/src/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Types.hs
@@ -0,0 +1,100 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Types where
+
+import Data.Map.Strict (Map)
+import Data.Text (Text)
+import Data.Version (showVersion)
+import GHC.Generics (Generic)
+import Paths_stacker qualified as Paths
+
+-- | LTS version (e.g., "24.23" for lts-24.23)
+data LTSVersion = LTSVersion
+  { ltsMajor :: Int
+  , ltsMinor :: Int
+  } deriving (Eq, Ord, Show, Generic)
+
+-- | Nightly version (e.g., "2025-12-09" for nightly-2025-12-09)
+data NightlyVersion = NightlyVersion
+  { nightlyYear :: Int
+  , nightlyMonth :: Int
+  , nightlyDay :: Int
+  } deriving (Eq, Ord, Show, Generic)
+
+-- | GHC version (e.g., "9.10.1")
+data GHCVersion = GHCVersion
+  { ghcMajor1 :: Int
+  , ghcMajor2 :: Int
+  , ghcMinor :: Int
+  } deriving (Eq, Ord, Show, Generic)
+
+-- | Snapshot reference
+data Snapshot
+  = LTS LTSVersion
+  | Nightly NightlyVersion
+  deriving (Eq, Ord, Show, Generic)
+
+-- | Action to take for a stack*.yaml file
+data Action = Action
+  { actionFile :: FilePath
+  , actionOldSnapshot :: Text
+  , actionNewSnapshot :: Maybe Text
+  , actionIsResolver :: Bool  -- True if 'resolver' field, False if 'snapshot'
+  , actionSpan :: (Int, Int)  -- Character span to replace
+  , actionSymlinkTarget :: Maybe FilePath  -- Just target if this is a symlink to another stack*.yaml in the list
+  } deriving (Eq, Show, Generic)
+
+-- | Database of snapshots
+data SnapshotDB = SnapshotDB
+  { dbLTS :: Map LTSVersion GHCVersion
+  , dbNightly :: Map NightlyVersion GHCVersion
+  , dbGHC :: Map GHCVersion Snapshot
+  } deriving (Eq, Show, Generic)
+
+-- | Configuration
+data AppConfig = AppConfig
+  { configRepo :: Maybe FilePath
+  } deriving (Eq, Show, Generic)
+
+-- | Command-line command
+data Command
+  = Bump [FilePath] Bool  -- Optional list of files to bump, recursive flag
+  | DryRun [FilePath] Bool  -- Optional list of files to check, recursive flag
+  | Config ConfigCmd
+  | Update
+  | Info
+  | Version
+  | NumericVersion
+  | PrintLicense
+  | Help
+  deriving (Eq, Show)
+
+-- | Config command
+data ConfigCmd
+  = SetRepo FilePath
+  deriving (Eq, Show)
+
+-- | Color option
+data ColorWhen
+  = Always
+  | Never
+  | Auto
+  deriving (Eq, Show, Read)
+
+-- | Options
+data Options = Options
+  { optCommand :: Command
+  , optColor :: ColorWhen
+  } deriving (Eq, Show)
+
+-- | Application version
+appVersion :: String
+appVersion = showVersion Paths.version
+
+-- | Application name
+appName :: String
+appName = "stacker"
+
+-- | Copyright information
+copyright :: String
+copyright = "Copyright (c) 2025 Andreas Abel"
diff --git a/src/XDG.hs b/src/XDG.hs
new file mode 100644
--- /dev/null
+++ b/src/XDG.hs
@@ -0,0 +1,30 @@
+module XDG
+  ( getStateDir
+  , getConfigDir
+  , getConfigFile
+  , getRepoDir
+  ) where
+
+import System.Directory (getXdgDirectory, XdgDirectory(..))
+import PathUtil ((</>))
+import Types (appName)
+
+-- | Get the XDG state directory for the application
+getStateDir :: IO FilePath
+getStateDir = getXdgDirectory XdgState appName
+
+-- | Get the XDG config directory for the application
+getConfigDir :: IO FilePath
+getConfigDir = getXdgDirectory XdgConfig appName
+
+-- | Get the path to the config file
+getConfigFile :: IO FilePath
+getConfigFile = do
+  dir <- getConfigDir
+  return $ dir </> "config.yaml"
+
+-- | Get the default repository directory
+getRepoDir :: IO FilePath
+getRepoDir = do
+  stateDir <- getStateDir
+  return $ stateDir </> "stackage-snapshots"
diff --git a/stacker.cabal b/stacker.cabal
new file mode 100644
--- /dev/null
+++ b/stacker.cabal
@@ -0,0 +1,126 @@
+cabal-version:      3.0
+name:               stacker
+version:            0.0.0.0
+synopsis:           Bump snapshots in stack.yaml files
+description:
+  A tool to bump snapshots (resolvers) in stack*.yaml files.
+  It upgrades LTS snapshots to the latest version and converts
+  nightlies to LTS when available.
+license:            BSD-3-Clause
+license-file:       LICENSE
+author:             Andreas Abel
+maintainer:         andreas.abel@gu.se
+category:           Development
+build-type:         Simple
+
+tested-with:
+  GHC == 9.4.8
+  GHC == 9.6.7
+  GHC == 9.8.4
+  GHC == 9.10.3
+  GHC == 9.12.4
+
+extra-doc-files:
+  CHANGELOG.md
+  README.md
+
+extra-source-files:
+  test/tests/*.yaml
+  test/golden/dry-run.golden
+  test/golden/dry-run-files.golden
+  test/golden/dry-run-recursive.golden
+  test/golden/tests/*.yaml
+  test/recursive/stack-9.6.yaml
+  test/recursive/subdir1/stack-9.8.yaml
+  test/recursive/subdir1/subdir2/stack-9.10.yaml
+  test/recursive/other/stack.yaml
+
+data-dir:
+  data
+data-files:
+  ghc.csv
+  lts.csv
+  nightly.csv
+
+source-repository head
+  type: git
+  location: https://github.com/andreasabel/stacker.git
+
+common warnings
+  ghc-options:
+    -Wall
+    -Wcompat
+    -Wunused-packages
+    -Wincomplete-patterns
+  default-language:
+    Haskell2010
+  default-extensions:
+    DeriveGeneric
+    LambdaCase
+    ImportQualifiedPost
+    ScopedTypeVariables
+  other-extensions:
+    OverloadedStrings
+
+library
+  import:           warnings
+  hs-source-dirs:   src
+  exposed-modules:
+    Options
+    ColorOption
+    License
+    Config
+    Git
+    CSV
+    StackYaml
+    Analysis
+    Commands
+    XDG
+    Types
+    PathUtil
+  other-modules:
+    Paths_stacker
+  autogen-modules:
+    Paths_stacker
+  build-depends:
+    , base                  >= 4.17 && < 5
+    , directory             >= 1.3.7.0
+        -- XdgState requires directory-1.3.7.0 or higher
+    , filepath              >= 1.4
+    , process               >= 1.6
+    , text                  >= 2.0
+    , yaml                  >= 0.11
+    , aeson                 >= 2.0
+    , containers            >= 0.6
+    , optparse-applicative  >= 0.17
+    , ansi-terminal         >= 0.11
+    , file-embed            >= 0.0.15
+
+executable stacker
+  import:           warnings
+  hs-source-dirs:   app
+  main-is:          Main.hs
+  build-depends:
+    , base       >= 4.17 && < 5
+    , stacker
+
+test-suite stacker-test
+  import:           warnings
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   test
+  main-is:          Main.hs
+  other-modules:
+    TestDryRun
+    TestBump
+  build-depends:
+    , base          >= 4.17 && < 5
+    , stacker
+    , tasty         >= 1.4
+    , tasty-golden  >= 2.3
+    , directory     >= 1.3.7.0
+    , text          >= 2.0
+    , bytestring    >= 0.11
+    , temporary     >= 1.3
+    , process
+  build-tool-depends:
+    , stacker:stacker
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,16 @@
+module Main where
+
+import Test.Tasty ( defaultMain, testGroup, TestTree )
+import TestDryRun ( dryRunTests )
+import TestBump ( bumpTestsIO )
+
+main :: IO ()
+main = do
+  bumpTests <- bumpTestsIO
+  defaultMain $ tests bumpTests
+
+tests :: [TestTree] -> TestTree
+tests bumpTests = testGroup "stack-snapshots tests"
+  [ testGroup "dry-run tests" dryRunTests
+  , testGroup "bump tests" bumpTests
+  ]
diff --git a/test/TestBump.hs b/test/TestBump.hs
new file mode 100644
--- /dev/null
+++ b/test/TestBump.hs
@@ -0,0 +1,60 @@
+module TestBump (bumpTestsIO) where
+
+import Test.Tasty ( TestTree )
+import Test.Tasty.Golden ( goldenVsFileDiff )
+import System.Directory (copyFile, setCurrentDirectory, getCurrentDirectory)
+import System.IO.Temp (createTempDirectory, getCanonicalTemporaryDirectory)
+import Control.Monad (forM_)
+import Data.Maybe (catMaybes)
+
+-- Import from library
+import StackYaml (findStackYamlFiles, getSymlinkMap, applyAction)
+import Analysis (analyzeStackYaml)
+import CSV (loadSnapshotDB, ensureCSVFiles)
+import PathUtil ((</>))
+
+-- | Generate bump tests - all files are bumped in one temp directory
+bumpTestsIO :: IO [TestTree]
+bumpTestsIO = do
+  -- Ensure CSV files are available
+  ensureCSVFiles
+
+  -- Create a temp directory for this test run
+  sysTempDir <- getCanonicalTemporaryDirectory
+  tempDir <- createTempDirectory sysTempDir "stacker-test"
+
+  -- Find all stack*.yaml files using library function
+  cwd <- getCurrentDirectory
+  setCurrentDirectory "test/tests"
+  stackYamlFiles <- findStackYamlFiles
+  setCurrentDirectory cwd
+
+  -- Copy all files to temp directory
+  forM_ stackYamlFiles $ \file -> do
+    copyFile ("test/tests" </> file) (tempDir </> file)
+
+  -- Run bump logic using library functions
+  setCurrentDirectory tempDir
+
+  -- Load snapshot database
+  db <- loadSnapshotDB
+
+  -- Get symlink map
+  symlinkMap <- getSymlinkMap stackYamlFiles
+
+  -- Get and run actions for each file
+  actions <- catMaybes <$>  mapM (analyzeStackYaml db symlinkMap) stackYamlFiles
+  mapM_ (applyAction False) actions
+
+  setCurrentDirectory cwd
+
+  -- Create a golden test for each file
+  return $ map (makeGoldenTest tempDir) stackYamlFiles
+  where
+
+    makeGoldenTest tempDir file = goldenVsFileDiff
+      ("bump " ++ file)
+      (\ref new -> ["diff", "-u", ref, new])
+      ("test/golden/tests" </> file)
+      (tempDir </> file)
+      (return ())  -- Action is empty since bump already ran
diff --git a/test/TestDryRun.hs b/test/TestDryRun.hs
new file mode 100644
--- /dev/null
+++ b/test/TestDryRun.hs
@@ -0,0 +1,53 @@
+module TestDryRun (dryRunTests) where
+
+import Test.Tasty
+import Test.Tasty.Golden
+import System.Process (readProcess)
+import System.Directory (setCurrentDirectory, getCurrentDirectory)
+import Data.ByteString.Lazy qualified as BSL
+import Data.Text qualified as T
+import Data.Text.Encoding qualified as TE
+import Data.List (sort)
+
+dryRunTests :: [TestTree]
+dryRunTests =
+  [ goldenVsString
+      "dry-run output"
+      "test/golden/dry-run.golden"
+      runDryRunTest
+  , goldenVsString
+      "dry-run with specific files"
+      "test/golden/dry-run-files.golden"
+      runDryRunWithFilesTest
+  , goldenVsString
+      "dry-run with recursive flag"
+      "test/golden/dry-run-recursive.golden"
+      runDryRunRecursiveTest
+  ]
+
+runDryRunTest :: IO BSL.ByteString
+runDryRunTest = runDryRun ["dry-run", "--color=never"]
+
+runDryRunWithFilesTest :: IO BSL.ByteString
+runDryRunWithFilesTest = runDryRun ["dry-run", "--color=never", "stack-9.6.yaml", "stack-9.8.yaml"]
+
+runDryRunRecursiveTest :: IO BSL.ByteString
+runDryRunRecursiveTest = do
+  cwd <- getCurrentDirectory
+  setCurrentDirectory "test/recursive"
+  -- Test that just --recursive works (defaults to dry-run)
+  output <- readProcess "stacker" ["--recursive", "--color=never"] ""
+  setCurrentDirectory cwd
+  -- Sort the output lines for consistent comparison
+  let sortedLines = T.unlines $ sort $ T.lines $ T.pack output
+  return $ BSL.fromStrict $ TE.encodeUtf8 sortedLines
+
+-- | Helper to run dry-run with specified arguments
+runDryRun :: [String] -> IO BSL.ByteString
+runDryRun args = do
+  cwd <- getCurrentDirectory
+  setCurrentDirectory "test/tests"
+  output <- readProcess "stacker" args ""
+  setCurrentDirectory cwd
+  -- Properly encode as UTF-8
+  return $ BSL.fromStrict $ TE.encodeUtf8 $ T.pack output
diff --git a/test/golden/dry-run-files.golden b/test/golden/dry-run-files.golden
new file mode 100644
--- /dev/null
+++ b/test/golden/dry-run-files.golden
@@ -0,0 +1,2 @@
+stack-9.6.yaml      nightly-2023-08-04       → bump to lts-22.44
+stack-9.8.yaml      lts-23.12                → bump to lts-23.28
diff --git a/test/golden/dry-run-recursive.golden b/test/golden/dry-run-recursive.golden
new file mode 100644
--- /dev/null
+++ b/test/golden/dry-run-recursive.golden
@@ -0,0 +1,6 @@
+other/stack.yaml                 lts-24.20                → bump to lts-24.36
+stack-9.6.yaml                   lts-22.40                → bump to lts-22.44
+stack.yaml                       lts-22.40                = symlink to stack-9.6.yaml
+subdir1/stack-9.8.yaml           lts-23.20                → bump to lts-23.28
+subdir1/stack-other.yaml         lts-24.20                = symlink to other/stack.yaml
+subdir1/subdir2/stack-9.10.yaml  nightly-2025-01-01       → bump to lts-24.36
diff --git a/test/golden/dry-run.golden b/test/golden/dry-run.golden
new file mode 100644
--- /dev/null
+++ b/test/golden/dry-run.golden
@@ -0,0 +1,8 @@
+stack-9.0.yaml      nightly-2021-12-04       → bump to lts-19.33
+stack-9.10.yaml     nightly-2025-05-14       → bump to lts-24.36
+stack-9.12.yaml     nightly-2025-10-05       → bump to nightly-2026-04-07
+stack-9.2.yaml      lts-20.1                 → bump to lts-20.26
+stack-9.4.yaml      lts-21.20                → bump to lts-21.25
+stack-9.6.yaml      nightly-2023-08-04       → bump to lts-22.44
+stack-9.8.yaml      lts-23.12                → bump to lts-23.28
+stack.yaml          nightly-2025-05-14       = symlink to stack-9.10.yaml
diff --git a/test/golden/tests/stack-9.0.yaml b/test/golden/tests/stack-9.0.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack-9.0.yaml
@@ -0,0 +1,9 @@
+snapshot: lts-19.33
+compiler: 9.0.2
+compiler-check: match-exact
+
+# Well, then...
+
+extra-deps: [base-4.19]
+# Doesn't make sense, I know...
+
diff --git a/test/golden/tests/stack-9.10.yaml b/test/golden/tests/stack-9.10.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack-9.10.yaml
@@ -0,0 +1,6 @@
+resolver: lts-24.36
+
+packages:
+  - lib/
+  - backends/
+  - executable/
diff --git a/test/golden/tests/stack-9.12.yaml b/test/golden/tests/stack-9.12.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack-9.12.yaml
@@ -0,0 +1,1 @@
+resolver: nightly-2026-04-07
diff --git a/test/golden/tests/stack-9.2.yaml b/test/golden/tests/stack-9.2.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack-9.2.yaml
@@ -0,0 +1,2 @@
+resolver: lts-20.26
+#EOF
diff --git a/test/golden/tests/stack-9.4.yaml b/test/golden/tests/stack-9.4.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack-9.4.yaml
@@ -0,0 +1,15 @@
+# This tests bumping of lts-21.20 to lts-21.25
+# Andreas Abel, 2025-12-10
+
+snapshot: lts-21.25
+
+extra-deps:
+- extra-1.18
+
+flag:
+  Agda:
+    debug: True
+
+extra-deps: [foo-9, bar-10]
+
+# This is already the end.
diff --git a/test/golden/tests/stack-9.6.yaml b/test/golden/tests/stack-9.6.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack-9.6.yaml
@@ -0,0 +1,10 @@
+# This tests bumping some old nightly to lts-22.44
+
+# Andreas Abel, 2025-12-10
+
+resolver: lts-22.44
+
+extra-deps:
+- kailash-9.1.1
+- everest-0.0.0
+# - other-1.2.3
diff --git a/test/golden/tests/stack-9.8.yaml b/test/golden/tests/stack-9.8.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack-9.8.yaml
@@ -0,0 +1,1 @@
+resolver: lts-23.28
diff --git a/test/golden/tests/stack.yaml b/test/golden/tests/stack.yaml
new file mode 100644
--- /dev/null
+++ b/test/golden/tests/stack.yaml
@@ -0,0 +1,6 @@
+resolver: lts-24.36
+
+packages:
+  - lib/
+  - backends/
+  - executable/
diff --git a/test/recursive/other/stack.yaml b/test/recursive/other/stack.yaml
new file mode 100644
--- /dev/null
+++ b/test/recursive/other/stack.yaml
@@ -0,0 +1,3 @@
+# Test file for recursive search - other dir
+
+resolver: lts-24.20
diff --git a/test/recursive/stack-9.6.yaml b/test/recursive/stack-9.6.yaml
new file mode 100644
--- /dev/null
+++ b/test/recursive/stack-9.6.yaml
@@ -0,0 +1,3 @@
+# Test file for recursive search - top level
+
+resolver: lts-22.40
diff --git a/test/recursive/subdir1/stack-9.8.yaml b/test/recursive/subdir1/stack-9.8.yaml
new file mode 100644
--- /dev/null
+++ b/test/recursive/subdir1/stack-9.8.yaml
@@ -0,0 +1,3 @@
+# Test file for recursive search - subdir1
+
+snapshot: lts-23.20
diff --git a/test/recursive/subdir1/subdir2/stack-9.10.yaml b/test/recursive/subdir1/subdir2/stack-9.10.yaml
new file mode 100644
--- /dev/null
+++ b/test/recursive/subdir1/subdir2/stack-9.10.yaml
@@ -0,0 +1,3 @@
+# Test file for recursive search - subdir2
+
+snapshot: nightly-2025-01-01
diff --git a/test/tests/stack-9.0.yaml b/test/tests/stack-9.0.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack-9.0.yaml
@@ -0,0 +1,9 @@
+snapshot: nightly-2021-12-04
+compiler: 9.0.2
+compiler-check: match-exact
+
+# Well, then...
+
+extra-deps: [base-4.19]
+# Doesn't make sense, I know...
+
diff --git a/test/tests/stack-9.10.yaml b/test/tests/stack-9.10.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack-9.10.yaml
@@ -0,0 +1,6 @@
+resolver: nightly-2025-05-14
+
+packages:
+  - lib/
+  - backends/
+  - executable/
diff --git a/test/tests/stack-9.12.yaml b/test/tests/stack-9.12.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack-9.12.yaml
@@ -0,0 +1,1 @@
+resolver: nightly-2025-10-05
diff --git a/test/tests/stack-9.2.yaml b/test/tests/stack-9.2.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack-9.2.yaml
@@ -0,0 +1,2 @@
+resolver: lts-20.1
+#EOF
diff --git a/test/tests/stack-9.4.yaml b/test/tests/stack-9.4.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack-9.4.yaml
@@ -0,0 +1,15 @@
+# This tests bumping of lts-21.20 to lts-21.25
+# Andreas Abel, 2025-12-10
+
+snapshot: lts-21.20
+
+extra-deps:
+- extra-1.18
+
+flag:
+  Agda:
+    debug: True
+
+extra-deps: [foo-9, bar-10]
+
+# This is already the end.
diff --git a/test/tests/stack-9.6.yaml b/test/tests/stack-9.6.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack-9.6.yaml
@@ -0,0 +1,10 @@
+# This tests bumping some old nightly to lts-22.44
+
+# Andreas Abel, 2025-12-10
+
+resolver: nightly-2023-08-04
+
+extra-deps:
+- kailash-9.1.1
+- everest-0.0.0
+# - other-1.2.3
diff --git a/test/tests/stack-9.8.yaml b/test/tests/stack-9.8.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack-9.8.yaml
@@ -0,0 +1,1 @@
+resolver: lts-23.12
diff --git a/test/tests/stack.yaml b/test/tests/stack.yaml
new file mode 100644
--- /dev/null
+++ b/test/tests/stack.yaml
@@ -0,0 +1,6 @@
+resolver: nightly-2025-05-14
+
+packages:
+  - lib/
+  - backends/
+  - executable/
