royalcat refactoring

This commit is contained in:
royalcat 2023-10-08 19:46:03 +03:00
parent 1da835cea6
commit b245c9f451
81 changed files with 1476 additions and 1580 deletions

View file

@ -5,7 +5,7 @@ on:
branches:
- master
tags:
- 'v*'
- "v*"
jobs:
main:
@ -18,7 +18,7 @@ jobs:
id: meta
uses: crazy-max/ghaction-docker-meta@v5.0.0
with:
images: distribyted/distribyted
images: tstor/tstor
tags: |
type=ref,event=branch
type=ref,event=pr
@ -52,4 +52,4 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: distribyted/distribyted
repository: tstor/tstor

View file

@ -5,72 +5,23 @@ on:
branches:
- master
tags:
- 'v*'
- "v*"
jobs:
mkdocs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
# git-revision-date-localized-plugin and mkdocs-rss-plugin need full git history depth
fetch-depth: 0
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- name: Set up Python
uses: actions/setup-python@v4
- uses: actions/cache@v3
with:
python-version: "3.x"
- uses: actions/cache@v3.3.2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
working-directory: ./mkdocs
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -r requirements.txt
- name: Build docs
working-directory: ./mkdocs
run: |
mkdocs build
# - name: Validate generated HTML files
# working-directory: ./mkdocs
# run: |
# docker run -v $(pwd):/test --rm wjdp/htmltest --conf .htmltest.yml
# On push to master or release branch, deploy docs
- name: Set up git author
run: |
remote_repo="https://${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
git config --global user.name "${GITHUB_ACTOR}"
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git remote rm origin
git remote add origin "${remote_repo}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy docs (Master)
if: github.ref == 'refs/heads/master'
working-directory: ./mkdocs
run: |
echo "${CUSTOM_DOMAIN}" > "${GITHUB_WORKSPACE}/mkdocs/docs/CNAME"
echo -e "User-agent: *\nDisallow: /v*.*/\nSitemap: https://${CUSTOM_DOMAIN}/sitemap.xml" > "${GITHUB_WORKSPACE}/mkdocs/docs/robots.txt"
git fetch origin gh-pages --verbose
mike deploy master dev --config-file "${GITHUB_WORKSPACE}/mkdocs/mkdocs.yml" --push --rebase
env:
CUSTOM_DOMAIN: distribyted.com
GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }}
- name: Deploy docs (Versions)
env:
GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }}
if: startsWith(github.ref, 'refs/tags/v')
run: |
git fetch origin gh-pages --verbose
mike deploy ${GITHUB_REF##*/} latest --config-file "${GITHUB_WORKSPACE}/mkdocs/mkdocs.yml" --push --rebase --update-aliases
mkdocs-material-
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force

3
.gitignore vendored
View file

@ -1,4 +1,5 @@
distribyted-data
tstor-data
httpfs_vfsdata.go
bin/
coverage.out
bin

16
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/tstor/main.go",
"cwd": "${workspaceFolder}/bin",
}
]
}

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"yaml.schemas": {
"https://json.schemastore.org/github-workflow.json": "file:///home/royalcat/projects/distribyted/.github/workflows/mkdocs.yml"
}
}

View file

@ -4,7 +4,7 @@
FROM golang:1.20-alpine as builder
ENV BIN_REPO=github.com/distribyted/distribyted
ENV BIN_REPO=git.kmsign.ru/royalcat/tstor
ENV BIN_PATH=$GOPATH/src/$BIN_REPO
COPY . $BIN_PATH
@ -12,7 +12,7 @@ WORKDIR $BIN_PATH
RUN apk add fuse-dev git gcc libc-dev g++ make
RUN BIN_OUTPUT=/bin/distribyted make build
RUN BIN_OUTPUT=/bin/tstor make build
#===============
# Stage 2: Run
@ -22,12 +22,12 @@ FROM alpine:3
RUN apk add gcc libc-dev fuse-dev
COPY --from=builder /bin/distribyted /bin/distribyted
RUN chmod +x /bin/distribyted
COPY --from=builder /bin/tstor /bin/tstor
RUN chmod +x /bin/tstor
RUN mkdir /distribyted-data
RUN mkdir /tstor-data
RUN echo "user_allow_other" >> /etc/fuse.conf
ENV DISTRIBYTED_FUSE_ALLOW_OTHER=true
ENV tstor_FUSE_ALLOW_OTHER=true
ENTRYPOINT ["./bin/distribyted"]
ENTRYPOINT ["./bin/tstor"]

View file

@ -2,7 +2,7 @@
VERSION := $(shell git describe --tags)
BUILD := $(shell git rev-parse --short HEAD)
BIN_OUTPUT ?= bin/distribyted-$(VERSION)-`go env GOOS`-`go env GOARCH``go env GOEXE`
BIN_OUTPUT ?= bin/tstor-$(VERSION)-`go env GOOS`-`go env GOARCH``go env GOEXE`
PROJECTNAME := $(shell basename "$(PWD)")
# Use linker flags to provide version/build settings
@ -13,7 +13,7 @@ MAKEFLAGS += --silent
## run: run from code.
run:
go run cmd/distribyted/main.go examples/conf_example.yaml
go run cmd/tstor/main.go examples/conf_example.yaml
## build: build binary.
build: go-generate go-build
@ -28,7 +28,7 @@ test:
go-build:
@echo " > Building binary on $(BIN_OUTPUT)..."
go build -o $(BIN_OUTPUT) -tags "release" -ldflags='$(LDFLAGS)' cmd/distribyted/main.go
go build -o $(BIN_OUTPUT) -tags "release" -ldflags='$(LDFLAGS)' cmd/tstor/main.go
go-generate:
@echo " > Generating code files..."

View file

@ -6,35 +6,36 @@
[![GPL3 License][license-shield]][license-url]
[![Coveralls][coveralls-shield]][coveralls-url]
[![Docker Image][docker-pulls-shield]][docker-pulls-url]
<!-- PROJECT LOGO -->
<br />
<p align="center">
<a href="https://github.com/distribyted/distribyted">
<img src="mkdocs/docs/images/distribyted_icon.png" alt="Logo" width="100">
<a href="https://git.kmsign.ru/royalcat/tstor">
<img src="mkdocs/docs/images/tstor_icon.png" alt="Logo" width="100">
</a>
<h3 align="center">distribyted</h3>
<h3 align="center">tstor</h3>
<p align="center">
Torrent client with on-demand file downloading as a filesystem.
<br />
<br />
<a href="https://github.com/distribyted/distribyted/issues">Report a Bug</a>
<a href="https://git.kmsign.ru/royalcat/tstor/issues">Report a Bug</a>
·
<a href="https://github.com/distribyted/distribyted/issues">Request Feature</a>
<a href="https://git.kmsign.ru/royalcat/tstor/issues">Request Feature</a>
</p>
</p>
## About The Project
![Distribyted Screen Shot][product-screenshot]
![tstor Screen Shot][product-screenshot]
Distribyted is an alternative torrent client.
tstor is an alternative torrent client.
It can expose torrent files as a standard FUSE, webDAV or HTTP endpoint and download them on demand, allowing random reads using a fixed amount of disk space.
Distribyted tries to make easier integrations with other applications using torrent files, presenting them as a standard filesystem.
tstor tries to make easier integrations with other applications using torrent files, presenting them as a standard filesystem.
**Note that distribyted is in beta version, it is a proof of concept with a lot of bugs.**
**Note that tstor is in beta version, it is a proof of concept with a lot of bugs.**
## Use Cases
@ -52,7 +53,8 @@ Check [here][main-url] for further documentation.
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
Some areas need more care than others:
- Windows and macOS tests and compatibility. I don't have any easy way to test distribyted on these operating systems.
- Windows and macOS tests and compatibility. I don't have any easy way to test tstor on these operating systems.
- Web interface. Web development is not my _forte_.
- Tutorials. Share with the community your use case!
@ -62,7 +64,6 @@ Some areas need more care than others:
- [Nwaples rardecode library, experimental branch][rardecode-repo-url]. The only go library that is able to seek over rar files and avoid to use `io.Discard`.
- [Bodgit 7zip library][sevenzip-repo-url]. Amazing library to decode 7zip files.
## License
Distributed under the GPL3 license. See `LICENSE` for more information.
@ -70,23 +71,23 @@ Distributed under the GPL3 license. See `LICENSE` for more information.
[sevenzip-repo-url]: https://github.com/bodgit/sevenzip
[rardecode-repo-url]: https://github.com/nwaples/rardecode/tree/experimental
[torrent-repo-url]: https://github.com/anacrolix/torrent
[main-url]: https://distribyted.com
[releases-shield]: https://img.shields.io/github/v/release/distribyted/distribyted.svg?style=flat-square
[releases-url]: https://github.com/distribyted/distribyted/releases
[docker-pulls-shield]:https://img.shields.io/docker/pulls/distribyted/distribyted.svg?style=flat-square
[docker-pulls-url]:https://hub.docker.com/r/distribyted/distribyted
[contributors-shield]: https://img.shields.io/github/contributors/distribyted/distribyted.svg?style=flat-square
[contributors-url]: https://github.com/distribyted/distribyted/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/distribyted/distribyted.svg?style=flat-square
[forks-url]: https://github.com/distribyted/distribyted/network/members
[stars-shield]: https://img.shields.io/github/stars/distribyted/distribyted.svg?style=flat-square
[stars-url]: https://github.com/distribyted/distribyted/stargazers
[issues-shield]: https://img.shields.io/github/issues/distribyted/distribyted.svg?style=flat-square
[issues-url]: https://github.com/distribyted/distribyted/issues
[releases-url]: https://github.com/distribyted/distribyted/releases
[license-shield]: https://img.shields.io/github/license/distribyted/distribyted.svg?style=flat-square
[license-url]: https://github.com/distribyted/distribyted/blob/master/LICENSE
[product-screenshot]: mkdocs/docs/images/distribyted.gif
[example-config]: https://github.com/distribyted/distribyted/blob/master/examples/conf_example.yaml
[coveralls-shield]: https://img.shields.io/coveralls/github/distribyted/distribyted?style=flat-square
[coveralls-url]: https://coveralls.io/github/distribyted/distribyted
[main-url]: https://tstor.com
[releases-shield]: https://img.shields.io/github/v/release/tstor/tstor.svg?style=flat-square
[releases-url]: https://git.kmsign.ru/royalcat/tstor/releases
[docker-pulls-shield]: https://img.shields.io/docker/pulls/tstor/tstor.svg?style=flat-square
[docker-pulls-url]: https://hub.docker.com/r/tstor/tstor
[contributors-shield]: https://img.shields.io/github/contributors/tstor/tstor.svg?style=flat-square
[contributors-url]: https://git.kmsign.ru/royalcat/tstor/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/tstor/tstor.svg?style=flat-square
[forks-url]: https://git.kmsign.ru/royalcat/tstor/network/members
[stars-shield]: https://img.shields.io/github/stars/tstor/tstor.svg?style=flat-square
[stars-url]: https://git.kmsign.ru/royalcat/tstor/stargazers
[issues-shield]: https://img.shields.io/github/issues/tstor/tstor.svg?style=flat-square
[issues-url]: https://git.kmsign.ru/royalcat/tstor/issues
[releases-url]: https://git.kmsign.ru/royalcat/tstor/releases
[license-shield]: https://img.shields.io/github/license/tstor/tstor.svg?style=flat-square
[license-url]: https://git.kmsign.ru/royalcat/tstor/blob/master/LICENSE
[product-screenshot]: mkdocs/docs/images/tstor.gif
[example-config]: https://git.kmsign.ru/royalcat/tstor/blob/master/examples/conf_example.yaml
[coveralls-shield]: https://img.shields.io/coveralls/github/tstor/tstor?style=flat-square
[coveralls-url]: https://coveralls.io/github/tstor/tstor

View file

