diff --git a/.github/release.yaml b/.github/release.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0f4884c9444e4b563eb90bd01b51e0dd3a29bf98
--- /dev/null
+++ b/.github/release.yaml
@@ -0,0 +1,18 @@
+changelog:
+  exclude:
+    labels:
+      - ignore-for-release
+    authors:
+      - dependabot 
+  categories:
+    - title: Breaking Changes 🛠
+      labels:
+        - semver-major
+        - breaking-change
+    - title: New Features 🎉
+      labels:
+        - semver-minor
+        - enhancement
+    - title: Other Changes
+      labels:
+        - '*'
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 77127856c380bb304bc9508a984191c787944f60..88d17826ea5f2985261ef0c2dcc6cef8ee458c9b 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -4,7 +4,7 @@ on:
   workflow_dispatch:
   pull_request:
   push:
-    branches: [main, contribute]
+    branches: ["*"]
     tags: ["*"]
 
 jobs:
@@ -12,47 +12,84 @@ jobs:
     strategy:
       matrix:
         runner: [windows-large, macos-12-xl]
-        configuration: [ReleaseOS]
-        addrsize: [64]
+        configuration: [Release, ReleaseOS]
+        python-version: ["3.11"]
         include:
           - runner: macos-12-xl
             developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer"
+        exclude:
+          - runner: macos-12-xl
     runs-on: ${{ matrix.runner }}
+    outputs:
+      viewer_channel: ${{ steps.build.outputs.viewer_channel }}
+      viewer_version: ${{ steps.build.outputs.viewer_version }}
+      imagename: ${{ steps.build.outputs.imagename }}
     env:
+      AUTOBUILD_ADDRSIZE: 64
+      AUTOBUILD_BUILD_ID: ${{ github.run_id }}
       AUTOBUILD_CONFIGURATION: ${{ matrix.configuration }}
-      AUTOBUILD_ADDRSIZE: ${{ matrix.addrsize }}
+      # authorizes fetching private constituent packages
+      AUTOBUILD_GITHUB_TOKEN: ${{ secrets.SHARED_AUTOBUILD_GITHUB_TOKEN }}
       AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables
       AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables
-      AUTOBUILD_VSVER: "170" # vs2k22
+      AUTOBUILD_VSVER: "170"
       DEVELOPER_DIR: ${{ matrix.developer_dir }}
-      LOGFAIL: debug # Show details when tests fail
+      # Ensure that Linden viewer builds engage Bugsplat.
+      BUGSPLAT_DB: ${{ matrix.configuration != 'ReleaseOS' && 'SecondLife_Viewer_2018' || '' }}
+      BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
+      BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
+      build_coverity: false
+      build_log_dir: ${{ github.workspace }}/.logs
+      build_viewer: true
+      BUILDSCRIPTS_SHARED: ${{ github.workspace }}/.shared
+      # extracted and committed to viewer repo
+      BUILDSCRIPTS_SUPPORT_FUNCTIONS: ${{ github.workspace }}/buildscripts_support_functions
       GIT_REF: ${{ github.head_ref || github.ref }}
       LL_SKIP_REQUIRE_SYSROOT: 1
+      # Setting this variable directs Linden's TUT test driver code to capture
+      # test-program log output at the specified level, but to display it only if
+      # the individual test fails.
+      LOGFAIL: DEBUG
+      master_message_template_checkout: ${{ github.workspace }}/.master-message-template
+      # Only set variants to the one configuration: don't let build.sh loop
+      # over variants, let GitHub distribute variants over multiple hosts.
+      variants: ${{ matrix.configuration }}
     steps:
       - name: Checkout code
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           ref: ${{ github.event.pull_request.head.sha || github.sha }}
 
+      - name: Setup python
+        uses: actions/setup-python@v4
+        with:
+          python-version: ${{ matrix.python-version }}
+
       - name: Checkout build variables
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           repository: secondlife/build-variables
           ref: viewer
           path: .build-variables
 
+      - name: Checkout master-message-template
+        uses: actions/checkout@v4
+        with:
+          repository: secondlife/master-message-template
+          path: .master-message-template
+
       - name: Install autobuild and python dependencies
-        run: pip3 install autobuild llbase
+        run: pip3 install autobuild llsd
 
       - name: Cache autobuild packages
         uses: actions/cache@v3
         id: cache-installables
         with:
           path: .autobuild-installables
-          key: ${{ runner.os }}-${{ matrix.addrsize }}-${{ matrix.configuration }}-${{ hashFiles('autobuild.xml') }}
+          key: ${{ runner.os }}-64-${{ matrix.configuration }}-${{ hashFiles('autobuild.xml') }}
           restore-keys: |
-            ${{ runner.os }}-${{ matrix.addrsize }}-${{ matrix.configuration }}-
-            ${{ runner.os }}-${{ matrix.addrsize }}-
+            ${{ runner.os }}-64-${{ matrix.configuration }}-
+            ${{ runner.os }}-64-
 
       - name: Install windows dependencies
         if: runner.os == 'Windows'
@@ -64,31 +101,266 @@ jobs:
         env:
           RUNNER_OS: ${{ runner.os }}
         run: |
+          # set up things the viewer's build.sh script expects
+          set -x
+          mkdir -p "$build_log_dir"
+          mkdir -p "$BUILDSCRIPTS_SHARED/packages/lib/python"
+          source "$BUILDSCRIPTS_SUPPORT_FUNCTIONS"
+          if [[ "$OSTYPE" =~ cygwin|msys ]]
+          then
+            native_path() { cygpath --windows "$1"; }
+            shell_path()  { cygpath --unix "$1"; }
+          else
+            native_path() { echo "$1"; }
+            shell_path()  { echo "$1"; }
+          fi
+          finalize()
+          {
+            case "$1" in
+              true|0)
+                record_success "Build Succeeded"
+                ;;
+              *)
+                record_failure "Build Failed with $1"
+                ;;
+            esac
+          }
+          initialize_build()
+          {
+            echo "initialize_build"
+          }
+          initialize_version()
+          {
+            export revision="$AUTOBUILD_BUILD_ID"
+          }
+          python_cmd()
+          {
+              if [[ "x${1:0:1}" == "x-" ]]    # -m, -c, etc.
+              then # if $1 is a switch, don't try to twiddle paths
+                   "$(shell_path "$PYTHON_COMMAND")" "$@"
+              elif [[ "$(basename "$1")" == "codeticket.py" ]]
+              then # ignore any attempt to contact codeticket
+                   echo "## $@"
+              else # running a script at an explicit path: fix path for Python
+                   local script="$1"
+                   shift
+                   "$(shell_path "$PYTHON_COMMAND")" "$(native_path "$script")" "$@"
+              fi
+          }
+          repo_branch()
+          {
+            git -C "$1" branch | grep '^* ' | cut -c 3-
+          }
+          record_dependencies_graph()
+          {
+            echo "TODO: generate and post dependency graph"
+          }
+          # Since we're not uploading to codeticket, DO NOT sleep for minutes.
+          sleep()
+          {
+            echo "Not sleeping for $1 seconds"
+          }
+          export -f native_path shell_path finalize initialize_build initialize_version
+          export -f python_cmd repo_branch record_dependencies_graph sleep
+          ## Useful for diagnosing Windows LLProcess/LLLeap test failures
+          ##export APR_LOG="${RUNNER_TEMP}/apr.log"
+          export arch=$(uname | cut -b-6)
+          # Surprise! GH Windows runner's MINGW6 is a $arch value we've never
+          # seen before, so numerous tests don't know about it.
+          [[ "$arch" == "MINGW6" ]] && arch=CYGWIN
+          export AUTOBUILD="$(which autobuild)"
+          # Build with a tag like "Second_Life_Project_Shiny#abcdef0" to get a
+          # viewer channel "Second Life Project Shiny" (ignoring "#hash",
+          # needed to disambiguate tags).
+          if [[ "$GITHUB_REF_TYPE" == "tag" && "${GITHUB_REF_NAME:0:12}" == "Second_Life_" ]]
+          then viewer_channel="${GITHUB_REF_NAME%#*}"
+               export viewer_channel="${viewer_channel//_/ }"
+          else export viewer_channel="Second Life Test"
+          fi
+          echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT"
+
           # On windows we need to point the build to the correct python
           # as neither CMake's FindPython nor our custom Python.cmake module
           # will resolve the correct interpreter location.
           if [[ "$RUNNER_OS" == "Windows" ]]; then
-            export PYTHON="$(cygpath -m "$(which python)")"
+            export PYTHON="$(native_path "$(which python)")"
             echo "Python location: $PYTHON"
+            export PYTHON_COMMAND="$PYTHON"
+          else
+            export PYTHON_COMMAND="python3"
           fi
-          
-          autobuild configure -- -DVIEWER_CHANNEL="Second Life Test ${GIT_REF##*/}"
-          autobuild  build --no-configure
+          export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")"
 
-          # Find artifacts
-          if [[ "$RUNNER_OS" == "Windows" ]]; then
-            installer_path=$(find ./build-*/newview/ | grep '_Setup\.exe')
-            installer_name="$(basename $installer_path)"
-          elif [[ "$RUNNER_OS" == "macOS" ]]; then
-            installer_path=$(find ./build-*/newview/ | grep '\.dmg')
-            installer_name="$(basename $installer_path)"
+          ./build.sh
+
+          # Each artifact is downloaded as a distinct .zip file. Multiple jobs
+          # (per the matrix above) writing the same filepath to the same
+          # artifact name will *overwrite* that file. Moreover, they can
+          # interfere with each other, causing the upload to fail.
+          # https://github.com/actions/upload-artifact#uploading-to-the-same-artifact
+          # Given the size of our installers, and the fact that we typically
+          # only want to download just one instead of a single zip containing
+          # several, generate a distinct artifact name for each installer.
+          # If the matrix above can run multiple builds on the same
+          # platform, we must disambiguate on more than the platform name.
+          # e.g. if we were still running Windows 32-bit builds, we'd need to
+          # qualify the artifact with bit width.
+          if [[ "$AUTOBUILD_CONFIGURATION" == "ReleaseOS" ]]
+          then cfg_suffix='OS'
+          else cfg_suffix=''
           fi
+          echo "artifact=$RUNNER_OS$cfg_suffix" >> $GITHUB_OUTPUT
 
-          echo "installer_path=$installer_path" >> $GITHUB_OUTPUT
-          echo "installer_name=$installer_name" >> $GITHUB_OUTPUT
-      
-      - name: Upload installer
+      - name: Upload executable
+        if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.viewer_app
         uses: actions/upload-artifact@v3
         with:
-          name: ${{ steps.build.outputs.installer_name }}
-          path: ${{ steps.build.outputs.installer_path }}
+          name: "${{ steps.build.outputs.artifact }}-app"
+          path: |
+            ${{ steps.build.outputs.viewer_app }}
+
+      # The other upload of nontrivial size is the symbol file. Use a distinct
+      # artifact for that too.
+      - name: Upload symbol file
+        if: matrix.configuration != 'ReleaseOS'
+        uses: actions/upload-artifact@v3
+        with:
+          name: "${{ steps.build.outputs.artifact }}-symbols"
+          path: |
+            ${{ steps.build.outputs.symbolfile }}
+
+      - name: Upload metadata
+        if: matrix.configuration != 'ReleaseOS'
+        uses: actions/upload-artifact@v3
+        with:
+          name: "${{ steps.build.outputs.artifact }}-metadata"
+          # emitted by build.sh, possibly multiple lines
+          path: |
+            ${{ steps.build.outputs.metadata }}
+
+      - name: Upload physics package
+        uses: actions/upload-artifact@v3
+        # should only be set for viewer-private
+        if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.physicstpv
+        with:
+          name: "${{ steps.build.outputs.artifact }}-physics"
+          # emitted by build.sh, zero or one lines
+          path: |
+            ${{ steps.build.outputs.physicstpv }}
+
+  sign-and-package-windows:
+    needs: build
+    runs-on: windows
+    steps:
+      - name: Sign and package Windows viewer
+        uses: secondlife/viewer-build-util/sign-pkg-windows@main
+        with:
+          vault_uri: "${{ secrets.AZURE_KEY_VAULT_URI }}"
+          cert_name: "${{ secrets.AZURE_CERT_NAME }}"
+          client_id: "${{ secrets.AZURE_CLIENT_ID }}"
+          client_secret: "${{ secrets.AZURE_CLIENT_SECRET }}"
+          tenant_id: "${{ secrets.AZURE_TENANT_ID }}"
+
+  sign-and-package-mac:
+    needs: build
+    runs-on: macos-latest
+    steps:
+      - name: Unpack Mac notarization credentials
+        id: note-creds
+        shell: bash
+        run: |
+          # In NOTARIZE_CREDS_MACOS we expect to find:
+          # USERNAME="..."
+          # PASSWORD="..."
+          # TEAM_ID="..."
+          eval "${{ secrets.NOTARIZE_CREDS_MACOS }}"
+          echo "::add-mask::$USERNAME"
+          echo "::add-mask::$PASSWORD"
+          echo "::add-mask::$TEAM_ID"
+          echo "note_user=$USERNAME" >> "$GITHUB_OUTPUT"
+          echo "note_pass=$PASSWORD" >> "$GITHUB_OUTPUT"
+          echo "note_team=$TEAM_ID" >> "$GITHUB_OUTPUT"
+          # If we didn't manage to retrieve all of these credentials, better
+          # find out sooner than later.
+          [[ -n "$USERNAME" && -n "$PASSWORD" && -n "$TEAM_ID" ]]
+
+      - name: Sign and package Mac viewer
+        uses: secondlife/viewer-build-util/sign-pkg-mac@main
+        with:
+          channel: ${{ needs.build.outputs.viewer_channel }}
+          imagename: ${{ needs.build.outputs.imagename }}
+          cert_base64: ${{ secrets.SIGNING_CERT_MACOS }}
+          cert_name: ${{ secrets.SIGNING_CERT_MACOS_IDENTITY }}
+          cert_pass: ${{ secrets.SIGNING_CERT_MACOS_PASSWORD }}
+          note_user: ${{ steps.note-creds.outputs.note_user }}
+          note_pass: ${{ steps.note-creds.outputs.note_pass }}
+          note_team: ${{ steps.note-creds.outputs.note_team }}
+
+  post-windows-symbols:
+    needs: build
+    runs-on: ubuntu-latest
+    steps:
+      - name: Post Windows symbols
+        uses: secondlife/viewer-build-util/post-bugsplat-windows@main
+        with:
+          username: ${{ secrets.BUGSPLAT_USER }}
+          password: ${{ secrets.BUGSPLAT_PASS }}
+          database: "SecondLife_Viewer_2018"
+          channel: ${{ needs.build.outputs.viewer_channel }}
+          version: ${{ needs.build.outputs.viewer_version }}
+
+  post-mac-symbols:
+    needs: build
+    runs-on: ubuntu-latest
+    steps:
+      - name: Post Mac symbols
+        uses: secondlife/viewer-build-util/post-bugsplat-mac@main
+        with:
+          username: ${{ secrets.BUGSPLAT_USER }}
+          password: ${{ secrets.BUGSPLAT_PASS }}
+          database: "SecondLife_Viewer_2018"
+          channel: ${{ needs.build.outputs.viewer_channel }}
+          version: ${{ needs.build.outputs.viewer_version }}
+
+  release:
+    needs: [sign-and-package-windows, sign-and-package-mac]
+    runs-on: ubuntu-latest
+    if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life_')
+    steps:
+      - uses: actions/download-artifact@v3
+        with:
+          path: artifacts
+
+      - name: Reshuffle artifact files
+        uses: secondlife/viewer-build-util/release-artifacts@main
+        with:
+          input-path: artifacts
+          output-path: assets
+          # The *-app artifacts are for use only by the signing and
+          # packaging steps. Once we've generated signed installers, we no
+          # longer need them, and we CERTAINLY don't want to publish
+          # thousands of individual files as separate URLs.
+          exclude: |-
+            Windows-app
+            macOS-app
+          # Use just "Windows" or "macOS" prefix because these are the only
+          # artifacts in which we expect files from both platforms with
+          # colliding names (e.g. autobuild-package.xml). release-artifacts
+          # normally resolves collisions by prepending the artifact name, so
+          # when we anticipate collisions, it's good to keep the prefix
+          # short and sweet.
+          prefix: |-
+            Windows-metadata=Windows
+            macOS-metadata=macOS
+
+      # forked from softprops/action-gh-release
+      - uses: secondlife-3p/action-gh-release@v1
+        with:
+          # name the release page for the build number so we can find it
+          # easily (analogous to looking up a codeticket build page)
+          name: "v${{ github.run_id }}"
+          prerelease: true
+          generate_release_notes: true
+          # the only reason we generate a GH release is to post build products
+          fail_on_unmatched_files: true
+          files: "assets/*"
diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
index 17c0ace02fc3fd46b3f4105560ef9aee9ee2e859..d626eef38d7fe3fff3c604537838c95b7fdb560c 100644
--- a/.github/workflows/pre-commit.yaml
+++ b/.github/workflows/pre-commit.yaml
@@ -11,7 +11,7 @@ jobs:
   pre-commit:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: actions/setup-python@v4
         with:
           python-version: 3.x
diff --git a/.gitignore b/.gitignore
index d9b0b9eb200035d883af599c0ac1f2632300d6b1..fc75db76bba8a73a28d7765029d185bbc49e0eec 100755
--- a/.gitignore
+++ b/.gitignore
@@ -86,4 +86,6 @@ tarfile_tmp
 trivial_change_force_build
 web/config.*
 web/locale.*
-web/secondlife.com.*
\ No newline at end of file
+web/secondlife.com.*
+
+.env
diff --git a/autobuild.xml b/autobuild.xml
index 4dcca3a0131f025ea797d9075ec7fe61452c0631..37371746d5651acd9ab0d14280af4cc6ac982472 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1,20 +1,14 @@
 <?xml version="1.0" ?>
 <llsd>
 <map>
+    <key>version</key>
+    <string>1.3</string>
+    <key>type</key>
+    <string>autobuild</string>
     <key>installables</key>
     <map>
       <key>SDL</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (C) 1997-2012 Sam Lantinga</string>
-        <key>description</key>
-        <string>Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.</string>
-        <key>license</key>
-        <string>lgpl</string>
-        <key>license_file</key>
-        <string>LICENSES/SDL.txt</string>
-        <key>name</key>
-        <string>SDL</string>
         <key>platforms</key>
         <map>
           <key>linux64</key>
@@ -30,21 +24,21 @@
             <string>linux64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>lgpl</string>
+        <key>license_file</key>
+        <string>LICENSES/SDL.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 1997-2012 Sam Lantinga</string>
         <key>version</key>
         <string>1.2.15</string>
+        <key>name</key>
+        <string>SDL</string>
+        <key>description</key>
+        <string>Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.</string>
       </map>
       <key>apr_suite</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.</string>
-        <key>description</key>
-        <string>Apache portable runtime project</string>
-        <key>license</key>
-        <string>apache</string>
-        <key>license_file</key>
-        <string>LICENSES/apr_suite.txt</string>
-        <key>name</key>
-        <string>apr_suite</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -52,9 +46,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>178b16ee9ff67986c8c14413ee68218e</string>
+              <string>dc4a38439f90325b406ec3f7cc4fa66edf0eeec8</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107593/938535/apr_suite-1.4.5.576669-darwin64-576669.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.2-e935465/apr_suite-1.7.2-e935465-darwin64-e935465.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -71,46 +67,36 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>d2997cad03dbd0d70a060276b5671480</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107594/938548/apr_suite-1.4.5.576669-windows-576669.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ec24f5945faa8f13807b83eeaeb994f8</string>
+              <string>8233de9a11f323a03d569db1043ba5198176457b</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107592/938547/apr_suite-1.4.5.576669-windows64-576669.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.2-e935465/apr_suite-1.7.2-e935465-windows64-e935465.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>apache</string>
+        <key>license_file</key>
+        <string>LICENSES/apr_suite.txt</string>
+        <key>copyright</key>
+        <string>Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.</string>
         <key>version</key>
-        <string>1.4.5.576669</string>
+        <string>1.7.2-e935465</string>
+        <key>name</key>
+        <string>apr_suite</string>
+        <key>description</key>
+        <string>Apache portable runtime project</string>
       </map>
       <key>boost</key>
       <map>
-        <key>copyright</key>
-        <string>(see individual source files)</string>
-        <key>description</key>
-        <string>Boost C++ Libraries</string>
-        <key>license</key>
-        <string>boost 1.0</string>
-        <key>license_file</key>
-        <string>LICENSES/boost.txt</string>
-        <key>name</key>
-        <string>boost</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -118,9 +104,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>fedc8d63856f534b6098102e059dc548</string>
+              <string>59c1827cab82516504a2eb31e0aa7e38035b5085</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87776/805857/boost-1.72-darwin64-563847.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-boost/releases/download/v1.81-90bb2df/boost-1.81-darwin64-90bb2df.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -137,46 +125,36 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>6cc9fb4ca21365c4470a3e516544ba71</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87784/805850/boost-1.72-windows-563847.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0c526efc3f8825cd25cdf635e238fab3</string>
+              <string>26214a33c568929ffeeb3463ce183f2888ce4fe4</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87783/805851/boost-1.72-windows64-563847.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-boost/releases/download/v1.81-90bb2df/boost-1.81-windows64-90bb2df.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>boost 1.0</string>
+        <key>license_file</key>
+        <string>LICENSES/boost.txt</string>
+        <key>copyright</key>
+        <string>(see individual source files)</string>
         <key>version</key>
-        <string>1.72</string>
+        <string>1.81</string>
+        <key>name</key>
+        <string>boost</string>
+        <key>description</key>
+        <string>Boost C++ Libraries</string>
       </map>
       <key>bugsplat</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright 2003-2017, BugSplat</string>
-        <key>description</key>
-        <string>Bugsplat crash reporting package</string>
-        <key>license</key>
-        <string>Proprietary</string>
-        <key>license_file</key>
-        <string>LICENSES/BUGSPLAT_LICENSE.txt</string>
-        <key>name</key>
-        <string>bugsplat</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -184,51 +162,45 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>27a77bfba1fa56fd59f4f26605baac35</string>
+              <string>d152f19f4a5a9c8013f006e19b1fcd88692bccf1</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113802/983479/bugsplat-1.0.7.579669-darwin64-579669.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.0.7-527603a/bugsplat-1.0.7-527603a-darwin64-527603a.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>c5abb9545039bd9113c8bf11d58f4501</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113803/983490/bugsplat-4.0.3.0.579669-windows-579669.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>45e9b9215ce653171b572f44ee7bbf0c</string>
+              <string>1364da04333570b73c771e4f4acd1bacc7fc3f02</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113804/983491/bugsplat-4.0.3.0.579669-windows64-579669.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-bugsplat/releases/download/v1.0.7-527603a/bugsplat-4.0.3.0-527603a-windows64-527603a.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>Proprietary</string>
+        <key>license_file</key>
+        <string>LICENSES/BUGSPLAT_LICENSE.txt</string>
+        <key>copyright</key>
+        <string>Copyright 2003-2017, BugSplat</string>
         <key>version</key>
-        <string>4.0.3.0.579669</string>
+        <string>4.0.3.0-527603a</string>
+        <key>name</key>
+        <string>bugsplat</string>
+        <key>description</key>
+        <string>Bugsplat crash reporting package</string>
       </map>
       <key>colladadom</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright 2006 Sony Computer Entertainment Inc.</string>
-        <key>license</key>
-        <string>SCEA</string>
-        <key>license_file</key>
-        <string>LICENSES/collada.txt</string>
-        <key>name</key>
-        <string>colladadom</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -236,9 +208,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a880dfc15fcb330baf548a85324cd88a</string>
+              <string>7f447d30d7add80270a55cf3c53000392821a1cb</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104133/913090/colladadom-2.3.574693-darwin64-574693.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3.d1ef72a/colladadom-2.3.d1ef72a-darwin64-d1ef72a.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -255,44 +229,34 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>7e84441d9c7cf019a7bdc7b818b16c27</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104112/912957/colladadom-2.3.574693-windows-574693.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2eaffbb8a93b03a732d3c47055a8efcb</string>
+              <string>b32294a2f31f5b4ca49928e66832aad1bb4a88ac</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104135/913103/colladadom-2.3.574693-windows64-574693.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3.d1ef72a/colladadom-2.3.d1ef72a-windows64-d1ef72a.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>SCEA</string>
+        <key>license_file</key>
+        <string>LICENSES/collada.txt</string>
+        <key>copyright</key>
+        <string>Copyright 2006 Sony Computer Entertainment Inc.</string>
         <key>version</key>
-        <string>2.3.574693</string>
+        <string>2.3.d1ef72a</string>
+        <key>name</key>
+        <string>colladadom</string>
       </map>
       <key>cubemaptoequirectangular</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2017 Jaume Sanchez Elias, http://www.clicktorelease.com</string>
-        <key>license</key>
-        <string>MIT</string>
-        <key>license_file</key>
-        <string>LICENSES/CUBEMAPTOEQUIRECTANGULAR_LICENSE.txt</string>
-        <key>name</key>
-        <string>cubemaptoequirectangular</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -300,9 +264,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7e4622b497bc465b01ff6d3e7e0b4214</string>
+              <string>d5fb3832a338bbe4891b823c64fdb4806706568e</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89303/815402/cubemaptoequirectangular-1.1.0-darwin64-564841.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-darwin64-d7afe27.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -312,51 +278,41 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ac54672e0b38f52726f5c99047c913e4</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89306/815431/cubemaptoequirectangular-1.1.0-windows64-564841.tar.bz2</string>
-            </map>
-          </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>b5ea7097ae10037024b0c2b3df9812b5</string>
+              <string>77c53daf558f51aec6e9f4bd9e930a103630ee7d</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89307/815434/cubemaptoequirectangular-1.1.0-windows-564841.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-linux64-d7afe27.tar.zst</string>
             </map>
-            <key>name</key>
-            <string>windows</string>
           </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ac54672e0b38f52726f5c99047c913e4</string>
+              <string>6c51855bcf3a8628289881fdaea08c25cf7b1b90</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89306/815431/cubemaptoequirectangular-1.1.0-windows64-564841.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-windows64-d7afe27.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>MIT</string>
+        <key>license_file</key>
+        <string>LICENSES/CUBEMAPTOEQUIRECTANGULAR_LICENSE.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2017 Jaume Sanchez Elias, http://www.clicktorelease.com</string>
         <key>version</key>
         <string>1.1.0</string>
+        <key>name</key>
+        <string>cubemaptoequirectangular</string>
       </map>
       <key>curl</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se).</string>
-        <key>description</key>
-        <string>Library for transferring data specified with URL syntax</string>
-        <key>license</key>
-        <string>curl</string>
-        <key>license_file</key>
-        <string>LICENSES/curl.txt</string>
-        <key>name</key>
-        <string>curl</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -364,9 +320,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>44d801e05811269d1bed7dbc75d85843</string>
+              <string>d4d5f27008de1ff7e86ae852841c68849b02eaea</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87786/805905/curl-7.54.1.563852-darwin64-563852.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-5a4a82d/curl-7.54.1-5a4a82d-darwin64-5a4a82d.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -383,48 +341,36 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>676f624d4ebdc2189caa43ef6dd8266d</string>
-              <key>hash_algorithm</key>
-              <string>md5</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87790/805917/curl-7.54.1.563852-windows-563852.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b3db5a2cdf275c1af7758fbe2d14544a</string>
+              <string>07423f41d1320ea405f493869f6460cf8c45def5</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87789/805918/curl-7.54.1.563852-windows64-563852.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-curl/releases/download/v7.54.1-5a4a82d/curl-7.54.1-5a4a82d-windows64-5a4a82d.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>curl</string>
+        <key>license_file</key>
+        <string>LICENSES/curl.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se).</string>
         <key>version</key>
-        <string>7.54.1.563852</string>
+        <string>7.54.1-5a4a82d</string>
+        <key>name</key>
+        <string>curl</string>
+        <key>description</key>
+        <string>Library for transferring data specified with URL syntax</string>
       </map>
       <key>dbus_glib</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (C) Red Hat Inc.</string>
-        <key>description</key>
-        <string>D-Bus bindings for glib</string>
-        <key>license</key>
-        <string>Academic Free License v. 2.1</string>
-        <key>license_file</key>
-        <string>LICENSES/dbus-glib.txt</string>
-        <key>name</key>
-        <string>dbus_glib</string>
         <key>platforms</key>
         <map>
           <key>linux64</key>
