Update metadata on download finish

This commit is contained in:
Alexander
2026-07-25 12:07:27 +02:00
parent 36225bbf40
commit 2a4098769a
37 changed files with 5016 additions and 800 deletions
+3
View File
@@ -37,6 +37,9 @@ config.yaml
devenv.local.nix
devenv.local.yaml
# Runtime artifacts (downloads, FUSE mount, etc.)
dev/
# direnv
.direnv
+2 -2
View File
@@ -1,9 +1,9 @@
[submodule "musicfs"]
path = musicfs
url = /home/fujin/Code/agregators/musicfs
url = ssh://git@gitea.susano-homelab.duckdns.org:2222/fujin/MusicFS.git
[submodule "tora"]
path = tora
url = /home/fujin/Code/agregators/tora
url = ssh://git@gitea.susano-homelab.duckdns.org:2222/fujin/tora.git
[submodule "metadata-agregator"]
path = metadata-agregator
url = ssh://git@gitea.susano-homelab.duckdns.org:2222/fujin/metadata-agregator.git
+1 -1
View File
@@ -1 +1 @@
/nix/store/caqfpcm0y8ar1fh9apqimnndhq32cfc1-pre-commit-config.json
/nix/store/89dh2k01lvb3lsmnyja13324p9x3fkih-pre-commit-config.json
+5 -1
View File
@@ -5,6 +5,8 @@
<!-- SECTION: Music-Agregator -->
- [ ] [P2] Every restart of devenv - recreates Jackett container *(priority: P2)*
- [ ] [P2] Implement reconnection on service restart *(priority: P2)*
- [ ] [P2] Update devenv services to properly show ready state similarly to postgres *(priority: P2)*
<!-- SECTION: HISTORY -->
@@ -12,8 +14,10 @@
| Timestamp | Item ID | Action | Details |
|-----------|---------|--------|---------|
| 2026-07-22T20:48:17.097Z | n-zlin24 | item_created | Update devenv services to properly show ready state similarly to postgres |
| 2026-07-20T10:27:43.739Z | n-wynn47 | item_created | Implement reconnection on service restart |
| 2026-07-19T12:57:24.051Z | n-ddy1wp | item_created | Every restart of devenv - recreates Jackett container |
<!-- SECTION: INTEGRITY -->
<!-- saved: 2026-07-19T12:57:24Z | checksum: sha256:f7fe0f5505ff6f0fba7734fe46f990b347b0b3319257b054d8034813d49461ec | entries: 1 | history: 1 -->
<!-- saved: 2026-07-22T20:48:17Z | checksum: sha256:3ddeca2b589fb28fadffbd34ac1b6ce1e3de80fa79d45e304640b88fd749b45e | entries: 3 | history: 3 -->
+2
View File
@@ -7,5 +7,7 @@ api = "feuxigkphd3z1q9yruxc3grp2fcs2reh"
address = "unix:///run/user/1000/devenv-ae542bd/torad.sock"
[metadata]
address = "http://localhost:50053"
[musicfs]
address = "http://127.0.0.1:50052"
[database]
url = "postgres://fujin@localhost:5432/music_agregator"
+20
View File
@@ -62,3 +62,23 @@ CREATE INDEX parsed_torrents_state_idx
CREATE UNIQUE INDEX parsed_torrents_info_hash_uidx
ON parsed_torrents (info_hash)
WHERE info_hash != '';
-- Albums that music-agregator has pointed tora at. One row per
-- (album_id, quality) pair: a re-monitor of the same album at the same
-- quality is rejected by the UNIQUE constraint until the previous row is
-- removed. The `torrent_id` column links back to tora's torrent; it's what
-- the startup notification subscriber uses to look up which album a
-- STATE_CHANGED -> FINISHED event belongs to.
CREATE TABLE monitored_albums (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
album_id TEXT NOT NULL,
torrent_id UUID NOT NULL,
quality TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
completed_at TIMESTAMPTZ,
UNIQUE (album_id, quality)
);
CREATE UNIQUE INDEX monitored_albums_torrent_id_uidx
ON monitored_albums (torrent_id);
@@ -0,0 +1,22 @@
info:
name: Search Album
type: grpc
seq: 2
grpc:
url: localhost:50051
method: /metadata.v1.MetadataService/SearchAlbums
methodType: unary
message: |-
{
"query": "arbor",
"artist": "sub",
"limit": 982,
"offset": 27,
"provider": 0,
"album_types": [
"natus",
"natus"
]
}
auth: inherit
@@ -0,0 +1,11 @@
info:
name: List Files
type: grpc
seq: 1
grpc:
url: localhost:50051
method: /musicfs.ClientControl/ListFiles
methodType: unary
message: "{}"
auth: inherit
+7
View File
@@ -0,0 +1,7 @@
info:
name: Musicfs
type: folder
seq: 7
request:
auth: inherit
+14
View File
@@ -0,0 +1,14 @@
info:
name: Add
type: grpc
seq: 3
grpc:
url: localhost:50051
method: /torrent.Torrents/Add
methodType: unary
message: |-
{
"magnet": "magnet:?xt=urn:btih:C1A42E5046D5AC2346D5EE47A44F8630FD1C33FB&tr=http%3A%2F%2Fbt2.t-ru.org%2Fann%3Fmagnet&dn=(%D0%A0%D0%BE%D0%BA)%20%D0%94%D0%94%D0%A2%20(DDT)%20-%20%D0%A2%D0%B2%D0%BE%D1%80%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%BE%20%D0%B2%20%D0%BF%D1%83%D1%81%D1%82%D0%BE%D1%82%D0%B5%20-%202021%2C%20MP3%2C%20320%20kbps"
}
auth: inherit
+1 -1
View File
@@ -9,7 +9,7 @@ grpc:
methodType: unary
message: |-
{
"id": "7a76f972-5bce-4266-8e29-870a29d297e1",
"id": "37d6c87c-db55-4f9d-ad32-f582c395b061",
"delete_files": true
}
auth: inherit
+14
View File
@@ -0,0 +1,14 @@
info:
name: Status
type: grpc
seq: 4
grpc:
url: localhost:50051
method: /torrent.Torrents/Status
methodType: unary
message: |-
{
"id": "ea0e2fec-08ec-4bcd-909c-4dedccfdcb6e"
}
auth: inherit
+34 -18
View File
@@ -83,11 +83,11 @@
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1782920231,
"narHash": "sha256-hE3aMd68LTOfoG+wxZFLi2LXp6xaDsxLLeluuNpQPLE=",
"lastModified": 1784644044,
"narHash": "sha256-U2kO/QOuW117JIctgK0Hq9b3+5quEDB1fxiIXqhX6OI=",
"owner": "cachix",
"repo": "devenv",
"rev": "9c262553e2d71f3b6c60b24405bd8567f28f384c",
"rev": "87c0b55cf635e41d0ba2d418d01189c9abf7a75d",
"type": "github"
},
"original": {
@@ -227,11 +227,11 @@
]
},
"locked": {
"lastModified": 1782908218,
"narHash": "sha256-wLMOrPgVyeF3XmP+qfYcLqnVdTxikdcSvbIY7rA9jTA=",
"lastModified": 1784288435,
"narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "9f7e99119ece7705299595299f3b031f39356de1",
"rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9",
"type": "github"
},
"original": {
@@ -285,6 +285,21 @@
"type": "github"
}
},
"jail-nix": {
"locked": {
"lastModified": 1776230864,
"narHash": "sha256-YsEjjdOsGEzTeD+iT7ONh071BqWAOQWpzYVei3okAXE=",
"owner": "~alexdavid",
"repo": "jail.nix",
"rev": "404e7da9da5ab9aa643666682b2ba1312fa5fbe8",
"type": "sourcehut"
},
"original": {
"owner": "~alexdavid",
"repo": "jail.nix",
"type": "sourcehut"
}
},
"nix-test-runner": {
"flake": false,
"locked": {
@@ -320,11 +335,11 @@
"nixpkgs-src": {
"flake": false,
"locked": {
"lastModified": 1782636521,
"narHash": "sha256-OG8laCOGtkxlB1JH3XqOnXxnkGJme4mQdXo5hkhCQIY=",
"lastModified": 1783279667,
"narHash": "sha256-/NAkDSsve+GNM0Bt6tleJdCGfsTlK89nPjkVOzZMo0s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e1c1b84752fb0897897380a3cae9dc7fcab91ca3",
"rev": "f205b5574fd0cb7da5b702a2da51507b7f4fdd1b",
"type": "github"
},
"original": {
@@ -339,11 +354,11 @@
"nixpkgs-src": "nixpkgs-src"
},
"locked": {
"lastModified": 1782924808,
"narHash": "sha256-tn2ahNv3ZNXyVHdPx/uw+N0xa7YSMtXUr6OEvu+s8ng=",
"lastModified": 1783345554,
"narHash": "sha256-LZhOm4kqjHUnwP4CNHpaqqEVcumGNd1PvOEOad8LkS0=",
"owner": "cachix",
"repo": "devenv-nixpkgs",
"rev": "e2c881cb8d5f1cac6cef9d71f0d450a55691b999",
"rev": "6004ea8c229fe9d41b21c6f4c76bf6c2e10771dd",
"type": "github"
},
"original": {
@@ -372,15 +387,16 @@
"pinix": {
"inputs": {
"bun2nix": "bun2nix",
"jail-nix": "jail-nix",
"nixpkgs": "nixpkgs_3",
"systems": "systems"
},
"locked": {
"lastModified": 1783064273,
"narHash": "sha256-8u4o7iP+GlgA/nxZtFy08SXaHehD0f6SZHi2cVV2ZfI=",
"lastModified": 1784532650,
"narHash": "sha256-50kpr8hJKmsd6J+0KKS1WRXp1JRw9nLDHFA4fi/QQ6o=",
"owner": "lukasl-dev",
"repo": "pi.nix",
"rev": "9538c024e2fc57b764fdd0dd1db8d79b635a1f7e",
"rev": "1ee5a66c7ae8b33051b90aa92016d976dfbb729c",
"type": "github"
},
"original": {
@@ -469,11 +485,11 @@
]
},
"locked": {
"lastModified": 1780220602,
"narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=",
"lastModified": 1784369104,
"narHash": "sha256-47cxbcZODibHv3rELFQ9vZly0vUNkND/atn/U7HLeb0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "db947814a175b7ca6ded66e21383d938df01c227",
"rev": "df3c0640565d04a0261253cdd89fce78ec50168a",
"type": "github"
},
"original": {
+21 -1
View File
@@ -46,9 +46,29 @@
enable = true;
initialDatabases = [
{
name = "music-agregator";
name = "music_agregator";
schema = ./db/schema.sql;
}
];
};
# torad downloads into dev/downloads/<torrent_name>/ and moves finished
# torrents to dev/downloads/completed/<torrent_name>/ on completion.
# musicfs scans only the completed/ subtree so it never sees partially
# written files.
processes.torad.exec = lib.mkForce ''
mkdir -p "$PWD/dev/downloads"
${config.outputs.torad}/bin/torad \
--socket "$TORAD_SOCKET" \
--pid-file "$TORAD_PID_FILE" \
--download-dir "$PWD/dev/downloads"
'';
processes.musicfs.exec = lib.mkForce ''
mkdir -p "$PWD/dev/downloads/completed" /tmp/dev-music
${config.outputs.musicfs}/bin/musicfs \
--source "$PWD/dev/downloads/completed" \
--mountpoint /tmp/dev-music \
--database "postgresql://fujin@localhost/musicfs?host=$PGHOST"
'';
}
+1 -1
Submodule musicfs updated: 5f79b3c2b0...78b4338f95
+12
View File
@@ -4,6 +4,7 @@ package music.v1;
service MusicService {
rpc MonitorAlbum(MonitorAlbumRequest) returns (MonitorAlbumResponse);
// rpc Notifications(MonitorNotificationsRequest) returns (stream NotificationResponse);
}
enum Quality {
@@ -20,3 +21,14 @@ message MonitorAlbumRequest {
message MonitorAlbumResponse {
}
message MonitorNotificationsRequest {}
message NotificationResponse{
enum NotificationType {
Unknown = 0;
TorrentStatus = 1;
}
NotificationType type = 1;
}
@@ -29,5 +29,5 @@ message AddRequest {
}
message AddResponse {
string torrent_id = 1;
}
+6
View File
@@ -6,6 +6,7 @@ pub struct Config {
pub indexer: IndexerConfig,
pub torrent: TorrentConfig,
pub metadata: MetadataConfig,
pub musicfs: MusicfsConfig,
pub database: DatabaseConfig,
}
@@ -31,6 +32,11 @@ pub struct MetadataConfig {
pub address: String,
}
#[derive(Debug, Deserialize)]
pub struct MusicfsConfig {
pub address: String,
}
#[derive(Debug, Deserialize)]
pub struct DatabaseConfig {
pub url: String,
+45 -7
View File
@@ -5,8 +5,6 @@ use uuid::Uuid;
use crate::torrent::{AudioFormat, ParsedTorrent, ReleaseSource, ReleaseType};
const SCHEMA_SQL: &str = include_str!("../db/schema.sql");
pub async fn connect(database_url: &str) -> Result<PgPool> {
let pool = PgPoolOptions::new()
.max_connections(5)
@@ -15,11 +13,6 @@ pub async fn connect(database_url: &str) -> Result<PgPool> {
Ok(pool)
}
pub async fn apply_schema(pool: &PgPool) -> Result<()> {
sqlx::raw_sql(SCHEMA_SQL).execute(pool).await?;
Ok(())
}
pub async fn insert_partial(pool: &PgPool, pt: &ParsedTorrent, source_url: &str) -> Result<Uuid> {
let row = sqlx::query(
"INSERT INTO parsed_torrents (
@@ -187,3 +180,48 @@ pub async fn get(pool: &PgPool, info_hash: &str) -> Result<Option<ParsedTorrent>
parse_errors: parse_errors.0,
}))
}
pub async fn insert_monitored_album(
pool: &PgPool,
album_id: &str,
torrent_id: Uuid,
quality: &str,
) -> Result<Uuid> {
let row = sqlx::query(
"INSERT INTO monitored_albums (album_id, torrent_id, quality)
VALUES ($1, $2, $3)
RETURNING id",
)
.bind(album_id)
.bind(torrent_id)
.bind(quality)
.fetch_one(pool)
.await?;
Ok(row.get("id"))
}
pub async fn get_pending_monitored_albums(pool: &PgPool) -> Result<Vec<(Uuid, String)>> {
let rows =
sqlx::query("SELECT torrent_id, album_id FROM monitored_albums WHERE completed_at IS NULL")
.fetch_all(pool)
.await?;
let result = rows
.iter()
.map(|row| (row.get("torrent_id"), row.get("album_id")))
.collect();
Ok(result)
}
pub async fn mark_album_completed(pool: &PgPool, torrent_id: Uuid) -> Result<()> {
sqlx::query(
"UPDATE monitored_albums SET completed_at = now(), updated_at = now() WHERE torrent_id = $1",
)
.bind(torrent_id)
.execute(pool)
.await?;
Ok(())
}
+123 -36
View File
@@ -31,6 +31,62 @@ impl ::prost::Name for MonitorAlbumResponse {
"/music.v1.MonitorAlbumResponse".into()
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct MonitorNotificationsRequest {}
impl ::prost::Name for MonitorNotificationsRequest {
const NAME: &'static str = "MonitorNotificationsRequest";
const PACKAGE: &'static str = "music.v1";
fn full_name() -> ::prost::alloc::string::String {
"music.v1.MonitorNotificationsRequest".into()
}
fn type_url() -> ::prost::alloc::string::String {
"/music.v1.MonitorNotificationsRequest".into()
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct NotificationResponse {
#[prost(enumeration = "notification_response::NotificationType", tag = "1")]
pub r#type: i32,
}
/// Nested message and enum types in `NotificationResponse`.
pub mod notification_response {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum NotificationType {
Unknown = 0,
TorrentStatus = 1,
}
impl NotificationType {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
Self::Unknown => "Unknown",
Self::TorrentStatus => "TorrentStatus",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"Unknown" => Some(Self::Unknown),
"TorrentStatus" => Some(Self::TorrentStatus),
_ => None,
}
}
}
}
impl ::prost::Name for NotificationResponse {
const NAME: &'static str = "NotificationResponse";
const PACKAGE: &'static str = "music.v1";
fn full_name() -> ::prost::alloc::string::String {
"music.v1.NotificationResponse".into()
}
fn type_url() -> ::prost::alloc::string::String {
"/music.v1.NotificationResponse".into()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum Quality {
@@ -59,7 +115,7 @@ impl Quality {
}
/// Encoded file descriptor set for the `music.v1` package
pub const FILE_DESCRIPTOR_SET: &[u8] = &[
0x0a, 0xdc, 0x05, 0x0a, 0x14, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x75,
0x0a, 0xc6, 0x09, 0x0a, 0x14, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x75,
0x73, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x6d, 0x75, 0x73, 0x69, 0x63,
0x2e, 0x76, 0x31, 0x22, 0x70, 0x0a, 0x13, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41, 0x6c,
0x62, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c,
@@ -69,42 +125,73 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[
0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6d, 0x75, 0x73, 0x69,
0x63, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x07, 0x71, 0x75,
0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x16, 0x0a, 0x14, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72,
0x41, 0x6c, 0x62, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x1c, 0x0a,
0x07, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x50, 0x33, 0x10,
0x00, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x4c, 0x41, 0x43, 0x10, 0x01, 0x32, 0x5d, 0x0a, 0x0c, 0x4d,
0x75, 0x73, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0c, 0x4d,
0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x62, 0x75, 0x6d, 0x12, 0x1d, 0x2e, 0x6d, 0x75,
0x41, 0x6c, 0x62, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x0a,
0x1b, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8f, 0x01, 0x0a,
0x14, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4e,
0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x32, 0x0a, 0x10, 0x4e, 0x6f,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b,
0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54,
0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x01, 0x2a, 0x1c,
0x0a, 0x07, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x50, 0x33,
0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x4c, 0x41, 0x43, 0x10, 0x01, 0x32, 0x5d, 0x0a, 0x0c,
0x4d, 0x75, 0x73, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0c,
0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x62, 0x75, 0x6d, 0x12, 0x1d, 0x2e, 0x6d,
0x75, 0x73, 0x69, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41,
0x6c, 0x62, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x75,
0x73, 0x69, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41, 0x6c,
0x62, 0x75, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x75, 0x73,
0x69, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x62,
0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4a, 0xaa, 0x03, 0x0a, 0x06, 0x12,
0x04, 0x00, 0x00, 0x15, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a,
0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x11, 0x0a, 0x0a, 0x0a, 0x02, 0x06, 0x00, 0x12,
0x04, 0x04, 0x00, 0x06, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x00, 0x01, 0x12, 0x03, 0x04, 0x08,
0x14, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00, 0x12, 0x03, 0x05, 0x02, 0x47, 0x0a, 0x0c,
0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x05, 0x06, 0x12, 0x0a, 0x0c, 0x0a, 0x05,
0x06, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x05, 0x13, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00,
0x02, 0x00, 0x03, 0x12, 0x03, 0x05, 0x31, 0x45, 0x0a, 0x0a, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04,
0x08, 0x00, 0x0b, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x08, 0x05, 0x0c,
0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x09, 0x02, 0x05, 0x0a, 0x0b,
0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x03, 0x09, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x05,
0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x09, 0x08, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02,
0x01, 0x01, 0x12, 0x03, 0x0a, 0x02, 0x06, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x01, 0x12,
0x03, 0x0a, 0x02, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x0a,
0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x0d, 0x00, 0x11, 0x01, 0x0a, 0x0a,
0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0d, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00,
0x02, 0x00, 0x05, 0x12, 0x03, 0x0e, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00,
0x12, 0x03, 0x0e, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03,
0x0e, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0e, 0x11,
0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x0f, 0x02, 0x08, 0x0a,
0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0f, 0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0f, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00,
0x02, 0x01, 0x03, 0x12, 0x03, 0x0f, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02,
0x06, 0x12, 0x03, 0x10, 0x02, 0x09, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03,
0x10, 0x02, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x10, 0x0a,
0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x10, 0x14, 0x15, 0x0a,
0x0a, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x13, 0x00, 0x15, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04,
0x01, 0x01, 0x12, 0x03, 0x13, 0x08, 0x1c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x62, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4a, 0xe3, 0x05, 0x0a, 0x06,
0x12, 0x04, 0x00, 0x00, 0x21, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x00, 0x00, 0x12,
0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x11, 0x0a, 0x0a, 0x0a, 0x02, 0x06, 0x00,
0x12, 0x04, 0x04, 0x00, 0x07, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x00, 0x01, 0x12, 0x03, 0x04,
0x08, 0x14, 0x0a, 0x64, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00, 0x12, 0x03, 0x05, 0x02, 0x47, 0x22,
0x57, 0x20, 0x72, 0x70, 0x63, 0x20, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x28, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66,
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x29,
0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x28, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x20, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x3b, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00,
0x01, 0x12, 0x03, 0x05, 0x06, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x02, 0x12,
0x03, 0x05, 0x13, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x05,
0x31, 0x45, 0x0a, 0x0a, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x09, 0x00, 0x0c, 0x01, 0x0a, 0x0a,
0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x09, 0x05, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00,
0x02, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x02, 0x05, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00,
0x12, 0x03, 0x0a, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03,
0x0a, 0x08, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0b, 0x02,
0x06, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0b, 0x02, 0x0b, 0x0a, 0x0c,
0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x0b, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,
0x04, 0x00, 0x12, 0x04, 0x0e, 0x00, 0x12, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12,
0x03, 0x0e, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0f,
0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0f, 0x02, 0x13, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0f, 0x09, 0x0e, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0f, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x10, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02,
0x01, 0x12, 0x03, 0x10, 0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12,
0x03, 0x10, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x10,
0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x11, 0x02, 0x09,
0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x11, 0x02, 0x16, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x11, 0x0a, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x11, 0x14, 0x15, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x01, 0x12,
0x04, 0x14, 0x00, 0x16, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x14, 0x08,
0x1c, 0x0a, 0x09, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x03, 0x18, 0x00, 0x26, 0x0a, 0x0a, 0x0a, 0x03,
0x04, 0x02, 0x01, 0x12, 0x03, 0x18, 0x08, 0x23, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04,
0x1a, 0x00, 0x21, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x1a, 0x08, 0x1c,
0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x04, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1e, 0x03, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x07, 0x17, 0x0a, 0x0e, 0x0a, 0x07,
0x04, 0x03, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1c, 0x04, 0x0b, 0x0a, 0x0d, 0x0a, 0x06,
0x04, 0x03, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x1c, 0x04, 0x10, 0x0a, 0x0e, 0x0a, 0x07, 0x04,
0x03, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x1c, 0x0e, 0x0f, 0x0a, 0x0e, 0x0a, 0x07, 0x04,
0x03, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x1d, 0x04, 0x11, 0x0a, 0x0d, 0x0a, 0x06, 0x04,
0x03, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x1d, 0x04, 0x16, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03,
0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x1d, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03,
0x02, 0x00, 0x06, 0x12, 0x03, 0x20, 0x02, 0x12, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00,
0x12, 0x03, 0x20, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03,
0x20, 0x13, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x20, 0x1a,
0x1b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
];
include!("music.v1.serde.rs");
include!("music.v1.tonic.rs");
+249
View File
@@ -200,6 +200,255 @@ impl<'de> serde::Deserialize<'de> for MonitorAlbumResponse {
deserializer.deserialize_struct("music.v1.MonitorAlbumResponse", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for MonitorNotificationsRequest {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let len = 0;
let struct_ser =
serializer.serialize_struct("music.v1.MonitorNotificationsRequest", len)?;
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for MonitorNotificationsRequest {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[];
#[allow(clippy::enum_variant_names)]
enum GeneratedField {}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
D: serde::Deserializer<'de>,
{
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = GeneratedField;
fn expecting(
&self,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}
#[allow(unused_variables)]
fn visit_str<E>(self, value: &str) -> std::result::Result<GeneratedField, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::unknown_field(value, FIELDS))
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = MonitorNotificationsRequest;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct music.v1.MonitorNotificationsRequest")
}
fn visit_map<V>(
self,
mut map_: V,
) -> std::result::Result<MonitorNotificationsRequest, V::Error>
where
V: serde::de::MapAccess<'de>,
{
while map_.next_key::<GeneratedField>()?.is_some() {
let _ = map_.next_value::<serde::de::IgnoredAny>()?;
}
Ok(MonitorNotificationsRequest {})
}
}
deserializer.deserialize_struct(
"music.v1.MonitorNotificationsRequest",
FIELDS,
GeneratedVisitor,
)
}
}
impl serde::Serialize for NotificationResponse {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut len = 0;
if self.r#type != 0 {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("music.v1.NotificationResponse", len)?;
if self.r#type != 0 {
let v =
notification_response::NotificationType::try_from(self.r#type).map_err(|_| {
serde::ser::Error::custom(format!("Invalid variant {}", self.r#type))
})?;
struct_ser.serialize_field("type", &v)?;
}
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for NotificationResponse {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &["type"];
#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Type,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
D: serde::Deserializer<'de>,
{
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = GeneratedField;
fn expecting(
&self,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}
#[allow(unused_variables)]
fn visit_str<E>(self, value: &str) -> std::result::Result<GeneratedField, E>
where
E: serde::de::Error,
{
match value {
"type" => Ok(GeneratedField::Type),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = NotificationResponse;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct music.v1.NotificationResponse")
}
fn visit_map<V>(
self,
mut map_: V,
) -> std::result::Result<NotificationResponse, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut r#type__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Type => {
if r#type__.is_some() {
return Err(serde::de::Error::duplicate_field("type"));
}
r#type__ = Some(
map_.next_value::<notification_response::NotificationType>()?
as i32,
);
}
}
}
Ok(NotificationResponse {
r#type: r#type__.unwrap_or_default(),
})
}
}
deserializer.deserialize_struct("music.v1.NotificationResponse", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for notification_response::NotificationType {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let variant = match self {
Self::Unknown => "Unknown",
Self::TorrentStatus => "TorrentStatus",
};
serializer.serialize_str(variant)
}
}
impl<'de> serde::Deserialize<'de> for notification_response::NotificationType {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &["Unknown", "TorrentStatus"];
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = notification_response::NotificationType;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}
fn visit_i64<E>(self, v: i64) -> std::result::Result<Self::Value, E>
where
E: serde::de::Error,
{
i32::try_from(v)
.ok()
.and_then(|x| x.try_into().ok())
.ok_or_else(|| {
serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self)
})
}
fn visit_u64<E>(self, v: u64) -> std::result::Result<Self::Value, E>
where
E: serde::de::Error,
{
i32::try_from(v)
.ok()
.and_then(|x| x.try_into().ok())
.ok_or_else(|| {
serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), &self)
})
}
fn visit_str<E>(self, value: &str) -> std::result::Result<Self::Value, E>
where
E: serde::de::Error,
{
match value {
"Unknown" => Ok(notification_response::NotificationType::Unknown),
"TorrentStatus" => Ok(notification_response::NotificationType::TorrentStatus),
_ => Err(serde::de::Error::unknown_variant(value, FIELDS)),
}
}
}
deserializer.deserialize_any(GeneratedVisitor)
}
}
impl serde::Serialize for Quality {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
+584 -370
View File
@@ -333,9 +333,92 @@ impl ::prost::Name for UpdateMusicMetadataResponse {
"/musicfs.UpdateMusicMetadataResponse".into()
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ListFilesRequest {}
impl ::prost::Name for ListFilesRequest {
const NAME: &'static str = "ListFilesRequest";
const PACKAGE: &'static str = "musicfs";
fn full_name() -> ::prost::alloc::string::String {
"musicfs.ListFilesRequest".into()
}
fn type_url() -> ::prost::alloc::string::String {
"/musicfs.ListFilesRequest".into()
}
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListFilesResponse {
#[prost(message, repeated, tag = "1")]
pub files: ::prost::alloc::vec::Vec<FileEntry>,
}
impl ::prost::Name for ListFilesResponse {
const NAME: &'static str = "ListFilesResponse";
const PACKAGE: &'static str = "musicfs";
fn full_name() -> ::prost::alloc::string::String {
"musicfs.ListFilesResponse".into()
}
fn type_url() -> ::prost::alloc::string::String {
"/musicfs.ListFilesResponse".into()
}
}
/// Human-readable tag fields only. Excludes the binary layout fields
/// (header, picture_block_headers, etc.) that only make sense inside
/// musicfs's FUSE read-assembly path.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FileMetadata {
#[prost(string, repeated, tag = "1")]
pub artist: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
#[prost(string, optional, tag = "2")]
pub album_artist: ::core::option::Option<::prost::alloc::string::String>,
#[prost(string, tag = "3")]
pub album: ::prost::alloc::string::String,
#[prost(int32, tag = "4")]
pub track_number: i32,
#[prost(string, tag = "5")]
pub track_title: ::prost::alloc::string::String,
#[prost(string, repeated, tag = "6")]
pub other_tags: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
impl ::prost::Name for FileMetadata {
const NAME: &'static str = "FileMetadata";
const PACKAGE: &'static str = "musicfs";
fn full_name() -> ::prost::alloc::string::String {
"musicfs.FileMetadata".into()
}
fn type_url() -> ::prost::alloc::string::String {
"/musicfs.FileMetadata".into()
}
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct FileEntry {
#[prost(uint64, tag = "1")]
pub inode: u64,
/// Real on-disk path (where tora/librqbit wrote the file).
#[prost(string, tag = "2")]
pub original_path: ::prost::alloc::string::String,
/// Virtual FUSE path ({artist}/{album}/{filename}); updated when metadata
/// changes via `UpdateMusicMetadata`.
#[prost(string, tag = "3")]
pub local_path: ::prost::alloc::string::String,
/// Filename component only.
#[prost(string, tag = "4")]
pub name: ::prost::alloc::string::String,
/// Empty if the file has no parsed tags.
#[prost(message, optional, tag = "5")]
pub metadata: ::core::option::Option<FileMetadata>,
}
impl ::prost::Name for FileEntry {
const NAME: &'static str = "FileEntry";
const PACKAGE: &'static str = "musicfs";
fn full_name() -> ::prost::alloc::string::String {
"musicfs.FileEntry".into()
}
fn type_url() -> ::prost::alloc::string::String {
"/musicfs.FileEntry".into()
}
}
/// Encoded file descriptor set for the `musicfs` package
pub const FILE_DESCRIPTOR_SET: &[u8] = &[
0x0a, 0xbe, 0x3e, 0x0a, 0x0d, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x0a, 0xee, 0x4e, 0x0a, 0x0d, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x07, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x52,
0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x2c, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
@@ -465,376 +548,507 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[
0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x16, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x4d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x32, 0xdf, 0x02, 0x0a, 0x07, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x46, 0x73, 0x12, 0x42, 0x0a,
0x09, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x6d, 0x75, 0x73,
0x69, 0x63, 0x66, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e,
0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x44, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x12, 0x1b, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61,
0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73,
0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x4d, 0x61,
0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x30, 0x01, 0x12, 0x38, 0x0a,
0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x17, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63,
0x66, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x12, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65,
0x43, 0x68, 0x75, 0x6e, 0x6b, 0x30, 0x01, 0x12, 0x4a, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63,
0x72, 0x69, 0x62, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x75, 0x73,
0x69, 0x63, 0x66, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x45, 0x76,
0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6d, 0x75,
0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e,
0x74, 0x30, 0x01, 0x32, 0x61, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x12, 0x51, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73,
0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66,
0x73, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xca, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x57, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d,
0x75, 0x73, 0x69, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x20, 0x2e, 0x6d,
0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x4d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x75, 0x73, 0x69,
0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x60, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x73, 0x69, 0x63,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x23, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63,
0x66, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x4d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e,
0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x75,
0x73, 0x69, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x4a, 0x83, 0x29, 0x0a, 0x07, 0x12, 0x05, 0x00, 0x00, 0x91, 0x01, 0x01, 0x0a,
0x08, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03,
0x02, 0x00, 0x10, 0x0a, 0x62, 0x0a, 0x02, 0x06, 0x00, 0x12, 0x04, 0x06, 0x00, 0x20, 0x01, 0x1a,
0x56, 0x20, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x46, 0x73, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x20, 0x6c, 0x69,
0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x74,
0x65, 0x20, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x0a, 0x20, 0x46, 0x55, 0x53, 0x45, 0x20,
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x00, 0x01, 0x12, 0x03,
0x06, 0x08, 0x0f, 0x0a, 0xac, 0x02, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0b, 0x02,
0x3e, 0x1a, 0x9e, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x2d, 0x62, 0x61, 0x73, 0x65, 0x64, 0x20,
0x72, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x68, 0x65,
0x20, 0x28, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x68, 0x61, 0x73, 0x68, 0x29, 0x20, 0x70,
0x61, 0x69, 0x72, 0x73, 0x20, 0x69, 0x74, 0x0a, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x6c, 0x79, 0x20, 0x68, 0x61, 0x73, 0x3b, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x72,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65,
0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x64, 0x20, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x68, 0x61,
0x73, 0x68, 0x2d, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x70, 0x6c,
0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x20, 0x74, 0x68,
0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x75, 0x74,
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x6e, 0x6f, 0x20, 0x6c,
0x6f, 0x6e, 0x67, 0x65, 0x72, 0x0a, 0x20, 0x68, 0x61, 0x73, 0x2e, 0x20, 0x43, 0x68, 0x65, 0x61,
0x70, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x69, 0x72, 0x65, 0x20, 0xe2, 0x80,
0x94, 0x20, 0x6e, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c,
0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x73, 0x6b, 0x73,
0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x06, 0x0f,
0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x0b, 0x10, 0x20, 0x0a, 0x0c,
0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0b, 0x2b, 0x3c, 0x0a, 0x94, 0x01, 0x0a,
0x04, 0x06, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0f, 0x02, 0x45, 0x1a, 0x86, 0x01, 0x20, 0x46, 0x65,
0x74, 0x63, 0x68, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63,
0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x20,
0x43, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x52, 0x65, 0x63,
0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20,
0x61, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x60, 0x63, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x64, 0x60, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x20,
0x6a, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x6f, 0x64, 0x65,
0x73, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0f, 0x06,
0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x0f, 0x12, 0x24, 0x0a,
0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, 0x0f, 0x2f, 0x35, 0x0a, 0x0c, 0x0a,
0x05, 0x06, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0f, 0x36, 0x43, 0x0a, 0xa8, 0x01, 0x0a, 0x04,
0x06, 0x00, 0x02, 0x02, 0x12, 0x03, 0x14, 0x02, 0x45, 0x1a, 0x9a, 0x01, 0x20, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x65,
0x6e, 0x74, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x62, 0x72,
0x61, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x63, 0x65,
0x20, 0x52, 0x50, 0x43, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x72,
0x75, 0x6e, 0x0a, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e,
0x67, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x2d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73,
0x68, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x2d, 0x62, 0x61, 0x73, 0x65,
0x64, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x20, 0x70, 0x61, 0x74, 0x68,
0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20,
0x63, 0x61, 0x73, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x01, 0x12,
0x03, 0x14, 0x06, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, 0x14,
0x12, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x14, 0x2f, 0x35,
0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x14, 0x36, 0x43, 0x0a, 0xf8,
0x01, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x03, 0x12, 0x03, 0x1a, 0x02, 0x39, 0x1a, 0xea, 0x01, 0x20,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73,
0x20, 0x6f, 0x66, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x20, 0x49, 0x66,
0x20, 0x60, 0x73, 0x74, 0x61, 0x72, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x60, 0x20, 0x61, 0x72, 0x65, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x7a,
0x65, 0x72, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
0x61, 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c,
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x66, 0x69,
0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x75, 0x73, 0x69,
0x63, 0x66, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x66,
0x69, 0x6c, 0x65, 0x73, 0x22, 0xd8, 0x01, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x74,
0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x18,
0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x12, 0x26, 0x0a,
0x0c, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x41, 0x72, 0x74, 0x69,
0x73, 0x74, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x74,
0x72, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1f,
0x0a, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12,
0x1d, 0x0a, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20,
0x03, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x42, 0x0f,
0x0a, 0x0d, 0x5f, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x22,
0xbe, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a,
0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e,
0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f,
0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x72, 0x69, 0x67,
0x69, 0x6e, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61,
0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x6d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e,
0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x32, 0xdf, 0x02, 0x0a, 0x07, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x46, 0x73, 0x12, 0x42, 0x0a, 0x09,
0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x6d, 0x75, 0x73, 0x69,
0x63, 0x66, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x52,
0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x44, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
0x1b, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74,
0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d,
0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e,
0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e,
0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x4d, 0x61, 0x6e,
0x69, 0x66, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x30, 0x01, 0x12, 0x38, 0x0a, 0x07,
0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x17, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66,
0x73, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x12, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43,
0x68, 0x75, 0x6e, 0x6b, 0x30, 0x01, 0x12, 0x4a, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
0x69, 0x62, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x75, 0x73, 0x69,
0x63, 0x66, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6d, 0x75, 0x73,
0x69, 0x63, 0x66, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74,
0x30, 0x01, 0x32, 0x61, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x12, 0x51, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e,
0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73,
0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8e, 0x02, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x57, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d, 0x75,
0x73, 0x69, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x20, 0x2e, 0x6d, 0x75,
0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x4d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e,
0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x75, 0x73, 0x69, 0x63,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x60, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x4d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x23, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66,
0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x4d, 0x65, 0x74,
0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d,
0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x75, 0x73,
0x69, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12,
0x19, 0x2e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69,
0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x75, 0x73,
0x69, 0x63, 0x66, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4a, 0x80, 0x35, 0x0a, 0x07, 0x12, 0x05, 0x00, 0x00, 0xb4,
0x01, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01,
0x02, 0x12, 0x03, 0x02, 0x00, 0x10, 0x0a, 0x62, 0x0a, 0x02, 0x06, 0x00, 0x12, 0x04, 0x06, 0x00,
0x20, 0x01, 0x1a, 0x56, 0x20, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x46, 0x73, 0x20, 0x73, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73,
0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x69, 0x63,
0x20, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x72, 0x65,
0x6d, 0x6f, 0x74, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x0a, 0x20, 0x46, 0x55,
0x53, 0x45, 0x20, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x00,
0x01, 0x12, 0x03, 0x06, 0x08, 0x0f, 0x0a, 0xac, 0x02, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00, 0x12,
0x03, 0x0b, 0x02, 0x3e, 0x1a, 0x9e, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x2d, 0x62, 0x61, 0x73,
0x65, 0x64, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x69, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x2e, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x73, 0x20,
0x74, 0x68, 0x65, 0x20, 0x28, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x68, 0x61, 0x73, 0x68,
0x29, 0x20, 0x70, 0x61, 0x69, 0x72, 0x73, 0x20, 0x69, 0x74, 0x0a, 0x20, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x68, 0x61, 0x73, 0x3b, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20,
0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x6f, 0x72, 0x0a,
0x20, 0x68, 0x61, 0x73, 0x68, 0x2d, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x29,
0x20, 0x70, 0x6c, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x73,
0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20,
0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x6e,
0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x0a, 0x20, 0x68, 0x61, 0x73, 0x2e, 0x20, 0x43,
0x68, 0x65, 0x61, 0x70, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x69, 0x72, 0x65,
0x20, 0xe2, 0x80, 0x94, 0x20, 0x6e, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x74,
0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x73, 0x20, 0x75, 0x6e,
0x74, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61,
0x73, 0x6b, 0x73, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03,
0x0b, 0x06, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x0b, 0x10,
0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0b, 0x2b, 0x3c, 0x0a,
0x94, 0x01, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0f, 0x02, 0x45, 0x1a, 0x86, 0x01,
0x20, 0x46, 0x65, 0x74, 0x63, 0x68, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69,
0x66, 0x69, 0x63, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x6f, 0x64, 0x65,
0x73, 0x2e, 0x20, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20,
0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x73, 0x20, 0x61, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x60,
0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x60, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x66,
0x6f, 0x72, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x69, 0x6e,
0x6f, 0x64, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x01, 0x12,
0x03, 0x0f, 0x06, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x0f,
0x12, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, 0x0f, 0x2f, 0x35,
0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0f, 0x36, 0x43, 0x0a, 0xa8,
0x01, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x02, 0x12, 0x03, 0x14, 0x02, 0x45, 0x1a, 0x9a, 0x01, 0x20,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c,
0x65, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c,
0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x2e, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x69, 0x65,
0x6e, 0x63, 0x65, 0x20, 0x52, 0x50, 0x43, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x69, 0x72, 0x73,
0x74, 0x2d, 0x72, 0x75, 0x6e, 0x0a, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70,
0x70, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x2d, 0x72, 0x65, 0x66,
0x72, 0x65, 0x73, 0x68, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x69, 0x66, 0x66, 0x2d, 0x62,
0x61, 0x73, 0x65, 0x64, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x20, 0x70,
0x61, 0x74, 0x68, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x6e, 0x6f, 0x72, 0x6d,
0x61, 0x6c, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02,
0x02, 0x01, 0x12, 0x03, 0x14, 0x06, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x02,
0x12, 0x03, 0x14, 0x12, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03,
0x14, 0x2f, 0x35, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x14, 0x36,
0x43, 0x0a, 0xf8, 0x01, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x03, 0x12, 0x03, 0x1a, 0x02, 0x39, 0x1a,
0xea, 0x01, 0x20, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x79,
0x74, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e,
0x20, 0x49, 0x66, 0x20, 0x60, 0x73, 0x74, 0x61, 0x72, 0x74, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20,
0x60, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x60, 0x20, 0x61, 0x72, 0x65, 0x20, 0x62, 0x6f, 0x74,
0x68, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65,
0x6e, 0x74, 0x69, 0x72, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3b, 0x20, 0x6f, 0x74, 0x68, 0x65,
0x72, 0x77, 0x69, 0x73, 0x65, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x20,
0x54, 0x68, 0x65, 0x0a, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x63, 0x68, 0x75, 0x6e, 0x6b,
0x20, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x73, 0x20, 0x60, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f,
0x73, 0x69, 0x7a, 0x65, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x6f, 0x66, 0x66, 0x73, 0x65,
0x74, 0x60, 0x3b, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x20, 0x63,
0x68, 0x75, 0x6e, 0x6b, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x0a, 0x20,
0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05,
0x06, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x1a, 0x06, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00,
0x02, 0x03, 0x02, 0x12, 0x03, 0x1a, 0x0e, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03,
0x06, 0x12, 0x03, 0x1a, 0x27, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x03, 0x12,
0x03, 0x1a, 0x2e, 0x37, 0x0a, 0xc2, 0x01, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x04, 0x12, 0x03, 0x1f,
0x02, 0x4b, 0x1a, 0xb4, 0x01, 0x20, 0x4c, 0x6f, 0x6e, 0x67, 0x2d, 0x6c, 0x69, 0x76, 0x65, 0x64,
0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73,
0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x65, 0x76, 0x65,
0x6e, 0x74, 0x73, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20,
0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x73, 0x0a, 0x20, 0x77,
0x61, 0x6b, 0x65, 0x2d, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x66, 0x65, 0x74,
0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x3b,
0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6c, 0x77,
0x61, 0x79, 0x73, 0x20, 0x72, 0x65, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65,
0x20, 0x68, 0x61, 0x73, 0x68, 0x0a, 0x20, 0x64, 0x69, 0x66, 0x66, 0x2c, 0x20, 0x6e, 0x65, 0x76,
0x65, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20,
0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02,
0x04, 0x01, 0x12, 0x03, 0x1f, 0x06, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x02,
0x12, 0x03, 0x1f, 0x16, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x06, 0x12, 0x03,
0x1f, 0x37, 0x3d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x1f, 0x3e,
0x49, 0x0a, 0x4f, 0x0a, 0x02, 0x06, 0x01, 0x12, 0x04, 0x23, 0x00, 0x25, 0x01, 0x1a, 0x43, 0x20,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74,
0x75, 0x73, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, 0x65,
0x72, 0x76, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x55, 0x53, 0x45,
0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x29,
0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x01, 0x01, 0x12, 0x03, 0x23, 0x08, 0x14, 0x0a, 0x0b,
0x0a, 0x04, 0x06, 0x01, 0x02, 0x00, 0x12, 0x03, 0x24, 0x02, 0x4d, 0x0a, 0x0c, 0x0a, 0x05, 0x06,
0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x24, 0x06, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x01, 0x02,
0x00, 0x02, 0x12, 0x03, 0x24, 0x16, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x01, 0x02, 0x00, 0x03,
0x12, 0x03, 0x24, 0x37, 0x4b, 0x0a, 0x0a, 0x0a, 0x02, 0x06, 0x02, 0x12, 0x04, 0x27, 0x00, 0x2e,
0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x02, 0x01, 0x12, 0x03, 0x27, 0x08, 0x15, 0x0a, 0x0b, 0x0a,
0x04, 0x06, 0x02, 0x02, 0x00, 0x12, 0x03, 0x28, 0x02, 0x53, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02,
0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x06, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x00,
0x02, 0x12, 0x03, 0x28, 0x17, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x00, 0x03, 0x12,
0x03, 0x28, 0x39, 0x51, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x02, 0x02, 0x01, 0x12, 0x03, 0x29, 0x02,
0x5c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x29, 0x06, 0x19, 0x0a,
0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x01, 0x02, 0x12, 0x03, 0x29, 0x1a, 0x34, 0x0a, 0x0c, 0x0a,
0x05, 0x06, 0x02, 0x02, 0x01, 0x03, 0x12, 0x03, 0x29, 0x3f, 0x5a, 0x0a, 0xb4, 0x01, 0x0a, 0x04,
0x06, 0x02, 0x02, 0x02, 0x12, 0x03, 0x2d, 0x02, 0x3e, 0x1a, 0xa6, 0x01, 0x20, 0x45, 0x76, 0x65,
0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x66, 0x73, 0x20,
0x6b, 0x6e, 0x6f, 0x77, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x2e, 0x20, 0x43, 0x61, 0x6c,
0x6c, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x20, 0x62, 0x79, 0x20, 0x60,
0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x60, 0x0a, 0x20,
0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x74,
0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x65, 0x73, 0x74, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x66,
0x69, 0x6c, 0x65, 0x73, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e,
0x67, 0x6c, 0x65, 0x0a, 0x20, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x27, 0x73, 0x20, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x29,
0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x02, 0x01, 0x12, 0x03, 0x2d, 0x06, 0x0f,
0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x02, 0x02, 0x12, 0x03, 0x2d, 0x10, 0x20, 0x0a, 0x0c,
0x0a, 0x05, 0x06, 0x02, 0x02, 0x02, 0x03, 0x12, 0x03, 0x2d, 0x2b, 0x3c, 0x0a, 0x0a, 0x0a, 0x02,
0x04, 0x00, 0x12, 0x04, 0x30, 0x00, 0x32, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12,
0x03, 0x30, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x31,
0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x31, 0x02, 0x21, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x31, 0x0b, 0x14, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x31, 0x15, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x31, 0x1f, 0x20, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x01, 0x12,
0x04, 0x34, 0x00, 0x37, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x34, 0x08,
0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x35, 0x02, 0x0a, 0x0a,
0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x35, 0x02, 0x21, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x35, 0x0b, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01,
0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x15, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00,
0x03, 0x12, 0x03, 0x35, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x04, 0x12,
0x03, 0x36, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x36, 0x02,
0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x36, 0x0b, 0x11, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x36, 0x12, 0x19, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x36, 0x1c, 0x1d, 0x0a, 0x0a, 0x0a, 0x02, 0x04,
0x02, 0x12, 0x04, 0x39, 0x00, 0x3c, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03,
0x39, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, 0x03, 0x3a, 0x02,
0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, 0x3a, 0x02, 0x13, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x3a, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x3a, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02,
0x02, 0x01, 0x05, 0x12, 0x03, 0x3b, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x01,
0x12, 0x03, 0x3b, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03,
0x3b, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x03, 0x12, 0x03, 0x3b, 0x10,
0x11, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x3e, 0x00, 0x40, 0x01, 0x0a, 0x0a, 0x0a,
0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x3e, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02,
0x00, 0x04, 0x12, 0x03, 0x3f, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12,
0x03, 0x3f, 0x02, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x05, 0x12, 0x03, 0x3f,
0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x3f, 0x12, 0x18,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x3f, 0x1b, 0x1c, 0x0a, 0x09,
0x0a, 0x02, 0x04, 0x04, 0x12, 0x03, 0x42, 0x00, 0x1d, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01,
0x12, 0x03, 0x42, 0x08, 0x1a, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x04, 0x44, 0x00, 0x49,
0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x44, 0x08, 0x16, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x05, 0x02, 0x00, 0x05, 0x12, 0x03, 0x45, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x05, 0x02, 0x00, 0x12, 0x03, 0x45, 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00,
0x01, 0x12, 0x03, 0x45, 0x09, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x03, 0x12,
0x03, 0x45, 0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x05, 0x12, 0x03, 0x47,
0x02, 0x08, 0x0a, 0x45, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, 0x03, 0x47, 0x02, 0x13, 0x1a,
0x38, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x61, 0x72, 0x65, 0x20,
0x7a, 0x65, 0x72, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x74, 0x69,
0x72, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3b, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69,
0x73, 0x65, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x20, 0x54, 0x68, 0x65,
0x0a, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x20, 0x63, 0x61,
0x72, 0x72, 0x69, 0x65, 0x73, 0x20, 0x60, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x7a,
0x65, 0x60, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x60, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x60, 0x3b,
0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x75, 0x6e,
0x6b, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x0a, 0x20, 0x66, 0x72, 0x6f,
0x6d, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02,
0x03, 0x01, 0x12, 0x03, 0x1a, 0x06, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x02,
0x12, 0x03, 0x1a, 0x0e, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x06, 0x12, 0x03,
0x1a, 0x27, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x1a, 0x2e,
0x37, 0x0a, 0xc2, 0x01, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x04, 0x12, 0x03, 0x1f, 0x02, 0x4b, 0x1a,
0xb4, 0x01, 0x20, 0x4c, 0x6f, 0x6e, 0x67, 0x2d, 0x6c, 0x69, 0x76, 0x65, 0x64, 0x20, 0x73, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73,
0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x75, 0x73, 0x65,
0x73, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x61, 0x73, 0x0a, 0x20, 0x77, 0x61, 0x6b, 0x65,
0x2d, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x66, 0x65, 0x74, 0x63, 0x68, 0x20,
0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x3b, 0x20, 0x63, 0x6f,
0x72, 0x72, 0x65, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73,
0x20, 0x72, 0x65, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61,
0x73, 0x68, 0x0a, 0x20, 0x64, 0x69, 0x66, 0x66, 0x2c, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20,
0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x01, 0x12,
0x03, 0x1f, 0x06, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x02, 0x12, 0x03, 0x1f,
0x16, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x06, 0x12, 0x03, 0x1f, 0x37, 0x3d,
0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x04, 0x03, 0x12, 0x03, 0x1f, 0x3e, 0x49, 0x0a, 0x0a,
0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x22, 0x00, 0x24, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00,
0x01, 0x12, 0x03, 0x22, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x04, 0x12,
0x03, 0x23, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x23, 0x02,
0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x23, 0x0b, 0x14, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x23, 0x15, 0x1c, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x23, 0x1f, 0x20, 0x0a, 0x0a, 0x0a, 0x02, 0x04,
0x01, 0x12, 0x04, 0x26, 0x00, 0x29, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03,
0x26, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x27, 0x02,
0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x27, 0x02, 0x21, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x27, 0x0b, 0x14, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x27, 0x15, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01,
0x02, 0x00, 0x03, 0x12, 0x03, 0x27, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01,
0x04, 0x12, 0x03, 0x28, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03,
0x28, 0x02, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x28, 0x0b,
0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x28, 0x12, 0x19, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x28, 0x1c, 0x1d, 0x0a, 0x0a, 0x0a,
0x02, 0x04, 0x02, 0x12, 0x04, 0x2b, 0x00, 0x2e, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01,
0x12, 0x03, 0x2b, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, 0x03,
0x2c, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, 0x2c, 0x02, 0x13,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2c, 0x09, 0x0e, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2c, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x02, 0x02, 0x01, 0x05, 0x12, 0x03, 0x2d, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02,
0x02, 0x01, 0x12, 0x03, 0x2d, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x01,
0x12, 0x03, 0x2d, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x03, 0x12, 0x03,
0x2d, 0x10, 0x11, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x30, 0x00, 0x32, 0x01, 0x0a,
0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x30, 0x08, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x03, 0x02, 0x00, 0x04, 0x12, 0x03, 0x31, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02,
0x00, 0x12, 0x03, 0x31, 0x02, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x05, 0x12,
0x03, 0x31, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x31,
0x12, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x31, 0x1b, 0x1c,
0x0a, 0x09, 0x0a, 0x02, 0x04, 0x04, 0x12, 0x03, 0x34, 0x00, 0x1d, 0x0a, 0x0a, 0x0a, 0x03, 0x04,
0x04, 0x01, 0x12, 0x03, 0x34, 0x08, 0x1a, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x04, 0x36,
0x00, 0x3b, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x36, 0x08, 0x16, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x05, 0x12, 0x03, 0x37, 0x02, 0x08, 0x0a, 0x0b, 0x0a,
0x04, 0x04, 0x05, 0x02, 0x00, 0x12, 0x03, 0x37, 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05,
0x02, 0x00, 0x01, 0x12, 0x03, 0x37, 0x09, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00,
0x03, 0x12, 0x03, 0x37, 0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x05, 0x12,
0x03, 0x39, 0x02, 0x08, 0x0a, 0x45, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x01, 0x12, 0x03, 0x39, 0x02,
0x13, 0x1a, 0x38, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x61, 0x72,
0x65, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e,
0x74, 0x69, 0x72, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x05, 0x02, 0x01, 0x01, 0x12, 0x03, 0x39, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02,
0x01, 0x03, 0x12, 0x03, 0x39, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x05,
0x12, 0x03, 0x3a, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x02, 0x12, 0x03, 0x3a,
0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x01, 0x12, 0x03, 0x3a, 0x09, 0x0f,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x03, 0x12, 0x03, 0x3a, 0x12, 0x13, 0x0a, 0x09,
0x0a, 0x02, 0x04, 0x06, 0x12, 0x03, 0x3d, 0x00, 0x21, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x06, 0x01,
0x12, 0x03, 0x3d, 0x08, 0x1e, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x07, 0x12, 0x04, 0x3f, 0x00, 0x47,
0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x07, 0x01, 0x12, 0x03, 0x3f, 0x08, 0x15, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x07, 0x02, 0x00, 0x05, 0x12, 0x03, 0x40, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x07, 0x02, 0x00, 0x12, 0x03, 0x40, 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00,
0x01, 0x12, 0x03, 0x40, 0x09, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12,
0x03, 0x40, 0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x05, 0x12, 0x03, 0x41,
0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x01, 0x12, 0x03, 0x41, 0x02, 0x16, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x01, 0x12, 0x03, 0x41, 0x09, 0x11, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x07, 0x02, 0x01, 0x03, 0x12, 0x03, 0x41, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x07, 0x02, 0x02, 0x05, 0x12, 0x03, 0x42, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02,
0x02, 0x12, 0x03, 0x42, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x02, 0x01, 0x12,
0x03, 0x42, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x02, 0x03, 0x12, 0x03, 0x42,
0x10, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x05, 0x12, 0x03, 0x43, 0x02, 0x08,
0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x03, 0x12, 0x03, 0x43, 0x02, 0x13, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x07, 0x02, 0x03, 0x01, 0x12, 0x03, 0x43, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x07, 0x02, 0x03, 0x03, 0x12, 0x03, 0x43, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02,
0x04, 0x05, 0x12, 0x03, 0x44, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x04, 0x12,
0x03, 0x44, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x04, 0x01, 0x12, 0x03, 0x44,
0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x04, 0x03, 0x12, 0x03, 0x44, 0x11, 0x12,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x05, 0x05, 0x12, 0x03, 0x45, 0x02, 0x08, 0x0a, 0x0b,
0x0a, 0x04, 0x04, 0x07, 0x02, 0x05, 0x12, 0x03, 0x45, 0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x07, 0x02, 0x05, 0x01, 0x12, 0x03, 0x45, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02,
0x05, 0x03, 0x12, 0x03, 0x45, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x06, 0x06,
0x12, 0x03, 0x46, 0x02, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x06, 0x12, 0x03, 0x46,
0x02, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x06, 0x01, 0x12, 0x03, 0x46, 0x10, 0x1e,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x06, 0x03, 0x12, 0x03, 0x46, 0x21, 0x22, 0x0a, 0x0a,
0x0a, 0x02, 0x04, 0x08, 0x12, 0x04, 0x49, 0x00, 0x56, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x08,
0x01, 0x12, 0x03, 0x49, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x04, 0x12,
0x03, 0x4a, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x00, 0x12, 0x03, 0x4a, 0x02,
0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x05, 0x12, 0x03, 0x4a, 0x0b, 0x11, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x01, 0x12, 0x03, 0x4a, 0x12, 0x18, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x08, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4a, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x08, 0x02, 0x01, 0x04, 0x12, 0x03, 0x4b, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02,
0x01, 0x12, 0x03, 0x4b, 0x02, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x05, 0x12,
0x03, 0x4b, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x01, 0x12, 0x03, 0x4b,
0x12, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x03, 0x12, 0x03, 0x4b, 0x21, 0x22,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x02, 0x05, 0x12, 0x03, 0x4c, 0x02, 0x08, 0x0a, 0x0b,
0x0a, 0x04, 0x04, 0x08, 0x02, 0x02, 0x12, 0x03, 0x4c, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x08, 0x02, 0x02, 0x01, 0x12, 0x03, 0x4c, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02,
0x02, 0x03, 0x12, 0x03, 0x4c, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x03, 0x05,
0x12, 0x03, 0x4d, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x03, 0x12, 0x03, 0x4d,
0x02, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x03, 0x01, 0x12, 0x03, 0x4d, 0x08, 0x14,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x03, 0x03, 0x12, 0x03, 0x4d, 0x17, 0x18, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x08, 0x02, 0x04, 0x05, 0x12, 0x03, 0x4e, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x08, 0x02, 0x04, 0x12, 0x03, 0x4e, 0x02, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02,
0x04, 0x01, 0x12, 0x03, 0x4e, 0x09, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x04, 0x03,
0x12, 0x03, 0x4e, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x05, 0x04, 0x12, 0x03,
0x4f, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x05, 0x12, 0x03, 0x4f, 0x02, 0x21,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x05, 0x05, 0x12, 0x03, 0x4f, 0x0b, 0x11, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x08, 0x02, 0x05, 0x01, 0x12, 0x03, 0x4f, 0x12, 0x1c, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x08, 0x02, 0x05, 0x03, 0x12, 0x03, 0x4f, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08,
0x02, 0x06, 0x05, 0x12, 0x03, 0x50, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x06,
0x12, 0x03, 0x50, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x06, 0x01, 0x12, 0x03,
0x50, 0x08, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x06, 0x03, 0x12, 0x03, 0x50, 0x11,
0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x07, 0x04, 0x12, 0x03, 0x51, 0x02, 0x0a, 0x0a,
0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x07, 0x12, 0x03, 0x51, 0x02, 0x2b, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x08, 0x02, 0x07, 0x05, 0x12, 0x03, 0x51, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08,
0x02, 0x07, 0x01, 0x12, 0x03, 0x51, 0x11, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x07,
0x03, 0x12, 0x03, 0x51, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x08, 0x04, 0x12,
0x03, 0x52, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x08, 0x12, 0x03, 0x52, 0x02,
0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x08, 0x06, 0x12, 0x03, 0x52, 0x0b, 0x1b, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x08, 0x01, 0x12, 0x03, 0x52, 0x1c, 0x2f, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x08, 0x02, 0x08, 0x03, 0x12, 0x03, 0x52, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x08, 0x02, 0x09, 0x05, 0x12, 0x03, 0x53, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02,
0x09, 0x12, 0x03, 0x53, 0x02, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x09, 0x01, 0x12,
0x03, 0x53, 0x09, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x09, 0x03, 0x12, 0x03, 0x53,
0x1c, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x0a, 0x05, 0x12, 0x03, 0x54, 0x02, 0x08,
0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x0a, 0x12, 0x03, 0x54, 0x02, 0x24, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x08, 0x02, 0x0a, 0x01, 0x12, 0x03, 0x54, 0x09, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x08, 0x02, 0x0a, 0x03, 0x12, 0x03, 0x54, 0x21, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02,
0x0b, 0x05, 0x12, 0x03, 0x55, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x0b, 0x12,
0x03, 0x55, 0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x0b, 0x01, 0x12, 0x03, 0x55,
0x09, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x0b, 0x03, 0x12, 0x03, 0x55, 0x21, 0x23,
0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x09, 0x12, 0x04, 0x58, 0x00, 0x5b, 0x01, 0x0a, 0x0a, 0x0a, 0x03,
0x04, 0x09, 0x01, 0x12, 0x03, 0x58, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00,
0x05, 0x12, 0x03, 0x59, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x00, 0x12, 0x03,
0x59, 0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x01, 0x12, 0x03, 0x59, 0x09,
0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x03, 0x12, 0x03, 0x59, 0x12, 0x13, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x05, 0x12, 0x03, 0x5a, 0x02, 0x08, 0x0a, 0x0b, 0x0a,
0x04, 0x04, 0x09, 0x02, 0x01, 0x12, 0x03, 0x5a, 0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09,
0x02, 0x01, 0x01, 0x12, 0x03, 0x5a, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01,
0x03, 0x12, 0x03, 0x5a, 0x12, 0x13, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0a, 0x12, 0x04, 0x5d, 0x00,
0x61, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0a, 0x01, 0x12, 0x03, 0x5d, 0x08, 0x11, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x05, 0x12, 0x03, 0x5e, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x0a, 0x02, 0x00, 0x12, 0x03, 0x5e, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02,
0x00, 0x01, 0x12, 0x03, 0x5e, 0x08, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x03,
0x12, 0x03, 0x5e, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x05, 0x12, 0x03,
0x5f, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x01, 0x12, 0x03, 0x5f, 0x02, 0x14,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x01, 0x12, 0x03, 0x5f, 0x09, 0x0f, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x03, 0x12, 0x03, 0x5f, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x0a, 0x02, 0x02, 0x05, 0x12, 0x03, 0x60, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0a,
0x02, 0x02, 0x12, 0x03, 0x60, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x01,
0x12, 0x03, 0x60, 0x09, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x03, 0x12, 0x03,
0x60, 0x16, 0x17, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0b, 0x12, 0x04, 0x63, 0x00, 0x66, 0x01, 0x0a,
0x0a, 0x0a, 0x03, 0x04, 0x0b, 0x01, 0x12, 0x03, 0x63, 0x08, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x0b, 0x02, 0x00, 0x05, 0x12, 0x03, 0x65, 0x02, 0x08, 0x0a, 0x2f, 0x0a, 0x04, 0x04, 0x0b, 0x02,
0x00, 0x12, 0x03, 0x65, 0x02, 0x12, 0x1a, 0x22, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
0x22, 0x2c, 0x20, 0x22, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x22, 0x2c, 0x20, 0x6f, 0x72, 0x20,
0x22, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0b,
0x02, 0x00, 0x01, 0x12, 0x03, 0x65, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00,
0x03, 0x12, 0x03, 0x65, 0x10, 0x11, 0x0a, 0x4f, 0x0a, 0x02, 0x06, 0x01, 0x12, 0x04, 0x69, 0x00,
0x6b, 0x01, 0x1a, 0x43, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x64, 0x65,
0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e,
0x67, 0x20, 0x28, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
0x20, 0x46, 0x55, 0x53, 0x45, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x70, 0x72, 0x6f,
0x63, 0x65, 0x73, 0x73, 0x29, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x06, 0x01, 0x01, 0x12, 0x03,
0x69, 0x08, 0x14, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x01, 0x02, 0x00, 0x12, 0x03, 0x6a, 0x02, 0x4d,
0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x6a, 0x06, 0x15, 0x0a, 0x0c,
0x0a, 0x05, 0x06, 0x01, 0x02, 0x00, 0x02, 0x12, 0x03, 0x6a, 0x16, 0x2c, 0x0a, 0x0c, 0x0a, 0x05,
0x06, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x6a, 0x37, 0x4b, 0x0a, 0x09, 0x0a, 0x02, 0x04, 0x0c,
0x12, 0x03, 0x6d, 0x00, 0x21, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0c, 0x01, 0x12, 0x03, 0x6d, 0x08,
0x1e, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0d, 0x12, 0x04, 0x6f, 0x00, 0x76, 0x01, 0x0a, 0x0a, 0x0a,
0x03, 0x04, 0x0d, 0x01, 0x12, 0x03, 0x6f, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02,
0x00, 0x05, 0x12, 0x03, 0x70, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x00, 0x12,
0x03, 0x70, 0x02, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x03, 0x70,
0x09, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x03, 0x70, 0x17, 0x18,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x01, 0x05, 0x12, 0x03, 0x71, 0x02, 0x08, 0x0a, 0x0b,
0x0a, 0x04, 0x04, 0x0d, 0x02, 0x01, 0x12, 0x03, 0x71, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x0d, 0x02, 0x01, 0x01, 0x12, 0x03, 0x71, 0x09, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02,
0x01, 0x03, 0x12, 0x03, 0x71, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x05,
0x12, 0x03, 0x72, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x02, 0x12, 0x03, 0x72,
0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x01, 0x12, 0x03, 0x72, 0x09, 0x13,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x03, 0x12, 0x03, 0x72, 0x16, 0x17, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x0d, 0x02, 0x03, 0x05, 0x12, 0x03, 0x73, 0x02, 0x06, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x0d, 0x02, 0x03, 0x12, 0x03, 0x73, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02,
0x03, 0x01, 0x12, 0x03, 0x73, 0x07, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x03, 0x03,
0x12, 0x03, 0x73, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x04, 0x05, 0x12, 0x03,
0x74, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x04, 0x12, 0x03, 0x74, 0x02, 0x1d,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x04, 0x01, 0x12, 0x03, 0x74, 0x09, 0x18, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x0d, 0x02, 0x04, 0x03, 0x12, 0x03, 0x74, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x0d, 0x02, 0x05, 0x05, 0x12, 0x03, 0x75, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d,
0x02, 0x05, 0x12, 0x03, 0x75, 0x02, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x05, 0x01,
0x12, 0x03, 0x75, 0x08, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x05, 0x03, 0x12, 0x03,
0x75, 0x1e, 0x1f, 0x0a, 0x0a, 0x0a, 0x02, 0x06, 0x02, 0x12, 0x04, 0x78, 0x00, 0x7b, 0x01, 0x0a,
0x0a, 0x0a, 0x03, 0x06, 0x02, 0x01, 0x12, 0x03, 0x78, 0x08, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x06,
0x02, 0x02, 0x00, 0x12, 0x03, 0x79, 0x02, 0x53, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x00,
0x01, 0x12, 0x03, 0x79, 0x06, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x00, 0x02, 0x12,
0x03, 0x79, 0x17, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x79,
0x39, 0x51, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x02, 0x02, 0x01, 0x12, 0x03, 0x7a, 0x02, 0x5c, 0x0a,
0x0c, 0x0a, 0x05, 0x06, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x7a, 0x06, 0x19, 0x0a, 0x0c, 0x0a,
0x05, 0x06, 0x02, 0x02, 0x01, 0x02, 0x12, 0x03, 0x7a, 0x1a, 0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x06,
0x02, 0x02, 0x01, 0x03, 0x12, 0x03, 0x7a, 0x3f, 0x5a, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0e, 0x12,
0x04, 0x7d, 0x00, 0x7f, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0e, 0x01, 0x12, 0x03, 0x7d, 0x08,
0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00, 0x05, 0x12, 0x03, 0x7e, 0x02, 0x08, 0x0a,
0x0b, 0x0a, 0x04, 0x04, 0x0e, 0x02, 0x00, 0x12, 0x03, 0x7e, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x0e, 0x02, 0x00, 0x01, 0x12, 0x03, 0x7e, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0e,
0x02, 0x00, 0x03, 0x12, 0x03, 0x7e, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0f, 0x12, 0x06,
0x81, 0x01, 0x00, 0x83, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0f, 0x01, 0x12, 0x04, 0x81,
0x01, 0x08, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x06, 0x12, 0x04, 0x82, 0x01,
0x02, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0f, 0x02, 0x00, 0x12, 0x04, 0x82, 0x01, 0x02, 0x1d,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x01, 0x12, 0x04, 0x82, 0x01, 0x10, 0x18, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x03, 0x12, 0x04, 0x82, 0x01, 0x1b, 0x1c, 0x0a, 0x0c,
0x0a, 0x02, 0x04, 0x10, 0x12, 0x06, 0x85, 0x01, 0x00, 0x8d, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03,
0x04, 0x10, 0x01, 0x12, 0x04, 0x85, 0x01, 0x08, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02,
0x00, 0x05, 0x12, 0x04, 0x86, 0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x00,
0x12, 0x04, 0x86, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, 0x01, 0x12,
0x04, 0x86, 0x01, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, 0x03, 0x12, 0x04,
0x86, 0x01, 0x11, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x04, 0x12, 0x04, 0x87,
0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x01, 0x12, 0x04, 0x87, 0x01, 0x02,
0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x05, 0x12, 0x04, 0x87, 0x01, 0x0b, 0x11,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x01, 0x12, 0x04, 0x87, 0x01, 0x12, 0x18, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x03, 0x12, 0x04, 0x87, 0x01, 0x1b, 0x1c, 0x0a, 0x0d,
0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x04, 0x12, 0x04, 0x88, 0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a,
0x04, 0x04, 0x10, 0x02, 0x02, 0x12, 0x04, 0x88, 0x01, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x10, 0x02, 0x02, 0x05, 0x12, 0x04, 0x88, 0x01, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10,
0x02, 0x02, 0x01, 0x12, 0x04, 0x88, 0x01, 0x12, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02,
0x02, 0x03, 0x12, 0x04, 0x88, 0x01, 0x21, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03,
0x05, 0x12, 0x04, 0x89, 0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x03, 0x12,
0x04, 0x89, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, 0x01, 0x12, 0x04,
0x89, 0x01, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, 0x03, 0x12, 0x04, 0x89,
0x01, 0x11, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x05, 0x12, 0x04, 0x8a, 0x01,
0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x04, 0x12, 0x04, 0x8a, 0x01, 0x02, 0x19,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x01, 0x12, 0x04, 0x8a, 0x01, 0x08, 0x14, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x03, 0x12, 0x04, 0x8a, 0x01, 0x17, 0x18, 0x0a, 0x0d,
0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x05, 0x12, 0x04, 0x8b, 0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a,
0x04, 0x04, 0x10, 0x02, 0x05, 0x12, 0x04, 0x8b, 0x01, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x10, 0x02, 0x05, 0x01, 0x12, 0x04, 0x8b, 0x01, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10,
0x02, 0x05, 0x03, 0x12, 0x04, 0x8b, 0x01, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02,
0x06, 0x04, 0x12, 0x04, 0x8c, 0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x06,
0x12, 0x04, 0x8c, 0x01, 0x02, 0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x05, 0x12,
0x04, 0x8c, 0x01, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x01, 0x12, 0x04,
0x8c, 0x01, 0x12, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x03, 0x12, 0x04, 0x8c,
0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x11, 0x12, 0x06, 0x8f, 0x01, 0x00, 0x91, 0x01,
0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x11, 0x01, 0x12, 0x04, 0x8f, 0x01, 0x08, 0x23, 0x0a, 0x0d,
0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x06, 0x12, 0x04, 0x90, 0x01, 0x02, 0x0f, 0x0a, 0x0c, 0x0a,
0x04, 0x04, 0x11, 0x02, 0x00, 0x12, 0x04, 0x90, 0x01, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x11, 0x02, 0x00, 0x01, 0x12, 0x04, 0x90, 0x01, 0x10, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11,
0x02, 0x00, 0x03, 0x12, 0x04, 0x90, 0x01, 0x1b, 0x1c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x72, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02,
0x01, 0x01, 0x12, 0x03, 0x47, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x01, 0x03,
0x12, 0x03, 0x47, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x05, 0x12, 0x03,
0x48, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x02, 0x12, 0x03, 0x48, 0x02, 0x14,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x01, 0x12, 0x03, 0x48, 0x09, 0x0f, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x05, 0x02, 0x02, 0x03, 0x12, 0x03, 0x48, 0x12, 0x13, 0x0a, 0x09, 0x0a, 0x02,
0x04, 0x06, 0x12, 0x03, 0x4b, 0x00, 0x21, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, 0x03,
0x4b, 0x08, 0x1e, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x07, 0x12, 0x04, 0x4d, 0x00, 0x55, 0x01, 0x0a,
0x0a, 0x0a, 0x03, 0x04, 0x07, 0x01, 0x12, 0x03, 0x4d, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x07, 0x02, 0x00, 0x05, 0x12, 0x03, 0x4e, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02,
0x00, 0x12, 0x03, 0x4e, 0x02, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x01, 0x12,
0x03, 0x4e, 0x09, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x00, 0x03, 0x12, 0x03, 0x4e,
0x0e, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x01, 0x05, 0x12, 0x03, 0x4f, 0x02, 0x08,
0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x01, 0x12, 0x03, 0x4f, 0x02, 0x16, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x07, 0x02, 0x01, 0x01, 0x12, 0x03, 0x4f, 0x09, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x07, 0x02, 0x01, 0x03, 0x12, 0x03, 0x4f, 0x14, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02,
0x02, 0x05, 0x12, 0x03, 0x50, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x02, 0x12,
0x03, 0x50, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x02, 0x01, 0x12, 0x03, 0x50,
0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x02, 0x03, 0x12, 0x03, 0x50, 0x10, 0x11,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x03, 0x05, 0x12, 0x03, 0x51, 0x02, 0x08, 0x0a, 0x0b,
0x0a, 0x04, 0x04, 0x07, 0x02, 0x03, 0x12, 0x03, 0x51, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x07, 0x02, 0x03, 0x01, 0x12, 0x03, 0x51, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02,
0x03, 0x03, 0x12, 0x03, 0x51, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x04, 0x05,
0x12, 0x03, 0x52, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x04, 0x12, 0x03, 0x52,
0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x04, 0x01, 0x12, 0x03, 0x52, 0x09, 0x0e,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x04, 0x03, 0x12, 0x03, 0x52, 0x11, 0x12, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x07, 0x02, 0x05, 0x05, 0x12, 0x03, 0x53, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x07, 0x02, 0x05, 0x12, 0x03, 0x53, 0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02,
0x05, 0x01, 0x12, 0x03, 0x53, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x05, 0x03,
0x12, 0x03, 0x53, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x06, 0x06, 0x12, 0x03,
0x54, 0x02, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x07, 0x02, 0x06, 0x12, 0x03, 0x54, 0x02, 0x23,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x07, 0x02, 0x06, 0x01, 0x12, 0x03, 0x54, 0x10, 0x1e, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x07, 0x02, 0x06, 0x03, 0x12, 0x03, 0x54, 0x21, 0x22, 0x0a, 0x0a, 0x0a, 0x02,
0x04, 0x08, 0x12, 0x04, 0x57, 0x00, 0x64, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x08, 0x01, 0x12,
0x03, 0x57, 0x08, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x04, 0x12, 0x03, 0x58,
0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x00, 0x12, 0x03, 0x58, 0x02, 0x1d, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x00, 0x05, 0x12, 0x03, 0x58, 0x0b, 0x11, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x08, 0x02, 0x00, 0x01, 0x12, 0x03, 0x58, 0x12, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x08, 0x02, 0x00, 0x03, 0x12, 0x03, 0x58, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02,
0x01, 0x04, 0x12, 0x03, 0x59, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x01, 0x12,
0x03, 0x59, 0x02, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x05, 0x12, 0x03, 0x59,
0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x01, 0x12, 0x03, 0x59, 0x12, 0x1e,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x01, 0x03, 0x12, 0x03, 0x59, 0x21, 0x22, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x08, 0x02, 0x02, 0x05, 0x12, 0x03, 0x5a, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x08, 0x02, 0x02, 0x12, 0x03, 0x5a, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02,
0x02, 0x01, 0x12, 0x03, 0x5a, 0x09, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x02, 0x03,
0x12, 0x03, 0x5a, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x03, 0x05, 0x12, 0x03,
0x5b, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x03, 0x12, 0x03, 0x5b, 0x02, 0x19,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x03, 0x01, 0x12, 0x03, 0x5b, 0x08, 0x14, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x08, 0x02, 0x03, 0x03, 0x12, 0x03, 0x5b, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x08, 0x02, 0x04, 0x05, 0x12, 0x03, 0x5c, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08,
0x02, 0x04, 0x12, 0x03, 0x5c, 0x02, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x04, 0x01,
0x12, 0x03, 0x5c, 0x09, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x04, 0x03, 0x12, 0x03,
0x5c, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x05, 0x04, 0x12, 0x03, 0x5d, 0x02,
0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x05, 0x12, 0x03, 0x5d, 0x02, 0x21, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x08, 0x02, 0x05, 0x05, 0x12, 0x03, 0x5d, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x08, 0x02, 0x05, 0x01, 0x12, 0x03, 0x5d, 0x12, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08,
0x02, 0x05, 0x03, 0x12, 0x03, 0x5d, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x06,
0x05, 0x12, 0x03, 0x5e, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x06, 0x12, 0x03,
0x5e, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x06, 0x01, 0x12, 0x03, 0x5e, 0x08,
0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x06, 0x03, 0x12, 0x03, 0x5e, 0x11, 0x12, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x07, 0x04, 0x12, 0x03, 0x5f, 0x02, 0x0a, 0x0a, 0x0b, 0x0a,
0x04, 0x04, 0x08, 0x02, 0x07, 0x12, 0x03, 0x5f, 0x02, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08,
0x02, 0x07, 0x05, 0x12, 0x03, 0x5f, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x07,
0x01, 0x12, 0x03, 0x5f, 0x11, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x07, 0x03, 0x12,
0x03, 0x5f, 0x29, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x08, 0x04, 0x12, 0x03, 0x60,
0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x08, 0x12, 0x03, 0x60, 0x02, 0x34, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x08, 0x06, 0x12, 0x03, 0x60, 0x0b, 0x1b, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x08, 0x02, 0x08, 0x01, 0x12, 0x03, 0x60, 0x1c, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x08, 0x02, 0x08, 0x03, 0x12, 0x03, 0x60, 0x32, 0x33, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02,
0x09, 0x05, 0x12, 0x03, 0x61, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x09, 0x12,
0x03, 0x61, 0x02, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x09, 0x01, 0x12, 0x03, 0x61,
0x09, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x09, 0x03, 0x12, 0x03, 0x61, 0x1c, 0x1e,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x0a, 0x05, 0x12, 0x03, 0x62, 0x02, 0x08, 0x0a, 0x0b,
0x0a, 0x04, 0x04, 0x08, 0x02, 0x0a, 0x12, 0x03, 0x62, 0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x08, 0x02, 0x0a, 0x01, 0x12, 0x03, 0x62, 0x09, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02,
0x0a, 0x03, 0x12, 0x03, 0x62, 0x21, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x0b, 0x05,
0x12, 0x03, 0x63, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x08, 0x02, 0x0b, 0x12, 0x03, 0x63,
0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x0b, 0x01, 0x12, 0x03, 0x63, 0x09, 0x1e,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x08, 0x02, 0x0b, 0x03, 0x12, 0x03, 0x63, 0x21, 0x23, 0x0a, 0x0a,
0x0a, 0x02, 0x04, 0x09, 0x12, 0x04, 0x66, 0x00, 0x69, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x09,
0x01, 0x12, 0x03, 0x66, 0x08, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x05, 0x12,
0x03, 0x67, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x09, 0x02, 0x00, 0x12, 0x03, 0x67, 0x02,
0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x01, 0x12, 0x03, 0x67, 0x09, 0x0f, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x00, 0x03, 0x12, 0x03, 0x67, 0x12, 0x13, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x09, 0x02, 0x01, 0x05, 0x12, 0x03, 0x68, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x09, 0x02, 0x01, 0x12, 0x03, 0x68, 0x02, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01,
0x01, 0x12, 0x03, 0x68, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x09, 0x02, 0x01, 0x03, 0x12,
0x03, 0x68, 0x12, 0x13, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0a, 0x12, 0x04, 0x6b, 0x00, 0x6f, 0x01,
0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0a, 0x01, 0x12, 0x03, 0x6b, 0x08, 0x11, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x0a, 0x02, 0x00, 0x05, 0x12, 0x03, 0x6c, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0a,
0x02, 0x00, 0x12, 0x03, 0x6c, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x01,
0x12, 0x03, 0x6c, 0x08, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x00, 0x03, 0x12, 0x03,
0x6c, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x05, 0x12, 0x03, 0x6d, 0x02,
0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x01, 0x12, 0x03, 0x6d, 0x02, 0x14, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x0a, 0x02, 0x01, 0x01, 0x12, 0x03, 0x6d, 0x09, 0x0f, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x0a, 0x02, 0x01, 0x03, 0x12, 0x03, 0x6d, 0x12, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a,
0x02, 0x02, 0x05, 0x12, 0x03, 0x6e, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0a, 0x02, 0x02,
0x12, 0x03, 0x6e, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x01, 0x12, 0x03,
0x6e, 0x09, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0a, 0x02, 0x02, 0x03, 0x12, 0x03, 0x6e, 0x16,
0x17, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x0b, 0x12, 0x04, 0x71, 0x00, 0x74, 0x01, 0x0a, 0x0a, 0x0a,
0x03, 0x04, 0x0b, 0x01, 0x12, 0x03, 0x71, 0x08, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02,
0x00, 0x05, 0x12, 0x03, 0x73, 0x02, 0x08, 0x0a, 0x2f, 0x0a, 0x04, 0x04, 0x0b, 0x02, 0x00, 0x12,
0x03, 0x73, 0x02, 0x12, 0x1a, 0x22, 0x20, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x22, 0x2c,
0x20, 0x22, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x22, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x72,
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00,
0x01, 0x12, 0x03, 0x73, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0b, 0x02, 0x00, 0x03, 0x12,
0x03, 0x73, 0x10, 0x11, 0x0a, 0x09, 0x0a, 0x02, 0x04, 0x0c, 0x12, 0x03, 0x76, 0x00, 0x21, 0x0a,
0x0a, 0x0a, 0x03, 0x04, 0x0c, 0x01, 0x12, 0x03, 0x76, 0x08, 0x1e, 0x0a, 0x0a, 0x0a, 0x02, 0x04,
0x0d, 0x12, 0x04, 0x78, 0x00, 0x7f, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x0d, 0x01, 0x12, 0x03,
0x78, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x05, 0x12, 0x03, 0x79, 0x02,
0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x00, 0x12, 0x03, 0x79, 0x02, 0x19, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x0d, 0x02, 0x00, 0x01, 0x12, 0x03, 0x79, 0x09, 0x14, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x0d, 0x02, 0x00, 0x03, 0x12, 0x03, 0x79, 0x17, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d,
0x02, 0x01, 0x05, 0x12, 0x03, 0x7a, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x01,
0x12, 0x03, 0x7a, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x01, 0x01, 0x12, 0x03,
0x7a, 0x09, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x01, 0x03, 0x12, 0x03, 0x7a, 0x16,
0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x02, 0x05, 0x12, 0x03, 0x7b, 0x02, 0x08, 0x0a,
0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x02, 0x12, 0x03, 0x7b, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x0d, 0x02, 0x02, 0x01, 0x12, 0x03, 0x7b, 0x09, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d,
0x02, 0x02, 0x03, 0x12, 0x03, 0x7b, 0x16, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x03,
0x05, 0x12, 0x03, 0x7c, 0x02, 0x06, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x03, 0x12, 0x03,
0x7c, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x03, 0x01, 0x12, 0x03, 0x7c, 0x07,
0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x03, 0x03, 0x12, 0x03, 0x7c, 0x1a, 0x1b, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x04, 0x05, 0x12, 0x03, 0x7d, 0x02, 0x08, 0x0a, 0x0b, 0x0a,
0x04, 0x04, 0x0d, 0x02, 0x04, 0x12, 0x03, 0x7d, 0x02, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d,
0x02, 0x04, 0x01, 0x12, 0x03, 0x7d, 0x09, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x04,
0x03, 0x12, 0x03, 0x7d, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x05, 0x05, 0x12,
0x03, 0x7e, 0x02, 0x07, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x0d, 0x02, 0x05, 0x12, 0x03, 0x7e, 0x02,
0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x05, 0x01, 0x12, 0x03, 0x7e, 0x08, 0x1b, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x0d, 0x02, 0x05, 0x03, 0x12, 0x03, 0x7e, 0x1e, 0x1f, 0x0a, 0x0c, 0x0a,
0x02, 0x04, 0x0e, 0x12, 0x06, 0x81, 0x01, 0x00, 0x83, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04,
0x0e, 0x01, 0x12, 0x04, 0x81, 0x01, 0x08, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00,
0x05, 0x12, 0x04, 0x82, 0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x0e, 0x02, 0x00, 0x12,
0x04, 0x82, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00, 0x01, 0x12, 0x04,
0x82, 0x01, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0e, 0x02, 0x00, 0x03, 0x12, 0x04, 0x82,
0x01, 0x11, 0x12, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x0f, 0x12, 0x06, 0x85, 0x01, 0x00, 0x87, 0x01,
0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x0f, 0x01, 0x12, 0x04, 0x85, 0x01, 0x08, 0x20, 0x0a, 0x0d,
0x0a, 0x05, 0x04, 0x0f, 0x02, 0x00, 0x06, 0x12, 0x04, 0x86, 0x01, 0x02, 0x0f, 0x0a, 0x0c, 0x0a,
0x04, 0x04, 0x0f, 0x02, 0x00, 0x12, 0x04, 0x86, 0x01, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x0f, 0x02, 0x00, 0x01, 0x12, 0x04, 0x86, 0x01, 0x10, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x0f,
0x02, 0x00, 0x03, 0x12, 0x04, 0x86, 0x01, 0x1b, 0x1c, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x10, 0x12,
0x06, 0x89, 0x01, 0x00, 0x91, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x10, 0x01, 0x12, 0x04,
0x89, 0x01, 0x08, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, 0x05, 0x12, 0x04, 0x8a,
0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x00, 0x12, 0x04, 0x8a, 0x01, 0x02,
0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, 0x01, 0x12, 0x04, 0x8a, 0x01, 0x09, 0x0e,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x00, 0x03, 0x12, 0x04, 0x8a, 0x01, 0x11, 0x12, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x01, 0x04, 0x12, 0x04, 0x8b, 0x01, 0x02, 0x0a, 0x0a, 0x0c,
0x0a, 0x04, 0x04, 0x10, 0x02, 0x01, 0x12, 0x04, 0x8b, 0x01, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05,
0x04, 0x10, 0x02, 0x01, 0x05, 0x12, 0x04, 0x8b, 0x01, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x10, 0x02, 0x01, 0x01, 0x12, 0x04, 0x8b, 0x01, 0x12, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10,
0x02, 0x01, 0x03, 0x12, 0x04, 0x8b, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02,
0x02, 0x04, 0x12, 0x04, 0x8c, 0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x02,
0x12, 0x04, 0x8c, 0x01, 0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x05, 0x12,
0x04, 0x8c, 0x01, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x01, 0x12, 0x04,
0x8c, 0x01, 0x12, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x02, 0x03, 0x12, 0x04, 0x8c,
0x01, 0x21, 0x22, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, 0x05, 0x12, 0x04, 0x8d, 0x01,
0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x03, 0x12, 0x04, 0x8d, 0x01, 0x02, 0x13,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, 0x01, 0x12, 0x04, 0x8d, 0x01, 0x09, 0x0e, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x03, 0x03, 0x12, 0x04, 0x8d, 0x01, 0x11, 0x12, 0x0a, 0x0d,
0x0a, 0x05, 0x04, 0x10, 0x02, 0x04, 0x05, 0x12, 0x04, 0x8e, 0x01, 0x02, 0x07, 0x0a, 0x0c, 0x0a,
0x04, 0x04, 0x10, 0x02, 0x04, 0x12, 0x04, 0x8e, 0x01, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x10, 0x02, 0x04, 0x01, 0x12, 0x04, 0x8e, 0x01, 0x08, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10,
0x02, 0x04, 0x03, 0x12, 0x04, 0x8e, 0x01, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02,
0x05, 0x05, 0x12, 0x04, 0x8f, 0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x05,
0x12, 0x04, 0x8f, 0x01, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x01, 0x12,
0x04, 0x8f, 0x01, 0x09, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x05, 0x03, 0x12, 0x04,
0x8f, 0x01, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x04, 0x12, 0x04, 0x90,
0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x10, 0x02, 0x06, 0x12, 0x04, 0x90, 0x01, 0x02,
0x21, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x05, 0x12, 0x04, 0x90, 0x01, 0x0b, 0x11,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x01, 0x12, 0x04, 0x90, 0x01, 0x12, 0x1c, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x10, 0x02, 0x06, 0x03, 0x12, 0x04, 0x90, 0x01, 0x1f, 0x20, 0x0a, 0x0c,
0x0a, 0x02, 0x04, 0x11, 0x12, 0x06, 0x93, 0x01, 0x00, 0x95, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03,
0x04, 0x11, 0x01, 0x12, 0x04, 0x93, 0x01, 0x08, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02,
0x00, 0x06, 0x12, 0x04, 0x94, 0x01, 0x02, 0x0f, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x11, 0x02, 0x00,
0x12, 0x04, 0x94, 0x01, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x01, 0x12,
0x04, 0x94, 0x01, 0x10, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x11, 0x02, 0x00, 0x03, 0x12, 0x04,
0x94, 0x01, 0x1b, 0x1c, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x12, 0x12, 0x04, 0x97, 0x01, 0x00, 0x1b,
0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x12, 0x01, 0x12, 0x04, 0x97, 0x01, 0x08, 0x18, 0x0a, 0x0c, 0x0a,
0x02, 0x04, 0x13, 0x12, 0x06, 0x99, 0x01, 0x00, 0x9b, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04,
0x13, 0x01, 0x12, 0x04, 0x99, 0x01, 0x08, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00,
0x04, 0x12, 0x04, 0x9a, 0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x13, 0x02, 0x00, 0x12,
0x04, 0x9a, 0x01, 0x02, 0x1f, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x06, 0x12, 0x04,
0x9a, 0x01, 0x0b, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x01, 0x12, 0x04, 0x9a,
0x01, 0x15, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x13, 0x02, 0x00, 0x03, 0x12, 0x04, 0x9a, 0x01,
0x1d, 0x1e, 0x0a, 0xb9, 0x01, 0x0a, 0x02, 0x04, 0x14, 0x12, 0x06, 0xa0, 0x01, 0x00, 0xa7, 0x01,
0x01, 0x1a, 0xaa, 0x01, 0x20, 0x48, 0x75, 0x6d, 0x61, 0x6e, 0x2d, 0x72, 0x65, 0x61, 0x64, 0x61,
0x62, 0x6c, 0x65, 0x20, 0x74, 0x61, 0x67, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x6f,
0x6e, 0x6c, 0x79, 0x2e, 0x20, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x20, 0x74, 0x68,
0x65, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x20,
0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x0a, 0x20, 0x28, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2c,
0x20, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68,
0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e, 0x29, 0x20, 0x74, 0x68,
0x61, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x73, 0x65, 0x6e,
0x73, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x0a, 0x20, 0x6d, 0x75, 0x73, 0x69, 0x63,
0x66, 0x73, 0x27, 0x73, 0x20, 0x46, 0x55, 0x53, 0x45, 0x20, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x61,
0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x0a, 0x0a, 0x0b,
0x0a, 0x03, 0x04, 0x14, 0x01, 0x12, 0x04, 0xa0, 0x01, 0x08, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x14, 0x02, 0x00, 0x04, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14,
0x02, 0x00, 0x12, 0x04, 0xa1, 0x01, 0x02, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x00,
0x05, 0x12, 0x04, 0xa1, 0x01, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x00, 0x01,
0x12, 0x04, 0xa1, 0x01, 0x12, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x00, 0x03, 0x12,
0x04, 0xa1, 0x01, 0x1b, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x04, 0x12, 0x04,
0xa2, 0x01, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02, 0x01, 0x12, 0x04, 0xa2, 0x01,
0x02, 0x23, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x05, 0x12, 0x04, 0xa2, 0x01, 0x0b,
0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x01, 0x12, 0x04, 0xa2, 0x01, 0x12, 0x1e,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x01, 0x03, 0x12, 0x04, 0xa2, 0x01, 0x21, 0x22, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x02, 0x05, 0x12, 0x04, 0xa3, 0x01, 0x02, 0x08, 0x0a, 0x0c,
0x0a, 0x04, 0x04, 0x14, 0x02, 0x02, 0x12, 0x04, 0xa3, 0x01, 0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05,
0x04, 0x14, 0x02, 0x02, 0x01, 0x12, 0x04, 0xa3, 0x01, 0x09, 0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x14, 0x02, 0x02, 0x03, 0x12, 0x04, 0xa3, 0x01, 0x11, 0x12, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14,
0x02, 0x03, 0x05, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02,
0x03, 0x12, 0x04, 0xa4, 0x01, 0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x03, 0x01,
0x12, 0x04, 0xa4, 0x01, 0x08, 0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x03, 0x03, 0x12,
0x04, 0xa4, 0x01, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x04, 0x05, 0x12, 0x04,
0xa5, 0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02, 0x04, 0x12, 0x04, 0xa5, 0x01,
0x02, 0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x04, 0x01, 0x12, 0x04, 0xa5, 0x01, 0x09,
0x14, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x04, 0x03, 0x12, 0x04, 0xa5, 0x01, 0x17, 0x18,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x14, 0x02, 0x05, 0x04, 0x12, 0x04, 0xa6, 0x01, 0x02, 0x0a, 0x0a,
0x0c, 0x0a, 0x04, 0x04, 0x14, 0x02, 0x05, 0x12, 0x04, 0xa6, 0x01, 0x02, 0x21, 0x0a, 0x0d, 0x0a,
0x05, 0x04, 0x14, 0x02, 0x05, 0x05, 0x12, 0x04, 0xa6, 0x01, 0x0b, 0x11, 0x0a, 0x0d, 0x0a, 0x05,
0x04, 0x14, 0x02, 0x05, 0x01, 0x12, 0x04, 0xa6, 0x01, 0x12, 0x1c, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x14, 0x02, 0x05, 0x03, 0x12, 0x04, 0xa6, 0x01, 0x1f, 0x20, 0x0a, 0x0c, 0x0a, 0x02, 0x04, 0x15,
0x12, 0x06, 0xa9, 0x01, 0x00, 0xb4, 0x01, 0x01, 0x0a, 0x0b, 0x0a, 0x03, 0x04, 0x15, 0x01, 0x12,
0x04, 0xa9, 0x01, 0x08, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x00, 0x05, 0x12, 0x04,
0xaa, 0x01, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x00, 0x12, 0x04, 0xaa, 0x01,
0x02, 0x13, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x00, 0x01, 0x12, 0x04, 0xaa, 0x01, 0x09,
0x0e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x00, 0x03, 0x12, 0x04, 0xaa, 0x01, 0x11, 0x12,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x05, 0x12, 0x04, 0xac, 0x01, 0x02, 0x08, 0x0a,
0x47, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x01, 0x12, 0x04, 0xac, 0x01, 0x02, 0x1b, 0x1a, 0x39, 0x20,
0x52, 0x65, 0x61, 0x6c, 0x20, 0x6f, 0x6e, 0x2d, 0x64, 0x69, 0x73, 0x6b, 0x20, 0x70, 0x61, 0x74,
0x68, 0x20, 0x28, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x72, 0x61, 0x2f, 0x6c, 0x69,
0x62, 0x72, 0x71, 0x62, 0x69, 0x74, 0x20, 0x77, 0x72, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65,
0x20, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01,
0x01, 0x12, 0x04, 0xac, 0x01, 0x09, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x01, 0x03,
0x12, 0x04, 0xac, 0x01, 0x19, 0x1a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x05, 0x12,
0x04, 0xaf, 0x01, 0x02, 0x08, 0x0a, 0x7a, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x02, 0x12, 0x04, 0xaf,
0x01, 0x02, 0x18, 0x1a, 0x6c, 0x20, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x46, 0x55,
0x53, 0x45, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x28, 0x7b, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74,
0x7d, 0x2f, 0x7b, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x66, 0x69, 0x6c, 0x65, 0x6e,
0x61, 0x6d, 0x65, 0x7d, 0x29, 0x3b, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77,
0x68, 0x65, 0x6e, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x20, 0x63, 0x68,
0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, 0x76, 0x69, 0x61, 0x20, 0x60, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x4d, 0x75, 0x73, 0x69, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x60, 0x2e,
0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x01, 0x12, 0x04, 0xaf, 0x01, 0x09, 0x13,
0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x02, 0x03, 0x12, 0x04, 0xaf, 0x01, 0x16, 0x17, 0x0a,
0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x03, 0x05, 0x12, 0x04, 0xb1, 0x01, 0x02, 0x08, 0x0a, 0x28,
0x0a, 0x04, 0x04, 0x15, 0x02, 0x03, 0x12, 0x04, 0xb1, 0x01, 0x02, 0x12, 0x1a, 0x1a, 0x20, 0x46,
0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x03,
0x01, 0x12, 0x04, 0xb1, 0x01, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x03, 0x03,
0x12, 0x04, 0xb1, 0x01, 0x10, 0x11, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15, 0x02, 0x04, 0x04, 0x12,
0x04, 0xb3, 0x01, 0x02, 0x0a, 0x0a, 0x35, 0x0a, 0x04, 0x04, 0x15, 0x02, 0x04, 0x12, 0x04, 0xb3,
0x01, 0x02, 0x25, 0x1a, 0x27, 0x20, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x69, 0x66, 0x20, 0x74,
0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x70,
0x61, 0x72, 0x73, 0x65, 0x64, 0x20, 0x74, 0x61, 0x67, 0x73, 0x2e, 0x0a, 0x0a, 0x0d, 0x0a, 0x05,
0x04, 0x15, 0x02, 0x04, 0x06, 0x12, 0x04, 0xb3, 0x01, 0x0b, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
0x15, 0x02, 0x04, 0x01, 0x12, 0x04, 0xb3, 0x01, 0x18, 0x20, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x15,
0x02, 0x04, 0x03, 0x12, 0x04, 0xb3, 0x01, 0x23, 0x24, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
];
include!("musicfs.serde.rs");
+518
View File
@@ -439,6 +439,361 @@ impl<'de> serde::Deserialize<'de> for FileChunk {
deserializer.deserialize_struct("musicfs.FileChunk", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for FileEntry {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut len = 0;
if self.inode != 0 {
len += 1;
}
if !self.original_path.is_empty() {
len += 1;
}
if !self.local_path.is_empty() {
len += 1;
}
if !self.name.is_empty() {
len += 1;
}
if self.metadata.is_some() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("musicfs.FileEntry", len)?;
if self.inode != 0 {
#[allow(clippy::needless_borrow)]
#[allow(clippy::needless_borrows_for_generic_args)]
struct_ser.serialize_field("inode", ToString::to_string(&self.inode).as_str())?;
}
if !self.original_path.is_empty() {
struct_ser.serialize_field("originalPath", &self.original_path)?;
}
if !self.local_path.is_empty() {
struct_ser.serialize_field("localPath", &self.local_path)?;
}
if !self.name.is_empty() {
struct_ser.serialize_field("name", &self.name)?;
}
if let Some(v) = self.metadata.as_ref() {
struct_ser.serialize_field("metadata", v)?;
}
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for FileEntry {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[
"inode",
"original_path",
"originalPath",
"local_path",
"localPath",
"name",
"metadata",
];
#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Inode,
OriginalPath,
LocalPath,
Name,
Metadata,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
D: serde::Deserializer<'de>,
{
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = GeneratedField;
fn expecting(
&self,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}
#[allow(unused_variables)]
fn visit_str<E>(self, value: &str) -> std::result::Result<GeneratedField, E>
where
E: serde::de::Error,
{
match value {
"inode" => Ok(GeneratedField::Inode),
"originalPath" | "original_path" => Ok(GeneratedField::OriginalPath),
"localPath" | "local_path" => Ok(GeneratedField::LocalPath),
"name" => Ok(GeneratedField::Name),
"metadata" => Ok(GeneratedField::Metadata),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = FileEntry;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct musicfs.FileEntry")
}
fn visit_map<V>(self, mut map_: V) -> std::result::Result<FileEntry, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut inode__ = None;
let mut original_path__ = None;
let mut local_path__ = None;
let mut name__ = None;
let mut metadata__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Inode => {
if inode__.is_some() {
return Err(serde::de::Error::duplicate_field("inode"));
}
inode__ = Some(
map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?
.0,
);
}
GeneratedField::OriginalPath => {
if original_path__.is_some() {
return Err(serde::de::Error::duplicate_field("originalPath"));
}
original_path__ = Some(map_.next_value()?);
}
GeneratedField::LocalPath => {
if local_path__.is_some() {
return Err(serde::de::Error::duplicate_field("localPath"));
}
local_path__ = Some(map_.next_value()?);
}
GeneratedField::Name => {
if name__.is_some() {
return Err(serde::de::Error::duplicate_field("name"));
}
name__ = Some(map_.next_value()?);
}
GeneratedField::Metadata => {
if metadata__.is_some() {
return Err(serde::de::Error::duplicate_field("metadata"));
}
metadata__ = map_.next_value()?;
}
}
}
Ok(FileEntry {
inode: inode__.unwrap_or_default(),
original_path: original_path__.unwrap_or_default(),
local_path: local_path__.unwrap_or_default(),
name: name__.unwrap_or_default(),
metadata: metadata__,
})
}
}
deserializer.deserialize_struct("musicfs.FileEntry", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for FileMetadata {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut len = 0;
if !self.artist.is_empty() {
len += 1;
}
if self.album_artist.is_some() {
len += 1;
}
if !self.album.is_empty() {
len += 1;
}
if self.track_number != 0 {
len += 1;
}
if !self.track_title.is_empty() {
len += 1;
}
if !self.other_tags.is_empty() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("musicfs.FileMetadata", len)?;
if !self.artist.is_empty() {
struct_ser.serialize_field("artist", &self.artist)?;
}
if let Some(v) = self.album_artist.as_ref() {
struct_ser.serialize_field("albumArtist", v)?;
}
if !self.album.is_empty() {
struct_ser.serialize_field("album", &self.album)?;
}
if self.track_number != 0 {
struct_ser.serialize_field("trackNumber", &self.track_number)?;
}
if !self.track_title.is_empty() {
struct_ser.serialize_field("trackTitle", &self.track_title)?;
}
if !self.other_tags.is_empty() {
struct_ser.serialize_field("otherTags", &self.other_tags)?;
}
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for FileMetadata {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[
"artist",
"album_artist",
"albumArtist",
"album",
"track_number",
"trackNumber",
"track_title",
"trackTitle",
"other_tags",
"otherTags",
];
#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Artist,
AlbumArtist,
Album,
TrackNumber,
TrackTitle,
OtherTags,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
D: serde::Deserializer<'de>,
{
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = GeneratedField;
fn expecting(
&self,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}
#[allow(unused_variables)]
fn visit_str<E>(self, value: &str) -> std::result::Result<GeneratedField, E>
where
E: serde::de::Error,
{
match value {
"artist" => Ok(GeneratedField::Artist),
"albumArtist" | "album_artist" => Ok(GeneratedField::AlbumArtist),
"album" => Ok(GeneratedField::Album),
"trackNumber" | "track_number" => Ok(GeneratedField::TrackNumber),
"trackTitle" | "track_title" => Ok(GeneratedField::TrackTitle),
"otherTags" | "other_tags" => Ok(GeneratedField::OtherTags),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = FileMetadata;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct musicfs.FileMetadata")
}
fn visit_map<V>(self, mut map_: V) -> std::result::Result<FileMetadata, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut artist__ = None;
let mut album_artist__ = None;
let mut album__ = None;
let mut track_number__ = None;
let mut track_title__ = None;
let mut other_tags__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Artist => {
if artist__.is_some() {
return Err(serde::de::Error::duplicate_field("artist"));
}
artist__ = Some(map_.next_value()?);
}
GeneratedField::AlbumArtist => {
if album_artist__.is_some() {
return Err(serde::de::Error::duplicate_field("albumArtist"));
}
album_artist__ = map_.next_value()?;
}
GeneratedField::Album => {
if album__.is_some() {
return Err(serde::de::Error::duplicate_field("album"));
}
album__ = Some(map_.next_value()?);
}
GeneratedField::TrackNumber => {
if track_number__.is_some() {
return Err(serde::de::Error::duplicate_field("trackNumber"));
}
track_number__ = Some(
map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?
.0,
);
}
GeneratedField::TrackTitle => {
if track_title__.is_some() {
return Err(serde::de::Error::duplicate_field("trackTitle"));
}
track_title__ = Some(map_.next_value()?);
}
GeneratedField::OtherTags => {
if other_tags__.is_some() {
return Err(serde::de::Error::duplicate_field("otherTags"));
}
other_tags__ = Some(map_.next_value()?);
}
}
}
Ok(FileMetadata {
artist: artist__.unwrap_or_default(),
album_artist: album_artist__,
album: album__.unwrap_or_default(),
track_number: track_number__.unwrap_or_default(),
track_title: track_title__.unwrap_or_default(),
other_tags: other_tags__.unwrap_or_default(),
})
}
}
deserializer.deserialize_struct("musicfs.FileMetadata", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for GetClientStatusRequest {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
@@ -1145,6 +1500,169 @@ impl<'de> serde::Deserialize<'de> for InodeHash {
deserializer.deserialize_struct("musicfs.InodeHash", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for ListFilesRequest {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let len = 0;
let struct_ser = serializer.serialize_struct("musicfs.ListFilesRequest", len)?;
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for ListFilesRequest {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[];
#[allow(clippy::enum_variant_names)]
enum GeneratedField {}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
D: serde::Deserializer<'de>,
{
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = GeneratedField;
fn expecting(
&self,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}
#[allow(unused_variables)]
fn visit_str<E>(self, value: &str) -> std::result::Result<GeneratedField, E>
where
E: serde::de::Error,
{
Err(serde::de::Error::unknown_field(value, FIELDS))
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = ListFilesRequest;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct musicfs.ListFilesRequest")
}
fn visit_map<V>(self, mut map_: V) -> std::result::Result<ListFilesRequest, V::Error>
where
V: serde::de::MapAccess<'de>,
{
while map_.next_key::<GeneratedField>()?.is_some() {
let _ = map_.next_value::<serde::de::IgnoredAny>()?;
}
Ok(ListFilesRequest {})
}
}
deserializer.deserialize_struct("musicfs.ListFilesRequest", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for ListFilesResponse {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut len = 0;
if !self.files.is_empty() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("musicfs.ListFilesResponse", len)?;
if !self.files.is_empty() {
struct_ser.serialize_field("files", &self.files)?;
}
struct_ser.end()
}
}
impl<'de> serde::Deserialize<'de> for ListFilesResponse {
#[allow(deprecated)]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &["files"];
#[allow(clippy::enum_variant_names)]
enum GeneratedField {
Files,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
D: serde::Deserializer<'de>,
{
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = GeneratedField;
fn expecting(
&self,
formatter: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
write!(formatter, "expected one of: {:?}", &FIELDS)
}
#[allow(unused_variables)]
fn visit_str<E>(self, value: &str) -> std::result::Result<GeneratedField, E>
where
E: serde::de::Error,
{
match value {
"files" => Ok(GeneratedField::Files),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
}
}
struct GeneratedVisitor;
impl<'de> serde::de::Visitor<'de> for GeneratedVisitor {
type Value = ListFilesResponse;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("struct musicfs.ListFilesResponse")
}
fn visit_map<V>(self, mut map_: V) -> std::result::Result<ListFilesResponse, V::Error>
where
V: serde::de::MapAccess<'de>,
{
let mut files__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::Files => {
if files__.is_some() {
return Err(serde::de::Error::duplicate_field("files"));
}
files__ = Some(map_.next_value()?);
}
}
}
Ok(ListFilesResponse {
files: files__.unwrap_or_default(),
})
}
}
deserializer.deserialize_struct("musicfs.ListFilesResponse", FIELDS, GeneratedVisitor)
}
}
impl serde::Serialize for ManifestEntry {
#[allow(deprecated)]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
+57
View File
@@ -940,6 +940,20 @@ pub mod client_control_client {
));
self.inner.unary(req, path, codec).await
}
pub async fn list_files(
&mut self,
request: impl tonic::IntoRequest<super::ListFilesRequest>,
) -> std::result::Result<tonic::Response<super::ListFilesResponse>, tonic::Status> {
self.inner.ready().await.map_err(|e| {
tonic::Status::unknown(format!("Service was not ready: {}", e.into()))
})?;
let codec = tonic_prost::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static("/musicfs.ClientControl/ListFiles");
let mut req = request.into_request();
req.extensions_mut()
.insert(GrpcMethod::new("musicfs.ClientControl", "ListFiles"));
self.inner.unary(req, path, codec).await
}
}
}
/// Generated server implementations.
@@ -963,6 +977,10 @@ pub mod client_control_server {
&self,
request: tonic::Request<super::UpdateMusicMetadataRequest>,
) -> std::result::Result<tonic::Response<super::UpdateMusicMetadataResponse>, tonic::Status>;
async fn list_files(
&self,
request: tonic::Request<super::ListFilesRequest>,
) -> std::result::Result<tonic::Response<super::ListFilesResponse>, tonic::Status>;
}
#[derive(Debug)]
pub struct ClientControlServer<T> {
@@ -1121,6 +1139,45 @@ pub mod client_control_server {
};
Box::pin(fut)
}
"/musicfs.ClientControl/ListFiles" => {
#[allow(non_camel_case_types)]
struct ListFilesSvc<T: ClientControl>(pub Arc<T>);
impl<T: ClientControl> tonic::server::UnaryService<super::ListFilesRequest> for ListFilesSvc<T> {
type Response = super::ListFilesResponse;
type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;
fn call(
&mut self,
request: tonic::Request<super::ListFilesRequest>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as ClientControl>::list_files(&inner, request).await
};
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let max_decoding_message_size = self.max_decoding_message_size;
let max_encoding_message_size = self.max_encoding_message_size;
let inner = self.inner.clone();
let fut = async move {
let method = ListFilesSvc(inner);
let codec = tonic_prost::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
)
.apply_max_message_size_config(
max_decoding_message_size,
max_encoding_message_size,
);
let res = grpc.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
_ => Box::pin(async move {
let mut response = http::Response::new(tonic::body::Body::default());
let headers = response.headers_mut();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+125
View File
@@ -173,6 +173,37 @@ pub mod torrents_client {
.insert(GrpcMethod::new("torrent.Torrents", "Resume"));
self.inner.unary(req, path, codec).await
}
pub async fn notifications(
&mut self,
request: impl tonic::IntoRequest<super::NotificationsRequest>,
) -> std::result::Result<
tonic::Response<tonic::codec::Streaming<super::Notification>>,
tonic::Status,
> {
self.inner.ready().await.map_err(|e| {
tonic::Status::unknown(format!("Service was not ready: {}", e.into()))
})?;
let codec = tonic_prost::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static("/torrent.Torrents/Notifications");
let mut req = request.into_request();
req.extensions_mut()
.insert(GrpcMethod::new("torrent.Torrents", "Notifications"));
self.inner.server_streaming(req, path, codec).await
}
pub async fn files(
&mut self,
request: impl tonic::IntoRequest<super::FilesRequest>,
) -> std::result::Result<tonic::Response<super::FilesResponse>, tonic::Status> {
self.inner.ready().await.map_err(|e| {
tonic::Status::unknown(format!("Service was not ready: {}", e.into()))
})?;
let codec = tonic_prost::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static("/torrent.Torrents/Files");
let mut req = request.into_request();
req.extensions_mut()
.insert(GrpcMethod::new("torrent.Torrents", "Files"));
self.inner.unary(req, path, codec).await
}
}
}
/// Generated server implementations.
@@ -212,6 +243,19 @@ pub mod torrents_server {
&self,
request: tonic::Request<super::ResumeRequest>,
) -> std::result::Result<tonic::Response<super::ResumeResponse>, tonic::Status>;
/// Server streaming response type for the Notifications method.
type NotificationsStream: tonic::codegen::tokio_stream::Stream<
Item = std::result::Result<super::Notification, tonic::Status>,
> + std::marker::Send
+ 'static;
async fn notifications(
&self,
request: tonic::Request<super::NotificationsRequest>,
) -> std::result::Result<tonic::Response<Self::NotificationsStream>, tonic::Status>;
async fn files(
&self,
request: tonic::Request<super::FilesRequest>,
) -> std::result::Result<tonic::Response<super::FilesResponse>, tonic::Status>;
}
#[derive(Debug)]
pub struct TorrentsServer<T> {
@@ -508,6 +552,87 @@ pub mod torrents_server {
};
Box::pin(fut)
}
"/torrent.Torrents/Notifications" => {
#[allow(non_camel_case_types)]
struct NotificationsSvc<T: Torrents>(pub Arc<T>);
impl<T: Torrents>
tonic::server::ServerStreamingService<super::NotificationsRequest>
for NotificationsSvc<T>
{
type Response = super::Notification;
type ResponseStream = T::NotificationsStream;
type Future =
BoxFuture<tonic::Response<Self::ResponseStream>, tonic::Status>;
fn call(
&mut self,
request: tonic::Request<super::NotificationsRequest>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
<T as Torrents>::notifications(&inner, request).await
};
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let max_decoding_message_size = self.max_decoding_message_size;
let max_encoding_message_size = self.max_encoding_message_size;
let inner = self.inner.clone();
let fut = async move {
let method = NotificationsSvc(inner);
let codec = tonic_prost::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
)
.apply_max_message_size_config(
max_decoding_message_size,
max_encoding_message_size,
);
let res = grpc.server_streaming(method, req).await;
Ok(res)
};
Box::pin(fut)
}
"/torrent.Torrents/Files" => {
#[allow(non_camel_case_types)]
struct FilesSvc<T: Torrents>(pub Arc<T>);
impl<T: Torrents> tonic::server::UnaryService<super::FilesRequest> for FilesSvc<T> {
type Response = super::FilesResponse;
type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;
fn call(
&mut self,
request: tonic::Request<super::FilesRequest>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move { <T as Torrents>::files(&inner, request).await };
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let max_decoding_message_size = self.max_decoding_message_size;
let max_encoding_message_size = self.max_encoding_message_size;
let inner = self.inner.clone();
let fut = async move {
let method = FilesSvc(inner);
let codec = tonic_prost::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
)
.apply_max_message_size_config(
max_decoding_message_size,
max_encoding_message_size,
);
let res = grpc.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
_ => Box::pin(async move {
let mut response = http::Response::new(tonic::body::Body::default());
let headers = response.headers_mut();
@@ -67,8 +67,11 @@ impl ::prost::Name for AddRequest {
"/torrent_manager.v1.AddRequest".into()
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AddResponse {}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct AddResponse {
#[prost(string, tag = "1")]
pub torrent_id: ::prost::alloc::string::String,
}
impl ::prost::Name for AddResponse {
const NAME: &'static str = "AddResponse";
const PACKAGE: &'static str = "torrent_manager.v1";
@@ -81,7 +84,7 @@ impl ::prost::Name for AddResponse {
}
/// Encoded file descriptor set for the `torrent_manager.v1` package
pub const FILE_DESCRIPTOR_SET: &[u8] = &[
0x0a, 0xd3, 0x09, 0x0a, 0x28, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e,
0x0a, 0xa9, 0x0a, 0x0a, 0x28, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e,
0x61, 0x67, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f,
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x74,
0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76,
@@ -100,65 +103,70 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[
0x65, 0x63, 0x68, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6c, 0x65,
0x65, 0x63, 0x68, 0x65, 0x72, 0x73, 0x22, 0x1e, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x0d, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa9, 0x01, 0x0a, 0x0e, 0x54, 0x6f, 0x72, 0x72, 0x65, 0x6e,
0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72,
0x63, 0x68, 0x12, 0x21, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e,
0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f,
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63,
0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x03, 0x41, 0x64, 0x64,
0x12, 0x1e, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1f, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67,
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x4a, 0xda, 0x05, 0x0a, 0x06, 0x12, 0x04, 0x00, 0x00, 0x20, 0x01, 0x0a, 0x08, 0x0a, 0x01,
0x0c, 0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x1b,
0x0a, 0x0a, 0x0a, 0x02, 0x06, 0x00, 0x12, 0x04, 0x04, 0x00, 0x07, 0x01, 0x0a, 0x0a, 0x0a, 0x03,
0x06, 0x00, 0x01, 0x12, 0x03, 0x04, 0x08, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00,
0x12, 0x03, 0x05, 0x02, 0x35, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03,
0x05, 0x06, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x05, 0x0d,
0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x05, 0x25, 0x33, 0x0a,
0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x01, 0x12, 0x03, 0x06, 0x02, 0x2c, 0x0a, 0x0c, 0x0a, 0x05,
0x06, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x06, 0x06, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00,
0x02, 0x01, 0x02, 0x12, 0x03, 0x06, 0x0a, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01,
0x03, 0x12, 0x03, 0x06, 0x1f, 0x2a, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x0a, 0x00,
0x0c, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x08, 0x15, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0b, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0b, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02,
0x00, 0x01, 0x12, 0x03, 0x0b, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03,
0x12, 0x03, 0x0b, 0x10, 0x11, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x0e, 0x00, 0x10,
0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x0e, 0x08, 0x16, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x0f, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x01, 0x02, 0x00, 0x12, 0x03, 0x0f, 0x02, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00,
0x06, 0x12, 0x03, 0x0f, 0x0b, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12,
0x03, 0x0f, 0x16, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0f,
0x1d, 0x1e, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x12, 0x00, 0x18, 0x01, 0x0a, 0x0a,
0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x12, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02,
0x02, 0x00, 0x05, 0x12, 0x03, 0x13, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00,
0x12, 0x03, 0x13, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03,
0x13, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x13, 0x10,
0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x05, 0x12, 0x03, 0x14, 0x02, 0x08, 0x0a,
0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x14, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x14, 0x09, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02,
0x02, 0x01, 0x03, 0x12, 0x03, 0x14, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02,
0x05, 0x12, 0x03, 0x16, 0x02, 0x07, 0x0a, 0x3c, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x02, 0x12, 0x03,
0x16, 0x02, 0x14, 0x1a, 0x2f, 0x20, 0x2d, 0x31, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68,
0x65, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x72, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f,
0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x01, 0x12, 0x03, 0x16,
0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x03, 0x12, 0x03, 0x16, 0x12, 0x13,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x05, 0x12, 0x03, 0x17, 0x02, 0x07, 0x0a, 0x0b,
0x0a, 0x04, 0x04, 0x02, 0x02, 0x03, 0x12, 0x03, 0x17, 0x02, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x02, 0x02, 0x03, 0x01, 0x12, 0x03, 0x17, 0x08, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02,
0x03, 0x03, 0x12, 0x03, 0x17, 0x13, 0x14, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x1a,
0x00, 0x1c, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x1a, 0x08, 0x12, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x05, 0x12, 0x03, 0x1b, 0x02, 0x08, 0x0a, 0x0b, 0x0a,
0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x1b, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03,
0x02, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x09, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00,
0x03, 0x12, 0x03, 0x1b, 0x0f, 0x10, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x04, 0x12, 0x04, 0x1e, 0x00,
0x20, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, 0x03, 0x1e, 0x08, 0x13, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x2c, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x72, 0x72, 0x65,
0x6e, 0x74, 0x49, 0x64, 0x32, 0xa9, 0x01, 0x0a, 0x0e, 0x54, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63,
0x68, 0x12, 0x21, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61,
0x67, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d,
0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x12,
0x1e, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1f, 0x2e, 0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x4a, 0x91, 0x06, 0x0a, 0x06, 0x12, 0x04, 0x00, 0x00, 0x20, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c,
0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x02, 0x00, 0x1b, 0x0a,
0x0a, 0x0a, 0x02, 0x06, 0x00, 0x12, 0x04, 0x04, 0x00, 0x07, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x06,
0x00, 0x01, 0x12, 0x03, 0x04, 0x08, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x06, 0x00, 0x02, 0x00, 0x12,
0x03, 0x05, 0x02, 0x35, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x05,
0x06, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x05, 0x0d, 0x1a,
0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x05, 0x25, 0x33, 0x0a, 0x0b,
0x0a, 0x04, 0x06, 0x00, 0x02, 0x01, 0x12, 0x03, 0x06, 0x02, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x06,
0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x06, 0x06, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02,
0x01, 0x02, 0x12, 0x03, 0x06, 0x0a, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x06, 0x00, 0x02, 0x01, 0x03,
0x12, 0x03, 0x06, 0x1f, 0x2a, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x0a, 0x00, 0x0c,
0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x08, 0x15, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0b, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x00, 0x02, 0x00, 0x12, 0x03, 0x0b, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00,
0x01, 0x12, 0x03, 0x0b, 0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12,
0x03, 0x0b, 0x10, 0x11, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x0e, 0x00, 0x10, 0x01,
0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x0e, 0x08, 0x16, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x0f, 0x02, 0x0a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01,
0x02, 0x00, 0x12, 0x03, 0x0f, 0x02, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06,
0x12, 0x03, 0x0f, 0x0b, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03,
0x0f, 0x16, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0f, 0x1d,
0x1e, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x12, 0x00, 0x18, 0x01, 0x0a, 0x0a, 0x0a,
0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x12, 0x08, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02,
0x00, 0x05, 0x12, 0x03, 0x13, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12,
0x03, 0x13, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x13,
0x09, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x13, 0x10, 0x11,
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x05, 0x12, 0x03, 0x14, 0x02, 0x08, 0x0a, 0x0b,
0x0a, 0x04, 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x14, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x14, 0x09, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02,
0x01, 0x03, 0x12, 0x03, 0x14, 0x0f, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x05,
0x12, 0x03, 0x16, 0x02, 0x07, 0x0a, 0x3c, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x02, 0x12, 0x03, 0x16,
0x02, 0x14, 0x1a, 0x2f, 0x20, 0x2d, 0x31, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65,
0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x72, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74,
0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x2e, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x01, 0x12, 0x03, 0x16, 0x08,
0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x03, 0x12, 0x03, 0x16, 0x12, 0x13, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03, 0x05, 0x12, 0x03, 0x17, 0x02, 0x07, 0x0a, 0x0b, 0x0a,
0x04, 0x04, 0x02, 0x02, 0x03, 0x12, 0x03, 0x17, 0x02, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02,
0x02, 0x03, 0x01, 0x12, 0x03, 0x17, 0x08, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x03,
0x03, 0x12, 0x03, 0x17, 0x13, 0x14, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x1a, 0x00,
0x1c, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x1a, 0x08, 0x12, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x05, 0x12, 0x03, 0x1b, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04,
0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x1b, 0x02, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02,
0x00, 0x01, 0x12, 0x03, 0x1b, 0x09, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03,
0x12, 0x03, 0x1b, 0x0f, 0x10, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x04, 0x12, 0x04, 0x1e, 0x00, 0x20,
0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, 0x03, 0x1e, 0x08, 0x13, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x04, 0x02, 0x00, 0x05, 0x12, 0x03, 0x1f, 0x02, 0x08, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x04, 0x02, 0x00, 0x12, 0x03, 0x1f, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00,
0x01, 0x12, 0x03, 0x1f, 0x09, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x03, 0x12,
0x03, 0x1f, 0x16, 0x17, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
];
include!("torrent_manager.v1.serde.rs");
include!("torrent_manager.v1.tonic.rs");
@@ -98,8 +98,14 @@ impl serde::Serialize for AddResponse {
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let len = 0;
let struct_ser = serializer.serialize_struct("torrent_manager.v1.AddResponse", len)?;
let mut len = 0;
if !self.torrent_id.is_empty() {
len += 1;
}
let mut struct_ser = serializer.serialize_struct("torrent_manager.v1.AddResponse", len)?;
if !self.torrent_id.is_empty() {
struct_ser.serialize_field("torrentId", &self.torrent_id)?;
}
struct_ser.end()
}
}
@@ -109,10 +115,12 @@ impl<'de> serde::Deserialize<'de> for AddResponse {
where
D: serde::Deserializer<'de>,
{
const FIELDS: &[&str] = &[];
const FIELDS: &[&str] = &["torrent_id", "torrentId"];
#[allow(clippy::enum_variant_names)]
enum GeneratedField {}
enum GeneratedField {
TorrentId,
}
impl<'de> serde::Deserialize<'de> for GeneratedField {
fn deserialize<D>(deserializer: D) -> std::result::Result<GeneratedField, D::Error>
where
@@ -135,7 +143,10 @@ impl<'de> serde::Deserialize<'de> for AddResponse {
where
E: serde::de::Error,
{
Err(serde::de::Error::unknown_field(value, FIELDS))
match value {
"torrentId" | "torrent_id" => Ok(GeneratedField::TorrentId),
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
}
}
}
deserializer.deserialize_identifier(GeneratedVisitor)
@@ -153,10 +164,20 @@ impl<'de> serde::Deserialize<'de> for AddResponse {
where
V: serde::de::MapAccess<'de>,
{
while map_.next_key::<GeneratedField>()?.is_some() {
let _ = map_.next_value::<serde::de::IgnoredAny>()?;
let mut torrent_id__ = None;
while let Some(k) = map_.next_key()? {
match k {
GeneratedField::TorrentId => {
if torrent_id__.is_some() {
return Err(serde::de::Error::duplicate_field("torrentId"));
}
torrent_id__ = Some(map_.next_value()?);
}
}
}
Ok(AddResponse {})
Ok(AddResponse {
torrent_id: torrent_id__.unwrap_or_default(),
})
}
}
deserializer.deserialize_struct("torrent_manager.v1.AddResponse", FIELDS, GeneratedVisitor)
+30 -9
View File
@@ -4,8 +4,11 @@ mod greeter;
mod health;
mod indexer;
mod magnet_resolver;
mod matching;
mod metadata;
mod music;
mod musicfs;
mod notifier;
mod torrent;
mod generated {
@@ -29,6 +32,10 @@ mod generated {
include!("generated/music/v1/music.v1.rs");
}
pub mod musicfs {
include!("generated/musicfs/musicfs.rs");
}
pub mod health {
include!("generated/health/health.rs");
}
@@ -38,8 +45,13 @@ use std::{fs, sync::Arc};
use generated::{
health::health_server::HealthServer as AggregatorHealthServer,
hello::greeter_server::GreeterServer, metadata::metadata_service_server::MetadataServiceServer,
music::music_service_server::MusicServiceServer, torrent::torrents_server::TorrentsServer,
hello::greeter_server::GreeterServer,
metadata::metadata_service_server::MetadataServiceServer,
music::music_service_server::MusicServiceServer,
musicfs::{
client_control_server::ClientControlServer, client_status_server::ClientStatusServer,
},
torrent::torrents_server::TorrentsServer,
torrent_manager::torrent_manager_server::TorrentManagerServer,
};
use greeter::GreeterService;
@@ -47,6 +59,7 @@ use health::HealthService;
use indexer::Jackett;
use metadata::MetadataService;
use music::MusicService;
use musicfs::MusicfsService;
use tonic_health::pb::health_server::HealthServer;
use torrent::{TorrentMananagerService, TorrentsService};
@@ -65,29 +78,35 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.register_encoded_file_descriptor_set(generated::torrent_manager::FILE_DESCRIPTOR_SET)
.register_encoded_file_descriptor_set(generated::metadata::FILE_DESCRIPTOR_SET)
.register_encoded_file_descriptor_set(generated::music::FILE_DESCRIPTOR_SET)
.register_encoded_file_descriptor_set(generated::musicfs::FILE_DESCRIPTOR_SET)
.register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET)
.build_v1()?;
let torrents = TorrentsService::new(&config.torrent.address);
let metadata = MetadataService::new(&config.metadata.address);
let musicfs = MusicfsService::new(&config.musicfs.address);
let health = HealthService::new(torrents.channel(), metadata.channel());
let indexer = Arc::new(Jackett::new(&config.indexer));
let torrent_manager = TorrentMananagerService::new(torrents.clone(), indexer);
let db_pool = match db::connect(&config.database.url).await {
Ok(pool) => {
if let Err(e) = db::apply_schema(&pool).await {
tracing::warn!(error = %e, "failed to apply DB schema");
}
Some(pool)
}
Ok(pool) => Some(pool),
Err(e) => {
tracing::warn!(error = %e, "failed to connect to database; caching disabled");
None
}
};
let music = MusicService::new(metadata.clone(), torrent_manager.clone(), db_pool);
let music = MusicService::new(metadata.clone(), torrent_manager.clone(), db_pool.clone());
if let Some(ref pool) = db_pool {
notifier::spawn(
pool.clone(),
torrents.clone(),
musicfs.clone(),
metadata.clone(),
);
}
tonic::transport::Server::builder()
.add_service(reflection)
@@ -97,6 +116,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.add_service(TorrentsServer::new(torrents))
.add_service(TorrentManagerServer::new(torrent_manager))
.add_service(MetadataServiceServer::new(metadata))
.add_service(ClientControlServer::new(musicfs.clone()))
.add_service(ClientStatusServer::new(musicfs))
.add_service(MusicServiceServer::new(music))
.serve(addr)
.await?;
+232
View File
@@ -0,0 +1,232 @@
//! Track-to-file matching for the notification subscriber pipeline.
//!
//! Pure functions that pair downloaded audio files with metadata tracks using
//! a two-phase hybrid strategy: deterministic track-number matching first,
//! then sorted-order pairing for the remainder.
use std::path::Path;
use crate::generated::{metadata::Track, musicfs::FileEntry};
/// Outcome of pairing a set of files against a set of tracks.
pub struct MatchResult {
pub matched: Vec<(FileEntry, Track)>,
pub unmatched_files: Vec<FileEntry>,
pub unmatched_tracks: Vec<Track>,
}
/// Strategy for pairing files with tracks.
pub trait TrackMatcher: Send + Sync {
fn match_files_to_tracks(&self, files: &[FileEntry], tracks: &[Track]) -> MatchResult;
}
/// Entry point for obtaining the default matcher.
pub struct MatcherFactory;
impl MatcherFactory {
/// Create the default matcher implementation.
pub fn create() -> impl TrackMatcher {
HybridMatcher
}
}
/// Two-phase matcher: track numbers first, sorted order second.
struct HybridMatcher;
impl TrackMatcher for HybridMatcher {
fn match_files_to_tracks(&self, files: &[FileEntry], tracks: &[Track]) -> MatchResult {
let mut matched: Vec<(FileEntry, Track)> = Vec::new();
let mut files_pool: Vec<usize> = (0..files.len()).collect();
let mut tracks_pool: Vec<usize> = (0..tracks.len()).collect();
// Phase 1: pair by the track number embedded in the filename.
let mut i = 0;
while i < files_pool.len() {
if let Some(num) = extract_track_number(&files[files_pool[i]].name)
&& let Some(pos) = tracks_pool
.iter()
.position(|&t| tracks[t].track_number == num)
{
let t_idx = tracks_pool.remove(pos);
let f_idx = files_pool.remove(i);
matched.push((files[f_idx].clone(), tracks[t_idx].clone()));
continue;
}
i += 1;
}
// Phase 2: alphabetical file order zipped with ascending track order.
files_pool.sort_by(|&a, &b| files[a].name.cmp(&files[b].name));
tracks_pool.sort_by(|&a, &b| tracks[a].track_number.cmp(&tracks[b].track_number));
let zip_count = files_pool.len().min(tracks_pool.len());
for k in 0..zip_count {
matched.push((files[files_pool[k]].clone(), tracks[tracks_pool[k]].clone()));
}
let unmatched_files = files_pool[zip_count..]
.iter()
.map(|&i| files[i].clone())
.collect();
let unmatched_tracks = tracks_pool[zip_count..]
.iter()
.map(|&i| tracks[i].clone())
.collect();
MatchResult {
matched,
unmatched_files,
unmatched_tracks,
}
}
}
/// Extract a track number from a filename by scanning for the first run of
/// ASCII digits in the stem (without extension). Handles `"01 - Title"`,
/// `"01. Title"`, `"14. Песня"`, and `"track5"`. Returns `None` when the
/// stem contains no digits (e.g. `"cover"`, `"foo_dr"`).
pub fn extract_track_number(name: &str) -> Option<i32> {
let stem = Path::new(name).file_stem()?.to_str()?;
let digits: String = stem
.chars()
.skip_while(|c| !c.is_ascii_digit())
.take_while(|c| c.is_ascii_digit())
.collect();
(!digits.is_empty())
.then(|| digits.parse::<i32>())
.and_then(Result::ok)
}
/// True when the filename has a recognized audio extension (case-insensitive).
pub fn is_audio_file(name: &str) -> bool {
let Some(ext) = Path::new(name).extension().and_then(|e| e.to_str()) else {
return false;
};
matches!(
ext.to_ascii_lowercase().as_str(),
"flac" | "mp3" | "m4a" | "ogg" | "wav" | "aac" | "opus"
)
}
#[cfg(test)]
mod tests {
use super::*;
fn file(inode: u64, name: &str) -> FileEntry {
FileEntry {
inode,
original_path: format!("/data/{name}"),
local_path: format!("/fuse/{name}"),
name: name.to_string(),
metadata: None,
}
}
fn track(track_number: i32, title: &str) -> Track {
Track {
id: format!("id-{track_number}"),
title: title.to_string(),
duration_ms: 0,
isrc: String::new(),
explicit: false,
disc_number: 1,
track_number,
artists: Vec::new(),
work: None,
external_ids: Vec::new(),
}
}
#[test]
fn track_number_extraction_cyrillic() {
assert_eq!(extract_track_number("14. Любовь не пропала.flac"), Some(14));
}
#[test]
fn track_number_extraction_leading_digits() {
assert_eq!(extract_track_number("01 - Song.flac"), Some(1));
assert_eq!(extract_track_number("track5.mp3"), Some(5));
}
#[test]
fn track_number_extraction_none() {
assert_eq!(extract_track_number("cover.jpg"), None);
assert_eq!(extract_track_number("foo_dr.flac"), None);
}
#[test]
fn is_audio_file_extensions() {
assert!(is_audio_file("song.flac"));
assert!(is_audio_file("song.mp3"));
assert!(!is_audio_file("cover.jpg"));
assert!(is_audio_file("song.FLAC"));
}
#[test]
fn hybrid_matcher_phase1_track_numbers() {
let files = vec![
file(1, "01 - Alpha.flac"),
file(2, "02 - Beta.flac"),
file(3, "03 - Gamma.flac"),
];
// Tracks deliberately out of order to prove number-based pairing.
let tracks = vec![track(3, "Gamma"), track(1, "Alpha"), track(2, "Beta")];
let result = HybridMatcher.match_files_to_tracks(&files, &tracks);
assert_eq!(result.matched.len(), 3);
assert!(result.unmatched_files.is_empty());
assert!(result.unmatched_tracks.is_empty());
let by_file: std::collections::HashMap<&str, i32> = result
.matched
.iter()
.map(|(f, t)| (f.name.as_str(), t.track_number))
.collect();
assert_eq!(by_file["01 - Alpha.flac"], 1);
assert_eq!(by_file["02 - Beta.flac"], 2);
assert_eq!(by_file["03 - Gamma.flac"], 3);
}
#[test]
fn hybrid_matcher_phase2_sort_order() {
let files = vec![file(1, "c.flac"), file(2, "a.flac"), file(3, "b.flac")];
let tracks = vec![track(3, "C"), track(1, "A"), track(2, "B")];
let result = HybridMatcher.match_files_to_tracks(&files, &tracks);
assert_eq!(result.matched.len(), 3);
// Sorted files: a, b, c <-> sorted tracks by number: 1, 2, 3.
assert_eq!(result.matched[0].0.name, "a.flac");
assert_eq!(result.matched[0].1.track_number, 1);
assert_eq!(result.matched[1].0.name, "b.flac");
assert_eq!(result.matched[1].1.track_number, 2);
assert_eq!(result.matched[2].0.name, "c.flac");
assert_eq!(result.matched[2].1.track_number, 3);
}
#[test]
fn hybrid_matcher_count_mismatch() {
let files = vec![
file(1, "01 - A.flac"),
file(2, "02 - B.flac"),
file(3, "extra.flac"),
];
let tracks = vec![track(1, "A")];
let result = HybridMatcher.match_files_to_tracks(&files, &tracks);
// Phase 1 pairs "01 - A.flac" with track 1; two files stay unmatched.
assert_eq!(result.matched.len(), 1);
assert!(!result.unmatched_files.is_empty());
assert!(result.unmatched_tracks.is_empty());
}
#[test]
fn hybrid_matcher_empty_inputs() {
let result = HybridMatcher.match_files_to_tracks(&[], &[]);
assert!(result.matched.is_empty());
assert!(result.unmatched_files.is_empty());
assert!(result.unmatched_tracks.is_empty());
}
}
+37 -16
View File
@@ -1,8 +1,10 @@
use chrono::Datelike;
use itertools::Itertools;
use tonic::{Request, Response, Status};
use uuid::Uuid;
use crate::{
db,
generated::{
metadata::{
Album, SearchAlbumsRequest, metadata_service_server::MetadataService as MetadataSvc,
@@ -44,8 +46,16 @@ impl Music for MusicService {
&self,
request: Request<MonitorAlbumRequest>,
) -> Result<Response<MonitorAlbumResponse>, Status> {
let pool = self
.db
.as_ref()
.ok_or_else(|| Status::failed_precondition("database unavailable"))?;
let req: &MonitorAlbumRequest = request.get_ref();
let quality = Quality::try_from(req.quality).map_err(|_| {
Status::invalid_argument(format!("invalid quality value: {}", req.quality))
})?;
let search_request = SearchAlbumsRequest {
query: req.album.clone(),
artist: req.artist.clone(),
@@ -57,7 +67,7 @@ impl Music for MusicService {
.search_albums(Request::new(search_request))
.await?;
dbg!(&search_response);
tracing::debug!(?search_response, "metadata search response");
let album: &Album = &search_response.get_ref().albums[0];
let release_year = dateparser::parse(&album.release_date)
@@ -71,12 +81,12 @@ impl Music for MusicService {
let torrent_search_request = SearchRequest { name: name };
dbg!(&torrent_search_request);
tracing::debug!(?torrent_search_request, "torrent search request");
let torrent_search_response = self
.torrent_manager
.search(Request::new(torrent_search_request))
.await?;
dbg!(&torrent_search_response);
tracing::debug!(?torrent_search_response, "torrent search response");
let resolver = match MagnetResolver::new().await {
Ok(r) => Some(std::sync::Arc::new(r)),
@@ -93,28 +103,39 @@ impl Music for MusicService {
let parsed_torrents: Vec<ParsedTorrent> = parser
.parse_search_response(torrent_search_response.get_ref())
.await;
dbg!(&parsed_torrents);
tracing::debug!(?parsed_torrents, "parsed torrents");
// I don't expect it to fail, the request should fail immediately at parse time rather then here
let quality = Quality::try_from(request.get_ref().quality).unwrap();
let matching: Option<ParsedTorrent> = parsed_torrents
.into_iter()
.filter(|pt| pt.year == release_year && quality_matches(quality, pt.format))
.sorted()
.next();
return match matching {
Some(matched) => {
let request: AddRequest = AddRequest { url: matched.url };
self.torrent_manager
.add(Request::new(request))
.await
.map(|_| Response::new(MonitorAlbumResponse::default()))
let matched = match matching {
Some(m) => m,
None => {
return Err(Status::not_found(
"no release matched the requested quality or has enough seeders",
));
}
None => Err(Status::not_found(
"no release matched the requested quality or has enough seeders",
)),
};
let add_request: AddRequest = AddRequest { url: matched.url };
let add_response = self
.torrent_manager
.add(Request::new(add_request))
.await?
.into_inner();
let torrent_id = Uuid::parse_str(&add_response.torrent_id)
.map_err(|e| Status::internal(format!("tora returned invalid torrent_id: {e}")))?;
let quality_str = quality.as_str_name().to_lowercase();
db::insert_monitored_album(pool, &album.id, torrent_id, &quality_str)
.await
.map_err(|e| Status::internal(format!("failed to persist monitored album: {e}")))?;
Ok(Response::new(MonitorAlbumResponse::default()))
}
}
+73
View File
@@ -0,0 +1,73 @@
//! musicfs subsystem proxy. Forwards incoming gRPC calls on the
//! `ClientControl` and `ClientStatus` services to the upstream musicfs-client
//! process, in the same shape as [`crate::torrent::TorrentsService`].
use crate::generated::musicfs::{
ClientStatusResponse, FileEntry, GetClientStatusRequest, GetMusicMetadataRequest,
GetMusicMetadataResponse, ListFilesRequest, ListFilesResponse, UpdateMusicMetadataRequest,
UpdateMusicMetadataResponse, client_control_client::ClientControlClient,
client_control_server::ClientControl, client_status_client::ClientStatusClient,
client_status_server::ClientStatus,
};
use tonic::transport::{Channel, Endpoint};
use tonic::{Request, Response, Status};
#[derive(Debug, Clone)]
pub struct MusicfsService {
channel: Channel,
}
impl MusicfsService {
pub fn new(address: &str) -> Self {
let channel = Endpoint::from_shared(address.to_string())
.expect("musicfs.address should be a valid endpoint")
.connect_lazy();
Self { channel }
}
pub fn channel(&self) -> Channel {
self.channel.clone()
}
}
#[tonic::async_trait]
impl ClientControl for MusicfsService {
async fn get_music_metadata(
&self,
request: Request<GetMusicMetadataRequest>,
) -> Result<Response<GetMusicMetadataResponse>, Status> {
ClientControlClient::new(self.channel.clone())
.get_music_metadata(request.into_inner())
.await
}
async fn update_music_metadata(
&self,
request: Request<UpdateMusicMetadataRequest>,
) -> Result<Response<UpdateMusicMetadataResponse>, Status> {
ClientControlClient::new(self.channel.clone())
.update_music_metadata(request.into_inner())
.await
}
async fn list_files(
&self,
request: Request<ListFilesRequest>,
) -> Result<Response<ListFilesResponse>, Status> {
ClientControlClient::new(self.channel.clone())
.list_files(request.into_inner())
.await
}
}
#[tonic::async_trait]
impl ClientStatus for MusicfsService {
async fn get_client_status(
&self,
request: Request<GetClientStatusRequest>,
) -> Result<Response<ClientStatusResponse>, Status> {
ClientStatusClient::new(self.channel.clone())
.get_client_status(request.into_inner())
.await
}
}
+465
View File
@@ -0,0 +1,465 @@
//! Notification subscriber: orchestrates the album-finishing pipeline.
//!
//! Background task that subscribes to tora's torrent notification stream,
//! catches up on missed FINISHED torrents on startup, and on each FINISHED
//! event looks up album metadata, matches downloaded files to tracks, and
//! writes metadata back into musicfs.
use std::path::Path;
use std::time::Duration;
use anyhow::Result;
use sqlx::PgPool;
use uuid::Uuid;
use crate::db::{get_pending_monitored_albums, mark_album_completed};
use crate::generated::metadata::metadata_service_client::MetadataServiceClient;
use crate::generated::metadata::{
GetAlbumRequest, GetAlbumTracksRequest, Provider, SearchAlbumsRequest,
get_album_request::Identifier as AlbumIdentifier,
};
use crate::generated::musicfs::client_control_client::ClientControlClient;
use crate::generated::musicfs::{ListFilesRequest, UpdateMusicMetadataRequest};
use crate::generated::torrent::notification::Detail as NotificationDetail;
use crate::generated::torrent::torrents_client::TorrentsClient;
use crate::generated::torrent::{
ListRequest, NotificationKind, NotificationsRequest, State, StatusRequest,
};
use crate::matching::{MatcherFactory, TrackMatcher, is_audio_file};
use crate::metadata::MetadataService;
use crate::musicfs::MusicfsService;
use crate::torrent::TorrentsService;
// tonic re-exports tokio_stream — do NOT add tokio-stream to Cargo.toml.
use tonic::codegen::tokio_stream::StreamExt;
/// Spawn the notification subscriber as a fire-and-forget background task.
#[allow(clippy::too_many_arguments)]
pub fn spawn(
pool: PgPool,
torrents: TorrentsService,
musicfs: MusicfsService,
metadata: MetadataService,
) {
tokio::spawn(async move {
run(pool, torrents, musicfs, metadata).await;
});
tracing::info!("notification subscriber started");
}
async fn run(
pool: PgPool,
torrents: TorrentsService,
musicfs: MusicfsService,
metadata: MetadataService,
) {
// Phase 0: reconcile with tora, discover untracked finished torrents.
if let Err(e) = reconcile_with_tora(&pool, &torrents, &metadata).await {
tracing::warn!(error = %e, "reconciliation pass failed");
}
// Phase 1: catch up on albums that finished while we were down.
if let Err(e) = catch_up_missed(&pool, &torrents, &musicfs, &metadata).await {
tracing::warn!(error = %e, "catch-up pass failed");
}
// Phase 2: live subscription with unconditional 5s reconnect.
loop {
if let Err(e) = subscribe_loop(&pool, &torrents, &musicfs, &metadata).await {
tracing::warn!(
error = %e,
code = ?e.code(),
"notification stream disconnected; reconnecting in 5s"
);
tokio::time::sleep(Duration::from_secs(5)).await;
}
}
}
/// Parse a torrent directory name into (artist, album_title).
/// Handles the common "Artist - Album - Year" format.
/// Falls back to (empty, full_name) when the format doesn't match.
fn parse_torrent_name(name: &str) -> (String, String) {
let parts: Vec<&str> = name.split(" - ").collect();
match parts.as_slice() {
[artist, album, ..] => (artist.trim().to_string(), album.trim().to_string()),
_ => (String::new(), name.trim().to_string()),
}
}
/// Discover torrents in tora that finished but were never tracked via
/// MonitorAlbum (e.g. downloaded before the notification subscriber existed).
/// For each, search the metadata service for a matching album and insert it
/// into monitored_albums so the catch-up pass processes it.
async fn reconcile_with_tora(
pool: &PgPool,
torrents: &TorrentsService,
metadata: &MetadataService,
) -> Result<()> {
tracing::info!("reconciliation: starting — querying tora for all torrents");
let list_resp = TorrentsClient::new(torrents.channel())
.list(ListRequest {})
.await?
.into_inner();
let tracked_ids: Vec<Uuid> = sqlx::query_scalar("SELECT torrent_id FROM monitored_albums")
.fetch_all(pool)
.await?;
let tracked: std::collections::HashSet<Uuid> = tracked_ids.into_iter().collect();
tracing::info!(
total_torrents = list_resp.torrents.len(),
already_tracked = tracked.len(),
"reconciliation: processing torrents"
);
let mut checked = 0u32;
let mut inserted = 0u32;
let mut skipped_not_finished = 0u32;
let mut skipped_tracked = 0u32;
let mut no_match = 0u32;
let mut errors = 0u32;
for torrent in &list_resp.torrents {
tracing::debug!(
id = %torrent.id,
name = %torrent.name,
state = torrent.state,
downloaded_bytes = torrent.downloaded_bytes,
total_bytes = torrent.total_bytes,
"reconciliation: checking torrent"
);
checked += 1;
if torrent.state != State::Finished as i32 {
skipped_not_finished += 1;
continue;
}
let torrent_uuid: Uuid = match torrent.id.parse() {
Ok(u) => u,
Err(_) => {
errors += 1;
continue;
}
};
if tracked.contains(&torrent_uuid) {
skipped_tracked += 1;
tracing::debug!(id = %torrent.id, "reconciliation: already tracked, skipping");
continue;
}
let (artist, album_query) = parse_torrent_name(&torrent.name);
tracing::debug!(
artist = %artist,
album = %album_query,
"reconciliation: searching metadata service"
);
let search_resp = match MetadataServiceClient::new(metadata.channel())
.search_albums(SearchAlbumsRequest {
query: album_query,
artist,
limit: 1,
offset: 0,
provider: Provider::Unspecified as i32,
album_types: vec![],
})
.await
{
Ok(resp) => resp.into_inner(),
Err(e) => {
tracing::warn!(
error = %e,
name = %torrent.name,
"reconcile: metadata search failed"
);
errors += 1;
continue;
}
};
tracing::debug!(
results = search_resp.albums.len(),
total_matches = search_resp.total,
"reconciliation: search returned"
);
let Some(album) = search_resp.albums.first() else {
tracing::warn!(
name = %torrent.name,
"reconcile: no album found in metadata service"
);
no_match += 1;
continue;
};
match crate::db::insert_monitored_album(pool, &album.id, torrent_uuid, "reconciled").await {
Ok(_) => {
tracing::info!(
name = %torrent.name,
album_id = %album.id,
"reconcile: tracked previously untracked torrent"
);
inserted += 1;
}
Err(e) => {
tracing::warn!(
error = %e,
name = %torrent.name,
"reconcile: failed to insert monitored_album"
);
errors += 1;
}
}
}
tracing::info!(
checked,
inserted,
skipped_not_finished,
skipped_tracked,
no_match,
errors,
"reconciliation: complete"
);
Ok(())
}
/// Replay any monitored album whose torrent reached FINISHED while the
/// subscriber was offline. Per-album failures are logged and skipped.
async fn catch_up_missed(
pool: &PgPool,
torrents: &TorrentsService,
musicfs: &MusicfsService,
metadata: &MetadataService,
) -> Result<()> {
let pending = get_pending_monitored_albums(pool).await?;
for (torrent_id, album_id) in pending {
let result: Result<()> = async {
let status = TorrentsClient::new(torrents.channel())
.status(StatusRequest {
id: torrent_id.to_string(),
})
.await?
.into_inner();
if status.state == State::Finished as i32 {
handle_finished(pool, torrents, musicfs, metadata, torrent_id, album_id).await?;
}
Ok(())
}
.await;
if let Err(e) = result {
tracing::warn!(error = %e, %torrent_id, "catch-up: failed to process album");
}
}
Ok(())
}
/// Subscribe to the live notification stream and dispatch FINISHED events.
/// Returns when the stream ends or errors; the caller owns reconnect policy.
async fn subscribe_loop(
pool: &PgPool,
torrents: &TorrentsService,
musicfs: &MusicfsService,
metadata: &MetadataService,
) -> Result<(), tonic::Status> {
let mut client = TorrentsClient::new(torrents.channel());
let response = client
.notifications(NotificationsRequest {
ids: vec![],
kinds: vec![NotificationKind::StateChanged as i32],
})
.await?;
let stream = response.into_inner();
tokio::pin!(stream);
while let Some(item) = stream.next().await {
let notification = item?;
if notification.kind != NotificationKind::StateChanged as i32 {
continue;
}
let Some(NotificationDetail::StateChanged(changed)) = notification.detail.as_ref() else {
continue;
};
if changed.current != State::Finished as i32 {
continue;
}
let Some(torrent) = notification.torrent.as_ref() else {
continue;
};
let torrent_id_str = torrent.id.clone();
// Give tora's move-on-completion a moment to settle.
tokio::time::sleep(Duration::from_secs(2)).await;
let torrent_uuid: Uuid = match torrent_id_str.parse() {
Ok(u) => u,
Err(e) => {
tracing::warn!(
error = %e,
id = %torrent_id_str,
"notification: unparseable torrent id"
);
continue;
}
};
let album_id: Option<String> =
sqlx::query_scalar("SELECT album_id FROM monitored_albums WHERE torrent_id = $1")
.bind(torrent_uuid)
.fetch_optional(pool)
.await
.map_err(|e| tonic::Status::internal(format!("db lookup failed: {e}")))?;
let Some(album_id) = album_id else {
continue;
};
if let Err(e) =
handle_finished(pool, torrents, musicfs, metadata, torrent_uuid, album_id).await
{
tracing::warn!(error = %e, %torrent_uuid, "live: failed to process album");
}
}
Ok(())
}
/// Process a single FINISHED album end-to-end: idempotency check, torrent
/// status lookup, metadata + tracks fetch, file filtering, matching, and
/// metadata writeback. Idempotent — a second call for the same torrent is a
/// no-op once `mark_album_completed` has run.
#[allow(clippy::too_many_arguments)]
async fn handle_finished(
pool: &PgPool,
torrents: &TorrentsService,
musicfs: &MusicfsService,
metadata: &MetadataService,
torrent_id: Uuid,
album_id: String,
) -> Result<()> {
let already_completed: bool = sqlx::query_scalar(
"SELECT EXISTS(SELECT 1 FROM monitored_albums \
WHERE torrent_id = $1 AND completed_at IS NOT NULL)",
)
.bind(torrent_id)
.fetch_one(pool)
.await?;
if already_completed {
return Ok(());
}
let status = TorrentsClient::new(torrents.channel())
.status(StatusRequest {
id: torrent_id.to_string(),
})
.await?
.into_inner();
let album_resp = MetadataServiceClient::new(metadata.channel())
.get_album(GetAlbumRequest {
provider: Provider::Unspecified as i32,
identifier: Some(AlbumIdentifier::Id(album_id.clone())),
})
.await?
.into_inner();
let Some(album) = album_resp.album else {
anyhow::bail!("metadata service returned no album for {album_id}");
};
let tracks_resp = MetadataServiceClient::new(metadata.channel())
.get_album_tracks(GetAlbumTracksRequest {
album_id,
provider: Provider::Unspecified as i32,
})
.await?
.into_inner();
let files_resp = ClientControlClient::new(musicfs.channel())
.list_files(ListFilesRequest {})
.await?
.into_inner();
// output_path is tora's download dir; after move-on-completion the files
// live under <download_dir>/completed/<dir_name>/, so we filter by the
// last path component, not by prefix.
let dir_name = Path::new(&status.output_path)
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("");
let mut filtered: Vec<_> = files_resp
.files
.iter()
.filter(|f| is_audio_file(&f.name) && f.original_path.contains(dir_name))
.cloned()
.collect();
filtered.sort_by(|a, b| a.name.cmp(&b.name));
let matcher = MatcherFactory::create();
let result = matcher.match_files_to_tracks(&filtered, &tracks_resp.tracks);
let album_artist = album
.artists
.first()
.and_then(|credit| credit.artist.as_ref())
.map(|artist| artist.name.clone())
.unwrap_or_else(|| "Unknown Artist".to_string());
for (file, track) in &result.matched {
let needs_update = match file.metadata.as_ref() {
None => true,
Some(existing) => {
existing.track_title != track.title
|| existing.track_number != track.track_number
|| existing.album != album.title
|| !existing.artist.iter().any(|a| a == &album_artist)
}
};
if !needs_update {
continue;
}
ClientControlClient::new(musicfs.channel())
.update_music_metadata(UpdateMusicMetadataRequest {
inode: file.inode,
artist: vec![album_artist.clone()],
album_artist: Some(album_artist.clone()),
album: album.title.clone(),
track_number: track.track_number,
track_title: track.title.clone(),
other_tags: vec![],
})
.await?;
tracing::debug!(
inode = file.inode,
name = %file.name,
before_track_title = ?file.metadata.as_ref().map(|m| &m.track_title),
before_track_number = ?file.metadata.as_ref().map(|m| m.track_number),
before_album = ?file.metadata.as_ref().map(|m| &m.album),
before_artist = ?file.metadata.as_ref().map(|m| &m.artist),
after_track_title = %track.title,
after_track_number = track.track_number,
after_album = %album.title,
after_artist = %album_artist,
"metadata updated"
);
}
for file in &result.unmatched_files {
tracing::warn!(inode = file.inode, name = %file.name, "no matching track for file");
}
mark_album_completed(pool, torrent_id).await?;
tracing::info!(
%torrent_id,
matched = result.matched.len(),
unmatched_files = result.unmatched_files.len(),
"album processing complete"
);
Ok(())
}
+20
View File
@@ -42,6 +42,8 @@ impl TorrentsService {
#[tonic::async_trait]
impl Torrents for TorrentsService {
type NotificationsStream = tonic::codec::Streaming<Notification>;
async fn add(
&self,
request: tonic::Request<AddRequest>,
@@ -95,4 +97,22 @@ impl Torrents for TorrentsService {
.resume(request.into_inner())
.await;
}
async fn notifications(
&self,
request: tonic::Request<NotificationsRequest>,
) -> Result<tonic::Response<Self::NotificationsStream>, tonic::Status> {
TorrentsClient::new(self.channel.clone())
.notifications(request.into_inner())
.await
}
async fn files(
&self,
request: tonic::Request<FilesRequest>,
) -> Result<tonic::Response<FilesResponse>, tonic::Status> {
TorrentsClient::new(self.channel.clone())
.files(request.into_inner())
.await
}
}
+7 -4
View File
@@ -74,10 +74,13 @@ impl TorrentManager for TorrentMananagerService {
let req = request.into_inner();
let daemon_req = DaemonAddRequest {
magnet: req.url,
output_dir: String::new(),
download_folder: String::new(),
move_after_completion_folder: String::new(),
};
return TorrentsDaemon::add(&self.torrents_service, tonic::Request::new(daemon_req))
.await
.map(|_| tonic::Response::new(AddResponse {}));
let daemon_resp =
TorrentsDaemon::add(&self.torrents_service, tonic::Request::new(daemon_req)).await?;
Ok(tonic::Response::new(AddResponse {
torrent_id: daemon_resp.into_inner().id,
}))
}
}
+1 -1
Submodule tora updated: 6309b87323...3f3a6d354a