aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/build_html90
-rwxr-xr-xbin/check_index22
-rwxr-xr-xbin/check_links41
-rw-r--r--bin/ci-puppeteer-config.json3
-rwxr-xr-xbin/make_redirects78
-rwxr-xr-xbin/mermaid-cli-in-ci52
-rwxr-xr-xbin/mermaid_cvt_svg26
-rw-r--r--bin/puppeteer-cache-expect-listings289
-rwxr-xr-xbin/reindex215
-rwxr-xr-xbin/via-cargo-install-in-ci20
-rwxr-xr-xbin/via-yarn-install-in-ci59
11 files changed, 895 insertions, 0 deletions
diff --git a/bin/build_html b/bin/build_html
new file mode 100755
index 0000000..b6ee26d
--- /dev/null
+++ b/bin/build_html
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+
+set -e -u -o pipefail -x
+
+: "${MDBOOK:=mdbook}"
+
+TOPLEVEL=$(realpath "$(dirname "$0")")/..
+cd "${TOPLEVEL}"
+./bin/reindex
+
+./bin/make_redirects
+
+# Now we deal with mermaid diagrams.
+#
+# This may require changes to the md files in {spec,proposals}
+# or to the mdbook.toml files in mdbook/*/.
+# We will make a copy of whatever we need to change,
+# and then make changes to that copy.
+#
+# When we are done with these changes, we will set some variables:
+# - MDBOOK_OUTPUT_DIR is "", or the location where we have put our raw mdbook output.
+# - MDBOOK_DIR is the parent directory of the possibly modified copies
+# of mdbook/{spec,proposals}.
+
+if test -n "${MMDC:-}" || command -v "mmdc" >&/dev/null; then
+ # CASE 1: mermaid-cli is installed.
+ #
+ # We will convert mermaid diagrams to svg. The mermaid_cvt_svg
+ # script does this with a temporary copy of our markdown directories,
+ # so as not to alter the original.
+ #
+ # (The conversion involves npm and a headless chrome browser,
+ # to it is understandable that not everybody would want to do it
+ # this way.)
+ echo "Using mermaid-cli to pre-render mermaid diagrams"
+
+ TMPDIR=$(mktemp -d "${TOPLEVEL}/tmp_mmdc.XXXXXXXX")
+ trap 'rm -rf "$TMPDIR"' 0
+ ./bin/mermaid_cvt_svg "$TMPDIR"
+ MDBOOK_OUTPUT_DIR="$TMPDIR/build"
+ MDBOOK_DIR="$TMPDIR/mdbook"
+elif test -n "${MDBOOK_MERMAID:-}" || command -v "mdbook-mermaid" >&/dev/null; then
+ # CASE 2: mdbook_mermaid is installed.
+ #
+ # We will make a temporary copy of the mdbook configuration directory
+ # only, and use mdbook-mermaid to alter that.
+ #
+ # This is much easier to run locally, but it requires that your
+ # browser has enough client-side javascript in order to run
+ # mermaid. It doesn't touch npm.
+ echo "Using mdbook-mermaid to set up dynamic rendering of mermaid diagrams"
+
+ MDBOOK_MERMAID=${MDBOOK_MERMAID:=mdbook-mermaid}
+ TMPDIR=$(mktemp -d "${TOPLEVEL}/tmp_mdbook_mermaid.XXXXXXXX")
+ trap 'rm -rf "$TMPDIR"' 0
+ cp -r ./mdbook/proposals ./mdbook/spec ./mdbook/theme "$TMPDIR"
+ mdbook-mermaid install "$TMPDIR/spec"
+ mdbook-mermaid install "$TMPDIR/proposals"
+ MDBOOK_OUTPUT_DIR=""
+ MDBOOK_DIR="$TMPDIR"
+else
+ # CASE 3: No mermaid support.
+ #
+ # In this case we run mdbook on our inputs unchanged.
+ # The mermaid blocks will render as code.
+ echo "No mermaid support found; mermaid diagrams will be unrendered"
+
+ MDBOOK_OUTPUT_DIR=""
+ MDBOOK_DIR="$TOPLEVEL/mdbook"
+fi
+
+# mdbook-linkcheck is a non-obvious dependency, and the mdbook output when it's
+# not found doesn't spell out how to install it.
+if ! command -v mdbook-linkcheck; then
+ echo 'ERROR: mdbook-linkcheck not found. You should probably install it with "cargo install mdbook-linkcheck"'
+ exit 1
+fi
+
+$MDBOOK build "${MDBOOK_DIR}/spec"
+$MDBOOK build "${MDBOOK_DIR}/proposals"
+
+if test -n "${MDBOOK_OUTPUT_DIR}"; then
+ rm -rf "${TOPLEVEL}/build"
+ mv "${MDBOOK_OUTPUT_DIR}" "${TOPLEVEL}/build"
+fi
+
+rm -rf "${TOPLEVEL}/html/"
+mv "${TOPLEVEL}/build/spec/html" "${TOPLEVEL}/html"
+mv "${TOPLEVEL}/build/proposals/html" "${TOPLEVEL}/html/proposals"
+
diff --git a/bin/check_index b/bin/check_index
new file mode 100755
index 0000000..a2e8c4f
--- /dev/null
+++ b/bin/check_index
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+#
+# Give an error if somebody forgot to run ./reindex.py.
+#
+# Only works on a clean git checkout.
+
+set -e -u -o pipefail -x
+
+TOPLEVEL=$(dirname "$0")/..
+
+if ! git diff --quiet ; then
+ echo "Git repository is not clean. Cannot procede."
+ exit 2
+fi
+
+cd "$TOPLEVEL/"
+./bin/reindex
+
+if ! git diff --quiet ; then
+ echo "Proposal index is not up-to-date. Run ./reindex.py to regenerate it." >&2
+ exit 1
+fi
diff --git a/bin/check_links b/bin/check_links
new file mode 100755
index 0000000..a079976
--- /dev/null
+++ b/bin/check_links
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# Check rustdoc HTML links and anchors
+# bin/build_html must have been run first.
+#
+# Adapted from
+# https://gitlab.torproject.org/Diziet/rust-derive-adhoc/-/blob/main/maint/check-doc-links?ref_type=heads
+
+set -e
+set -o pipefail
+
+# nailing-cargo --no-nail --- bin/build_html
+# nailing-cargo --preclean=no --- bin/check_links
+
+chk_dir=html.link-check
+
+rm -rf html.link-check
+cp -al html $chk_dir
+
+# Fix up https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=425632
+
+# shellcheck disable=SC2016
+find $chk_dir -name \*.html -print0 |
+xargs -0r -- perl -i~ -pe '
+ s{\bid=("[^"]+")[^<>]*\>}{$&<a name=$1>}g;
+'
+
+linklint -xref -out linklint.errors -error -root $chk_dir /@
+
+cat linklint.errors
+
+set +e
+grep ERROR linklint.errors
+rc=$?
+set -e
+
+case $rc in
+0) echo >&2 '** found linkcheck errors **'; exit 1;;
+1) ;;
+*) echo >&2 "linkcheck failed $rc"; exit 1;;
+esac
diff --git a/bin/ci-puppeteer-config.json b/bin/ci-puppeteer-config.json
new file mode 100644
index 0000000..3201af7
--- /dev/null
+++ b/bin/ci-puppeteer-config.json
@@ -0,0 +1,3 @@
+{
+ "args": ["--no-sandbox"]
+}
diff --git a/bin/make_redirects b/bin/make_redirects
new file mode 100755
index 0000000..a26b871
--- /dev/null
+++ b/bin/make_redirects
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+
+import yaml, os, re, sys
+
+def update_file(fname, start_marker, end_marker, replacement):
+ content = list(open(fname, 'r').readlines())
+ startline = content.index(start_marker)
+ endline = content.index(end_marker)
+ assert endline > startline
+ content[startline+1:endline] = replacement
+
+ with open(fname+".tmp", 'w') as f:
+ f.write("".join(content))
+ os.rename(fname+".tmp", fname)
+
+BOOK_START = "# BEGIN AUTO-GENERATED REDIRECTS\n"
+BOOK_END = "# END AUTO-GENERATED REDIRECTS\n"
+
+HTML_MARKER_START = "<!-- BEGIN AUTO-GENERATED REDIRECTS -->\n"
+HTML_MARKER_END = "<!-- END AUTO-GENERATED REDIRECTS -->\n"
+
+def book_redirects(rs, spec_dir):
+ lines = []
+ for kwd, info in rs.items():
+ if os.path.isdir(os.path.join(spec_dir, kwd)):
+ assert os.path.isfile(os.path.join(spec_dir, kwd, "index.md"))
+ assert info.get('implicit')
+ continue
+ elif any((os.path.isfile(os.path.join(spec_dir, kwd) + ext)) for ext in [".txt", ".md"]):
+ assert info.get('implicit')
+ continue
+ else:
+ assert not info.get('implicit')
+ source = kwd + ".html"
+ target = info['target']
+ lines.append(
+ f'"/{source}" = "{target}"\n'
+ )
+ return "".join(lines)
+
+def permalinks_redirects(rs):
+ lines = [ "<dl>\n" ]
+ for kwd, info in rs.items():
+ target = info['target']
+ desc = info['description']
+ lines.append(f'<dt><code>/{kwd}</code></dt>\n')
+ lines.append(f'<dd><a href="{target}"><code>{target}</code> ({desc})</a></dt>\n')
+
+ lines.append("</dl>\n")
+ return "".join(lines)
+
+def proposal_redirects(proposals_dir):
+ lines = []
+ for fname in os.listdir(proposals_dir):
+ m = re.match(r'^(\d+)-.*\.(?:md|txt)$', fname)
+ if m:
+ source = m.group(1) + ".html"
+ target, targetext = os.path.splitext(fname)
+ if targetext == '.md':
+ targetext = ".html"
+ lines.append(f'"/{source}" = "./{target}{targetext}"\n')
+ lines.sort()
+ return "".join(lines)
+
+if __name__ == '__main__':
+ toplevel = os.path.join(os.path.dirname(sys.argv[0]), "..")
+ spec_book_fname = os.path.join(toplevel, "mdbook", "spec", "book.toml")
+ spec_dir = os.path.join(toplevel, "spec")
+ permalinks_fname = os.path.join(toplevel, "spec", "permalinks.md")
+ prop_dir = os.path.join(toplevel, "proposals")
+ prop_book_fname = os.path.join(toplevel, "mdbook", "proposals", "book.toml")
+ yaml_fname = os.path.join(toplevel, "mdbook", "spec", "spec-redirects.yaml")
+
+ rs = yaml.load(open(yaml_fname), yaml.Loader)['redirects']
+
+ update_file(spec_book_fname, BOOK_START, BOOK_END, book_redirects(rs, spec_dir))
+ update_file(permalinks_fname, HTML_MARKER_START, HTML_MARKER_END, permalinks_redirects(rs))
+ update_file(prop_book_fname, BOOK_START, BOOK_END, proposal_redirects(prop_dir))
diff --git a/bin/mermaid-cli-in-ci b/bin/mermaid-cli-in-ci
new file mode 100755
index 0000000..07700fa
--- /dev/null
+++ b/bin/mermaid-cli-in-ci
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+set -x
+
+# Bump this to "clear" the cache.
+# Actually, it just causes us to ignore previous cached results.
+cache_clear_token=2023-11-09c
+
+cache_dir="cache/$CI_JOB_IMAGE,$cache_clear_token,puppeteer"
+local_dir="$HOME/.cache/puppeteer"
+
+if test -d "$cache_dir"; then
+ mkdir -p "$local_dir"/.
+ cp -a "$cache_dir"/. "$local_dir"/.
+fi
+
+./bin/via-yarn-install-in-ci mmdc https://github.com/mermaid-js/mermaid-cli \
+ bba0240ad87f6fbf44d8a24941e37f4bc2c8bf30
+
+(
+ cd "$local_dir"
+ find . -printf '%y %p %l\n' | sort
+ find . -type f | sort | xargs sha256sum --
+) >puppeteer-cache-got-listings
+
+# Empirically, the mermaid-cli locked install produced a very old
+# chromium today. So I suspect it's not fetching "latest", but a controlled
+# version. Nevertheless, we should check that what we got is actually
+# the same and hasn't been changed by Google (or something on the way).
+
+# Doing this now isn't ideal, because I don't actually know if
+# the mermaid-cli *install* process runs anything from here.
+# But I don't think it runs the main chrome binary, since at one point
+# in our tests we got as far as this and then the chrome binary
+# failed with due to a missing OS shared library.
+
+# This expected output listing shouldn't be in bin/ but the best way
+# to fix that would be to rename the whole bin directory to maint.
+diff -u bin/puppeteer-cache-expect-listings puppeteer-cache-got-listings
+
+if ! test -d "$cache_dir"; then
+ mkdir -p "$cache_dir"
+ cp -a "$local_dir"/. "$cache_dir"/.
+fi
+
+# This is the easiest way to get the shared libraries that chromium
+# depends on. Obviously, using the Debian package's dependencies
+# is totally wrong, but it works in practice, and we don't have a proper
+# dependency list from the binaries from the ad-hoc downloads.
+apt-get install -y chromium
diff --git a/bin/mermaid_cvt_svg b/bin/mermaid_cvt_svg
new file mode 100755
index 0000000..a48bbee
--- /dev/null
+++ b/bin/mermaid_cvt_svg
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+set -e -u -o pipefail -x
+
+TOPLEVEL=$(realpath "$(dirname "$0")")/..
+TMPDIR="$1"
+: "${MMDC:=mmdc}"
+
+cd "$TOPLEVEL"
+
+# We make a mirror of the specs, since we will need to make changes to them.
+cp -rl spec proposals mdbook "$TMPDIR"
+
+# We use mermaid-cli to extract the mermaid from any file containing it,
+# and generate a new version that uses svg instead.
+shopt -s globstar nullglob
+for fname in "$TMPDIR"/**/*.md; do
+ if grep '^```mermaid' "$fname"; then
+ ORIG="${fname%.md}.__orig.md"
+ mv "$fname" "$ORIG"
+ $MMDC -i "$ORIG" -o "$fname"
+ fi
+done
+
+
+
diff --git a/bin/puppeteer-cache-expect-listings b/bin/puppeteer-cache-expect-listings
new file mode 100644
index 0000000..a5d5783
--- /dev/null
+++ b/bin/puppeteer-cache-expect-listings
@@ -0,0 +1,289 @@
+d .
+d ./chrome
+d ./chrome/linux-1108766
+d ./chrome/linux-1108766/chrome-linux
+d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm
+d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific
+d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific/linux_x64
+d ./chrome/linux-1108766/chrome-linux/MEIPreload
+d ./chrome/linux-1108766/chrome-linux/locales
+d ./chrome/linux-1108766/chrome-linux/resources
+d ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay
+f ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific/linux_x64/libclearkeycdm.so
+f ./chrome/linux-1108766/chrome-linux/MEIPreload/manifest.json
+f ./chrome/linux-1108766/chrome-linux/MEIPreload/preloaded_data.pb
+f ./chrome/linux-1108766/chrome-linux/chrome
+f ./chrome/linux-1108766/chrome-linux/chrome-wrapper
+f ./chrome/linux-1108766/chrome-linux/chrome_100_percent.pak
+f ./chrome/linux-1108766/chrome-linux/chrome_200_percent.pak
+f ./chrome/linux-1108766/chrome-linux/chrome_crashpad_handler
+f ./chrome/linux-1108766/chrome-linux/chrome_sandbox
+f ./chrome/linux-1108766/chrome-linux/icudtl.dat
+f ./chrome/linux-1108766/chrome-linux/libEGL.so
+f ./chrome/linux-1108766/chrome-linux/libGLESv2.so
+f ./chrome/linux-1108766/chrome-linux/libvk_swiftshader.so
+f ./chrome/linux-1108766/chrome-linux/libvulkan.so.1
+f ./chrome/linux-1108766/chrome-linux/locales/af.pak
+f ./chrome/linux-1108766/chrome-linux/locales/af.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/am.pak
+f ./chrome/linux-1108766/chrome-linux/locales/am.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ar.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ar.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/bg.pak
+f ./chrome/linux-1108766/chrome-linux/locales/bg.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/bn.pak
+f ./chrome/linux-1108766/chrome-linux/locales/bn.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ca.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ca.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/cs.pak
+f ./chrome/linux-1108766/chrome-linux/locales/cs.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/da.pak
+f ./chrome/linux-1108766/chrome-linux/locales/da.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/de.pak
+f ./chrome/linux-1108766/chrome-linux/locales/de.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/el.pak
+f ./chrome/linux-1108766/chrome-linux/locales/el.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak
+f ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/en-US.pak
+f ./chrome/linux-1108766/chrome-linux/locales/en-US.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak
+f ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/es-419.pak
+f ./chrome/linux-1108766/chrome-linux/locales/es-419.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/es.pak
+f ./chrome/linux-1108766/chrome-linux/locales/es.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/et.pak
+f ./chrome/linux-1108766/chrome-linux/locales/et.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fa.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fa.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fi.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fi.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fil.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fil.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/gu.pak
+f ./chrome/linux-1108766/chrome-linux/locales/gu.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/he.pak
+f ./chrome/linux-1108766/chrome-linux/locales/he.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/hi.pak
+f ./chrome/linux-1108766/chrome-linux/locales/hi.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/hr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/hr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/hu.pak
+f ./chrome/linux-1108766/chrome-linux/locales/hu.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/id.pak
+f ./chrome/linux-1108766/chrome-linux/locales/id.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/it.pak
+f ./chrome/linux-1108766/chrome-linux/locales/it.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ja.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ja.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/kn.pak
+f ./chrome/linux-1108766/chrome-linux/locales/kn.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ko.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ko.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/lt.pak
+f ./chrome/linux-1108766/chrome-linux/locales/lt.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/lv.pak
+f ./chrome/linux-1108766/chrome-linux/locales/lv.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ml.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ml.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/mr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/mr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ms.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ms.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/nb.pak
+f ./chrome/linux-1108766/chrome-linux/locales/nb.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/nl.pak
+f ./chrome/linux-1108766/chrome-linux/locales/nl.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/pl.pak
+f ./chrome/linux-1108766/chrome-linux/locales/pl.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak
+f ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak
+f ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ro.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ro.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ru.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ru.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sk.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sk.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sl.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sl.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sv.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sv.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sw.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sw.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ta.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ta.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/te.pak
+f ./chrome/linux-1108766/chrome-linux/locales/te.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/th.pak
+f ./chrome/linux-1108766/chrome-linux/locales/th.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/tr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/tr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/uk.pak
+f ./chrome/linux-1108766/chrome-linux/locales/uk.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ur.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ur.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/vi.pak
+f ./chrome/linux-1108766/chrome-linux/locales/vi.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak
+f ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak
+f ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak.info
+f ./chrome/linux-1108766/chrome-linux/nacl_helper
+f ./chrome/linux-1108766/chrome-linux/nacl_helper_bootstrap
+f ./chrome/linux-1108766/chrome-linux/nacl_irt_x86_64.nexe
+f ./chrome/linux-1108766/chrome-linux/product_logo_48.png
+f ./chrome/linux-1108766/chrome-linux/resources.pak
+f ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/inspector_overlay_resources.grd
+f ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/main.js
+f ./chrome/linux-1108766/chrome-linux/v8_context_snapshot.bin
+f ./chrome/linux-1108766/chrome-linux/vk_swiftshader_icd.json
+f ./chrome/linux-1108766/chrome-linux/xdg-mime
+f ./chrome/linux-1108766/chrome-linux/xdg-settings
+c0b731f77524b864f90bd6ba538880169a1ae2a8ece21a849a752e1c8809ef1d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific/linux_x64/libclearkeycdm.so
+44844cf3dde6e80087ae0e6bf0d9326d7ef7d23326d24ac83af0850be26923d2 ./chrome/linux-1108766/chrome-linux/MEIPreload/manifest.json
+c6070a157b4e28d16fbccbd233e93846ddb070c85e1a1bc64469b7a5f1424fad ./chrome/linux-1108766/chrome-linux/MEIPreload/preloaded_data.pb
+9fb6757b5c61b28cbdd23a6c17a9acc61da856f812c02dae0b5156c0ee168a48 ./chrome/linux-1108766/chrome-linux/chrome
+17b0432a26e628287789f1efa53056384a46b6265939e8bf819b1b6cf8472ada ./chrome/linux-1108766/chrome-linux/chrome-wrapper
+7ab09e1609f2dd97cfbfa8988c71575d6abbe329d9c5a0d555b75504d5c4b980 ./chrome/linux-1108766/chrome-linux/chrome_100_percent.pak
+2e3fe3b1da0944d3704d1593c73e6ce3e286f8733829138d60a49766b69c03ff ./chrome/linux-1108766/chrome-linux/chrome_200_percent.pak
+f429e74163d634d37253d07730adc7651ce68fa16ebf794c1640193f94156392 ./chrome/linux-1108766/chrome-linux/chrome_crashpad_handler
+c97779a42a6edebdb6e94ff4836b87444380e4fcb6df007f715cbc3b362231bb ./chrome/linux-1108766/chrome-linux/chrome_sandbox
+e185ba581543fe286f1640a579d6f2219c181d95fa76e64f66c5a706f308860a ./chrome/linux-1108766/chrome-linux/icudtl.dat
+1647b2a56c450d02dc735f334ee12a6e442e6b2f6dae5ff0f6e4b05efedc9465 ./chrome/linux-1108766/chrome-linux/libEGL.so
+2af932a8f93999a0a32b87be6002fe83ca0e4579fc8ddba72a1a150323c38b58 ./chrome/linux-1108766/chrome-linux/libGLESv2.so
+fd7894d32ccbaed94672b63e9ff76f970e995f193716271005c581a4a2f3c947 ./chrome/linux-1108766/chrome-linux/libvk_swiftshader.so
+a94387cd9baf120b97fce4dcf8569c1a83e99ce85dd41978291b7fff25541aad ./chrome/linux-1108766/chrome-linux/libvulkan.so.1
+323c7a7ca326e7ef582b7034d10f4e81deaf630722cf43d5466b1deb419ec801 ./chrome/linux-1108766/chrome-linux/locales/af.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/af.pak.info
+f087f1f2bb83c48016b647799190f0f7f172df2fb5577ae9597ec17071caab90 ./chrome/linux-1108766/chrome-linux/locales/am.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/am.pak.info
+5dae1653f48a41abe2869245fd4fbc8a8e415dbfa125942706a6ff039e9a7f0c ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak.info
+5e22492cd14f8d739d2b14c7c5b0c10ed4f8585b5dddb402f36652d2c990b170 ./chrome/linux-1108766/chrome-linux/locales/ar.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ar.pak.info
+dde3b5d59f81d593045518a40be3d9236d3f66a678f5823e342f3f379056858f ./chrome/linux-1108766/chrome-linux/locales/bg.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/bg.pak.info
+afb37a07a9fae9cf5d278f0426c047334f24a08c5f52aac76f75f3bfc1957bf6 ./chrome/linux-1108766/chrome-linux/locales/bn.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/bn.pak.info
+628c2f24f00ef37ba42af1ecf74136b5620a4f304a1bba9358129ba52f1124b2 ./chrome/linux-1108766/chrome-linux/locales/ca.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ca.pak.info
+b5e95d9d94bfdef932f6fcaadf828b000e2f5a3b6d4a7c3a1b8ff1e55f2809aa ./chrome/linux-1108766/chrome-linux/locales/cs.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/cs.pak.info
+e5ea8dc83b39971db4bc62616d90c574311ad111ef38269befeff04c76b5a3bb ./chrome/linux-1108766/chrome-linux/locales/da.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/da.pak.info
+6983d893c1005c5a91718870b24c9444164427b901dd788435fcc78357a140b2 ./chrome/linux-1108766/chrome-linux/locales/de.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/de.pak.info
+e20982ee140a95bd8d440b645b593faab16ddc5a3c41fe40ca3b77243bfbacf8 ./chrome/linux-1108766/chrome-linux/locales/el.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/el.pak.info
+0918c68b0c5cd09f0ef1e9cc984fecb8ce79c0d0a509cdac2b77f9c0c29ce143 ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak.info
+b090180d5cd6ebfc25cb245c44156a4b945b52f581725b4184b0e0e5d78ff381 ./chrome/linux-1108766/chrome-linux/locales/en-US.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/en-US.pak.info
+7376d5f7cdbb0763efff84f2d8fa546be589577af5291cc629387425ca4e207e ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak.info
+290017770c41c26844032b8a2a1b97f7674653083411e23c12b72cc9ed8f49ea ./chrome/linux-1108766/chrome-linux/locales/es-419.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/es-419.pak.info
+a6d11beb2cf80c222d1a62133a6243776d4c379c18392794027ec0e64489af1b ./chrome/linux-1108766/chrome-linux/locales/es.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/es.pak.info
+42a74c9af1d7eee8c912c0b06b0439b0082ac453bf247ab044a2dccf8abbe7a5 ./chrome/linux-1108766/chrome-linux/locales/et.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/et.pak.info
+5ac624214ee7eded46e70368653f42b15ede5348621d0a57e7e615a56d8c9c05 ./chrome/linux-1108766/chrome-linux/locales/fa.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fa.pak.info
+13c852eb058b37b736df5d87a81ed5370404cdb0c9a5f35d64d6d6ca03eaf013 ./chrome/linux-1108766/chrome-linux/locales/fi.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fi.pak.info
+34572afd7489460793ea95b65e4bd68cb2f70a4873f74f2230fc71865bd514fa ./chrome/linux-1108766/chrome-linux/locales/fil.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fil.pak.info
+4f3760d38ae95943ff8f2b79aa7c7d41b4143cad9ac81fe34080fc0aff66838b ./chrome/linux-1108766/chrome-linux/locales/fr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fr.pak.info
+01732e407c1ef2ffb678f2e1d8ba47e64b4d7583ba6fc2e3cfa4d40e89b325d9 ./chrome/linux-1108766/chrome-linux/locales/gu.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/gu.pak.info
+c191ec5dfc7eee295fe784e529bdf87878dec24d9705ae87a23a0a7be2daf742 ./chrome/linux-1108766/chrome-linux/locales/he.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/he.pak.info
+518729e2d63e92b36b146a6017eda1f36d5a1b93c4733509a8d8ed30ad8a2abe ./chrome/linux-1108766/chrome-linux/locales/hi.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/hi.pak.info
+7faa324f5deb95621f19401bab3b616bc8f4fc99b1864d8dd02b53f64ff13972 ./chrome/linux-1108766/chrome-linux/locales/hr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/hr.pak.info
+eb99d8d7345da980371850ee26d74b1f98bebf5227a3e2b42fc55621c4ecb826 ./chrome/linux-1108766/chrome-linux/locales/hu.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/hu.pak.info
+cd5f6af3d83e9b49b66057b5de4defef8c925c2eea29171d336846c4f1b8c0e2 ./chrome/linux-1108766/chrome-linux/locales/id.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/id.pak.info
+aba599aef83877ec43647f17381b5ea677b115573f829fee19b5e95a106d82d2 ./chrome/linux-1108766/chrome-linux/locales/it.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/it.pak.info
+77a6f638d6e20c57335b1a419abbd5419a45b996f20a8b247f8323f95d8b8a7d ./chrome/linux-1108766/chrome-linux/locales/ja.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ja.pak.info
+4251e497322a09eb9d11fcdeb79eacbd1d5ca738824b6efa41c20742bf05e041 ./chrome/linux-1108766/chrome-linux/locales/kn.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/kn.pak.info
+9cbf60872e4853badc62264af46de01f3700049f72d40412b805c1f2f0fc1c1d ./chrome/linux-1108766/chrome-linux/locales/ko.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ko.pak.info
+a54f4825d04fef04066c88e3a1cfe2e014551cbfb19d4de3df71e38b118aec54 ./chrome/linux-1108766/chrome-linux/locales/lt.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/lt.pak.info
+f23f05077da21b8c811b60181389c15fddffd41327c36fe0c6e7a691fa9433d2 ./chrome/linux-1108766/chrome-linux/locales/lv.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/lv.pak.info
+6b1f3aad63a2152ae7343c6c20fe4f77f1eeb973ba957893feece942ba88e54a ./chrome/linux-1108766/chrome-linux/locales/ml.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ml.pak.info
+c55c1e54776346c536abd431e289c467a01ba963a93ee2ff1845a150b207c744 ./chrome/linux-1108766/chrome-linux/locales/mr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/mr.pak.info
+2a7f4e67717d25e9ccc74d16cfb1bab5dd18eaf16d8771d80fe38b226ec2ad5a ./chrome/linux-1108766/chrome-linux/locales/ms.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ms.pak.info
+2971e09f96b9249b74ad8be35d777516fe1e49ae8ee8099935a40280105ff759 ./chrome/linux-1108766/chrome-linux/locales/nb.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/nb.pak.info
+c6df365597b3dd966ba84e6cd0d7fc4027a520ff85b36a47da9ed61e2b3a994a ./chrome/linux-1108766/chrome-linux/locales/nl.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/nl.pak.info
+ce50ebb59577f58a81444d074bb3602badf7df026c8a778333870647e9b54b52 ./chrome/linux-1108766/chrome-linux/locales/pl.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/pl.pak.info
+30d3eae85ccb68a513f49981c5dd8b67d4a42ea4c330016cbe30e37ee38e0a1d ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak.info
+bdcfdb657a204904faef4c2f627954dab097702e1dfd2e3e15971bb4d959c843 ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak.info
+d67a006273ce46f0c5ba724efe2c1bdf7943e88a9d88c7563421c31d14ba42a9 ./chrome/linux-1108766/chrome-linux/locales/ro.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ro.pak.info
+723a919b66af7e2c428e4724376237fce747a47a9a0128810132f9f0b07d64ba ./chrome/linux-1108766/chrome-linux/locales/ru.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ru.pak.info
+de81e6beb671141293605e396ba0992cc040ad8d2b4a9a019f60a2e40c954562 ./chrome/linux-1108766/chrome-linux/locales/sk.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sk.pak.info
+16eee255672f7803ae9b282ce9d3aab6a29797a8ce1c787f949ab208a1f35352 ./chrome/linux-1108766/chrome-linux/locales/sl.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sl.pak.info
+01b9a0a613d1d7504e90f9a523a90102d245f999ee8ff93d284c4186e6c2f463 ./chrome/linux-1108766/chrome-linux/locales/sr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sr.pak.info
+b8f738b3b5f334230f7ac8849a4eef3d77862e54202728e0c5608426b4add140 ./chrome/linux-1108766/chrome-linux/locales/sv.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sv.pak.info
+4d7a3154fa0dbafefb96ef1fff1f60563a16de55deccfd11f2c5d3f733e29d0a ./chrome/linux-1108766/chrome-linux/locales/sw.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sw.pak.info
+2dde4957d13101ade6f393a88332f8fc774f0565c73ece361f2f1ad12be235a2 ./chrome/linux-1108766/chrome-linux/locales/ta.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ta.pak.info
+331489c0918c2b105b1112cdd620eba4af78bc80284730ed0c5691685be622fe ./chrome/linux-1108766/chrome-linux/locales/te.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/te.pak.info
+e04402b90dd5bbae71b68f85c834247c46eead0bcf0ac1996f4cc191f204d0c0 ./chrome/linux-1108766/chrome-linux/locales/th.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/th.pak.info
+fef2df11ed39c4f0f1687d49ff60b97d07513e03f9ff56ebe09ef088d7918473 ./chrome/linux-1108766/chrome-linux/locales/tr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/tr.pak.info
+7a90a56c50fdc2a9add8c2399c18cc97f4af00d6ad067990f5758158987af6f2 ./chrome/linux-1108766/chrome-linux/locales/uk.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/uk.pak.info
+599d28b9b15b4a7e49a6747899310b919a5a05c428e7fb8e62fd67498ce46cdb ./chrome/linux-1108766/chrome-linux/locales/ur.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ur.pak.info
+858a3ace87bff36cd4dc1532ad95626b061fa2af07dff40d896f266facc46ca7 ./chrome/linux-1108766/chrome-linux/locales/vi.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/vi.pak.info
+27d1f81e8302bd24bdaaf39ec9734e732f812644cf24cf282c86851bd1a4ee1a ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak.info
+72fa334fe28ab855115c32d9005c34620115960c0fc1e3709c2fb6e9e53d6976 ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak.info
+a20f2ff7a775859e2493c9fc4118080b5d31c2b28c4e79c08255f7d0e411a12b ./chrome/linux-1108766/chrome-linux/nacl_helper
+2bb2fa72fab83a34dfa6690973177d3537a3a946300d66ede276c8b6de2cbec7 ./chrome/linux-1108766/chrome-linux/nacl_helper_bootstrap
+17dcbaeb7337547b75884c44bd38377dccf36b444c6cab9a740cf0aef1b7abf5 ./chrome/linux-1108766/chrome-linux/nacl_irt_x86_64.nexe
+21b2927bb47d305bbda718b9c08c6b51fbc0597454587978ea0046bc595393fb ./chrome/linux-1108766/chrome-linux/product_logo_48.png
+64b6feb043f51c13b25b5b72290bf30ec48c4181ed9716b1b4bee76a7c0f55ba ./chrome/linux-1108766/chrome-linux/resources.pak
+68760fc7002c3999d3b2ac6eb80febe28182134a0dd1d53829f660b3d96bc9ef ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/inspector_overlay_resources.grd
+cd1db1a3000b7397c4232bcc2c05b9fa436c25f0c00aaab683d448b325588256 ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/main.js
+46639e627710cf843878115db26b97da94678782a8a0d109a5c29ac04b6b0d9e ./chrome/linux-1108766/chrome-linux/v8_context_snapshot.bin
+c9eef28b6b984fec220ef0abfecc40b502d46946706e47bfe97707027cb818bd ./chrome/linux-1108766/chrome-linux/vk_swiftshader_icd.json
+ad2d5802bb3604daa849ce5ac86a81acf7548c8ffd10ab4ecae1d56a5f10d63b ./chrome/linux-1108766/chrome-linux/xdg-mime
+442777b1f7d206c5ff661fea00dc1a8319df6256feccc54f186f6edacf235801 ./chrome/linux-1108766/chrome-linux/xdg-settings
diff --git a/bin/reindex b/bin/reindex
new file mode 100755
index 0000000..24e76eb
--- /dev/null
+++ b/bin/reindex
@@ -0,0 +1,215 @@
+#!/usr/bin/env python3
+
+import sys
+if sys.version_info[0] < 3:
+ print("No support for Python 2.")
+ sys.exit(1)
+
+import codecs, re, os
+class Error(Exception): pass
+
+STATUSES = """DRAFT NEEDS-REVISION NEEDS-RESEARCH OPEN ACCEPTED META FINISHED
+ CLOSED SUPERSEDED DEAD REJECTED OBSOLETE RESERVE INFORMATIONAL""".split()
+REQUIRED_FIELDS = [ "Filename", "Status", "Title"]
+CONDITIONAL_FIELDS = { "OPEN" : [ "Target", "Ticket" ],
+ "ACCEPTED" : [ "Target", "Ticket" ],
+ "CLOSED" : [ "Implemented-In", "Ticket" ],
+ "FINISHED" : [ "Implemented-In", "Ticket" ] }
+FNAME_RE = re.compile(r'^(\d\d\d)-.*[^\~]$')
+DIR = "."
+OUTFILE_TXT = "000-index.txt"
+TMPFILE_TXT = OUTFILE_TXT+".tmp"
+
+TEMPFILES = [TMPFILE_TXT]
+
+def unlink_if_present(fname):
+ try:
+ os.unlink(fname)
+ except OSError:
+ pass
+
+def indexed(seq):
+ n = 0
+ for i in seq:
+ yield n, i
+ n += 1
+
+def readProposal(fn):
+ fields = { }
+ f = codecs.open(fn, 'r', encoding='utf-8')
+ lastField = None
+ try:
+ for lineno, line in indexed(f):
+ line = line.rstrip()
+ if not line:
+ return fields
+ if line[0].isspace():
+ fields[lastField] += " %s"%(line.strip())
+ elif line == "```":
+ pass
+ else:
+ parts = line.split(":", 1)
+ if len(parts) != 2:
+ raise Error("%s:%s: Neither field, continuation, nor ```."%
+ (fn,lineno))
+ else:
+ fields[parts[0]] = parts[1].strip()
+ lastField = parts[0]
+
+ return fields
+ finally:
+ f.close()
+
+def getProposalNumber(fn):
+ """Get the proposal's assigned number from its filename `fn`."""
+ parts = fn.split('-', 1)
+
+ assert len(parts) == 2, \
+ "Filename must have a proposal number and title separated by a '-'"
+
+ return int(parts[0])
+
+def checkProposal(fn, fields):
+ status = fields.get("Status")
+ need_fields = REQUIRED_FIELDS + CONDITIONAL_FIELDS.get(status, [])
+
+ number = getProposalNumber(fn)
+ # Since prop#288 was the newest when we began requiring the 'Ticket:'
+ # field, we don't require the field for it or any older proposal.
+ # (Although you're encouraged to add it to your proposal, and add it for
+ # older proposals where you know the correct ticket, as it greatly helps
+ # newcomers find more information on the implementation.)
+ if number <= 288:
+ if "Ticket" in need_fields:
+ need_fields.remove("Ticket")
+
+ for f in need_fields:
+ if f not in fields:
+ raise Error("%s has no %s field"%(fn, f))
+ if fn != fields['Filename']:
+ raise Error("Mismatched Filename field in %s"%fn)
+ if fields['Title'][-1] == '.':
+ fields['Title'] = fields['Title'][:-1]
+
+ status = fields['Status'] = status.upper()
+ if status not in STATUSES:
+ raise Error("I've never heard of status %s in %s"%(status,fn))
+ if status in [ "SUPERSEDED", "DEAD" ]:
+ for f in [ 'Implemented-In', 'Target' ]:
+ if f in fields: del fields[f]
+
+ fields['FilenameTruncated'] = os.path.splitext(fields['Filename'])[0]
+
+def readProposals():
+ res = []
+ for fn in os.listdir(DIR):
+ m = FNAME_RE.match(fn)
+ if not m: continue
+ if fn.endswith(".tmp"):
+ continue
+ if not (fn.endswith(".txt") or fn.endswith(".md")):
+ raise Error("%s doesn't end with .txt or .md"%fn)
+ num = m.group(1)
+ fields = readProposal(fn)
+ checkProposal(fn, fields)
+ fields['num'] = num
+ res.append(fields)
+ return res
+
+def writeTextIndexFile(proposals):
+ proposals.sort(key=lambda f:f['num'])
+ seenStatuses = set()
+ for p in proposals:
+ seenStatuses.add(p['Status'])
+
+ out = open(TMPFILE_TXT, 'w')
+ inf = open(OUTFILE_TXT, 'r')
+ for line in inf:
+ out.write(line)
+ if line.startswith("====="): break
+ inf.close()
+
+ out.write("Proposals by number:\n\n")
+ for prop in proposals:
+ out.write("%(num)s %(Title)s [%(Status)s]\n"%prop)
+ out.write("\n\nProposals by status:\n\n")
+ for s in STATUSES:
+ if s not in seenStatuses: continue
+ out.write(" %s:\n"%s)
+ for prop in proposals:
+ if s == prop['Status']:
+ out.write(" %(num)s %(Title)s"%prop)
+ if "Target" in prop:
+ out.write(" [for %(Target)s]"%prop)
+ if "Implemented-In" in prop:
+ out.write(" [in %(Implemented-In)s]"%prop)
+ out.write("\n")
+
+ out.write("```\n")
+ out.close()
+ os.rename(TMPFILE_TXT, OUTFILE_TXT)
+
+def formatMarkdownEntry(prop, withStatus=False):
+ if withStatus:
+ fmt = "* [`{Filename}`](/proposals/{Filename}): {Title} \\[{Status}\\]\n"
+ else:
+ fmt = "* [`{Filename}`](/proposals/{Filename}): {Title}\n"
+ return fmt.format(**prop)
+
+def formatSummaryEntry(prop):
+ return " - [`{FilenameTruncated}`](./{Filename}): {Title} ({Status})\n".format(**prop)
+
+def writeMarkdownFile(prefix, format_inputs):
+ template = prefix+"_template.md"
+ output = prefix+".md"
+ t = open(template).read()
+ content = t.format(**format_inputs)
+ with open(output, 'w') as f:
+ f.write(content)
+
+def writeMarkdownIndexFiles(proposals):
+ markdown_files = [ "BY_INDEX", "BY_STATUS", "SUMMARY" ]
+ format_inputs = {}
+
+ format_inputs['warning'] = "<!-- DO NOT EDIT THIS FILE -->"
+
+ entries = []
+ for prop in proposals:
+ entries.append(formatMarkdownEntry(prop, withStatus=True))
+ format_inputs["BY_INDEX"] = "".join(entries)
+
+ entries = []
+ for prop in proposals:
+ entries.append(formatSummaryEntry(prop))
+ format_inputs["SUMMARY_TABLE"] = "".join(entries)
+
+ for s in STATUSES:
+ entries = []
+ for prop in proposals:
+ if s == prop['Status']:
+ entries.append(formatMarkdownEntry(prop))
+ if entries:
+ format_inputs[s] = "".join(entries)
+ else:
+ format_inputs[s] = "(There are no proposals in this category)\n"
+
+ entries = []
+ for prop in proposals:
+ if prop['Status'] in ('DEAD', 'REJECTED', 'OBSOLETE'):
+ entries.append(formatMarkdownEntry(prop, withStatus=True))
+ format_inputs['DEAD_REJECTED_OBSOLETE'] = "".join(entries)
+
+ for prefix in markdown_files:
+ writeMarkdownFile(prefix, format_inputs)
+
+if __name__ == '__main__':
+ proposal_dir = os.path.join(os.path.dirname(sys.argv[0]), "..", "proposals")
+ os.chdir(proposal_dir)
+
+ proposals = readProposals()
+ try:
+ writeTextIndexFile(proposals)
+ writeMarkdownIndexFiles(proposals)
+ finally:
+ for tempfile in TEMPFILES:
+ unlink_if_present(tempfile)
diff --git a/bin/via-cargo-install-in-ci b/bin/via-cargo-install-in-ci
new file mode 100755
index 0000000..c104ff9
--- /dev/null
+++ b/bin/via-cargo-install-in-ci
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+# Bump this to "clear" the cache.
+# Actually, it just causes us to ignore previous cached results.
+cache_clear_token=2023-09-11
+
+cache_dir=cache/"$CI_JOB_IMAGE","$cache_clear_token"
+
+mkdir -p "$cache_dir"
+
+for cmd in "$@"; do
+ cache="$cache_dir/$cmd"
+
+ if cp "$cache" "$CARGO_HOME"/bin/; then continue; fi
+
+ cargo install --locked "$cmd"
+ cp -v "$CARGO_HOME/bin/$cmd" "$cache"
+done
diff --git a/bin/via-yarn-install-in-ci b/bin/via-yarn-install-in-ci
new file mode 100755
index 0000000..5aa9fcb
--- /dev/null
+++ b/bin/via-yarn-install-in-ci
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+set -x
+
+# usage:
+# bin/via-yarn-install-in-ci COMMAND GIT-URL-FOR-PACKAGE COMMITID
+#
+# We demand a commitid to mitigate the security risks of npm
+
+command="$1"
+git_url="$2"
+commitid="$3"
+
+# Bump this to "clear" the cache.
+# Actually, it just causes us to ignore previous cached results.
+cache_clear_token=2023-11-09c
+
+cache_dir=cache/"$CI_JOB_IMAGE","$cache_clear_token","$command","$commitid"
+local_dir="yarn-build,$command"
+
+mkdir -p "$local_dir"
+
+if test -d "$cache_dir"/; then
+ cp -al "$cache_dir"/. "$local_dir"/.
+
+ type -p node || apt-get install -y nodejs
+else
+
+ if [ -z "${YARN-}" ]; then
+ type -p yarnpkg || apt-get install -y yarnpkg
+ YARN=yarnpkg
+ fi
+
+ cd "$local_dir"
+ git clone "$git_url" "$command".git
+ cd "$command".git
+ git config advice.detachedHead false
+ git checkout "$commitid"
+
+ : ----- invoke yarn to build "$command": running -----
+ $YARN install --frozen-lockfile --non-interactive
+ : ----- invoke yarn to build "$command": complete -----
+
+ cd ../..
+ ls -al "$PWD"/"$local_dir"/"$command".git/src/cli.js
+
+ mkdir -p "$cache_dir"
+ cp -al "$local_dir"/. "$cache_dir"/.
+fi
+
+# We abuse $CARGO_HOME/bin.
+# The rust: CI images we're using have that on PATH.
+# If one were to run this outside CI, putting a symlink
+# to some NPM thing in ~/.cargo/bin doesn't seem terrible.
+
+ln -s "$PWD"/"$local_dir"/"$command".git/src/cli.js \
+ "$CARGO_HOME"/bin/"$command"