packages feed

stacker (empty) → 0.0.0.0

raw patch · 46 files changed

+5737/−0 lines, 46 filesdep +aesondep +ansi-terminaldep +base

Dependencies added: aeson, ansi-terminal, base, bytestring, containers, directory, file-embed, filepath, optparse-applicative, process, stacker, tasty, tasty-golden, temporary, text, yaml

Files

+ CHANGELOG.md view
@@ -0,0 +1,7 @@+0.0.0.0+=======++Initial release.+* Tested with GHC 9.4.8 - 9.12.4.++_Andreas Abel, 2026-04-08_
+ LICENSE view
@@ -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.
+ README.md view
@@ -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.
+ app/Main.hs view
@@ -0,0 +1,9 @@+module Main where++import Options (parseOptions)+import Commands (runCommand)++main :: IO ()+main = do+  opts <- parseOptions+  runCommand opts
+ data/ghc.csv view
@@ -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
+ data/lts.csv view
@@ -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
+ data/nightly.csv view
@@ -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
+ src/Analysis.hs view
@@ -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
+ src/CSV.hs view
@@ -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
+ src/ColorOption.hs view
@@ -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
+ src/Commands.hs view
@@ -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
+ src/Config.hs view
@@ -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
+ src/Git.hs view
@@ -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")
+ src/License.hs view
@@ -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")
+ src/Options.hs view
@@ -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
+ src/PathUtil.hs view
@@ -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)
+ src/StackYaml.hs view
@@ -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)
+ src/Types.hs view
@@ -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"
+ src/XDG.hs view
@@ -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"
+ stacker.cabal view
@@ -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
+ test/Main.hs view
@@ -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+  ]
+ test/TestBump.hs view
@@ -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
+ test/TestDryRun.hs view
@@ -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
+ test/golden/dry-run-files.golden view
@@ -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
+ test/golden/dry-run-recursive.golden view
@@ -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
+ test/golden/dry-run.golden view
@@ -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
+ test/golden/tests/stack-9.0.yaml view
@@ -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...+
+ test/golden/tests/stack-9.10.yaml view
@@ -0,0 +1,6 @@+resolver: lts-24.36++packages:+  - lib/+  - backends/+  - executable/
+ test/golden/tests/stack-9.12.yaml view
@@ -0,0 +1,1 @@+resolver: nightly-2026-04-07
+ test/golden/tests/stack-9.2.yaml view
@@ -0,0 +1,2 @@+resolver: lts-20.26+#EOF
+ test/golden/tests/stack-9.4.yaml view
@@ -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.
+ test/golden/tests/stack-9.6.yaml view
@@ -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
+ test/golden/tests/stack-9.8.yaml view
@@ -0,0 +1,1 @@+resolver: lts-23.28
+ test/golden/tests/stack.yaml view
@@ -0,0 +1,6 @@+resolver: lts-24.36++packages:+  - lib/+  - backends/+  - executable/
+ test/recursive/other/stack.yaml view
@@ -0,0 +1,3 @@+# Test file for recursive search - other dir++resolver: lts-24.20
+ test/recursive/stack-9.6.yaml view
@@ -0,0 +1,3 @@+# Test file for recursive search - top level++resolver: lts-22.40
+ test/recursive/subdir1/stack-9.8.yaml view
@@ -0,0 +1,3 @@+# Test file for recursive search - subdir1++snapshot: lts-23.20
+ test/recursive/subdir1/subdir2/stack-9.10.yaml view
@@ -0,0 +1,3 @@+# Test file for recursive search - subdir2++snapshot: nightly-2025-01-01
+ test/tests/stack-9.0.yaml view
@@ -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...+
+ test/tests/stack-9.10.yaml view
@@ -0,0 +1,6 @@+resolver: nightly-2025-05-14++packages:+  - lib/+  - backends/+  - executable/
+ test/tests/stack-9.12.yaml view
@@ -0,0 +1,1 @@+resolver: nightly-2025-10-05
+ test/tests/stack-9.2.yaml view
@@ -0,0 +1,2 @@+resolver: lts-20.1+#EOF
+ test/tests/stack-9.4.yaml view
@@ -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.
+ test/tests/stack-9.6.yaml view
@@ -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
+ test/tests/stack-9.8.yaml view
@@ -0,0 +1,1 @@+resolver: lts-23.12
+ test/tests/stack.yaml view
@@ -0,0 +1,6 @@+resolver: nightly-2025-05-14++packages:+  - lib/+  - backends/+  - executable/