@@ -440,21 +386,21 @@
             <string>linux64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>Academic Free License v. 2.1</string>
+        <key>license_file</key>
+        <string>LICENSES/dbus-glib.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) Red Hat Inc.</string>
         <key>version</key>
         <string>0.76</string>
+        <key>name</key>
+        <string>dbus_glib</string>
+        <key>description</key>
+        <string>D-Bus bindings for glib</string>
       </map>
       <key>dictionaries</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright 2014 Apache OpenOffice software</string>
-        <key>description</key>
-        <string>Spell checking dictionaries to bundled into the viewer</string>
-        <key>license</key>
-        <string>various open source</string>
-        <key>license_file</key>
-        <string>LICENSES/dictionaries.txt</string>
-        <key>name</key>
-        <string>dictionaries</string>
         <key>platforms</key>
         <map>
           <key>common</key>
@@ -462,29 +408,31 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d778c6a3475bc35ee8b9615dfc38b4a9</string>
+              <string>f6835c4d7745cd1cadfbce47b40331d08affb532</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55025/511964/dictionaries-1.538984-common-538984.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-dictionaries/releases/download/v1.0.1-dev2.gf887629-f887629/dictionaries-common-None.tar.zst</string>
             </map>
             <key>name</key>
             <string>common</string>
           </map>
         </map>
+        <key>license</key>
+        <string>various open source</string>
+        <key>license_file</key>
+        <string>LICENSES/dictionaries.txt</string>
+        <key>copyright</key>
+        <string>Copyright 2014 Apache OpenOffice software</string>
         <key>version</key>
-        <string>1.538984</string>
+        <string>None</string>
+        <key>name</key>
+        <string>dictionaries</string>
+        <key>description</key>
+        <string>Spell checking dictionaries to bundled into the viewer</string>
       </map>
       <key>dullahan</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2017, Linden Research, Inc.</string>
-        <key>description</key>
-        <string>A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies.</string>
-        <key>license</key>
-        <string>MPL</string>
-        <key>license_file</key>
-        <string>LICENSES/LICENSE.txt</string>
-        <key>name</key>
-        <string>dullahan</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -492,53 +440,45 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>439d92ec73f0500ba1671faad2bd8090</string>
+              <string>e4d568c166049ce61b39d69887b56d2382781a1a</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104637/916643/dullahan-1.12.4.202209142017_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-575005.tar.bz2</string>
+              <string>https://github.com/secondlife/dullahan/releases/download/v118.0.5993.54/dullahan-1.14.0.202310131309_118.4.1_g3dd6078_chromium-118.0.5993.54-darwin64-6b02a60.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>2a7c01da15de77bc1fd1863327174d5e</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104638/916654/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-575005.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d06bee9b2517fbb09ba1a65e6d675361</string>
+              <string>a00eae7f5dc430ae48389ab723ced39739b0a144</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104639/916659/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-575005.tar.bz2</string>
+              <string>https://github.com/secondlife/dullahan/releases/download/v118.0.5993.54/dullahan-1.14.0.202310131404_118.4.1_g3dd6078_chromium-118.0.5993.54-windows64-6b02a60.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>MPL</string>
+        <key>license_file</key>
+        <string>LICENSES/LICENSE.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2017, Linden Research, Inc.</string>
         <key>version</key>
-        <string>1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
+        <string>1.14.0.202310131404_118.4.1_g3dd6078_chromium-118.0.5993.54</string>
+        <key>name</key>
+        <string>dullahan</string>
+        <key>description</key>
+        <string>A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies.</string>
       </map>
       <key>expat</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.</string>
-        <key>description</key>
-        <string>Expat is an XML parser library written in C</string>
-        <key>license</key>
-        <string>expat</string>
-        <key>license_file</key>
-        <string>LICENSES/expat.txt</string>
-        <key>name</key>
-        <string>expat</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -546,9 +486,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f4e80e0dfcab713a3da90cd8f7f23e7b</string>
+              <string>b85526ca80b6a7e73c7870285cf68d568f742095</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76341/727265/expat-2.1.1.555519-darwin64-555519.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-expat/releases/download/v2.1.1.1f36d02/expat-2.1.1.1f36d02-darwin64-1f36d02.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -558,63 +500,59 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5e1f025d1cebd12db542080aa755257f</string>
+              <string>4cd82e2dec06ddff19e9b3dc0254f2593ec80452</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/380/943/expat-2.1.1.500375-linux64-500375.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-expat/releases/download/v2.1.1.1f36d02/expat-2.1.1.1f36d02-linux64-1f36d02.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>cd4fe03473076c324d80ae3bd91a85bb</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76343/727273/expat-2.1.1.555519-windows-555519.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d2d74d73b914150982b1883a3b96e60b</string>
+              <string>47c01a89bc32c5740efe51be43e459ffd9b7cd34</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76344/727279/expat-2.1.1.555519-windows64-555519.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-expat/releases/download/v2.1.1.1f36d02/expat-2.1.1.1f36d02-windows64-1f36d02.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>expat</string>
+        <key>license_file</key>
+        <string>LICENSES/expat.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.</string>
         <key>version</key>
-        <string>2.1.1.555519</string>
+        <string>2.1.1.1f36d02</string>
+        <key>name</key>
+        <string>expat</string>
+        <key>description</key>
+        <string>Expat is an XML parser library written in C</string>
       </map>
       <key>fmodstudio</key>
       <map>
-        <key>copyright</key>
-        <string>FMOD Studio by Firelight Technologies Pty Ltd.</string>
-        <key>description</key>
-        <string>FMOD Studio API</string>
-        <key>license</key>
-        <string>fmod</string>
-        <key>license_file</key>
-        <string>LICENSES/fmodstudio.txt</string>
-        <key>name</key>
-        <string>fmodstudio</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>5a1d52ec3981292855a179be86988a02</string>
+              <string>fb6797ff93b6e881b060d2a8b396d8d7477834ee</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/112152/972159/fmodstudio-2.02.13.578928-darwin64-578928.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-fmodstudio/releases/assets/108908444</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -623,54 +561,50 @@
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>24b86630ccdfb5b3221f90ca7a9704f6</string>
+              <string>a378bd1604aa97ca763140911f9f4e463ced85c0</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89682/818423/fmodstudio-2.02.03.565082-linux-565082.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-fmodstudio/releases/assets/108908446</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>8594ec180b73be42d37b6f93ac59ab4a</string>
-              <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/112153/972171/fmodstudio-2.02.13.578928-windows-578928.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>46941a2610f83c353e551d300e536c54</string>
+              <string>72304491d86bd797b840999b255358f195b06609</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/112154/972170/fmodstudio-2.02.13.578928-windows64-578928.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-fmodstudio/releases/assets/108908456</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>fmod</string>
+        <key>license_file</key>
+        <string>LICENSES/fmodstudio.txt</string>
+        <key>copyright</key>
+        <string>FMOD Studio by Firelight Technologies Pty Ltd.</string>
         <key>version</key>
         <string>2.02.13.578928</string>
+        <key>name</key>
+        <string>fmodstudio</string>
+        <key>description</key>
+        <string>FMOD Studio API</string>
       </map>
       <key>fontconfig</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Å egan, 2012 Google, Inc.</string>
-        <key>description</key>
-        <string>Fontconfig is a library for configuring and customizing font access.</string>
-        <key>license</key>
-        <string>bsd</string>
-        <key>license_file</key>
-        <string>LICENSES/fontconfig.txt</string>
-        <key>name</key>
-        <string>fontconfig</string>
         <key>platforms</key>
         <map>
           <key>linux64</key>
@@ -686,21 +620,21 @@
             <string>linux64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>bsd</string>
+        <key>license_file</key>
+        <string>LICENSES/fontconfig.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Å egan, 2012 Google, Inc.</string>
         <key>version</key>
         <string>2.11.0</string>
+        <key>name</key>
+        <string>fontconfig</string>
+        <key>description</key>
+        <string>Fontconfig is a library for configuring and customizing font access.</string>
       </map>
       <key>freetype</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
-        <key>description</key>
-        <string>Font rendering library</string>
-        <key>license</key>
-        <string>FreeType</string>
-        <key>license_file</key>
-        <string>LICENSES/freetype.txt</string>
-        <key>name</key>
-        <string>freetype</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -708,9 +642,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8865739d8e530199dacb3c3042c1bc01</string>
+              <string>912d122aae996483ba814fe8e569394ddca0d42e</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87777/805782/freetype-2.4.4.563848-darwin64-563848.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-freetype/releases/download/v2.4.4.4f739fa/freetype-2.4.4.4f739fa-darwin64-4f739fa.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -720,53 +656,45 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>94cf61dfdbc86aae5bbaf0b5cb8a366c</string>
+              <string>14f57822f0cedef957a50a03a7b5372075cf8e1c</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/874/1914/freetype-2.4.4.500865-linux64-500865.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-freetype/releases/download/v2.4.4.4f739fa/freetype-2.4.4.4f739fa-linux64-4f739fa.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>c0b3601e997553931cadc7d7ee94168b</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87779/805814/freetype-2.4.4.563848-windows-563848.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e98e1e088cdcd20442e05e9abecdadf9</string>
+              <string>d175b39257b691a957724e655c6cffe0b5a7b104</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87778/805815/freetype-2.4.4.563848-windows64-563848.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-freetype/releases/download/v2.4.4.4f739fa/freetype-2.4.4.4f739fa-windows64-4f739fa.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>FreeType</string>
+        <key>license_file</key>
+        <string>LICENSES/freetype.txt</string>
+        <key>copyright</key>
+        <string>Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
         <key>version</key>
-        <string>2.4.4.563848</string>
+        <string>2.4.4.4f739fa</string>
+        <key>name</key>
+        <string>freetype</string>
+        <key>description</key>
+        <string>Font rendering library</string>
       </map>
       <key>glext</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2007-2010 The Khronos Group Inc.</string>
-        <key>description</key>
-        <string>glext headers define function prototypes and constants for OpenGL extensions</string>
-        <key>license</key>
-        <string>Copyright (c) 2007-2010 The Khronos Group Inc.</string>
-        <key>license_file</key>
-        <string>LICENSES/glext.txt</string>
-        <key>name</key>
-        <string>glext</string>
         <key>platforms</key>
         <map>
           <key>common</key>
@@ -784,21 +712,21 @@
             <string>common</string>
           </map>
         </map>
+        <key>license</key>
+        <string>Copyright (c) 2007-2010 The Khronos Group Inc.</string>
+        <key>license_file</key>
+        <string>LICENSES/glext.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2007-2010 The Khronos Group Inc.</string>
         <key>version</key>
         <string>68</string>
+        <key>name</key>
+        <string>glext</string>
+        <key>description</key>
+        <string>glext headers define function prototypes and constants for OpenGL extensions</string>
       </map>
       <key>glh_linear</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2000 Cass Everitt</string>
-        <key>description</key>
-        <string>glh - is a platform-indepenedent C++ OpenGL helper library</string>
-        <key>license</key>
-        <string>BSD</string>
-        <key>license_file</key>
-        <string>LICENSES/glh-linear.txt</string>
-        <key>name</key>
-        <string>glh_linear</string>
         <key>platforms</key>
         <map>
           <key>common</key>
@@ -806,29 +734,31 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>dce3f3c01fddb400cb143c3283fe9259</string>
+              <string>6604c1cca515d287e697997a8d5593d1cae172a9</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/82754/775367/glh_linear-0.0.0-common-560278.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-glh_linear/releases/download/v1.0.1-dev2.g3253ed7-3253ed7/glh_linear-common-None.tar.zst</string>
             </map>
             <key>name</key>
             <string>common</string>
           </map>
         </map>
-        <key>version</key>
-        <string>0.0.0</string>
-      </map>
-      <key>googlemock</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright 2008, Google Inc.</string>
-        <key>description</key>
-        <string>a library for writing and using C++ mock classes</string>
         <key>license</key>
         <string>BSD</string>
         <key>license_file</key>
-        <string>LICENSES/gmock.txt</string>
+        <string>LICENSES/glh-linear.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2000 Cass Everitt</string>
+        <key>version</key>
+        <string>None</string>
         <key>name</key>
-        <string>googlemock</string>
+        <string>glh_linear</string>
+        <key>description</key>
+        <string>glh - is a platform-indepenedent C++ OpenGL helper library</string>
+      </map>
+      <key>googlemock</key>
+      <map>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -836,9 +766,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>11d0794582e91a57f6524ad345f2399d</string>
+              <string>c016d7333a3ded88c060119b4e3a5847015a8711</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87791/805924/googlemock-1.7.0.563853-darwin64-563853.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-googlemock/releases/download/v1.7.0.77bba00/googlemock-1.7.0.77bba00-darwin64-77bba00.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -855,44 +787,36 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>7d267050970ec6e28749178597bc8af0</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87793/805930/googlemock-1.7.0.563853-windows-563853.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>27638c692f0ec6121e54bf75f2d45e49</string>
+              <string>df51dff9a820fc96c18c2bc00b64467e541633a5</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87792/805936/googlemock-1.7.0.563853-windows64-563853.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-googlemock/releases/download/v1.7.0.77bba00/googlemock-1.7.0.77bba00-windows64-77bba00.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>BSD</string>
+        <key>license_file</key>
+        <string>LICENSES/gmock.txt</string>
+        <key>copyright</key>
+        <string>Copyright 2008, Google Inc.</string>
         <key>version</key>
-        <string>1.7.0.563853</string>
+        <string>1.7.0.77bba00</string>
+        <key>name</key>
+        <string>googlemock</string>
+        <key>description</key>
+        <string>a library for writing and using C++ mock classes</string>
       </map>
       <key>gstreamer</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</string>
-        <key>license</key>
-        <string>LGPL</string>
-        <key>license_file</key>
-        <string>LICENSES/gstreamer.txt</string>
-        <key>name</key>
-        <string>gstreamer</string>
         <key>platforms</key>
         <map>
           <key>linux64</key>
@@ -908,19 +832,19 @@
             <string>linux64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>LGPL</string>
+        <key>license_file</key>
+        <string>LICENSES/gstreamer.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</string>
         <key>version</key>
         <string>0.10.6.314267</string>
+        <key>name</key>
+        <string>gstreamer</string>
       </map>
       <key>gtk-atk-pango-glib</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (various, see sources)</string>
-        <key>license</key>
-        <string>lgpl</string>
-        <key>license_file</key>
-        <string>LICENSES/gtk-atk-pango-glib.txt</string>
-        <key>name</key>
-        <string>gtk-atk-pango-glib</string>
         <key>platforms</key>
         <map>
           <key>linux64</key>
@@ -936,31 +860,33 @@
             <string>linux64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>lgpl</string>
+        <key>license_file</key>
+        <string>LICENSES/gtk-atk-pango-glib.txt</string>
+        <key>copyright</key>
+        <string>Copyright (various, see sources)</string>
         <key>version</key>
         <string>0.1</string>
+        <key>name</key>
+        <string>gtk-atk-pango-glib</string>
       </map>
       <key>havok-source</key>
       <map>
-        <key>copyright</key>
-        <string>Uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.</string>
-        <key>description</key>
-        <string>Havok source code for libs and demos</string>
-        <key>license</key>
-        <string>havok</string>
-        <key>license_file</key>
-        <string>LICENSES/havok.txt</string>
-        <key>name</key>
-        <string>havok-source</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>ba229348c1d9d58519cd854ff9d8ef3d</string>
+              <string>a193ff65d6db48626d65d96c6124c6efca85e8ec</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/55213/512968/havok_source-2012.1-2-darwin64-539117.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/108912596</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -977,44 +903,38 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>4ff2af85106907acb171bb1e38a3757e</string>
-              <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/55214/512993/havok_source-2012.1-2-windows-539117.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>bcaf4631ea10f7d09eecb73e8f5bef6c</string>
+              <string>ebfb82b6143874e7938b9d1e8a70d0a2e28aa818</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/55212/512962/havok_source-2012.1-2-windows64-539117.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/108912599</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>havok</string>
+        <key>license_file</key>
+        <string>LICENSES/havok.txt</string>
+        <key>copyright</key>
+        <string>Uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.</string>
         <key>version</key>
         <string>2012.1-2</string>
+        <key>name</key>
+        <string>havok-source</string>
+        <key>description</key>
+        <string>Havok source code for libs and demos</string>
       </map>
       <key>jpegencoderbasic</key>
       <map>
-        <key>copyright</key>
-        <string>Andreas Ritter, www.bytestrom.eu, 11/2009</string>
-        <key>license</key>
-        <string>NONE</string>
-        <key>license_file</key>
-        <string>LICENSES/JPEG_ENCODER_BASIC_LICENSE.txt</string>
-        <key>name</key>
-        <string>jpegencoderbasic</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1022,9 +942,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c3c9e60bdc12b35e0e3d6b67d5635f60</string>
+              <string>f271809c0d4244128fb52a71226a4d7674e14e0a</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89304/815407/jpegencoderbasic-1.0-darwin64-564842.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-9165e47/jpegencoderbasic-1.0-darwin64-9165e47.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1034,51 +956,41 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e70898903475d8ac2e81ff33278fc987</string>
+              <string>35d6a617444fde9c8a5e998ef29dc43b95747637</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89309/815433/jpegencoderbasic-1.0-windows64-564842.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-9165e47/jpegencoderbasic-1.0-linux64-9165e47.tar.zst</string>
             </map>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>0a376676dbb43fdd0c81ffdfbc5e6f81</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89308/815432/jpegencoderbasic-1.0-windows-564842.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e70898903475d8ac2e81ff33278fc987</string>
+              <string>8ec22e9fc8734ba3d1826f4b88171a6017cc8676</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89309/815433/jpegencoderbasic-1.0-windows64-564842.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-9165e47/jpegencoderbasic-1.0-windows64-9165e47.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>NONE</string>
+        <key>license_file</key>
+        <string>LICENSES/JPEG_ENCODER_BASIC_LICENSE.txt</string>
+        <key>copyright</key>
+        <string>Andreas Ritter, www.bytestrom.eu, 11/2009</string>
         <key>version</key>
         <string>1.0</string>
+        <key>name</key>
+        <string>jpegencoderbasic</string>
       </map>
       <key>jpeglib</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding.</string>
-        <key>description</key>
-        <string>JPEG encoding, decoding library</string>
-        <key>license</key>
-        <string>jpeglib</string>
-        <key>license_file</key>
-        <string>LICENSES/jpeglib.txt</string>
-        <key>name</key>
-        <string>jpeglib</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1086,9 +998,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>3f2e34e3a2dac8eea957cad143a71dc5</string>
+              <string>776d114aa1e3455bb13deaacd756deb07b53ecbe</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54847/510113/jpeglib-8c.538977-darwin64-538977.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jpeglib/releases/download/v8c.7846234/jpeglib-8c.7846234-darwin64-7846234.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1098,53 +1012,45 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ba9c62863ec338a049de83c24639f57c</string>
+              <string>b4b2278bd2fcae85619e2145a243cca388d760d7</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/3151/7568/jpeglib-8c.503140-linux64-503140.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jpeglib/releases/download/v8c.7846234/jpeglib-8c.7846234-linux64-7846234.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>c8dee00ef13af40ec68becc25830e195</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54992/511854/jpeglib-8c.538977-windows-538977.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6f40620e86f3c9b91b6b5fe3c81776fc</string>
+              <string>d50fcac69eeb9404638da07db96ee3e1191ecf93</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54991/511847/jpeglib-8c.538977-windows64-538977.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jpeglib/releases/download/v8c.7846234/jpeglib-8c.7846234-windows64-7846234.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>jpeglib</string>
+        <key>license_file</key>
+        <string>LICENSES/jpeglib.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding.</string>
         <key>version</key>
-        <string>8c.538977</string>
+        <string>8c.7846234</string>
+        <key>name</key>
+        <string>jpeglib</string>
+        <key>description</key>
+        <string>JPEG encoding, decoding library</string>
       </map>
       <key>jsoncpp</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2007-2010 Baptiste Lepilleur</string>
-        <key>description</key>
-        <string>jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++.</string>
-        <key>license</key>
-        <string>public domain</string>
-        <key>license_file</key>
-        <string>LICENSES/jsoncpp.txt</string>
-        <key>name</key>
-        <string>jsoncpp</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1152,9 +1058,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>87d32aaac4183590c96edd0b6d9bf3e4</string>
+              <string>07761ab01e61d5d6b40d303ffafd85ec055ec9f7</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54846/510106/jsoncpp-0.5.0.538976-darwin64-538976.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jsoncpp/releases/download/v0.5.0.bc46e62/jsoncpp-0.5.0.bc46e62-darwin64-bc46e62.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1164,63 +1072,59 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9a658ae561c75e60bd9c0cee56731d21</string>
+              <string>97e268754808cb2fbd682c4d3beafd2c598e1ba7</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1475/3274/jsoncpp-0.5.0.501464-linux64-501464.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jsoncpp/releases/download/v0.5.0.bc46e62/jsoncpp-0.5.0.bc46e62-linux64-bc46e62.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>b73d9addab278eacc100bd312ab6ec5c</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54990/511840/jsoncpp-0.5.0.538976-windows-538976.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1b9ac5708cc526d2c5358ef0a427109d</string>
+              <string>500e455b210d6bc4985185cef2472987ed3034bf</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54989/511833/jsoncpp-0.5.0.538976-windows64-538976.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-jsoncpp/releases/download/v0.5.0.bc46e62/jsoncpp-0.5.0.bc46e62-windows64-bc46e62.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
-        <key>version</key>
-        <string>0.5.0.538976</string>
-      </map>
-      <key>kdu</key>
-      <map>
-        <key>copyright</key>
-        <string>Kakadu software</string>
-        <key>description</key>
-        <string>JPEG2000 library by Kakadu</string>
         <key>license</key>
-        <string>Kakadu</string>
+        <string>public domain</string>
         <key>license_file</key>
-        <string>LICENSES/kdu.txt</string>
+        <string>LICENSES/jsoncpp.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2007-2010 Baptiste Lepilleur</string>
+        <key>version</key>
+        <string>0.5.0.bc46e62</string>
         <key>name</key>
-        <string>kdu</string>
+        <string>jsoncpp</string>
+        <key>description</key>
+        <string>jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++.</string>
+      </map>
+      <key>kdu</key>
+      <map>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>ccfd8eacd1ebe92715944094064ba2e4</string>
+              <string>bcc7e2c34896fc9cbc41828dee8a4ddf54f10453</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/55187/512570/kdu-7.10.4.539108-darwin64-539108.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298968</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1229,54 +1133,50 @@
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>a705a665810a71e7b0114a97ae9a2224</string>
+              <string>9de772df2ed12e9c742df6c90670c7cbbb9c93a6</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/15256/98457/kdu-7.10.4.513518-linux64-513518.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298969</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>38574fbcb6c94c42745ef48748002e58</string>
-              <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/55189/512583/kdu-7.10.4.539108-windows-539108.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>3dfeb869c781a766874f0aedc7d4fcef</string>
+              <string>92533ff0f8c1881ad85e75800f9072c413ccf7b7</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/55188/512576/kdu-7.10.4.539108-windows64-539108.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-kdu/releases/assets/108298970</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>Kakadu</string>
+        <key>license_file</key>
+        <string>LICENSES/kdu.txt</string>
+        <key>copyright</key>
+        <string>Kakadu software</string>
         <key>version</key>
         <string>7.10.4.539108</string>
+        <key>name</key>
+        <string>kdu</string>
+        <key>description</key>
+        <string>JPEG2000 library by Kakadu</string>
       </map>
       <key>libhunspell</key>
       <map>
-        <key>copyright</key>
-        <string>See hunspell.txt</string>
-        <key>description</key>
-        <string>Spell checking library</string>
-        <key>license</key>
-        <string>LGPL</string>
-        <key>license_file</key>
-        <string>LICENSES/hunspell.txt</string>
-        <key>name</key>
-        <string>libhunspell</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1284,9 +1184,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2021ea3a19b81c82993e733709683303</string>
+              <string>d5757ab84d934fa358f299ab91e2e297beaa3dac</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76371/727419/libhunspell-1.3.2.555528-darwin64-555528.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libhunspell/releases/download/v1.3.2.650fb94/libhunspell-1.3.2.650fb94-darwin64-650fb94.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1296,53 +1198,45 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ffbdd109356d66ddfefd8a5d57f63f1f</string>
+              <string>6413d3bd4cd50c2a6b7f949eb4bd6f0c94feb984</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/533/1144/libhunspell-1.3.2.500526-linux64-500526.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libhunspell/releases/download/v1.3.2.650fb94/libhunspell-1.3.2.650fb94-linux64-650fb94.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>2253ec09136cc7c208481030d78d9dd7</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76369/727412/libhunspell-1.3.2.555528-windows-555528.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>858d1708f6b3a74738a3d57a5387e20f</string>
+              <string>c1be4a79b20435030b2e0e01b582c61b462c8376</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76370/727413/libhunspell-1.3.2.555528-windows64-555528.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libhunspell/releases/download/v1.3.2.650fb94/libhunspell-1.3.2.650fb94-windows64-650fb94.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>LGPL</string>
+        <key>license_file</key>
+        <string>LICENSES/hunspell.txt</string>
+        <key>copyright</key>
+        <string>See hunspell.txt</string>
         <key>version</key>
-        <string>1.3.2.555528</string>
+        <string>1.3.2.650fb94</string>
+        <key>name</key>
+        <string>libhunspell</string>
+        <key>description</key>
+        <string>Spell checking library</string>
       </map>
       <key>libndofdev</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved.</string>
-        <key>description</key>
-        <string>3DConnexion SDK</string>
-        <key>license</key>
-        <string>BSD</string>
-        <key>license_file</key>
-        <string>LICENSES/libndofdev.txt</string>
-        <key>name</key>
-        <string>libndofdev</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1350,53 +1244,45 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a487fff84208a45844602c4a1f68c974</string>
+              <string>e3dd320c90e67e0c80caf4d4df23257b0196dfb6</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76356/727333/libndofdev-0.1.555523-darwin64-555523.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libndofdev/releases/download/v0.1.8e9edc7/libndofdev-0.1.8e9edc7-darwin64-8e9edc7.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>4c839555bf0ed9ae60ffc3f8a7c96f9b</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76354/727340/libndofdev-0.1.555523-windows-555523.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>cbc033ae3b034b992b59f6de1034247c</string>
+              <string>ae9d554e8839f42230b8ed6c850445d54654a38f</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76355/727341/libndofdev-0.1.555523-windows64-555523.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libndofdev/releases/download/v0.1.8e9edc7/libndofdev-0.1.8e9edc7-windows64-8e9edc7.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>BSD</string>
+        <key>license_file</key>
+        <string>LICENSES/libndofdev.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved.</string>
         <key>version</key>
-        <string>0.1.555523</string>
+        <string>0.1.8e9edc7</string>
+        <key>name</key>
+        <string>libndofdev</string>
+        <key>description</key>
+        <string>3DConnexion SDK</string>
       </map>
       <key>libpng</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson</string>
-        <key>description</key>
-        <string>PNG Reference library</string>
-        <key>license</key>
-        <string>libpng</string>
-        <key>license_file</key>
-        <string>LICENSES/libpng.txt</string>
-        <key>name</key>
-        <string>libpng</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1404,9 +1290,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7a0059748d0b8733f2f9ce434cf604b8</string>
+              <string>fea8f0684a4ed0a73343651948b13049a135a92a</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107514/937867/libpng-1.6.38.576621-darwin64-576621.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.38-ca06e99/libpng-1.6.38-ca06e99-darwin64-ca06e99.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1423,46 +1311,36 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>3112013186ad60b0fc270a398d4dd499</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107513/937823/libpng-1.6.38.576621-windows-576621.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7c6bfcdb0d6162587cdbc436f595dd02</string>
+              <string>b91c116a1fda2377954355e56517634db0137699</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107512/937822/libpng-1.6.38.576621-windows64-576621.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libpng/releases/download/v1.6.38-ca06e99/libpng-1.6.38-ca06e99-windows64-ca06e99.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>libpng</string>
+        <key>license_file</key>
+        <string>LICENSES/libpng.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson</string>
         <key>version</key>
-        <string>1.6.38.576621</string>
+        <string>1.6.38-ca06e99</string>
+        <key>name</key>
+        <string>libpng</string>
+        <key>description</key>
+        <string>PNG Reference library</string>
       </map>
       <key>libuuid</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2004-2008 The OSSP Project &lt;http://www.ossp.org/&gt;</string>
