This commit is contained in:
Michael Zhang 2022-05-09 11:56:49 -05:00
parent 24dedd4b57
commit 934917a7b3
Signed by: michael
GPG Key ID: BDA47A31A3C8EE6B
552 changed files with 12295 additions and 0 deletions

1
editor-old/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

811
editor-old/Cargo.lock generated Normal file
View File

@ -0,0 +1,811 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "addr2line"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
[[package]]
name = "autocfg"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598"
dependencies = [
"addr2line",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cc"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags",
]
[[package]]
name = "cmake"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855"
dependencies = [
"cc",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "editor"
version = "0.1.0"
dependencies = [
"anyhow",
"osu",
"sdl2",
"soloud",
]
[[package]]
name = "env_logger"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
dependencies = [
"log",
"regex",
]
[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2 1.0.24",
"quote 1.0.7",
"syn 1.0.54",
"synstructure",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "futures"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
[[package]]
name = "futures-executor"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb"
[[package]]
name = "futures-macro"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556"
dependencies = [
"proc-macro-hack",
"proc-macro2 1.0.24",
"quote 1.0.7",
"syn 1.0.54",
]
[[package]]
name = "futures-sink"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
[[package]]
name = "futures-task"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d"
dependencies = [
"once_cell",
]
[[package]]
name = "futures-util"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]
[[package]]
name = "gimli"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
[[package]]
name = "itoa"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "log"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if 0.1.10",
]
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "miniz_oxide"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
dependencies = [
"adler",
"autocfg 1.0.1",
]
[[package]]
name = "num-bigint"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e9a41747ae4633fce5adffb4d2e81ffc5e89593cb19917f8fb2cc5ff76507bf"
dependencies = [
"autocfg 1.0.1",
"num-integer",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg 1.0.1",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
"autocfg 1.0.1",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg 1.0.1",
]
[[package]]
name = "object"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
[[package]]
name = "once_cell"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
[[package]]
name = "osu"
version = "0.0.8"
dependencies = [
"difference",
"failure",
"futures",
"lazy_static",
"num-rational",
"regex",
"serde",
"serde_json",
"sortedvec",
"thiserror",
]
[[package]]
name = "pin-project"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f"
dependencies = [
"proc-macro2 1.0.24",
"quote 1.0.7",
"syn 1.0.54",
]
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
[[package]]
name = "proc-macro2"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
dependencies = [
"unicode-xid 0.1.0",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid 0.2.1",
]
[[package]]
name = "quickcheck"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c35d9c36a562f37eca96e79f66d5fd56eefbc22560dacc4a864cabd2d277456"
dependencies = [
"env_logger",
"log",
"rand",
"rand_core 0.4.2",
]
[[package]]
name = "quickcheck_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dfc1c4a1e048f5cc7d36a4c4118dfcf31d217c79f4b9a61bad65d68185752c"
dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.13",
"syn 0.15.44",
]
[[package]]
name = "quote"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
dependencies = [
"proc-macro2 0.4.30",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2 1.0.24",
]
[[package]]
name = "rand"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
dependencies = [
"autocfg 0.1.7",
"libc",
"rand_chacha",
"rand_core 0.4.2",
"rand_hc",
"rand_isaac",
"rand_jitter",
"rand_os",
"rand_pcg",
"rand_xorshift",
"winapi",
]
[[package]]
name = "rand_chacha"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
dependencies = [
"autocfg 0.1.7",
"rand_core 0.3.1",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rand_hc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rand_isaac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rand_jitter"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
dependencies = [
"libc",
"rand_core 0.4.2",
"winapi",
]
[[package]]
name = "rand_os"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
dependencies = [
"cloudabi",
"fuchsia-cprng",
"libc",
"rand_core 0.4.2",
"rdrand",
"winapi",
]
[[package]]
name = "rand_pcg"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
dependencies = [
"autocfg 0.1.7",
"rand_core 0.4.2",
]
[[package]]
name = "rand_xorshift"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "regex"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
[[package]]
name = "rustc-demangle"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "sdl2"
version = "0.34.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcbb85f4211627a7291c83434d6bbfa723e28dcaa53c7606087e3c61929e4b9c"
dependencies = [
"bitflags",
"lazy_static",
"libc",
"sdl2-sys",
]
[[package]]
name = "sdl2-sys"
version = "0.34.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d81feded049b9c14eceb4a4f6d596a98cebbd59abdba949c5552a015466d33"
dependencies = [
"cfg-if 0.1.10",
"libc",
"version-compare",
]
[[package]]
name = "serde"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
dependencies = [
"proc-macro2 1.0.24",
"quote 1.0.7",
"syn 1.0.54",
]
[[package]]
name = "serde_json"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "soloud"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0132cf191d55ce7d58cae67e2b59f32fd219a632500a66dd5fc835a1e900be20"
dependencies = [
"soloud-derive",
"soloud-sys",
]
[[package]]
name = "soloud-derive"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba751f21243757bd8159bc736864d955d98c019ac18cbf5030eeb74d2eb7d23a"
dependencies = [
"quote 1.0.7",
"syn 1.0.54",
]
[[package]]
name = "soloud-sys"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b8d8e6ab2c2779d7b0c699a0aafb8f9c96d334b00eefd33bd5c5eba5cc0e6bf"
dependencies = [
"cmake",
"libc",
]
[[package]]
name = "sortedvec"
version = "0.5.0"
dependencies = [
"quickcheck",
"quickcheck_macros",
"rand",
]
[[package]]
name = "syn"
version = "0.15.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.13",
"unicode-xid 0.1.0",
]
[[package]]
name = "syn"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
dependencies = [
"proc-macro2 1.0.24",
"quote 1.0.7",
"unicode-xid 0.2.1",
]
[[package]]
name = "synstructure"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
dependencies = [
"proc-macro2 1.0.24",
"quote 1.0.7",
"syn 1.0.54",
"unicode-xid 0.2.1",
]
[[package]]
name = "thiserror"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [
"proc-macro2 1.0.24",
"quote 1.0.7",
"syn 1.0.54",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
dependencies = [
"lazy_static",
]
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "version-compare"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

17
editor-old/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "editor"
version = "0.1.0"
authors = ["Michael Zhang <iptq@protonmail.com>"]
edition = "2018"
[workspace]
members = [
"osu",
"sortedvec",
]
[dependencies]
soloud = { version = "0.1.8", features = ["use-ninja"] }
anyhow = "1.0.32"
sdl2 = { version = "0.34.3", features = ["ttf"] }
osu = {path = "osu", default-features = false}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

93
editor-old/font/OFL.txt Normal file
View File

@ -0,0 +1,93 @@
Copyright 2020 The Epilogue Project Authors (https://github.com/Etcetera-Type-Co/Epilogue)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

5
editor-old/osu/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
Cargo.lock
target
.pytest_cache
*~

24
editor-old/osu/Cargo.toml Normal file
View File

@ -0,0 +1,24 @@
[package]
name = "osu"
version = "0.0.8"
authors = ["michael <mail@mzhang.io>"]
edition = "2018"
description = "General-purpose osu! library with bindings for other languages."
license = "MIT"
readme = "README.md"
[dev-dependencies]
serde_json = "1.0.57"
difference = "2.0.0"
[dependencies]
failure = "0.1.8"
futures = "0.3.5"
lazy_static = "1.4.0"
num-rational = "0.3.0"
regex = "1.3.9"
serde = { version = "1.0.116", features = ["derive"] }
serde_json = "1.0.57"
sortedvec = {path = "../sortedvec"}
thiserror = "1.0.20"

39
editor-old/osu/README.md Normal file
View File

@ -0,0 +1,39 @@
libosu
======
[![CI](https://travis-ci.org/iptq/libosu.svg?branch=master)](https://travis-ci.org/iptq/libosu)
[![Crates.io](https://img.shields.io/crates/d/libosu.svg)](https://crates.io/crates/libosu)
[![Documentation](https://docs.rs/libosu/badge.svg)](https://docs.rs/libosu)
[![dependency status](https://deps.rs/repo/github/iptq/libosu/status.svg)](https://deps.rs/repo/github/iptq/libosu)
[![Discord](https://img.shields.io/discord/419098645783379978.svg)](https://discord.gg/MpXXvsD)
General-purpose osu! library
Installation
------------
This package is hosted on [crates.io](https://crates.io). In order to include this library into your project, simply add this line into your `Cargo.toml`:
```rust
libosu = "*"
```
Bindings for other languages are under development, and will be listed here once they become available.
Getting Started
---------------
Check out the [API Documentation](https://docs.rs/libosu) for details on how to use the various functions, or check out some of the examples (pending).
Why Rust?
---------
The real question is, why _not_ rust? For a low level language, Rust has many language features such as generics and a rich type system that greatly enhances development. Additionally, its strong emphasis on memory safety means that it can perform at native speeds. Most languages support native library extensions already, so integration into other languages is also possible. One other interesting feature is that Rust already has relatively good support for WebAssembly, which means it could be possible to integrate this library into web applications as well.
Contact
-------
Authors: Michael Zhang
License: MIT

View File

@ -0,0 +1,331 @@
mod timing;
use std::path::PathBuf;
use failure::Error;
use serde::ser::{Serialize, SerializeStruct, Serializer};
use crate::{
Color, HitObject, HitObjectKind, Hitsound, Mode, SampleSet, Timestamp,
TimingPoint,
};
/// Difficulty settings defined by the map.
#[derive(Debug, Default)]
pub struct Difficulty {
/// HP Drain Rate
///
/// The wiki doesn't have a solid definition of this field yet.
pub hp_drain_rate: f32,
/// Circle Size
///
/// This is a value between 0 and 10 representing how big circles should
/// appear on screen. The radius in osu!pixels is defined by the
/// formula `32 * (1 - 0.7 * (CircleSize - 5) / 5)`, alternatively written
/// `54.4 - 4.48 * CircleSize`.
///
/// In osu!mania, this actually defines the number of columns (keys).
pub circle_size: f32,
/// Overall Difficulty
pub overall_difficulty: f32,
/// Approach Rate
pub approach_rate: f32,
/// Slider Multiplier
pub slider_multiplier: f32,
}
sortedvec! {
/// List of hit objects that's always sorted
#[derive(Debug)]
pub struct HitObjectList {
fn derive_key(hit_object: &HitObject) -> Timestamp {
hit_object.start_time
}
}
}
sortedvec! {
/// List of timing points that's always sorted
#[derive(Debug)]
pub struct TimingPointList {
fn derive_key(timing_point: &TimingPoint) -> (Timestamp, bool) {
(timing_point.time, timing_point.is_inherited())
}
}
}
/// Represents a single beatmap.
#[derive(Debug)]
pub struct Beatmap {
/// File path
pub file_path: Option<PathBuf>,
/// The osu! file format being used
pub version: u32,
/// The name of the audio file to use, relative to the beatmap file.
pub audio_filename: String,
/// The amount of time (in milliseconds) added before the audio file begins
/// playing. Useful for audio files that begin immediately.
pub audio_leadin: u32,
/// When (in milliseconds) the audio file should begin playing when
/// selected in the song selection menu.
pub preview_time: u32,
/// Whether or not to show the countdown
pub countdown: bool,
/// The default sample set for hit objects which don't have a custom
/// override.
pub sample_set: SampleSet,
/// Leniency for stacked objects.
pub stack_leniency: f64,
/// The game mode (standard, taiko, catch the beat, mania).
pub mode: Mode,
/// Whether or not to show black borders during breaks.
pub letterbox_in_breaks: bool,
/// TODO: unknown field
pub widescreen_storyboard: bool,
/// An instance of the difficulty settings.
pub difficulty: Difficulty,
/// Bookmarks in the editor
pub bookmarks: Vec<i32>,
/// The last setting used for distance spacing.
pub distance_spacing: f64,
/// The last setting used for beat divisor
pub beat_divisor: u8,
/// The last setting used for grid size
pub grid_size: u8,
/// The last setting used for timeline zoom
pub timeline_zoom: f64,
/// The title of the song (ASCII only).
pub title: String,
/// The title of the song (UTF-8).
pub title_unicode: String,
/// The artist of the song (ASCII only).
pub artist: String,
/// The artist of the song (UTF-8).
pub artist_unicode: String,
/// The creator of the mapset.
pub creator: String,
/// The name of the difficulty.
pub difficulty_name: String,
/// Optional source.
pub source: String,
/// Optional tags.
pub tags: Vec<String>,
/// The beatmap ID on Bancho.
pub beatmap_id: i32,
/// The beatmap set ID on Bancho.
pub beatmap_set_id: i32,
/// Overridden combo colors.
pub colors: Vec<Color>,
/// The set of hit objects.
pub hit_objects: HitObjectList,
/// The set of timing points.
pub timing_points: TimingPointList,
}
impl Default for Beatmap {
fn default() -> Self {
Beatmap {
file_path: None,
version: 0,
audio_filename: String::new(),
audio_leadin: 0,
preview_time: 0,
countdown: false,
sample_set: SampleSet::None,
stack_leniency: 0.7,
mode: Mode::Osu,
letterbox_in_breaks: false,
widescreen_storyboard: false,
difficulty: Difficulty::default(),
bookmarks: Vec::new(),
distance_spacing: 0.0,
beat_divisor: 1,
grid_size: 1,
timeline_zoom: 0.0,
title: String::new(),
title_unicode: String::new(),
artist: String::new(),
artist_unicode: String::new(),
creator: String::new(),
difficulty_name: String::new(),
source: String::new(),
tags: Vec::new(),
beatmap_id: 0,
beatmap_set_id: -1,
colors: Vec::new(),
hit_objects: HitObjectList::default(),
timing_points: TimingPointList::default(),
}
}
}
impl Beatmap {
/// Gets the path to the audio file
///
/// Returns none if the file doesn't exist
pub fn audio_filepath(&self) -> Option<PathBuf> {
self.file_path.clone().and_then(|path| {
let path = path.parent()?.join(&self.audio_filename);
if !path.exists() {
return None;
}
Some(path)
})
}
pub(crate) fn associate_hitobjects(&mut self) {
/*
let mut curr = 1;
for obj_ref in self.hit_objects.iter() {
if curr >= self.timing_points.len() {
break;
}
let obj = obj_ref.borrow();
let obj_time = obj.start_time.into_milliseconds();
// should we advance?
let next_time = self.timing_points[curr].borrow().time.into_milliseconds();
if obj_time >= next_time {
curr += 1;
}
// assign timing point
let tp = &self.timing_points[curr - 1].borrow();
let bpm = tp.get_bpm();
let meter = tp.get_meter();
let (measures, frac) = obj.start_time.approximate(&tp.time, bpm, meter);
let mut obj_mut = (**obj_ref).borrow_mut();
obj_mut.start_time = TimeLocation::Relative {
time: Box::new(tp.time.clone()),
bpm: tp.get_bpm(),
meter: tp.get_meter(),
measures,
frac,
};
}
*/
}
/// Returns the timing point associated with the timing section to which the
/// given time belongs.`
pub fn locate_timing_point(
&self,
time: impl Into<Timestamp>,
) -> Option<TimingPoint> {
// TODO: make this efficient
let mut tp = None;
let time = time.into();
for timing_point in self.timing_points.iter() {
if &timing_point.time < &time {
tp = Some(timing_point.clone());
}
}
tp
}
/// Returns the hitobject located at the given time.
pub fn locate_hitobject(
&self,
time: impl Into<Timestamp>,
) -> Option<HitObject> {
let time = time.into();
for mut hit_object in self.hit_objects.iter() {
if &hit_object.start_time == &time {
return Some(hit_object.clone());
}
if let HitObjectKind::Slider { .. } = hit_object.kind {}
}
None
}
/// Set a hitsound at the given time.
// pub fn set_hitsound(&mut self, time: impl Into<TimeLocation>, hitsound:
// &Hitsound) { if let Some(hit_object) =
// self.locate_hitobject(time) { if let Some(mut hit_object) =
// self.hit_objects.take(&hit_object) {
// hit_object.set_hitsound(hitsound);
// self.hit_objects.insert(hit_object); }
// }
// }
/// Get a list of all hit objects.
pub fn get_hitobjects(&self) -> Vec<HitObject> {
self.hit_objects.iter().cloned().collect::<Vec<_>>()
}
/// Returns a list of this beatmap's hitsounds.
///
/// This will also return hitsounds that occur on parts of objects, for
/// example on slider bodies or slider ends. If a hitsound occurs on a
/// spinner, the only "sound" that's counted is the moment that the
/// spinner ends.
pub fn get_hitsounds(&self) -> Result<Vec<(Timestamp, Hitsound)>, Error> {
let mut hitsounds = Vec::new();
for obj in self.hit_objects.iter() {
let start_time = obj.start_time;
match obj.kind {
HitObjectKind::Slider {
ref repeats,
ref duration,
..
} => {
// TODO: calculate middle hitsounds
for i in 0..(repeats + 1) {
let time = start_time + (i * duration) as f64;
hitsounds.push((time, obj.hitsound.clone()));
}
}
_ => hitsounds.push((start_time, obj.hitsound.clone())),
}
}
Ok(hitsounds)
}
}
impl Serialize for Beatmap {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("Beatmap", 1)?;
state.serialize_field("version", &self.version)?;
// state.serialize_field("timing_points", &self.timing_points)?;
state.end()
}
}

View File

@ -0,0 +1,63 @@
use crate::timing::{TimingPoint, TimingPointKind};
use super::{Beatmap, TimingPointList};
impl Beatmap {
/// Gets the closest parent that is an uninherited timing point.
pub fn get_uninherited_ancestor<'a>(
&'a self,
timing_point: &'a TimingPoint,
) -> &'a TimingPoint {
match timing_point.kind {
TimingPointKind::Uninherited { .. } => timing_point,
TimingPointKind::Inherited { .. } => {
// get the current one
let mut current_idx = self
.timing_points
.index(&(timing_point.time, timing_point.is_inherited()))
// TODO: don't unwrap here
.unwrap();
loop {
let timing_point = &self.timing_points[current_idx];
if !timing_point.is_inherited() {
break;
}
if current_idx == 0 {
panic!("asdf");
}
current_idx -= 1;
}
&self.timing_points[current_idx]
}
}
}
/// Gets the BPM of this timing section by climbing the timing section tree.
pub fn get_bpm_of(&self, timing_point: &TimingPoint) -> f64 {
let ancestor = self.get_uninherited_ancestor(timing_point);
match &ancestor.kind {
&TimingPointKind::Uninherited { ref bpm, .. } => *bpm,
_ => panic!(
"The ancestor should always be an Uninherited timing point."
),
}
}
/// Gets the meter of this timing section by climbing the timing section
/// tree.
pub fn get_meter_of(&self, timing_point: &TimingPoint) -> u32 {
let ancestor = self.get_uninherited_ancestor(timing_point);
match &ancestor.kind {
&TimingPointKind::Uninherited { ref meter, .. } => *meter,
_ => panic!(
"The ancestor should always be an Uninherited timing point."
),
}
}
/// Returns the number of milliseconds in a beat for this timing section.
pub fn get_beat_duration(&self, timing_point: &TimingPoint) -> f64 {
return 60_000.0 / self.get_bpm_of(timing_point);
}
}

View File

@ -0,0 +1,10 @@
/// Represents an RGB color.
// TODO: alpha?
#[derive(Debug, Serialize, Deserialize)]
pub struct Color {
red: u8,
green: u8,
blue: u8,
}
impl Color {}

View File

@ -0,0 +1,58 @@
use std::ops::BitOr;
/// Integer enumeration of the game's game modes.
#[derive(Debug, Copy, Clone)]
#[allow(missing_docs)]
pub enum Mode {
Osu = 0,
Taiko = 1,
Catch = 2,
Mania = 3,
}
/// Mod listing with their respective bitwise representation.
///
/// This list is ripped directly from the [osu! wiki](https://github.com/ppy/osu-api/wiki).
#[allow(missing_docs)]
pub enum Mods {
None = 0,
NoFail = 1,
Easy = 2,
NoVideo = 4, /* Not used anymore, but can be found on old plays like
* Mesita on b/78239 */
Hidden = 8,
HardRock = 16,
SuddenDeath = 32,
DoubleTime = 64,
Relax = 128,
HalfTime = 256,
Nightcore = 512, // Only set along with DoubleTime. i.e: NC only gives 576
Flashlight = 1024,
Autoplay = 2048,
SpunOut = 4096,
Relax2 = 8192, // Autopilot?
Perfect = 16384, /* Only set along with SuddenDeath. i.e: PF only gives
* 16416 */
Key4 = 32768,
Key5 = 65536,
Key6 = 131072,
Key7 = 262144,
Key8 = 524288,
KeyMod = 1015808,
FadeIn = 1048576,
Random = 2097152,
LastMod = 4194304,
FreeModAllowed = 2077883,
Key9 = 16777216,
Key10 = 33554432,
Key1 = 67108864,
Key3 = 134217728,
Key2 = 268435456,
}
impl BitOr for Mods {
type Output = u32;
fn bitor(self, other: Self) -> Self::Output {
return self as u32 | other as u32;
}
}

View File

@ -0,0 +1,106 @@
use std::cmp::Ordering;
use serde::ser::*;
use crate::{Hitsound, Point, Timestamp, TimingPoint};
/// Distinguishes between different types of slider splines.
#[derive(Clone, Debug)]
pub enum SliderSplineKind {
/// Linear is the most straightforward, and literally consists of two
/// endpoints.
Linear,
/// Bezier is more complex, using control points to create smooth curves.
Bezier,
/// Catmull is a deprecated slider spline used mainly in older maps (looks
/// ugly btw).
Catmull,
/// Perfect (circle) splines are circles circumscribed around three control
/// points.
Perfect,
}
/// Distinguishes between different types of hit objects.
#[derive(Clone, Debug)]
pub enum HitObjectKind {
/// Regular hit circle.
Circle,
/// Slider.
Slider {
/// The algorithm used to calculate the spline.
kind: SliderSplineKind,
/// The control points that make up the body of the slider.
control: Vec<Point<i32>>,
/// The number of times this slider should repeat.
repeats: u32,
/// How long this slider is in pixels.
pixel_length: f64,
/// The number of milliseconds long that this slider lasts.
duration: u32,
},
/// Spinner.
Spinner {
/// The time at which the slider ends.
end_time: Timestamp,
},
}
/// Represents a single hit object.
#[derive(Clone, Debug)]
pub struct HitObject {
/// The position on the map at which this hit object is located (head for
/// sliders).
pub pos: Point<i32>,
/// When this hit object occurs during the map.
pub start_time: Timestamp,
/// The kind of HitObject this represents (circle, slider, spinner).
pub kind: HitObjectKind,
/// Whether or not this object begins a new combo.
pub new_combo: bool,
/// Reference to the timing point under which this HitObject belongs.
pub timing_point: Option<TimingPoint>,
/// The number of combo colors to skip
pub skip_color: i32,
/// The hitsound attached to this hit object.
pub hitsound: Hitsound,
}
impl HitObject {
/// Replaces the hitsound on this hitobject.
pub fn set_hitsound(&mut self, hitsound: &Hitsound) {
self.hitsound = hitsound.clone();
}
}
impl Serialize for HitObject {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let state = serializer.serialize_struct("HitObject", 0)?;
state.end()
}
}
impl PartialOrd for HitObject {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.start_time.partial_cmp(&other.start_time)
}
}
impl Eq for HitObject {}
impl PartialEq for HitObject {
fn eq(&self, other: &Self) -> bool {
self.start_time == other.start_time
}
}

View File

@ -0,0 +1,54 @@
use std::ops::BitOr;
use crate::Timestamp;
/// A set of hitsound samples.
///
/// Hitsounds come in sample sets of (normal, soft, drum). In beatmaps, there is
/// a sample set that apply to the entire beatmap as a whole, to timing sections
/// specifically, to individual notes, or even the hitsound additions (whistle,
/// finish, clap).
#[derive(Clone, Debug)]
pub enum SampleSet {
/// No sample set used. (TODO: wtf?)
None = 0,
/// Normal sample set.
Normal = 1,
/// Soft sample set.
Soft = 2,
/// Drum sample set.
Drum = 3,
}
/// A representation of hitsound additions.
#[derive(Clone, Debug)]
pub struct Additions(pub u32);
/// A hitsound "item" represents a single "hitsound".
#[derive(Clone, Debug)]
pub struct Hitsound {
/// The time at which this hitsound occurs.
pub time: Timestamp,
/// The sample (normal/soft/drum) this hitsound uses.
pub sample: SampleSet,
/// The additions (whistle, finish, clap) attached to this hitsound.
pub additions: Additions,
/// TODO: additional field
pub sample_set: i32,
/// TODO: additional field
pub addition_set: i32,
/// TODO: additional field
pub custom_index: i32,
/// TODO: additional field
pub sample_volume: i32,
/// TODO: additional field
pub filename: String,
}
impl BitOr for Additions {
type Output = u32;
fn bitor(self, other: Self) -> Self::Output {
return self.0 | other.0;
}
}

47
editor-old/osu/src/lib.rs Normal file
View File

@ -0,0 +1,47 @@
//! # libosu
//!
//! `libosu` is an attempt to make a convenient library for writing osu!-related
//! programs. It includes data structures and parsers for beatmaps, replays, and
//! more.
//!
//! Please note that until this crate hits `1.0`, none of the APIs in this crate
//! will be stable, so take care when using this crate.
#![deny(missing_docs)]
#[macro_use]
extern crate failure;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate serde;
#[macro_use]
extern crate sortedvec;
#[macro_use]
extern crate thiserror;
mod beatmap;
mod color;
mod enums;
mod hitobject;
mod hitsounds;
mod osz;
mod point;
mod replay;
mod timing;
pub use beatmap::*;
pub use color::*;
pub use enums::*;
pub use hitobject::*;
pub use hitsounds::*;
pub use osz::*;
pub use point::*;
pub use replay::*;
pub use timing::*;
/// Says "hello there"
#[deprecated]
pub fn say_hello_there() {
println!("hello there");
}

View File

@ -0,0 +1,367 @@
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use failure::Error;
use regex::Regex;
use crate::beatmap::{Beatmap, HitObjectList, TimingPointList};
use crate::{HitObject, Mode, SampleSet, TimingPoint, TimingPointKind};
lazy_static! {
static ref OSU_FORMAT_VERSION_RGX: Regex =
Regex::new(r"^osu file format v(?P<version>\d+)$").unwrap();
static ref SECTION_HEADER_RGX: Regex =
Regex::new(r"^\[(?P<name>[A-Za-z]+)\]$").unwrap();
static ref KEY_VALUE_RGX: Regex =
Regex::new(r"^(?P<key>[A-Za-z0-9]+)\s*:\s*(?P<value>.+)$").unwrap();
}
/// Macro for matching beatmap keys easier.
macro_rules! kvalue {
($captures:ident[$name:expr]: str) => {
$name = String::from(&$captures["value"]);
};
($captures:ident[$name:expr] => str) => {
String::from(&$captures["value"])
};
($captures:ident[$name:expr]: parse(bool)) => {
$name = {
let val = kvalue!($captures[$name] => parse(u8));
if val == 0 {
false
} else {
true
}
};
};
($captures:ident[$name:expr] => parse($type:ident)) => {
$captures["value"].parse::<$type>()?
};
($captures:ident[$name:expr]: parse($type:ident)) => {
$name = $captures["value"].parse::<$type>()?;
};
}
impl Beatmap {
/// Loads a Beatmap from a path
pub fn from_file(path: impl AsRef<Path>) -> Result<Beatmap, Error> {
let path = path.as_ref().to_path_buf();
let mut file = File::open(&path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Self::from_osz(contents, Some(path))
}
/// Creates a Beatmap from the *.osz format
pub fn from_osz(
input: impl AsRef<str>,
path: Option<PathBuf>,
) -> Result<Beatmap, Error> {
// TODO: actually, replace all the required "default" values with
// Option<T>s.
let mut section = "Version".to_owned();
let mut beatmap = Beatmap::default();
beatmap.file_path = path;
let mut timing_points = Vec::new();
let mut timing_point_lines = Vec::new();
let mut hit_object_lines = Vec::new();
for line in input.as_ref().lines() {
match SECTION_HEADER_RGX.captures(line) {
Some(captures) => {
section = String::from(&captures["name"]);
continue;
}
None => (),
}
// println!("\"{}\" {}", section, line);
//
if line.trim().len() == 0 {
continue;
}
match section.as_ref() {
"HitObjects" => {
hit_object_lines.push(line);
}
"TimingPoints" => {
timing_point_lines.push(line);
}
"Version" => {
if let Some(capture) = OSU_FORMAT_VERSION_RGX.captures(line)
{
beatmap.version = capture["version"].parse::<u32>()?;
}
}
_ => {
if let Some(captures) = KEY_VALUE_RGX.captures(line) {
match &captures["key"] {
"AudioFilename" => {
kvalue!(captures[beatmap.audio_filename]: str)
}
"AudioLeadIn" => kvalue!(
captures[beatmap.audio_leadin]: parse(u32)
),
"PreviewTime" => kvalue!(
captures[beatmap.preview_time]: parse(u32)
),
"Countdown" => kvalue!(
captures[beatmap.countdown]: parse(bool)
),
"SampleSet" => {
beatmap.sample_set = {
let sample_set = kvalue!(captures[beatmap.sample_set] => str);
match sample_set.as_ref() {
"None" => SampleSet::None,
"Normal" => SampleSet::Normal,
"Soft" => SampleSet::Soft,
"Drum" => SampleSet::Drum,
_ => bail!(
"Invalid sample set '{}'.",
sample_set
),
}
}
}
"StackLeniency" => kvalue!(
captures[beatmap.stack_leniency]: parse(f64)
),
"Mode" => {
beatmap.mode = {
let mode = kvalue!(captures[beatmap.mode]=> parse(u8));
match mode {
0 => Mode::Osu,
1 => Mode::Taiko,
2 => Mode::Catch,
3 => Mode::Mania,
_ => {
bail!("Invalid game mode: {}", mode)
}
}
}
}
"LetterBoxInBreaks" => kvalue!(
captures[beatmap.letterbox_in_breaks]:
parse(bool)
),
"WidescreenStoryboard" => kvalue!(
captures[beatmap.widescreen_storyboard]:
parse(bool)
),
"Bookmarks" => {
beatmap.bookmarks = captures["value"]
.split(",")
.map(|n| n.parse::<i32>().unwrap())
.collect()
}
"DistanceSpacing" => kvalue!(
captures[beatmap.distance_spacing]: parse(f64)
),
"BeatDivisor" => kvalue!(
captures[beatmap.beat_divisor]: parse(u8)
),
"GridSize" => {
kvalue!(captures[beatmap.grid_size]: parse(u8))
}
"TimelineZoom" => kvalue!(
captures[beatmap.timeline_zoom]: parse(f64)
),
"Title" => kvalue!(captures[beatmap.title]: str),
"TitleUnicode" => {
kvalue!(captures[beatmap.title_unicode]: str)
}
"Artist" => kvalue!(captures[beatmap.artist]: str),
"ArtistUnicode" => {
kvalue!(captures[beatmap.artist_unicode]: str)
}
"Creator" => {
kvalue!(captures[beatmap.creator]: str)
}
"Version" => {
kvalue!(captures[beatmap.difficulty_name]: str)
}
"Source" => kvalue!(captures[beatmap.source]: str),
"Tags" => {
beatmap.tags = captures["value"]
.split(" ")
.map(|s| s.to_owned())
.collect()
}
"BeatmapID" => kvalue!(
captures[beatmap.beatmap_id]: parse(i32)
),
"BeatmapSetID" => kvalue!(
captures[beatmap.beatmap_set_id]: parse(i32)
),
"HPDrainRate" => kvalue!(
captures[beatmap.difficulty.hp_drain_rate]:
parse(f32)
),
"CircleSize" => kvalue!(
captures[beatmap.difficulty.circle_size]:
parse(f32)
),
"OverallDifficulty" => kvalue!(
captures[beatmap.difficulty.overall_difficulty]:
parse(f32)
),
"ApproachRate" => kvalue!(
captures[beatmap.difficulty.approach_rate]:
parse(f32)
),
"SliderMultiplier" => kvalue!(
captures[beatmap.difficulty.slider_multiplier]:
parse(f32)
),
_ => (),
}
}
}
}
}
if beatmap.version == 0 {
bail!(
"Could not find osu! file format version line. Check your beatmap and try again."
);
}
eprintln!("len: {}", timing_point_lines.len());
// parse timing points
// let mut prev = None;
for line in timing_point_lines {
let tp = TimingPoint::from_osz(line)?;
timing_points.push(tp);
}
beatmap.timing_points = TimingPointList::from(timing_points);
// set their parents now
// if let Some(mut prev) = timing_points.first().cloned() {
// for mut tp in timing_points.into_iter() {
// use TimingPointKind::*;
// match tp.kind {
// Inherited { .. } => tp.set_parent(&prev),
// Uninherited { .. } => prev = tp.clone(),
// };
// beatmap.timing_points.push(tp);
// }
// }
let mut hit_objects = Vec::new();
for line in hit_object_lines {
let obj = HitObject::from_osz(line, &beatmap)?;
hit_objects.push(obj);
}
beatmap.hit_objects = HitObjectList::from(hit_objects);
// beatmap.associate_hitobjects();
Ok(beatmap)
}
/// Serializes this Beatmap into the *.osz format.
pub fn as_osz(&self) -> Result<String, Error> {
let mut lines = vec![];
// version
// TODO: should probably use a fixed version
lines.push(format!("osu file format v{}", self.version));
lines.push("".to_string()); // new line
// general
lines.push("[General]".to_string());
lines.push(format!("AudioFilename: {}", self.audio_filename));
lines.push(format!("AudioLeadIn: {}", self.audio_leadin));
lines.push(format!("PreviewTime: {}", self.preview_time));
lines
.push(format!("Countdown: {}", if self.countdown { 1 } else { 0 }));
lines.push(format!(
"SampleSet: {}",
match &self.sample_set {
&SampleSet::None => "None",
&SampleSet::Normal => "Normal",
&SampleSet::Soft => "Soft",
&SampleSet::Drum => "Drum",
}
));
lines.push(format!("StackLeniency: {}", self.stack_leniency));
lines.push(format!("Mode: {}", self.mode as u32));
lines.push(format!(
"LetterboxInBreaks: {}",
if self.letterbox_in_breaks { 1 } else { 0 }
));
lines.push(format!(
"WidescreenStoryboard: {}",
if self.widescreen_storyboard { 1 } else { 0 }
));
lines.push("".to_string());
// editor
lines.push("[Editor]".to_string());
lines.push(format!(
"Bookmarks: {}",
self.bookmarks
.iter()
.map(|n| n.to_string())
.collect::<Vec<_>>()
.join(",")
));
lines.push(format!("DistanceSpacing: {}", self.distance_spacing));
lines.push(format!("BeatDivisor: {}", self.beat_divisor));
lines.push(format!("GridSize: {}", self.grid_size));
lines.push(format!("TimelineZoom: {}", self.timeline_zoom));
lines.push("".to_string());
// metadata
lines.push("[Metadata]".to_string());
lines.push(format!("Title:{}", self.title));
lines.push(format!("TitleUnicode:{}", self.title_unicode));
lines.push(format!("Artist:{}", self.artist));
lines.push(format!("ArtistUnicode:{}", self.artist_unicode));
lines.push(format!("Creator:{}", self.creator));
lines.push(format!("Version:{}", self.difficulty_name));
lines.push(format!("Source:{}", self.source));
lines.push(format!("Tags:{}", self.tags.join(" ")));
lines.push(format!("BeatmapID:{}", self.beatmap_id));
lines.push(format!("BeatmapSetID:{}", self.beatmap_set_id));
lines.push("".to_string());
// difficulty
lines.push("[Difficulty]".to_string());
lines.push(format!("HPDrainRate:{}", self.difficulty.hp_drain_rate));
lines.push(format!("CircleSize:{}", self.difficulty.circle_size));
lines.push(format!(
"OverallDifficulty:{}",
self.difficulty.overall_difficulty
));
lines.push(format!("ApproachRate:{}", self.difficulty.approach_rate));
// events
lines.push("[Events]".to_string());
lines.push("".to_string());
// timing points
lines.push("[TimingPoints]".to_string());
for timing_point in self.timing_points.iter() {
lines.push(timing_point.as_osz()?);
}
lines.push("".to_string());
// colors
lines.push("[Colours]".to_string());
lines.push("".to_string());
// hit objects
lines.push("[HitObjects]".to_string());
for hit_object in self.hit_objects.iter() {
lines.push(hit_object.as_osz()?);
}
lines.push("".to_string());
Ok(lines.join("\n"))
}
}

View File

@ -0,0 +1,2 @@
#[derive(Debug, Error)]
pub enum Error {}

View File

@ -0,0 +1,187 @@
use failure::Error;
use crate::{
Additions, Beatmap, HitObject, HitObjectKind, Hitsound, Point, SampleSet,
SliderSplineKind, Timestamp,
};
impl HitObject {
/// Creates a HitObject from the *.osz format
pub fn from_osz(
input: impl AsRef<str>,
beatmap: &Beatmap,
) -> Result<HitObject, Error> {
let parts = input.as_ref().split(",").collect::<Vec<_>>();
let x = parts[0].parse::<i32>()?;
let y = parts[1].parse::<i32>()?;
let timestamp = parts[2].parse::<i32>()?;
let obj_type = parts[3].parse::<i32>()?;
let addition = parts[4].parse::<u32>()?;
let start_time = Timestamp::from_millis(timestamp);
let extras;
// color is the top 3 bits of the "type" string, since there's a
// possible of 8 different combo colors max
let skip_color = (obj_type >> 4) & 0b111;
let new_combo = (obj_type & 4) == 4;
let kind = if (obj_type & 1) == 1 {
extras = parts[5];
HitObjectKind::Circle
} else if (obj_type & 2) == 2 {
let mut ctl_parts = parts[5].split("|").collect::<Vec<_>>();
let repeats = parts[6].parse::<u32>()?;
let slider_type = ctl_parts.remove(0);
extras = if parts.len() < 11 {
"0:0:0:0:"
} else {
parts[10]
};
// slider duration = pixelLength / (100.0 * SliderMultiplier) *
// BeatDuration from the osu wiki
let pixel_length = parts[7].parse::<f64>()?;
let timing_point = beatmap.locate_timing_point(start_time).unwrap();
let beat_duration = beatmap.get_beat_duration(&timing_point);
let duration = (pixel_length as f64 * beat_duration
/ (100.0 * beatmap.difficulty.slider_multiplier as f64))
as u32;
HitObjectKind::Slider {
kind: match slider_type {
"L" => SliderSplineKind::Linear,
"B" => SliderSplineKind::Bezier,
"C" => SliderSplineKind::Catmull,
"P" => SliderSplineKind::Perfect,
_ => bail!("Invalid slider type."),
},
control: ctl_parts
.into_iter()
.map(|s| {
let p = s.split(":").collect::<Vec<_>>();
Point(
p[0].parse::<i32>().unwrap(),
p[1].parse::<i32>().unwrap(),
)
})
.collect(),
repeats,
pixel_length,
duration,
}
} else if (obj_type & 8) == 8 {
let end_time = parts[5].parse::<i32>()?;
extras = parts[6];
HitObjectKind::Spinner {
end_time: Timestamp::from_millis(end_time),
}
} else {
bail!("Invalid object type.")
};
let extra_parts = extras.split(":").collect::<Vec<_>>();
let sample_set = extra_parts[0].parse::<i32>()?;
let addition_set = extra_parts[1].parse::<i32>()?;
let custom_index = extra_parts[2].parse::<i32>()?;
let sample_volume = extra_parts[3].parse::<i32>()?;
let filename = extra_parts[4].to_owned();
// TODO: handle extras field
let hitsound = Hitsound {
additions: Additions(addition),
sample: SampleSet::Normal, // TODO
time: match &kind {
&HitObjectKind::Spinner { ref end_time } => end_time.clone(),
_ => start_time.clone(),
},
sample_set,
addition_set,
custom_index,
sample_volume,
filename,
};
let hit_obj = HitObject {
kind,
pos: Point(x, y),
new_combo,
hitsound,
timing_point: None,
skip_color,
start_time,
};
Ok(hit_obj)
}
/// Serializes this HitObject into the *.osz format.
pub fn as_osz(&self) -> Result<String, Error> {
let obj_type = match &self.kind {
&HitObjectKind::Circle => 1,
&HitObjectKind::Slider { .. } => 2,
&HitObjectKind::Spinner { .. } => 8,
} | if self.new_combo { 4 } else { 0 }
| self.skip_color;
let hitsound = self.hitsound.additions.0;
let extras = format!(
"{}:{}:{}:{}:{}",
self.hitsound.sample_set,
self.hitsound.addition_set,
self.hitsound.custom_index,
self.hitsound.sample_volume,
self.hitsound.filename
);
let type_specific = match &self.kind {
&HitObjectKind::Slider {
ref kind,
ref repeats,
ref control,
ref pixel_length,
..
} => {
let edge_hitsounds = "0";
let edge_additions = "0:0";
format!(
"{}|{},{},{},{},{},",
match kind {
&SliderSplineKind::Linear => "L",
&SliderSplineKind::Bezier => "B",
&SliderSplineKind::Catmull => "C",
&SliderSplineKind::Perfect => "P",
},
control
.iter()
.map(|point| format!("{}:{}", point.0, point.1))
.collect::<Vec<_>>()
.join("|"),
repeats,
pixel_length,
edge_hitsounds,
edge_additions,
)
}
&HitObjectKind::Spinner { ref end_time } => {
format!("{},", end_time.value())
}
_ => String::new(),
};
let line = format!(
"{},{},{},{},{},{}{}",
self.pos.0,
self.pos.1,
self.start_time.value(),
obj_type,
hitsound,
type_specific,
extras
);
Ok(line)
}
}

View File

@ -0,0 +1,8 @@
mod beatmap;
mod errors;
mod hitobject;
mod timing;
pub use self::beatmap::*;
pub use self::hitobject::*;
pub use self::timing::*;

View File

@ -0,0 +1,67 @@
use failure::Error;
use crate::{SampleSet, Timestamp, TimingPoint, TimingPointKind};
impl TimingPoint {
/// Creates a TimingPoint from the *.osz format
pub fn from_osz(input: impl AsRef<str>) -> Result<TimingPoint, Error> {
let parts = input.as_ref().split(",").collect::<Vec<_>>();
let timestamp = parts[0].parse::<i32>()?;
let mpb = parts[1].parse::<f64>()?;
let meter = parts[2].parse::<u32>()?;
let sample_set = parts[3].parse::<i32>()?;
let sample_index = parts[4].parse::<u32>()?;
let volume = parts[5].parse::<u16>()?;
let inherited = parts[6].parse::<i32>()? == 0;
let kiai = parts[7].parse::<i32>()? > 0;
// calculate bpm from mpb
let bpm = 60_000.0 / mpb;
let time = Timestamp::from_millis(timestamp);
let timing_point = TimingPoint {
kind: if inherited {
TimingPointKind::Inherited {
slider_velocity: 0.0, // TODO: calculate this from mpb
}
} else {
TimingPointKind::Uninherited { bpm, meter }
},
kiai,
sample_set: match sample_set {
0 => SampleSet::None,
1 => SampleSet::Normal,
2 => SampleSet::Soft,
3 => SampleSet::Drum,
_ => panic!("Invalid sample set '{}'.", sample_set),
},
mpb,
sample_index,
volume,
time,
};
Ok(timing_point)
}
/// Serializes this TimingPoint into the *.osz format.
pub fn as_osz(&self) -> Result<String, Error> {
let inherited = match &self.kind {
&TimingPointKind::Inherited { .. } => 0,
&TimingPointKind::Uninherited { .. } => 1,
};
let line = format!(
"{},{},{},{},{},{},{},{}",
self.time.value(),
self.mpb,
12345, // TODO: meter
self.sample_set.clone() as i32,
self.sample_index,
self.volume,
inherited,
if self.kiai { 1 } else { 0 },
);
Ok(line)
}
}

View File

@ -0,0 +1,40 @@
use std::fmt::{self, Display};
use std::ops::{Add, Mul, Sub};
/// Represents a 2D point (or any pair of objects).
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct Point<T>(pub T, pub T);
impl<T: Display> fmt::Display for Point<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.0, self.1)
}
}
impl<T: Add<Output = T>> Add for Point<T> {
type Output = Point<T>;
fn add(self, other: Point<T>) -> Self::Output {
Point(self.0 + other.0, self.1 + other.1)
}
}
impl<T: Sub<Output = T>> Sub for Point<T> {
type Output = Point<T>;
fn sub(self, other: Point<T>) -> Self::Output {
Point(self.0 - other.0, self.1 - other.1)
}
}
impl<T: Mul<Output = T>> Mul<Point<T>> for Point<T> {
type Output = Point<T>;
fn mul(self, other: Point<T>) -> Self::Output {
Point(self.0 * other.0, self.1 * other.1)
}
}
impl<T: Clone + Mul<Output = T>> Mul<T> for Point<T> {
type Output = Point<T>;
fn mul(self, other: T) -> Self::Output {
Point(self.0 * other.clone(), self.1 * other)
}
}

View File

@ -0,0 +1,2 @@
/// A replay object.
pub struct Replay {}

View File

@ -0,0 +1,151 @@
use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::ops::{Add, Div, Mul, Sub};
use serde::ser::*;
use crate::SampleSet;
/// A struct representing a location in time in SECONDS.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Timestamp(f64);
impl Display for Timestamp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let ms = (self.0 * 1000.0).abs() as u64 % 1000;
let s = self.0.abs() as u64 % 60;
let m = self.0.abs() as u64 / 60;
write!(f, "{}:{:02}:{:03}", m, s, ms)
}
}
impl Timestamp {
/// Create a new Timestamp
pub fn new(value: f64) -> Self {
if value == std::f64::NAN {
panic!("cannot create NaN timestamp");
}
Timestamp(value)
}
/// Create a new Timestamp from milliseconds
pub fn from_millis(value: i32) -> Self {
Self::new(value as f64 / 1000.0)
}
/// Gets the numerical value of the timestamp.
pub fn value(&self) -> f64 {
self.0
}
}
impl Eq for Timestamp {}
impl Ord for Timestamp {
fn cmp(&self, other: &Self) -> Ordering {
self.0.partial_cmp(&other.0).unwrap()
}
}
impl Sub<Timestamp> for Timestamp {
type Output = f64;
fn sub(self, rhs: Timestamp) -> Self::Output {
self.0 - rhs.0
}
}
impl Add<f64> for Timestamp {
type Output = Timestamp;
fn add(self, rhs: f64) -> Self::Output {
Timestamp(self.0 + rhs)
}
}
impl Sub<f64> for Timestamp {
type Output = Timestamp;
fn sub(self, rhs: f64) -> Self::Output {
Timestamp(self.0 - rhs)
}
}
impl Mul<f64> for Timestamp {
type Output = Timestamp;
fn mul(self, rhs: f64) -> Self::Output {
Timestamp(self.0 * rhs)
}
}
impl Div<f64> for Timestamp {
type Output = Timestamp;
fn div(self, rhs: f64) -> Self::Output {
Timestamp(self.0 / rhs)
}
}
/// An enum distinguishing between inherited and uninherited timing points.
#[derive(Clone, Debug)]
pub enum TimingPointKind {
/// Uninherited timing point
Uninherited {
/// BPM (beats per minute) of this timing section
bpm: f64,
/// The number of beats in a single measure
meter: u32,
},
/// Inherited timing point
Inherited {
/// Slider velocity multiplier
slider_velocity: f64,
},
}
/// A timing point, which represents configuration settings for a timing
/// section.
///
/// This is a generic timing point struct representing both inherited and
/// uninherited timing points, distinguished by the `kind` field.
#[derive(Clone, Debug)]
pub struct TimingPoint {
/// The timestamp of this timing point, represented as a `TimeLocation`.
pub time: Timestamp,
/// Whether or not Kiai time should be on for this timing point.
pub kiai: bool,
/// The sample set associated with this timing section.
pub sample_set: SampleSet,
/// Index (if using a custom sample)
pub sample_index: u32,
/// Volume of this timing section.
pub volume: u16,
/// Milliseconds per beat
pub mpb: f64,
/// The type of this timing point. See `TimingPointKind`.
pub kind: TimingPointKind,
}
impl TimingPoint {
/// Whether or not this timing point is inherited (green line)
pub fn is_inherited(&self) -> bool {
match self.kind {
TimingPointKind::Inherited { .. } => true,
TimingPointKind::Uninherited { .. } => false,
}
}
}
impl Serialize for TimingPoint {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let state = serializer.serialize_struct("TimingPoint", 0)?;
state.end()
}
}

1
editor-old/osu/tests/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
out

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,899 @@
osu file format v14
[General]
AudioFilename: cYsmix - Manic 224.mp3
AudioLeadIn: 0
PreviewTime: 52858
Countdown: 0
SampleSet: None
StackLeniency: 0.4
Mode: 0
LetterboxInBreaks: 0
WidescreenStoryboard: 0
[Editor]
Bookmarks: 14458,27258,40058,91258,104058,116858,129658,168058
DistanceSpacing: 1
BeatDivisor: 2
GridSize: 8
TimelineZoom: 2.9
[Metadata]
Title:Manic
TitleUnicode:Manic
Artist:cYsmix
ArtistUnicode:cYsmix
Creator:Bonsai
Version:Extra
Source:osu!
Tags:Mapping With Rewards
BeatmapID:804683
BeatmapSetID:361214
[Difficulty]
HPDrainRate:7
CircleSize:4.5
OverallDifficulty:8.5
ApproachRate:9
SliderMultiplier:1.6
SliderTickRate:1
[Events]
//Background and Video events
0,0,"osu!cysmix-bgtiny.jpg",0,0
//Break Periods
2,78658,87458
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Sound Samples
[TimingPoints]
1658,400,4,3,0,55,1,0
13058,-100,4,3,0,45,0,0
13258,-100,4,3,0,35,0,0
13458,-100,4,3,0,25,0,0
13558,-100,4,3,0,20,0,0
14058,-100,4,3,0,55,0,0
14458,-100,4,2,1,45,0,0
20858,-100,4,2,0,60,0,0
27258,-100,4,3,0,65,0,0
40058,-125,4,3,0,55,0,0
41658,-117.647058823529,4,3,0,55,0,0
43258,-111.111111111111,4,3,0,55,0,0
44858,-105.263157894737,4,3,0,55,0,0
46458,-100,4,2,0,55,0,0
48058,-90.9090909090909,4,2,0,55,0,0
49658,-83.3333333333333,4,2,0,60,0,0
50058,-76.9230769230769,4,2,0,60,0,0
51258,-71.4285714285714,4,2,0,65,0,0
51658,-66.6666666666667,4,2,0,65,0,0
52058,-62.5,4,2,0,65,0,0
52858,-74.0740740740741,4,3,0,65,0,1
53908,-74.0740740740741,4,3,0,5,0,1
54058,-74.0740740740741,4,3,0,65,0,1
55558,-74.0740740740741,4,3,0,5,0,1
55658,-74.0740740740741,4,3,0,65,0,1
55958,-74.0740740740741,4,3,0,5,0,1
56058,-74.0740740740741,4,3,0,65,0,1
58858,-66.6666666666667,4,3,0,65,0,1
59158,-74.0740740740741,4,3,0,5,0,1
59258,-74.0740740740741,4,3,0,65,0,1
60308,-74.0740740740741,4,3,0,5,0,1
60458,-74.0740740740741,4,3,0,65,0,1
61958,-74.0740740740741,4,3,0,5,0,1
62058,-74.0740740740741,4,3,0,65,0,1
62358,-74.0740740740741,4,3,0,5,0,1
62458,-74.0740740740741,4,3,0,65,0,1
64458,-74.0740740740741,4,3,0,65,0,0
64558,-74.0740740740741,4,3,0,5,0,0
64658,-74.0740740740741,4,3,0,20,0,0
65058,-74.0740740740741,4,3,0,50,0,0
65658,-74.0740740740741,4,3,0,65,0,1
68358,-74.0740740740741,4,3,0,5,0,1
68458,-74.0740740740741,4,3,0,65,0,1
68758,-74.0740740740741,4,3,0,5,0,1
68858,-74.0740740740741,4,3,0,65,0,1
71758,-74.0740740740741,4,3,0,5,0,1
72058,-74.0740740740741,4,3,0,65,0,1
77258,-74.0740740740741,4,3,0,55,0,0
88058,-100,4,3,0,55,0,0
89858,-100,4,3,0,40,0,0
89958,-100,4,3,0,30,0,0
90058,-100,4,3,0,15,0,0
90158,-100,4,3,0,10,0,0
90858,-100,4,3,0,15,0,0
90958,-100,4,3,0,30,0,0
91058,-100,4,3,0,40,0,0
91158,-100,4,3,0,55,0,0
103758,-100,4,3,0,5,0,0
103858,-100,4,3,0,55,0,0
103958,-100,4,3,0,5,0,0
104058,-100,4,3,0,65,0,0
107158,-100,4,3,0,5,0,0
107258,-100,4,3,0,65,0,0
116858,-125,4,3,0,55,0,0
118458,-117.647058823529,4,3,0,55,0,0
120058,-111.111111111111,4,3,0,55,0,0
121658,-105.263157894737,4,3,0,55,0,0
123258,-100,4,2,0,55,0,0
124858,-90.9090909090909,4,2,0,55,0,0
126458,-83.3333333333333,4,2,0,60,0,0
126858,-76.9230769230769,4,2,0,60,0,0
128058,-71.4285714285714,4,2,0,65,0,0
128458,-66.6666666666667,4,2,0,65,0,0
128858,-62.5,4,2,0,65,0,0
129658,-100,4,2,0,45,0,0
132608,-100,4,2,0,5,0,0
132658,-83.3333333333333,4,2,0,45,0,0
132808,-83.3333333333333,4,2,0,5,0,0
132858,-74.0740740740741,4,3,0,65,0,1
134158,-74.0740740740741,4,3,0,5,0,1
134258,-74.0740740740741,4,3,0,65,0,1
134358,-74.0740740740741,4,3,0,5,0,1
134458,-74.0740740740741,4,3,0,65,0,1
135658,-66.6666666666667,4,3,0,65,0,1
135958,-74.0740740740741,4,3,0,5,0,1
136058,-74.0740740740741,4,3,0,65,0,1
137108,-74.0740740740741,4,3,0,5,0,1
137258,-74.0740740740741,4,3,0,65,0,1
138758,-74.0740740740741,4,3,0,5,0,1
138858,-74.0740740740741,4,3,0,65,0,1
139158,-74.0740740740741,4,3,0,5,0,1
139258,-74.0740740740741,4,3,0,65,0,1
141258,-74.0740740740741,4,3,0,65,0,0
141358,-74.0740740740741,4,3,0,5,0,0
141458,-74.0740740740741,4,3,0,20,0,0
141858,-74.0740740740741,4,3,0,50,0,0
142458,-74.0740740740741,4,3,0,65,0,1
145158,-74.0740740740741,4,3,0,5,0,1
145258,-74.0740740740741,4,3,0,65,0,1
145558,-74.0740740740741,4,3,0,5,0,1
145658,-74.0740740740741,4,3,0,65,0,1
148558,-74.0740740740741,4,3,0,5,0,1
148858,-74.0740740740741,4,3,0,65,0,1
149908,-74.0740740740741,4,3,0,5,0,1
150058,-74.0740740740741,4,3,0,65,0,1
154058,-74.0740740740741,4,3,0,65,0,0
154658,-74.0740740740741,4,3,0,50,0,0
155258,-74.0740740740741,4,3,0,65,0,1
157958,-74.0740740740741,4,3,0,5,0,1
158058,-74.0740740740741,4,3,0,65,0,1
158358,-74.0740740740741,4,3,0,5,0,1
158458,-74.0740740740741,4,3,0,65,0,1
161658,-100,4,3,0,55,0,0
[Colours]
Combo1 : 221,221,221
Combo2 : 242,236,0
Combo3 : 254,103,183
Combo4 : 0,86,191
[HitObjects]
396,264,1258,5,0,0:0:0:0:
189,160,1658,5,2,0:0:0:0:
238,286,1858,2,0,P|245:332|239:401,1,80,2|0,0:0|0:0,0:0:0:0:
199,155,2258,1,2,0:0:0:0:
225,288,2458,2,0,P|223:335|206:402,1,80,2|0,0:0|0:0,0:0:0:0:
209,154,2858,1,2,0:0:0:0:
215,291,3058,2,0,P|205:336|176:398,1,80,2|0,0:0|0:0,0:0:0:0:
222,154,3458,1,2,0:0:0:0:
202,289,3658,2,0,P|184:332|144:390,1,80,2|0,0:0|0:0,0:0:0:0:
233,156,4058,5,2,0:0:0:0:
190,288,4258,2,0,P|166:327|116:378,1,80,2|0,0:0|0:0,0:0:0:0:
245,162,4658,1,2,0:0:0:0:
178,283,4858,2,0,P|146:320|90:358,1,80,2|0,0:0|0:0,0:0:0:0:
255,169,5258,1,2,0:0:0:0:
169,276,5458,2,0,P|131:305|69:335,1,80,2|0,0:0|0:0,0:0:0:0:
263,178,5858,1,2,0:0:0:0:
160,267,6058,2,0,P|118:289|51:309,1,80,2|0,0:0|0:0,0:0:0:0:
269,186,6458,5,2,0:0:0:0:
153,259,6658,2,0,P|106:274|37:281,1,80,2|0,0:0|0:0,0:0:0:0:
275,196,7058,1,2,0:0:0:0:
149,248,7258,2,0,P|99:254|32:249,1,80,2|0,0:0|0:0,0:0:0:0:
279,209,7658,1,2,0:0:0:0:
139,197,7858,1,2,0:0:0:0:
0,180,8058,5,4,0:0:0:0:
18,154,8458,1,4,0:0:0:0:
37,128,8858,2,0,P|73:116|126:42,1,120,4|8,0:0|0:2,0:0:0:0:
133,15,9258,1,4,0:0:0:0:
22,33,9458,1,8,0:2:0:0:
178,145,9658,5,4,0:0:0:0:
184,176,10058,1,4,0:0:0:0:
190,207,10458,2,0,P|162:259|167:318,1,120,4|8,0:0|0:2,0:0:0:0:
190,351,10858,1,4,0:0:0:0:
71,290,11058,1,8,0:2:0:0:
261,279,11258,5,4,0:0:0:0:
276,275,11358,1,0,0:0:0:0:
291,270,11458,1,0,0:0:0:0:
306,264,11558,1,0,0:0:0:0:
320,256,11658,1,4,0:0:0:0:
333,247,11758,1,0,0:0:0:0:
346,237,11858,1,0,0:0:0:0:
357,226,11958,1,0,0:0:0:0:
367,213,12058,1,4,0:0:0:0:
376,200,12158,1,0,0:0:0:0:
384,186,12258,1,0,0:0:0:0:
390,171,12358,1,0,0:0:0:0:
395,156,12458,1,4,0:0:0:0:
398,141,12558,1,0,0:0:0:0:
400,125,12658,1,0,0:0:0:0:
401,109,12758,1,0,0:0:0:0:
401,93,12858,6,0,L|397:55,16,20,4|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0,0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0:
128,184,14058,5,12,0:0:0:0:
291,24,14458,5,2,0:0:0:0:
277,56,14558,1,0,0:0:0:0:
280,92,14658,1,0,0:0:0:0:
301,122,14758,1,0,0:0:0:0:
333,139,14858,1,0,0:0:0:0:
369,139,14958,1,0,0:0:0:0:
402,124,15058,1,0,0:0:0:0:
422,94,15158,1,0,0:0:0:0:
351,70,15258,5,2,0:0:0:0:
335,102,15358,1,0,0:0:0:0:
317,133,15458,1,0,0:0:0:0:
298,164,15558,1,0,0:0:0:0:
262,169,15658,1,0,0:0:0:0:
226,174,15758,1,0,0:0:0:0:
190,177,15858,1,0,0:0:0:0:
154,179,15958,1,0,0:0:0:0:
112,110,16058,5,2,0:0:0:0:
146,98,16158,1,0,0:0:0:0:
181,105,16258,1,0,0:0:0:0:
211,127,16358,1,0,0:0:0:0:
225,160,16458,1,0,0:0:0:0:
221,195,16558,1,0,0:0:0:0:
206,227,16658,2,0,P|192:242|169:255,1,40,2|0,2:0|0:0,0:0:0:0:
249,301,16858,5,2,0:0:0:0:
284,302,16958,1,0,0:0:0:0:
319,303,17058,1,0,0:0:0:0:
354,301,17158,1,0,0:0:0:0:
384,230,17258,1,2,0:0:0:0:
380,186,17358,1,0,0:0:0:0:
372,142,17458,2,0,L|365:79,1,40
291,34,17658,5,2,0:0:0:0:
287,61,17758,1,0,0:0:0:0:
285,88,17858,1,0,0:0:0:0:
281,115,17958,1,0,0:0:0:0:
278,142,18058,2,0,L|271:199,1,40
185,119,18258,1,2,0:0:0:0:
181,146,18358,1,0,0:0:0:0:
177,173,18458,1,0,0:0:0:0:
174,200,18558,1,0,0:0:0:0:
171,227,18658,2,0,L|164:284,1,40
79,204,18858,5,2,0:0:0:0:
75,231,18958,1,0,0:0:0:0:
71,258,19058,1,0,0:0:0:0:
68,285,19158,1,0,0:0:0:0:
65,312,19258,2,0,L|78:361,1,40
181,360,19458,1,2,0:0:0:0:
185,333,19558,1,0,0:0:0:0:
189,306,19658,1,0,0:0:0:0:
194,278,19758,1,0,0:0:0:0:
200,250,19858,2,0,L|238:199,1,40
324,222,20058,5,2,0:0:0:0:
320,249,20158,1,0,0:0:0:0:
316,276,20258,1,0,0:0:0:0:
312,303,20358,1,0,0:0:0:0:
310,331,20458,2,0,L|323:380,1,40
410,382,20658,1,2,0:0:0:0:
438,382,20758,1,0,0:0:0:0:
471,318,20858,6,0,B|473:297|473:297|469:273,1,40,2|0,0:3|0:3,0:3:0:0:
364,205,21058,2,0,B|361:185|361:185|363:165,1,40,2|0,0:3|0:3,0:3:0:0:
459,94,21258,1,0,0:3:0:0:
442,71,21358,1,0,0:3:0:0:
418,55,21458,1,0,0:3:0:0:
390,51,21558,1,0,0:3:0:0:
326,84,21658,6,0,B|308:89|308:89|287:91,1,40,2|0,0:3|0:3,0:3:0:0:
178,30,21858,2,0,B|156:31|156:31|139:37,1,40,2|0,0:3|0:3,0:3:0:0:
72,131,22058,1,0,0:3:0:0:
76,158,22158,1,0,0:3:0:0:
80,185,22258,1,0,0:3:0:0:
84,212,22358,1,0,0:3:0:0:
119,274,22458,6,0,B|136:279|136:279|157:281,1,40,2|0,0:3|0:3,0:3:0:0:
269,221,22658,2,0,B|290:222|290:222|307:228,1,40,2|0,0:3|0:3,0:3:0:0:
345,346,22858,1,0,0:3:0:0:
326,367,22958,1,0,0:3:0:0:
298,371,23058,1,0,0:3:0:0:
272,360,23158,1,0,0:3:0:0:
229,301,23258,6,0,B|223:283|223:283|221:262,1,40,2|0,0:3|0:3,0:3:0:0:
286,149,23458,2,0,B|284:127|284:127|278:110,1,40,2|0,0:3|0:3,0:3:0:0:
158,74,23658,2,0,B|136:75|119:81,3,40,2|0|0|0,0:3|0:3|0:3|0:3,0:3:0:0:
70,171,24058,6,0,L|78:224,1,40,2|0,0:3|0:3,0:3:0:0:
184,285,24258,2,0,L|179:246,1,40,2|0,0:3|0:3,0:3:0:0:
278,158,24458,1,0,0:3:0:0:
282,185,24558,1,0,0:3:0:0:
289,224,24658,6,0,L|297:277,1,40,2|0,0:3|0:3,0:3:0:0:
412,325,24858,2,0,L|406:285,1,40,2|0,0:3|0:3,0:3:0:0:
496,199,25058,1,0,0:3:0:0:
492,171,25158,1,0,0:3:0:0:
485,132,25258,6,0,L|479:92,1,40,2|0,0:3|0:3,0:3:0:0:
355,34,25458,2,0,L|363:87,1,40,2|0,0:3|0:3,0:3:0:0:
278,158,25658,1,0,0:3:0:0:
282,185,25758,1,0,0:3:0:0:
289,224,25858,6,0,L|295:264,1,40,2|0,0:3|0:3,0:3:0:0:
194,352,26058,2,0,L|186:299,1,40,2|0,0:3|0:3,0:3:0:0:
73,251,26258,1,0,0:3:0:0:
67,224,26358,1,0,0:3:0:0:
59,185,26458,6,0,L|51:132,1,40,2|0,0:3|0:3,0:3:0:0:
148,45,26658,2,0,L|154:85,1,40,2|0,0:3|0:3,0:3:0:0:
237,161,26858,2,0,L|277:155,3,40,2|0|0|0,0:3|0:3|0:3|0:3,0:3:0:0:
319,219,27258,5,6,0:0:0:0:
96,187,27458,1,2,0:0:0:0:
253,76,27658,2,0,P|292:73|354:94,1,80,8|0,0:0|0:0,0:0:0:0:
387,138,27958,1,0,0:0:0:0:
384,177,28058,5,6,0:0:0:0:
486,13,28258,1,2,0:0:0:0:
470,213,28458,2,0,L|464:308,1,80,8|0,0:0|0:0,0:0:0:0:
403,340,28758,1,0,0:0:0:0:
399,379,28858,5,6,0:0:0:0:
306,158,29058,1,2,0:0:0:0:
177,325,29258,2,0,L|174:372,1,40,8|0,0:0|0:0,0:0:0:0:
120,203,29458,2,0,L|123:155,1,40
27,270,29658,5,6,0:0:0:0:
282,263,29858,1,2,0:0:0:0:
237,53,30058,2,0,P|299:33|367:50,1,120,8|0,0:0|0:0,0:0:0:0:
423,75,30458,5,6,0:0:0:0:
315,217,30658,1,2,0:0:0:0:
476,138,30858,1,0,0:0:0:0:
273,42,31058,5,6,0:0:0:0:
315,217,31258,1,2,0:0:0:0:
351,42,31458,1,0,0:0:0:0:
152,133,31658,5,6,0:0:0:0:
315,217,31858,1,0,0:0:0:0:
204,76,32058,1,2,0:0:0:0:
146,280,32258,5,6,0:0:0:0:
315,217,32458,1,0,0:0:0:0:
137,204,32658,1,2,0:0:0:0:
251,384,32858,5,6,0:0:0:0:
315,217,33058,1,2,0:0:0:0:
146,280,33258,2,0,P|84:288|19:243,1,120,10|0,0:0|0:0,0:0:0:0:
19,167,33658,5,6,0:0:0:0:
22,351,33858,1,2,0:0:0:0:
146,280,34058,2,0,B|157:271|157:271|150:198,1,80,8|0,0:0|0:0,0:0:0:0:
88,160,34358,1,0,0:0:0:0:
48,166,34458,5,6,0:0:0:0:
290,133,34658,1,2,0:0:0:0:
146,280,34858,2,0,P|150:335|178:376,1,80,8|0,0:0|0:0,0:0:0:0:
234,384,35158,1,0,0:0:0:0:
273,378,35258,5,6,0:0:0:0:
75,280,35458,1,2,0:0:0:0:
317,240,35658,1,8,0:0:0:0:
308,200,35758,1,0,0:0:0:0:
302,160,35858,2,0,L|289:88,1,40
385,48,36058,5,6,0:0:0:0:
160,83,36258,1,2,0:0:0:0:
373,150,36458,2,0,P|418:183|436:248,1,120,8|0,0:0|0:0,0:0:0:0:
413,316,36858,5,6,0:0:0:0:
296,153,37058,1,2,0:0:0:0:
493,187,37258,1,0,0:0:0:0:
338,349,37458,5,6,0:0:0:0:
296,153,37658,1,2,0:0:0:0:
465,258,37858,1,0,0:0:0:0:
260,350,38058,5,6,0:0:0:0:
296,153,38258,1,2,0:0:0:0:
413,316,38458,1,0,0:0:0:0:
189,322,38658,5,6,0:0:0:0:
296,153,38858,1,2,0:0:0:0:
338,349,39058,1,0,0:0:0:0:
130,265,39258,5,6,0:0:0:0:
296,153,39458,1,2,0:0:0:0:
115,61,39658,2,0,P|83:81|82:120,1,80,10|0,0:0|0:0,0:0:0:0:
357,29,40058,5,4,0:0:0:0:
371,97,40258,1,0,0:0:0:0:
384,166,40458,1,4,0:0:0:0:
384,166,40858,2,0,P|411:181|430:207,1,64,4|0,0:0|0:0,0:0:0:0:
448,274,41158,1,8,0:2:0:0:
448,274,41258,2,0,P|432:300|433:350,1,64,4|8,0:0|0:2,0:0:0:0:
326,375,41658,5,4,0:0:0:0:
251,372,41858,1,0,0:0:0:0:
188,330,42058,1,4,0:0:0:0:
188,330,42458,2,0,P|172:302|169:266,1,68.0000012969971,4|0,0:0|0:0,0:0:0:0:
182,192,42758,1,8,0:2:0:0:
182,192,42858,2,0,P|203:166|212:133,1,68.0000012969971,4|8,0:0|0:2,0:0:0:0:
199,23,43258,5,4,0:0:0:0:
124,49,43458,1,0,0:0:0:0:
89,120,43658,1,4,0:0:0:0:
89,120,44058,2,0,P|80:150|91:193,1,71.9999978027344,4|0,0:0|0:0,0:0:0:0:
117,262,44358,1,8,0:2:0:0:
117,262,44458,2,0,P|146:273|173:309,1,71.9999978027344,4|8,0:0|0:2,0:0:0:0:
297,354,44858,5,4,0:0:0:0:
310,271,45058,1,0,0:0:0:0:
321,188,45258,1,4,0:0:0:0:
321,188,45658,2,0,P|340:163|386:147,1,75.9999979705811,4|0,0:0|0:0,0:0:0:0:
450,180,45958,1,8,0:2:0:0:
450,180,46058,2,0,P|427:207|389:221,1,75.9999979705811,4|8,0:0|0:2,0:0:0:0:
231,162,46458,5,2,0:3:0:0:
119,189,46658,1,2,0:3:0:0:
57,92,46858,1,2,0:3:0:0:
129,4,47058,1,2,0:3:0:0:
236,45,47258,2,0,P|270:51|320:37,1,80,2|2,0:3|0:3,0:3:0:0:
387,8,47558,1,0,0:3:0:0:
387,8,47658,2,0,L|391:68,1,40,2|0,0:3|0:3,0:3:0:0:
443,107,47858,2,0,L|433:163,1,40,2|0,0:3|0:3,0:3:0:0:
474,223,48058,5,2,0:3:0:0:
341,238,48258,1,2,0:3:0:0:
308,376,48458,1,2,0:3:0:0:
441,364,48658,1,2,0:3:0:0:
341,238,48858,2,0,P|311:217|247:215,1,88.000002685547,2|2,0:3|0:3,0:3:0:0:
210,284,49158,1,0,0:3:0:0:
210,284,49258,2,0,L|188:331,1,44.0000013427735,2|0,0:3|0:3,0:3:0:0:
104,312,49458,2,0,L|39:336,1,44.0000013427735,2|0,0:3|0:0,0:3:0:0:
5,249,49658,6,0,P|34:217|72:205,1,71.9999978027344,2|0,0:3|0:3,0:3:0:0:
108,218,49858,2,0,P|143:221|177:210,1,71.9999978027344,2|0,0:3|0:3,0:3:0:0:
209,150,50058,2,0,L|229:68,1,77.9999964294435,2|0,0:3|0:3,0:3:0:0:
296,41,50258,2,0,P|328:40|376:52,1,77.9999964294435,2|0,0:3|0:3,0:3:0:0:
393,127,50458,2,0,P|395:165|407:202,1,77.9999964294435,2|0,0:3|0:3,0:3:0:0:
408,283,50658,6,0,P|380:304|343:317,1,51.999997619629,2|0,0:3|0:3,0:3:0:0:
261,287,50858,2,0,P|224:289|186:281,1,51.999997619629,2|0,0:3|0:3,0:3:0:0:
130,221,51058,2,0,P|98:203|70:175,1,51.999997619629,2|0,0:3|0:3,0:3:0:0:
76,64,51258,6,0,L|182:51,1,83.9999974365235,2|0,0:3|0:3,0:3:0:0:
233,21,51458,2,0,P|272:48|324:37,1,83.9999974365235,2|0,0:3|0:3,0:3:0:0:
353,119,51658,2,0,P|353:160|324:196,1,90.0000034332277,2|0,0:3|0:3,0:3:0:0:
243,235,51858,2,0,P|251:281|296:326,1,90.0000034332277,2|0,0:3|0:3,0:3:0:0:
379,377,52058,2,0,L|281:385,1,96,2|0,0:3|0:3,0:3:0:0:
184,311,52258,2,0,L|109:302,1,64,2|0,0:3|0:3,0:3:0:0:
0,210,52458,1,14,0:3:0:0:
496,144,52858,5,6,0:0:0:0:
256,56,53058,1,2,0:0:0:0:
256,232,53258,1,4,0:0:0:0:
16,232,53458,1,2,0:0:0:0:
256,144,53658,1,6,0:0:0:0:
256,320,53858,2,0,B|256:354,1,27.0000001029968
454,202,54058,5,6,0:0:0:0:
412,364,54258,1,2,0:0:0:0:
256,320,54458,1,4,0:0:0:0:
256,56,54658,1,2,0:0:0:0:
98,17,54858,1,6,0:0:0:0:
58,175,55058,1,0,0:0:0:0:
256,192,55258,6,0,P|327:174|384:110,1,162.000000617981,6|0,0:0|2:0,0:0:0:0:
256,192,55658,2,0,P|185:210|133:279,1,162.000000617981,6|0,0:0|2:0,0:0:0:0:
256,320,56058,5,6,0:0:0:0:
391,187,56258,2,0,B|418:156|458:145|458:145|436:132,1,108.000000411987,2|4,0:0|0:0,0:0:0:0:
114,179,56658,1,2,0:0:0:0:
254,53,56858,2,0,P|311:21|377:23,1,108.000000411987,6|0,0:0|0:0,0:0:0:0:
256,320,57258,5,6,0:0:0:0:
114,179,57458,2,0,L|34:106,1,108.000000411987,2|4,0:0|0:0,0:0:0:0:
391,187,57858,1,2,0:0:0:0:
254,53,58058,2,0,B|201:2|201:2|207:42,1,108.000000411987,6|0,0:0|0:0,0:0:0:0:
476,194,58458,5,6,0:0:0:0:
256,320,58658,1,2,0:0:0:0:
40,227,58858,2,0,B|44:189|44:189|69:194|69:194|83:177|83:177|106:189|106:189|123:171|123:171|162:206,1,180.000006866455,6|0,0:0|0:0,0:0:0:0:
123,296,59258,5,6,0:0:0:0:
170,71,59458,1,2,0:0:0:0:
256,320,59658,1,4,0:0:0:0:
431,117,59858,1,2,0:0:0:0:
384,342,60058,1,6,0:0:0:0:
298,93,60258,2,0,B|290:68,1,27.0000001029968
279,202,60458,5,6,0:0:0:0:
381,26,60658,1,2,0:0:0:0:
407,234,60858,1,4,0:0:0:0:
151,234,61058,1,2,0:0:0:0:
177,26,61258,1,6,0:0:0:0:
279,202,61458,1,0,0:0:0:0:
175,140,61658,6,0,P|96:152|47:220,1,162.000000617981,6|0,0:0|0:0,0:0:0:0:
119,327,62058,2,0,P|198:315|245:251,1,162.000000617981,6|0,0:0|0:0,0:0:0:0:
290,98,62458,5,6,0:0:0:0:
367,308,62658,2,0,B|396:375|396:375|407:332,1,108.000000411987,2|4,0:0|0:0,0:0:0:0:
414,134,63058,1,2,0:0:0:0:
238,269,63258,2,0,B|200:301|200:301|177:355,1,108.000000411987,6|0,0:0|0:0,0:0:0:0:
367,308,63658,5,6,0:0:0:0:
177,354,63858,2,0,B|131:347|131:347|134:355|134:355|82:345,1,108.000000411987,2|4,0:0|0:0,0:0:0:0:
90,132,64258,1,2,0:0:0:0:
238,269,64458,2,0,B|268:292|268:292|266:270,2,54.0000002059937,6|0|0,0:0|2:0|0:0,0:0:0:0:
359,24,65058,5,2,0:0:0:0:
373,152,65258,1,2,0:0:0:0:
386,280,65458,1,2,0:0:0:0:
171,243,65658,5,6,0:0:0:0:
239,44,65858,1,2,0:0:0:0:
316,212,66058,2,0,P|363:235|417:233,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
472,23,66458,1,4,0:0:0:0:
239,44,66658,1,2,0:0:0:0:
316,212,66858,1,14,0:0:0:0:
402,374,67058,1,2,0:0:0:0:
171,243,67258,6,0,B|134:202|144:138,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
457,186,67658,2,0,B|493:226|478:291,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
184,316,68058,2,0,B|112:327|112:327|116:307|116:307|26:320,1,162.000000617981,4|0,0:0|0:0,0:0:0:0:
171,243,68458,2,0,P|251:281|239:362,1,162.000000617981,14|0,0:0|0:0,0:0:0:0:
346,376,68858,5,6,0:0:0:0:
459,160,69058,1,2,0:0:0:0:
265,273,69258,1,14,0:0:0:0:
265,48,69458,1,2,0:0:0:0:
395,273,69658,1,6,0:0:0:0:
200,160,69858,1,2,0:0:0:0:
395,48,70058,1,14,0:0:0:0:
265,273,70258,1,2,0:0:0:0:
398,148,70458,6,0,P|451:145|499:169,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
374,356,70858,2,0,B|354:359|354:359|338:346|338:346|318:350|318:350|300:335|300:335|277:341|277:341|260:324,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
83,361,71258,1,4,0:0:0:0:
83,361,71458,1,0,0:0:0:0:
119,174,71658,5,14,0:0:0:0:
374,356,72058,5,6,0:0:0:0:
471,211,72258,1,0,0:0:0:0:
289,327,72458,2,0,P|235:333|186:312,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
11,167,72858,2,0,L|148:175,1,108.000000411987,6|0,0:0|0:0,0:0:0:0:
322,119,73258,1,10,0:0:0:0:
301,278,73458,1,2,0:0:0:0:
442,90,73658,5,4,0:0:0:0:
462,294,73858,1,0,0:0:0:0:
323,120,74058,2,0,P|264:99|209:111,1,108.000000411987,14|2,0:0|0:0,0:0:0:0:
161,153,74358,1,2,0:0:0:0:
161,153,74458,2,0,L|166:212,1,54.0000002059937,6|2,0:0|0:0,0:0:0:0:
99,296,74658,1,2,0:0:0:0:
99,296,74758,1,2,0:0:0:0:
99,296,74858,2,0,P|108:332|128:357,1,54.0000002059937,14|2,0:0|0:0,0:0:0:0:
227,355,75058,2,0,P|263:361|295:352,1,54.0000002059937,2|2,0:0|0:0,0:0:0:0:
352,265,75258,5,6,0:0:0:0:
343,239,75358,1,2,0:0:0:0:
334,213,75458,1,2,0:0:0:0:
326,187,75558,1,2,0:0:0:0:
254,169,75658,1,14,0:0:0:0:
245,143,75758,1,2,0:0:0:0:
236,117,75858,1,2,0:0:0:0:
228,91,75958,1,2,0:0:0:0:
166,55,76058,1,6,0:0:0:0:
393,127,76258,5,2,0:0:0:0:
452,351,76458,1,14,0:0:0:0:
225,282,76658,1,2,0:0:0:0:
459,200,76858,2,0,P|491:146|491:90,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
247,20,77258,2,0,P|294:62|317:40,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
54,319,77858,5,0,0:0:0:0:
195,252,78058,2,0,B|249:259|249:259|300:240,1,108.000000411987,10|2,0:0|0:0,0:0:0:0:
457,265,78458,1,4,0:0:0:0:
121,274,88058,5,0,0:0:0:0:
138,282,88158,1,0,0:0:0:0:
157,289,88258,1,0,0:0:0:0:
177,293,88358,1,0,0:0:0:0:
197,296,88458,1,0,0:0:0:0:
217,295,88558,1,0,0:0:0:0:
236,293,88658,1,0,0:0:0:0:
256,288,88758,1,0,0:0:0:0:
274,281,88858,1,0,0:0:0:0:
292,271,88958,1,0,0:0:0:0:
308,260,89058,1,0,0:0:0:0:
323,246,89158,1,0,0:0:0:0:
337,232,89258,1,0,0:0:0:0:
348,215,89358,1,0,0:0:0:0:
358,198,89458,1,0,0:0:0:0:
365,179,89558,1,0,0:0:0:0:
370,160,89658,6,0,L|373:122,30,20
417,143,91258,6,0,P|450:98|501:81,1,80,2|0,0:0|0:0,0:0:0:0:
473,271,91658,2,0,L|386:341,1,80,2|0,0:0|0:0,0:0:0:0:
238,293,92058,1,2,0:0:0:0:
354,193,92258,2,0,L|416:142,1,80,2|0,0:0|0:0,0:0:0:0:
252,120,92658,5,2,0:0:0:0:
321,263,92858,2,0,P|323:302|308:339,1,80,2|0,0:0|0:0,0:0:0:0:
110,294,93258,2,0,P|107:254|122:217,1,80,2|0,0:0|0:0,0:0:0:0:
187,149,93658,1,0,0:0:0:0:
220,305,93858,1,2,0:0:0:0:
377,274,94058,1,2,0:0:0:0:
344,117,94258,1,2,0:0:0:0:
187,149,94458,1,0,0:0:0:0:
340,199,94658,6,0,P|378:191|410:167,2,80,2|2|0,0:0|0:0|0:0,0:0:0:0:
236,76,95258,2,0,P|209:47|172:32,2,80,2|2|0,0:0|0:0|0:0,0:0:0:0:
182,227,95858,2,0,P|169:265|174:305,2,80,2|2|0,0:0|0:0|0:0,0:0:0:0:
340,199,96458,6,0,L|422:189,2,80,2|0|0,0:0|0:0|0:0,0:0:0:0:
163,112,97058,1,2,0:0:0:0:
151,228,97258,1,2,0:0:0:0:
267,238,97458,1,2,0:0:0:0:
279,123,97658,1,0,0:0:0:0:
177,301,97858,6,0,L|175:358,1,40,2|0,0:0|0:0,0:0:0:0:
257,286,98058,1,2,0:0:0:0:
113,384,98258,1,0,0:0:0:0:
383,303,98458,2,0,L|422:301,1,40,2|0,0:0|0:0,0:0:0:0:
327,359,98658,1,2,0:0:0:0:
486,262,98858,1,0,0:0:0:0:
302,124,99058,6,0,L|245:122,1,40,2|0,0:0|0:0,0:0:0:0:
338,196,99258,1,2,0:0:0:0:
392,34,99458,1,0,0:0:0:0:
384,263,99658,2,0,L|382:320,1,40,2|0,0:0|0:0,0:0:0:0:
452,218,99858,1,2,0:0:0:0:
226,313,100058,1,0,0:0:0:0:
218,144,100258,6,0,L|216:104,1,40,2|0,0:0|0:0,0:0:0:0:
146,189,100458,1,2,0:0:0:0:
292,356,100658,1,0,0:0:0:0:
452,218,100858,1,0,0:0:0:0:
285,109,101058,6,0,L|283:69,1,40,2|0,0:0|0:0,0:0:0:0:
287,185,101258,1,2,0:0:0:0:
420,96,101458,1,0,0:0:0:0:
223,225,101658,2,0,L|189:246,1,40,2|0,0:0|0:0,0:0:0:0:
287,185,101858,1,2,0:0:0:0:
140,120,102058,1,0,0:0:0:0:
354,222,102258,6,0,L|389:240,1,40,2|0,0:0|0:0,0:0:0:0:
287,185,102458,1,2,0:0:0:0:
292,344,102658,1,0,0:0:0:0:
285,109,102858,2,0,L|283:69,1,40,2|0,0:0|0:0,0:0:0:0:
287,185,103058,1,2,0:0:0:0:
391,24,103258,1,2,0:0:0:0:
456,209,103458,6,0,L|458:249,1,40,2|0,0:0|0:0,0:0:0:0:
512,124,103658,1,14,0:0:0:0:
285,109,104058,5,6,0:0:0:0:
288,272,104258,1,2,0:0:0:0:
196,107,104458,2,0,P|156:101|118:114,1,80,8|0,0:0|0:0,0:0:0:0:
77,179,104758,1,0,0:0:0:0:
79,218,104858,5,6,0:0:0:0:
67,28,105058,1,2,0:0:0:0:
165,191,105258,2,0,L|171:280,1,80,8|0,0:0|0:0,0:0:0:0:
119,323,105558,1,0,0:0:0:0:
121,362,105658,5,6,0:0:0:0:
242,215,105858,1,2,0:0:0:0:
258,359,106058,1,8,0:0:0:0:
292,379,106158,1,0,0:0:0:0:
331,383,106258,1,0,0:0:0:0:
369,372,106358,1,0,0:0:0:0:
400,347,106458,5,6,0:0:0:0:
186,365,106658,1,2,0:0:0:0:
307,262,106858,2,0,P|322:225|285:146,1,120,10|0,0:0|0:0,0:0:0:0:
223,133,107258,5,6,0:0:0:0:
422,174,107458,1,2,0:0:0:0:
418,76,107658,1,0,0:0:0:0:
223,133,107858,5,6,0:0:0:0:
378,261,108058,1,2,0:0:0:0:
422,174,108258,1,0,0:0:0:0:
223,133,108458,5,6,0:0:0:0:
300,320,108658,1,2,0:0:0:0:
378,261,108858,1,0,0:0:0:0:
223,133,109058,5,6,0:0:0:0:
203,334,109258,1,2,0:0:0:0:
300,320,109458,1,0,0:0:0:0:
223,133,109658,5,6,0:0:0:0:
111,301,109858,1,2,0:0:0:0:
132,102,110058,2,0,P|116:45|70:7,1,120,10|0,0:0|0:0,0:0:0:0:
0,36,110458,5,6,0:0:0:0:
197,42,110658,1,2,0:0:0:0:
56,106,110858,2,0,P|62:145|80:180,1,80,8|0,0:0|0:0,0:0:0:0:
159,177,111158,1,0,0:0:0:0:
198,172,111258,5,6,0:0:0:0:
28,253,111458,1,2,0:0:0:0:
186,273,111658,2,0,P|204:308|210:347,1,80,8|0,0:0|0:0,0:0:0:0:
139,368,111958,1,0,0:0:0:0:
100,373,112058,5,6,0:0:0:0:
310,348,112258,1,2,0:0:0:0:
257,201,112458,1,8,0:0:0:0:
245,162,112558,1,0,0:0:0:0:
264,116,112658,1,0,0:0:0:0:
252,78,112758,1,0,0:0:0:0:
270,32,112858,5,6,0:0:0:0:
88,46,113058,1,2,0:0:0:0:
172,190,113258,2,0,P|178:247|144:295,1,120,8|0,0:0|0:0,0:0:0:0:
67,326,113658,5,6,0:0:0:0:
104,120,113858,1,2,0:0:0:0:
80,248,114058,1,0,0:0:0:0:
294,249,114258,5,6,0:0:0:0:
257,43,114458,1,2,0:0:0:0:
281,171,114658,1,0,0:0:0:0:
449,42,114858,5,6,0:0:0:0:
411,248,115058,1,2,0:0:0:0:
435,120,115258,1,0,0:0:0:0:
221,119,115458,5,6,0:0:0:0:
258,325,115658,1,2,0:0:0:0:
234,197,115858,1,0,0:0:0:0:
66,325,116058,5,6,0:0:0:0:
103,119,116258,1,2,0:0:0:0:
258,325,116458,2,0,P|294:336|324:312,1,80,10|0,0:0|0:0,0:0:0:0:
339,69,116858,5,4,0:0:0:0:
274,97,117058,1,0,0:0:0:0:
210,126,117258,1,4,0:0:0:0:
210,126,117658,2,0,P|184:144|168:172,1,64,4|0,0:0|0:0,0:0:0:0:
153,240,117958,1,8,0:2:0:0:
153,240,118058,2,0,P|163:270|159:301,1,64,4|8,0:0|0:2,0:0:0:0:
8,384,118458,5,4,0:0:0:0:
82,377,118658,1,0,0:0:0:0:
156,372,118858,1,4,0:0:0:0:
156,372,119258,2,0,P|171:344|201:325,1,68.0000012969971,4|0,0:0|0:0,0:0:0:0:
271,306,119558,1,8,0:2:0:0:
271,306,119658,2,0,P|304:309|335:298,1,68.0000012969971,4|8,0:0|0:2,0:0:0:0:
286,163,120058,5,4,0:0:0:0:
295,84,120258,1,0,0:0:0:0:
360,39,120458,1,4,0:0:0:0:
360,39,120858,2,0,P|373:70|370:110,1,71.9999978027344,4|0,0:0|0:2,0:0:0:0:
361,183,121158,1,8,0:2:0:0:
361,183,121258,2,0,P|374:214|370:254,1,71.9999978027344,4|8,0:0|0:2,0:0:0:0:
296,376,121658,5,4,0:0:0:0:
234,319,121858,1,0,0:0:0:0:
225,235,122058,1,4,0:0:0:0:
225,235,122458,2,0,P|248:211|259:168,1,75.9999979705811,4|0,0:0|0:2,0:0:0:0:
217,107,122758,1,8,0:2:0:0:
217,107,122858,2,0,P|193:130|183:174,1,75.9999979705811,4|8,0:0|0:2,0:0:0:0:
329,207,123258,5,2,0:3:0:0:
435,162,123458,1,2,0:3:0:0:
511,248,123658,1,2,0:3:0:0:
454,347,123858,1,2,0:3:0:0:
341,323,124058,2,0,P|306:322|260:345,1,80,2|2,0:3|0:3,0:3:0:0:
189,361,124358,1,0,0:3:0:0:
189,361,124458,2,0,L|200:293,1,40,2|0,0:3|0:3,0:3:0:0:
152,254,124658,2,0,L|148:183,1,40,2|0,0:3|0:3,0:3:0:0:
84,155,124858,5,2,0:3:0:0:
57,294,125058,1,2,0:3:0:0:
195,321,125258,1,2,0:3:0:0:
222,183,125458,1,2,0:3:0:0:
333,83,125658,2,0,P|372:80|419:100,1,88.000002685547,2|2,0:3|0:3,0:3:0:0:
451,180,125958,1,0,0:3:0:0:
451,180,126058,2,0,L|432:239,1,44.0000013427735,2|0,0:3|0:3,0:3:0:0:
354,252,126258,2,0,L|367:307,1,44.0000013427735,2|0,0:3|0:3,0:3:0:0:
300,360,126458,6,0,P|330:378|384:383,1,71.9999978027344,2|0,0:3|0:3,0:3:0:0:
413,377,126658,2,0,P|432:328|458:307,1,71.9999978027344,2|0,0:3|0:3,0:3:0:0:
503,279,126858,2,0,L|484:203,1,77.9999964294435,2|0,0:3|0:3,0:3:0:0:
450,132,127058,2,0,P|386:121|358:133,1,77.9999964294435,2|0,0:3|0:3,0:3:0:0:
338,194,127258,2,0,P|322:236|283:273,1,77.9999964294435,2|0,0:3|0:3,0:3:0:0:
235,317,127458,6,0,P|201:306|169:283,1,51.999997619629,2|0,0:3|0:3,0:3:0:0:
147,197,127658,2,0,P|124:168|110:131,1,51.999997619629,2|0,0:3|0:3,0:3:0:0:
128,51,127858,2,0,P|124:14|132:-23,1,51.999997619629,2|0,0:3|0:3,0:3:0:0:
273,54,128058,6,0,L|312:153,1,83.9999974365235,2|0,0:3|0:3,0:3:0:0:
275,209,128258,2,0,P|250:242|268:301,1,83.9999974365235,2|0,0:3|0:3,0:3:0:0:
291,383,128458,2,0,P|236:390|185:358,1,90.0000034332277,2|0,0:3|0:3,0:3:0:0:
117,319,128658,2,0,L|124:225,1,90.0000034332277,2|0,0:3|0:3,0:3:0:0:
172,136,128858,2,0,P|120:110|67:107,1,96,2|0,0:3|0:3,0:3:0:0:
183,0,129058,2,0,P|235:26|252:25,1,64,2|0,0:3|0:3,0:3:0:0:
388,1,129258,1,14,0:3:0:0:
366,258,129658,5,6,0:0:0:0:
367,269,129758,1,2,0:3:0:0:
367,280,129858,1,2,0:3:0:0:
418,100,130058,6,0,B|423:84|423:84|403:57|396:11,1,80
193,96,130458,5,6,0:0:0:0:
204,97,130558,1,2,0:3:0:0:
215,98,130658,1,2,0:3:0:0:
156,201,130791,5,0,0:0:0:0:
156,201,130858,2,0,B|151:217|151:217|171:244|178:290,1,80
293,172,131258,5,6,0:0:0:0:
283,165,131358,1,2,0:3:0:0:
273,158,131458,1,2,0:3:0:0:
296,263,132058,5,4,0:0:0:0:
293,274,132158,1,2,0:3:0:0:
231,312,132258,1,2,0:3:0:0:
228,323,132358,1,2,0:3:0:0:
268,384,132458,2,0,L|343:372,1,60,4|0,0:0|0:3,0:3:0:0:
393,360,132658,2,0,P|397:332|433:305,1,71.9999978027344,2|0,0:3|0:3,0:3:0:0:
498,304,132858,5,6,0:0:0:0:
271,313,133058,2,0,B|217:318|217:318|165:299,1,108.000000411987,2|4,0:0|0:0,0:0:0:0:
362,161,133458,1,2,0:0:0:0:
393,360,133658,1,6,0:0:0:0:
166,299,133858,1,0,0:0:0:0:
260,107,134058,6,0,B|262:71|262:71|232:99,1,54.0000002059937,6|0,0:0|2:0,0:0:0:0:
189,121,134258,2,0,P|160:95|153:74,1,54.0000002059937,2|0,0:0|2:0,0:0:0:0:
195,22,134458,1,4,0:0:0:0:
111,212,134658,1,2,0:0:0:0:
298,198,134858,2,0,B|371:194|371:194|338:171,1,108.000000411987,6|0,0:0|0:0,0:0:0:0:
189,121,135258,5,6,0:0:0:0:
351,273,135458,1,2,0:0:0:0:
387,55,135658,2,0,B|366:28|366:28|343:46|343:46|318:30|318:30|299:46|299:46|273:36|273:36|265:69,1,180.000006866455,6|0,0:0|0:0,0:0:0:0:
228,148,136058,5,6,0:0:0:0:
450,123,136258,1,2,0:0:0:0:
359,328,136458,1,4,0:0:0:0:
332,70,136658,1,2,0:0:0:0:
231,277,136858,1,6,0:0:0:0:
464,252,137058,2,0,B|449:253|483:249,1,27.0000001029968
291,344,137258,5,6,0:0:0:0:
61,332,137458,1,2,0:0:0:0:
231,277,137658,1,4,0:0:0:0:
138,66,137858,1,2,0:0:0:0:
354,53,138058,1,6,0:0:0:0:
163,187,138258,1,0,0:0:0:0:
372,181,138458,6,0,P|444:211|476:284,1,162.000000617981,6|0,0:0|0:0,0:0:0:0:
389,374,138858,2,0,P|316:343|284:270,1,162.000000617981,6|0,0:0|0:0,0:0:0:0:
314,126,139258,5,6,0:0:0:0:
200,303,139458,2,0,B|160:364|160:364|202:349,1,108.000000411987,2|4,0:0|0:0,0:0:0:0:
382,279,139858,1,2,0:0:0:0:
184,168,140058,2,0,L|85:114,1,108.000000411987,6|0,0:0|0:0,0:0:0:0:
312,25,140458,5,6,0:0:0:0:
289,236,140658,2,0,B|285:269|285:269|263:285|263:285|258:351,1,108.000000411987,2|4,0:0|0:0,0:0:0:0:
479,178,141058,1,2,0:0:0:0:
270,152,141258,2,0,B|231:147|231:147|245:165,2,54.0000002059937,6|0|0,0:0|0:0|0:0,0:0:0:0:
399,64,141858,5,2,0:0:0:0:
385,192,142058,1,2,0:0:0:0:
372,320,142258,1,2,0:0:0:0:
163,210,142458,5,6,0:0:0:0:
385,192,142658,1,2,0:0:0:0:
175,120,142858,2,0,P|110:132|73:176,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
136,342,143258,1,4,0:0:0:0:
0,164,143458,1,2,0:0:0:0:
181,188,143658,1,14,0:0:0:0:
363,205,143858,1,2,0:0:0:0:
239,19,144058,5,4,0:0:0:0:
249,221,144258,1,0,0:0:0:0:
317,9,144458,1,12,0:0:0:0:
181,188,144658,1,0,0:0:0:0:
388,32,144858,2,0,P|446:88|462:167,1,162.000000617981,4|0,0:0|0:0,0:0:0:0:
407,285,145258,2,0,P|349:229|333:150,1,162.000000617981,14|0,0:0|0:0,0:0:0:0:
317,9,145658,5,6,0:0:0:0:
147,140,145858,1,2,0:0:0:0:
362,124,146058,1,10,0:0:0:0:
376,340,146258,1,2,0:0:0:0:
161,355,146458,1,6,0:0:0:0:
376,340,146658,1,2,0:0:0:0:
362,124,146858,1,14,0:0:0:0:
147,140,147058,1,2,0:0:0:0:
348,220,147258,6,0,P|413:208|450:164,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
239,108,147658,2,0,B|222:120|222:120|202:116|202:116|186:128|186:128|163:124|163:124|146:140|146:140|123:133,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
80,299,148058,1,4,0:0:0:0:
80,299,148258,1,0,0:0:0:0:
272,248,148458,5,14,0:0:0:0:
96,64,148858,5,6,0:0:0:0:
138,252,149058,1,0,0:0:0:0:
261,68,149258,2,0,B|314:44|314:44|364:46,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
472,210,149658,1,6,0:0:0:0:
215,146,149858,2,0,B|167:135|167:135,1,27.0000001029968
291,276,150058,1,14,0:0:0:0:
354,93,150258,1,2,0:0:0:0:
366,320,150458,2,0,P|325:354|272:359,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
60,215,150858,6,0,L|185:209,1,108.000000411987,14|2,0:0|0:0,0:0:0:0:
249,202,151158,1,2,0:0:0:0:
249,202,151258,2,0,P|265:163|280:151,1,54.0000002059937,6|2,0:0|0:0,0:0:0:0:
363,116,151458,1,2,0:0:0:0:
363,116,151558,1,2,0:0:0:0:
363,116,151658,2,0,L|358:178,1,54.0000002059937,14|2,0:0|0:0,0:0:0:0:
299,261,151858,2,0,P|327:292|345:298,1,54.0000002059937,2|2,0:0|0:0,0:0:0:0:
447,344,152058,5,6,0:0:0:0:
459,319,152158,1,2,0:0:0:0:
464,292,152258,1,2,0:0:0:0:
462,265,152358,1,2,0:0:0:0:
432,195,152458,1,14,0:0:0:0:
407,183,152558,1,2,0:0:0:0:
386,166,152658,1,2,0:0:0:0:
370,143,152758,1,2,0:0:0:0:
356,68,152858,1,6,0:0:0:0:
203,105,153058,5,2,0:0:0:0:
159,303,153258,1,14,0:0:0:0:
377,276,153458,1,2,0:0:0:0:
156,197,153658,2,0,B|107:207|107:207|61:244,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
315,216,154058,2,0,P|336:171|294:146,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
187,352,154658,5,2,0:0:0:0:
183,362,154858,1,2,0:0:0:0:
193,358,155058,1,2,0:0:0:0:
393,308,155258,5,6,0:0:0:0:
170,284,155458,1,2,0:0:0:0:
341,130,155658,1,12,0:0:0:0:
126,194,155858,1,0,0:0:0:0:
250,0,156058,1,4,0:0:0:0:
249,208,156258,1,2,0:0:0:0:
465,169,156458,1,14,0:0:0:0:
285,293,156658,1,2,0:0:0:0:
138,106,156858,6,0,P|88:87|36:99,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
181,311,157258,2,0,B|235:313|235:313|284:293,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
409,86,157658,6,0,B|337:97|337:97|341:77|341:77|251:90,1,162.000000617981,6|0,0:0|0:0,0:0:0:0:
244,230,158058,2,0,P|313:262|372:212,1,162.000000617981,14|0,0:0|0:0,0:0:0:0:
493,160,158458,5,6,0:0:0:0:
380,327,158658,1,2,0:0:0:0:
293,154,158858,1,14,0:0:0:0:
98,152,159058,1,2,0:0:0:0:
284,54,159258,1,6,0:0:0:0:
264,246,159458,1,2,0:0:0:0:
86,315,159658,1,14,0:0:0:0:
211,152,159858,1,2,0:0:0:0:
321,344,160058,6,0,B|372:360|372:360|424:355,1,108.000000411987,4|0,0:0|0:0,0:0:0:0:
469,137,160458,2,0,B|417:120|417:120|365:125,1,108.000000411987,12|0,0:0|0:0,0:0:0:0:
267,250,160858,1,4,0:0:0:0:
267,250,161058,1,0,0:0:0:0:
277,76,161258,1,14,0:0:0:0:
421,274,161658,5,2,0:0:0:0:
325,273,161858,1,0,0:0:0:0:
325,369,162058,1,0,0:0:0:0:
229,369,162258,1,0,0:0:0:0:
229,273,162458,1,2,0:0:0:0:
133,273,162658,1,0,0:0:0:0:
133,178,162858,1,2,0:0:0:0:
229,178,163058,1,2,0:0:0:0:
229,82,163258,1,0,0:0:0:0:
325,82,163458,1,0,0:0:0:0:
325,178,163658,6,0,L|324:275,1,80,2|2,0:0|0:0,0:0:0:0:
328,330,163958,1,2,0:0:0:0:
328,330,164058,1,2,0:0:0:0:
281,329,164158,1,2,0:0:0:0:
233,330,164258,1,2,0:0:0:0:
184,329,164358,1,2,0:0:0:0:
183,257,164458,1,2,0:0:0:0:
232,258,164558,1,2,0:0:0:0:
280,257,164658,1,2,0:0:0:0:
328,258,164758,1,2,0:0:0:0:
328,186,164858,6,0,L|328:136,2,40,2|2|2,0:0|0:0|0:0,0:0:0:0:
279,185,165158,2,0,L|279:135,2,40,2|2|2,0:0|0:0|0:0,0:0:0:0:
231,186,165458,1,2,0:0:0:0:
232,138,165558,1,2,0:0:0:0:
231,90,165658,1,2,0:0:0:0:
135,90,165858,1,2,0:0:0:0:
135,186,166058,1,2,0:0:0:0:
39,186,166258,1,2,0:0:0:0:
39,90,166458,6,0,L|39:10,2,80
135,186,167058,2,0,L|134:266,2,80

View File

@ -0,0 +1,49 @@
extern crate libosu;
extern crate serde;
#[macro_use]
extern crate serde_json;
use std::fs::File;
use std::io::{Read, Write};
use libosu::*;
macro_rules! test_serde {
($($name:ident: $id:expr,)*) => {
$(
#[test]
fn $name() {
let mut file = File::open(format!("tests/files/{}.osu", $id)).expect("couldn't open file");
let mut contents = String::new();
file.read_to_string(&mut contents).expect("couldn't read file");
let beatmap = Beatmap::from_osz(&contents).expect("couldn't parse");
// stage 1
let stage1 = beatmap.as_osz().expect("couldn't serialize");
// let mut file = File::create(format!("tests/out/{}.stage1.osu", $id)).expect("couldn't open file");
// file.write_all(stage1.as_bytes()).expect("couldn't write");
// eprintln!("STAGE 2 --------------------");
// ok parse again
let beatmap1 = Beatmap::from_osz(stage1.clone()).expect("couldn't parse");
// stage 2
let stage2 = beatmap1.as_osz().expect("couldn't serialize");
println!("{}", stage2);
println!("{:?}", beatmap);
assert_eq!(stage1, stage2);
// panic!();
json!(beatmap).to_string();
}
)*
};
}
test_serde! {
test_parser_774965: 774965,
test_parser_804683: 804683,
}

3
editor-old/rustfmt.toml Normal file
View File

@ -0,0 +1,3 @@
max_width = 80
wrap_comments = true

View File

@ -0,0 +1,7 @@
All osu! graphic and other game assets are copyright ppy Pty Ltd.
You are granted permission to use the elements contained within this archive as a template for creating your own skins. You can modify these in any way you see fit. Please do not include the resources if you haven't modified them; the defaults will automatically be used in this case.
You are NOT permitted to use these graphics outside of skins and/or beatmaps. This includes using them on other websites, games, products etc.
If you would like to use the resources outside of the scope provided above, please contact me at pe@ppy.sh

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More