@ -1,15 +1,13 @@
Handlebars.registerHelper('ibytes', function (bytesSec, timePassed) {
Handlebars.registerHelper("ibytes", function (bytesSec, timePassed) {
return Humanize.ibytes(bytesSec / timePassed, 1024);
});
Handlebars.registerHelper('bytes', function (bytes) {
Handlebars.registerHelper("bytes", function (bytes) {
return Humanize.bytes(bytes, 1024);
});
var tstor = tstor || {};
var Distribyted = Distribyted || {};
Distribyted.message = {
tstor.message = {
_toastr: function () {
toastr.options = {
closeButton: true,
@ -26,21 +24,20 @@ Distribyted.message = {
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
hideMethod: "fadeOut",
};
return toastr;
},
error: function (message) {
this._toastr().error(message);
},
info: function (message) {
this._toastr().info(message);
}
}
},
};
$(document).ready(function () {
"use strict";
@ -48,17 +45,16 @@ $(document).ready(function () {
/*======== 1. SCROLLBAR SIDEBAR ========*/
var sidebarScrollbar = $(".sidebar-scrollbar");
if (sidebarScrollbar.length != 0) {
sidebarScrollbar.slimScroll({
sidebarScrollbar
.slimScroll({
opacity: 0,
height: "100%",
color: "#808080",
size: "5px",
touchScrollStep: 50
touchScrollStep: 50,
})
.mouseover(function () {
$(this)
.next(".slimScrollBar")
.css("opacity", 0.5);
$(this).next(".slimScrollBar").css("opacity", 0.5);
});
}
@ -66,30 +62,31 @@ $(document).ready(function () {
if ($(window).width() < 768) {
$(".sidebar-toggle").on("click", function () {
$("body").css("overflow", "hidden");
$('body').prepend('<div class="mobile-sticky-body-overlay"></div>')
$("body").prepend('<div class="mobile-sticky-body-overlay"></div>');
});
$(document).on("click", '.mobile-sticky-body-overlay', function (e) {
$(document).on("click", ".mobile-sticky-body-overlay", function (e) {
$(this).remove();
$("#body").removeClass("sidebar-mobile-in").addClass("sidebar-mobile-out");
$("#body")
.removeClass("sidebar-mobile-in")
.addClass("sidebar-mobile-out");
$("body").css("overflow", "auto");
});
}
/*======== 3. SIDEBAR MENU ========*/
var sidebar = $(".sidebar")
var sidebar = $(".sidebar");
if (sidebar.length != 0) {
$(".sidebar .nav > .has-sub > a").click(function () {
$(this).parent().siblings().removeClass('expand')
$(this).parent().toggleClass('expand')
})
$(this).parent().siblings().removeClass("expand");
$(this).parent().toggleClass("expand");
});
$(".sidebar .nav > .has-sub .has-sub > a").click(function () {
$(this).parent().toggleClass('expand')
})
$(this).parent().toggleClass("expand");
});
}
/*======== 4. SIDEBAR TOGGLE FOR MOBILE ========*/
if ($(window).width() < 768) {
$(document).on("click", ".sidebar-toggle", function (e) {
@ -98,19 +95,14 @@ $(document).ready(function () {
min_out = "sidebar-mobile-out",
body = "#body";
$(body).hasClass(min)
? $(body)
.removeClass(min)
.addClass(min_out)
: $(body)
.addClass(min)
.removeClass(min_out)
? $(body).removeClass(min).addClass(min_out)
: $(body).addClass(min).removeClass(min_out);
});
}
/*======== 5. SIDEBAR TOGGLE FOR VARIOUS SIDEBAR LAYOUT ========*/
var body = $("#body");
if ($(window).width() >= 768) {
if (typeof window.isMinified === "undefined") {
window.isMinified = false;
}
@ -140,10 +132,7 @@ $(document).ready(function () {
}
}
if (
body.hasClass("sidebar-fixed") ||
body.hasClass("sidebar-static")
) {
if (body.hasClass("sidebar-fixed") || body.hasClass("sidebar-static")) {
$(this)
.addClass("sidebar-toggle")
.removeClass("sidebar-offcanvas-toggle");
@ -163,10 +152,7 @@ $(document).ready(function () {
}
if ($(window).width() >= 768 && $(window).width() < 992) {
if (
body.hasClass("sidebar-fixed") ||
body.hasClass("sidebar-static")
) {
if (body.hasClass("sidebar-fixed") || body.hasClass("sidebar-static")) {
body
.removeClass("sidebar-collapse sidebar-minified-out")
.addClass("sidebar-minified");

View file

@ -1,10 +1,10 @@
Distribyted.config = {
tstor.config = {
_editor: null,
_infoDiv: document.getElementById("distribyted-reload-info-text"),
_loadingInfoDom: document.getElementById("distribyted-reload-info-loading"),
_infoDiv: document.getElementById("tstor-reload-info-text"),
_loadingInfoDom: document.getElementById("tstor-reload-info-loading"),
_valid: function () {
if (this._editor == null) {
return false
return false;
}
let getYamlCodeValidationErrors = (code) => {
@ -44,15 +44,17 @@ Distribyted.config = {
})
.then(function (response) {
if (response.ok) {
Distribyted.message.info("Configuration saved");
tstor.message.info("Configuration saved");
} else {
Distribyted.message.error(
tstor.message.error(
"Error saving configuration file. Response: " + response.status
);
}
})
.catch(function (error) {
Distribyted.message.error("Error saving configuration file: " + error.message);
tstor.message.error(
"Error saving configuration file: " + error.message
);
});
},
@ -65,20 +67,23 @@ Distribyted.config = {
if (response.ok) {
return response.json();
} else {
Distribyted.config.showInfo("Error reloading server. Response: " + response.status, "ko");
tstor.config.showInfo(
"Error reloading server. Response: " + response.status,
"ko"
);
}
})
.then(function (json) {
Distribyted.config.showInfo(json.message, "ok");
tstor.config.showInfo(json.message, "ok");
})
.catch(function (error) {
Distribyted.message.error("Error reloading server: " + error.message);
tstor.message.error("Error reloading server: " + error.message);
});
},
cleanInfo: function () {
this._loadingInfoDom.style.display = "block";
this._infoDiv.innerText = ""
this._infoDiv.innerText = "";
},
showInfo: function (message, flag) {
@ -117,17 +122,17 @@ Distribyted.config = {
name: "save",
bindKey: { win: "Ctrl-S", mac: "Command-S" },
exec: function (editor) {
if (Distribyted.config._valid()) {
Distribyted.config.save();
if (tstor.config._valid()) {
tstor.config.save();
} else {
Distribyted.message.error("Check file format errors before saving");
tstor.message.error("Check file format errors before saving");
}
},
readOnly: false,
});
this._editor.on("change", () => {
Distribyted.config._valid();
tstor.config._valid();
});
fetch("/api/config")
@ -135,23 +140,21 @@ Distribyted.config = {
if (response.ok) {
return response.text();
} else {
Distribyted.message.error(
tstor.message.error(
"Error getting data from server. Response: " + response.status
);
}
})
.then(function (yaml) {
Distribyted.config._editor.setValue(yaml);
tstor.config._editor.setValue(yaml);
})
.catch(function (error) {
Distribyted.message.error("Error getting yaml from server: " + error.message);
tstor.message.error("Error getting yaml from server: " + error.message);
});
var stream = new EventSource("/api/events");
stream.addEventListener("event", function (e) {
Distribyted.config.showInfo(e.data);
tstor.config.showInfo(e.data);
});
}
}
},
};

View file

@ -1,22 +1,30 @@
GeneralChart.init();
Distribyted.dashboard = {
tstor.dashboard = {
_cacheChart: new CacheChart("main-cache-chart", "Cache disk"),
loadView: function () {
fetch('/api/status')
fetch("/api/status")
.then(function (response) {
if (response.ok) {
return response.json();
} else {
Distribyted.message.error('Error getting data from server. Response: ' + response.status)
tstor.message.error(
"Error getting data from server. Response: " + response.status
);
}
}).then(function (stats) {
var download = stats.torrentStats.downloadedBytes / stats.torrentStats.timePassed;
var upload = stats.torrentStats.uploadedBytes / stats.torrentStats.timePassed;
})
.then(function (stats) {
var download =
stats.torrentStats.downloadedBytes / stats.torrentStats.timePassed;
var upload =
stats.torrentStats.uploadedBytes / stats.torrentStats.timePassed;
GeneralChart.update(download, upload);
Distribyted.dashboard._cacheChart.update(stats.cacheFilled, stats.cacheCapacity - stats.cacheFilled);
tstor.dashboard._cacheChart.update(
stats.cacheFilled,
stats.cacheCapacity - stats.cacheFilled
);
document.getElementById("general-download-speed").innerText =
Humanize.ibytes(download, 1024) + "/s";
@ -25,7 +33,7 @@ Distribyted.dashboard = {
Humanize.ibytes(upload, 1024) + "/s";
})
.catch(function (error) {
Distribyted.message.error('Error getting status info: ' + error.message)
tstor.message.error("Error getting status info: " + error.message);
});
}
}
},
};

View file

@ -1,59 +1,77 @@
Distribyted.logs = {
tstor.logs = {
loadView: function () {
fetch("/api/log")
.then(response => {
.then((response) => {
if (response.ok) {
return response.body.getReader();
} else {
response.json().then(json => {
Distribyted.message.error('Error getting logs from server. Error: ' + json.error);
}).catch(error => {
Distribyted.message.error('Error getting logs from server. Error: ' + error);
response
.json()
.then((json) => {
tstor.message.error(
"Error getting logs from server. Error: " + json.error
);
})
.catch((error) => {
tstor.message.error(
"Error getting logs from server. Error: " + error
);
});
}
})
.then(reader => {
var decoder = new TextDecoder()
var lastString = ''
reader.read().then(function processText({ done, value }) {
.then((reader) => {
var decoder = new TextDecoder();
var lastString = "";
reader
.read()
.then(function processText({ done, value }) {
if (done) {
return;
}
const string = `${lastString}${decoder.decode(value)}`
const lines = string.split(/\r\n|[\r\n]/g)
this.lastString = lines.pop() || ''
const string = `${lastString}${decoder.decode(value)}`;
const lines = string.split(/\r\n|[\r\n]/g);
this.lastString = lines.pop() || "";
lines.forEach(element => {
lines.forEach((element) => {
try {
var json = JSON.parse(element)
var properties = ""
var json = JSON.parse(element);
var properties = "";
for (let [key, value] of Object.entries(json)) {
if (key == "level" || key == "component" || key == "message" || key == "time") {
continue
if (
key == "level" ||
key == "component" ||
key == "message" ||
key == "time"
) {
continue;
}
properties += `<b>${key}</b>=${value} `
properties += `<b>${key}</b>=${value} `;
}
var tableClass = "table-primary"
var tableClass = "table-primary";
switch (json.level) {
case "info":
tableClass = ""
tableClass = "";
break;
case "error":
tableClass = "table-danger"
tableClass = "table-danger";
break;
case "warn":
tableClass = "table-warning"
tableClass = "table-warning";
break;
case "debug":
tableClass = "table-info"
tableClass = "table-info";
break;
default:
break;
}
template = `<tr class="${tableClass}"><td>${new Date(json.time*1000).toLocaleString()}</td><td>${json.level}</td><td>${json.component}</td><td>${json.message}</td><td>${properties}</td></tr>`;
template = `<tr class="${tableClass}"><td>${new Date(
json.time * 1000
).toLocaleString()}</td><td>${json.level}</td><td>${
json.component
}</td><td>${json.message}</td><td>${properties}</td></tr>`;
document.getElementById("log_table").innerHTML += template;
} catch (err) {
// server can send some corrupted json line
@ -61,9 +79,10 @@ Distribyted.logs = {
}
});
return reader.read().then(processText);
}).catch(err => console.log(err));
}).catch(err => console.log(err));
}
}
})
.catch((err) => console.log(err));
})
.catch((err) => console.log(err));
},
};

View file

@ -1,14 +1,14 @@
Handlebars.registerHelper("torrent_status", function (chunks, totalPieces) {
const pieceStatus = {
"H": { class: "bg-warning", tooltip: "checking pieces" },
"P": { class: "bg-info", tooltip: "" },
"C": { class: "bg-success", tooltip: "downloaded pieces" },
"W": { class: "bg-transparent" },
H: { class: "bg-warning", tooltip: "checking pieces" },
P: { class: "bg-info", tooltip: "" },
C: { class: "bg-success", tooltip: "downloaded pieces" },
W: { class: "bg-transparent" },
"?": { class: "bg-danger", tooltip: "erroed pieces" },
};
const chunksAsHTML = chunks.map(chunk => {
const percentage = totalPieces * chunk.numPieces / 100;
const pcMeta = pieceStatus[chunk.status]
const chunksAsHTML = chunks.map((chunk) => {
const percentage = (totalPieces * chunk.numPieces) / 100;
const pcMeta = pieceStatus[chunk.status];
const pieceStatusClass = pcMeta.class;
const pieceStatusTip = pcMeta.tooltip;
@ -27,7 +27,8 @@ Handlebars.registerHelper("torrent_status", function (chunks, totalPieces) {
return div.outerHTML;
});
return '<div class="progress mb-3">' + chunksAsHTML.join("\n"); + '</div>'
return '<div class="progress mb-3">' + chunksAsHTML.join("\n");
+"</div>";
});
Handlebars.registerHelper("torrent_info", function (peers, seeders, pieceSize) {
@ -36,7 +37,7 @@ Handlebars.registerHelper("torrent_info", function (peers, seeders, pieceSize) {
var messages = [];
var errorLevels = [];
const seedersMsg = "- Number of seeders is too low (" + seeders + ")."
const seedersMsg = "- Number of seeders is too low (" + seeders + ").";
if (seeders < 2) {
errorLevels[0] = 2;
messages.push(seedersMsg);
@ -47,10 +48,13 @@ Handlebars.registerHelper("torrent_info", function (peers, seeders, pieceSize) {
errorLevels[0] = 0;
}
const pieceSizeMsg = "- Piece size is too big (" + Humanize.bytes(pieceSize, 1024) + "). Recommended size is 1MB or less."
const pieceSizeMsg =
"- Piece size is too big (" +
Humanize.bytes(pieceSize, 1024) +
"). Recommended size is 1MB or less.";
if (pieceSize <= MB) {
errorLevels[1] = 0;
} else if (pieceSize > MB && pieceSize < (MB * 4)) {
} else if (pieceSize > MB && pieceSize < MB * 4) {
errorLevels[1] = 1;
messages.push(pieceSizeMsg);
} else {
@ -68,7 +72,9 @@ Handlebars.registerHelper("torrent_info", function (peers, seeders, pieceSize) {
i.className = "mdi " + icon[errIndex];
i.title = messages.join("\n");
const text = document.createTextNode(peers + "/" + seeders + " (" + Humanize.bytes(pieceSize, 1024) + " chunks) ");
const text = document.createTextNode(
peers + "/" + seeders + " (" + Humanize.bytes(pieceSize, 1024) + " chunks) "
);
div.className = level[errIndex];
div.appendChild(text);
@ -77,27 +83,29 @@ Handlebars.registerHelper("torrent_info", function (peers, seeders, pieceSize) {
return div.outerHTML;
});
Distribyted.routes = {
tstor.routes = {
_template: null,
_getTemplate: function () {
if (this._template != null) {
return this._template
return this._template;
}
const tTemplate = fetch('/assets/templates/routes.html')
const tTemplate = fetch("/assets/templates/routes.html")
.then((response) => {
if (response.ok) {
return response.text();
} else {
Distribyted.message.error('Error getting data from server. Response: ' + response.status);
tstor.message.error(
"Error getting data from server. Response: " + response.status
);
}
})
.then((t) => {
return Handlebars.compile(t);
})
.catch(error => {
Distribyted.message.error('Error getting routes template: ' + error.message);
.catch((error) => {
tstor.message.error("Error getting routes template: " + error.message);
});
this._template = tTemplate;
@ -105,82 +113,92 @@ Distribyted.routes = {
},
_getRoutesJson: function () {
return fetch('/api/routes')
return fetch("/api/routes")
.then(function (response) {
if (response.ok) {
return response.json();
} else {
Distribyted.message.error('Error getting data from server. Response: ' + response.status)
tstor.message.error(
"Error getting data from server. Response: " + response.status
);
}
}).then(function (routes) {
})
.then(function (routes) {
return routes;
})
.catch(function (error) {
Distribyted.message.error('Error getting status info: ' + error.message)
tstor.message.error("Error getting status info: " + error.message);
});
},
deleteTorrent: function (route, torrentHash) {
var url = '/api/routes/' + route + '/torrent/' + torrentHash
var url = "/api/routes/" + route + "/torrent/" + torrentHash;
return fetch(url, {
method: 'DELETE'
method: "DELETE",
})
.then(function (response) {
if (response.ok) {
Distribyted.message.info('Torrent deleted.')
Distribyted.routes.loadView();
tstor.message.info("Torrent deleted.");
tstor.routes.loadView();
} else {
response.json().then(json => {
Distribyted.message.error('Error deletting torrent. Response: ' + json.error)
})
response.json().then((json) => {
tstor.message.error(
"Error deletting torrent. Response: " + json.error
);
});
}
})
.catch(function (error) {
Distribyted.message.error('Error deletting torrent: ' + error.message)
tstor.message.error("Error deletting torrent: " + error.message);
});
},
loadView: function () {
this._getTemplate()
.then(t =>
this._getRoutesJson().then(routes => {
document.getElementById('template_target').innerHTML = t(routes);
this._getTemplate().then((t) =>
this._getRoutesJson().then((routes) => {
document.getElementById("template_target").innerHTML = t(routes);
})
);
}
}
},
};
$("#new-magnet").submit(function (event) {
event.preventDefault();
let route = $("#route-string :selected").val()
let magnet = $("#magnet-url").val()
let route = $("#route-string :selected").val();
let magnet = $("#magnet-url").val();
let url = '/api/routes/' + route + '/torrent'
let body = JSON.stringify({ magnet: magnet })
let url = "/api/routes/" + route + "/torrent";
let body = JSON.stringify({ magnet: magnet });
document.getElementById("submit_magnet_loading").style = "display:block"
document.getElementById("submit_magnet_loading").style = "display:block";
fetch(url, {
method: 'POST',
body: body
method: "POST",
body: body,
})
.then(function (response) {
if (response.ok) {
Distribyted.message.info('New magnet added.')
Distribyted.routes.loadView();
tstor.message.info("New magnet added.");
tstor.routes.loadView();
} else {
response.json().then(json => {
Distribyted.message.error('Error adding new magnet. Response: ' + json.error)
}).catch(function (error) {
Distribyted.message.error('Error adding new magnet: ' + response.status)
response
.json()
.then((json) => {
tstor.message.error(
"Error adding new magnet. Response: " + json.error
);
})
.catch(function (error) {
tstor.message.error("Error adding new magnet: " + response.status);
});
}
})
.catch(function (error) {
Distribyted.message.error('Error adding torrent: ' + error.message)
}).then(function () {
document.getElementById("submit_magnet_loading").style = "display:none"
tstor.message.error("Error adding torrent: " + error.message);
})
.then(function () {
document.getElementById("submit_magnet_loading").style = "display:none";
});
});

View file

@ -1,28 +1,30 @@
Handlebars.registerHelper("to_date", function (timestamp) {
return new Date(timestamp * 1000).toLocaleString()
return new Date(timestamp * 1000).toLocaleString();
});
Distribyted.servers = {
tstor.servers = {
_template: null,
_getTemplate: function () {
if (this._template != null) {
return this._template
return this._template;
}
const tTemplate = fetch('/assets/templates/servers.html')
const tTemplate = fetch("/assets/templates/servers.html")
.then((response) => {
if (response.ok) {
return response.text();
} else {
Distribyted.message.error('Error getting data from server. Response: ' + response.status);
tstor.message.error(
"Error getting data from server. Response: " + response.status
);
}
})
.then((t) => {
return Handlebars.compile(t);
})
.catch(error => {
Distribyted.message.error('Error getting servers template: ' + error.message);
.catch((error) => {
tstor.message.error("Error getting servers template: " + error.message);
});
this._template = tTemplate;
@ -30,25 +32,26 @@ Distribyted.servers = {
},
_getRoutesJson: function () {
return fetch('/api/servers')
return fetch("/api/servers")
.then(function (response) {
if (response.ok) {
return response.json();
} else {
Distribyted.message.error('Error getting data from server. Response: ' + response.status)
tstor.message.error(
"Error getting data from server. Response: " + response.status
);
}
})
.catch(function (error) {
Distribyted.message.error('Error getting status info: ' + error.message)
tstor.message.error("Error getting status info: " + error.message);
});
},
loadView: function () {
this._getTemplate()
.then(t =>
this._getRoutesJson().then(routes => {
document.getElementById('template_target').innerHTML = t(routes);
this._getTemplate().then((t) =>
this._getRoutesJson().then((routes) => {
document.getElementById("template_target").innerHTML = t(routes);
})
);
}
}
},
};

View file

@ -2,17 +2,26 @@
<div class="row">
<div class="col-12">
<div class="card card-table-border-none">
<div class="card-header justify-content-between card-header-border-bottom">
<div
class="card-header justify-content-between card-header-border-bottom"
>
<h2>Route: {{name}}</h2>
</div>
<div class="card-body pt-0 pb-5">
<table class="table card-table table-responsive table-responsive-large" style="width:100%">
<table
class="table card-table table-responsive table-responsive-large"
style="width: 100%"
>
<thead>
<tr>
<th style="width: 30%">Name</th>
<th style="width: 15%"><i class="mdi mdi-arrow-down"></i> / <i class="mdi mdi-arrow-up"></i>
<th style="width: 15%">
<i class="mdi mdi-arrow-down"></i> /
<i class="mdi mdi-arrow-up"></i>
</th>
<th style="width: 15%" class="d-none d-lg-table-cell">
Peers/Seeders
</th>
<th style="width: 15%" class="d-none d-lg-table-cell">Peers/Seeders</th>
<th style="width: 35%" class="d-none d-lg-table-cell">Status</th>
<th style="width: 5%">Actions</th>
</tr>
@ -21,13 +30,23 @@
{{#torrentStats}}
<tr>
<td>{{name}}</td>
<td>{{ibytes downloadedBytes timePassed}} / {{ibytes
uploadedBytes timePassed}}</td>
<td class="d-none d-lg-table-cell">{{{torrent_info peers seeders pieceSize}}}</td>
<td>
{{ibytes downloadedBytes timePassed}} / {{ibytes uploadedBytes
timePassed}}
</td>
<td class="d-none d-lg-table-cell">
{{{torrent_info peers seeders pieceSize}}}
</td>
<td class="d-none d-lg-table-cell">
{{{torrent_status pieceChunks totalPieces}}}
</td>
<td><i class="mdi mdi-delete-forever" title="delete torrent" onclick='Distribyted.routes.deleteTorrent("{{../name}}","{{hash}}")'></i></td>
<td>
<i
class="mdi mdi-delete-forever"
title="delete torrent"
onclick='tstor.routes.deleteTorrent("{{../name}}","{{hash}}")'
></i>
</td>
</tr>
{{/torrentStats}}
</tbody>

View file

@ -10,19 +10,19 @@ import (
"syscall"
"time"
"github.com/anacrolix/missinggo/v2/filecache"
"git.kmsign.ru/royalcat/tstor/src/config"
"github.com/anacrolix/torrent/storage"
"github.com/distribyted/distribyted/config"
"github.com/distribyted/distribyted/fs"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
"github.com/distribyted/distribyted/fuse"
"github.com/distribyted/distribyted/http"
dlog "github.com/distribyted/distribyted/log"
"github.com/distribyted/distribyted/torrent"
"github.com/distribyted/distribyted/torrent/loader"
"github.com/distribyted/distribyted/webdav"
"git.kmsign.ru/royalcat/tstor/src/fs"
"git.kmsign.ru/royalcat/tstor/src/http"
dlog "git.kmsign.ru/royalcat/tstor/src/log"
"git.kmsign.ru/royalcat/tstor/src/mounts/fuse"
"git.kmsign.ru/royalcat/tstor/src/mounts/httpfs"
"git.kmsign.ru/royalcat/tstor/src/mounts/webdav"
"git.kmsign.ru/royalcat/tstor/src/torrent"
"git.kmsign.ru/royalcat/tstor/src/torrent/loader"
)
const (
@ -34,32 +34,13 @@ const (
func main() {
app := &cli.App{
Name: "distribyted",
Name: "tstor",
Usage: "Torrent client with on-demand file downloading as a filesystem.",
Flags: []cli.Flag{
&cli.StringFlag{
Name: configFlag,
Value: "./distribyted-data/config/config.yaml",
EnvVars: []string{"DISTRIBYTED_CONFIG"},
Usage: "YAML file containing distribyted configuration.",
},
&cli.IntFlag{
Name: portFlag,
Value: 4444,
EnvVars: []string{"DISTRIBYTED_HTTP_PORT"},
Usage: "HTTP port for web interface.",
},
&cli.IntFlag{
Name: webDAVPortFlag,
Value: 36911,
EnvVars: []string{"DISTRIBYTED_WEBDAV_PORT"},
Usage: "Port used for WebDAV interface.",
},
&cli.BoolFlag{
Name: fuseAllowOther,
Value: false,
EnvVars: []string{"DISTRIBYTED_FUSE_ALLOW_OTHER"},
Usage: "Allow other users to access all fuse mountpoints. You need to add user_allow_other flag to /etc/fuse.conf file.",
Value: "./config.yaml",
Usage: "YAML file containing tstor configuration.",
},
},
@ -84,81 +65,93 @@ func main() {
}
}
func load(configPath string, port, webDAVPort int, fuseAllowOther bool) error {
ch := config.NewHandler(configPath)
func setupStorage(tcfg config.TorrentClient) (storage.ClientImplCloser, storage.PieceCompletion, error) {
pcp := filepath.Join(tcfg.MetadataFolder, "piece-completion")
if err := os.MkdirAll(pcp, 0744); err != nil {
return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err)
}
pc, err := storage.NewBoltPieceCompletion(pcp)
if err != nil {
return nil, nil, fmt.Errorf("error creating servers piece completion: %w", err)
}
conf, err := ch.Get()
// TODO implement cache dir and storage capacity
// cacheDir := filepath.Join(tcfg.MetadataFolder, "cache")
// if err := os.MkdirAll(cacheDir, 0744); err != nil {
// return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err)
// }
// fc, err := filecache.NewCache(cacheDir)
// if err != nil {
// return nil, nil, fmt.Errorf("error creating cache: %w", err)
// }
// log.Info().Msg(fmt.Sprintf("setting cache size to %d MB", tcfg.GlobalCacheSize))
// fc.SetCapacity(tcfg.GlobalCacheSize * 1024 * 1024)
filesDir := filepath.Join(tcfg.MetadataFolder, "files")
if err := os.MkdirAll(pcp, 0744); err != nil {
return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err)
}
st := storage.NewFileWithCompletion(filesDir, pc)
return st, pc, nil
}
func load(configPath string, port, webDAVPort int, fuseAllowOther bool) error {
conf, err := config.Load(configPath)
if err != nil {
return fmt.Errorf("error loading configuration: %w", err)
}
dlog.Load(conf.Log)
dlog.Load(&conf.Log)
if err := os.MkdirAll(conf.Torrent.MetadataFolder, 0744); err != nil {
if err := os.MkdirAll(conf.TorrentClient.MetadataFolder, 0744); err != nil {
return fmt.Errorf("error creating metadata folder: %w", err)
}
cf := filepath.Join(conf.Torrent.MetadataFolder, "cache")
fc, err := filecache.NewCache(cf)
if err != nil {
return fmt.Errorf("error creating cache: %w", err)
}
st := storage.NewResourcePieces(fc.AsResourceProvider())
// cache is not working with windows
if runtime.GOOS == "windows" {
st = storage.NewFile(cf)
}
fis, err := torrent.NewFileItemStore(filepath.Join(conf.Torrent.MetadataFolder, "items"), 2*time.Hour)
fis, err := torrent.NewFileItemStore(filepath.Join(conf.TorrentClient.MetadataFolder, "items"), 2*time.Hour)
if err != nil {
return fmt.Errorf("error starting item store: %w", err)
}
id, err := torrent.GetOrCreatePeerID(filepath.Join(conf.Torrent.MetadataFolder, "ID"))
id, err := torrent.GetOrCreatePeerID(filepath.Join(conf.TorrentClient.MetadataFolder, "ID"))
if err != nil {
return fmt.Errorf("error creating node ID: %w", err)
}
c, err := torrent.NewClient(st, fis, conf.Torrent, id)
st, pc, err := setupStorage(conf.TorrentClient)
if err != nil {
return err
}
c, err := torrent.NewClient(st, fis, &conf.TorrentClient, id)
if err != nil {
return fmt.Errorf("error starting torrent client: %w", err)
}
pcp := filepath.Join(conf.Torrent.MetadataFolder, "piece-completion")
if err := os.MkdirAll(pcp, 0744); err != nil {
return fmt.Errorf("error creating piece completion folder: %w", err)
}
pc, err := storage.NewBoltPieceCompletion(pcp)
if err != nil {
return fmt.Errorf("error creating servers piece completion: %w", err)
}
var servers []*torrent.Server
for _, s := range conf.Servers {
server := torrent.NewServer(c, pc, s)
for _, s := range conf.TorrentClient.Servers {
server := torrent.NewServer(c, pc, &s)
servers = append(servers, server)
if err := server.Start(); err != nil {
return fmt.Errorf("error starting server: %w", err)
}
}
cl := loader.NewConfig(conf.Routes)
fl := loader.NewFolder(conf.Routes)
cl := loader.NewConfig(conf.TorrentClient.Routes)
fl := loader.NewFolder(conf.TorrentClient.Routes)
ss := torrent.NewStats()
dbl, err := loader.NewDB(filepath.Join(conf.Torrent.MetadataFolder, "magnetdb"))
dbl, err := loader.NewDB(filepath.Join(conf.TorrentClient.MetadataFolder, "magnetdb"))
if err != nil {
return fmt.Errorf("error starting magnet database: %w", err)
}
ts := torrent.NewService([]loader.Loader{cl, fl}, dbl, ss, c, conf.Torrent.AddTimeout, conf.Torrent.ReadTimeout)
ts := torrent.NewService([]loader.Loader{cl, fl}, dbl, ss, c, conf.TorrentClient.AddTimeout, conf.TorrentClient.ReadTimeout)
var mh *fuse.Handler
if conf.Fuse != nil {
mh = fuse.NewHandler(fuseAllowOther || conf.Fuse.AllowOther, conf.Fuse.Path)
if conf.Mounts.Fuse.Enabled {
mh = fuse.NewHandler(conf.Mounts.Fuse.AllowOther, conf.Mounts.Fuse.Path)
}
sigChan := make(chan os.Signal)
@ -188,9 +181,6 @@ func load(configPath string, port, webDAVPort int, fuseAllowOther bool) error {
os.Exit(1)
}()
log.Info().Msg(fmt.Sprintf("setting cache size to %d MB", conf.Torrent.GlobalCacheSize))
fc.SetCapacity(conf.Torrent.GlobalCacheSize * 1024 * 1024)
fss, err := ts.Load()
if err != nil {
return fmt.Errorf("error when loading torrents: %w", err)
@ -207,10 +197,10 @@ func load(configPath string, port, webDAVPort int, fuseAllowOther bool) error {
}()
go func() {
if conf.WebDAV != nil {
if conf.Mounts.WebDAV.Enabled {
port = webDAVPort
if port == 0 {
port = conf.WebDAV.Port
port = conf.Mounts.WebDAV.Port
}
cfs, err := fs.NewContainerFs(fss)
@ -219,7 +209,7 @@ func load(configPath string, port, webDAVPort int, fuseAllowOther bool) error {
return
}
if err := webdav.NewWebDAVServer(cfs, port, conf.WebDAV.User, conf.WebDAV.Pass); err != nil {
if err := webdav.NewWebDAVServer(cfs, port, conf.Mounts.WebDAV.User, conf.Mounts.WebDAV.Pass); err != nil {
log.Error().Err(err).Msg("error starting webDAV")
}
}
@ -232,10 +222,10 @@ func load(configPath string, port, webDAVPort int, fuseAllowOther bool) error {
return fmt.Errorf("error when loading torrents: %w", err)
}
httpfs := torrent.NewHTTPFS(cfs)
httpfs := httpfs.NewHTTPFS(cfs)
logFilename := filepath.Join(conf.Log.Path, dlog.FileName)
err = http.New(fc, ss, ts, ch, servers, httpfs, logFilename, conf.HTTPGlobal)
err = http.New(nil, ss, ts, conf, servers, httpfs, logFilename, conf)
log.Error().Err(err).Msg("error initializing HTTP server")
return err
}

View file

@ -1,83 +0,0 @@
package config
const (
m1 = "magnet:?xt=urn:btih:c9e15763f722f23e98a29decdfae341b98d53056&dn=Cosmos+Laundromat&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fcosmos-laundromat.torrent"
m2 = "magnet:?xt=urn:btih:dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c&dn=Big+Buck+Bunny&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fbig-buck-bunny.torrent"
m3 = "magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent"
m4 = "magnet:?xt=urn:btih:209c8226b299b308beaf2b9cd3fb49212dbd13ec&dn=Tears+of+Steel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Ftears-of-steel.torrent"
m5 = "magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent"
)
const (
metadataFolder = "./distribyted-data/metadata"
mountFolder = "./distribyted-data/mount"
logsFolder = "./distribyted-data/logs"
serverFolder = "./distribyted-data/served-folders/server"
)
func DefaultConfig() *Root {
return &Root{
HTTPGlobal: &HTTPGlobal{
Port: 4444,
IP: "0.0.0.0",
HTTPFS: true,
},
WebDAV: &WebDAVGlobal{
Port: 36911,
User: "admin",
Pass: "admin",
},
Torrent: &TorrentGlobal{
GlobalCacheSize: 2048,
MetadataFolder: metadataFolder,
AddTimeout: 60,
ReadTimeout: 120,
},
Fuse: &FuseGlobal{
AllowOther: false,
Path: mountFolder,
},
Log: &Log{
Path: logsFolder,
MaxBackups: 2,
MaxSize: 50,
},
Routes: []*Route{
{
Name: "multimedia",
Torrents: []*Torrent{
{
MagnetURI: m1,
},
{
MagnetURI: m2,
},
{
MagnetURI: m3,
},
{
MagnetURI: m4,
},
{
MagnetURI: m5,
},
},
},
},
Servers: []*Server{
{
Name: "server",
Path: serverFolder,
Trackers: []string{
"wss://tracker.btorrent.xyz",
"wss://tracker.openwebtorrent.com",
"http://p4p.arenabg.com:1337/announce",
"udp://tracker.opentrackr.org:1337/announce",
"udp://open.tracker.cl:1337/announce",
"http://openbittorrent.com:80/announce",
},
},
},
}
}

View file

@ -1,53 +0,0 @@
package config
import (
"io/ioutil"
"os"
"testing"
"github.com/goccy/go-yaml"
"github.com/stretchr/testify/require"
)
func TestTemplateConfig(t *testing.T) {
t.Parallel()
require := require.New(t)
f, err := os.Open("../templates/config_template.yaml")
require.NoError(err)
b, err := ioutil.ReadAll(f)
require.NoError(err)
conf := &Root{}
err = yaml.Unmarshal(b, conf)
require.NoError(err)
require.Equal(DefaultConfig(), conf)
}
func TestDefaults(t *testing.T) {
t.Parallel()
require := require.New(t)
r := &Root{}
dr := AddDefaults(r)
require.NotNil(dr)
// FUSE can be deactivated
require.Nil(dr.Fuse)
require.NotNil(dr.HTTPGlobal)
require.NotNil(dr.Log)
require.NotNil(dr.Torrent)
// Add defaults when fuse is set
r = &Root{
Fuse: &FuseGlobal{},
}
dr = AddDefaults(r)
require.NotNil(dr.Fuse)
require.Equal(mountFolder, dr.Fuse.Path)
}

View file

@ -1,70 +0,0 @@
package config
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/distribyted/distribyted"
"gopkg.in/yaml.v3"
)
type EventFunc func(event string)
type ReloadFunc func(*Root, EventFunc) error
type Handler struct {
p string
}
func NewHandler(path string) *Handler {
return &Handler{p: path}
}
func (c *Handler) createFromTemplateFile() ([]byte, error) {
t, err := distribyted.Templates.Open("templates/config_template.yaml")
if err != nil {
return nil, err
}
defer t.Close()
tb, err := ioutil.ReadAll(t)
if err != nil {
return nil, err
}
if err := os.MkdirAll(filepath.Dir(c.p), 0744); err != nil {
return nil, fmt.Errorf("error creating path for configuration file: %s, %w", c.p, err)
}
return tb, ioutil.WriteFile(c.p, tb, 0644)
}
func (c *Handler) GetRaw() ([]byte, error) {
f, err := ioutil.ReadFile(c.p)
if os.IsNotExist(err) {
fmt.Println("configuration file does not exist, creating from template file:", c.p)
return c.createFromTemplateFile()
}
if err != nil {
return nil, fmt.Errorf("error reading configuration file: %w", err)
}
return f, nil
}
func (c *Handler) Get() (*Root, error) {
b, err := c.GetRaw()
if err != nil {
return nil, err
}
conf := &Root{}
if err := yaml.Unmarshal(b, conf); err != nil {
return nil, fmt.Errorf("error parsing configuration file: %w", err)
}
conf = AddDefaults(conf)
return conf, nil
}

View file

@ -1,106 +0,0 @@
package config
// Root is the main yaml config object
type Root struct {
HTTPGlobal *HTTPGlobal `yaml:"http"`
WebDAV *WebDAVGlobal `yaml:"webdav"`
Torrent *TorrentGlobal `yaml:"torrent"`
Fuse *FuseGlobal `yaml:"fuse"`
Log *Log `yaml:"log"`
Routes []*Route `yaml:"routes"`
Servers []*Server `yaml:"servers"`
}
type Log struct {
Debug bool `yaml:"debug"`
MaxBackups int `yaml:"max_backups"`
MaxSize int `yaml:"max_size"`
MaxAge int `yaml:"max_age"`
Path string `yaml:"path"`
}
type TorrentGlobal struct {
ReadTimeout int `yaml:"read_timeout,omitempty"`
AddTimeout int `yaml:"add_timeout,omitempty"`
GlobalCacheSize int64 `yaml:"global_cache_size,omitempty"`
MetadataFolder string `yaml:"metadata_folder,omitempty"`
DisableIPv6 bool `yaml:"disable_ipv6,omitempty"`
}
type WebDAVGlobal struct {
Port int `yaml:"port"`
User string `yaml:"user"`
Pass string `yaml:"pass"`
}
type HTTPGlobal struct {
Port int `yaml:"port"`
IP string `yaml:"ip"`
HTTPFS bool `yaml:"httpfs"`
}
type FuseGlobal struct {
AllowOther bool `yaml:"allow_other,omitempty"`
Path string `yaml:"path"`
}
type Route struct {
Name string `yaml:"name"`
Torrents []*Torrent `yaml:"torrents"`
TorrentFolder string `yaml:"torrent_folder"`
}
type Server struct {
Name string `yaml:"name"`
Path string `yaml:"path"`
Trackers []string `yaml:"trackers"`
TrackerURL string `yaml:"tracker_url"`
}
type Torrent struct {
MagnetURI string `yaml:"magnet_uri,omitempty"`
TorrentPath string `yaml:"torrent_path,omitempty"`
}
func AddDefaults(r *Root) *Root {
if r.Torrent == nil {
r.Torrent = &TorrentGlobal{}
}
if r.Torrent.AddTimeout == 0 {
r.Torrent.AddTimeout = 60
}
if r.Torrent.ReadTimeout == 0 {
r.Torrent.ReadTimeout = 120
}
if r.Torrent.GlobalCacheSize == 0 {
r.Torrent.GlobalCacheSize = 2048 // 2GB
}
if r.Torrent.MetadataFolder == "" {
r.Torrent.MetadataFolder = metadataFolder
}
if r.Fuse != nil {
if r.Fuse.Path == "" {
r.Fuse.Path = mountFolder
}
}
if r.HTTPGlobal == nil {
r.HTTPGlobal = &HTTPGlobal{}
}
if r.HTTPGlobal.IP == "" {
r.HTTPGlobal.IP = "0.0.0.0"
}
if r.Log == nil {
r.Log = &Log{}
}
return r
}

138
go.mod
View file

@ -1,45 +1,35 @@
module github.com/distribyted/distribyted
module git.kmsign.ru/royalcat/tstor
go 1.20
go 1.21
require (
github.com/RoaringBitmap/roaring v1.5.0 // indirect
github.com/anacrolix/dht/v2 v2.20.0
github.com/anacrolix/log v0.14.2
github.com/anacrolix/log v0.14.3-0.20230823030427-4b296d71a6b4
github.com/anacrolix/missinggo/v2 v2.7.2
github.com/anacrolix/multiless v0.3.1-0.20221221005021-2d12701f83f7 // indirect
github.com/anacrolix/torrent v1.52.6-0.20230905090324-873da77cca69
github.com/anacrolix/torrent v1.52.6-0.20230929044811-45c91b322ad1
github.com/billziss-gh/cgofuse v1.5.0
github.com/bodgit/sevenzip v1.4.3
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/dgraph-io/badger/v3 v3.2103.5
github.com/dgraph-io/badger/v4 v4.2.0
github.com/fsnotify/fsnotify v1.6.0
github.com/gin-gonic/gin v1.9.1
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-yaml v1.11.2
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/knadh/koanf/parsers/yaml v0.1.0
github.com/knadh/koanf/providers/env v0.1.0
github.com/knadh/koanf/providers/file v0.1.0
github.com/knadh/koanf/providers/structs v0.1.0
github.com/knadh/koanf/v2 v2.0.1
github.com/mattn/go-colorable v0.1.13
github.com/nwaples/rardecode/v2 v2.0.0-beta.2
github.com/pion/dtls/v2 v2.2.7 // indirect
github.com/pion/mdns v0.0.8 // indirect
github.com/pion/rtp v1.8.1 // indirect
github.com/pion/sctp v1.8.8 // indirect
github.com/rs/zerolog v1.31.0
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.25.7
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/net v0.15.0
golang.org/x/sys v0.12.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/net v0.16.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/RoaringBitmap/roaring v1.2.3 // indirect
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 // indirect
github.com/alecthomas/atomic v0.1.0-alpha2 // indirect
github.com/anacrolix/chansync v0.3.0 // indirect
@ -49,92 +39,110 @@ require (
github.com/anacrolix/missinggo v1.3.0 // indirect
github.com/anacrolix/missinggo/perf v1.0.0 // indirect
github.com/anacrolix/mmsg v1.0.0 // indirect
github.com/anacrolix/stm v0.5.0 // indirect
github.com/anacrolix/sync v0.4.0 // indirect
github.com/anacrolix/multiless v0.3.1-0.20221221005021-2d12701f83f7 // indirect
github.com/anacrolix/stm v0.4.1-0.20221221005312-96d17df0e496 // indirect
github.com/anacrolix/sync v0.4.1-0.20230926072150-b8cd7cfb92d0 // indirect
github.com/anacrolix/upnp v0.1.3-0.20220123035249-922794e51c96 // indirect
github.com/anacrolix/utp v0.2.0 // indirect
github.com/anacrolix/utp v0.1.0 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/benbjohnson/immutable v0.4.3 // indirect
github.com/bits-and-blooms/bitset v1.8.0 // indirect
github.com/benbjohnson/immutable v0.4.1-0.20221220213129-8932b999621d // indirect
github.com/bits-and-blooms/bitset v1.2.2 // indirect
github.com/bodgit/plumbing v1.3.0 // indirect
github.com/bodgit/windows v1.0.1 // indirect
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-llsqlite/adapter v0.0.0-20230905083127-a7568332b3ac // indirect
github.com/go-llsqlite/crawshaw v0.0.0-20230904103556-219a9360a2c0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-llsqlite/adapter v0.0.0-20230927005056-7f5ce7f0c916 // indirect
github.com/go-llsqlite/crawshaw v0.4.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/flatbuffers v2.0.0+incompatible // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/flatbuffers v1.12.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.16.6 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/knadh/koanf/maps v0.1.1 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pion/datachannel v1.5.5 // indirect
github.com/pion/ice/v3 v3.0.0 // indirect
github.com/pion/interceptor v0.1.18 // indirect
github.com/pion/datachannel v1.5.2 // indirect
github.com/pion/dtls/v2 v2.2.4 // indirect
github.com/pion/ice/v2 v2.2.6 // indirect
github.com/pion/interceptor v0.1.11 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.5 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.10 // indirect
github.com/pion/sdp/v3 v3.0.6 // indirect
github.com/pion/srtp/v3 v3.0.0 // indirect
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.3 // indirect
github.com/pion/transport/v3 v3.0.1 // indirect
github.com/pion/turn/v3 v3.0.0 // indirect
github.com/pion/webrtc/v3 v3.2.18 // indirect
github.com/pion/rtcp v1.2.9 // indirect
github.com/pion/rtp v1.7.13 // indirect
github.com/pion/sctp v1.8.2 // indirect
github.com/pion/sdp/v3 v3.0.5 // indirect
github.com/pion/srtp/v2 v2.0.9 // indirect
github.com/pion/stun v0.3.5 // indirect
github.com/pion/transport v0.13.1 // indirect
github.com/pion/transport/v2 v2.0.0 // indirect
github.com/pion/turn/v2 v2.0.8 // indirect
github.com/pion/udp v0.1.4 // indirect
github.com/pion/webrtc/v3 v3.1.42 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect
github.com/tidwall/btree v1.6.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/otel v1.17.0 // indirect
go.opentelemetry.io/otel/metric v1.17.0 // indirect
go.opentelemetry.io/otel/trace v1.17.0 // indirect
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.opencensus.io v0.22.5 // indirect
go.opentelemetry.io/otel v1.8.0 // indirect
go.opentelemetry.io/otel/trace v1.8.0 // indirect
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
google.golang.org/protobuf v1.30.0 // indirect
modernc.org/libc v1.21.5 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.22.3 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.4.0 // indirect
modernc.org/sqlite v1.20.0 // indirect
zombiezen.com/go/sqlite v0.12.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/sqlite v1.21.1 // indirect
zombiezen.com/go/sqlite v0.13.1 // indirect
)

349
go.sum
View file

@ -14,11 +14,11 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797 h1:yDf7ARQc637HoxDho7xjqdvO5ZA2Yb+xzv/fOnnvZzw=
crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk=
crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
@ -26,16 +26,18 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI=
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
github.com/RoaringBitmap/roaring v1.5.0 h1:V0VCSiHjroItEYCM3guC8T83ehi5QMt3oM9EefTTOms=
github.com/RoaringBitmap/roaring v1.5.0/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE=
github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY=
github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 h1:byYvvbfSo3+9efR4IeReh77gVs4PnNDR3AMOE9NJ7a0=
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0/go.mod h1:q37NoqncT41qKc048STsifIt69LfUJ8SrWWcz/yam5k=
github.com/alecthomas/assert/v2 v2.0.0-alpha3 h1:pcHeMvQ3OMstAWgaeaXIAL8uzB9xMm2zlxt+/4ml8lk=
github.com/alecthomas/assert/v2 v2.0.0-alpha3/go.mod h1:+zD0lmDXTeQj7TgDgCt0ePWxb0hMC1G+PGTsTCv1B9o=
github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8=
github.com/alecthomas/atomic v0.1.0-alpha2/go.mod h1:zD6QGEyw49HIq19caJDc2NMXAy8rNi9ROrxtMXATfyI=
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48=
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -57,8 +59,8 @@ github.com/anacrolix/log v0.3.0/go.mod h1:lWvLTqzAnCWPJA08T2HCstZi0L1y2Wyvm3FJgw
github.com/anacrolix/log v0.6.0/go.mod h1:lWvLTqzAnCWPJA08T2HCstZi0L1y2Wyvm3FJgwU9jwU=
github.com/anacrolix/log v0.10.1-0.20220123034749-3920702c17f8/go.mod h1:GmnE2c0nvz8pOIPUSC9Rawgefy1sDXqposC2wgtBZE4=
github.com/anacrolix/log v0.13.1/go.mod h1:D4+CvN8SnruK6zIFS/xPoRJmtvtnxs+CSfDQ+BFxZ68=
github.com/anacrolix/log v0.14.2 h1:i9v/Lw/CceCKthcLW+UiajkSW8M/razXCwVYlZtAKsk=
github.com/anacrolix/log v0.14.2/go.mod h1:1OmJESOtxQGNMlUO5rcv96Vpp9mfMqXXbe2RdinFLdY=
github.com/anacrolix/log v0.14.3-0.20230823030427-4b296d71a6b4 h1:01OE3pdiBGIZGyQb6cIAu+QfaNhBR9k5MVmLsl+DVbE=
github.com/anacrolix/log v0.14.3-0.20230823030427-4b296d71a6b4/go.mod h1:1OmJESOtxQGNMlUO5rcv96Vpp9mfMqXXbe2RdinFLdY=
github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62 h1:P04VG6Td13FHMgS5ZBcJX23NPC/fiC4cp9bXwYujdYM=
github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62/go.mod h1:66cFKPCO7Sl4vbFnAaSq7e4OXtdMhRSBagJGWgmpJbM=
github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df/go.mod h1:kwGiTUTZ0+p4vAz3VbAI5a30t2YbvemcmspjKwrAz5s=
@ -80,21 +82,21 @@ github.com/anacrolix/mmsg v1.0.0/go.mod h1:x8kRaJY/dCrY9Al0PEcj1mb/uFHwP6GCJ9fLl
github.com/anacrolix/multiless v0.3.1-0.20221221005021-2d12701f83f7 h1:lOtCD+LzoD1g7bowhYJNR++uV+FyY5bTZXKwnPex9S8=
github.com/anacrolix/multiless v0.3.1-0.20221221005021-2d12701f83f7/go.mod h1:zJv1JF9AqdZiHwxqPgjuOZDGWER6nyE48WBCi/OOrMM=
github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg=
github.com/anacrolix/stm v0.5.0 h1:9df1KBpttF0TzLgDq51Z+TEabZKMythqgx89f1FQJt8=
github.com/anacrolix/stm v0.5.0/go.mod h1:MOwrSy+jCm8Y7HYfMAwPj7qWVu7XoVvjOiYwJmpeB/M=
github.com/anacrolix/stm v0.4.1-0.20221221005312-96d17df0e496 h1:aMiRi2kOOd+nG64suAmFMVnNK2E6GsnLif7ia9tI3cA=
github.com/anacrolix/stm v0.4.1-0.20221221005312-96d17df0e496/go.mod h1:DBm8/1OXm4A4RZ6Xa9u/eOsjeAXCaoRYvd2JzlskXeM=
github.com/anacrolix/sync v0.0.0-20180808010631-44578de4e778/go.mod h1:s735Etp3joe/voe2sdaXLcqDdJSay1O0OPnM0ystjqk=
github.com/anacrolix/sync v0.3.0/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
github.com/anacrolix/sync v0.4.0 h1:T+MdO/u87ir/ijWsTFsPYw5jVm0SMm4kVpg8t4KF38o=
github.com/anacrolix/sync v0.4.0/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
github.com/anacrolix/sync v0.4.1-0.20230926072150-b8cd7cfb92d0 h1:M2HtYrYz6CVwo88TfVrGNlc+mSe59KXCBe3gFuEsEto=
github.com/anacrolix/sync v0.4.1-0.20230926072150-b8cd7cfb92d0/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
github.com/anacrolix/tagflag v1.0.0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
github.com/anacrolix/tagflag v1.1.0/go.mod h1:Scxs9CV10NQatSmbyjqmqmeQNwGzlNe0CMUMIxqHIG8=
github.com/anacrolix/torrent v1.52.6-0.20230905090324-873da77cca69 h1:cE8GzF+t9wsYcSTaxcGAC5hY3zmip0eRICa/ZEHbSUE=
github.com/anacrolix/torrent v1.52.6-0.20230905090324-873da77cca69/go.mod h1:JkfVCMluhwf+7HkjzoqO/vX8b7bnAmzKb2+jH0GD4Ec=
github.com/anacrolix/torrent v1.52.6-0.20230929044811-45c91b322ad1 h1:KzIKTajeqBXWeLjHv2KHjlwigyR19TkdvU5uLGPGQAI=
github.com/anacrolix/torrent v1.52.6-0.20230929044811-45c91b322ad1/go.mod h1:q4utKicrzW80odcXiy3J8sObJELsGGFI1FxhFt/2qA0=
github.com/anacrolix/upnp v0.1.3-0.20220123035249-922794e51c96 h1:QAVZ3pN/J4/UziniAhJR2OZ9Ox5kOY2053tBbbqUPYA=
github.com/anacrolix/upnp v0.1.3-0.20220123035249-922794e51c96/go.mod h1:Wa6n8cYIdaG35x15aH3Zy6d03f7P728QfdcDeD/IEOs=
github.com/anacrolix/utp v0.2.0 h1:65Cdmr6q9WSw2KsM+rtJFu7rqDzLl2bdysf4KlNPcFI=
github.com/anacrolix/utp v0.2.0/go.mod h1:HGk4GYQw1O/3T1+yhqT/F6EcBd+AAwlo9dYErNy7mj8=
github.com/anacrolix/utp v0.1.0 h1:FOpQOmIwYsnENnz7tAGohA+r6iXpRjrq8ssKSre2Cp4=
github.com/anacrolix/utp v0.1.0/go.mod h1:MDwc+vsGEq7RMw6lr2GKOEqjWny5hO5OZXRVNaBJ2Dk=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@ -102,16 +104,16 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/benbjohnson/immutable v0.2.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
github.com/benbjohnson/immutable v0.4.3 h1:GYHcksoJ9K6HyAUpGxwZURrbTkXA0Dh4otXGqbhdrjA=
github.com/benbjohnson/immutable v0.4.3/go.mod h1:qJIKKSmdqz1tVzNtst1DZzvaqOU1onk1rc03IeM3Owk=
github.com/benbjohnson/immutable v0.4.1-0.20221220213129-8932b999621d h1:2qVb9bsAMtmAfnxXltm+6eBzrrS7SZ52c3SedsulaMI=
github.com/benbjohnson/immutable v0.4.1-0.20221220213129-8932b999621d/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/billziss-gh/cgofuse v1.5.0 h1:kH516I/s+Ab4diL/Y/ayFeUjjA8ey+JK12xDfBf4HEs=
github.com/billziss-gh/cgofuse v1.5.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c=
github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk=
github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bodgit/plumbing v1.3.0 h1:pf9Itz1JOQgn7vEOE7v7nlEfBykYqvUYioC61TwWCFU=
github.com/bodgit/plumbing v1.3.0/go.mod h1:JOTb4XiRu5xfnmdnDJo6GmSbSbtSyufrsyZFByMtKEs=
github.com/bodgit/sevenzip v1.4.3 h1:46Rb9vCYdpceC1U+GIR0bS3hP2/Xv8coKFDeLJySV/A=
@ -129,19 +131,15 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@ -155,28 +153,28 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg=
github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw=
github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs=
github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak=
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
@ -197,18 +195,19 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-llsqlite/adapter v0.0.0-20230905083127-a7568332b3ac h1:JYM7DEMD5W+pVLmyFGY0h/TCQmiZ41hDC7DhPyJQFg8=
github.com/go-llsqlite/adapter v0.0.0-20230905083127-a7568332b3ac/go.mod h1:kyfY1RB62UhX0Cyh902kGhiHVz9+I+i0G6tLAH4DHuw=
github.com/go-llsqlite/crawshaw v0.0.0-20230904103556-219a9360a2c0 h1:gBgO8x7vT06pP8D3v/IQ38mBnITO8lUDQyTq9nilUaI=
github.com/go-llsqlite/crawshaw v0.0.0-20230904103556-219a9360a2c0/go.mod h1:Hw0HOqxPMRCkOI87dESIgpdJrRR43OwYN0tbEFyG4OQ=
github.com/go-llsqlite/adapter v0.0.0-20230927005056-7f5ce7f0c916 h1:OyQmpAN302wAopDgwVjgs2HkFawP9ahIEqkUYz7V7CA=
github.com/go-llsqlite/adapter v0.0.0-20230927005056-7f5ce7f0c916/go.mod h1:DADrR88ONKPPeSGjFp5iEN55Arx3fi2qXZeKCYDpbmU=
github.com/go-llsqlite/crawshaw v0.4.0 h1:L02s2jZBBJj80xm1VkkdyB/JlQ/Fi0kLbNHfXA8yrec=
github.com/go-llsqlite/crawshaw v0.4.0/go.mod h1:/YJdV7uBQaYDE0fwe4z3wwJIZBJxdYzd38ICggWqtaE=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
@ -219,8 +218,6 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ=
github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -231,9 +228,8 @@ github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@ -247,31 +243,25 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v2.0.0+incompatible h1:dicJ2oXwypfwUGnB2/TYWYEKiuk9eYQlQO/AnOHl5mI=
github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
@ -281,12 +271,9 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@ -297,25 +284,23 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -326,7 +311,6 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
@ -335,12 +319,25 @@ github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs=
github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
github.com/knadh/koanf/parsers/yaml v0.1.0 h1:ZZ8/iGfRLvKSaMEECEBPM1HQslrZADk8fP1XFUxVI5w=
github.com/knadh/koanf/parsers/yaml v0.1.0/go.mod h1:cvbUDC7AL23pImuQP0oRw/hPuccrNBS2bps8asS0CwY=
github.com/knadh/koanf/providers/env v0.1.0 h1:LqKteXqfOWyx5Ab9VfGHmjY9BvRXi+clwyZozgVRiKg=
github.com/knadh/koanf/providers/env v0.1.0/go.mod h1:RE8K9GbACJkeEnkl8L/Qcj8p4ZyPXZIQ191HJi44ZaQ=
github.com/knadh/koanf/providers/file v0.1.0 h1:fs6U7nrV58d3CFAFh8VTde8TM262ObYf3ODrc//Lp+c=
github.com/knadh/koanf/providers/file v0.1.0/go.mod h1:rjJ/nHQl64iYCtAW2QQnF0eSmDEX/YZ/eNFj5yR6BvA=
github.com/knadh/koanf/providers/structs v0.1.0 h1:wJRteCNn1qvLtE5h8KQBvLJovidSdntfdyIbbCzEyE0=
github.com/knadh/koanf/providers/structs v0.1.0/go.mod h1:sw2YZ3txUcqA3Z27gPlmmBzWn1h8Nt9O6EP/91MkcWE=
github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g=
github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -348,18 +345,20 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -392,46 +391,49 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/ice/v3 v3.0.0 h1:7bnFWQNIJqabCp111sMIbo4dOjRMLzpf4qhWEadf9IY=
github.com/pion/ice/v3 v3.0.0/go.mod h1:PTKU5KYRIlBTvrj1fh1PiY3z4YsMiC/AECGJqMwFSxI=
github.com/pion/interceptor v0.1.18 h1:Hk26334NUQeUcJNR27YHYKT+sWNhhegQ9KFz5Nn6yMQ=
github.com/pion/interceptor v0.1.18/go.mod h1:tpvvF4cPM6NGxFA1DUMbhabzQBxdWMATDGEUYOR9x6I=
github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E=
github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ=
github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus=
github.com/pion/dtls/v2 v2.1.5/go.mod h1:BqCE7xPZbPSubGasRoDFJeTsyJtdD1FanJYL0JGheqY=
github.com/pion/dtls/v2 v2.2.4 h1:YSfYwDQgrxMYXLBc/m7PFY5BVtWlNm/DN4qoU2CbcWg=
github.com/pion/dtls/v2 v2.2.4/go.mod h1:WGKfxqhrddne4Kg3p11FUMJrynkOY4lb25zHNO49wuw=
github.com/pion/ice/v2 v2.2.6 h1:R/vaLlI1J2gCx141L5PEwtuGAGcyS6e7E0hDeJFq5Ig=
github.com/pion/ice/v2 v2.2.6/go.mod h1:SWuHiOGP17lGromHTFadUe1EuPgFh/oCU6FCMZHooVE=
github.com/pion/interceptor v0.1.11 h1:00U6OlqxA3FFB50HSg25J/8cWi7P6FbSzw4eFn24Bvs=
github.com/pion/interceptor v0.1.11/go.mod h1:tbtKjZY14awXd7Bq0mmWvgtHB5MDaRN7HV3OZ/uy7s8=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.8 h1:HhicWIg7OX5PVilyBO6plhMetInbzkVJAhbdJiAeVaI=
github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI=
github.com/pion/mdns v0.0.5 h1:Q2oj/JB3NqfzY9xGZ1fPzZzK7sDSD8rZPOvcIQ10BCw=
github.com/pion/mdns v0.0.5/go.mod h1:UgssrvdD3mxpi8tMxAXbsppL3vJ4Jipw1mTCW+al01g=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc=
github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
github.com/pion/rtp v1.8.1 h1:26OxTc6lKg/qLSGir5agLyj0QKaOv8OP5wps2SFnVNQ=
github.com/pion/rtp v1.8.1/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
github.com/pion/sctp v1.8.8 h1:5EdnnKI4gpyR1a1TwbiS/wxEgcUWBHsc7ILAjARJB+U=
github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs=
github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
github.com/pion/srtp/v3 v3.0.0 h1:dH5nZUTxN+JDu4otle8Dfh5E/MHR6m8/aib7eD22QDc=
github.com/pion/srtp/v3 v3.0.0/go.mod h1:WxJGk0scShe0UdUidDgR0kDHywX7JN83JOYPkYiLdpM=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
github.com/pion/transport/v2 v2.2.3 h1:XcOE3/x41HOSKbl1BfyY1TF1dERx7lVvlMCbXU7kfvA=
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v3 v3.0.0/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
github.com/pion/turn/v3 v3.0.0 h1:zafXa25ZWmiUYRi4JlnAsUhCDoFfF7YMYWnosvK5vBk=
github.com/pion/turn/v3 v3.0.0/go.mod h1:z4ih3T0zTERgNSEJRa2QHBNcbB3SOtTYsr5LH0pil6Q=
github.com/pion/webrtc/v3 v3.2.18 h1:uJJmFy8hU5dWQhdXRhBYdxuiyBfEYSuQ2fDCK2NJO9Y=
github.com/pion/webrtc/v3 v3.2.18/go.mod h1:SnzidjAnRkFxX2u/DcVR7UZjvkKK65VCuyCtPYDDzkE=
github.com/pion/rtcp v1.2.9 h1:1ujStwg++IOLIEoOiIQ2s+qBuJ1VN81KW+9pMPsif+U=
github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo=
github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
github.com/pion/sctp v1.8.2 h1:yBBCIrUMJ4yFICL3RIvR4eh/H2BTTvlligmSTy+3kiA=
github.com/pion/sctp v1.8.2/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
github.com/pion/sdp/v3 v3.0.5 h1:ouvI7IgGl+V4CrqskVtr3AaTrPvPisEOxwgpdktctkU=
github.com/pion/sdp/v3 v3.0.5/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
github.com/pion/srtp/v2 v2.0.9 h1:JJq3jClmDFBPX/F5roEb0U19jSU7eUhyDqR/NZ34EKQ=
github.com/pion/srtp/v2 v2.0.9/go.mod h1:5TtM9yw6lsH0ppNCehB/EjEUli7VkUgKSPJqWVqbhQ4=
github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg=
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A=
github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g=
github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA=
github.com/pion/transport v0.13.1/go.mod h1:EBxbqzyv+ZrmDb82XswEE0BjfQFtuw1Nu6sjnjWCsGg=
github.com/pion/transport/v2 v2.0.0 h1:bsMYyqHCbkvHwj+eNCFBuxtlKndKfyGI2vaQmM3fIE4=
github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc=
github.com/pion/turn/v2 v2.0.8 h1:KEstL92OUN3k5k8qxsXHpr7WWfrdp7iJZHx99ud8muw=
github.com/pion/turn/v2 v2.0.8/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw=
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
github.com/pion/udp v0.1.4 h1:OowsTmu1Od3sD6i3fQUJxJn2fEvJO6L1TidgadtbTI8=
github.com/pion/udp v0.1.4/go.mod h1:G8LDo56HsFwC24LIcnT4YIDU5qcB6NepqqjP0keL2us=
github.com/pion/webrtc/v3 v3.1.42 h1:wJEQFIXVanptnQcHOLTuIo4AtGB2+mG2x4OhIhnITOA=
github.com/pion/webrtc/v3 v3.1.42/go.mod h1:ffD9DulDrPxyWvDPUIPAOSAWx9GUlOExiJPf7cCcMLA=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -457,14 +459,16 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 h1:18kd+8ZUlt/ARXhljq+14TwAoKa61q6dX8jtwOf6DH8=
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v8ObDPR0dzr2a6sXTB1Fq7IHs=
github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
@ -475,8 +479,8 @@ github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8=
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@ -532,25 +536,22 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsr
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM=
go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0=
go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc=
go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o=
go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ=
go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY=
go4.org v0.0.0-20201209231011-d4a079459e60 h1:iqAGo78tVOJXELHQFRjR6TMwItrvXH4hrGJ32I/NFF8=
go4.org v0.0.0-20201209231011-d4a079459e60/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg=
go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY=
go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU=
go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
@ -562,12 +563,12 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -576,8 +577,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -597,7 +598,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -619,20 +619,22 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -646,7 +648,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -670,20 +671,20 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -691,24 +692,17 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -717,17 +711,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -754,18 +745,15 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@ -793,26 +781,20 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
@ -842,40 +824,17 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0=
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0=
modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
modernc.org/libc v1.21.5 h1:xBkU9fnHV+hvZuPSRszN0AXDG4M7nwPLwTWwkYcvLCI=
modernc.org/libc v1.21.5/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.20.0 h1:80zmD3BGkm8BZ5fUi/4lwJQHiO3GXgIUvZRXpoIfROY=
modernc.org/sqlite v1.20.0/go.mod h1:EsYz8rfOvLCiYTy5ZFsOYzoCcRMu98YYkwAcCw5YIYw=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.15.0/go.mod h1:xRoGotBZ6dU+Zo2tca+2EqVEeMmOUBzHnhIwq4YrVnE=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/sqlite v1.21.1 h1:GyDFqNnESLOhwwDRaHGdp2jKLDzpyT/rNLglX3ZkMSU=
modernc.org/sqlite v1.21.1/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
zombiezen.com/go/sqlite v0.12.0 h1:0IDiV/XR6fWS2iFcOuVpGg3O2rJV0uVYEW30ANTKjeE=
zombiezen.com/go/sqlite v0.12.0/go.mod h1:RKdRR9xoQDSnB47yy7G4PtrjGZJtupb/SyEbJZLaRes=
zombiezen.com/go/sqlite v0.13.1 h1:qDzxyWWmMtSSEH5qxamqBFmqA2BLSSbtODi3ojaE02o=
zombiezen.com/go/sqlite v0.13.1/go.mod h1:Ht/5Rg3Ae2hoyh1I7gbWtWAl89CNocfqeb/aAMTkJr4=

View file

@ -1,4 +1,4 @@
package distribyted
package tstor
import (
"embed"

View file

@ -1 +1 @@
distribyted.com
tstor.com

View file

@ -4,21 +4,21 @@
Get the latest release from [releases][releases-url] page or download the source code and execute `make build`.
Run the program: `./distribyted-[VERSION]-[OS]-[ARCH]`
Run the program: `./tstor-[VERSION]-[OS]-[ARCH]`
Defaults are good enough for starters, but you can change them. Here is the output of `./distribyted -help`:
Defaults are good enough for starters, but you can change them. Here is the output of `./tstor -help`:
```text
NAME:
distribyted - Torrent client with on-demand file downloading as a filesystem.
tstor - Torrent client with on-demand file downloading as a filesystem.
USAGE:
distribyted [global options] [arguments...]
tstor [global options] [arguments...]
GLOBAL OPTIONS:
--config value YAML file containing distribyted configuration. (default: "./distribyted-data/config.yaml") [$DISTRIBYTED_CONFIG]
--http-port value HTTP port for web interface (default: 4444) [$DISTRIBYTED_HTTP_PORT]
--fuse-allow-other Allow other users to acces to all fuse mountpoints. You need to add user_allow_other flag to /etc/fuse.conf file. (default: false) [$DISTRIBYTED_FUSE_ALLOW_OTHER]
--config value YAML file containing tstor configuration. (default: "./tstor-data/config.yaml") [$tstor_CONFIG]
--http-port value HTTP port for web interface (default: 4444) [$tstor_HTTP_PORT]
--fuse-allow-other Allow other users to acces to all fuse mountpoints. You need to add user_allow_other flag to /etc/fuse.conf file. (default: false) [$tstor_FUSE_ALLOW_OTHER]
--help, -h show help (default: false)
```
@ -36,26 +36,26 @@ docker run \
--cap-add SYS_ADMIN \
--device /dev/fuse \
--security-opt apparmor:unconfined \
-v /tmp/mount:/distribyted-data/mount:shared \
-v /tmp/metadata:/distribyted-data/metadata \
-v /tmp/config:/distribyted-data/config \
distribyted/distribyted:latest
-v /tmp/mount:/tstor-data/mount:shared \
-v /tmp/metadata:/tstor-data/metadata \
-v /tmp/config:/tstor-data/config \
tstor/tstor:latest
```
Docker compose example:
```yaml
distribyted:
container_name: distribyted
image: distribyted/distribyted:latest
tstor:
container_name: tstor
image: tstor/tstor:latest
restart: always
ports:
- "4444:4444/tcp"
- "36911:36911/tcp"
volumes:
- /home/user/mount:/distribyted-data/mount:shared
- /home/user/metadata:/distribyted-data/metadata
- /home/user/config:/distribyted-data/config
- /home/user/mount:/tstor-data/mount:shared
- /home/user/metadata:/tstor-data/metadata
- /home/user/config:/tstor-data/config
security_opt:
- apparmor:unconfined
devices:
@ -71,13 +71,13 @@ It contains information about the mounted routes and torrent files like download
### Configuration File
You can see the default configuration file with some explanation comments [here](https://github.com/distribyted/distribyted/blob/master/templates/config_template.yaml).
You can see the default configuration file with some explanation comments [here](https://git.kmsign.ru/royalcat/tstor/blob/master/templates/config_template.yaml).
### Routes
Here there is a list of all available routes with their torrents and some info. You can add and remove torrents from here too.
![routes screen](images/distribyted-routes-border-large.png)
![routes screen](images/tstor-routes-border-large.png)
### Servers
@ -86,10 +86,10 @@ All servers configured using the config yaml file will be here.
When some data is changed on these folders, a new magnet URI will be generated.
You can share that magnet URI with anyone to share these files.
![server screen](images/distribyted-server-border.png)
![server screen](images/tstor-server-border.png)
### Logs
You can check logs in real time from the web interface:
![logs screen](images/distribyted-logs-border.png)
![logs screen](images/tstor-logs-border.png)

View file

@ -1,34 +1,36 @@
Distribyted is an alternative torrent client.
tstor is an alternative torrent client.
It can expose torrent files as a standard FUSE mount or webDAV endpoint and download them on demand, allowing random reads using a fixed amount of disk space.
![Distribyted Screen Shot][product-screenshot]
[product-screenshot]: images/distribyted.gif
![tstor Screen Shot][product-screenshot]
[product-screenshot]: images/tstor.gif
## Features
### User Interfaces
Distribyted supports several ways to expose the files to the user or external applications:
tstor supports several ways to expose the files to the user or external applications:
#### Supported
- FUSE: Other applications can access to torrent files directly as a filesystem.
- WebDAV: Applications that supports WebDAV can access torrent files using this protocol. It is recommended when distribyted is running in a remote machine or using docker.
- WebDAV: Applications that supports WebDAV can access torrent files using this protocol. It is recommended when tstor is running in a remote machine or using docker.
- HTTP: A simple HTTP interface for all the available routes. You can acces it from `http://[HOST]:[PORT]/fs`
### _Expandable_ File Formats
Distribyted can show some kind of files directly as folders, making it possible for applications read only the parts that they need. Here is a list of supported, to be supported and not supported formats.
tstor can show some kind of files directly as folders, making it possible for applications read only the parts that they need. Here is a list of supported, to be supported and not supported formats.
#### Supported
- zip: Able to uncompress just one file. The file is decompressed to a temporal file sequentially to make possible seek over it. The decompression stops if no one is reading it.
- rar: Thanks to [rardecode](https://github.com/nwaples/rardecode/tree/experimental) experimental branch library, it is possible to seek through rar files.
- 7zip: Thanks to [sevenzip](https://github.com/bodgit/sevenzip) library, it is possible to read `7z` files in a similar way that is done using the `zip` implementation.
#### To Be Supported
- xz: Only worth it when the file is created using blocks. Possible library [here](https://github.com/ulikunitz/xz) and [here](https://github.com/frrad/bxzf).
#### Not Supported
- gzip: As far as I know, it doesn't support random access.

View file

@ -1,7 +1,7 @@
site_name: Distribyted
site_url: https://distribyted.com/
repo_url: https://github.com/distribyted/distribyted
repo_name: distribyted/distribyted
site_name: tstor
site_url: https://tstor.com/
repo_url: https://git.kmsign.ru/royalcat/tstor
repo_name: tstor/tstor
nav:
- Home: index.md
@ -10,7 +10,7 @@ nav:
- API Reference: api-reference.md
theme:
logo: images/distribyted_icon.png
logo: images/tstor_icon.png
icon:
repo: fontawesome/brands/github
name: material
@ -37,9 +37,6 @@ extra:
version:
default: latest
provider: mike
analytics:
provider: google
property: !ENV GOOGLE_ANALYTICS_KEY
markdown_extensions:
- toc:

82
src/config/default.go Normal file
View file

@ -0,0 +1,82 @@
package config
const (
metadataFolder = "./tstor-data/metadata"
mountFolder = "./tstor-data/mount"
logsFolder = "./tstor-data/logs"
serverFolder = "./tstor-data/served-folders/server"
)
var defaultConfig = Config{
WebUi: WebUi{
Port: 4444,
IP: "0.0.0.0",
},
Mounts: Mounts{
HttpFs: HttpFs{
Enabled: true,
Port: 4445,
},
WebDAV: WebDAV{
Enabled: true,
Port: 36911,
User: "admin",
Pass: "admin",
},
Fuse: Fuse{
Enabled: false,
AllowOther: false,
Path: mountFolder,
},
},
TorrentClient: TorrentClient{
GlobalCacheSize: 2048,
MetadataFolder: metadataFolder,
AddTimeout: 60,
ReadTimeout: 120,
},
Log: Log{
Path: logsFolder,
MaxBackups: 2,
MaxSize: 50,
},
}
var defaultRoutes = []Route{
{
Name: "multimedia",
Torrents: []Torrent{
{
MagnetURI: "magnet:?xt=urn:btih:c9e15763f722f23e98a29decdfae341b98d53056&dn=Cosmos+Laundromat&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fcosmos-laundromat.torrent",
},
{
MagnetURI: "magnet:?xt=urn:btih:dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c&dn=Big+Buck+Bunny&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fbig-buck-bunny.torrent",
},
{
MagnetURI: "magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent",
},
{
MagnetURI: "magnet:?xt=urn:btih:209c8226b299b308beaf2b9cd3fb49212dbd13ec&dn=Tears+of+Steel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Ftears-of-steel.torrent",
},
{
MagnetURI: "magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent",
},
},
},
}
var defaultServers = []Server{
{
Name: "server",
Path: serverFolder,
Trackers: []string{
"wss://tracker.btorrent.xyz",
"wss://tracker.openwebtorrent.com",
"http://p4p.arenabg.com:1337/announce",
"udp://tracker.opentrackr.org:1337/announce",
"udp://open.tracker.cl:1337/announce",
"http://openbittorrent.com:80/announce",
},
},
}

48
src/config/load.go Normal file
View file

@ -0,0 +1,48 @@
package config
import (
"os"
"strings"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/providers/structs"
"github.com/knadh/koanf/v2"
)
var k = koanf.New(".")
func Load(path string) (*Config, error) {
err := k.Load(structs.Provider(defaultConfig, "koanf"), nil)
if err != nil {
return nil, err
}
if path != "" {
_ = k.Load(file.Provider(path), yaml.Parser()) // its ok if file doesnt exist
}
err = k.Load(env.Provider("tstor_", ".", func(s string) string {
return strings.Replace(strings.ToLower(
strings.TrimPrefix(s, "tstor_")), "_", ".", -1)
}), nil)
if err != nil {
return nil, err
}
data, err := k.Marshal(yaml.Parser())
if err != nil {
return nil, err
}
err = os.WriteFile(path, data, os.ModePerm)
if err != nil {
return nil, err
}
conf := Config{}
k.Unmarshal("", &conf)
return &conf, nil
}

75
src/config/model.go Normal file
View file

@ -0,0 +1,75 @@
package config
// Config is the main config object
type Config struct {
WebUi WebUi `koanf:"webUi"`
TorrentClient TorrentClient `koanf:"torrent"`
Mounts Mounts `koanf:"mounts"`
Log Log `koanf:"log"`
}
type WebUi struct {
Port int `koanf:"port"`
IP string `koanf:"ip"`
}
type Log struct {
Debug bool `koanf:"debug"`
MaxBackups int `koanf:"max_backups"`
MaxSize int `koanf:"max_size"`
MaxAge int `koanf:"max_age"`
Path string `koanf:"path"`
}
type TorrentClient struct {
ReadTimeout int `koanf:"read_timeout,omitempty"`
AddTimeout int `koanf:"add_timeout,omitempty"`
GlobalCacheSize int64 `koanf:"global_cache_size,omitempty"`
MetadataFolder string `koanf:"metadata_folder,omitempty"`
DisableIPv6 bool `koanf:"disable_ipv6,omitempty"`
Routes []Route `koanf:"routes"`
Servers []Server `koanf:"servers"`
}
type Route struct {
Name string `koanf:"name"`
Torrents []Torrent `koanf:"torrents"`
TorrentFolder string `koanf:"torrent_folder"`
}
type Server struct {
Name string `koanf:"name"`
Path string `koanf:"path"`
Trackers []string `koanf:"trackers"`
TrackerURL string `koanf:"tracker_url"`
}
type Torrent struct {
MagnetURI string `koanf:"magnet_uri,omitempty"`
TorrentPath string `koanf:"torrent_path,omitempty"`
}
type Mounts struct {
WebDAV WebDAV `koanf:"webdav"`
HttpFs HttpFs `koanf:"httpfs"`
Fuse Fuse `koanf:"fuse"`
}
type HttpFs struct {
Enabled bool `koanf:"enabled"`
Port int `koanf:"port"`
}
type WebDAV struct {
Enabled bool `koanf:"enabled"`
Port int `koanf:"port"`
User string `koanf:"user"`
Pass string `koanf:"pass"`
}
type Fuse struct {
Enabled bool `koanf:"enabled"`
AllowOther bool `koanf:"allow_other,omitempty"`
Path string `koanf:"path"`
}

View file

@ -7,8 +7,8 @@ import (
"path/filepath"
"sync"
"git.kmsign.ru/royalcat/tstor/src/iio"
"github.com/bodgit/sevenzip"
"github.com/distribyted/distribyted/iio"
"github.com/nwaples/rardecode/v2"
)

View file

@ -6,7 +6,7 @@ import (
"io"
"testing"
"github.com/distribyted/distribyted/iio"
"git.kmsign.ru/royalcat/tstor/src/iio"
"github.com/stretchr/testify/require"
)

View file

@ -4,7 +4,7 @@ import (
"os"
"time"
"github.com/distribyted/distribyted/iio"
"git.kmsign.ru/royalcat/tstor/src/iio"
)
type File interface {

View file

@ -6,9 +6,9 @@ import (
"sync"
"time"
"git.kmsign.ru/royalcat/tstor/src/iio"
"github.com/anacrolix/missinggo/v2"
"github.com/anacrolix/torrent"
"github.com/distribyted/distribyted/iio"
)
var _ Filesystem = &Torrent{}

View file

@ -8,20 +8,25 @@ import (
"os"
"sort"
"git.kmsign.ru/royalcat/tstor/src/torrent"
"github.com/anacrolix/missinggo/v2/filecache"
"github.com/distribyted/distribyted/torrent"
"github.com/gin-gonic/gin"
)
var apiStatusHandler = func(fc *filecache.Cache, ss *torrent.Stats) gin.HandlerFunc {
return func(ctx *gin.Context) {
// TODO move to a struct
ctx.JSON(http.StatusOK, gin.H{
"cacheItems": fc.Info().NumItems,
"cacheFilled": fc.Info().Filled / 1024 / 1024,
"cacheCapacity": fc.Info().Capacity / 1024 / 1024,
stat := gin.H{
"torrentStats": ss.GlobalStats(),
})
}
if fc != nil {
stat["cacheItems"] = fc.Info().NumItems
stat["cacheFilled"] = fc.Info().Filled / 1024 / 1024
stat["cacheCapacity"] = fc.Info().Capacity / 1024 / 1024
}
// TODO move to a struct
ctx.JSON(http.StatusOK, stat)
}
}

View file

@ -4,16 +4,16 @@ import (
"fmt"
"net/http"
"git.kmsign.ru/royalcat/tstor"
"git.kmsign.ru/royalcat/tstor/src/config"
"git.kmsign.ru/royalcat/tstor/src/torrent"
"github.com/anacrolix/missinggo/v2/filecache"
"github.com/distribyted/distribyted"
"github.com/distribyted/distribyted/config"
"github.com/distribyted/distribyted/torrent"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"github.com/shurcooL/httpfs/html/vfstemplate"
)
func New(fc *filecache.Cache, ss *torrent.Stats, s *torrent.Service, ch *config.Handler, tss []*torrent.Server, fs http.FileSystem, logPath string, cfg *config.HTTPGlobal) error {
func New(fc *filecache.Cache, ss *torrent.Stats, s *torrent.Service, ch *config.Config, tss []*torrent.Server, fs http.FileSystem, logPath string, cfg *config.Config) error {
gin.SetMode(gin.ReleaseMode)
r := gin.New()
r.Use(gin.Recovery())
@ -21,18 +21,18 @@ func New(fc *filecache.Cache, ss *torrent.Stats, s *torrent.Service, ch *config.
r.Use(Logger())
r.GET("/assets/*filepath", func(c *gin.Context) {
c.FileFromFS(c.Request.URL.Path, http.FS(distribyted.Assets))
c.FileFromFS(c.Request.URL.Path, http.FS(tstor.Assets))
})
if cfg.HTTPFS {
log.Info().Str("host", fmt.Sprintf("%s:%d/fs", cfg.IP, cfg.Port)).Msg("starting HTTPFS")
if cfg.Mounts.HttpFs.Enabled {
log.Info().Str("host", fmt.Sprintf("0.0.0.0:%d/fs", cfg.Mounts.HttpFs.Port)).Msg("starting HTTPFS")
r.GET("/fs/*filepath", func(c *gin.Context) {
path := c.Param("filepath")
c.FileFromFS(path, fs)
})
}
t, err := vfstemplate.ParseGlob(http.FS(distribyted.Templates), nil, "/templates/*")
t, err := vfstemplate.ParseGlob(http.FS(tstor.Templates), nil, "/templates/*")
if err != nil {
return fmt.Errorf("error parsing html: %w", err)
}
@ -56,9 +56,9 @@ func New(fc *filecache.Cache, ss *torrent.Stats, s *torrent.Service, ch *config.
}
log.Info().Str("host", fmt.Sprintf("%s:%d", cfg.IP, cfg.Port)).Msg("starting webserver")
log.Info().Str("host", fmt.Sprintf("%s:%d", cfg.WebUi.IP, cfg.WebUi.Port)).Msg("starting webserver")
if err := r.Run(fmt.Sprintf("%s:%d", cfg.IP, cfg.Port)); err != nil {
if err := r.Run(fmt.Sprintf("%s:%d", cfg.WebUi.IP, cfg.WebUi.Port)); err != nil {
return fmt.Errorf("error initializing server: %w", err)
}

View file

@ -3,7 +3,7 @@ package http
import (
"net/http"
"github.com/distribyted/distribyted/torrent"
"git.kmsign.ru/royalcat/tstor/src/torrent"
"github.com/gin-gonic/gin"
)

View file

@ -2,7 +2,6 @@ package iio
import (
"io"
"io/ioutil"
"os"
"sync"
)
@ -21,7 +20,7 @@ type DiskTeeReader struct {
}
func NewDiskTeeReader(r io.Reader) (Reader, error) {
fr, err := ioutil.TempFile("", "dtb_tmp")
fr, err := os.CreateTemp("", "dtb_tmp")
if err != nil {
return nil, err
}
@ -35,7 +34,7 @@ func (dtr *DiskTeeReader) ReadAt(p []byte, off int64) (int, error) {
tb := off + int64(len(p))
if tb > dtr.fo {
w, err := io.CopyN(ioutil.Discard, dtr.tr, tb-dtr.fo)
w, err := io.CopyN(io.Discard, dtr.tr, tb-dtr.fo)
dtr.to += w
if err != nil && err != io.EOF {
return 0, err

View file

@ -4,8 +4,8 @@ import (
"io"
"testing"
"github.com/distribyted/distribyted/fs"
"github.com/distribyted/distribyted/iio"
"git.kmsign.ru/royalcat/tstor/src/fs"
"git.kmsign.ru/royalcat/tstor/src/iio"
"github.com/stretchr/testify/require"
)

View file

@ -5,14 +5,14 @@ import (
"os"
"path/filepath"
"github.com/distribyted/distribyted/config"
"git.kmsign.ru/royalcat/tstor/src/config"
"github.com/mattn/go-colorable"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"gopkg.in/natefinch/lumberjack.v2"
)
const FileName = "distribyted.log"
const FileName = "tstor.log"
func Load(config *config.Log) {
var writers []io.Writer

View file

@ -5,8 +5,9 @@ import (
"path/filepath"
"runtime"
"git.kmsign.ru/royalcat/tstor/src/fs"
"github.com/billziss-gh/cgofuse/fuse"
"github.com/distribyted/distribyted/fs"
"github.com/rs/zerolog/log"
)

View file

@ -7,8 +7,9 @@ import (
"os"
"sync"
"git.kmsign.ru/royalcat/tstor/src/fs"
"github.com/billziss-gh/cgofuse/fuse"
"github.com/distribyted/distribyted/fs"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
@ -43,6 +44,12 @@ func (fs *FS) Open(path string, flags int) (errc int, fh uint64) {
return 0, fh
}
// Unlink removes a file.
// The FileSystemBase implementation returns -ENOSYS.
func (fs *FS) Unlink(path string) int {
return -fuse.ENOSYS
}
func (fs *FS) Opendir(path string) (errc int, fh uint64) {
return fs.Open(path, 0)
}

View file

@ -7,7 +7,7 @@ import (
"testing"
"time"
"github.com/distribyted/distribyted/fs"
"git.kmsign.ru/royalcat/tstor/src/fs"
"github.com/stretchr/testify/require"
)

View file

@ -1,4 +1,4 @@
package torrent
package httpfs
import (
"io"
@ -7,8 +7,8 @@ import (
"os"
"sync"
dfs "github.com/distribyted/distribyted/fs"
"github.com/distribyted/distribyted/iio"
dfs "git.kmsign.ru/royalcat/tstor/src/fs"
"git.kmsign.ru/royalcat/tstor/src/iio"
)
var _ http.FileSystem = &HTTPFS{}

View file

@ -8,8 +8,8 @@ import (
"sync"
"time"
"github.com/distribyted/distribyted/fs"
"github.com/distribyted/distribyted/iio"
"git.kmsign.ru/royalcat/tstor/src/fs"
"git.kmsign.ru/royalcat/tstor/src/iio"
"golang.org/x/net/webdav"
)

View file

@ -6,7 +6,7 @@ import (
"os"
"testing"
"github.com/distribyted/distribyted/fs"
"git.kmsign.ru/royalcat/tstor/src/fs"
"github.com/stretchr/testify/require"
"golang.org/x/net/webdav"
)

View file

@ -3,7 +3,7 @@ package webdav
import (
"net/http"
"github.com/distribyted/distribyted/fs"
"git.kmsign.ru/royalcat/tstor/src/fs"
"github.com/rs/zerolog/log"
"golang.org/x/net/webdav"
)

View file

@ -4,7 +4,7 @@ import (
"fmt"
"net/http"
"github.com/distribyted/distribyted/fs"
"git.kmsign.ru/royalcat/tstor/src/fs"
"github.com/rs/zerolog/log"
)

View file

@ -10,11 +10,11 @@ import (
"github.com/anacrolix/torrent/storage"
"github.com/rs/zerolog/log"
"github.com/distribyted/distribyted/config"
dlog "github.com/distribyted/distribyted/log"
"git.kmsign.ru/royalcat/tstor/src/config"
dlog "git.kmsign.ru/royalcat/tstor/src/log"
)
func NewClient(st storage.ClientImpl, fis bep44.Store, cfg *config.TorrentGlobal, id [20]byte) (*torrent.Client, error) {
func NewClient(st storage.ClientImpl, fis bep44.Store, cfg *config.TorrentClient, id [20]byte) (*torrent.Client, error) {
// TODO download and upload limits
torrentCfg := torrent.NewDefaultClientConfig()
torrentCfg.Seed = true

View file

@ -1,14 +1,14 @@
package loader
import "github.com/distribyted/distribyted/config"
import "git.kmsign.ru/royalcat/tstor/src/config"
var _ Loader = &Config{}
type Config struct {
c []*config.Route
c []config.Route
}
func NewConfig(r []*config.Route) *Config {
func NewConfig(r []config.Route) *Config {
return &Config{
c: r,
}

View file

@ -3,9 +3,9 @@ package loader
import (
"path"
dlog "git.kmsign.ru/royalcat/tstor/src/log"
"github.com/anacrolix/torrent/metainfo"
"github.com/dgraph-io/badger/v3"
dlog "github.com/distribyted/distribyted/log"
"github.com/rs/zerolog/log"
)

View file

@ -5,16 +5,16 @@ import (
"path"
"path/filepath"
"github.com/distribyted/distribyted/config"
"git.kmsign.ru/royalcat/tstor/src/config"
)
var _ Loader = &Folder{}
type Folder struct {
c []*config.Route
c []config.Route
}
func NewFolder(r []*config.Route) *Folder {
func NewFolder(r []config.Route) *Folder {
return &Folder{
c: r,
}

View file

@ -8,11 +8,11 @@ import (
"sync/atomic"
"time"
"git.kmsign.ru/royalcat/tstor/src/config"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/bencode"
"github.com/anacrolix/torrent/metainfo"
"github.com/anacrolix/torrent/storage"
"github.com/distribyted/distribyted/config"
"github.com/fsnotify/fsnotify"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

View file

@ -7,10 +7,10 @@ import (
"sync"
"time"
"git.kmsign.ru/royalcat/tstor/src/fs"
"git.kmsign.ru/royalcat/tstor/src/torrent/loader"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo"
"github.com/distribyted/distribyted/fs"
"github.com/distribyted/distribyted/torrent/loader"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)

View file

@ -5,9 +5,9 @@ import (
"encoding/gob"
"time"
dlog "git.kmsign.ru/royalcat/tstor/src/log"
"github.com/anacrolix/dht/v2/bep44"
"github.com/dgraph-io/badger/v3"
dlog "github.com/distribyted/distribyted/log"
"github.com/dgraph-io/badger/v4"
"github.com/rs/zerolog/log"
)

View file

@ -18,13 +18,13 @@ webdav:
# Specific configuration for torrent backend.
torrent:
# Size in MB for the cache. This is the maximum space used by distribyted to store
# Size in MB for the cache. This is the maximum space used by tstor to store
# torrent data. Less used torrent data will be discarded if this value is reached.
# global_cache_size: -1 #No limit
global_cache_size: 2048
# Folder where distribyted metadata will be stored.
metadata_folder: ./distribyted-data/metadata
# Folder where tstor metadata will be stored.
metadata_folder: ./tstor-data/metadata
# Disable IPv6.
#disable_ipv6: true
@ -35,18 +35,18 @@ torrent:
# Timeout in seconds when reading any torrent content. Usefult when reading
# archived content from .rar, .zip or .7z.
read_timeout: 120
fuse:
# Folder where fuse will mount torrent filesystem
# For windows users:
# - You can set here also a disk letter like X: or Z:.
# - The folder MUST NOT exists.
path: ./distribyted-data/mount
# Add this flag if you want to allow other users to access this fuse mountpoint.
# You need to add user_allow_other flag to /etc/fuse.conf file.
# allow_other: true
# fuse:
# # Folder where fuse will mount torrent filesystem
# # For windows users:
# # - You can set here also a disk letter like X: or Z:.
# # - The folder MUST NOT exists.
# path: ./tstor-data/mount
# # Add this flag if you want to allow other users to access this fuse mountpoint.
# # You need to add user_allow_other flag to /etc/fuse.conf file.
# # allow_other: true
log:
path: ./distribyted-data/logs
path: ./tstor-data/logs
# MaxBackups is the maximum number of old log files to retain. The default
# is to retain all old log files (though MaxAge may still cause them to get
@ -89,18 +89,18 @@ routes:
# List of folders where the content will be transformed to a magnet link. You can share any content sending that magnet link to others.
servers:
- name: server
path: ./distribyted-data/served-folders/server
path: ./tstor-data/served-folders/server
# Get trackers from web text file. The file will be loaded every time a magnet uri is generated,
# so all trackers will be up to date.
# tracker_url: "https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt"
tracker_url: "https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt"
# Trackers to be used to announce the served content. If tracker_url is set and it fails,
# this list will be used instead.
trackers:
- "wss://tracker.btorrent.xyz"
- "wss://tracker.openwebtorrent.com"
- "http://p4p.arenabg.com:1337/announce"
- "udp://tracker.opentrackr.org:1337/announce"
- "udp://open.tracker.cl:1337/announce"
- "http://openbittorrent.com:80/announce"
# trackers:
# - "wss://tracker.btorrent.xyz"
# - "wss://tracker.openwebtorrent.com"
# - "http://p4p.arenabg.com:1337/announce"
# - "udp://tracker.opentrackr.org:1337/announce"
# - "udp://open.tracker.cl:1337/announce"
# - "http://openbittorrent.com:80/announce"

View file

@ -1,12 +1,17 @@
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Distribyted - {{.}}</title>
<title>tstor - {{.}}</title>
<!-- GOOGLE FONTS -->
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500|Poppins:400,500,600,700|Roboto:400,500"
rel="stylesheet" />
<link href="https://cdn.materialdesignicons.com/4.4.95/css/materialdesignicons.min.css" rel="stylesheet" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:400,500|Poppins:400,500,600,700|Roboto:400,500"
rel="stylesheet"
/>
<link
href="https://cdn.materialdesignicons.com/4.4.95/css/materialdesignicons.min.css"
rel="stylesheet"
/>
<!-- SLEEK CSS -->
<link id="sleek-css" rel="stylesheet" href="assets/css/sleek.min.css" />
<link href="assets/plugins/toastr/toastr.min.css" rel="stylesheet" />

View file

@ -96,9 +96,9 @@
<script src="assets/js/cache_chart.js"></script>
<script src="assets/js/dashboard.js"></script>
<script>
Distribyted.dashboard.loadView();
tstor.dashboard.loadView();
setInterval(function () {
Distribyted.dashboard.loadView();
tstor.dashboard.loadView();
}, 2000)
</script>
</body>

View file

@ -70,7 +70,7 @@
<script src="assets/js/logs.js"></script>
<script>
Distribyted.logs.loadView();
tstor.logs.loadView();
</script>
</body>

View file

@ -7,9 +7,9 @@
<div id="sidebar" class="sidebar sidebar-with-footer">
<!-- Aplication Brand -->
<div class="app-brand">
<a href="/" title="Distribyted">
<a href="/" title="tstor">
<img src="/assets/img/favicon.png" />
<span class="brand-name text-truncate">Distribyted</span>
<span class="brand-name text-truncate">tstor</span>
</a>
</div>
<!-- begin sidebar scrollbar -->

View file

@ -69,9 +69,9 @@
<script src="assets/js/routes.js"></script>
<script>
Distribyted.routes.loadView();
tstor.routes.loadView();
setInterval(function () {
Distribyted.routes.loadView();
tstor.routes.loadView();
}, 2000)
</script>

View file

@ -34,9 +34,9 @@
<script src="assets/js/servers.js"></script>
<script>
Distribyted.servers.loadView();
tstor.servers.loadView();
setInterval(function () {
Distribyted.servers.loadView();
tstor.servers.loadView();
}, 5000)
</script>