-        <key>description</key>
-        <string>OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). </string>
-        <key>license</key>
-        <string>UUID</string>
-        <key>license_file</key>
-        <string>LICENSES/uuid.txt</string>
-        <key>name</key>
-        <string>libuuid</string>
         <key>platforms</key>
         <map>
           <key>linux64</key>
@@ -1478,21 +1356,21 @@
             <string>linux64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>UUID</string>
+        <key>license_file</key>
+        <string>LICENSES/uuid.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2004-2008 The OSSP Project &lt;http://www.ossp.org/&gt;</string>
         <key>version</key>
         <string>1.6.2</string>
+        <key>name</key>
+        <string>libuuid</string>
+        <key>description</key>
+        <string>OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). </string>
       </map>
       <key>libxml2</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.</string>
-        <key>description</key>
-        <string>Libxml2 is the XML C parser and toolkit developed for the Gnome project.</string>
-        <key>license</key>
-        <string>mit</string>
-        <key>license_file</key>
-        <string>LICENSES/libxml2.txt</string>
-        <key>name</key>
-        <string>libxml2</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1500,9 +1378,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6f37dd6c4a5174f358b6cc5d953f121b</string>
+              <string>2c46547d9dc83c47f41eacc7e5092affa72f3eee</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87768/805766/libxml2-2.9.4.563845-darwin64-563845.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.9.4.7476681/libxml2-2.9.4.7476681-darwin64-7476681.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1512,53 +1392,45 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>740fc93f195c77b3a0c0800b31878ecb</string>
+              <string>4cda464277bfa6756ce4663a91cd724f3f45b8d8</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/890/1968/libxml2-2.9.4.500877-linux64-500877.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.9.4.7476681/libxml2-2.9.4.7476681-linux64-7476681.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>fd85d3aa13fbdfd1f1ace587e95ef151</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87773/805797/libxml2-2.9.4.563845-windows-563845.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d231d36c3b8942e0259aa2d9fcaa3b7e</string>
+              <string>7e506d26f8cb6f205146e41d74095e7e27087e84</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87772/805795/libxml2-2.9.4.563845-windows64-563845.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-libxml2/releases/download/v2.9.4.7476681/libxml2-2.9.4.7476681-windows64-7476681.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>mit</string>
+        <key>license_file</key>
+        <string>LICENSES/libxml2.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.</string>
         <key>version</key>
-        <string>2.9.4.563845</string>
+        <string>2.9.4.7476681</string>
+        <key>name</key>
+        <string>libxml2</string>
+        <key>description</key>
+        <string>Libxml2 is the XML C parser and toolkit developed for the Gnome project.</string>
       </map>
       <key>llappearance_utility</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2000-2012, Linden Research, Inc.</string>
-        <key>description</key>
-        <string>Linden Lab appearance utility for server-side avatar baking services.</string>
-        <key>license</key>
-        <string>Proprietary</string>
-        <key>license_file</key>
-        <string>LICENSES/llappearanceutility.txt</string>
-        <key>name</key>
-        <string>llappearance_utility</string>
         <key>platforms</key>
         <map>
           <key>linux</key>
@@ -1574,20 +1446,21 @@
             <string>linux</string>
           </map>
         </map>
+        <key>license</key>
+        <string>Proprietary</string>
+        <key>license_file</key>
+        <string>LICENSES/llappearanceutility.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2000-2012, Linden Research, Inc.</string>
         <key>version</key>
         <string>0.0.1</string>
+        <key>name</key>
+        <string>llappearance_utility</string>
+        <key>description</key>
+        <string>Linden Lab appearance utility for server-side avatar baking services.</string>
       </map>
       <key>llca</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project.
-      </string>
-        <key>license</key>
-        <string>mit</string>
-        <key>license_file</key>
-        <string>LICENSES/ca-license.txt</string>
-        <key>name</key>
-        <string>llca</string>
         <key>platforms</key>
         <map>
           <key>common</key>
@@ -1595,39 +1468,44 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d6e7ab8483c348f223fd24028e27a52f</string>
+              <string>e50ea94bbaa4ff41bf53b84b7192df1a694c5337</string>
               <key>hash_algorithm</key>
-              <string>md5</string>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/93933/844890/llca-202202010217.567974-common-567974.tar.bz2</string>
+              <string>https://github.com/secondlife/llca/releases/download/v202310121525.0-d22bd98/llca-202310121530.0-common-d22bd98.tar.zst</string>
             </map>
             <key>name</key>
             <string>common</string>
           </map>
         </map>
+        <key>license</key>
+        <string>mit</string>
+        <key>license_file</key>
+        <string>LICENSES/ca-license.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project.
+      </string>
         <key>version</key>
-        <string>202202010217.567974</string>
+        <string>202310121530.0</string>
+        <key>name</key>
+        <string>llca</string>
       </map>
       <key>llphysicsextensions_source</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2010, Linden Research, Inc.</string>
-        <key>license</key>
-        <string>internal</string>
-        <key>license_file</key>
-        <string>LICENSES/llphysicsextensions.txt</string>
-        <key>name</key>
-        <string>llphysicsextensions_source</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>e51c6f5dfd76eb148348a44ff57e66c2</string>
+              <string>48bca5d0233d1e724a59f649a2c6c7ac5f40ec3c</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/104810/918016/llphysicsextensions_source-1.0.575107-darwin64-575107.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009335</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1636,40 +1514,48 @@
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>c1b43e99c5ddccc18b0e9cb288bf75e1</string>
+              <string>39f52d0350e130f41c5c758f7cb94e87b962c223</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4721/14828/llphysicsextensions_source-1.0.504710-linux64-504710.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009336</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
+          <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>dbbe4cc568ac149d862e421cdda4dd48</string>
+              <string>7b5e645fb7eb399abbea63bd21e8063bbb32a911</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/104809/918011/llphysicsextensions_source-1.0.575107-windows-575107.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009339</string>
             </map>
             <key>name</key>
-            <string>windows</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>1.0.565768</string>
-      </map>
-      <key>llphysicsextensions_stub</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2010, Linden Research, Inc.</string>
+            <string>windows64</string>
+          </map>
+        </map>
         <key>license</key>
         <string>internal</string>
         <key>license_file</key>
         <string>LICENSES/llphysicsextensions.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2010, Linden Research, Inc.</string>
+        <key>version</key>
+        <string>1.0.565768</string>
         <key>name</key>
-        <string>llphysicsextensions_stub</string>
+        <string>llphysicsextensions_source</string>
+      </map>
+      <key>llphysicsextensions_stub</key>
+      <map>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1709,19 +1595,19 @@
             <string>windows</string>
           </map>
         </map>
+        <key>license</key>
+        <string>internal</string>
+        <key>license_file</key>
+        <string>LICENSES/llphysicsextensions.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2010, Linden Research, Inc.</string>
         <key>version</key>
         <string>1.0.542456</string>
+        <key>name</key>
+        <string>llphysicsextensions_stub</string>
       </map>
       <key>llphysicsextensions_tpv</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2010, Linden Research, Inc.</string>
-        <key>license</key>
-        <string>internal</string>
-        <key>license_file</key>
-        <string>LICENSES/HavokSublicense.pdf</string>
-        <key>name</key>
-        <string>llphysicsextensions_tpv</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1748,18 +1634,6 @@
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>60e399f707bca32d0a4f7ee33ac4c35b</string>
-              <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/84730/788138/llphysicsextensions_tpv-1.0.561752-windows-561752.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
@@ -1773,17 +1647,19 @@
             <string>windows</string>
           </map>
         </map>
+        <key>license</key>
+        <string>internal</string>
+        <key>license_file</key>
+        <string>LICENSES/HavokSublicense.pdf</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2010, Linden Research, Inc.</string>
         <key>version</key>
         <string>1.0.561752</string>
+        <key>name</key>
+        <string>llphysicsextensions_tpv</string>
       </map>
       <key>mesa</key>
       <map>
-        <key>license</key>
-        <string>mesa</string>
-        <key>license_file</key>
-        <string>LICENSES/mesa.txt</string>
-        <key>name</key>
-        <string>mesa</string>
         <key>platforms</key>
         <map>
           <key>linux</key>
@@ -1799,23 +1675,17 @@
             <string>linux</string>
           </map>
         </map>
+        <key>license</key>
+        <string>mesa</string>
+        <key>license_file</key>
+        <string>LICENSES/mesa.txt</string>
         <key>version</key>
         <string>7.11.1.297294</string>
+        <key>name</key>
+        <string>mesa</string>
       </map>
       <key>meshoptimizer</key>
       <map>
-        <key>canonical_repo</key>
-        <string>https://bitbucket.org/lindenlab/3p-meshoptimizer</string>
-        <key>copyright</key>
-        <string>Copyright (c) 2016-2021 Arseny Kapoulkine</string>
-        <key>description</key>
-        <string>Meshoptimizer. Mesh optimization library.</string>
-        <key>license</key>
-        <string>meshoptimizer</string>
-        <key>license_file</key>
-        <string>LICENSES/meshoptimizer.txt</string>
-        <key>name</key>
-        <string>meshoptimizer</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1823,40 +1693,44 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>30bc37db57bbd87c4b5f62634964242a</string>
+              <string>3bf88febd23656327a4ee2a3ebe99cae4b15573e</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84218/784918/meshoptimizer-0.16.561408-darwin64-561408.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v160-032f20a/meshoptimizer-160-darwin64-032f20a.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>ca3684bcf0447746cd2844e94f6d1fc7</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84219/784924/meshoptimizer-0.16.561408-windows-561408.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>aef28c089d20f69d13c9c3e113fb3895</string>
+              <string>13c0a33d9c49cc07b354527c7ef992d33f854c59</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/84220/784931/meshoptimizer-0.16.561408-windows64-561408.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v160-032f20a/meshoptimizer-160-windows64-032f20a.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>meshoptimizer</string>
+        <key>license_file</key>
+        <string>LICENSES/meshoptimizer.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2016-2021 Arseny Kapoulkine</string>
         <key>version</key>
-        <string>0.16.561408</string>
+        <string>160</string>
+        <key>name</key>
+        <string>meshoptimizer</string>
+        <key>canonical_repo</key>
+        <string>https://bitbucket.org/lindenlab/3p-meshoptimizer</string>
+        <key>description</key>
+        <string>Meshoptimizer. Mesh optimization library.</string>
       </map>
       <key>mikktspace</key>
       <map>
@@ -1916,18 +1790,6 @@
       </map>
       <key>minizip-ng</key>
       <map>
-        <key>canonical_repo</key>
-        <string>https://bitbucket.org/lindenlab/3p-minizip-ng</string>
-        <key>copyright</key>
-        <string>This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
-        <key>description</key>
-        <string>minizip-ng is a zip manipulation library. Based on work of Gilles Vollant.</string>
-        <key>license</key>
-        <string>minizip-ng</string>
-        <key>license_file</key>
-        <string>LICENSES/minizip-ng.txt</string>
-        <key>name</key>
-        <string>minizip-ng</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1935,54 +1797,61 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>843587a078102d86d90054d03354684d</string>
+              <string>303fa93a0fd6c636a65fd9d5d53beceb84752b0e</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95876/856095/minizip_ng-3.0.2.569217-darwin64-569217.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v3.0.2.3e9876e/minizip_ng-3.0.2.3e9876e-darwin64-3e9876e.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
+          <key>linux64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>26dc254f443ca9c5509547d7fbd9d8e5</string>
+              <string>d4f35ebcea53ab6e9f2e6cbc0d680b10d10b9c53</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95878/856107/minizip_ng-3.0.2.569217-windows-569217.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v3.0.2.3e9876e/minizip_ng-3.0.2.3e9876e-linux64-3e9876e.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows</string>
+            <string>linux64</string>
           </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e9241fa325f4014995b62193321e7a1c</string>
+              <string>5dc469172ba4c6015d5b771e516bc88a65d769eb</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95877/856106/minizip_ng-3.0.2.569217-windows64-569217.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-minizip-ng/releases/download/v3.0.2.3e9876e/minizip_ng-3.0.2.3e9876e-windows64-3e9876e.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>minizip-ng</string>
+        <key>license_file</key>
+        <string>LICENSES/minizip-ng.txt</string>
+        <key>copyright</key>
+        <string>This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
         <key>version</key>
-        <string>3.0.2.569217</string>
+        <string>3.0.2.3e9876e</string>
+        <key>name</key>
+        <string>minizip-ng</string>
+        <key>canonical_repo</key>
+        <string>https://bitbucket.org/lindenlab/3p-minizip-ng</string>
+        <key>description</key>
+        <string>minizip-ng is a zip manipulation library. Based on work of Gilles Vollant.</string>
       </map>
       <key>nghttp2</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
-Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
-        <key>description</key>
-        <string>Library providing HTTP 2 support for libcurl</string>
-        <key>license</key>
-        <string>MIT</string>
-        <key>license_file</key>
-        <string>LICENSES/nghttp2.txt</string>
-        <key>name</key>
-        <string>nghttp2</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -1990,9 +1859,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e4f784d8a035c51921a1562ca7a1bab6</string>
+              <string>fff611030a34e78b3a88168f64e4e33aef117bc3</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76357/727350/nghttp2-1.40.0.555524-darwin64-555524.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-nghttp2/releases/download/v1.40.0.b1526c6/nghttp2-1.40.0.b1526c6-darwin64-b1526c6.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2002,97 +1873,80 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c3c5ff7d2f7ac1143ef8d888192d4a53</string>
+              <string>5798b5f6c8579ad44f211a873c072ee8d3fd8c93</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/9257/41579/nghttp2-1.25.0.509246-linux64-509246.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-nghttp2/releases/download/v1.40.0.b1526c6/nghttp2-1.40.0.b1526c6-linux64-b1526c6.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>af05aa2994c9845308fecd094b7b2d25</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76359/727360/nghttp2-1.40.0.555524-windows-555524.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5a55cede40eef16b9d1e47c418a2b77a</string>
+              <string>05aad7759519719a54a6100fddd35b69e57f2386</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76358/727359/nghttp2-1.40.0.555524-windows64-555524.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-nghttp2/releases/download/v1.40.0.b1526c6/nghttp2-1.40.0.b1526c6-windows64-b1526c6.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>MIT</string>
+        <key>license_file</key>
+        <string>LICENSES/nghttp2.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
+Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
+        <key>version</key>
+        <string>1.40.0.b1526c6</string>
+        <key>name</key>
+        <string>nghttp2</string>
+        <key>description</key>
+        <string>Library providing HTTP 2 support for libcurl</string>
         <key>source_type</key>
         <string>hg</string>
-        <key>version</key>
-        <string>1.40.0.555524</string>
       </map>
       <key>nvapi</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright © 2012 NVIDIA Corporation.  All rights reserved.</string>
-        <key>description</key>
-        <string>NVAPI provides an interface to NVIDIA devices.</string>
-        <key>license</key>
-        <string>NVIDIA Corporation Software License Agreement – NVAPI SDK</string>
-        <key>license_file</key>
-        <string>LICENSES/NVAPI_SDK_License_Agreement.pdf</string>
-        <key>name</key>
-        <string>nvapi</string>
         <key>platforms</key>
         <map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>4305515ad326c911a390388366a9107b</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54947/511704/nvapi-352.539058-windows-539058.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>25c8ac919f24b8952653d38ec43640e5</string>
+              <string>1ebe715fc1096198e343c41d50654c11509cdbba</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54945/511697/nvapi-352.539058-windows64-539058.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-nvapi/releases/download/v352.aac0e19/nvapi-352.aac0e19-windows64-aac0e19.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>NVIDIA Corporation Software License Agreement – NVAPI SDK</string>
+        <key>license_file</key>
+        <string>LICENSES/NVAPI_SDK_License_Agreement.pdf</string>
+        <key>copyright</key>
+        <string>Copyright © 2012 NVIDIA Corporation.  All rights reserved.</string>
         <key>version</key>
-        <string>352.539058</string>
+        <string>352.aac0e19</string>
+        <key>name</key>
+        <string>nvapi</string>
+        <key>description</key>
+        <string>NVAPI provides an interface to NVIDIA devices.</string>
       </map>
       <key>ogg_vorbis</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2002, Xiph.org Foundation</string>
-        <key>description</key>
-        <string>Audio encoding library</string>
-        <key>license</key>
-        <string>ogg-vorbis</string>
-        <key>license_file</key>
-        <string>LICENSES/ogg-vorbis.txt</string>
-        <key>name</key>
-        <string>ogg_vorbis</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2100,9 +1954,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a066f1d12caee1d87fc72f48169f9677</string>
+              <string>ad0dd0f608b868cc44c225ee48e114239fca2807</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54841/510071/ogg_vorbis-1.3.3-1.3.6.538971-darwin64-538971.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.3-1.3.6.e4101b6/ogg_vorbis-1.3.3-1.3.6.e4101b6-darwin64-e4101b6.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2119,61 +1975,51 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>d4b8ed3fd679a2b484d2d1a66c063908</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54981/511789/ogg_vorbis-1.3.3-1.3.6.538971-windows-538971.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ec4a657fe639bb458ee5132062146a7a</string>
+              <string>2e73a0a5659c9a09eba2f94619aa5c23c7cc3937</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54980/511782/ogg_vorbis-1.3.3-1.3.6.538971-windows64-538971.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.3-1.3.6.e4101b6/ogg_vorbis-1.3.3-1.3.6.e4101b6-windows64-e4101b6.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>ogg-vorbis</string>
+        <key>license_file</key>
+        <string>LICENSES/ogg-vorbis.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2002, Xiph.org Foundation</string>
         <key>version</key>
-        <string>1.3.3-1.3.6.538971</string>
+        <string>1.3.3-1.3.6.e4101b6</string>
+        <key>name</key>
+        <string>ogg_vorbis</string>
+        <key>description</key>
+        <string>Audio encoding library</string>
       </map>
       <key>open-libndofdev</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com)</string>
-        <key>description</key>
-        <string>Open Source replacement for 3DConnection SDK</string>
         <key>license</key>
         <string>BSD</string>
         <key>license_file</key>
         <string>LICENSES/libndofdev.txt</string>
-        <key>name</key>
-        <string>open-libndofdev</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com)</string>
         <key>version</key>
         <string>0.3</string>
+        <key>name</key>
+        <string>open-libndofdev</string>
+        <key>description</key>
+        <string>Open Source replacement for 3DConnection SDK</string>
       </map>
       <key>openal</key>
       <map>
-        <key>copyright</key>
-        <string>Creative Labs</string>
-        <key>description</key>
-        <string>OpenAL is a cross-platform 3D audio API appropriate for use with gaming applications and many other types of audio applications.</string>
-        <key>license</key>
-        <string>lgpl</string>
-        <key>license_file</key>
-        <string>LICENSES/openal.txt</string>
-        <key>name</key>
-        <string>openal</string>
         <key>platforms</key>
         <map>
           <key>linux64</key>
@@ -2181,55 +2027,59 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7530fab3979312da75a903d87b73e3a9</string>
+              <string>e0fbc4874acc4167a6e2b6489fbb8258d98fd665</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/Linux/installer/openal-1.12.854-1.1.0.314223-linux64-314223.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-linux64-18e315c.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
+          <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d9c86f79a6bb56a670e2801c33fd2dd1</string>
+              <string>6ae3b5310eb1988741bc55416681ca9d64f76f85</string>
               <key>hash_algorithm</key>
-              <string>md5</string>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/CYGWIN/installer/openal-1.12.854-1.1.0.314223-windows-314223.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-windows64-18e315c.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows</string>
+            <string>windows64</string>
           </map>
-          <key>windows64</key>
+          <key>darwin64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e0fdd9394a8cd8c6360b922f6f237e57</string>
+              <string>4edaef5f03a1122eae8467c4a04d9caccaaaf847</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/CYGWIN/installer/openal-1.12.854-1.1.0.314223-windows64-314223.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-darwin64-18e315c.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows64</string>
+            <string>darwin64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>LGPL2</string>
+        <key>license_file</key>
+        <string>LICENSES/openal-soft.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 1999-2007 by authors.</string>
         <key>version</key>
-        <string>1.12.854-1.1.0.314223</string>
+        <string>1.23.1</string>
+        <key>name</key>
+        <string>openal</string>
+        <key>description</key>
+        <string>OpenAL Soft is a software implementation of the OpenAL 3D audio API.</string>
       </map>
       <key>openjpeg</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications &amp; Systemes &lt;jerome.fimes@c-s.fr&gt;; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France;</string>
-        <key>description</key>
-        <string>The OpenJPEG library is an open-source JPEG 2000 codec written in C language.</string>
-        <key>license</key>
-        <string>BSD</string>
-        <key>license_file</key>
-        <string>LICENSES/openjpeg.txt</string>
-        <key>name</key>
-        <string>openjpeg</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2237,9 +2087,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8114c6a7e499ea20d325db0de08ce30a</string>
+              <string>c16deaf773cb2a5d001732122ee3ec74db1dceeb</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105469/923024/openjpeg-2.5.0.575496-darwin64-575496.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.0.ea12248/openjpeg-2.5.0.ea12248-darwin64-ea12248.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2249,53 +2101,45 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ac66f3197010b1549a5e4467aebbc27d</string>
+              <string>8c277dde6076fb682cb07264dd70f6f2298b633f</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1113/2571/openjpeg-1.5.1.501102-linux64-501102.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.0.ea12248/openjpeg-2.5.0.ea12248-linux64-ea12248.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>edc9388870d951632a6d595792293e05</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105472/923036/openjpeg-2.5.0.575496-windows-575496.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b95f0732f2388ebb0ddf33d4a30e0ff1</string>
+              <string>2abf9535adf21ebdf2295f8a680300432abe6280</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105471/923037/openjpeg-2.5.0.575496-windows64-575496.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.0.ea12248/openjpeg-2.5.0.ea12248-windows64-ea12248.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>BSD</string>
+        <key>license_file</key>
+        <string>LICENSES/openjpeg.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications &amp; Systemes &lt;jerome.fimes@c-s.fr&gt;; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France;</string>
         <key>version</key>
-        <string>2.5.0.575496</string>
+        <string>2.5.0.ea12248</string>
+        <key>name</key>
+        <string>openjpeg</string>
+        <key>description</key>
+        <string>The OpenJPEG library is an open-source JPEG 2000 codec written in C language.</string>
       </map>
       <key>openssl</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)</string>
-        <key>description</key>
-        <string>Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) Library</string>
-        <key>license</key>
-        <string>openssl</string>
-        <key>license_file</key>
-        <string>LICENSES/openssl.txt</string>
-        <key>name</key>
-        <string>openssl</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2303,9 +2147,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>142d0ad85d0ee4fbb673c9f9e414fbdd</string>
+              <string>b286e4a10cf6b1b2710b85ff96ffc0e41fd5fde8</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87769/805772/openssl-1.1.1l.563846-darwin64-563846.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1q.de53f55/openssl-1.1.1q.de53f55-darwin64-de53f55.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2315,53 +2161,45 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d50ccfbf0c1d249392919e2c46ad8d5c</string>
+              <string>5f6953db991ef6badb0525ecc98daf28d368e9e7</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/8339/33495/openssl-1.0.2l.508328-linux64-508328.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1q.de53f55/openssl-1.1.1q.de53f55-linux64-de53f55.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>55bd833166d03f1467e2c7f24fa9143e</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87775/805841/openssl-1.1.1l.563846-windows-563846.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6fefc60f68882fc6b246521b696497ab</string>
+              <string>8bd3dea6d81de5e469b241a1b79e61efce6ecc05</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87774/805833/openssl-1.1.1l.563846-windows64-563846.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-openssl/releases/download/v1.1.1q.de53f55/openssl-1.1.1q.de53f55-windows64-de53f55.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>openssl</string>
+        <key>license_file</key>
+        <string>LICENSES/openssl.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)</string>
         <key>version</key>
-        <string>1.1.1l.563846</string>
+        <string>1.1.1q.de53f55</string>
+        <key>name</key>
+        <string>openssl</string>
+        <key>description</key>
+        <string>Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) Library</string>
       </map>
       <key>pcre</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright (c) 1997-2014 University of Cambridge; Copyright(c) 2009-2014 Zoltan Herczeg; Copyright (c) 2007-2012, Google Inc.</string>
-        <key>description</key>
-        <string>PCRE Perl-compatible regular expression library</string>
-        <key>license</key>
-        <string>bsd</string>
-        <key>license_file</key>
-        <string>LICENSES/pcre-license.txt</string>
-        <key>name</key>
-        <string>pcre</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2369,9 +2207,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d8c0f97fe5abef43e72b6f84aba698b2</string>
+              <string>b372d37596474043a62568e569b0ce155192f484</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54856/510176/pcre-8.35.538986-darwin64-538986.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-pcre/releases/download/v8.35.979fd86/pcre-8.35.979fd86-darwin64-979fd86.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2388,56 +2228,50 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>3660db45793df3050b63920bfb7d8479</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55041/512002/pcre-8.35.538986-windows-538986.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>cdee8e8b48a66266550bf279c40abc22</string>
+              <string>166564afb60a7536a038fae80e2fc9a41d6dbccb</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55038/511992/pcre-8.35.538986-windows64-538986.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-pcre/releases/download/v8.35.979fd86/pcre-8.35.979fd86-windows64-979fd86.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>bsd</string>
+        <key>license_file</key>
+        <string>LICENSES/pcre-license.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 1997-2014 University of Cambridge; Copyright(c) 2009-2014 Zoltan Herczeg; Copyright (c) 2007-2012, Google Inc.</string>
         <key>version</key>
-        <string>8.35.538986</string>
+        <string>8.35.979fd86</string>
+        <key>name</key>
+        <string>pcre</string>
+        <key>description</key>
+        <string>PCRE Perl-compatible regular expression library</string>
       </map>
       <key>slvoice</key>
       <map>
-        <key>copyright</key>
-        <string>2010 Vivox, including audio coding using Polycom¨ Siren14TM (ITU-T Rec. G.722.1 Annex C)</string>
-        <key>description</key>
-        <string>Vivox SDK components</string>
-        <key>license</key>
-        <string>Mixed</string>
-        <key>license_file</key>
-        <string>LICENSES/vivox_licenses.txt</string>
-        <key>name</key>
-        <string>slvoice</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>b583668b28fde0490e6953f10e93e4ab</string>
+              <string>cc7c5bf53f83cff81d874ad66394df0991bd432c</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98681/871545/slvoice-4.10.0000.32327.5fc3fe7c.571099-darwin64-571099.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-slvoice/releases/assets/108299352</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2454,44 +2288,38 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>6e0ed41653955afe8eeb8945776cf07b</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98683/871560/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows-571099.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
+              <key>creds</key>
+              <string>github</string>
               <key>hash</key>
-              <string>c39735851fd05c194d0be09b8f9e8cb7</string>
+              <string>0c205371bb1731a9812b00556037729fdc057cbc</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98682/871552/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows64-571099.tar.bz2</string>
+              <string>https://api.github.com/repos/secondlife/3p-slvoice/releases/assets/108299356</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>Mixed</string>
+        <key>license_file</key>
+        <string>LICENSES/vivox_licenses.txt</string>
+        <key>copyright</key>
+        <string>2010 Vivox, including audio coding using Polycom¨ Siren14TM (ITU-T Rec. G.722.1 Annex C)</string>
         <key>version</key>
         <string>4.10.0000.32327.5fc3fe7c.571099</string>
+        <key>name</key>
+        <string>slvoice</string>
+        <key>description</key>
+        <string>Vivox SDK components</string>
       </map>
       <key>threejs</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright © 2010-2021 three.js authors</string>
-        <key>license</key>
-        <string>MIT</string>
-        <key>license_file</key>
-        <string>LICENSES/THREEJS_LICENSE.txt</string>
-        <key>name</key>
-        <string>threejs</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2499,9 +2327,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>24440e8219e59d81423b68d3be381fef</string>
+              <string>cfed00d8ea7265c035c2d86a234b28efb0b23756</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89305/815412/threejs-0.132.2-darwin64-564843.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-darwin64-b8f6746.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2511,38 +2341,38 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>46edf0f55417f8ef0d33a5c007bc3644</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89310/815451/threejs-0.132.2-windows64-564843.tar.bz2</string>
-            </map>
-          </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>e1303fb9f2242a79aee5fd9f97726ace</string>
+              <string>9de1295b157c9913c28be81ff933c73493ecc132</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89311/815452/threejs-0.132.2-windows-564843.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-linux64-b8f6746.tar.zst</string>
             </map>
-            <key>name</key>
-            <string>windows</string>
           </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>46edf0f55417f8ef0d33a5c007bc3644</string>
+              <string>4141710fccbd1ea2b3b53d00e189bdfa2ee9d441</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89310/815451/threejs-0.132.2-windows64-564843.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-windows64-b8f6746.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>MIT</string>
+        <key>license_file</key>
+        <string>LICENSES/THREEJS_LICENSE.txt</string>
+        <key>copyright</key>
+        <string>Copyright © 2010-2021 three.js authors</string>
         <key>version</key>
         <string>0.132.2</string>
+        <key>name</key>
+        <string>threejs</string>
       </map>
       <key>tinygltf</key>
       <map>
@@ -2582,18 +2412,90 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
       </map>
       <key>tracy</key>
       <map>
-        <key>canonical_repo</key>
-        <string>https://bitbucket.org/lindenlab/3p-tracy</string>
+        <key>platforms</key>
+        <map>
+          <key>darwin64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>9b6e1a1f4b0969d38a1ca8ee00aeb548</string>
+              <key>url</key>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110584/960613/tracy-v0.8.1.578241-darwin64-578241.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin64</string>
+          </map>
+          <key>windows64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>05b72ae5d733aed7d3bf142287601cc6</string>
+              <key>hash_algorithm</key>
+              <string>md5</string>
+              <key>url</key>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110586/960637/tracy-v0.8.1.578241-windows64-578241.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows64</string>
+          </map>
+        </map>
+        <key>license</key>
+        <string>bsd</string>
+        <key>license_file</key>
+        <string>LICENSES/tracy_license.txt</string>
         <key>copyright</key>
         <string>Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl)</string>
+        <key>version</key>
+        <string>v0.8.1.235e98f</string>
+        <key>name</key>
+        <string>tracy</string>
+        <key>canonical_repo</key>
+        <string>https://bitbucket.org/lindenlab/3p-tracy</string>
         <key>description</key>
         <string>Tracy Profiler Library</string>
+        <key>source</key>
+        <string>https://bitbucket.org/lindenlab/3p-tracy</string>
+        <key>source_type</key>
+        <string>git</string>
+        <key>version</key>
+        <string>v0.8.1.578241</string>
+      </map>
+      <key>tut</key>
+      <map>
+        <key>platforms</key>
+        <map>
+          <key>common</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>9f0bf4545f08df5381e0f39ccce3a57c6ec4b0f4</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
+              <key>url</key>
+              <string>https://github.com/secondlife/3p-tut/releases/download/v2008.11.30-409bce5/tut-2008.11.30-common-409bce5.tar.zst</string>
+            </map>
+            <key>name</key>
+            <string>common</string>
+          </map>
+        </map>
         <key>license</key>
         <string>bsd</string>
         <key>license_file</key>
-        <string>LICENSES/tracy_license.txt</string>
+        <string>LICENSES/tut.txt</string>
+        <key>copyright</key>
+        <string>Copyright 2002-2006 Vladimir Dyuzhev, Copyright 2007 Denis Kononenko, Copyright 2008-2009 Michał Rzechonek</string>
+        <key>version</key>
+        <string>2008.11.30</string>
         <key>name</key>
-        <string>tracy</string>
+        <string>tut</string>
+        <key>description</key>
+        <string>TUT is a small and portable unit test framework for C++.</string>
+      </map>
+      <key>uriparser</key>
+      <map>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2601,91 +2503,59 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9b6e1a1f4b0969d38a1ca8ee00aeb548</string>
+              <string>4b6ee5113b1368ec9ff5b59e195adde370b9f585</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110584/960613/tracy-v0.8.1.578241-darwin64-578241.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-uriparser/releases/download/v0.9.4-8fff38a/uriparser-0.9.4-darwin64-8fff38a.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
+          <key>linux64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9e6975565d7337442259324e68bcf59c</string>
+              <string>44dc74ec73e37c56bef6317d12a29d0435cb4bbb</string>
               <key>hash_algorithm</key>
-              <string>md5</string>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110585/960636/tracy-v0.8.1.578241-windows-578241.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-uriparser/releases/download/v0.9.4-8fff38a/uriparser-0.9.4-linux64-8fff38a.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows</string>
+            <string>linux64</string>
           </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>05b72ae5d733aed7d3bf142287601cc6</string>
+              <string>e8b20edfc624f1d09bc83480932a9c844d47fc13</string>
               <key>hash_algorithm</key>
-              <string>md5</string>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110586/960637/tracy-v0.8.1.578241-windows64-578241.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-uriparser/releases/download/v0.9.4-8fff38a/uriparser-0.9.4-windows64-8fff38a.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
-        <key>source</key>
-        <string>https://bitbucket.org/lindenlab/3p-tracy</string>
-        <key>source_type</key>
-        <string>git</string>
-        <key>version</key>
-        <string>v0.8.1.578241</string>
-      </map>
-      <key>tut</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright 2002-2006 Vladimir Dyuzhev, Copyright 2007 Denis Kononenko, Copyright 2008-2009 Michał Rzechonek</string>
-        <key>description</key>
-        <string>TUT is a small and portable unit test framework for C++.</string>
-        <key>license</key>
-        <string>bsd</string>
-        <key>license_file</key>
-        <string>LICENSES/tut.txt</string>
-        <key>name</key>
-        <string>tut</string>
-        <key>platforms</key>
-        <map>
-          <key>common</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>64e1c979aea2f74fe9c2d9d04573336d</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/55001/511871/tut-2008.11.30-common-539059.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>common</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>2008.11.30</string>
-      </map>
-      <key>uriparser</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (C) 2007, Weijia Song &lt;songweijia@gmail.com&gt;, Sebastian Pipping &lt;webmaster@hartwork.org&gt;</string>
-        <key>description</key>
-        <string>uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C. uriparser is cross-platform, fast, supports Unicode and is licensed under the New BSD license.</string>
         <key>license</key>
         <string>New BSD license</string>
         <key>license_file</key>
         <string>LICENSES/uriparser.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 2007, Weijia Song &lt;songweijia@gmail.com&gt;, Sebastian Pipping &lt;webmaster@hartwork.org&gt;</string>
+        <key>version</key>
+        <string>0.9.4</string>
         <key>name</key>
         <string>uriparser</string>
+        <key>description</key>
+        <string>uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C. uriparser is cross-platform, fast, supports Unicode and is licensed under the New BSD license.</string>
+      </map>
+      <key>viewer-manager</key>
+      <map>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2693,9 +2563,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b97d0f6570104277de92d0d3f2d1111d</string>
+              <string>d8bc8720846cfa31e23e7e1008e32ba6ad4a8322</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89474/816487/uriparser-0.9.4-darwin64-564957.tar.bz2</string>
+              <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0.cc7ea1e/viewer_manager-3.0.cc7ea1e-darwin64-cc7ea1e.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2705,53 +2577,49 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>087375378f104cdac0cb0fe0ca43dd4d</string>
+              <string>228fae4ee0ce12b9d1d1b0a8ebb0bdf58ee521eb</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/346/880/uriparser-0.8.0.1-linux64-500342.tar.bz2</string>
+              <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0.cc7ea1e/viewer_manager-3.0.cc7ea1e-linux64-cc7ea1e.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>e2600c798e220cc98c1cc77341aee00d</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89476/816496/uriparser-0.9.4-windows-564957.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>50d857117d31844fc8b84b07b795fd00</string>
+              <string>ca6999b64d96d45952fe872b381db9b2abc0248c</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89475/816497/uriparser-0.9.4-windows64-564957.tar.bz2</string>
+              <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0.cc7ea1e/viewer_manager-3.0.cc7ea1e-windows64-cc7ea1e.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
-        <key>version</key>
-        <string>0.9.4</string>
-      </map>
-      <key>viewer-manager</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (c) 2000-2012, Linden Research, Inc.</string>
-        <key>description</key>
-        <string>Linden Lab Viewer Management Process suite.</string>
         <key>license</key>
         <string>viewerlgpl</string>
         <key>license_file</key>
         <string>LICENSE</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2000-2012, Linden Research, Inc.</string>
+        <key>version</key>
+        <string>3.0.cc7ea1e</string>
         <key>name</key>
         <string>viewer-manager</string>
+        <key>description</key>
+        <string>Linden Lab Viewer Management Process suite.</string>
+        <key>source</key>
+        <string>https://bitbucket.org/lindenlab/vmp-standalone</string>
+        <key>source_type</key>
+        <string>hg</string>
+      </map>
+      <key>vlc-bin</key>
+      <map>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2759,43 +2627,43 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8b091b1f13348eedadf66d7d81cb6bc1</string>
+              <string>a26b47ab01a7e2c0add4c236886162c1135b3b79</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/116621/1003286/viewer_manager-3.0.580913-darwin64-580913.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.16.c219a5d/vlc_bin-3.0.16.c219a5d-darwin64-c219a5d.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
+          <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>647e86470e02509b1cf89829d08dfd46</string>
+              <string>d56002da7435bab166c88d59eeaf69fd87cd897d</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/116623/1003293/viewer_manager-3.0.580913-windows-580913.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.16.c219a5d/vlc_bin-3.0.16.c219a5d-windows64-c219a5d.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows</string>
+            <string>windows64</string>
           </map>
         </map>
-        <key>source</key>
-        <string>https://bitbucket.org/lindenlab/vmp-standalone</string>
-        <key>source_type</key>
-        <string>hg</string>
-        <key>version</key>
-        <string>3.0.580913</string>
-      </map>
-      <key>vlc-bin</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright (C) 1998-2016 VLC authors and VideoLAN</string>
         <key>license</key>
         <string>GPL2</string>
         <key>license_file</key>
         <string>LICENSES/vlc.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 1998-2016 VLC authors and VideoLAN</string>
+        <key>version</key>
+        <string>3.0.16.c219a5d</string>
         <key>name</key>
         <string>vlc-bin</string>
+      </map>
+      <key>xmlrpc-epi</key>
+      <map>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -2803,40 +2671,56 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>738688816ebd76958e49772712a6b972</string>
+              <string>aa12611374876196b3ebb6bda8d419a697217b8b</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90004/820701/vlc_bin-3.0.16.565299-darwin64-565299.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-darwin64-8a05acf.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
           </map>
-          <key>windows</key>
+          <key>linux64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6801f91f3f27e626898bab90d40fc1c3</string>
+              <string>ad0c8b41ee4b4de216382bec46ee1c25962a3f12</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90005/820712/vlc_bin-3.0.16.565299-windows-565299.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-linux64-8a05acf.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows</string>
+            <string>linux64</string>
           </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7f66982d6edf3c38f3493e28826d58e8</string>
+              <string>e53fd38c14b8c47c7c84dead8a1b211bb8be170c</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90006/820713/vlc_bin-3.0.16.565299-windows64-565299.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-windows64-8a05acf.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>xmlrpc-epi</string>
+        <key>license_file</key>
+        <string>LICENSES/xmlrpc-epi.txt</string>
+        <key>copyright</key>
+        <string>Copyright: (C) 2000 Epinions, Inc.</string>
         <key>version</key>
-        <string>3.0.16.565299</string>
+        <string>0.54.1.8a05acf</string>
+        <key>name</key>
+        <string>xmlrpc-epi</string>
+        <key>description</key>
+        <string>XMLRPC Library</string>
       </map>
       <key>vulkan_gltf</key>
       <map>
@@ -2894,116 +2778,80 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>version</key>
         <string>1</string>
       </map>
-      <key>xmlrpc-epi</key>
+      <key>xxhash</key>
       <map>
-        <key>copyright</key>
-        <string>Copyright: (C) 2000 Epinions, Inc.</string>
-        <key>description</key>
-        <string>XMLRPC Library</string>
-        <key>license</key>
-        <string>xmlrpc-epi</string>
-        <key>license_file</key>
-        <string>LICENSES/xmlrpc-epi.txt</string>
-        <key>name</key>
-        <string>xmlrpc-epi</string>
         <key>platforms</key>
         <map>
-          <key>darwin64</key>
+          <key>common</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>922a0dea32266897ed1911200438e1e1</string>
+              <string>e4f77ba0a9b8ec3cc3fabc51c4da81d2</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76372/727426/xmlrpc_epi-0.54.1.555529-darwin64-555529.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110070/956941/xxhash-0.8.1.578006-windows-578006.tar.bz2</string>
             </map>
             <key>name</key>
-            <string>darwin64</string>
+            <string>common</string>
           </map>
-          <key>linux64</key>
+          <key>darwin64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>35df17c3eb673030dea4bde9191aa506</string>
+              <string>fdcc803a76a3359bb426db7dac161406676d51e7</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/727/1489/xmlrpc_epi-0.54.1.500719-linux64-500719.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-darwin64-7501c90.tar.zst</string>
             </map>
             <key>name</key>
-            <string>linux64</string>
+            <string>darwin64</string>
           </map>
-          <key>windows</key>
+          <key>linux64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>34b847e6b280048465fe7c6ce67fe05c</string>
+              <string>7acb3f94a549fbb9bd7bc16604e34f33c5365a9b</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76374/727436/xmlrpc_epi-0.54.1.555529-windows-555529.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-linux64-7501c90.tar.zst</string>
             </map>
             <key>name</key>
-            <string>windows</string>
+            <string>linux64</string>
           </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8fbe7c4ea22bb7f23a93c73884ebb34c</string>
+              <string>4522d075ea4703ef4b527c3039864ef735ea7953</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76373/727435/xmlrpc_epi-0.54.1.555529-windows64-555529.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-windows64-7501c90.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
-        <key>version</key>
-        <string>0.54.1.555529</string>
-      </map>
-      <key>xxhash</key>
-      <map>
-        <key>copyright</key>
-        <string>Copyright 2012-2020 Yann Collet</string>
-        <key>description</key>
-        <string>xxHash Extremely fast hash algorithm</string>
         <key>license</key>
-        <string>bsd</string>
+        <string>xxhash</string>
         <key>license_file</key>
         <string>LICENSES/xxhash.txt</string>
+        <key>copyright</key>
+        <string>Copyright (c) 2012-2021 Yann Collet</string>
+        <key>version</key>
+        <string>0.8.1.7501c90</string>
         <key>name</key>
         <string>xxhash</string>
-        <key>platforms</key>
-        <map>
-          <key>common</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>e4f77ba0a9b8ec3cc3fabc51c4da81d2</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110070/956941/xxhash-0.8.1.578006-windows-578006.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>common</string>
-          </map>
-        </map>
-        <key>version</key>
-        <string>0.8.1</string>
+        <key>description</key>
+        <string>xxHash Library</string>
       </map>
       <key>zlib-ng</key>
       <map>
-        <key>canonical_repo</key>
-        <string>https://bitbucket.org/lindenlab/3p-zlib-ng</string>
-        <key>copyright</key>
-        <string>Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
-        <key>description</key>
-        <string>zlib data compression library for the next generation systems</string>
-        <key>license</key>
-        <string>zlib-ng</string>
-        <key>license_file</key>
-        <string>LICENSES/zlib-ng.txt</string>
-        <key>name</key>
-        <string>zlib-ng</string>
         <key>platforms</key>
         <map>
           <key>darwin64</key>
@@ -3011,9 +2859,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>bf306e38bf81c6095e0967bdef6a2445</string>
+              <string>dacc5f3fb307c4d1292ed1ffb1d595d83599062d</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87759/805718/zlib_ng-2.0.5.563838-darwin64-563838.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v1.2.11.zlib-ng.32fd361/zlib_ng-1.2.11.zlib-ng.32fd361-darwin64-32fd361.tar.zst</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3023,56 +2873,48 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>dab6be8b0596c1e3354f2b6d41335131</string>
+              <string>fba88375e12454ae19f4528e11ffc7ddf7d879ec</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/866/1898/zlib-1.2.8.500857-linux64-500857.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v1.2.11.zlib-ng.32fd361/zlib_ng-1.2.11.zlib-ng.32fd361-linux64-32fd361.tar.zst</string>
             </map>
             <key>name</key>
             <string>linux64</string>
           </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>8ffce5bd00e3d5afa8cb39b855237c4a</string>
-              <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87761/805730/zlib_ng-2.0.5.563838-windows-563838.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
           <key>windows64</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>bd103a9129e57f7ea35886bc7750f8a6</string>
+              <string>ccfca9451063e2d0e95baa73b1ad2054d3e38907</string>
+              <key>hash_algorithm</key>
+              <string>sha1</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87760/805729/zlib_ng-2.0.5.563838-windows64-563838.tar.bz2</string>
+              <string>https://github.com/secondlife/3p-zlib-ng/releases/download/v1.2.11.zlib-ng.32fd361/zlib_ng-1.2.11.zlib-ng.32fd361-windows64-32fd361.tar.zst</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
+        <key>license</key>
+        <string>zlib-ng</string>
+        <key>license_file</key>
+        <string>LICENSES/zlib-ng.txt</string>
+        <key>copyright</key>
+        <string>Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler</string>
         <key>version</key>
-        <string>2.0.5.563838</string>
+        <string>1.2.11.zlib-ng.32fd361</string>
+        <key>name</key>
+        <string>zlib-ng</string>
+        <key>canonical_repo</key>
+        <string>https://bitbucket.org/lindenlab/3p-zlib-ng</string>
+        <key>description</key>
+        <string>zlib data compression library for the next generation systems</string>
       </map>
     </map>
     <key>package_description</key>
     <map>
-      <key>canonical_repo</key>
-      <string>https://github.com/secondlife/viewer</string>
-      <key>copyright</key>
-      <string>Copyright (c) 2020, Linden Research, Inc.</string>
-      <key>description</key>
-      <string>Second Life Viewer</string>
-      <key>license</key>
-      <string>LGPL</string>
-      <key>license_file</key>
-      <string>docs/LICENSE-source.txt</string>
-      <key>name</key>
-      <string>Second Life Viewer</string>
       <key>platforms</key>
       <map>
         <key>common</key>
@@ -3081,9 +2923,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
           <map>
             <key>RelWithDebInfo</key>
             <map>
-              <key>build</key>
-              <map>
-              </map>
               <key>configure</key>
               <map>
                 <key>command</key>
@@ -3094,7 +2933,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
                   <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string>
                   <string>-DINSTALL_PROPRIETARY=TRUE</string>
-                </array>
+</array>
+              </map>
+              <key>build</key>
+              <map>
               </map>
               <key>name</key>
               <string>RelWithDebInfo</string>
@@ -3103,10 +2945,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <map>
               <key>configure</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>../indra</string>
-                </array>
                 <key>command</key>
                 <string>cmake</string>
                 <key>options</key>
@@ -3115,16 +2953,17 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
                   <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
-                </array>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>../indra</string>
+</array>
               </map>
               <key>name</key>
               <string>RelWithDebInfoOS</string>
             </map>
             <key>Release</key>
             <map>
-              <key>build</key>
-              <map>
-              </map>
               <key>configure</key>
               <map>
                 <key>command</key>
@@ -3135,7 +2974,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
                   <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string>
                   <string>-DINSTALL_PROPRIETARY=TRUE</string>
-                </array>
+</array>
+              </map>
+              <key>build</key>
+              <map>
               </map>
               <key>name</key>
               <string>Release</string>
@@ -3144,10 +2986,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <map>
               <key>configure</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>../indra</string>
-                </array>
                 <key>command</key>
                 <string>cmake</string>
                 <key>options</key>
@@ -3156,7 +2994,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE</string>
                   <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
-                </array>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>../indra</string>
+</array>
               </map>
               <key>name</key>
               <string>ReleaseOS</string>
@@ -3167,12 +3009,22 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         </map>
         <key>darwin64</key>
         <map>
-          <key>build_directory</key>
-          <string>build-darwin-x86_64</string>
           <key>configurations</key>
           <map>
             <key>RelWithDebInfo</key>
             <map>
+              <key>configure</key>
+              <map>
+                <key>options</key>
+                <array>
+                  <string>-G</string>
+                  <string>Xcode</string>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>../indra</string>
+</array>
+              </map>
               <key>build</key>
               <map>
                 <key>command</key>
@@ -3184,19 +3036,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-project</string>
                   <string>SecondLife.xcodeproj</string>
                   <string>-parallelizeTargets</string>
-                </array>
-              </map>
-              <key>configure</key>
-              <map>
-                <key>arguments</key>
-                <array>
-                  <string>../indra</string>
-                </array>
-                <key>options</key>
-                <array>
-                  <string>-G</string>
-                  <string>Xcode</string>
-                </array>
+</array>
               </map>
               <key>default</key>
               <string>True</string>
@@ -3205,6 +3045,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             </map>
             <key>RelWithDebInfoOS</key>
             <map>
+              <key>configure</key>
+              <map>
+                <key>options</key>
+                <array>
+                  <string>-G</string>
+                  <string>Xcode</string>
+</array>
+              </map>
               <key>build</key>
               <map>
                 <key>command</key>
@@ -3216,21 +3064,25 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-project</string>
                   <string>SecondLife.xcodeproj</string>
                   <string>-parallelizeTargets</string>
-                </array>
+</array>
               </map>
+              <key>name</key>
+              <string>RelWithDebInfoOS</string>
+            </map>
+            <key>Release</key>
+            <map>
               <key>configure</key>
               <map>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>Xcode</string>
-                </array>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>../indra</string>
+</array>
               </map>
-              <key>name</key>
-              <string>RelWithDebInfoOS</string>
-            </map>
-            <key>Release</key>
-            <map>
               <key>build</key>
               <map>
                 <key>command</key>
@@ -3242,25 +3094,21 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-project</string>
                   <string>SecondLife.xcodeproj</string>
                   <string>-parallelizeTargets</string>
-                </array>
+</array>
               </map>
+              <key>name</key>
+              <string>Release</string>
+            </map>
+            <key>ReleaseOS</key>
+            <map>
               <key>configure</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>../indra</string>
-                </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>Xcode</string>
-                </array>
+</array>
               </map>
-              <key>name</key>
-              <string>Release</string>
-            </map>
-            <key>ReleaseOS</key>
-            <map>
               <key>build</key>
               <map>
                 <key>command</key>
@@ -3272,48 +3120,40 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-project</string>
                   <string>SecondLife.xcodeproj</string>
                   <string>-parallelizeTargets</string>
-                </array>
-              </map>
-              <key>configure</key>
-              <map>
-                <key>options</key>
-                <array>
-                  <string>-G</string>
-                  <string>Xcode</string>
-                </array>
+</array>
               </map>
               <key>name</key>
               <string>ReleaseOS</string>
             </map>
           </map>
+          <key>build_directory</key>
+          <string>build-darwin-x86_64</string>
           <key>name</key>
           <string>darwin64</string>
         </map>
         <key>linux64</key>
         <map>
-          <key>build_directory</key>
-          <string>build-linux-x86_64</string>
           <key>configurations</key>
           <map>
             <key>Release</key>
             <map>
-              <key>build</key>
-              <map>
-                <key>command</key>
-                <string>ninja</string>
-              </map>
               <key>configure</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>../indra</string>
-                </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>Ninja</string>
                   <string>-DLL_TESTS=Off</string>
-                </array>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>../indra</string>
+</array>
+              </map>
+              <key>build</key>
+              <map>
+                <key>command</key>
+                <string>ninja</string>
               </map>
               <key>default</key>
               <string>True</string>
@@ -3322,11 +3162,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             </map>
             <key>ReleaseOS</key>
             <map>
-              <key>build</key>
-              <map>
-                <key>command</key>
-                <string>ninja</string>
-              </map>
               <key>configure</key>
               <map>
                 <key>options</key>
@@ -3334,7 +3169,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>-G</string>
                   <string>Ninja</string>
                   <string>-DLL_TESTS=Off</string>
-                </array>
+</array>
+              </map>
+              <key>build</key>
+              <map>
+                <key>command</key>
+                <string>ninja</string>
               </map>
               <key>name</key>
               <string>ReleaseOS</string>
@@ -3348,44 +3188,44 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
               <string>default</string>
             </map>
           </map>
+          <key>build_directory</key>
+          <string>build-linux-x86_64</string>
           <key>name</key>
           <string>linux64</string>
         </map>
         <key>windows</key>
         <map>
-          <key>build_directory</key>
-          <string>build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE</string>
           <key>configurations</key>
           <map>
             <key>RelWithDebInfo</key>
             <map>
-              <key>build</key>
+              <key>configure</key>
               <map>
+                <key>options</key>
+                <array>
+                  <string>-G</string>
+                  <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
+                  <string>-A</string>
+                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
+</array>
                 <key>arguments</key>
                 <array>
-                  <string>SecondLife.sln</string>
-                </array>
+                  <string>..\indra</string>
+</array>
+              </map>
+              <key>build</key>
+              <map>
                 <key>command</key>
                 <string>devenv</string>
                 <key>options</key>
                 <array>
                   <string>/build</string>
                   <string>RelWithDebInfo|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
-                </array>
-              </map>
-              <key>configure</key>
-              <map>
+</array>
                 <key>arguments</key>
                 <array>
-                  <string>..\indra</string>
-                </array>
-                <key>options</key>
-                <array>
-                  <string>-G</string>
-                  <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
-                  <string>-A</string>
-                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
-                </array>
+                  <string>SecondLife.sln</string>
+</array>
               </map>
               <key>default</key>
               <string>True</string>
@@ -3394,12 +3234,25 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             </map>
             <key>RelWithDebInfoOS</key>
             <map>
-              <key>build</key>
+              <key>configure</key>
               <map>
+                <key>options</key>
+                <array>
+                  <string>-G</string>
+                  <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
+                  <string>-A</string>
+                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
+                  <string>-DINSTALL_PROPRIETARY=FALSE</string>
+                  <string>-DUSE_KDU=FALSE</string>
+                  <string>-DUSE_OPENAL:BOOL=ON</string>
+</array>
                 <key>arguments</key>
                 <array>
-                  <string>SecondLife.sln</string>
-                </array>
+                  <string>..\indra</string>
+</array>
+              </map>
+              <key>build</key>
+              <map>
                 <key>command</key>
                 <string>msbuild.exe</string>
                 <key>options</key>
@@ -3410,69 +3263,70 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>/p:useenv=true</string>
                   <string>/verbosity:minimal</string>
                   <string>/p:VCBuildAdditionalOptions= /incremental</string>
-                </array>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>SecondLife.sln</string>
+</array>
               </map>
+              <key>name</key>
+              <string>RelWithDebInfoOS</string>
+            </map>
+            <key>Release</key>
+            <map>
               <key>configure</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>..\indra</string>
-                </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
                   <string>-A</string>
                   <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
-                  <string>-DINSTALL_PROPRIETARY=FALSE</string>
-                  <string>-DUSE_KDU=FALSE</string>
-                  <string>-DUSE_OPENAL:BOOL=ON</string>
-                </array>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>..\indra</string>
+</array>
               </map>
-              <key>name</key>
-              <string>RelWithDebInfoOS</string>
-            </map>
-            <key>Release</key>
-            <map>
               <key>build</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>SecondLife.sln</string>
-                </array>
                 <key>command</key>
                 <string>devenv</string>
                 <key>options</key>
                 <array>
                   <string>/build</string>
                   <string>Release|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
-                </array>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>SecondLife.sln</string>
+</array>
               </map>
+              <key>name</key>
+              <string>Release</string>
+            </map>
+            <key>ReleaseOS</key>
+            <map>
               <key>configure</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>..\indra</string>
-                </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
                   <string>-A</string>
                   <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
-                </array>
+                  <string>-DUNATTENDED:BOOL=ON</string>
+                  <string>-DINSTALL_PROPRIETARY=FALSE</string>
+                  <string>-DUSE_KDU=FALSE</string>
+                  <string>-DUSE_OPENAL:BOOL=ON</string>
+</array>
+                <key>arguments</key>
+                <array>
+                  <string>..\indra</string>
+</array>
               </map>
-              <key>name</key>
-              <string>Release</string>
-            </map>
-            <key>ReleaseOS</key>
-            <map>
               <key>build</key>
               <map>
-                <key>arguments</key>
-                <array>
-                  <string>SecondLife.sln</string>
-                </array>
                 <key>command</key>
                 <string>msbuild.exe</string>
                 <key>options</key>
@@ -3483,40 +3337,36 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                   <string>/p:useenv=true</string>
                   <string>/verbosity:minimal</string>
                   <string>/p:VCBuildAdditionalOptions= /incremental</string>
-                </array>
-              </map>
-              <key>configure</key>
-              <map>
+</array>
                 <key>arguments</key>
                 <array>
-                  <string>..\indra</string>
-                </array>
-                <key>options</key>
-                <array>
-                  <string>-G</string>
-                  <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
-                  <string>-A</string>
-                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
-                  <string>-DINSTALL_PROPRIETARY=FALSE</string>
-                  <string>-DUSE_KDU=FALSE</string>
-                  <string>-DUSE_OPENAL:BOOL=ON</string>
-                </array>
+                  <string>SecondLife.sln</string>
+</array>
               </map>
               <key>name</key>
               <string>ReleaseOS</string>
             </map>
           </map>
+          <key>build_directory</key>
+          <string>build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE</string>
           <key>name</key>
           <string>windows</string>
         </map>
       </map>
+      <key>license</key>
+      <string>LGPL</string>
+      <key>license_file</key>
+      <string>docs/LICENSE-source.txt</string>
+      <key>copyright</key>
+      <string>Copyright (c) 2020, Linden Research, Inc.</string>
       <key>version_file</key>
       <string>newview/viewer_version.txt</string>
+      <key>name</key>
+      <string>Second Life Viewer</string>
+      <key>canonical_repo</key>
+      <string>https://github.com/secondlife/viewer</string>
+      <key>description</key>
+      <string>Second Life Viewer</string>
     </map>
-    <key>type</key>
-    <string>autobuild</string>
-    <key>version</key>
-    <string>1.3</string>
   </map>
 </llsd>
diff --git a/build.sh b/build.sh
index 89609a9ffd6d3b5b07fa30e6442700b2bf59ce9d..22f9e0c78a4a1ec82f7e99aa0136ae4b46aae9eb 100755
--- a/build.sh
+++ b/build.sh
@@ -16,6 +16,8 @@
 # * The special style in which python is invoked is intentional to permit
 #   use of a native python install on windows - which requires paths in DOS form
 
+cleanup="true"
+
 retry_cmd()
 {
     max_attempts="$1"; shift
@@ -110,6 +112,34 @@ installer_CYGWIN()
   fi
 }
 
+[[ -n "$GITHUB_OUTPUT" ]] || fatal "Need to export GITHUB_OUTPUT"
+# The following is based on the Warning for GitHub multiline output strings:
+# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
+EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
+
+# Build up these arrays as we go
+metadata=()
+symbolfile=()
+physicstpv=()
+# and dump them to GITHUB_OUTPUT when done
+cleanup="$cleanup ; \
+arrayoutput metadata ; \
+arrayoutput symbolfile ; \
+arrayoutput physicstpv"
+trap "$cleanup" EXIT
+
+arrayoutput()
+{
+    local outputname="$1"
+    # append "[*]" to the array name so array indirection works
+    local array="$1[*]"
+    local IFS='
+'
+    echo "$outputname<<$EOF
+${!array}
+$EOF" >> "$GITHUB_OUTPUT"
+}
+
 pre_build()
 {
   local variant="$1"
@@ -121,7 +151,7 @@ pre_build()
     RELEASE_CRASH_REPORTING=ON
     HAVOK=ON
     SIGNING=()
-    if [ "$arch" == "Darwin" -a "$variant" == "Release" ]
+    if [[ "$arch" == "Darwin" && "$variant" == "Release" ]]
     then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
                   "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
     fi
@@ -145,15 +175,27 @@ pre_build()
         VIEWER_SYMBOL_FILE="$(native_path "$abs_build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2")"
     fi
 
-    # don't spew credentials into build log
-    bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
-    set +x
-    if [ -r "$bugsplat_sh" ]
-    then # show that we're doing this, just not the contents
-         echo source "$bugsplat_sh"
-         source "$bugsplat_sh"
+    # expect these variables to be set in the environment from GitHub secrets
+    if [[ -n "$BUGSPLAT_DB" ]]
+    then
+        # don't spew credentials into build log
+        set +x
+        if [[ -z "$BUGSPLAT_USER" || -z "$BUGSPLAT_PASS" ]]
+        then
+            # older mechanism involving build-secrets repo -
+            # if build_secrets_checkout isn't set, report its name
+            bugsplat_sh="${build_secrets_checkout:-\$build_secrets_checkout}/bugsplat/bugsplat.sh"
+            if [ -r "$bugsplat_sh" ]
+            then # show that we're doing this, just not the contents
+                echo source "$bugsplat_sh"
+                source "$bugsplat_sh"
+            else
+                fatal "BUGSPLAT_USER or BUGSPLAT_PASS missing, and no $bugsplat_sh"
+            fi
+        fi
+        set -x
+        export BUGSPLAT_USER BUGSPLAT_PASS
     fi
-    set -x
 
     # honor autobuild_configure_parameters same as sling-buildscripts
     eval_autobuild_configure_parameters=$(eval $(echo echo $autobuild_configure_parameters))
@@ -181,13 +223,17 @@ package_llphysicsextensions_tpv()
   # nat 2016-12-21: without HAVOK, can't build PhysicsExtensions_TPV.
   if [ "$variant" = "Release" -a "${HAVOK:-}" != "OFF" ]
   then 
-      test -r  "$build_dir/packages/llphysicsextensions/autobuild-tpv.xml" || fatal "No llphysicsextensions_tpv autobuild configuration found"
-      tpvconfig=$(native_path "$build_dir/packages/llphysicsextensions/autobuild-tpv.xml")
-      "$autobuild" build --quiet --config-file "$tpvconfig" -c Tpv || fatal "failed to build llphysicsextensions_tpv"
+      tpvconfig="$build_dir/packages/llphysicsextensions/autobuild-tpv.xml"
+      test -r "$tpvconfig" || fatal "No llphysicsextensions_tpv autobuild configuration found"
+      # SL-19942: autobuild ignores -c switch if AUTOBUILD_CONFIGURATION set
+      unset AUTOBUILD_CONFIGURATION
+      "$autobuild" build --quiet --config-file "$(native_path "$tpvconfig")" -c Tpv \
+          || fatal "failed to build llphysicsextensions_tpv"
       
       # capture the package file name for use in upload later...
       PKGTMP=`mktemp -t pgktpv.XXXXXX`
-      trap "rm $PKGTMP* 2>/dev/null" 0
+      cleanup="$cleanup ; rm $PKGTMP* 2>/dev/null"
+      trap "$cleanup" EXIT
       "$autobuild" package --quiet --config-file "$tpvconfig" --results-file "$(native_path $PKGTMP)" || fatal "failed to package llphysicsextensions_tpv"
       tpv_status=$?
       if [ -r "${PKGTMP}" ]
@@ -313,12 +359,20 @@ begin_section "coding policy check"
 # this far. Running coding policy checks on one platform *should* suffice...
 if [[ "$arch" == "Darwin" ]]
 then
-    # install the git-hooks dependencies
-    pip install -r "$(native_path "$git_hooks_checkout/requirements.txt")" || \
-        fatal "pip install git-hooks failed"
-    # validate the branch we're about to build
-    python_cmd "$git_hooks_checkout/coding_policy_git.py" --all_files || \
-        fatal "coding policy check failed"
+    git_hooks_reqs="$git_hooks_checkout/requirements.txt"
+    if [[ -r "$(shell_path "$git_hooks_reqs")" ]]
+    then
+        # install the git-hooks dependencies
+        pip install -r "$(native_path "$git_hooks_reqs")" || \
+            fatal "pip install git-hooks failed"
+    fi
+    git_hooks_script="$git_hooks_checkout/coding_policy_git.py"
+    if [[ -r "$(shell_path "$git_hooks_script")" ]]
+    then
+        # validate the branch we're about to build
+        python_cmd "$(native_path "$git_hooks_script")" --all_files || \
+            fatal "coding policy check failed"
+    fi
 fi
 end_section "coding policy check"
 
@@ -353,6 +407,7 @@ do
                   begin_section "Autobuild metadata"
                   python_cmd "$helpers/codeticket.py" addoutput "Autobuild Metadata" "$build_dir/autobuild-package.xml" --mimetype text/xml \
                       || fatal "Upload of autobuild metadata failed"
+                  metadata+=("$build_dir/autobuild-package.xml")
                   if [ "$arch" != "Linux" ]
                   then
                       record_dependencies_graph "$build_dir/autobuild-package.xml" # defined in buildscripts/hg/bin/build.sh
@@ -366,8 +421,11 @@ do
               if [ -r "$build_dir/newview/viewer_version.txt" ]
               then
                   begin_section "Viewer Version"
-                  python_cmd "$helpers/codeticket.py" addoutput "Viewer Version" "$(<"$build_dir/newview/viewer_version.txt")" --mimetype inline-text \
+                  viewer_version="$(<"$build_dir/newview/viewer_version.txt")"
+                  python_cmd "$helpers/codeticket.py" addoutput "Viewer Version" "$viewer_version" --mimetype inline-text \
                       || fatal "Upload of viewer version failed"
+                  metadata+=("$build_dir/newview/viewer_version.txt")
+                  echo "viewer_version=$viewer_version" >> "$GITHUB_OUTPUT"
                   end_section "Viewer Version"
               fi
               ;;
@@ -376,12 +434,14 @@ do
               then
                   record_event "Doxygen warnings generated; see doxygen_warnings.log"
                   python_cmd "$helpers/codeticket.py" addoutput "Doxygen Log" "$build_dir/doxygen_warnings.log" --mimetype text/plain ## TBD
+                  metadata+=("$build_dir/doxygen_warnings.log")
               fi
               if [ -d "$build_dir/doxygen/html" ]
               then
                   tar -c -f "$build_dir/viewer-doxygen.tar.bz2" --strip-components 3  "$build_dir/doxygen/html"
                   python_cmd "$helpers/codeticket.py" addoutput "Doxygen Tarball" "$build_dir/viewer-doxygen.tar.bz2" \
                       || fatal "Upload of doxygen tarball failed"
+                  metadata+=("$build_dir/viewer-doxygen.tar.bz2")
               fi
               ;;
             *)
@@ -486,64 +546,29 @@ then
   if $build_viewer
   then
     begin_section "Uploads"
-    # Upload installer
-    package=$(installer_$arch)
-    if [ x"$package" = x ] || test -d "$package"
+    # nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
+    if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
     then
-      fatal "No installer found from `pwd`"
-      succeeded=$build_coverity
-    else
-      # Upload base package.
-      retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput Installer "$package"  \
-          || fatal "Upload of installer failed"
-      wait_for_codeticket
-
-      # Upload additional packages.
-      for package_id in $additional_packages
-      do
-        package=$(installer_$arch "$package_id")
-        if [ x"$package" != x ]
+        # BugSplat wants to see xcarchive.zip
+        # e.g. build-darwin-x86_64/newview/Release/Second Life Test.xcarchive.zip
+        symbol_file="${build_dir}/newview/${variant}/${viewer_channel}.xcarchive.zip"
+        if [[ ! -f "$symbol_file" ]]
         then
-          retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \
-              || fatal "Upload of installer $package_id failed"
-          wait_for_codeticket
-        else
-          record_failure "Failed to find additional package for '$package_id'."
+            # symbol tarball we prep for (e.g.) Breakpad
+            symbol_file="$VIEWER_SYMBOL_FILE"
         fi
-      done
-
-      if [ "$last_built_variant" = "Release" ]
-      then
-          # nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
-          if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
-          then
-              # Upload crash reporter file
-              retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
-                  || fatal "Upload of symbolfile failed"
-              wait_for_codeticket
-          fi
-
-          # Upload the llphysicsextensions_tpv package, if one was produced
-          # *TODO: Make this an upload-extension
-          if [ -r "$build_dir/llphysicsextensions_package" ]
-          then
-              llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
-              retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \
-                  || fatal "Upload of physics extensions package failed"
-          fi
-      fi
+        # Upload crash reporter file
+        symbolfile+=("$symbol_file")
+    fi
 
-      # Run upload extensions
-      # Ex: bugsplat
-      if [ -d ${build_dir}/packages/upload-extensions ]; then
-          for extension in ${build_dir}/packages/upload-extensions/*.sh; do
-              begin_section "Upload Extension $extension"
-              . $extension
-              [ $? -eq 0 ] || fatal "Upload of extension $extension failed"
-              wait_for_codeticket
-              end_section "Upload Extension $extension"
-          done
-      fi
+    # Upload the llphysicsextensions_tpv package, if one was produced
+    # Only upload this package when building the private repo so the
+    # artifact is private.
+    if [[ "x$GITHUB_REPOSITORY" == "xsecondlife/viewer-private" && \
+          -r "$build_dir/llphysicsextensions_package" ]]
+    then
+        llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
+        physicstpv+=("$llphysicsextensions_package")
     fi
     end_section "Uploads"
   else
diff --git a/buildscripts_support_functions b/buildscripts_support_functions
new file mode 100644
index 0000000000000000000000000000000000000000..557d2f80fbe12300d5f558e9ee889e84b0c32799
--- /dev/null
+++ b/buildscripts_support_functions
@@ -0,0 +1,60 @@
+# standalone functions from sling-buildscripts
+
+set_build_number_to_revision()
+{
+    record_event "buildNumber $revision"
+}
+
+record_event()
+{
+    echo "=== $@"
+}
+
+begin_section()
+{
+    record_event "START $*"
+    sections+=("$*")
+}
+
+end_section()
+{
+    # accommodate dumb Mac bash 3, which doesn't understand array[-1]
+    local last=$(( ${#sections[@]} - 1 ))
+    record_event "END ${*:-${sections[$last]}}"
+    unset "sections[$last]"
+}
+
+record_success()
+{
+    record_event "SUCCESS $*"
+}
+
+record_failure()
+{
+    record_event "FAILURE $*" >&2
+}
+
+fatal()
+{
+    record_failure "$@"
+    finalize false
+    exit 1
+}
+
+# redefined fail for backward compatibility
+alias fail=fatal
+
+pass()
+{
+  exit 0
+}
+
+export -f set_build_number_to_revision
+export -f record_event
+export -f begin_section
+export -f end_section
+export -f record_success
+export -f record_failure
+export -f fatal
+export -f pass
+export sections
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index a93c5d06e811e712c66320b61a2eee12a13c0dde..24534c98d9fd4d588f81465219d7aad45694f4ad 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -26,6 +26,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
 
 # Portable compilation flags.
 add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE})
+# Because older versions of Boost.Bind dumped placeholders _1, _2 et al. into
+# the global namespace, Boost now requires either BOOST_BIND_NO_PLACEHOLDERS
+# to avoid that or BOOST_BIND_GLOBAL_PLACEHOLDERS to state that we require it
+# -- which we do. Without one or the other, we get a ton of Boost warnings.
+add_compile_definitions(BOOST_BIND_GLOBAL_PLACEHOLDERS)
 
 # Configure crash reporting
 set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
@@ -55,15 +60,6 @@ if (WINDOWS)
   # http://www.cmake.org/pipermail/cmake/2009-September/032143.html
   string(REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
 
-  # Without PreferredToolArchitecture=x64, as of 2020-06-26 the 32-bit
-  # compiler on our TeamCity build hosts has started running out of virtual
-  # memory for the precompiled header file.
-  # CP changed to only append the flag for 32bit builds - on 64bit builds,
-  # locally at least, the build output is spammed with 1000s of 'D9002'
-  # warnings about this switch being ignored.
-  if(ADDRESS_SIZE EQUAL 32 AND DEFINED ENV{"TEAMCITY_PROJECT_NAME"})
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")  
-  endif()
   # zlib has assembly-language object files incompatible with SAFESEH
   add_link_options(/LARGEADDRESSAWARE
           /SAFESEH:NO
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index 8a0939c92c96698ec4809f16e815d1a850633a73..21139319c336817f22ff5d83073800e957285ab7 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -16,7 +16,6 @@ if (WINDOWS)
   endif (LLCOMMON_LINK_SHARED)
   target_link_libraries( ll::apr INTERFACE
           ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib
-          ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apriconv-1.lib
           ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib
           )
 elseif (DARWIN)
@@ -37,7 +36,6 @@ else (WINDOWS)
   target_link_libraries( ll::apr INTERFACE
           apr-1
           aprutil-1
-          iconv
           uuid
           rt
           )
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index d43cc3070690f5798dca64a714cf8474489998c1..a3db02372d85861d66a3f181ea1090adf5f72017 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -57,7 +57,6 @@ if(WINDOWS)
         openjp2.dll
         libapr-1.dll
         libaprutil-1.dll
-        libapriconv-1.dll
         nghttp2.dll
         libhunspell.dll
         uriparser.dll
@@ -172,7 +171,6 @@ elseif(DARWIN)
         libndofdev.dylib
         libnghttp2.dylib
         libnghttp2.14.dylib
-        libnghttp2.14.19.0.dylib
         liburiparser.dylib
         liburiparser.1.dylib
         liburiparser.1.0.27.dylib
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 4a501f420b52a43fab584dab105bc5ad872ddcba..1ce21c11f97aeb7c51d54bc58b37f9bfb6b29150 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -62,6 +62,7 @@ elseif (WINDOWS)
           user32
           ole32
           dbghelp
+          rpcrt4.lib
           legacy_stdio_definitions
           )
 else()
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 820f356daec25e5816bc2f8772f365931a1acfdc..bcb9d884c38bd60c485710da4c9ce62c1e9f0ef8 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -38,6 +38,7 @@
 import operator
 import os
 import re
+import shlex
 import shutil
 import subprocess
 import sys
@@ -531,15 +532,15 @@ def ensure_dst_dir(self, reldir):
         self.cmakedirs(path)
         return path
 
-    def run_command(self, command):
+    def run_command(self, command, **kwds):
         """ 
         Runs an external command.  
         Raises ManifestError exception if the command returns a nonzero status.
         """
-        print("Running command:", command)
+        print("Running command:", shlex.join(command))
         sys.stdout.flush()
         try:
-            subprocess.check_call(command)
+            subprocess.check_call(command, **kwds)
         except subprocess.CalledProcessError as err:
             raise ManifestError( "Command %s returned non-zero status (%s)"
                                 % (command, err.returncode) )
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index a1338989693942ac96102629a70cb1dab306db31..c045d18c42f0eba3a9ee038c48e868ab4a6f9436 100755
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -30,6 +30,7 @@
 
 #include <list>
 #include <map>
+#include <array>
 
 #include "v3math.h"
 #include "v3dmath.h"
diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h
index a3cab97cd2f4ab4663ed569150bf6d06eed18055..562c96c794bd294b253c6186d2452f85d627d382 100644
--- a/indra/llaudio/llaudioengine_openal.h
+++ b/indra/llaudio/llaudioengine_openal.h
@@ -42,6 +42,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
 
         virtual bool init(void *user_data, const std::string &app_title);
         virtual std::string getDriverName(bool verbose);
+        virtual LLStreamingAudioInterface* createDefaultStreamingAudioImpl() const { return nullptr; }
 		virtual void allocateListener();
 
 		virtual void shutdown();
@@ -56,7 +57,6 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
 		/*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);
 
 	private:
-		void * windDSP(void *newbuffer, int length);
         typedef S16 WIND_SAMPLE_T;
     	LLWindGen<WIND_SAMPLE_T> *mWindGen;
     	S16 *mWindBuf;
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 70d8dfc8b932565668b5617ae4f51559660fadf5..cfaf3415e762ad56dbc92b45ff22a64f6b901c06 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -123,11 +123,7 @@ LLCoros::LLCoros():
     // Previously we used
     // boost::context::guarded_stack_allocator::default_stacksize();
     // empirically this is insufficient.
-#if ADDRESS_SIZE == 64
-    mStackSize(512*1024),
-#else
-    mStackSize(256*1024),
-#endif
+    mStackSize(768*1024),
     // mCurrent does NOT own the current CoroData instance -- it simply
     // points to it. So initialize it with a no-op deleter.
     mCurrent{ [](CoroData*){} }
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index eaf1be60f23aea495cd7d1851ba975ac2492ac17..414515854a241be125a3d33ab5b662b6bb75b40d 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1603,5 +1603,18 @@ namespace LLError
     }
 }
 
-
-
+void crashdriver(void (*callback)(int*))
+{
+    // The LLERROR_CRASH macro used to have inline code of the form:
+    //int* make_me_crash = NULL;
+    //*make_me_crash = 0;
+
+    // But compilers are getting smart enough to recognize that, so we must
+    // assign to an address supplied by a separate source file. We could do
+    // the assignment here in crashdriver() -- but then BugSplat would group
+    // all LL_ERRS() crashes as the fault of this one function, instead of
+    // identifying the specific LL_ERRS() source line. So instead, do the
+    // assignment in a lambda in the caller's source. We just provide the
+    // nullptr target.
+    callback(nullptr);
+}
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index f229b4964a8e60e9fa1b36b366ed6860924f8f67..05dd88ee514fc5a2097b7888d0744359e3699efd 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -385,11 +385,9 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
 #define LL_NEWLINE '\n'
 
 // Use this only in LL_ERRS or in a place that LL_ERRS may not be used
-#define LLERROR_CRASH         \
-{                             \
-    int* make_me_crash = NULL;\
-    *make_me_crash = 0;       \
-    exit(*make_me_crash);     \
+#define LLERROR_CRASH                                   \
+{                                                       \
+    crashdriver([](int* ptr){ *ptr = 0; exit(*ptr); }); \
 }
 
 #define LL_ENDL                                         \
@@ -491,4 +489,7 @@ LL_DEBUGS("SomeTag") performs the locking and map-searching ONCE, then caches
 the result in a static variable.
 */ 
 
+// used by LLERROR_CRASH
+void crashdriver(void (*)(int*));
+
 #endif // LL_LLERROR_H
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index 259f5bc5051bc0be4b96c1faa1d510aaf9d64b4c..5b5bf97cef2e1545c06423d2a40e3704c958d4e6 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -389,6 +389,17 @@ class LLLeapImpl: public LLLeap
             // Read all remaining bytes and log.
             LL_INFOS("LLLeap") << mDesc << ": " << rest << LL_ENDL;
         }
+        /*--------------------------- diagnostic ---------------------------*/
+        else if (data["eof"].asBoolean())
+        {
+            LL_DEBUGS("LLLeap") << mDesc << " ended, no partial line" << LL_ENDL;
+        }
+        else
+        {
+            LL_DEBUGS("LLLeap") << mDesc << " (still running, " << childerr.size()
+                                << " bytes pending)" << LL_ENDL;
+        }
+        /*------------------------- end diagnostic -------------------------*/
         return false;
     }
 
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 4a1a81f083875824e15358183d836321610110e1..28f8bc2b930d946a558a6404d6310a26ee15a543 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -746,7 +746,7 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl
 		__cpuid(0x1, eax, ebx, ecx, edx);
 		if(feature_infos[0] != (S32)edx)
 		{
-			LL_ERRS() << "machdep.cpu.feature_bits doesn't match expected cpuid result!" << LL_ENDL;
+			LL_WARNS() << "machdep.cpu.feature_bits doesn't match expected cpuid result!" << LL_ENDL;
 		} 
 #endif // LL_RELEASE_FOR_DOWNLOAD 	
 
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
index cb28a8f5c3910c4b4436c1cb18519ca4e24f137d..33afc50cf78881747294ca8187ce036f5a2a8e07 100644
--- a/indra/llcommon/llrand.cpp
+++ b/indra/llcommon/llrand.cpp
@@ -58,46 +58,14 @@
  * to restore uniform distribution.
  */
 
-// *NOTE: The system rand implementation is probably not correct.
-#define LL_USE_SYSTEM_RAND 0
+static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
 
-#if LL_USE_SYSTEM_RAND
-#include <cstdlib>
-#endif
+// no default implementation, only specific F64 and F32 specializations
+template <typename REAL>
+inline REAL ll_internal_random();
 
-#if LL_USE_SYSTEM_RAND
-class LLSeedRand
-{
-public:
-	LLSeedRand()
-	{
-#if LL_WINDOWS
-		srand(LLUUID::getRandomSeed());
-#else
-		srand48(LLUUID::getRandomSeed());
-#endif
-	}
-};
-static LLSeedRand sRandomSeeder;
-inline F64 ll_internal_random_double()
-{
-#if LL_WINDOWS
-	return (F64)rand() / (F64)RAND_MAX; 
-#else
-	return drand48();
-#endif
-}
-inline F32 ll_internal_random_float()
-{
-#if LL_WINDOWS
-	return (F32)rand() / (F32)RAND_MAX; 
-#else
-	return (F32)drand48();
-#endif
-}
-#else
-static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
-inline F64 ll_internal_random_double()
+template <>
+inline F64 ll_internal_random<F64>()
 {
 	// *HACK: Through experimentation, we have found that dual core
 	// CPUs (or at least multi-threaded processes) seem to
@@ -108,15 +76,35 @@ inline F64 ll_internal_random_double()
 	return rv;
 }
 
+template <>
+inline F32 ll_internal_random<F32>()
+{
+    return F32(ll_internal_random<F64>());
+}
+
+/*------------------------------ F64 aliases -------------------------------*/
+inline F64 ll_internal_random_double()
+{
+    return ll_internal_random<F64>();
+}
+
+F64 ll_drand()
+{
+	return ll_internal_random_double();
+}
+
+/*------------------------------ F32 aliases -------------------------------*/
 inline F32 ll_internal_random_float()
 {
-	// The clamping rules are described above.
-	F32 rv = (F32)gRandomGenerator();
-	if(!((rv >= 0.0f) && (rv < 1.0f))) return fmod(rv, 1.f);
-	return rv;
+    return ll_internal_random<F32>();
+}
+
+F32 ll_frand()
+{
+	return ll_internal_random_float();
 }
-#endif
 
+/*-------------------------- clamped random range --------------------------*/
 S32 ll_rand()
 {
 	return ll_rand(RAND_MAX);
@@ -130,42 +118,28 @@ S32 ll_rand(S32 val)
 	return rv;
 }
 
-F32 ll_frand()
-{
-	return ll_internal_random_float();
-}
-
-F32 ll_frand(F32 val)
+template <typename REAL>
+REAL ll_grand(REAL val)
 {
 	// The clamping rules are described above.
-	F32 rv = ll_internal_random_float() * val;
+	REAL rv = ll_internal_random<REAL>() * val;
 	if(val > 0)
 	{
-		if(rv >= val) return 0.0f;
+		if(rv >= val) return REAL();
 	}
 	else
 	{
-		if(rv <= val) return 0.0f;
+		if(rv <= val) return REAL();
 	}
 	return rv;
 }
 
-F64 ll_drand()
+F32 ll_frand(F32 val)
 {
-	return ll_internal_random_double();
+    return ll_grand<F32>(val);
 }
 
 F64 ll_drand(F64 val)
 {
-	// The clamping rules are described above.
-	F64 rv = ll_internal_random_double() * val;
-	if(val > 0)
-	{
-		if(rv >= val) return 0.0;
-	}
-	else
-	{
-		if(rv <= val) return 0.0;
-	}
-	return rv;
+    return ll_grand<F64>(val);
 }
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index 3ae48a25328eea1bc44d58e62fe0871d184925c2..7197dedfbf27aa7b019e451341005831296a03e7 100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -17,8 +17,6 @@
 // std headers
 #include <functional>
 // external library headers
-#include <boost/assign/list_of.hpp>
-#include <boost/phoenix/core/argument.hpp>
 // other Linden headers
 #include "../test/lltut.h"
 #include "../test/namedtempfile.h"
@@ -30,10 +28,6 @@
 #include "stringize.h"
 #include "StringVec.h"
 
-using boost::assign::list_of;
-
-StringVec sv(const StringVec& listof) { return listof; }
-
 #if defined(LL_WINDOWS)
 #define sleep(secs) _sleep((secs) * 1000)
 
@@ -104,17 +98,12 @@ namespace tut
         llleap_data():
             reader(".py",
                    // This logic is adapted from vita.viewerclient.receiveEvent()
-                   boost::phoenix::placeholders::arg1 <<
+                   [](std::ostream& out){ out <<
                    "import re\n"
                    "import os\n"
                    "import sys\n"
                    "\n"
-                   "try:\n"
-                   // new freestanding llsd package
-                   "    import llsd\n"
-                   "except ImportError:\n"
-                   // older llbase.llsd module
-                   "    from llbase import llsd\n"
+                   "import llsd\n"
                    "\n"
                    "class ProtocolError(Exception):\n"
                    "    def __init__(self, msg, data):\n"
@@ -193,7 +182,7 @@ namespace tut
                    "def request(pump, data):\n"
                    "    # we expect 'data' is a dict\n"
                    "    data['reply'] = _reply\n"
-                   "    send(pump, data)\n"),
+                   "    send(pump, data)\n";}),
             // Get the actual pathname of the NamedExtTempFile and trim off
             // the ".py" extension. (We could cache reader.getName() in a
             // separate member variable, but I happen to know getName() just
@@ -218,14 +207,14 @@ namespace tut
     void object::test<1>()
     {
         set_test_name("multiple LLLeap instances");
-        NamedTempFile script("py",
-                             "import time\n"
-                             "time.sleep(1)\n");
+        NamedExtTempFile script("py",
+                                "import time\n"
+                                "time.sleep(1)\n");
         LLLeapVector instances;
         instances.push_back(LLLeap::create(get_test_name(),
-                                           sv(list_of(PYTHON)(script.getName())))->getWeak());
+                                           StringVec{PYTHON, script.getName()})->getWeak());
         instances.push_back(LLLeap::create(get_test_name(),
-                                           sv(list_of(PYTHON)(script.getName())))->getWeak());
+                                           StringVec{PYTHON, script.getName()})->getWeak());
         // In this case we're simply establishing that two LLLeap instances
         // can coexist without throwing exceptions or bombing in any other
         // way. Wait for them to terminate.
@@ -236,10 +225,10 @@ namespace tut
     void object::test<2>()
     {
         set_test_name("stderr to log");
-        NamedTempFile script("py",
-                             "import sys\n"
-                             "sys.stderr.write('''Hello from Python!\n"
-                             "note partial line''')\n");
+        NamedExtTempFile script("py",
+                                "import sys\n"
+                                "sys.stderr.write('''Hello from Python!\n"
+                                "note partial line''')\n");
         StringVec vcommand{ PYTHON, script.getName() };
         CaptureLog log(LLError::LEVEL_INFO);
         waitfor(LLLeap::create(get_test_name(), vcommand));
@@ -251,11 +240,11 @@ namespace tut
     void object::test<3>()
     {
         set_test_name("bad stdout protocol");
-        NamedTempFile script("py",
-                             "print('Hello from Python!')\n");
+        NamedExtTempFile script("py",
+                                "print('Hello from Python!')\n");
         CaptureLog log(LLError::LEVEL_WARN);
         waitfor(LLLeap::create(get_test_name(),
-                               sv(list_of(PYTHON)(script.getName()))));
+                               StringVec{PYTHON, script.getName()}));
         ensure_contains("error log line",
                         log.messageWith("invalid protocol"), "Hello from Python!");
     }
@@ -264,13 +253,13 @@ namespace tut
     void object::test<4>()
     {
         set_test_name("leftover stdout");
-        NamedTempFile script("py",
-                             "import sys\n"
-                             // note lack of newline
-                             "sys.stdout.write('Hello from Python!')\n");
+        NamedExtTempFile script("py",
+                                "import sys\n"
+                                // note lack of newline
+                                "sys.stdout.write('Hello from Python!')\n");
         CaptureLog log(LLError::LEVEL_WARN);
         waitfor(LLLeap::create(get_test_name(),
-                               sv(list_of(PYTHON)(script.getName()))));
+                               StringVec{PYTHON, script.getName()}));
         ensure_contains("error log line",
                         log.messageWith("Discarding"), "Hello from Python!");
     }
@@ -279,12 +268,12 @@ namespace tut
     void object::test<5>()
     {
         set_test_name("bad stdout len prefix");
-        NamedTempFile script("py",
-                             "import sys\n"
-                             "sys.stdout.write('5a2:something')\n");
+        NamedExtTempFile script("py",
+                                "import sys\n"
+                                "sys.stdout.write('5a2:something')\n");
         CaptureLog log(LLError::LEVEL_WARN);
         waitfor(LLLeap::create(get_test_name(),
-                               sv(list_of(PYTHON)(script.getName()))));
+                               StringVec{PYTHON, script.getName()}));
         ensure_contains("error log line",
                         log.messageWith("invalid protocol"), "5a2:");
     }
@@ -386,17 +375,18 @@ namespace tut
         set_test_name("round trip");
         AckAPI api;
         Result result;
-        NamedTempFile script("py",
-                             boost::phoenix::placeholders::arg1 <<
-                             "from " << reader_module << " import *\n"
-                             // make a request on our little API
-                             "request(pump='" << api.getName() << "', data={})\n"
-                             // wait for its response
-                             "resp = get()\n"
-                             "result = '' if resp == dict(pump=replypump(), data='ack')\\\n"
-                             "            else 'bad: ' + str(resp)\n"
-                             "send(pump='" << result.getName() << "', data=result)\n");
-        waitfor(LLLeap::create(get_test_name(), sv(list_of(PYTHON)(script.getName()))));
+        NamedExtTempFile script("py",
+                                [&](std::ostream& out){ out <<
+                                "from " << reader_module << " import *\n"
+                                // make a request on our little API
+                                "request(pump='" << api.getName() << "', data={})\n"
+                                // wait for its response
+                                "resp = get()\n"
+                                "result = '' if resp == dict(pump=replypump(), data='ack')\\\n"
+                                "            else 'bad: ' + str(resp)\n"
+                                "send(pump='" << result.getName() << "', data=result)\n";});
+        waitfor(LLLeap::create(get_test_name(),
+                               StringVec{PYTHON, script.getName()}));
         result.ensure();
     }
 
@@ -424,38 +414,38 @@ namespace tut
         // iterations etc. in OS pipes and the LLLeap/LLProcess implementation.
         ReqIDAPI api;
         Result result;
-        NamedTempFile script("py",
-                             boost::phoenix::placeholders::arg1 <<
-                             "import sys\n"
-                             "from " << reader_module << " import *\n"
-                             // Note that since reader imports llsd, this
-                             // 'import *' gets us llsd too.
-                             "sample = llsd.format_notation(dict(pump='" <<
-                             api.getName() << "', data=dict(reqid=999999, reply=replypump())))\n"
-                             // The whole packet has length prefix too: "len:data"
-                             "samplen = len(str(len(sample))) + 1 + len(sample)\n"
-                             // guess how many messages it will take to
-                             // accumulate BUFFERED_LENGTH
-                             "count = int(" << BUFFERED_LENGTH << "/samplen)\n"
-                             "print('Sending %s requests' % count, file=sys.stderr)\n"
-                             "for i in range(count):\n"
-                             "    request('" << api.getName() << "', dict(reqid=i))\n"
-                             // The assumption in this specific test that
-                             // replies will arrive in the same order as
-                             // requests is ONLY valid because the API we're
-                             // invoking sends replies instantly. If the API
-                             // had to wait for some external event before
-                             // sending its reply, replies could arrive in
-                             // arbitrary order, and we'd have to tick them
-                             // off from a set.
-                             "result = ''\n"
-                             "for i in range(count):\n"
-                             "    resp = get()\n"
-                             "    if resp['data']['reqid'] != i:\n"
-                             "        result = 'expected reqid=%s in %s' % (i, resp)\n"
-                             "        break\n"
-                             "send(pump='" << result.getName() << "', data=result)\n");
-        waitfor(LLLeap::create(get_test_name(), sv(list_of(PYTHON)(script.getName()))),
+        NamedExtTempFile script("py",
+                                [&](std::ostream& out){ out <<
+                                "import sys\n"
+                                "from " << reader_module << " import *\n"
+                                // Note that since reader imports llsd, this
+                                // 'import *' gets us llsd too.
+                                "sample = llsd.format_notation(dict(pump='" <<
+                                api.getName() << "', data=dict(reqid=999999, reply=replypump())))\n"
+                                // The whole packet has length prefix too: "len:data"
+                                "samplen = len(str(len(sample))) + 1 + len(sample)\n"
+                                // guess how many messages it will take to
+                                // accumulate BUFFERED_LENGTH
+                                "count = int(" << BUFFERED_LENGTH << "/samplen)\n"
+                                "print('Sending %s requests' % count, file=sys.stderr)\n"
+                                "for i in range(count):\n"
+                                "    request('" << api.getName() << "', dict(reqid=i))\n"
+                                // The assumption in this specific test that
+                                // replies will arrive in the same order as
+                                // requests is ONLY valid because the API we're
+                                // invoking sends replies instantly. If the API
+                                // had to wait for some external event before
+                                // sending its reply, replies could arrive in
+                                // arbitrary order, and we'd have to tick them
+                                // off from a set.
+                                "result = ''\n"
+                                "for i in range(count):\n"
+                                "    resp = get()\n"
+                                "    if resp['data']['reqid'] != i:\n"
+                                "        result = 'expected reqid=%s in %s' % (i, resp)\n"
+                                "        break\n"
+                                "send(pump='" << result.getName() << "', data=result)\n";});
+        waitfor(LLLeap::create(get_test_name(), StringVec{PYTHON, script.getName()}),
                 300);               // needs more realtime than most tests
         result.ensure();
     }
@@ -467,65 +457,62 @@ namespace tut
     {
         ReqIDAPI api;
         Result result;
-        NamedTempFile script("py",
-                             boost::phoenix::placeholders::arg1 <<
-                             "import sys\n"
-                             "from " << reader_module << " import *\n"
-                             // Generate a very large string value.
-                             "desired = int(sys.argv[1])\n"
-                             // 7 chars per item: 6 digits, 1 comma
-                             "count = int((desired - 50)/7)\n"
-                             "large = ''.join('%06d,' % i for i in range(count))\n"
-                             // Pass 'large' as reqid because we know the API
-                             // will echo reqid, and we want to receive it back.
-                             "request('" << api.getName() << "', dict(reqid=large))\n"
-                             "try:\n"
-                             "    resp = get()\n"
-                             "except ParseError as e:\n"
-                             "    # try to find where e.data diverges from expectation\n"
-                             // Normally we'd expect a 'pump' key in there,
-                             // too, with value replypump(). But Python
-                             // serializes keys in a different order than C++,
-                             // so incoming data start with 'data'.
-                             // Truthfully, though, if we get as far as 'pump'
-                             // before we find a difference, something's very
-                             // strange.
-                             "    expect = llsd.format_notation(dict(data=dict(reqid=large)))\n"
-                             "    chunk = 40\n"
-                             "    for offset in range(0, max(len(e.data), len(expect)), chunk):\n"
-                             "        if e.data[offset:offset+chunk] != \\\n"
-                             "           expect[offset:offset+chunk]:\n"
-                             "            print('Offset %06d: expect %r,\\n'\\\n"
-                             "                                '                  get %r' %\\\n"
-                             "                                (offset,\n"
-                             "                                 expect[offset:offset+chunk],\n"
-                             "                                 e.data[offset:offset+chunk]),\n"
-                             "                                 file=sys.stderr)\n"
-                             "            break\n"
-                             "    else:\n"
-                             "        print('incoming data matches expect?!', file=sys.stderr)\n"
-                             "    send('" << result.getName() << "', '%s: %s' % (e.__class__.__name__, e))\n"
-                             "    sys.exit(1)\n"
-                             "\n"
-                             "echoed = resp['data']['reqid']\n"
-                             "if echoed == large:\n"
-                             "    send('" << result.getName() << "', '')\n"
-                             "    sys.exit(0)\n"
-                             // Here we know echoed did NOT match; try to find where
-                             "for i in range(count):\n"
-                             "    start = 7*i\n"
-                             "    end   = 7*(i+1)\n"
-                             "    if end > len(echoed)\\\n"
-                             "    or echoed[start:end] != large[start:end]:\n"
-                             "        send('" << result.getName() << "',\n"
-                             "             'at offset %s, expected %r but got %r' %\n"
-                             "             (start, large[start:end], echoed[start:end]))\n"
-                             "sys.exit(1)\n");
+        NamedExtTempFile script("py",
+                                [&](std::ostream& out){ out <<
+                                "import sys\n"
+                                "from " << reader_module << " import *\n"
+                                // Generate a very large string value.
+                                "desired = int(sys.argv[1])\n"
+                                // 7 chars per item: 6 digits, 1 comma
+                                "count = int((desired - 50)/7)\n"
+                                "large = ''.join('%06d,' % i for i in range(count))\n"
+                                // Pass 'large' as reqid because we know the API
+                                // will echo reqid, and we want to receive it back.
+                                "request('" << api.getName() << "', dict(reqid=large))\n"
+                                "try:\n"
+                                "    resp = get()\n"
+                                "except ParseError as e:\n"
+                                "    # try to find where e.data diverges from expectation\n"
+                                // Normally we'd expect a 'pump' key in there,
+                                // too, with value replypump(). But Python
+                                // serializes keys in a different order than C++,
+                                // so incoming data start with 'data'.
+                                // Truthfully, though, if we get as far as 'pump'
+                                // before we find a difference, something's very
+                                // strange.
+                                "    expect = llsd.format_notation(dict(data=dict(reqid=large)))\n"
+                                "    chunk = 40\n"
+                                "    for offset in range(0, max(len(e.data), len(expect)), chunk):\n"
+                                "        if e.data[offset:offset+chunk] != \\\n"
+                                "           expect[offset:offset+chunk]:\n"
+                                "            print('Offset %06d: expect %r,\\n'\\\n"
+                                "                                '                  get %r' %\\\n"
+                                "                                (offset,\n"
+                                "                                 expect[offset:offset+chunk],\n"
+                                "                                 e.data[offset:offset+chunk]),\n"
+                                "                                 file=sys.stderr)\n"
+                                "            break\n"
+                                "    else:\n"
+                                "        print('incoming data matches expect?!', file=sys.stderr)\n"
+                                "    send('" << result.getName() << "', '%s: %s' % (e.__class__.__name__, e))\n"
+                                "    sys.exit(1)\n"
+                                "\n"
+                                "echoed = resp['data']['reqid']\n"
+                                "if echoed == large:\n"
+                                "    send('" << result.getName() << "', '')\n"
+                                "    sys.exit(0)\n"
+                                // Here we know echoed did NOT match; try to find where
+                                "for i in range(count):\n"
+                                "    start = 7*i\n"
+                                "    end   = 7*(i+1)\n"
+                                "    if end > len(echoed)\\\n"
+                                "    or echoed[start:end] != large[start:end]:\n"
+                                "        send('" << result.getName() << "',\n"
+                                "             'at offset %s, expected %r but got %r' %\n"
+                                "             (start, large[start:end], echoed[start:end]))\n"
+                                "sys.exit(1)\n";});
         waitfor(LLLeap::create(test_name,
-                               sv(list_of
-                                  (PYTHON)
-                                  (script.getName())
-                                  (stringize(size)))),
+                               StringVec{PYTHON, script.getName(), stringize(size)}),
                 180);               // try a longer timeout
         result.ensure();
     }
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index 81449b4a421ba549c78c04f77b1d6c3b87b2f721..b6b297b8d7bfafdfb790837b72345d7a55ba2a52 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -151,8 +151,38 @@ struct PythonProcessLauncher
     /// Launch Python script; verify that it launched
     void launch()
     {
-        mPy = LLProcess::create(mParams);
-        tut::ensure(STRINGIZE("Couldn't launch " << mDesc << " script"), bool(mPy));
+        try
+        {
+            mPy = LLProcess::create(mParams);
+            tut::ensure(STRINGIZE("Couldn't launch " << mDesc << " script"), bool(mPy));
+        }
+        catch (const tut::failure&)
+        {
+            // On Windows, if APR_LOG is set, our version of APR's
+            // apr_create_proc() logs to the specified file. If this test
+            // failed, try to report that log.
+            const char* APR_LOG = getenv("APR_LOG");
+            if (APR_LOG && *APR_LOG)
+            {
+                std::ifstream inf(APR_LOG);
+                if (! inf.is_open())
+                {
+                    LL_WARNS() << "Couldn't open '" << APR_LOG << "'" << LL_ENDL;
+                }
+                else
+                {
+                    LL_WARNS() << "==============================" << LL_ENDL;
+                    LL_WARNS() << "From '" << APR_LOG << "':" << LL_ENDL;
+                    std::string line;
+                    while (std::getline(inf, line))
+                    {
+                        LL_WARNS() << line << LL_ENDL;
+                    }
+                    LL_WARNS() << "==============================" << LL_ENDL;
+                }
+            }
+            throw;
+        }
     }
 
     /// Run Python script and wait for it to complete.
@@ -191,7 +221,7 @@ struct PythonProcessLauncher
     LLProcess::Params mParams;
     LLProcessPtr mPy;
     std::string mDesc;
-    NamedTempFile mScript;
+    NamedExtTempFile mScript;
 };
 
 /// convenience function for PythonProcessLauncher::run()
@@ -214,30 +244,26 @@ static std::string python_out(const std::string& desc, const CONTENT& script)
 class NamedTempDir: public boost::noncopyable
 {
 public:
-    // Use python() function to create a temp directory: I've found
-    // nothing in either Boost.Filesystem or APR quite like Python's
-    // tempfile.mkdtemp().
-    // Special extra bonus: on Mac, mkdtemp() reports a pathname
-    // starting with /var/folders/something, whereas that's really a
-    // symlink to /private/var/folders/something. Have to use
-    // realpath() to compare properly.
     NamedTempDir():
-        mPath(python_out("mkdtemp()",
-                         "from __future__ import with_statement\n"
-                         "import os.path, sys, tempfile\n"
-                         "with open(sys.argv[1], 'w') as f:\n"
-                         "    f.write(os.path.normcase(os.path.normpath(os.path.realpath(tempfile.mkdtemp()))))\n"))
-    {}
+        mPath(NamedTempFile::temp_path()),
+        mCreated(boost::filesystem::create_directories(mPath))
+    {
+        mPath = boost::filesystem::canonical(mPath);
+    }
 
     ~NamedTempDir()
     {
-        aprchk(apr_dir_remove(mPath.c_str(), gAPRPoolp));
+        if (mCreated)
+        {
+            boost::filesystem::remove_all(mPath);
+        }
     }
 
-    std::string getName() const { return mPath; }
+    std::string getName() const { return mPath.string(); }
 
 private:
-    std::string mPath;
+    boost::filesystem::path mPath;
+    bool mCreated;
 };
 
 /*****************************************************************************
@@ -355,7 +381,7 @@ namespace tut
         set_test_name("raw APR nonblocking I/O");
 
         // Create a script file in a temporary place.
-        NamedTempFile script("py",
+        NamedExtTempFile script("py",
             "from __future__ import print_function" EOL
             "import sys" EOL
             "import time" EOL
@@ -565,7 +591,13 @@ namespace tut
                                  "    f.write(os.path.normcase(os.path.normpath(os.getcwd())))\n");
         // Before running, call setWorkingDirectory()
         py.mParams.cwd = tempdir.getName();
-        ensure_equals("os.getcwd()", py.run_read(), tempdir.getName());
+        std::string expected{ tempdir.getName() };
+#if LL_WINDOWS
+        // SIGH, don't get tripped up by "C:" != "c:" --
+        // but on the Mac, using tolower() fails because "/users" != "/Users"!
+        expected = utf8str_tolower(expected);
+#endif
+        ensure_equals("os.getcwd()", py.run_read(), expected);
     }
 
     template<> template<>
diff --git a/indra/llcommon/tests/llrand_test.cpp b/indra/llcommon/tests/llrand_test.cpp
index 383e6f9e0a926fdd04fa68d3a76848b2aa0a9aa6..ac5a33d0ba0a9049eb5f7d44c3767ba6837c8dc0 100644
--- a/indra/llcommon/tests/llrand_test.cpp
+++ b/indra/llcommon/tests/llrand_test.cpp
@@ -29,7 +29,23 @@
 #include "../test/lltut.h"
 
 #include "../llrand.h"
+#include "stringize.h"
 
+// In llrand.h, every function is documented to return less than the high end
+// -- specifically, because you can pass a negative extent, they're documented
+// never to return a value equal to the extent.
+// So that we don't need two different versions of ensure_in_range(), when
+// testing extent < 0, negate the return value and the extent before passing
+// into ensure_in_range().
+template <typename NUMBER>
+void ensure_in_range(const std::string_view& name,
+                     NUMBER value, NUMBER low, NUMBER high)
+{
+    auto failmsg{ stringize(name, " >= ", low, " (", value, ')') };
+    tut::ensure(failmsg, (value >= low));
+    failmsg = stringize(name, " < ", high, " (", value, ')');
+    tut::ensure(failmsg, (value < high));
+}
 
 namespace tut
 {
@@ -44,84 +60,65 @@ namespace tut
 	template<> template<>
 	void random_object_t::test<1>()
 	{
-		F32 number = 0.0f;
 		for(S32 ii = 0; ii < 100000; ++ii)
 		{
-			number = ll_frand();
-			ensure("frand >= 0", (number >= 0.0f));
-			ensure("frand < 1", (number < 1.0f));
+			ensure_in_range("frand", ll_frand(), 0.0f, 1.0f);
 		}
 	}
 
 	template<> template<>
 	void random_object_t::test<2>()
 	{
-		F64 number = 0.0f;
 		for(S32 ii = 0; ii < 100000; ++ii)
 		{
-			number = ll_drand();
-			ensure("drand >= 0", (number >= 0.0));
-			ensure("drand < 1", (number < 1.0));
+			ensure_in_range("drand", ll_drand(), 0.0, 1.0);
 		}
 	}
 
 	template<> template<>
 	void random_object_t::test<3>()
 	{
-		F32 number = 0.0f;
 		for(S32 ii = 0; ii < 100000; ++ii)
 		{
-			number = ll_frand(2.0f) - 1.0f;
-			ensure("frand >= 0", (number >= -1.0f));
-			ensure("frand < 1", (number <= 1.0f));
+			ensure_in_range("frand(2.0f)", ll_frand(2.0f) - 1.0f, -1.0f, 1.0f);
 		}
 	}
 
 	template<> template<>
 	void random_object_t::test<4>()
 	{
-		F32 number = 0.0f;
 		for(S32 ii = 0; ii < 100000; ++ii)
 		{
-			number = ll_frand(-7.0);
-			ensure("drand <= 0", (number <= 0.0));
-			ensure("drand > -7", (number > -7.0));
+			// Negate the result so we don't have to allow a templated low-end
+			// comparison as well.
+			ensure_in_range("-frand(-7.0)", -ll_frand(-7.0), 0.0f, 7.0f);
 		}
 	}
 
 	template<> template<>
 	void random_object_t::test<5>()
 	{
-		F64 number = 0.0f;
 		for(S32 ii = 0; ii < 100000; ++ii)
 		{
-			number = ll_drand(-2.0);
-			ensure("drand <= 0", (number <= 0.0));
-			ensure("drand > -2", (number > -2.0));
+			ensure_in_range("-drand(-2.0)", -ll_drand(-2.0), 0.0, 2.0);
 		}
 	}
 
 	template<> template<>
 	void random_object_t::test<6>()
 	{
-		S32 number = 0;
 		for(S32 ii = 0; ii < 100000; ++ii)
 		{
-			number = ll_rand(100);
-			ensure("rand >= 0", (number >= 0));
-			ensure("rand < 100", (number < 100));
+			ensure_in_range("rand(100)", ll_rand(100), 0, 100);
 		}
 	}
 
 	template<> template<>
 	void random_object_t::test<7>()
 	{
-		S32 number = 0;
 		for(S32 ii = 0; ii < 100000; ++ii)
 		{
-			number = ll_rand(-127);
-			ensure("rand <= 0", (number <= 0));
-			ensure("rand > -127", (number > -127));
+			ensure_in_range("-rand(-127)", -ll_rand(-127), 0, 127);
 		}
 	}
 }
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index acb2953b5b45fc18aec8a53630b2fb3ba8bba39b..ac40125f752df2a4af8d734b8a5db22cb6f56b42 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -45,11 +45,6 @@ typedef U32 uint32_t;
 #endif
 
 #include "boost/range.hpp"
-#include "boost/foreach.hpp"
-#include "boost/bind.hpp"
-#include "boost/phoenix/bind/bind_function.hpp"
-#include "boost/phoenix/core/argument.hpp"
-using namespace boost::phoenix;
 
 #include "llsd.h"
 #include "llsdserialize.h"
@@ -57,9 +52,11 @@ using namespace boost::phoenix;
 #include "llformat.h"
 #include "llmemorystream.h"
 
+#include "../test/hexdump.h"
 #include "../test/lltut.h"
 #include "../test/namedtempfile.h"
 #include "stringize.h"
+#include "StringVec.h"
 #include <functional>
 
 typedef std::function<void(const LLSD& data, std::ostream& str)> FormatterFunction;
@@ -1796,16 +1793,12 @@ namespace tut
     // helper for TestPythonCompatible
     static std::string import_llsd("import os.path\n"
                                    "import sys\n"
-                                   "try:\n"
-                                   // new freestanding llsd package
-                                   "    import llsd\n"
-                                   "except ImportError:\n"
-                                   // older llbase.llsd module
-                                   "    from llbase import llsd\n");
+                                   "import llsd\n");
 
     // helper for TestPythonCompatible
-    template <typename CONTENT>
-    void python(const std::string& desc, const CONTENT& script, int expect=0)
+    template <typename CONTENT, typename... ARGS>
+    void python_expect(const std::string& desc, const CONTENT& script, int expect=0,
+                       ARGS&&... args)
     {
         auto PYTHON(LLStringUtil::getenv("PYTHON"));
         ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
@@ -1816,7 +1809,8 @@ namespace tut
         std::string q("\"");
         std::string qPYTHON(q + PYTHON + q);
         std::string qscript(q + scriptfile.getName() + q);
-        int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(), NULL);
+        int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(),
+                         std::forward<ARGS>(args)..., NULL);
         if (rc == -1)
         {
             char buffer[256];
@@ -1832,6 +1826,10 @@ namespace tut
         LLProcess::Params params;
         params.executable = PYTHON;
         params.args.add(scriptfile.getName());
+        for (const std::string& arg : StringVec{ std::forward<ARGS>(args)... })
+        {
+            params.args.add(arg);
+        }
         LLProcessPtr py(LLProcess::create(params));
         ensure(STRINGIZE("Couldn't launch " << desc << " script"), bool(py));
         // Implementing timeout would mean messing with alarm() and
@@ -1866,6 +1864,14 @@ namespace tut
 #endif
     }
 
+    // helper for TestPythonCompatible
+    template <typename CONTENT, typename... ARGS>
+    void python(const std::string& desc, const CONTENT& script, ARGS&&... args)
+    {
+        // plain python() expects rc 0
+        python_expect(desc, script, 0, std::forward<ARGS>(args)...);
+    }
+
     struct TestPythonCompatible
     {
         TestPythonCompatible() {}
@@ -1880,10 +1886,10 @@ namespace tut
     void TestPythonCompatibleObject::test<1>()
     {
         set_test_name("verify python()");
-        python("hello",
-               "import sys\n"
-               "sys.exit(17)\n",
-               17);                 // expect nonzero rc
+        python_expect("hello",
+                      "import sys\n"
+                      "sys.exit(17)\n",
+                      17);                 // expect nonzero rc
     }
 
     template<> template<>
@@ -1899,7 +1905,7 @@ namespace tut
     static void writeLLSDArray(const FormatterFunction& serialize,
                                std::ostream& out, const LLSD& array)
     {
-        for (const LLSD& item : llsd::inArray(array))
+        for (const LLSD& item: llsd::inArray(array))
         {
             // It's important to delimit the entries in this file somehow
             // because, although Python's llsd.parse() can accept a file
@@ -1914,7 +1920,14 @@ namespace tut
             auto buffstr{ buffer.str() };
             int bufflen{ static_cast<int>(buffstr.length()) };
             out.write(reinterpret_cast<const char*>(&bufflen), sizeof(bufflen));
+            LL_DEBUGS() << "Wrote length: "
+                        << hexdump(reinterpret_cast<const char*>(&bufflen),
+                                   sizeof(bufflen))
+                        << LL_ENDL;
             out.write(buffstr.c_str(), buffstr.length());
+            LL_DEBUGS() << "Wrote data:   "
+                        << hexmix(buffstr.c_str(), buffstr.length())
+                        << LL_ENDL;
         }
     }
 
@@ -1943,10 +1956,10 @@ namespace tut
             "    else:\n"
             "        raise AssertionError('Too many data items')\n";
 
-        // Create an llsdXXXXXX file containing 'data' serialized to
-        // notation.
+        // Create an llsdXXXXXX file containing 'data' serialized per
+        // FormatterFunction.
         NamedTempFile file("llsd",
-                           // NamedTempFile's boost::function constructor
+                           // NamedTempFile's function constructor
                            // takes a callable. To this callable it passes the
                            // std::ostream with which it's writing the
                            // NamedTempFile.
@@ -1954,34 +1967,50 @@ namespace tut
                            (std::ostream& out)
                            { writeLLSDArray(serialize, out, cdata); });
 
-        python("read C++ " + desc,
-               placeholders::arg1 <<
-               import_llsd <<
-               "from functools import partial\n"
-               "import io\n"
-               "import struct\n"
-               "lenformat = struct.Struct('i')\n"
-               "def parse_each(inf):\n"
-               "    for rawlen in iter(partial(inf.read, lenformat.size), b''):\n"
-               "        len = lenformat.unpack(rawlen)[0]\n"
-               // Since llsd.parse() has no max_bytes argument, instead of
-               // passing the input stream directly to parse(), read the item
-               // into a distinct bytes object and parse that.
-               "        data = inf.read(len)\n"
-               "        try:\n"
-               "            frombytes = llsd.parse(data)\n"
-               "        except llsd.LLSDParseError as err:\n"
-               "            print(f'*** {err}')\n"
-               "            print(f'Bad content:\\n{data!r}')\n"
-               "            raise\n"
-               // Also try parsing from a distinct stream.
-               "        stream = io.BytesIO(data)\n"
-               "        fromstream = llsd.parse(stream)\n"
-               "        assert frombytes == fromstream\n"
-               "        yield frombytes\n"
-               << pydata <<
-               // Don't forget raw-string syntax for Windows pathnames.
-               "verify(parse_each(open(r'" << file.getName() << "', 'rb')))\n");
+        // 'debug' starts empty because it's intended as an output file
+        NamedTempFile debug("debug", "");
+
+        try
+        {
+            python("read C++ " + desc,
+                   [&](std::ostream& out){ out <<
+                   import_llsd <<
+                   "from functools import partial\n"
+                   "import io\n"
+                   "import struct\n"
+                   "lenformat = struct.Struct('i')\n"
+                   "def parse_each(inf):\n"
+                   "    for rawlen in iter(partial(inf.read, lenformat.size), b''):\n"
+                   "        print('Read length:', ''.join(('%02x' % b) for b in rawlen),\n"
+                   "              file=debug)\n"
+                   "        len = lenformat.unpack(rawlen)[0]\n"
+                   // Since llsd.parse() has no max_bytes argument, instead of
+                   // passing the input stream directly to parse(), read the item
+                   // into a distinct bytes object and parse that.
+                   "        data = inf.read(len)\n"
+                   "        print('Read data:  ', repr(data), file=debug)\n"
+                   "        try:\n"
+                   "            frombytes = llsd.parse(data)\n"
+                   "        except llsd.LLSDParseError as err:\n"
+                   "            print(f'*** {err}')\n"
+                   "            print(f'Bad content:\\n{data!r}')\n"
+                   "            raise\n"
+                   // Also try parsing from a distinct stream.
+                   "        stream = io.BytesIO(data)\n"
+                   "        fromstream = llsd.parse(stream)\n"
+                   "        assert frombytes == fromstream\n"
+                   "        yield frombytes\n"
+                   << pydata <<
+                   // Don't forget raw-string syntax for Windows pathnames.
+                   "debug = open(r'" << debug.getName() << "', 'w')\n"
+                   "verify(parse_each(open(r'" << file.getName() << "', 'rb')))\n";});
+        }
+        catch (const failure&)
+        {
+            LL_DEBUGS() << "Script debug output:" << LL_ENDL;
+            debug.peep_log();
+            throw;
+        }
     }
 
     template<> template<>
@@ -2068,7 +2097,7 @@ namespace tut
         NamedTempFile file("llsd", "");
 
         python("Python " + pyformatter,
-               placeholders::arg1 <<
+               [&](std::ostream& out){ out <<
                import_llsd <<
                "import struct\n"
                "lenformat = struct.Struct('i')\n"
@@ -2086,7 +2115,7 @@ namespace tut
                "    for item in DATA:\n"
                "        serialized = llsd." << pyformatter << "(item)\n"
                "        f.write(lenformat.pack(len(serialized)))\n"
-               "        f.write(serialized)\n");
+               "        f.write(serialized)\n";});
 
         std::ifstream inf(file.getName().c_str());
         LLSD item;
diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp
index 41aa858084720cd53735766dbdbd4acb8d25f5fa..df16f4a46eaecefaa63b3a243ec6b1380ad8bfce 100644
--- a/indra/llcommon/tests/workqueue_test.cpp
+++ b/indra/llcommon/tests/workqueue_test.cpp
@@ -83,7 +83,11 @@ namespace tut
         // signal the work item that it can quit; consider LLOneShotCond.
         LLCond<Shared> data;
         auto start = WorkSchedule::TimePoint::clock::now();
-        auto interval = 100ms;
+        // 2s seems like a long time to wait, since it directly impacts the
+        // duration of this test program. Unfortunately GitHub's Mac runners
+        // are pretty wimpy, and we're getting spurious "too late" errors just
+        // because the thread doesn't wake up as soon as we want.
+        auto interval = 2s;
         queue.postEvery(
             interval,
             [&data, count = 0]
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index bcf8bf626415da373bbd50d4a50222d0830d4a35..86340558be996925e5a82c16553a3473000a75e6 100644
--- a/indra/llinventory/llsettingsbase.cpp
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -31,6 +31,7 @@
 #include <algorithm>
 
 #include "llsdserialize.h"
+#include <boost/bind.hpp>
 
 //=========================================================================
 namespace
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index fedbed2990f07c36fba8bf21e0746f4298d04c7f..c3cd7262fb66d81185058a83c00b92dabb14fd43 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -31,6 +31,7 @@
 #include "lltrace.h"
 #include "llfasttimer.h"
 #include "v3colorutil.h"
+#include <boost/bind.hpp>
 
 
 //=========================================================================
diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp
index 348848b29a79fc58ca2cdf10d3b91c89f400eccf..f5d4538c104d31f238ad2851d1dd886659e5df39 100644
--- a/indra/llinventory/llsettingswater.cpp
+++ b/indra/llinventory/llsettingswater.cpp
@@ -32,6 +32,7 @@
 #include "llfasttimer.h"
 #include "v3colorutil.h"
 #include "indra_constants.h"
+#include <boost/bind.hpp>
 
 const std::string LLSettingsWater::SETTING_BLUR_MULTIPLIER("blur_multiplier");
 const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color");
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index 8e9b6c09e730f7e2051409489a860d57e4fc206f..ff8f40a1449d6d7a6a7486dd4768b6853967a9c6 100755
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -33,7 +33,6 @@
 import sys
 from http.server import HTTPServer, BaseHTTPRequestHandler
 
-from llsd.fastest_elementtree import parse as xml_parse
 import llsd
 from testrunner import freeport, run, debug, VERBOSE
 import time
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8eef7cd9d46fbaa8d71a415c71a73123b481bbd8..026bdd5c4c0940ec5122da3217134881be53c6d9 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2166,20 +2166,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
         )
       add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
       add_dependencies(dsym_generate ${VIEWER_BINARY_NAME})
-      add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
-        # See above comments about "tar ...j"
-        COMMAND "tar"
-        ARGS
-          "cjf"
-          "${VIEWER_SYMBOL_FILE}"
-          "-C"
-          "${VIEWER_APP_DSYM}/.."
-          "${product}.dSYM"
-        DEPENDS "${VIEWER_APP_DSYM}"
-        COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
-        )
-      add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}")
-      add_dependencies(dsym_tarball dsym_generate)
       add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
         COMMAND "zip"
         ARGS
@@ -2197,24 +2183,22 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
       add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
         COMMAND rm -rf "${VIEWER_APP_DSYM}"
         COMMAND touch "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
-        DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_APP_XCARCHIVE}"
+        DEPENDS "${VIEWER_APP_XCARCHIVE}"
         COMMENT "Cleaning up dSYM"
         )
       add_custom_target(generate_symbols DEPENDS
         "${VIEWER_APP_DSYM}"
-        "${VIEWER_SYMBOL_FILE}"
         "${VIEWER_APP_XCARCHIVE}"
         "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
         )
-      add_dependencies(generate_symbols dsym_tarball dsym_xcarchive)
+      add_dependencies(generate_symbols dsym_xcarchive)
     endif (DARWIN)
     if (LINUX)
       # TBD
     endif (LINUX)
-  endif (USE_BUGSPLAT)
 
-  # for both Bugsplat and Breakpad
-  add_dependencies(llpackage generate_symbols)
+    add_dependencies(llpackage generate_symbols)
+  endif (USE_BUGSPLAT)
 endif ()
 
 if (LL_TESTS)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 66ce77b7ead5c03f8d614495285190635c0889d9..9fe9ff9d996b339374d1d060c6195ce7dbd53be7 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.0.0
+7.0.1
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 39247b3f4798611930b13b70efa52b543b08da82..63608cdbf8f17816b03770acbace8206a44c5ff0 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -26,7 +26,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Compiler flags
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Unicode true
 SetOverwrite on				# Overwrite files
 SetCompress auto			# Compress if saves space
 SetCompressor /solid lzma	# Compress whole installer as one block
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e20658d32711851c827610c14b047636efc2aea9..1fc4a8532d526597bb01c92959d82d93cd3dd811 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3226,8 +3226,10 @@ LLSD LLAppViewer::getViewerInfo() const
 	// LLFloaterAbout.
 	LLSD info;
 	auto& versionInfo(LLVersionInfo::instance());
+	// With GitHub builds, the build number is too big to fit in a 32-bit int,
+	// and LLSD doesn't deal with integers wider than int. Use string.
 	info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(),
-										 versionInfo.getPatch(), versionInfo.getBuild());
+										 versionInfo.getPatch(), stringize(versionInfo.getBuild()));
 	info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
 	info["CHANNEL"] = versionInfo.getChannel();
 	info["ADDRESS_SIZE"] = ADDRESS_SIZE;
@@ -3574,7 +3576,7 @@ void LLAppViewer::writeSystemInfo()
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
 	gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
-	gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::instance().getBuild();
+	gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild());
 	gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::instance().getAddressSize();
 
 	gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
@@ -5533,7 +5535,7 @@ void LLAppViewer::handleLoginComplete()
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
 	gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
-	gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::instance().getBuild();
+	gDebugInfo["ClientInfo"]["BuildVersion"] = std::to_string(LLVersionInfo::instance().getBuild());
 
 	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
 	if ( parcel && parcel->getMusicURL()[0])
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 232e461fd0fa076dbfea12378248455e842e80d6..4c0a5cf18324124c35855c7f0164456f3d2d832d 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -45,6 +45,7 @@
 #include "llxmlrpctransaction.h"
 #include "llviewernetwork.h"
 #include "llpanel.h"
+#include "stringize.h"
 
 
 const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0;
@@ -158,7 +159,7 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
 		mLocalCurrencyEstimated = true;
 		return;
 	}
-	
+
 	LLXMLRPCValue keywordArgs = LLXMLRPCValue::createStruct();
 	keywordArgs.appendString("agentId", gAgent.getID().asString());
 	keywordArgs.appendString(
@@ -170,8 +171,10 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
 	keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
 	keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
 	keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
-	keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
-	
+	// With GitHub builds, the build number is too big to fit in a 32-bit int,
+	// and XMLRPC_VALUE doesn't deal with integers wider than int. Use string.
+	keywordArgs.appendString("viewerBuildVersion", stringize(LLVersionInfo::instance().getBuild()));
+
 	LLXMLRPCValue params = LLXMLRPCValue::createArray();
 	params.append(keywordArgs);
 
@@ -245,7 +248,9 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
 	keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
 	keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
 	keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
-	keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
+	// With GitHub builds, the build number is too big to fit in a 32-bit int,
+	// and XMLRPC_VALUE doesn't deal with integers wider than int. Use string.
+	keywordArgs.appendString("viewerBuildVersion", stringize(LLVersionInfo::instance().getBuild()));
 
 	LLXMLRPCValue params = LLXMLRPCValue::createArray();
 	params.append(keywordArgs);
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
index 82bfc4ec513f7b6a83f2e44b4ad8d40d582bf380..408952bb5b4d3c8fe2c53a28cd685b1dcee5e495 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -42,6 +42,8 @@
 
 #include <boost/signals2.hpp>
 
+#include <array>
+
 //-------------------------------------------------------------------------
 class LLViewerCamera;
 class LLParcel;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 6880cf217189e663448827cfef7a99394b3909fa..61a01d7418d383b79d0389998d2135e7f414575c 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -72,6 +72,8 @@
 #include "llcorehttputil.h"
 #include "lluiusage.h"
 
+#include <array>
+
 const static std::string ADHOC_NAME_SUFFIX(" Conference");
 
 const static std::string NEARBY_P2P_BY_OTHER("nearby_P2P_by_other");
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index 62180bb066f34eb37259ba181a8e4d8a0199bb15..e44103c5aa0daa03c7de1eabc2a494e11615664a 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -2409,6 +2409,8 @@ void LLInventoryGallery::startDrag()
             ids.push_back(selected_id);
         }
     }
+    // We must have set this for some reason, but it's causing compile errors
+    (void)src;
     LLToolDragAndDrop::getInstance()->beginMultiDrag(types, ids, LLToolDragAndDrop::SOURCE_AGENT);
 }
 
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 07825c1b0c076553869eaa8c2b98ce5f4788c995..052ac50185369096d2b211a224054368bef210ef 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -41,7 +41,7 @@
 
 #include <boost/algorithm/string/trim.hpp>
 #include <boost/algorithm/string/replace.hpp>
-#include <boost/regex/v4/match_results.hpp>
+#include <boost/regex.hpp>
 #include <boost/foreach.hpp>
 
 #if LL_MSVC
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 49756a4e09c4b70c4b06a30b95094c3e151b64b4..025a653c47b7fce010b3020503f1340255053736 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -65,6 +65,7 @@
 #include "lltrans.h"
 #include "llglheaders.h"
 #include "llpanelloginlistener.h"
+#include "stringize.h"
 
 #if LL_WINDOWS
 #pragma warning(disable: 4355)      // 'this' used in initializer list
@@ -300,10 +301,9 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	setDefaultBtn(def_btn);
 
 	std::string channel = LLVersionInfo::instance().getChannel();
-	std::string version = llformat("%s (%d)",
-								   LLVersionInfo::instance().getShortVersion().c_str(),
-								   LLVersionInfo::instance().getBuild());
-	
+	std::string version = stringize(LLVersionInfo::instance().getShortVersion(), " (",
+									LLVersionInfo::instance().getBuild(), ')');
+
 	LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
 	forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
 
@@ -894,9 +894,8 @@ void LLPanelLogin::loadLoginPage()
 	}
 
 	// Channel and Version
-	params["version"] = llformat("%s (%d)",
-								 LLVersionInfo::instance().getShortVersion().c_str(),
-								 LLVersionInfo::instance().getBuild());
+	params["version"] = stringize(LLVersionInfo::instance().getShortVersion(), " (",
+								  LLVersionInfo::instance().getBuild(), ')');
 	params["channel"] = LLVersionInfo::instance().getChannel();
 
 	// Grid
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index c37c955e8def57dc2803c9273a010774df7b4974..6526e1df927a4c5b9d189f99959034a1f58f177a 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -39,6 +39,7 @@
 #include "json/reader.h"
 #include "llcorehttputil.h"
 #include "llurlregistry.h"
+#include "stringize.h"
 
 
 static const std::string AZURE_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">");
@@ -160,12 +161,12 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD
     LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
 
 
-    std::string user_agent = llformat("%s %d.%d.%d (%d)",
-        LLVersionInfo::instance().getChannel().c_str(),
-        LLVersionInfo::instance().getMajor(),
-        LLVersionInfo::instance().getMinor(),
-        LLVersionInfo::instance().getPatch(),
-        LLVersionInfo::instance().getBuild());
+    std::string user_agent = stringize(
+        LLVersionInfo::instance().getChannel(), ' ',
+        LLVersionInfo::instance().getMajor(), '.',
+        LLVersionInfo::instance().getMinor(), '.',
+        LLVersionInfo::instance().getPatch(), " (",
+        LLVersionInfo::instance().getBuild(), ')');
 
     initHttpHeader(httpHeaders, user_agent, key);
 
@@ -215,12 +216,12 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
     LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
 
 
-    std::string user_agent = llformat("%s %d.%d.%d (%d)",
-        LLVersionInfo::instance().getChannel().c_str(),
-        LLVersionInfo::instance().getMajor(),
-        LLVersionInfo::instance().getMinor(),
-        LLVersionInfo::instance().getPatch(),
-        LLVersionInfo::instance().getBuild());
+    std::string user_agent = stringize(
+        LLVersionInfo::instance().getChannel(), ' ',
+        LLVersionInfo::instance().getMajor(), '.',
+        LLVersionInfo::instance().getMinor(), '.',
+        LLVersionInfo::instance().getPatch(), " (",
+        LLVersionInfo::instance().getBuild(), ')');
 
     initHttpHeader(httpHeaders, user_agent);
     httpOpts->setSSLVerifyPeer(false);
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 376a7fce7619374663dfc4e981816740a914eb32..9551df7bee30417fa347140b5aa39c78db0f9a5b 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -69,7 +69,7 @@ void LLVersionInfo::initSingleton()
 	// fully constructed; such calls don't really belong in the constructor.
 
 	// cache the version string
-	version = STRINGIZE(getShortVersion() << "." << getBuild());
+	version = stringize(getShortVersion(), ".", getBuild());
 }
 
 LLVersionInfo::~LLVersionInfo()
@@ -91,7 +91,7 @@ S32 LLVersionInfo::getPatch()
 	return LL_VIEWER_VERSION_PATCH;
 }
 
-S32 LLVersionInfo::getBuild()
+U64 LLVersionInfo::getBuild()
 {
 	return LL_VIEWER_VERSION_BUILD;
 }
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index 02ff0c094aaa96fab6d5d5e5aeeebb52ed9ec46d..a40042380a0766bb1ead56105f609121dd2cadf5 100644
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -61,7 +61,7 @@ class LLVersionInfo: public LLSingleton<LLVersionInfo>
 	S32 getPatch();
 
 	/// return the build number as an integer
-	S32 getBuild();
+	U64 getBuild();
 
 	/// return the full viewer version as a string like "2.0.0.200030"
 	std::string getVersion();
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index c4d873dd22bc42c2ec140567f070ae9c5cdc3a65..9afe332025ce19ba5f512df59f2fbefdd02bc48d 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -160,7 +160,7 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
 	substitution["VERSION_MAJOR"] = LLVersionInfo::instance().getMajor();
 	substitution["VERSION_MINOR"] = LLVersionInfo::instance().getMinor();
 	substitution["VERSION_PATCH"] = LLVersionInfo::instance().getPatch();
-	substitution["VERSION_BUILD"] = LLVersionInfo::instance().getBuild();
+	substitution["VERSION_BUILD"] = std::to_string(LLVersionInfo::instance().getBuild());
 	substitution["CHANNEL"] = LLVersionInfo::instance().getChannel();
 	substitution["GRID"] = LLGridManager::getInstance()->getGridId();
 	substitution["GRID_LOWERCASE"] = utf8str_tolower(LLGridManager::getInstance()->getGridId());
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 1760ccde1f8405c5afd55a3f56503302671b8dac..ba7e8d7298cb0d6c00722bc43ec32f44ee2bac63 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -42,6 +42,7 @@
 #include "bufferarray.h"
 #include "llversioninfo.h"
 #include "llviewercontrol.h"
+#include "stringize.h"
 
 // Have to include these last to avoid queue redefinition!
 
@@ -390,14 +391,14 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
 
 	httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
 
-    std::string user_agent = llformat("%s %d.%d.%d (%d)",
-        LLVersionInfo::instance().getChannel().c_str(),
-        LLVersionInfo::instance().getMajor(),
-        LLVersionInfo::instance().getMinor(),
-        LLVersionInfo::instance().getPatch(),
-        LLVersionInfo::instance().getBuild());
+	std::string user_agent = stringize(
+		LLVersionInfo::instance().getChannel(), ' ',
+		LLVersionInfo::instance().getMajor(), '.',
+		LLVersionInfo::instance().getMinor(), '.',
+		LLVersionInfo::instance().getPatch(), " (",
+		LLVersionInfo::instance().getBuild(), ')');
 
-    httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+	httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
 
 	///* Setting the DNS cache timeout to -1 disables it completely.
 	//This might help with bug #503 */
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 3a7c7d7f46ac96ba93a77401d047cde6d7ea20ea..1fa4df16824551c2a6dfdd66469ae810e3b886a8 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -35,13 +35,13 @@
 import plistlib
 import random
 import re
+import secrets
 import shutil
-import stat
 import subprocess
 import sys
 import tarfile
+import tempfile
 import time
-import zipfile
 
 viewer_dir = os.path.dirname(__file__)
 # Add indra/lib/python to our path so we don't have to muck with PYTHONPATH.
@@ -410,11 +410,29 @@ def relpath(self, path, base=None, symlink=False):
 
         return os.path.relpath(abspath(path), abspath(base))
 
+    def set_github_output_path(self, variable, path):
+        self.set_github_output(variable,
+                               os.path.normpath(os.path.join(self.get_dst_prefix(), path)))
 
-class WindowsManifest(ViewerManifest):
+    def set_github_output(self, variable, *values):
+        GITHUB_OUTPUT = os.getenv('GITHUB_OUTPUT')
+        if GITHUB_OUTPUT and values:
+            with open(GITHUB_OUTPUT, 'a') as outf:
+                if len(values) == 1:
+                    print('='.join((variable, values[0])), file=outf)
+                else:
+                    delim = secrets.token_hex(8)
+                    print('<<'.join((variable, delim)), file=outf)
+                    for value in values:
+                        print(value, file=outf)
+                    print(delim, file=outf)
+
+
+class Windows_x86_64_Manifest(ViewerManifest):
     # We want the platform, per se, for every Windows build to be 'win'. The
     # VMP will concatenate that with the address_size.
     build_data_json_platform = 'win'
+    address_size = 64
 
     def final_exe(self):
         return self.exec_name()+".exe"
@@ -475,7 +493,7 @@ def test_for_no_msvcrt_manifest_and_copy_action(self, src, dst):
             print("Doesn't exist:", src)
         
     def construct(self):
-        super(WindowsManifest, self).construct()
+        super().construct()
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
@@ -484,6 +502,30 @@ def construct(self):
         if self.is_packaging_viewer():
             # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.
             self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
+            # Emit the whole app image as one of the GitHub step outputs. We
+            # want the whole app -- but NOT the extraneous build products that
+            # get tossed into the same directory, such as the installer and
+            # the symbols tarball, so add exclusions. When we feed
+            # upload-artifact multiple absolute pathnames, even just for
+            # exclusion, it ends up creating several extraneous directory
+            # levels within the artifact -- so try using only relative paths.
+            # One problem: as of right now, our current directory os.getcwd()
+            # is not the same as the initial working directory for this job
+            # step, meaning paths relative to our os.getcwd() won't work for
+            # the subsequent upload-artifact step. We're a couple directory
+            # levels down. Try adjusting for those when specifying the base
+            # for self.relpath().
+            appbase = self.relpath(
+                self.get_dst_prefix(),
+                base=os.path.join(os.getcwd(), os.pardir, os.pardir))
+            self.set_github_output('viewer_app', appbase,
+                                   # except for this stuff
+                                   *(('!' + os.path.join(appbase, pattern))
+                                     for pattern in (
+                                             'secondlife-bin.*',
+                                             '*_Setup.exe',
+                                             '*.bat',
+                                             '*.tar.bz2')))
 
             with self.prefix(src=os.path.join(pkgdir, "VMP")):
                 # include the compiled launcher scripts so that it gets included in the file_list
@@ -534,20 +576,12 @@ def construct(self):
                 self.path("SLVoice.exe")
 
             # Vivox libraries
-            if (self.address_size == 64):
-                self.path("vivoxsdk_x64.dll")
-                self.path("ortp_x64.dll")
-            else:
-                self.path("vivoxsdk.dll")
-                self.path("ortp.dll")
+            self.path("vivoxsdk_x64.dll")
+            self.path("ortp_x64.dll")
             
             # OpenSSL
-            if (self.address_size == 64):
-                self.path("libcrypto-1_1-x64.dll")
-                self.path("libssl-1_1-x64.dll")
-            else:
-                self.path("libcrypto-1_1.dll")
-                self.path("libssl-1_1.dll")
+            self.path("libcrypto-1_1-x64.dll")
+            self.path("libssl-1_1-x64.dll")
 
             # HTTP/2
             self.path("nghttp2.dll")
@@ -557,14 +591,9 @@ def construct(self):
 
             # BugSplat
             if self.args.get('bugsplat'):
-                if(self.address_size == 64):
-                    self.path("BsSndRpt64.exe")
-                    self.path("BugSplat64.dll")
-                    self.path("BugSplatRc64.dll")
-                else:
-                    self.path("BsSndRpt.exe")
-                    self.path("BugSplat.dll")
-                    self.path("BugSplatRc.dll")
+                self.path("BsSndRpt64.exe")
+                self.path("BugSplat64.dll")
+                self.path("BugSplatRc64.dll")
 
         self.path(src="licenses-win32.txt", dst="licenses.txt")
         self.path("featuretable.txt")
@@ -679,46 +708,46 @@ def construct(self):
             self.package_file = "copied_deps"    
 
     def nsi_file_commands(self, install=True):
-        def wpath(path):
-            if path.endswith('/') or path.endswith(os.path.sep):
-                path = path[:-1]
-            path = path.replace('/', '\\')
-            return path
-
-        result = ""
+        def INSTDIR(path):
+            # Note that '$INSTDIR' is purely textual here: we write
+            # exactly that into the .nsi file for NSIS to interpret.
+            # Pass the result through normpath() to handle the case in which
+            # path is the empty string. On Windows, that produces "$INSTDIR\".
+            # Unfortunately, if that's the last item on a line, NSIS takes
+            # that as line continuation and misinterprets the following line.
+            # Ensure we don't emit a trailing backslash.
+            return os.path.normpath(os.path.join('$INSTDIR', path))
+
+        result = []
         dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])]
         # sort deepest hierarchy first
         dest_files.sort(key=lambda f: (f.count(os.path.sep), f), reverse=True)
         out_path = None
         for pkg_file in dest_files:
-            rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,''))
-            installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file)))
-            pkg_file = wpath(os.path.normpath(pkg_file))
-            if installed_dir != out_path:
-                if install:
-                    out_path = installed_dir
-                    result += 'SetOutPath ' + out_path + '\n'
+            pkg_file = os.path.normpath(pkg_file)
+            rel_file = self.relpath(pkg_file)
+            installed_dir = INSTDIR(os.path.dirname(rel_file))
+            if install and installed_dir != out_path:
+                out_path = installed_dir
+                # emit SetOutPath every time it changes
+                result.append('SetOutPath ' + out_path)
             if install:
-                result += 'File ' + pkg_file + '\n'
+                result.append('File ' + rel_file)
             else:
-                result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n'
+                result.append('Delete ' + INSTDIR(rel_file))
 
         # at the end of a delete, just rmdir all the directories
         if not install:
-            deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list]
-            # find all ancestors so that we don't skip any dirs that happened to have no non-dir children
-            deleted_dirs = []
-            for d in deleted_file_dirs:
-                deleted_dirs.extend(path_ancestors(d))
+            deleted_file_dirs = [os.path.dirname(self.relpath(f)) for f in dest_files]
+            # find all ancestors so that we don't skip any dirs that happened
+            # to have no non-dir children
+            deleted_dirs = set(itertools.chain.from_iterable(path_ancestors(d)
+                                                             for d in deleted_file_dirs))
             # sort deepest hierarchy first
-            deleted_dirs.sort(key=lambda f: (f.count(os.path.sep), f), reverse=True)
-            prev = None
-            for d in deleted_dirs:
-                if d != prev:   # skip duplicates
-                    result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n'
-                prev = d
+            for d in sorted(deleted_dirs, key=lambda f: (f.count(os.path.sep), f), reverse=True):
+                result.append('RMDir ' + INSTDIR(d))
 
-        return result
+        return '\n'.join(result)
 
     def package_finish(self):
         # a standard map of strings for replacing in the templates
@@ -726,8 +755,7 @@ def package_finish(self):
             'version' : '.'.join(self.args['version']),
             'version_short' : '.'.join(self.args['version'][:-1]),
             'version_dashes' : '-'.join(self.args['version']),
-            'version_registry' : '%s(%s)' %
-            ('.'.join(self.args['version']), self.address_size),
+            'version_registry' : '%s(64)' % '.'.join(self.args['version']),
             'final_exe' : self.final_exe(),
             'flags':'',
             'app_name':self.app_name(),
@@ -759,75 +787,38 @@ def package_finish(self):
             Caption "%(caption)s"
             """
 
-        if(self.address_size == 64):
-            engage_registry="SetRegView 64"
-            program_files="!define MULTIUSER_USE_PROGRAMFILES64"
-        else:
-            engage_registry="SetRegView 32"
-            program_files=""
+        engage_registry="SetRegView 64"
+        program_files="!define MULTIUSER_USE_PROGRAMFILES64"
+
+        # Dump the installers/windows directory into the raw app image tree
+        # because NSIS needs those files. But don't use path() because we
+        # don't want them installed with the viewer - they're only for use by
+        # the installer itself.
+        shutil.copytree(os.path.join(self.get_src_prefix(), 'installers', 'windows'),
+                        os.path.join(self.get_dst_prefix(), 'installers', 'windows'),
+                        dirs_exist_ok=True)
 
         tempfile = "secondlife_setup_tmp.nsi"
         # the following replaces strings in the nsi template
         # it also does python-style % substitution
         self.replace_in("installers/windows/installer_template.nsi", tempfile, {
                 "%%VERSION%%":version_vars,
-                "%%SOURCE%%":self.get_src_prefix(),
+                # The template references "%%SOURCE%%\installers\windows\...".
+                # Now that we've copied that directory into the app image
+                # tree, we can just replace %%SOURCE%% with '.'.
+                "%%SOURCE%%":'.',
                 "%%INST_VARS%%":inst_vars_template % substitution_strings,
                 "%%INSTALL_FILES%%":self.nsi_file_commands(True),
                 "%%PROGRAMFILES%%":program_files,
                 "%%ENGAGEREGISTRY%%":engage_registry,
                 "%%DELETE_FILES%%":self.nsi_file_commands(False)})
 
-        # If we're on a build machine, sign the code using our Authenticode certificate. JC
-        # note that the enclosing setup exe is signed later, after the makensis makes it.
-        # Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc.
-        for exe in (
-            self.final_exe(),
-            "SLVersionChecker.exe",
-            "llplugin/dullahan_host.exe",
-            ):
-            self.sign(exe)
-            
-        # Check two paths, one for Program Files, and one for Program Files (x86).
-        # Yay 64bit windows.
-        nsis_path = "makensis.exe"
-        for program_files in '${programfiles}', '${programfiles(x86)}':
-            for nesis_path in 'NSIS', 'NSIS\\Unicode':
-                possible_path = os.path.expandvars(f"{program_files}\\{nesis_path}\\makensis.exe")
-                if os.path.exists(possible_path):
-                    nsis_path = possible_path
-                    break
-
-        self.run_command([possible_path, '/V2', self.dst_path_of(tempfile)])
-
-        self.sign(installer_file)
-        self.created_path(self.dst_path_of(installer_file))
         self.package_file = installer_file
 
-    def sign(self, exe):
-        sign_py = os.environ.get('SIGN', r'C:\buildscripts\code-signing\sign.py')
-        python  = os.environ.get('PYTHON', sys.executable)
-        if os.path.exists(sign_py):
-            dst_path = self.dst_path_of(exe)
-            print("about to run signing of: ", dst_path)
-            self.run_command([python, sign_py, dst_path])
-        else:
-            print("Skipping code signing of %s %s: %s not found" % (self.dst_path_of(exe), exe, sign_py))
-
-    def escape_slashes(self, path):
-        return path.replace('\\', '\\\\\\\\')
-
-class Windows_i686_Manifest(WindowsManifest):
-    # Although we aren't literally passed ADDRESS_SIZE, we can infer it from
-    # the passed 'arch', which is used to select the specific subclass.
-    address_size = 32
-
-class Windows_x86_64_Manifest(WindowsManifest):
-    address_size = 64
 
-
-class DarwinManifest(ViewerManifest):
+class Darwin_x86_64_Manifest(ViewerManifest):
     build_data_json_platform = 'mac'
+    address_size = 64
 
     def finish_build_data_dict(self, build_data_dict):
         build_data_dict.update({'Bundle Id':self.args['bundleid']})
@@ -844,8 +835,9 @@ def is_rearranging(self):
         return bool(set(["package", "unpacked"]).intersection(self.args['actions']))
 
     def construct(self):
-        # copy over the build result (this is a no-op if run within the xcode script)
-        self.path(os.path.join(self.args['configuration'], self.channel()+".app"), dst="")
+        # copy over the build result (this is a no-op if run within the xcode
+        # script)
+        self.path(os.path.join(self.args['configuration'], self.channel() + ".app"), dst="")
 
         pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
         relpkgdir = os.path.join(pkgdir, "lib", "release")
@@ -898,7 +890,8 @@ def construct(self):
                     # work, we need the build to noisily fail!
                     oldpath = subprocess.check_output(
                         ['objdump', '--macho', '--dylib-id', '--non-verbose',
-                         os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")]
+                         os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")],
+                        text=True
                         ).splitlines()[-1]  # take the last line of output
                     self.run_command(
                         ['install_name_tool', '-change', oldpath,
@@ -919,7 +912,7 @@ def construct(self):
             with self.prefix(dst="Resources"):
                 # defer cross-platform file copies until we're in the
                 # nested Resources directory
-                super(DarwinManifest, self).construct()
+                super().construct()
 
                 # need .icns file referenced by Info.plist
                 with self.prefix(src=self.icon_path(), dst="") :
@@ -1167,194 +1160,35 @@ def path_optional(src, dst):
                             self.path( "plugins.dat" )
 
     def package_finish(self):
-        global CHANNEL_VENDOR_BASE
-        # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning.
-        #  If we really need differently named volumes, we'll need to create multiple DS_Store file images, or use some other trick.
-
-        volname=CHANNEL_VENDOR_BASE+" Installer"  # DO NOT CHANGE without understanding comment above
-
         imagename = self.installer_base_name()
-
-        sparsename = imagename + ".sparseimage"
+        self.set_github_output('imagename', imagename)
         finalname = imagename + ".dmg"
-        # make sure we don't have stale files laying about
-        self.remove(sparsename, finalname)
-
-        self.run_command(['hdiutil', 'create', sparsename,
-                          '-volname', volname, '-fs', 'HFS+',
-                          '-type', 'SPARSE', '-megabytes', '1300',
-                          '-layout', 'SPUD'])
-
-        # mount the image and get the name of the mount point and device node
-        try:
-            hdi_output = subprocess.check_output(['hdiutil', 'attach', '-private', sparsename], text=True)
-        except subprocess.CalledProcessError as err:
-            sys.exit("failed to mount image at '%s'" % sparsename)
-            
-        try:
-            devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
-            volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
-
-            # Copy everything in to the mounted .dmg
-
-            app_name = self.app_name()
-
-            # Hack:
-            # Because there is no easy way to coerce the Finder into positioning
-            # the app bundle in the same place with different app names, we are
-            # adding multiple .DS_Store files to svn. There is one for release,
-            # one for release candidate and one for first look. Any other channels
-            # will use the release .DS_Store, and will look broken.
-            # - Ambroff 2008-08-20
-            dmg_template = os.path.join(
-                'installers', 'darwin', '%s-dmg' % self.channel_type())
-
-            if not os.path.exists (self.src_path_of(dmg_template)):
-                dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
-
-            for s,d in list({self.get_dst_prefix():app_name + ".app",
-                        os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
-                        os.path.join(dmg_template, "background.jpg"): "background.jpg",
-                        os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items()):
-                print("Copying to dmg", s, d)
-                self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
-
-            # Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
-            for f in ".VolumeIcon.icns", "background.jpg", ".DS_Store":
-                pathname = os.path.join(volpath, f)
-                self.run_command(['SetFile', '-a', 'V', pathname])
-
-            # Create the alias file (which is a resource file) from the .r
-            self.run_command(
-                ['Rez', self.src_path_of("installers/darwin/release-dmg/Applications-alias.r"),
-                 '-o', os.path.join(volpath, "Applications")])
-
-            # Set the alias file's alias and custom icon bits
-            self.run_command(['SetFile', '-a', 'AC', os.path.join(volpath, "Applications")])
-
-            # Set the disk image root's custom icon bit
-            self.run_command(['SetFile', '-a', 'C', volpath])
-
-            # Sign the app if requested; 
-            # do this in the copy that's in the .dmg so that the extended attributes used by 
-            # the signature are preserved; moving the files using python will leave them behind
-            # and invalidate the signatures.
-            if 'signature' in self.args:
-                app_in_dmg=os.path.join(volpath,self.app_name()+".app")
-                print("Attempting to sign '%s'" % app_in_dmg)
-                identity = self.args['signature']
-                if identity == '':
-                    identity = 'Developer ID Application'
-
-                # Look for an environment variable set via build.sh when running in Team City.
-                try:
-                    build_secrets_checkout = os.environ['build_secrets_checkout']
-                except KeyError:
-                    pass
-                else:
-                    # variable found so use it to unlock keychain followed by codesign
-                    home_path = os.environ['HOME']
-                    keychain_pwd_path = os.path.join(build_secrets_checkout,'code-signing-osx','password.txt')
-                    keychain_pwd = open(keychain_pwd_path).read().rstrip()
-
-                    # Note: As of macOS Sierra, keychains are created with
-                    #       names postfixed with '-db' so for example, the SL
-                    #       Viewer keychain would by default be found in
-                    #       ~/Library/Keychains/viewer.keychain-db instead of
-                    #       just ~/Library/Keychains/viewer.keychain in
-                    #       earlier versions.
-                    #
-                    #       Because we have old OS files from previous
-                    #       versions of macOS on the build hosts, the
-                    #       configurations are different on each host. Some
-                    #       have viewer.keychain, some have viewer.keychain-db
-                    #       and some have both. As you can see in the line
-                    #       below, this script expects the Linden Developer
-                    #       cert/keys to be in viewer.keychain.
-                    #
-                    #       To correctly sign builds you need to make sure
-                    #       ~/Library/Keychains/viewer.keychain exists on the
-                    #       host and that it contains the correct cert/key. If
-                    #       a build host is set up with a clean version of
-                    #       macOS Sierra (or later) then you will need to
-                    #       change this line (and the one for 'codesign'
-                    #       command below) to point to right place or else
-                    #       pull in the cert/key into the default viewer
-                    #       keychain 'viewer.keychain-db' and export it to
-                    #       'viewer.keychain'
-                    viewer_keychain = os.path.join(home_path, 'Library',
-                                                   'Keychains', 'viewer.keychain')
-                    self.run_command(['security', 'unlock-keychain',
-                                      '-p', keychain_pwd, viewer_keychain])
-                    sign_retry_wait=15
-                    resources = app_in_dmg + "/Contents/Resources/"
-                    plain_sign = glob.glob(resources + "llplugin/*.dylib")
-                    deep_sign = [
-                        resources + "updater/SLVersionChecker",
-                        resources + "SLPlugin.app/Contents/MacOS/SLPlugin",
-                        app_in_dmg,
-                        ]
-                    for attempt in range(3):
-                        if attempt: # second or subsequent iteration
-                            print("codesign failed, waiting {:d} seconds before retrying".format(sign_retry_wait),
-                                  file=sys.stderr)
-                            time.sleep(sign_retry_wait)
-                            sign_retry_wait*=2
-
-                        try:
-                            # Note: See blurb above about names of keychains
-                            for signee in plain_sign:
-                                self.run_command(
-                                    ['codesign',
-                                     '--force',
-                                     '--timestamp',
-                                     '--keychain', viewer_keychain,
-                                     '--sign', identity,
-                                     signee])
-                            for signee in deep_sign:
-                                self.run_command(
-                                    ['codesign',
-                                     '--verbose',
-                                     '--deep',
-                                     '--force',
-                                     '--entitlements', self.src_path_of("slplugin.entitlements"),
-                                     '--options', 'runtime',
-                                     '--keychain', viewer_keychain,
-                                     '--sign', identity,
-                                     signee])
-                            break # if no exception was raised, the codesign worked
-                        except ManifestError as err:
-                            # 'err' goes out of scope
-                            sign_failed = err
-                    else:
-                        print("Maximum codesign attempts exceeded; giving up", file=sys.stderr)
-                        raise sign_failed
-                    self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
-                    self.run_command([self.src_path_of("installers/darwin/apple-notarize.sh"), app_in_dmg])
-
-        finally:
-            # Unmount the image even if exceptions from any of the above 
-            self.run_command(['hdiutil', 'detach', '-force', devfile])
-
-        print("Converting temp disk image to final disk image")
-        self.run_command(['hdiutil', 'convert', sparsename, '-format', 'UDZO',
-                          '-imagekey', 'zlib-level=9', '-o', finalname])
-        # get rid of the temp file
         self.package_file = finalname
-        self.remove(sparsename)
-
-
-class Darwin_i386_Manifest(DarwinManifest):
-    address_size = 32
-
-
-class Darwin_i686_Manifest(DarwinManifest):
-    """alias in case arch is passed as i686 instead of i386"""
-    pass
 
-
-class Darwin_x86_64_Manifest(DarwinManifest):
-    address_size = 64
+        RUNNER_TEMP = os.getenv('RUNNER_TEMP')
+        # When running as a GitHub Action job, RUNNER_TEMP is the recommended
+        # temp directory. If we're not running on GitHub, don't create this
+        # temp directory or this tarball: we don't clean them up, trusting
+        # that the runner is itself transient. On a dev machine, that would
+        # result in temp-directory clutter.
+        if RUNNER_TEMP:
+            # Per GitHub's actions/upload-artifact documentation
+            # https://github.com/actions/upload-artifact#maintaining-file-permissions-and-case-sensitive-files
+            # we must package the app bundle with tar before posting as an
+            # artifact. Posting individual files follows symlinks, which
+            # causes problems, especially with frameworks: a framework's top
+            # level must contain symlinks into its Versions/Current, which
+            # must itself be a symlink to some specific Versions subdir.
+            tarpath = os.path.join(RUNNER_TEMP, "viewer.tar.bz2")
+            print(f'Creating {tarpath} from {self.get_dst_prefix()}')
+            with tarfile.open(tarpath, mode="w:bz2") as tarball:
+                # Store in the tarball as just 'Second Life Mumble.app'
+                # instead of 'Users/someone/.../newview/Release/Second...'
+                # It's at this point that we rename 'Second Life Release.app'
+                # to 'Second Life Viewer.app'.
+                tarball.add(self.get_dst_prefix(),
+                            arcname=self.app_name() + ".app")
+            self.set_github_output_path('viewer_app', tarpath)
 
 
 class LinuxManifest(ViewerManifest):
diff --git a/indra/test/hexdump.h b/indra/test/hexdump.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd7cbaaa3c56eecd1f05612be20137d8de678a5d
--- /dev/null
+++ b/indra/test/hexdump.h
@@ -0,0 +1,97 @@
+/**
+ * @file   hexdump.h
+ * @author Nat Goodspeed
+ * @date   2023-09-08
+ * @brief  Provide hexdump() and hexmix() ostream formatters
+ * 
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Copyright (c) 2023, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_HEXDUMP_H)
+#define LL_HEXDUMP_H
+
+#include <cctype>
+#include <iomanip>
+#include <iostream>
+#include <string_view>
+
+// Format a given byte string as 2-digit hex values, no separators
+// Usage: std::cout << hexdump(somestring) << ...
+class hexdump
+{
+public:
+    hexdump(const std::string_view& data):
+        hexdump(data.data(), data.length())
+    {}
+
+    hexdump(const char* data, size_t len):
+        hexdump(reinterpret_cast<const unsigned char*>(data), len)
+    {}
+
+    hexdump(const unsigned char* data, size_t len):
+        mData(data, data + len)
+    {}
+
+    friend std::ostream& operator<<(std::ostream& out, const hexdump& self)
+    {
+        auto oldfmt{ out.flags() };
+        auto oldfill{ out.fill() };
+        out.setf(std::ios_base::hex, std::ios_base::basefield);
+        out.fill('0');
+        for (auto c : self.mData)
+        {
+            out << std::setw(2) << unsigned(c);
+        }
+        out.setf(oldfmt, std::ios_base::basefield);
+        out.fill(oldfill);
+        return out;
+    }
+
+private:
+    std::vector<unsigned char> mData;
+};
+
+// Format a given byte string as a mix of printable characters and, for each
+// non-printable character, "\xnn"
+// Usage: std::cout << hexmix(somestring) << ...
+class hexmix
+{
+public:
+    hexmix(const std::string_view& data):
+        mData(data)
+    {}
+
+    hexmix(const char* data, size_t len):
+        mData(data, len)
+    {}
+
+    friend std::ostream& operator<<(std::ostream& out, const hexmix& self)
+    {
+        auto oldfmt{ out.flags() };
+        auto oldfill{ out.fill() };
+        out.setf(std::ios_base::hex, std::ios_base::basefield);
+        out.fill('0');
+        for (auto c : self.mData)
+        {
+            // std::isprint() must be passed an unsigned char!
+            if (std::isprint(static_cast<unsigned char>(c)))
+            {
+                out << c;
+            }
+            else
+            {
+                out << "\\x" << std::setw(2) << unsigned(c);
+            }
+        }
+        out.setf(oldfmt, std::ios_base::basefield);
+        out.fill(oldfill);
+        return out;
+    }
+
+private:
+    std::string mData;
+};
+
+#endif /* ! defined(LL_HEXDUMP_H) */
diff --git a/indra/test/namedtempfile.h b/indra/test/namedtempfile.h
index 7d59cad32c25618934b9f32b392d7c162170e3c3..ad14cebbd1e916369811b5f6b77d2c57d214d82b 100644
--- a/indra/test/namedtempfile.h
+++ b/indra/test/namedtempfile.h
@@ -13,15 +13,16 @@
 #define LL_NAMEDTEMPFILE_H
 
 #include "llerror.h"
-#include "llapr.h"
-#include "apr_file_io.h"
+#include "llstring.h"
+#include "stringize.h"
 #include <string>
-#include <boost/function.hpp>
-#include <boost/phoenix/core/argument.hpp>
-#include <boost/phoenix/operator/bitwise.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
 #include <boost/noncopyable.hpp>
+#include <functional>
 #include <iostream>
 #include <sstream>
+#include <string_view>
 
 /**
  * Create a text file with specified content "somewhere in the
@@ -31,134 +32,123 @@ class NamedTempFile: public boost::noncopyable
 {
     LOG_CLASS(NamedTempFile);
 public:
-    NamedTempFile(const std::string& pfx, const std::string& content, apr_pool_t* pool=gAPRPoolp):
-        mPool(pool)
+    NamedTempFile(const std::string_view& pfx,
+                  const std::string_view& content,
+                  const std::string_view& sfx=std::string_view(""))
     {
-        createFile(pfx, boost::phoenix::placeholders::arg1 << content);
+        createFile(pfx, [&content](std::ostream& out){ out << content; }, sfx);
     }
 
-    // Disambiguate when passing string literal
-    NamedTempFile(const std::string& pfx, const char* content, apr_pool_t* pool=gAPRPoolp):
-        mPool(pool)
+    // Disambiguate when passing string literal -- unclear why a string
+    // literal should be ambiguous wrt std::string_view and Streamer
+    NamedTempFile(const std::string_view& pfx,
+                  const char* content,
+                  const std::string_view& sfx=std::string_view(""))
     {
-        createFile(pfx, boost::phoenix::placeholders::arg1 << content);
+        createFile(pfx, [&content](std::ostream& out){ out << content; }, sfx);
     }
 
     // Function that accepts an ostream ref and (presumably) writes stuff to
     // it, e.g.:
     // (boost::phoenix::placeholders::arg1 << "the value is " << 17 << '\n')
-    typedef boost::function<void(std::ostream&)> Streamer;
+    typedef std::function<void(std::ostream&)> Streamer;
 
-    NamedTempFile(const std::string& pfx, const Streamer& func, apr_pool_t* pool=gAPRPoolp):
-        mPool(pool)
+    NamedTempFile(const std::string_view& pfx,
+                  const Streamer& func,
+                  const std::string_view& sfx=std::string_view(""))
     {
-        createFile(pfx, func);
+        createFile(pfx, func, sfx);
     }
 
     virtual ~NamedTempFile()
     {
-        ll_apr_assert_status(apr_file_remove(mPath.c_str(), mPool));
+        boost::filesystem::remove(mPath);
     }
 
-    virtual std::string getName() const { return mPath; }
+    std::string getName() const { return mPath.string(); }
 
-    void peep()
+    template <typename CALLABLE>
+    void peep_via(CALLABLE&& callable) const
     {
-        std::cout << "File '" << mPath << "' contains:\n";
-        std::ifstream reader(mPath.c_str());
+        std::forward<CALLABLE>(callable)(stringize("File '", mPath, "' contains:"));
+        boost::filesystem::ifstream reader(mPath, std::ios::binary);
         std::string line;
         while (std::getline(reader, line))
-            std::cout << line << '\n';
-        std::cout << "---\n";
+            std::forward<CALLABLE>(callable)(line);
+        std::forward<CALLABLE>(callable)("---");
+    }
+
+    void peep_log() const
+    {
+        peep_via([](const std::string& line){ LL_DEBUGS() << line << LL_ENDL; });
+    }
+
+    void peep(std::ostream& out=std::cout) const
+    {
+        peep_via([&out](const std::string& line){ out << line << '\n'; });
+    }
+
+    friend std::ostream& operator<<(std::ostream& out, const NamedTempFile& self)
+    {
+        self.peep(out);
+        return out;
+    }
+
+    static boost::filesystem::path temp_path(const std::string_view& pfx="",
+                                             const std::string_view& sfx="")
+    {
+        // This variable is set by GitHub actions and is the recommended place
+        // to put temp files belonging to an actions job.
+        const char* RUNNER_TEMP = getenv("RUNNER_TEMP");
+        boost::filesystem::path tempdir{
+            // if RUNNER_TEMP is set and not empty
+            (RUNNER_TEMP && *RUNNER_TEMP)?
+            boost::filesystem::path(RUNNER_TEMP) : // use RUNNER_TEMP if available
+            boost::filesystem::temp_directory_path()}; // else canonical temp dir
+        boost::filesystem::path tempname{
+            // use filename template recommended by unique_path() doc, but
+            // with underscores instead of hyphens: some use cases involve
+            // temporary Python scripts
+            tempdir / stringize(pfx, "%%%%_%%%%_%%%%_%%%%", sfx) };
+        return boost::filesystem::unique_path(tempname);
     }
 
 protected:
-    void createFile(const std::string& pfx, const Streamer& func)
+    void createFile(const std::string_view& pfx,
+                    const Streamer& func,
+                    const std::string_view& sfx)
     {
         // Create file in a temporary place.
-        const char* tempdir = NULL;
-        ll_apr_assert_status(apr_temp_dir_get(&tempdir, mPool));
-
-        // Construct a temp filename template in that directory.
-        char *tempname = NULL;
-        ll_apr_assert_status(apr_filepath_merge(&tempname,
-                                                tempdir,
-                                                (pfx + "XXXXXX").c_str(),
-                                                0,
-                                                mPool));
-
-        // Create a temp file from that template.
-        apr_file_t* fp = NULL;
-        ll_apr_assert_status(apr_file_mktemp(&fp,
-                                             tempname,
-                                             APR_CREATE | APR_WRITE | APR_EXCL,
-                                             mPool));
-        // apr_file_mktemp() alters tempname with the actual name. Not until
-        // now is it valid to capture as our mPath.
-        mPath = tempname;
-
+        mPath = temp_path(pfx, sfx);
+        boost::filesystem::ofstream out{ mPath, std::ios::binary };
         // Write desired content.
-        std::ostringstream out;
-        // Stream stuff to it.
         func(out);
-
-        std::string data(out.str());
-        apr_size_t writelen(data.length());
-        ll_apr_assert_status(apr_file_write(fp, data.c_str(), &writelen));
-        ll_apr_assert_status(apr_file_close(fp));
-        llassert_always(writelen == data.length());
     }
 
-    std::string mPath;
-    apr_pool_t* mPool;
+    boost::filesystem::path mPath;
 };
 
 /**
  * Create a NamedTempFile with a specified filename extension. This is useful
  * when, for instance, you must be able to use the file in a Python import
  * statement.
- *
- * A NamedExtTempFile actually has two different names. We retain the original
- * no-extension name as a placeholder in the temp directory to ensure
- * uniqueness; to that we link the name plus the desired extension. Naturally,
- * both must be removed on destruction.
  */
 class NamedExtTempFile: public NamedTempFile
 {
     LOG_CLASS(NamedExtTempFile);
 public:
-    NamedExtTempFile(const std::string& ext, const std::string& content, apr_pool_t* pool=gAPRPoolp):
-        NamedTempFile(remove_dot(ext), content, pool),
-        mLink(mPath + ensure_dot(ext))
-    {
-        linkto(mLink);
-    }
+    NamedExtTempFile(const std::string& ext, const std::string_view& content):
+        NamedTempFile(remove_dot(ext), content, ensure_dot(ext))
+    {}
 
     // Disambiguate when passing string literal
-    NamedExtTempFile(const std::string& ext, const char* content, apr_pool_t* pool=gAPRPoolp):
-        NamedTempFile(remove_dot(ext), content, pool),
-        mLink(mPath + ensure_dot(ext))
-    {
-        linkto(mLink);
-    }
-
-    NamedExtTempFile(const std::string& ext, const Streamer& func, apr_pool_t* pool=gAPRPoolp):
-        NamedTempFile(remove_dot(ext), func, pool),
-        mLink(mPath + ensure_dot(ext))
-    {
-        linkto(mLink);
-    }
+    NamedExtTempFile(const std::string& ext, const char* content):
+        NamedTempFile(remove_dot(ext), content, ensure_dot(ext))
+    {}
 
-    virtual ~NamedExtTempFile()
-    {
-        ll_apr_assert_status(apr_file_remove(mLink.c_str(), mPool));
-    }
-
-    // Since the caller has gone to the trouble to create the name with the
-    // extension, that should be the name we return. In this class, mPath is
-    // just a placeholder to ensure that future createFile() calls won't
-    // collide.
-    virtual std::string getName() const { return mLink; }
+    NamedExtTempFile(const std::string& ext, const Streamer& func):
+        NamedTempFile(remove_dot(ext), func, ensure_dot(ext))
+    {}
 
     static std::string ensure_dot(const std::string& ext)
     {
@@ -175,7 +165,7 @@ class NamedExtTempFile: public NamedTempFile
         {
             return ext;
         }
-        return std::string(".") + ext;
+        return "." + ext;
     }
 
     static std::string remove_dot(const std::string& ext)
@@ -187,19 +177,6 @@ class NamedExtTempFile: public NamedTempFile
         }
         return ext.substr(found);
     }
-
-private:
-    void linkto(const std::string& path)
-    {
-        // This method assumes that since mPath (without extension) is
-        // guaranteed by apr_file_mktemp() to be unique, then (mPath + any
-        // extension) is also unique. This is likely, though not guaranteed:
-        // files could be created in the same temp directory other than by
-        // this class.
-        ll_apr_assert_status(apr_file_link(mPath.c_str(), path.c_str()));
-    }
-
-    std::string mLink;
 };
 
 #endif /* ! defined(LL_NAMEDTEMPFILE_H) */
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index 28f25087ac5476644dafab2c003efe2a5dc3a06e..4987cf4727b2784b1f3a085e0f9a19f24538a57b 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -97,10 +97,10 @@ class LLReplayLog
 class RecordToTempFile : public LLError::Recorder, public boost::noncopyable
 {
 public:
-	RecordToTempFile(apr_pool_t* pPool)
+	RecordToTempFile()
 		: LLError::Recorder(),
 		boost::noncopyable(),
-		mTempFile("log", "", pPool),
+		mTempFile("log", ""),
 		mFile(mTempFile.getName().c_str())
 	{
 	}
@@ -141,11 +141,11 @@ class RecordToTempFile : public LLError::Recorder, public boost::noncopyable
 class LLReplayLogReal: public LLReplayLog, public boost::noncopyable
 {
 public:
-	LLReplayLogReal(LLError::ELevel level, apr_pool_t* pool)
+	LLReplayLogReal(LLError::ELevel level)
 		: LLReplayLog(),
 		boost::noncopyable(),
 		mOldSettings(LLError::saveAndResetSettings()),
-		mRecorder(new RecordToTempFile(pool))
+		mRecorder(new RecordToTempFile())
 	{
 		LLError::setFatalFunction(wouldHaveCrashed);
 		LLError::setDefaultLevel(level);
@@ -624,7 +624,7 @@ int main(int argc, char **argv)
 		if (LOGFAIL && *LOGFAIL)
 		{
 			LLError::ELevel level = LLError::decodeLevel(LOGFAIL);
-			replayer.reset(new LLReplayLogReal(level, gAPRPoolp));
+			replayer.reset(new LLReplayLogReal(level));
 		}
 	}
 	LLError::setFatalFunction(wouldHaveCrashed);