Commit a336c43f authored by 陈冲's avatar 陈冲

init

parents
/target
.codex
config.json
test_ds.sh
addons/
This source diff could not be displayed because it is too large. You can view the blob instead.
[package]
name = "backend-ds"
version = "0.1.0"
edition = "2024"
[dependencies]
bytes = "1.10.1"
chrono = { version = "0.4.44", features = ["serde"] }
async-trait = "0.1.89"
sqlx = { version = "0.8.2", features = ["runtime-tokio", "tls-rustls-ring-native-roots", "postgres", "chrono", "json"] }
rand = "0.10.0"
rust-embed = { version = "8.11.0", features = ["debug-embed"] }
salvo = { version = "0.90.1", features = ["serve-static", "tower-compat"] }
serde = "1.0.228"
serde_json = "1.0.149"
rmp-serde = "1.3.0"
socketioxide = { version = "0.18.2", features = ["tracing", "extensions", "state"] }
tokio = {version = "1.50.0", features = ["full"]}
tower = "0.5.3"
tower-http = { version = "0.6.8", features = ["cors"] }
dashmap = "6.1.0"
base64 = "0.22.1"
lazy_static = "1.5.0"
aes = "0.8.4"
cbc = { version = "0.1.2", features = ["alloc"] }
md5 = { version = "0.10.6", package = "md-5" }
[[bin]]
name = "backend-ds"
# [target.aarch64-unknown-linux-gnu]
# linker = "aarch64-linux-gnu-gcc"
# cross build --release --target aarch64-unknown-linux-gnu
### 福彩小游戏
\ No newline at end of file
drop table if exists tb_game;
create table tb_game
(
event_date date, -- 活动日期
wechat_id varchar(50), -- 微信id
nickname varchar(50), -- 昵称
avatar varchar(200), -- 头像
round_num int NOT NULL CHECK (round_num between 1 and 3), -- 比赛场次
item_num int not null check (item_num between 1 and 6), -- 游戏项目(1到6)
score int not null default 0 check (score >= 0), -- 得分
create_date timestamptz, -- 创建时间
unique(event_date,wechat_id,round_num,item_num)
);
SELECT * FROM tb_game
DROP TABLE IF EXISTS tb_log;
CREATE TABLE tb_log
(
id BIGSERIAL PRIMARY KEY,
msg TEXT,
params jsonb,
create_date timestamptz
);
SELECT * FROM tb_log
drop table if exists tb_manager;
create table tb_manager
(
id SERIAL PRIMARY KEY,
username VARCHAR(20),
"password" VARCHAR(20),
token VARCHAR(36)
)
INSERT INTO tb_manager(username,"password",token) VALUES('admin','123456','88236aeb-8d3f-6d56-fdf5-3adca3961dfb');
SELECT * FROM tb_manager;
use std::{fs, io::Write};
use serde::{Deserialize, Serialize};
#[derive(Clone, Deserialize, Serialize, Debug)]
#[serde(default)]
pub struct Config {
// 当前服务监听地址,Salvo HTTP 和 socket.io 都挂在这个地址上。
pub host: String,
// 玩家客户端连接的 socket.io namespace。
pub client_ns: String,
// Socket.IO 的 HTTP 传输路径,前后端和 nginx 需要保持一致。
pub socket_path: String,
// 玩家身份校验用的 AES 密钥短语,需和客户端加密逻辑保持一致。
#[serde(skip_serializing_if = "Option::is_none")]
pub aes_passphrase: Option<String>,
// 数据库配置:所有 master/worker 节点都可以直连同一台 DB。
pub db: DbConfig,
}
#[derive(Clone, Deserialize, Serialize, Debug)]
#[serde(default)]
pub struct DbConfig {
// 数据库类型:mongodb、postgresql、mysql、sqlite。
pub kind: String,
// mongodb://admin:123456@127.0.0.1:27017/backend_ds
// postgresql://admin:123456@localhost:5432/backend_ds
pub uri: String,
}
impl Default for Config {
fn default() -> Self {
Self {
host: "127.0.0.1:8082".to_string(),
client_ns: "/ws".to_string(),
socket_path: "/socket.io".to_string(),
aes_passphrase: None,
db: DbConfig::default(),
}
}
}
impl Default for DbConfig {
fn default() -> Self {
Self {
kind: "postgresql".to_string(),
uri: "postgres://postgres:123456@localhost:5432/backend_ds".to_string(),
}
}
}
impl Config {
pub fn load() -> std::io::Result<Self> {
let path = "config.json";
let err_msg = &format!("<{path}>文件不存在或配置异常");
if !fs::exists(path).expect(err_msg) {
let mut file = fs::File::create(path).expect(err_msg);
let json_str = serde_json::to_string_pretty(&Self::default())?;
file.write_all(json_str.as_bytes())?;
panic!("请配置config.json相关参数后运行");
}
let text = fs::read_to_string(path).expect(err_msg);
let cfg: Self = serde_json::from_str(&text).expect(err_msg);
Ok(cfg)
}
}
pub mod config;
pub mod utils;
use super::config::Config;
use aes::Aes256;
use aes::cipher::BlockDecryptMut;
use aes::cipher::block_padding::Pkcs7;
use aes::cipher::{BlockEncryptMut, KeyIvInit};
use base64::{Engine as _, engine::general_purpose};
use cbc::Decryptor;
use md5::{Digest, Md5};
use rand::Rng;
use std::sync::LazyLock;
pub static CONFIG: LazyLock<Config> = LazyLock::new(|| Config::load().unwrap());
type Aes256CbcDec = Decryptor<Aes256>;
type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
pub fn get_aes_passphrase() -> Option<String> {
CONFIG.aes_passphrase.clone()
}
fn evp_bytes_to_key(password: &[u8], salt: &[u8]) -> ([u8; 32], [u8; 16]) {
let mut hasher = Md5::new();
let mut key_iv = Vec::new();
let mut derived_bytes = Vec::new();
while key_iv.len() < 48 {
// 32 bytes for key + 16 bytes for IV
if !derived_bytes.is_empty() {
hasher.update(&derived_bytes);
}
hasher.update(password);
hasher.update(salt);
derived_bytes = hasher.finalize_reset().to_vec();
key_iv.extend_from_slice(&derived_bytes);
}
let mut key = [0u8; 32];
key.copy_from_slice(&key_iv[0..32]);
let mut iv = [0u8; 16];
iv.copy_from_slice(&key_iv[32..48]);
(key, iv)
}
pub fn decrypt_cryptojs_aes(encrypted_base64: &str, passphrase: &str) -> Result<String, String> {
// Decode Base64 input
let encrypted_data = general_purpose::STANDARD
.decode(encrypted_base64)
.map_err(|e| format!("Base64 decode error: {}", e))?;
// Validate data format and extract salt and ciphertext
if encrypted_data.len() < 16 || &encrypted_data[0..8] != b"Salted__" {
return Err("Invalid encrypted data format: missing 'Salted__' prefix".to_string());
}
let salt = &encrypted_data[8..16];
let ciphertext = &encrypted_data[16..];
// Derive key and IV
let (key, iv) = evp_bytes_to_key(passphrase.as_bytes(), salt);
// Initialize AES-256-CBC decryptor
let cipher = Aes256CbcDec::new(&key.into(), &iv.into());
// Decrypt with PKCS#7 padding
let mut buf = ciphertext.to_vec();
let decrypted_bytes = cipher
.decrypt_padded_mut::<Pkcs7>(&mut buf)
.map_err(|e| format!("Decryption error: {}", e))?;
// Convert decrypted bytes to UTF-8 string
String::from_utf8(decrypted_bytes.to_vec())
.map_err(|e| format!("UTF-8 conversion error: {}", e))
}
pub fn encrypt_cryptojs_aes(plaintext: &str, passphrase: &str) -> Result<String, String> {
// Validate inputs
if plaintext.is_empty() {
return Err("Empty plaintext".to_string());
}
if passphrase.is_empty() {
return Err("Empty passphrase".to_string());
}
// Generate random 8-byte salt
let mut salt = [0u8; 8];
rand::rng().fill_bytes(&mut salt);
// Derive key and IV
let (key, iv) = evp_bytes_to_key(passphrase.as_bytes(), &salt);
// Debug: Print inputs and derived values
// eprintln!("Plaintext: {}", plaintext);
// eprintln!("Plaintext length: {}", plaintext.len());
// eprintln!(
// "Plaintext bytes (hex): {}",
// hex::encode(plaintext.as_bytes())
// );
// eprintln!("Salt (hex): {}", hex::encode(&salt));
// eprintln!("Key (hex): {}", hex::encode(&key));
// eprintln!("IV (hex): {}", hex::encode(&iv));
// Initialize AES-256-CBC encryptor
let cipher = Aes256CbcEnc::new(&key.into(), &iv.into());
// Encrypt with PKCS#7 padding, using encrypt_padded_vec_mut to handle buffer
let encrypted_bytes = cipher.encrypt_padded_vec_mut::<Pkcs7>(plaintext.as_bytes());
// Debug: Print encrypted bytes
// eprintln!("Encrypted bytes (hex): {}", hex::encode(&encrypted_bytes));
// Construct output: Salted__ + salt + ciphertext
let mut output = Vec::with_capacity(8 + 8 + encrypted_bytes.len());
output.extend_from_slice(b"Salted__");
output.extend_from_slice(&salt);
output.extend_from_slice(&encrypted_bytes);
// Encode to Base64
let base64_output = general_purpose::STANDARD.encode(&output);
// eprintln!("Encrypted Base64: {}", base64_output);
Ok(base64_output)
}
/// 返回当前UTC时间戳,没有毫秒
pub fn get_current_timestamp() -> u64 {
chrono::Local::now().timestamp() as u64
// SystemTime::now()
// .duration_since(UNIX_EPOCH)
// .unwrap()
// .as_secs()
}
pub fn format_timestamp() {}
pub fn add_second(ts: u64, val: u64) -> u64 {
ts + val
}
pub fn add_minute(ts: u64, val: u64) -> u64 {
add_second(ts, val * 60)
}
pub fn add_hour(ts: u64, val: u64) -> u64 {
add_minute(ts, val * 60)
}
use crate::commons::utils::CONFIG as config;
use crate::db::pg::PgDb;
use async_trait::async_trait;
use serde_json::Value;
use tokio::sync::OnceCell;
pub mod pg;
pub mod models;
#[async_trait]
trait DbDriver: Send + Sync {
async fn query(&self, sql: &str, params: Vec<Value>) -> Result<Vec<Value>, String>;
async fn transaction(&self, queries: Vec<Value>) -> Result<Vec<Value>, String>;
}
static DB_CONN: OnceCell<Box<dyn DbDriver>> = OnceCell::const_new();
pub async fn init_db() -> Result<(), String> {
let conn: Box<dyn DbDriver> = match config.db.kind.as_str() {
"postgresql" => Box::new(PgDb::new().await?),
other => {
return Err(format!("unsupported db kind: {other}"));
}
};
DB_CONN
.set(conn)
.map_err(|_| "db already initialized".to_string())
}
pub async fn db_query(sql: &str, params: Vec<Value>) -> Result<Vec<Value>, String> {
let conn = DB_CONN
.get()
.ok_or_else(|| "db not initialized".to_string())?;
conn.query(sql, params).await
}
pub async fn db_transaction(queries: Vec<Value>) -> Result<Vec<Value>, String> {
let conn = DB_CONN
.get()
.ok_or_else(|| "db not initialized".to_string())?;
conn.transaction(queries).await
}
use chrono::{DateTime, NaiveDate, Utc};
use serde_json::json;
use crate::db::models::log::Log;
pub struct Game {
/// 活动日期
pub event_date: NaiveDate,
pub wechat_id: String,
pub nickname: Option<String>,
pub avatar: Option<String>,
/// 比赛场次
pub round_num: i32,
/// 游戏项目(1到6)
pub item_num: i32,
/// 得分
pub score: i32,
/// 创建时间
pub create_date: Option<DateTime<Utc>>,
}
impl Game {
pub async fn insert(&self) -> bool {
let res = crate::db::db_query(
r#"insert into tb_game(event_date,wechat_id,nickname,avatar,round_num,item_num,score,create_date) values(?::date,?,?,?,?,?,?,now());"#,
vec![
json!(&self.event_date),
json!(&self.wechat_id),
json!(&self.nickname),
json!(&self.avatar),
json!(&self.round_num),
json!(&self.item_num),
json!(&self.score),
],
)
.await;
match res {
Ok(res) => {
// dbg!(&res);
true
}
Err(err) => {
// dbg!(&err);
let log = Log {
id: 0,
msg: err,
params: json!({
"event_date": self.event_date,
"wechat_id": self.wechat_id,
"nickname": self.nickname,
"avatar": self.avatar,
"round_num": self.round_num,
"item_num": self.item_num,
"score": self.score,
}),
create_date: None,
};
log.insert().await;
false
}
}
}
}
use chrono::{DateTime, Utc};
use serde_json::{Value, json};
pub struct Log {
pub id: i32,
pub msg: String,
pub params: Value,
pub create_date: Option<DateTime<Utc>>,
}
impl Log {
pub async fn insert(&self) -> bool {
let res = crate::db::db_query(
r#"insert into tb_log(msg,params,create_date) values(?,?::jsonb,now());"#,
vec![json!(&self.msg), json!(&self.params)],
)
.await;
match res {
Ok(res) => {
// dbg!(&res);
true
}
Err(err) => {
// dbg!(&err);
false
}
}
}
}
use serde_json::{Value, json};
use crate::db::models::*;
#[derive(Debug)]
pub struct Manager {
pub id: i32,
pub username: String,
pub password: String,
pub token: String,
}
pub enum ManagerLogin {
/// username / password
unpw(String, String),
token(String),
}
impl Manager {
pub async fn Login(m: ManagerLogin) -> Result<Self, String> {
match m {
ManagerLogin::unpw(username, password) => {
let rows = crate::db::db_query(
r#"select id,username,password,token from tb_manager where username=? and password=? limit 1;"#,
vec![json!(username), json!(password)],
)
.await
.map_err(|err| format!("用户名或密码错误,{err}"))?;
let row = rows.first().ok_or_else(|| "用户名或密码错误".to_string())?;
Ok(Self {
id: get_i32(row, "id")?,
username: get_string(row, "username")?,
password: get_string(row, "password")?,
token: get_string(row, "token")?,
})
}
ManagerLogin::token(token) => {
let rows = crate::db::db_query(
r#"select id,username,password,token from tb_manager where token=? limit 1;"#,
vec![json!(token)],
)
.await
.map_err(|err| format!("token异常,{err}"))?;
let row = rows.first().ok_or_else(|| "token异常".to_string())?;
Ok(Self {
id: get_i32(row, "id")?,
username: get_string(row, "username")?,
password: get_string(row, "password")?,
token: get_string(row, "token")?,
})
}
}
}
}
use serde_json::Value;
pub mod game;
pub mod log;
pub mod manager;
pub fn get_i32(row: &Value, key: &str) -> Result<i32, String> {
row.get(key)
.and_then(|value| value.as_i64())
.and_then(|value| i32::try_from(value).ok())
.ok_or_else(|| format!("{key}字段格式错误"))
}
pub fn get_string(row: &Value, key: &str) -> Result<String, String> {
row.get(key)
.and_then(|value| value.as_str())
.map(|value| value.to_string())
.ok_or_else(|| format!("{key}字段格式错误"))
}
use crate::commons::utils::CONFIG as config;
use crate::db::{DbDriver};
use async_trait::async_trait;
use serde_json::{Value, json};
use sqlx::postgres::{PgPoolOptions, PgRow};
use sqlx::{Column, PgPool, Row, TypeInfo};
pub struct PgDb {
pool: PgPool,
}
impl PgDb {
pub async fn new() -> Result<Self, String> {
let pool = PgPoolOptions::new()
.max_connections(16)
.connect(&config.db.uri)
.await
.map_err(|err| err.to_string())?;
Ok(Self { pool })
}
}
#[async_trait]
impl DbDriver for PgDb {
async fn query(&self, sql: &str, params: Vec<Value>) -> Result<Vec<Value>, String> {
let mut conn = self.pool.acquire().await.map_err(|err| err.to_string())?;
pg_query_rows(&mut *conn, sql, params).await
}
async fn transaction(&self, queries: Vec<Value>) -> Result<Vec<Value>, String> {
let mut tx = self.pool.begin().await.map_err(|err| err.to_string())?;
let mut results = Vec::with_capacity(queries.len());
for query in queries.iter() {
let sql = query
.get("query")
.or_else(|| query.get("sql"))
.and_then(|value| value.as_str())
.unwrap_or("")
.trim();
if sql.is_empty() {
return Err("transaction query sql is empty".to_string());
}
let params = query
.get("params")
.and_then(|value| value.as_array())
.cloned()
.unwrap_or_default();
let rows = pg_query_rows(&mut *tx, sql, params).await?;
results.push(Value::Array(rows));
}
tx.commit().await.map_err(|err| err.to_string())?;
Ok(results)
}
}
async fn pg_query_rows<'e, E>(
executor: E,
sql: &str,
params: Vec<Value>,
) -> Result<Vec<Value>, String>
where
E: sqlx::Executor<'e, Database = sqlx::Postgres>,
{
let sql = normalize_sql_placeholders(sql);
let mut query = sqlx::query(sql.as_str());
for param in params.into_iter() {
query = pg_bind_param(query, param);
}
let rows = query
.fetch_all(executor)
.await
.map_err(|err| err.to_string())?;
rows.into_iter()
.map(pg_row_to_json)
.collect::<Result<Vec<_>, _>>()
}
fn normalize_sql_placeholders(sql: &str) -> String {
let mut index = 1;
let mut out = String::with_capacity(sql.len());
for ch in sql.chars() {
if ch == '?' {
out.push('$');
out.push_str(index.to_string().as_str());
index += 1;
} else {
out.push(ch);
}
}
out
}
fn pg_bind_param<'q>(
query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>,
value: Value,
) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
match value {
Value::Bool(v) => query.bind(v),
Value::Number(v) => {
if let Some(v) = v.as_i64() {
query.bind(v)
} else {
let v = v.as_f64().unwrap_or_default();
if v.fract() == 0.0 {
query.bind(v as i64)
} else {
query.bind(v)
}
}
}
Value::String(v) => query.bind(v),
Value::Array(v) => query.bind(Value::Array(v)),
Value::Object(v) => query.bind(Value::Object(v)),
Value::Null => query.bind(Option::<String>::None),
}
}
fn pg_row_to_json(row: PgRow) -> Result<Value, String> {
let mut item = serde_json::Map::new();
for (index, column) in row.columns().iter().enumerate() {
let type_name = column.type_info().name().to_ascii_uppercase();
let value = match type_name.as_str() {
"BOOL" => json!(
row.try_get::<Option<bool>, _>(index)
.map_err(|err| err.to_string())?
),
"INT2" => json!(
row.try_get::<Option<i16>, _>(index)
.map_err(|err| err.to_string())?
),
"INT4" => json!(
row.try_get::<Option<i32>, _>(index)
.map_err(|err| err.to_string())?
),
"INT8" => json!(
row.try_get::<Option<i64>, _>(index)
.map_err(|err| err.to_string())?
),
"FLOAT4" => {
json!(
row.try_get::<Option<f32>, _>(index)
.map_err(|err| err.to_string())?
)
}
"FLOAT8" => {
json!(
row.try_get::<Option<f64>, _>(index)
.map_err(|err| err.to_string())?
)
}
"VARCHAR" | "TEXT" | "BPCHAR" | "NAME" => {
json!(
row.try_get::<Option<String>, _>(index)
.map_err(|err| err.to_string())?
)
}
"JSON" | "JSONB" => row
.try_get::<Option<Value>, _>(index)
.map_err(|err| err.to_string())?
.unwrap_or(Value::Null),
"TIMESTAMPTZ" => {
let value = row
.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(index)
.map_err(|err| err.to_string())?
.map(|ts| ts.timestamp_millis())
.unwrap_or(0);
json!(value)
}
_ => json!(type_name),
};
item.insert(column.name().to_string(), value);
}
Ok(Value::Object(item))
}
mod commons;
mod db;
mod protocols;
mod router;
use commons::utils::CONFIG as config;
use sqlx::PgPool;
use sqlx::postgres::PgPoolOptions;
pub async fn init_postgresql_schema() -> Result<(), String> {
let pool = PgPoolOptions::new()
.max_connections(4)
.connect(&config.db.uri)
.await
.map_err(|err| err.to_string())?;
sqlx::raw_sql(
"create table if not exists player_profiles (
userid text primary key,
nickname text not null,
level bigint not null default 1,
exp bigint not null default 0,
avatar_id bigint not null default 0,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
create table if not exists player_wallets (
userid text primary key references player_profiles(userid) on delete cascade,
gold bigint not null default 0,
diamond bigint not null default 0,
stamina bigint not null default 100,
updated_at timestamptz not null default now()
);
create table if not exists player_items (
id bigserial primary key,
userid text not null references player_profiles(userid) on delete cascade,
item_id text not null,
item_count bigint not null default 0,
updated_at timestamptz not null default now(),
unique(userid, item_id)
);
create table if not exists player_mails (
id bigserial primary key,
userid text not null references player_profiles(userid) on delete cascade,
title text not null,
content text not null default '',
attachments jsonb not null default '[]'::jsonb,
status text not null default 'unread',
created_at timestamptz not null default now()
);
create table if not exists task_idempotency (
task_id text primary key,
task_type text not null,
status text not null default 'running',
attempt bigint not null default 1,
result jsonb,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
alter table player_profiles alter column level type bigint;
alter table player_profiles alter column avatar_id type bigint;
alter table player_wallets alter column stamina type bigint;",
)
.execute(&pool)
.await
.map_err(|err| err.to_string())?;
migrate_legacy_players(&pool).await
}
async fn migrate_legacy_players(pool: &PgPool) -> Result<(), String> {
let row: (bool,) = sqlx::query_as("select to_regclass('public.players') is not null")
.fetch_one(pool)
.await
.map_err(|err| err.to_string())?;
let has_legacy_table = row.0;
if !has_legacy_table {
return Ok(());
}
sqlx::raw_sql(
"insert into player_profiles (userid, nickname)
select userid, nickname
from players
on conflict (userid)
do update set nickname = excluded.nickname;
insert into player_wallets (userid)
select userid
from players
on conflict (userid) do nothing;
drop table if exists players;",
)
.execute(pool)
.await
.map_err(|err| err.to_string())?;
Ok(())
}
#[cfg(test)]
mod tests {
use serde_json::json;
use std::time::{SystemTime, UNIX_EPOCH};
use crate::commons::utils;
async fn init_db() {
_ = crate::db::init_db().await;
}
#[tokio::test]
async fn test_db() {
_ = init_db().await;
// if let Ok(res) =
// crate::db::db_query("select * from tb_user where id=?", vec![json!("123")]).await
// {
// dbg!(&res);
// }
// let game = crate::db::models::game::Game {
// event_date: "2026-05-25".parse().unwrap(),
// wechat_id: "test_wechat_id".to_string(),
// nickname: Some("test_nickname".to_string()),
// avatar: Some("test_avatar".to_string()),
// round_num: 1,
// item_num: 2,
// score: 100,
// create_date: None,
// };
// let res = game.insert().await;
// dbg!(&res);
let res = crate::db::models::manager::Manager::Login(
crate::db::models::manager::ManagerLogin::unpw(
"admin".to_string(),
"123456".to_string(),
),
)
.await;
dbg!(&res);
}
fn test_userid() -> String {
let ts = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|value| value.as_millis())
.unwrap_or(0);
format!("test_userid_{ts}")
}
#[tokio::test]
async fn test_current_timestamp() {
let ts = utils::get_current_timestamp();
dbg!(&ts);
let ts = utils::add_second(ts, 3);
dbg!(&ts);
let now = chrono::Local::now();
println!("{}", now.format("%Y-%m-%d %H:%M:%S"));
let utc_ts = chrono::Utc::now().timestamp();
let local_time = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
println!("时间戳: {}", utc_ts);
println!("本地时间: {}", local_time);
}
}
use salvo::prelude::*;
mod commons;
mod db;
mod protocols;
mod router;
use commons::utils::CONFIG as config;
use db::init_db;
#[derive(rust_embed::RustEmbed)]
#[folder = "src/web"]
struct Assets;
#[tokio::main]
async fn main() {
if let Err(err) = init_db().await {
panic!("init db failed: {err}");
}
let router = Router::new().push(router::config_router()).push(
Router::with_path("/web/{**path}")
.get(salvo::serve_static::static_embed::<Assets>().fallback("index.html")),
);
let host = config.host.clone();
dbg!(&config);
println!("http://{}", host);
let service = Service::new(router).catcher(router::config_catcher());
let acceptor = TcpListener::new(host).bind().await;
Server::new(acceptor).serve(service).await;
}
use crate::commons::utils::{self};
use crate::db::models::manager::*;
use bytes::Bytes;
use dashmap::DashMap;
use dashmap::mapref::entry::Entry;
use salvo::prelude::*;
use serde_json::{Value, json};
use socketioxide::SocketIo;
use socketioxide::extract::{Data, SocketRef};
use socketioxide::socket::DisconnectReason;
use std::collections::HashMap;
lazy_static::lazy_static! {
static ref CLIENT_ADMIN_MAP: DashMap<String, SocketRef> = DashMap::new();
static ref CLIENT_PLAYER_MAP: DashMap<String, SocketRef> = DashMap::new();
static ref ROOM_STATE: std::sync::Mutex<RoomState> = std::sync::Mutex::new(RoomState::default());
}
const ROOM_RANKING_LIMIT: usize = 10;
#[derive(Clone, Default)]
struct RoomPlayer {
/// 成绩分数,具体含义由前端和游戏逻辑自行定义,后端只负责存储和排序。
score: i64,
/// 是否在线,离线的玩家不允许提交分数,但保留在排行榜里,等他重新上线时可以继续提交分数。
online: bool,
/// 玩家昵称
nickname: String,
/// 玩家联系方式
telephone: String,
/// 头像
avatar: String,
}
#[derive(Clone)]
struct RankingPlayer {
userid: String,
score: i64,
nickname: String,
telephone: String,
avatar: String,
}
#[derive(Default)]
struct RoomState {
accepting: bool, //是否接受玩家加入了
running: bool, //是否已经开始了
ended: bool, //是否已经结束了
countdown_secs: u64, //如果正在倒计时,这个字段表示还剩多少秒
started_at: u64, //游戏开始的时间点,结束后可以用这个字段来计算游戏总时长
ended_at: u64, //游戏结束的时间点
players: HashMap<String, RoomPlayer>, //玩家列表,key 是 userid,value 包含分数和在线状态
ranking: Vec<RankingPlayer>,
}
// 获取玩家数量,包含在线和离线的玩家, 不统计管理员
pub fn get_player_count() -> usize {
CLIENT_PLAYER_MAP.len()
}
// 获取管理员数量,包含在线和离线的管理员
pub fn get_admin_count() -> usize {
CLIENT_ADMIN_MAP.len()
}
pub fn emit_to_user(userid: &str, event: &str, payload: &Value) {
if userid.is_empty() {
return;
}
if let Some(socket) = CLIENT_PLAYER_MAP.get(userid) {
_ = socket.emit(event, payload);
}
}
pub fn broadcast_clients(event: &str, payload: &Value) {
for socket in CLIENT_PLAYER_MAP.iter() {
_ = socket.value().emit(event, payload);
}
}
fn valid_user(userid: &str, validuser: &str) -> bool {
let aes_passphrase = utils::get_aes_passphrase();
if aes_passphrase.is_none() {
return true; //没有配置 AES 密钥短语就不启用鉴权。
}
match utils::decrypt_cryptojs_aes(validuser, &aes_passphrase.unwrap_or_else(|| "".into())) {
Ok(u) => &u == userid,
Err(_) => false,
}
}
fn decode_msgpack(data: &Data<Bytes>) -> Result<Value, rmp_serde::decode::Error> {
rmp_serde::from_slice(data.0.as_ref())
}
fn encode_msgpack(value: &Value) -> Option<Bytes> {
rmp_serde::to_vec(value).ok().map(Bytes::from)
}
/// 回发给玩家
fn emit_msgpack(socket: &SocketRef, event: &str, payload: &Value) {
if let Some(payload) = encode_msgpack(payload) {
_ = socket.emit(event, &payload);
}
}
/// 发送给所有玩家(不包含管理员)
fn broadcast_msgpack_all_player(event: &str, payload: &Value) {
if let Some(payload) = encode_msgpack(payload) {
for socket in CLIENT_PLAYER_MAP.iter() {
_ = socket.value().emit(event, &payload);
}
}
}
/// 发送给所有管理员
fn broadcast_msgpack_all_admin(event: &str, payload: &Value) {
if let Some(payload) = encode_msgpack(payload) {
for socket in CLIENT_ADMIN_MAP.iter() {
_ = socket.value().emit(event, &payload);
}
}
}
/// 发送给所有管理员和玩家
fn broadcast_msgpack_all(event: &str, payload: &Value) {
if let Some(payload) = encode_msgpack(payload) {
for socket in CLIENT_PLAYER_MAP.iter() {
_ = socket.value().emit(event, &payload);
}
for socket in CLIENT_ADMIN_MAP.iter() {
_ = socket.value().emit(event, &payload);
}
}
}
fn ok_resp(data: Option<Value>) -> Value {
json!({
"state": 1,
"msg": "",
"data": data,
})
}
fn err_resp(msg: &str, data: Option<Value>) -> Value {
json!({
"state": 0,
"msg": msg,
"data": data,
})
}
// fn task_resp(data: Value) -> Value {
// if data.get("state").is_some() && data.get("msg").is_some() && data.get("data").is_some() {
// return data;
// }
// ok_resp(Some(data))
// }
// fn broadcast_all(from_userid: &str, data: &Value) -> Value {
// let payload = json!({
// "from": from_userid,
// "data": data.get("data").cloned().unwrap_or_else(|| json!({})),
// });
// broadcast_msgpack_all_player("broadcast", &ok_resp(payload));
// ok_resp(Some(json!({
// "event": "broadcast",
// "player_count": get_player_count(),
// })))
// }
fn ranking_from_player(userid: &str, player: &RoomPlayer) -> RankingPlayer {
RankingPlayer {
userid: userid.to_string(),
score: player.score,
nickname: player.nickname.clone(),
telephone: player.telephone.clone(),
avatar: player.avatar.clone(),
}
}
fn sort_room_ranking(ranking: &mut Vec<RankingPlayer>) {
ranking.sort_by(|a, b| b.score.cmp(&a.score).then_with(|| a.userid.cmp(&b.userid)));
ranking.truncate(ROOM_RANKING_LIMIT);
}
fn room_ranking_payload(ranking: &[RankingPlayer]) -> Vec<Value> {
ranking
.iter()
.map(|player| {
json!({
"userid": player.userid,
"score": player.score,
"nickname": player.nickname,
"telephone": player.telephone,
"avatar": player.avatar
})
})
.collect()
}
fn rebuild_room_ranking(state: &mut RoomState) -> Vec<Value> {
state.ranking = state
.players
.iter()
.map(|(userid, player)| ranking_from_player(userid, player))
.collect();
sort_room_ranking(&mut state.ranking);
room_ranking_payload(&state.ranking)
}
fn update_room_ranking(
state: &mut RoomState,
userid: &str,
old_score: i64,
new_score: i64,
) -> Option<Vec<Value>> {
let player = state.players.get(userid)?;
let ranking_player = ranking_from_player(userid, player);
if let Some(index) = state
.ranking
.iter()
.position(|player| player.userid == userid)
{
if new_score == old_score {
return None;
}
if new_score < old_score {
return Some(rebuild_room_ranking(state));
}
state.ranking[index] = ranking_player;
sort_room_ranking(&mut state.ranking);
return Some(room_ranking_payload(&state.ranking));
}
let can_enter_ranking = state.ranking.len() < ROOM_RANKING_LIMIT
|| state
.ranking
.last()
.map(|last_player| new_score >= last_player.score)
.unwrap_or(true);
if !can_enter_ranking {
return None;
}
state.ranking.push(ranking_player);
sort_room_ranking(&mut state.ranking);
if state.ranking.iter().any(|player| player.userid == userid) {
Some(room_ranking_payload(&state.ranking))
} else {
None
}
}
fn room_snapshot(state: &RoomState) -> Value {
json!({
"accepting": state.accepting,
"running": state.running,
"ended": state.ended,
"countdown_secs": state.countdown_secs,
"started_at": state.started_at,
"ended_at": state.ended_at,
"room_admin_count": get_admin_count(),
"room_player_count": get_player_count(),
})
}
fn current_room_snapshot() -> Value {
if let Ok(state) = ROOM_STATE.lock() {
let snapshot = room_snapshot(&state);
drop(state);
snapshot
} else {
json!({})
}
}
fn set_room_online(userid: &str, online: bool) {
if let Ok(mut state) = ROOM_STATE.lock() {
if let Some(player) = state.players.get_mut(userid) {
player.online = online;
}
drop(state);
}
}
// fn spawn_room_countdown(countdown_secs: u64) {
// tokio::spawn(async move {
// for _tick in (3..=countdown_secs).rev() {
// // broadcast_msgpack(
// // "room_game_tick",
// // &ok_resp(json!({
// // "left": left,
// // })),
// // );
// tokio::time::sleep(Duration::from_secs(1)).await;
// }
// // if let Some(payload) = finish_room_round("countdown_finished") {
// // // broadcast_msgpack_all_player("room_finished", &payload);
// // }
// });
// }
fn handle_room_command(socket: &SocketRef, userid: &str, is_admin: bool, cmd: &str, data: &Value) {
let evt = &format!("{cmd}_result");
match cmd {
"room_create" => {
// 只有管理员可以创建房间
if !is_admin {
return;
}
if let Ok(mut state) = ROOM_STATE.lock() {
if state.accepting && !state.ended {
drop(state);
emit_msgpack(&socket, evt, &err_resp("不能重复创建房间", None));
return;
}
state.accepting = true;
state.running = false;
state.ended = false;
state.countdown_secs = 0;
state.players.clear();
state.ranking.clear();
let snapshot = room_snapshot(&state);
drop(state);
// emit_msgpack(&socket, evt, &ok_resp(Some(snapshot)));
broadcast_msgpack_all_admin(evt, &ok_resp(Some(snapshot)));
}
}
"room_join" => {
// 玩家才能进入
if is_admin {
return;
}
let nickname = data.get("nickname").unwrap_or(&json!("")).to_string();
let telephone = data.get("telephone").unwrap_or(&json!("")).to_string();
let avatar = data.get("avatar").unwrap_or(&json!("")).to_string();
if let Ok(mut state) = ROOM_STATE.lock() {
let already_joined = state.players.contains_key(userid);
if !state.accepting && !already_joined {
drop(state);
emit_msgpack(&socket, evt, &err_resp("房间未开放", None));
return;
}
state
.players
.entry(userid.to_string())
.and_modify(|player| {
player.online = true;
})
.or_insert(RoomPlayer {
score: 0,
online: true,
nickname: nickname.to_string(),
telephone: telephone.to_string(),
avatar: avatar.to_string(),
});
let snapshot = room_snapshot(&state);
drop(state);
emit_msgpack(&socket, evt, &ok_resp(Some(snapshot.clone())));
//给所有管理员广播房间状态更新
broadcast_msgpack_all_admin(evt, &ok_resp(Some(snapshot)));
}
}
"game_start" => {
if !is_admin {
return;
}
let countdown_secs = data.as_i64().unwrap_or(3) as u64;
if let Ok(mut state) = ROOM_STATE.lock() {
if state.players.is_empty() {
drop(state);
emit_msgpack(&socket, evt, &err_resp("房间里没有玩家", None));
return;
}
if !state.accepting || state.ended {
drop(state);
emit_msgpack(&socket, evt, &err_resp("房间未开放", None));
return;
}
if state.running {
drop(state);
emit_msgpack(&socket, evt, &err_resp("房间已在运行中", None));
return;
}
state.countdown_secs = countdown_secs;
state.running = true;
state.started_at = utils::get_current_timestamp();
state.ended_at = utils::add_second(state.started_at, countdown_secs);
let snapshot = room_snapshot(&state);
drop(state);
broadcast_msgpack_all_player(evt, &ok_resp(Some(snapshot.clone())));
emit_msgpack(&socket, evt, &ok_resp(Some(snapshot)));
}
}
"submit_score" => {
if is_admin {
return;
}
let score = data.get("score").and_then(|v| v.as_i64()).unwrap_or(0);
let _time = data.get("time").and_then(|v| v.as_i64()).unwrap_or(0);
if let Ok(mut state) = ROOM_STATE.lock() {
if !state.players.contains_key(userid) {
drop(state);
emit_msgpack(&socket, evt, &err_resp("您不在房间中", None));
} else if !state.running {
drop(state);
emit_msgpack(&socket, evt, &err_resp("房间未开始", None));
} else if state.players.contains_key(userid) {
let old_score = {
let player = state.players.get_mut(userid).unwrap();
let old_score = player.score;
player.score = score;
player.online = true;
old_score
};
//玩家分数排序
let ranking = update_room_ranking(&mut state, userid, old_score, score);
drop(state);
emit_msgpack(&socket, evt, &ok_resp(None));
//将数据提交到数据库
if let Some(ranking) = ranking {
broadcast_msgpack_all_admin(evt, &ok_resp(Some(json!(ranking))));
}
} else {
drop(state);
emit_msgpack(&socket, evt, &err_resp("提交异常", None));
}
}
}
"submit_finish" => {
if !is_admin {
return;
}
//结束后要做排行,统计相关
}
"room_close" => {
if !is_admin {
return;
}
reset_room();
broadcast_msgpack_all_player(evt, &json!({}));
emit_msgpack(&socket, evt, &ok_resp(None));
}
"room_state" => {
emit_msgpack(&socket, evt, &ok_resp(Some(current_room_snapshot())));
}
_ => {
emit_msgpack(&socket, "unknow_cmd", &&err_resp("未知指令", None));
}
};
}
fn reset_room() {
if let Ok(mut state) = ROOM_STATE.lock() {
state.accepting = false;
state.running = false;
state.ended = false;
state.countdown_secs = 0;
state.players.clear();
state.ranking.clear();
drop(state);
}
}
pub async fn on_connect(_io: SocketIo, socket: SocketRef, Data(data): Data<Value>) {
let is_create_user = false;
let userid = data
.get("userid")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
// 鉴权失败直接断开连接,鉴权通过后才会在内存里记录这个连接。
if userid.is_empty() {
_ = socket.disconnect();
return;
}
let mut is_admin = false;
// 接入微信小程序不做验证,但只要传了 validuser 字段 且验证成功是管理员,
let validuser = data.get("validuser").and_then(|v| v.as_str()).unwrap_or("");
if !validuser.is_empty() {
if valid_user(&userid, validuser) {
is_admin = true;
} else {
// 传了 validuser 字段 但验证失败的直接断开连接
_ = socket.disconnect();
return;
}
}
// 原子检查 + 写入,避免并发下同一个 userid 同时登录。
if (is_admin) {
match CLIENT_ADMIN_MAP.entry(userid.clone()) {
Entry::Occupied(_) => {
_ = socket.disconnect();
return;
}
Entry::Vacant(entry) => {
entry.insert(socket.clone());
}
}
} else {
if CLIENT_ADMIN_MAP.is_empty() {
emit_msgpack(&socket, "connect_result", &err_resp("游戏未开放", None));
_ = socket.disconnect();
return;
}
match CLIENT_PLAYER_MAP.entry(userid.clone()) {
Entry::Occupied(_) => {
_ = socket.disconnect();
return;
}
Entry::Vacant(entry) => {
entry.insert(socket.clone());
set_room_online(&userid, true);
}
}
}
// dbg!(&is_admin,&userid);
// 鉴权通过后,在这里挂玩家消息事件处理器
let message_userid = userid.clone();
socket.on("message", move |socket: SocketRef, data: Data<Bytes>| {
let message_userid = message_userid.clone();
async move {
let data = match decode_msgpack(&data) {
Ok(data) => data,
Err(_err) => {
//dbg!("invalid_message", socket.id, err.to_string());
return;
}
};
/*
{"cmd": String("get_player"),"data": Object {"userid": String("u1")},}
*/
if let (Some(cmd), Some(data)) =
(data.get("cmd").and_then(|v| v.as_str()), data.get("data"))
{
handle_room_command(&socket, &message_userid, is_admin, cmd, &data);
// //转发给所有人,包含发送者自己。前端可以根据 event 和 from 字段来决定要不要处理这个消息。
// if cmd == "broadcast_all" {
// let resp = broadcast_all(&message_userid, &message);
// emit_msgpack(&socket, &format!("{cmd}_result"), &resp);
// return;
// }
// //(暂未测试)其他命令交给 worker_task 模块处理,前提是这个命令在 worker_task::has_task_handler 中有注册。
// if let Some((event, resp)) = worker_task::run_client_task(message).await {
// emit_msgpack(&socket, &event, &task_resp(resp));
// return;
// }
// emit_msgpack(&socket, "unknown_cmd", &err_resp("unknown_cmd", None));
}
}
});
socket.on_disconnect({
move |_socket: SocketRef, _reason: DisconnectReason| async move {
if !is_create_user {
if is_admin {
CLIENT_ADMIN_MAP.remove(&userid);
if CLIENT_ADMIN_MAP.is_empty() {
// 如果管理员都退出了,就把房间状态重置了。
reset_room();
}
} else {
CLIENT_PLAYER_MAP.remove(&userid);
// 有玩家退出时通知所有管理员
broadcast_msgpack_all_admin(
"room_state_result",
&ok_resp(Some(current_room_snapshot())),
);
}
}
}
});
}
#[handler]
pub async fn login(req: &mut Request, res: &mut Response) {
let params = match req.parse_body::<HashMap<String, String>>().await {
Ok(params) => params,
Err(_) => {
res.status_code(StatusCode::BAD_REQUEST);
res.render(Json(err_resp("参数格式错误", None)));
return;
}
};
let username = params
.get("username")
.map(|value| value.trim())
.unwrap_or_default();
let password = params
.get("password")
.map(|value| value.trim())
.unwrap_or_default();
if username.is_empty() || password.is_empty() {
res.status_code(StatusCode::BAD_REQUEST);
res.render(Json(err_resp("username和password不能为空", None)));
return;
}
let manager = match Manager::Login(ManagerLogin::unpw(
"admin".to_string(),
"123456".to_string(),
))
.await
{
Ok(manager) => manager,
Err(err) => {
res.status_code(StatusCode::UNAUTHORIZED);
res.render(Json(err_resp(&err, None)));
return;
}
};
let passphrase = utils::get_aes_passphrase();
if passphrase.is_none() {
res.status_code(StatusCode::BAD_REQUEST);
res.render(Json(err_resp("username和password不能为空", None)));
}
res.render(Json(ok_resp(Some(json!({
"passphrase":passphrase,
"token": manager.token
})))));
}
\ No newline at end of file
use crate::commons::utils::CONFIG as config;
use crate::protocols;
use salvo::catcher::Catcher;
use salvo::prelude::*;
use serde_json::json;
use socketioxide::SocketIo;
use tower::ServiceBuilder;
use tower_http::cors::CorsLayer;
pub fn config_router() -> Router {
let (layer, io) = SocketIo::new_layer();
let layer = ServiceBuilder::new()
.layer(CorsLayer::permissive())
.layer(layer);
let layer = layer.compat();
let mut r = Router::new().push(
Router::with_path(config.socket_path.as_str())
.hoop(layer)
.goal(hello),
);
io.ns(
config.client_ns.as_str(),
crate::protocols::socket_io::on_connect,
);
r = r.push(Router::with_path("/manager/login").post(crate::protocols::socket_io::login));
r
}
pub fn config_catcher() -> Catcher {
Catcher::default().hoop(rewrite_405_to_404)
}
#[handler]
async fn hello() -> &'static str {
""
}
// 将 405 Method Not Allowed 转换为 404 Not Found,并渲染统一的 404 页面。
#[handler]
async fn rewrite_405_to_404(
req: &mut Request,
depot: &mut Depot,
res: &mut Response,
ctrl: &mut FlowCtrl,
) {
if res.status_code == Some(StatusCode::METHOD_NOT_ALLOWED) {
res.status_code(StatusCode::NOT_FOUND);
}
if res.status_code == Some(StatusCode::NOT_FOUND) {
render_not_found(req, res);
ctrl.skip_rest();
return;
}
ctrl.call_next(req, depot, res).await;
}
// 根据请求的 Accept 头和 URL 路径,返回 JSON 格式的 404 错误信息,或者渲染一个简单的 HTML 404 页面。
fn render_not_found(req: &Request, res: &mut Response) {
let accept = req
.headers()
.get("accept")
.and_then(|value| value.to_str().ok())
.unwrap_or("");
let path = req.uri().path();
if path.starts_with("/api/") || accept.contains("application/json") {
res.render(Json(json!({
"code": 404,
"message": "resource not found",
"path": path,
})));
return;
}
res.render(Text::Html(
r#"<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>404 Not Found</title>
<style>
body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f6f7fb;color:#1f2937;font-family:sans-serif;}main{padding:32px;text-align:center;}h1{margin:0 0 12px;font-size:64px;}p{margin:0;font-size:16px;}
</style>
</head>
<body>
<main>
<h1>404</h1>
<p>页面不存在</p>
</main>
</body>
</html>"#,
));
}
!function(t,e){"object"==typeof exports?module.exports=exports=e():"function"==typeof define&&define.amd?define([],e):t.CryptoJS=e()}(this,function(){var W,O,I,U,K,X,L,l,j,T,t,N,q,e,Z,V,G,J,Q,Y,$,t1,e1,r1,i1,o1,n1,s,s1,c1,a1,h1,l1,o,f1,r,d1,u1,n,c,a,h,f,d,i=function(h){var i;if("undefined"!=typeof window&&window.crypto&&(i=window.crypto),"undefined"!=typeof self&&self.crypto&&(i=self.crypto),!(i=!(i=!(i="undefined"!=typeof globalThis&&globalThis.crypto?globalThis.crypto:i)&&"undefined"!=typeof window&&window.msCrypto?window.msCrypto:i)&&"undefined"!=typeof global&&global.crypto?global.crypto:i)&&"function"==typeof require)try{i=require("crypto")}catch(t){}var r=Object.create||function(t){return e.prototype=t,t=new e,e.prototype=null,t};function e(){}var t={},o=t.lib={},n=o.Base={extend:function(t){var e=r(this);return t&&e.mixIn(t),e.hasOwnProperty("init")&&this.init!==e.init||(e.init=function(){e.$super.init.apply(this,arguments)}),(e.init.prototype=e).$super=this,e},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}},l=o.WordArray=n.extend({init:function(t,e){t=this.words=t||[],this.sigBytes=null!=e?e:4*t.length},toString:function(t){return(t||c).stringify(this)},concat:function(t){var e=this.words,r=t.words,i=this.sigBytes,o=t.sigBytes;if(this.clamp(),i%4)for(var n=0;n<o;n++){var s=r[n>>>2]>>>24-n%4*8&255;e[i+n>>>2]|=s<<24-(i+n)%4*8}else for(var c=0;c<o;c+=4)e[i+c>>>2]=r[c>>>2];return this.sigBytes+=o,this},clamp:function(){var t=this.words,e=this.sigBytes;t[e>>>2]&=4294967295<<32-e%4*8,t.length=h.ceil(e/4)},clone:function(){var t=n.clone.call(this);return t.words=this.words.slice(0),t},random:function(t){for(var e=[],r=0;r<t;r+=4)e.push(function(){if(i){if("function"==typeof i.getRandomValues)try{return i.getRandomValues(new Uint32Array(1))[0]}catch(t){}if("function"==typeof i.randomBytes)try{return i.randomBytes(4).readInt32LE()}catch(t){}}throw new Error("Native crypto module could not be used to get secure random number.")}());return new l.init(e,t)}}),s=t.enc={},c=s.Hex={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],o=0;o<r;o++){var n=e[o>>>2]>>>24-o%4*8&255;i.push((n>>>4).toString(16)),i.push((15&n).toString(16))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i+=2)r[i>>>3]|=parseInt(t.substr(i,2),16)<<24-i%8*4;return new l.init(r,e/2)}},a=s.Latin1={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],o=0;o<r;o++){var n=e[o>>>2]>>>24-o%4*8&255;i.push(String.fromCharCode(n))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i++)r[i>>>2]|=(255&t.charCodeAt(i))<<24-i%4*8;return new l.init(r,e)}},f=s.Utf8={stringify:function(t){try{return decodeURIComponent(escape(a.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return a.parse(unescape(encodeURIComponent(t)))}},d=o.BufferedBlockAlgorithm=n.extend({reset:function(){this._data=new l.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=f.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(t){var e,r=this._data,i=r.words,o=r.sigBytes,n=this.blockSize,s=o/(4*n),c=(s=t?h.ceil(s):h.max((0|s)-this._minBufferSize,0))*n,t=h.min(4*c,o);if(c){for(var a=0;a<c;a+=n)this._doProcessBlock(i,a);e=i.splice(0,c),r.sigBytes-=t}return new l.init(e,t)},clone:function(){var t=n.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),u=(o.Hasher=d.extend({cfg:n.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){d.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){return t&&this._append(t),this._doFinalize()},blockSize:16,_createHelper:function(r){return function(t,e){return new r.init(e).finalize(t)}},_createHmacHelper:function(r){return function(t,e){return new u.HMAC.init(r,e).finalize(t)}}}),t.algo={});return t}(Math),u=(u=(p=i).lib,W=u.Base,O=u.WordArray,(u=p.x64={}).Word=W.extend({init:function(t,e){this.high=t,this.low=e}}),u.WordArray=W.extend({init:function(t,e){t=this.words=t||[],this.sigBytes=null!=e?e:8*t.length},toX32:function(){for(var t=this.words,e=t.length,r=[],i=0;i<e;i++){var o=t[i];r.push(o.high),r.push(o.low)}return O.create(r,this.sigBytes)},clone:function(){for(var t=W.clone.call(this),e=t.words=this.words.slice(0),r=e.length,i=0;i<r;i++)e[i]=e[i].clone();return t}}),"function"==typeof ArrayBuffer&&(p=i.lib.WordArray,I=p.init,(p.init=function(t){if((t=(t=t instanceof ArrayBuffer?new Uint8Array(t):t)instanceof Int8Array||"undefined"!=typeof Uint8ClampedArray&&t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):t)instanceof Uint8Array){for(var e=t.byteLength,r=[],i=0;i<e;i++)r[i>>>2]|=t[i]<<24-i%4*8;I.call(this,r,e)}else I.apply(this,arguments)}).prototype=p),i),p1=u.lib.WordArray;function _1(t){return t<<8&4278255360|t>>>8&16711935}(u=u.enc).Utf16=u.Utf16BE={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],o=0;o<r;o+=2){var n=e[o>>>2]>>>16-o%4*8&65535;i.push(String.fromCharCode(n))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i++)r[i>>>1]|=t.charCodeAt(i)<<16-i%2*16;return p1.create(r,2*e)}},u.Utf16LE={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],o=0;o<r;o+=2){var n=_1(e[o>>>2]>>>16-o%4*8&65535);i.push(String.fromCharCode(n))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i++)r[i>>>1]|=_1(t.charCodeAt(i)<<16-i%2*16);return p1.create(r,2*e)}},U=(p=i).lib.WordArray,p.enc.Base64={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=this._map,o=(t.clamp(),[]),n=0;n<r;n+=3)for(var s=(e[n>>>2]>>>24-n%4*8&255)<<16|(e[n+1>>>2]>>>24-(n+1)%4*8&255)<<8|e[n+2>>>2]>>>24-(n+2)%4*8&255,c=0;c<4&&n+.75*c<r;c++)o.push(i.charAt(s>>>6*(3-c)&63));var a=i.charAt(64);if(a)for(;o.length%4;)o.push(a);return o.join("")},parse:function(t){var e=t.length,r=this._map;if(!(i=this._reverseMap))for(var i=this._reverseMap=[],o=0;o<r.length;o++)i[r.charCodeAt(o)]=o;for(var n,s,c=r.charAt(64),a=(!c||-1!==(c=t.indexOf(c))&&(e=c),t),h=e,l=i,f=[],d=0,u=0;u<h;u++)u%4&&(s=l[a.charCodeAt(u-1)]<<u%4*2,n=l[a.charCodeAt(u)]>>>6-u%4*2,s=s|n,f[d>>>2]|=s<<24-d%4*8,d++);return U.create(f,d)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},K=(u=i).lib.WordArray,u.enc.Base64url={stringify:function(t,e){for(var r=t.words,i=t.sigBytes,o=(e=void 0===e?!0:e)?this._safe_map:this._map,n=(t.clamp(),[]),s=0;s<i;s+=3)for(var c=(r[s>>>2]>>>24-s%4*8&255)<<16|(r[s+1>>>2]>>>24-(s+1)%4*8&255)<<8|r[s+2>>>2]>>>24-(s+2)%4*8&255,a=0;a<4&&s+.75*a<i;a++)n.push(o.charAt(c>>>6*(3-a)&63));var h=o.charAt(64);if(h)for(;n.length%4;)n.push(h);return n.join("")},parse:function(t,e){var r=t.length,i=(e=void 0===e?!0:e)?this._safe_map:this._map;if(!(o=this._reverseMap))for(var o=this._reverseMap=[],n=0;n<i.length;n++)o[i.charCodeAt(n)]=n;for(var s,c,e=i.charAt(64),a=(!e||-1!==(e=t.indexOf(e))&&(r=e),t),h=r,l=o,f=[],d=0,u=0;u<h;u++)u%4&&(c=l[a.charCodeAt(u-1)]<<u%4*2,s=l[a.charCodeAt(u)]>>>6-u%4*2,c=c|s,f[d>>>2]|=c<<24-d%4*8,d++);return K.create(f,d)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",_safe_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"};for(var y1=Math,p=i,g1=(u=p.lib).WordArray,v1=u.Hasher,u=p.algo,A=[],B1=0;B1<64;B1++)A[B1]=4294967296*y1.abs(y1.sin(B1+1))|0;function z(t,e,r,i,o,n,s){t=t+(e&r|~e&i)+o+s;return(t<<n|t>>>32-n)+e}function H(t,e,r,i,o,n,s){t=t+(e&i|r&~i)+o+s;return(t<<n|t>>>32-n)+e}function C(t,e,r,i,o,n,s){t=t+(e^r^i)+o+s;return(t<<n|t>>>32-n)+e}function R(t,e,r,i,o,n,s){t=t+(r^(e|~i))+o+s;return(t<<n|t>>>32-n)+e}u=u.MD5=v1.extend({_doReset:function(){this._hash=new g1.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(t,e){for(var r=0;r<16;r++){var i=e+r,o=t[i];t[i]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}var n=this._hash.words,s=t[e+0],c=t[e+1],a=t[e+2],h=t[e+3],l=t[e+4],f=t[e+5],d=t[e+6],u=t[e+7],p=t[e+8],_=t[e+9],y=t[e+10],g=t[e+11],v=t[e+12],B=t[e+13],w=t[e+14],k=t[e+15],x=z(n[0],S=n[1],m=n[2],b=n[3],s,7,A[0]),b=z(b,x,S,m,c,12,A[1]),m=z(m,b,x,S,a,17,A[2]),S=z(S,m,b,x,h,22,A[3]);x=z(x,S,m,b,l,7,A[4]),b=z(b,x,S,m,f,12,A[5]),m=z(m,b,x,S,d,17,A[6]),S=z(S,m,b,x,u,22,A[7]),x=z(x,S,m,b,p,7,A[8]),b=z(b,x,S,m,_,12,A[9]),m=z(m,b,x,S,y,17,A[10]),S=z(S,m,b,x,g,22,A[11]),x=z(x,S,m,b,v,7,A[12]),b=z(b,x,S,m,B,12,A[13]),m=z(m,b,x,S,w,17,A[14]),x=H(x,S=z(S,m,b,x,k,22,A[15]),m,b,c,5,A[16]),b=H(b,x,S,m,d,9,A[17]),m=H(m,b,x,S,g,14,A[18]),S=H(S,m,b,x,s,20,A[19]),x=H(x,S,m,b,f,5,A[20]),b=H(b,x,S,m,y,9,A[21]),m=H(m,b,x,S,k,14,A[22]),S=H(S,m,b,x,l,20,A[23]),x=H(x,S,m,b,_,5,A[24]),b=H(b,x,S,m,w,9,A[25]),m=H(m,b,x,S,h,14,A[26]),S=H(S,m,b,x,p,20,A[27]),x=H(x,S,m,b,B,5,A[28]),b=H(b,x,S,m,a,9,A[29]),m=H(m,b,x,S,u,14,A[30]),x=C(x,S=H(S,m,b,x,v,20,A[31]),m,b,f,4,A[32]),b=C(b,x,S,m,p,11,A[33]),m=C(m,b,x,S,g,16,A[34]),S=C(S,m,b,x,w,23,A[35]),x=C(x,S,m,b,c,4,A[36]),b=C(b,x,S,m,l,11,A[37]),m=C(m,b,x,S,u,16,A[38]),S=C(S,m,b,x,y,23,A[39]),x=C(x,S,m,b,B,4,A[40]),b=C(b,x,S,m,s,11,A[41]),m=C(m,b,x,S,h,16,A[42]),S=C(S,m,b,x,d,23,A[43]),x=C(x,S,m,b,_,4,A[44]),b=C(b,x,S,m,v,11,A[45]),m=C(m,b,x,S,k,16,A[46]),x=R(x,S=C(S,m,b,x,a,23,A[47]),m,b,s,6,A[48]),b=R(b,x,S,m,u,10,A[49]),m=R(m,b,x,S,w,15,A[50]),S=R(S,m,b,x,f,21,A[51]),x=R(x,S,m,b,v,6,A[52]),b=R(b,x,S,m,h,10,A[53]),m=R(m,b,x,S,y,15,A[54]),S=R(S,m,b,x,c,21,A[55]),x=R(x,S,m,b,p,6,A[56]),b=R(b,x,S,m,k,10,A[57]),m=R(m,b,x,S,d,15,A[58]),S=R(S,m,b,x,B,21,A[59]),x=R(x,S,m,b,l,6,A[60]),b=R(b,x,S,m,g,10,A[61]),m=R(m,b,x,S,a,15,A[62]),S=R(S,m,b,x,_,21,A[63]),n[0]=n[0]+x|0,n[1]=n[1]+S|0,n[2]=n[2]+m|0,n[3]=n[3]+b|0},_doFinalize:function(){for(var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes,o=(e[i>>>5]|=128<<24-i%32,y1.floor(r/4294967296)),o=(e[15+(64+i>>>9<<4)]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),e[14+(64+i>>>9<<4)]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8),t.sigBytes=4*(e.length+1),this._process(),this._hash),n=o.words,s=0;s<4;s++){var c=n[s];n[s]=16711935&(c<<8|c>>>24)|4278255360&(c<<24|c>>>8)}return o},clone:function(){var t=v1.clone.call(this);return t._hash=this._hash.clone(),t}}),p.MD5=v1._createHelper(u),p.HmacMD5=v1._createHmacHelper(u),u=(p=i).lib,X=u.WordArray,L=u.Hasher,u=p.algo,l=[],u=u.SHA1=L.extend({_doReset:function(){this._hash=new X.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(t,e){for(var r=this._hash.words,i=r[0],o=r[1],n=r[2],s=r[3],c=r[4],a=0;a<80;a++){a<16?l[a]=0|t[e+a]:(h=l[a-3]^l[a-8]^l[a-14]^l[a-16],l[a]=h<<1|h>>>31);var h=(i<<5|i>>>27)+c+l[a];h+=a<20?1518500249+(o&n|~o&s):a<40?1859775393+(o^n^s):a<60?(o&n|o&s|n&s)-1894007588:(o^n^s)-899497514,c=s,s=n,n=o<<30|o>>>2,o=i,i=h}r[0]=r[0]+i|0,r[1]=r[1]+o|0,r[2]=r[2]+n|0,r[3]=r[3]+s|0,r[4]=r[4]+c|0},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[14+(64+i>>>9<<4)]=Math.floor(r/4294967296),e[15+(64+i>>>9<<4)]=r,t.sigBytes=4*e.length,this._process(),this._hash},clone:function(){var t=L.clone.call(this);return t._hash=this._hash.clone(),t}}),p.SHA1=L._createHelper(u),p.HmacSHA1=L._createHmacHelper(u);var w1=Math,p=i,k1=(u=p.lib).WordArray,x1=u.Hasher,u=p.algo,b1=[],m1=[];function S1(t){return 4294967296*(t-(0|t))|0}for(var A1=2,z1=0;z1<64;)!function(t){for(var e=w1.sqrt(t),r=2;r<=e;r++)if(!(t%r))return;return 1}(A1)||(z1<8&&(b1[z1]=S1(w1.pow(A1,.5))),m1[z1]=S1(w1.pow(A1,1/3)),z1++),A1++;var _=[],u=u.SHA256=x1.extend({_doReset:function(){this._hash=new k1.init(b1.slice(0))},_doProcessBlock:function(t,e){for(var r=this._hash.words,i=r[0],o=r[1],n=r[2],s=r[3],c=r[4],a=r[5],h=r[6],l=r[7],f=0;f<64;f++){f<16?_[f]=0|t[e+f]:(d=_[f-15],u=_[f-2],_[f]=((d<<25|d>>>7)^(d<<14|d>>>18)^d>>>3)+_[f-7]+((u<<15|u>>>17)^(u<<13|u>>>19)^u>>>10)+_[f-16]);var d=i&o^i&n^o&n,u=l+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&a^~c&h)+m1[f]+_[f],l=h,h=a,a=c,c=s+u|0,s=n,n=o,o=i,i=u+(((i<<30|i>>>2)^(i<<19|i>>>13)^(i<<10|i>>>22))+d)|0}r[0]=r[0]+i|0,r[1]=r[1]+o|0,r[2]=r[2]+n|0,r[3]=r[3]+s|0,r[4]=r[4]+c|0,r[5]=r[5]+a|0,r[6]=r[6]+h|0,r[7]=r[7]+l|0},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[14+(64+i>>>9<<4)]=w1.floor(r/4294967296),e[15+(64+i>>>9<<4)]=r,t.sigBytes=4*e.length,this._process(),this._hash},clone:function(){var t=x1.clone.call(this);return t._hash=this._hash.clone(),t}}),p=(p.SHA256=x1._createHelper(u),p.HmacSHA256=x1._createHmacHelper(u),j=(p=i).lib.WordArray,u=p.algo,T=u.SHA256,u=u.SHA224=T.extend({_doReset:function(){this._hash=new j.init([3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428])},_doFinalize:function(){var t=T._doFinalize.call(this);return t.sigBytes-=4,t}}),p.SHA224=T._createHelper(u),p.HmacSHA224=T._createHmacHelper(u),i),H1=p.lib.Hasher,y=(u=p.x64).Word,C1=u.WordArray,u=p.algo;function g(){return y.create.apply(y,arguments)}for(var R1=[g(1116352408,3609767458),g(1899447441,602891725),g(3049323471,3964484399),g(3921009573,2173295548),g(961987163,4081628472),g(1508970993,3053834265),g(2453635748,2937671579),g(2870763221,3664609560),g(3624381080,2734883394),g(310598401,1164996542),g(607225278,1323610764),g(1426881987,3590304994),g(1925078388,4068182383),g(2162078206,991336113),g(2614888103,633803317),g(3248222580,3479774868),g(3835390401,2666613458),g(4022224774,944711139),g(264347078,2341262773),g(604807628,2007800933),g(770255983,1495990901),g(1249150122,1856431235),g(1555081692,3175218132),g(1996064986,2198950837),g(2554220882,3999719339),g(2821834349,766784016),g(2952996808,2566594879),g(3210313671,3203337956),g(3336571891,1034457026),g(3584528711,2466948901),g(113926993,3758326383),g(338241895,168717936),g(666307205,1188179964),g(773529912,1546045734),g(1294757372,1522805485),g(1396182291,2643833823),g(1695183700,2343527390),g(1986661051,1014477480),g(2177026350,1206759142),g(2456956037,344077627),g(2730485921,1290863460),g(2820302411,3158454273),g(3259730800,3505952657),g(3345764771,106217008),g(3516065817,3606008344),g(3600352804,1432725776),g(4094571909,1467031594),g(275423344,851169720),g(430227734,3100823752),g(506948616,1363258195),g(659060556,3750685593),g(883997877,3785050280),g(958139571,3318307427),g(1322822218,3812723403),g(1537002063,2003034995),g(1747873779,3602036899),g(1955562222,1575990012),g(2024104815,1125592928),g(2227730452,2716904306),g(2361852424,442776044),g(2428436474,593698344),g(2756734187,3733110249),g(3204031479,2999351573),g(3329325298,3815920427),g(3391569614,3928383900),g(3515267271,566280711),g(3940187606,3454069534),g(4118630271,4000239992),g(116418474,1914138554),g(174292421,2731055270),g(289380356,3203993006),g(460393269,320620315),g(685471733,587496836),g(852142971,1086792851),g(1017036298,365543100),g(1126000580,2618297676),g(1288033470,3409855158),g(1501505948,4234509866),g(1607167915,987167468),g(1816402316,1246189591)],D1=[],E1=0;E1<80;E1++)D1[E1]=g();u=u.SHA512=H1.extend({_doReset:function(){this._hash=new C1.init([new y.init(1779033703,4089235720),new y.init(3144134277,2227873595),new y.init(1013904242,4271175723),new y.init(2773480762,1595750129),new y.init(1359893119,2917565137),new y.init(2600822924,725511199),new y.init(528734635,4215389547),new y.init(1541459225,327033209)])},_doProcessBlock:function(W,O){for(var t=this._hash.words,e=t[0],r=t[1],i=t[2],o=t[3],n=t[4],s=t[5],c=t[6],t=t[7],I=e.high,a=e.low,U=r.high,h=r.low,K=i.high,l=i.low,X=o.high,f=o.low,L=n.high,d=n.low,j=s.high,u=s.low,T=c.high,p=c.low,N=t.high,_=t.low,y=I,g=a,v=U,B=h,w=K,k=l,q=X,x=f,b=L,m=d,Z=j,S=u,V=T,G=p,J=N,Q=_,A=0;A<80;A++)var z,H,C=D1[A],R=(A<16?(H=C.high=0|W[O+2*A],z=C.low=0|W[O+2*A+1]):(F=(P=D1[A-15]).high,P=P.low,M=(E=D1[A-2]).high,E=E.low,D=(R=D1[A-7]).high,R=R.low,$=(Y=D1[A-16]).high,H=(H=((F>>>1|P<<31)^(F>>>8|P<<24)^F>>>7)+D+((z=(D=(P>>>1|F<<31)^(P>>>8|F<<24)^(P>>>7|F<<25))+R)>>>0<D>>>0?1:0))+((M>>>19|E<<13)^(M<<3|E>>>29)^M>>>6)+((z+=P=(E>>>19|M<<13)^(E<<3|M>>>29)^(E>>>6|M<<26))>>>0<P>>>0?1:0),z+=F=Y.low,C.high=H=H+$+(z>>>0<F>>>0?1:0),C.low=z),b&Z^~b&V),D=m&S^~m&G,E=y&v^y&w^v&w,M=(g>>>28|y<<4)^(g<<30|y>>>2)^(g<<25|y>>>7),P=R1[A],Y=P.high,$=P.low,F=Q+((m>>>14|b<<18)^(m>>>18|b<<14)^(m<<23|b>>>9)),C=J+((b>>>14|m<<18)^(b>>>18|m<<14)^(b<<23|m>>>9))+(F>>>0<Q>>>0?1:0),t1=M+(g&B^g&k^B&k),J=V,Q=G,V=Z,G=S,Z=b,S=m,b=q+(C=C+R+((F=F+D)>>>0<D>>>0?1:0)+Y+((F=F+$)>>>0<$>>>0?1:0)+H+((F=F+z)>>>0<z>>>0?1:0))+((m=x+F|0)>>>0<x>>>0?1:0)|0,q=w,x=k,w=v,k=B,v=y,B=g,y=C+(((y>>>28|g<<4)^(y<<30|g>>>2)^(y<<25|g>>>7))+E+(t1>>>0<M>>>0?1:0))+((g=F+t1|0)>>>0<F>>>0?1:0)|0;a=e.low=a+g,e.high=I+y+(a>>>0<g>>>0?1:0),h=r.low=h+B,r.high=U+v+(h>>>0<B>>>0?1:0),l=i.low=l+k,i.high=K+w+(l>>>0<k>>>0?1:0),f=o.low=f+x,o.high=X+q+(f>>>0<x>>>0?1:0),d=n.low=d+m,n.high=L+b+(d>>>0<m>>>0?1:0),u=s.low=u+S,s.high=j+Z+(u>>>0<S>>>0?1:0),p=c.low=p+G,c.high=T+V+(p>>>0<G>>>0?1:0),_=t.low=_+Q,t.high=N+J+(_>>>0<Q>>>0?1:0)},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[30+(128+i>>>10<<5)]=Math.floor(r/4294967296),e[31+(128+i>>>10<<5)]=r,t.sigBytes=4*e.length,this._process(),this._hash.toX32()},clone:function(){var t=H1.clone.call(this);return t._hash=this._hash.clone(),t},blockSize:32}),p.SHA512=H1._createHelper(u),p.HmacSHA512=H1._createHmacHelper(u),u=(p=i).x64,t=u.Word,N=u.WordArray,u=p.algo,q=u.SHA512,u=u.SHA384=q.extend({_doReset:function(){this._hash=new N.init([new t.init(3418070365,3238371032),new t.init(1654270250,914150663),new t.init(2438529370,812702999),new t.init(355462360,4144912697),new t.init(1731405415,4290775857),new t.init(2394180231,1750603025),new t.init(3675008525,1694076839),new t.init(1203062813,3204075428)])},_doFinalize:function(){var t=q._doFinalize.call(this);return t.sigBytes-=16,t}}),p.SHA384=q._createHelper(u),p.HmacSHA384=q._createHmacHelper(u);for(var M1=Math,p=i,P1=(u=p.lib).WordArray,F1=u.Hasher,W1=p.x64.Word,u=p.algo,O1=[],I1=[],U1=[],v=1,B=0,K1=0;K1<24;K1++){O1[v+5*B]=(K1+1)*(K1+2)/2%64;var X1=(2*v+3*B)%5;v=B%5,B=X1}for(v=0;v<5;v++)for(B=0;B<5;B++)I1[v+5*B]=B+(2*v+3*B)%5*5;for(var L1=1,j1=0;j1<24;j1++){for(var T1,N1=0,q1=0,Z1=0;Z1<7;Z1++)1&L1&&((T1=(1<<Z1)-1)<32?q1^=1<<T1:N1^=1<<T1-32),128&L1?L1=L1<<1^113:L1<<=1;U1[j1]=W1.create(N1,q1)}for(var D=[],V1=0;V1<25;V1++)D[V1]=W1.create();function G1(t,e,r){return t&e|~t&r}function J1(t,e,r){return t&r|e&~r}function Q1(t,e){return t<<e|t>>>32-e}function Y1(t){return"string"==typeof t?f1:o}function $1(t,e,r){var i,o=this._iv;o?(i=o,this._iv=void 0):i=this._prevBlock;for(var n=0;n<r;n++)t[e+n]^=i[n]}function t2(t,e,r,i){var o,n=this._iv;n?(o=n.slice(0),this._iv=void 0):o=this._prevBlock,i.encryptBlock(o,0);for(var s=0;s<r;s++)t[e+s]^=o[s]}function e2(t){var e,r,i;return 255==(t>>24&255)?(r=t>>8&255,i=255&t,255===(e=t>>16&255)?(e=0,255===r?(r=0,255===i?i=0:++i):++r):++e,t=0,t=(t+=e<<16)+(r<<8)+i):t+=1<<24,t}u=u.SHA3=F1.extend({cfg:F1.cfg.extend({outputLength:512}),_doReset:function(){for(var t=this._state=[],e=0;e<25;e++)t[e]=new W1.init;this.blockSize=(1600-2*this.cfg.outputLength)/32},_doProcessBlock:function(t,e){for(var r=this._state,i=this.blockSize/2,o=0;o<i;o++){var n=t[e+2*o],s=t[e+2*o+1],n=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8);(x=r[o]).high^=16711935&(s<<8|s>>>24)|4278255360&(s<<24|s>>>8),x.low^=n}for(var c=0;c<24;c++){for(var a=0;a<5;a++){for(var h=0,l=0,f=0;f<5;f++)h^=(x=r[a+5*f]).high,l^=x.low;var d=D[a];d.high=h,d.low=l}for(a=0;a<5;a++)for(var u=D[(a+4)%5],p=D[(a+1)%5],_=p.high,p=p.low,h=u.high^(_<<1|p>>>31),l=u.low^(p<<1|_>>>31),f=0;f<5;f++)(x=r[a+5*f]).high^=h,x.low^=l;for(var y=1;y<25;y++){var g=(x=r[y]).high,v=x.low,B=O1[y],g=(l=B<32?(h=g<<B|v>>>32-B,v<<B|g>>>32-B):(h=v<<B-32|g>>>64-B,g<<B-32|v>>>64-B),D[I1[y]]);g.high=h,g.low=l}var w=D[0],k=r[0];w.high=k.high,w.low=k.low;for(a=0;a<5;a++)for(f=0;f<5;f++){var x=r[y=a+5*f],b=D[y],m=D[(a+1)%5+5*f],S=D[(a+2)%5+5*f];x.high=b.high^~m.high&S.high,x.low=b.low^~m.low&S.low}x=r[0],w=U1[c];x.high^=w.high,x.low^=w.low}},_doFinalize:function(){for(var t=this._data,e=t.words,r=(this._nDataBytes,8*t.sigBytes),i=32*this.blockSize,o=(e[r>>>5]|=1<<24-r%32,e[(M1.ceil((1+r)/i)*i>>>5)-1]|=128,t.sigBytes=4*e.length,this._process(),this._state),r=this.cfg.outputLength/8,n=r/8,s=[],c=0;c<n;c++){var a=o[c],h=a.high,a=a.low,h=16711935&(h<<8|h>>>24)|4278255360&(h<<24|h>>>8);s.push(16711935&(a<<8|a>>>24)|4278255360&(a<<24|a>>>8)),s.push(h)}return new P1.init(s,r)},clone:function(){for(var t=F1.clone.call(this),e=t._state=this._state.slice(0),r=0;r<25;r++)e[r]=e[r].clone();return t}}),p.SHA3=F1._createHelper(u),p.HmacSHA3=F1._createHmacHelper(u),Math,u=(p=i).lib,e=u.WordArray,Z=u.Hasher,u=p.algo,V=e.create([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13]),G=e.create([5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]),J=e.create([11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]),Q=e.create([8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]),Y=e.create([0,1518500249,1859775393,2400959708,2840853838]),$=e.create([1352829926,1548603684,1836072691,2053994217,0]),u=u.RIPEMD160=Z.extend({_doReset:function(){this._hash=e.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(t,e){for(var r=0;r<16;r++){var i=e+r,o=t[i];t[i]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}for(var n,s,c,a,h,l,f=this._hash.words,d=Y.words,u=$.words,p=V.words,_=G.words,y=J.words,g=Q.words,v=n=f[0],B=s=f[1],w=c=f[2],k=a=f[3],x=h=f[4],r=0;r<80;r+=1)l=(l=Q1(l=(l=n+t[e+p[r]]|0)+(r<16?(s^c^a)+d[0]:r<32?G1(s,c,a)+d[1]:r<48?((s|~c)^a)+d[2]:r<64?J1(s,c,a)+d[3]:(s^(c|~a))+d[4])|0,y[r]))+h|0,n=h,h=a,a=Q1(c,10),c=s,s=l,l=(l=Q1(l=(l=v+t[e+_[r]]|0)+(r<16?(B^(w|~k))+u[0]:r<32?J1(B,w,k)+u[1]:r<48?((B|~w)^k)+u[2]:r<64?G1(B,w,k)+u[3]:(B^w^k)+u[4])|0,g[r]))+x|0,v=x,x=k,k=Q1(w,10),w=B,B=l;l=f[1]+c+k|0,f[1]=f[2]+a+x|0,f[2]=f[3]+h+v|0,f[3]=f[4]+n+B|0,f[4]=f[0]+s+w|0,f[0]=l},_doFinalize:function(){for(var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes,i=(e[i>>>5]|=128<<24-i%32,e[14+(64+i>>>9<<4)]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8),t.sigBytes=4*(e.length+1),this._process(),this._hash),o=i.words,n=0;n<5;n++){var s=o[n];o[n]=16711935&(s<<8|s>>>24)|4278255360&(s<<24|s>>>8)}return i},clone:function(){var t=Z.clone.call(this);return t._hash=this._hash.clone(),t}}),p.RIPEMD160=Z._createHelper(u),p.HmacRIPEMD160=Z._createHmacHelper(u),u=(p=i).lib.Base,t1=p.enc.Utf8,p.algo.HMAC=u.extend({init:function(t,e){t=this._hasher=new t.init,"string"==typeof e&&(e=t1.parse(e));for(var r=t.blockSize,i=4*r,t=((e=e.sigBytes>i?t.finalize(e):e).clamp(),this._oKey=e.clone()),e=this._iKey=e.clone(),o=t.words,n=e.words,s=0;s<r;s++)o[s]^=1549556828,n[s]^=909522486;t.sigBytes=e.sigBytes=i,this.reset()},reset:function(){var t=this._hasher;t.reset(),t.update(this._iKey)},update:function(t){return this._hasher.update(t),this},finalize:function(t){var e=this._hasher,t=e.finalize(t);return e.reset(),e.finalize(this._oKey.clone().concat(t))}}),u=(p=i).lib,w=u.Base,e1=u.WordArray,u=p.algo,P=u.SHA256,r1=u.HMAC,i1=u.PBKDF2=w.extend({cfg:w.extend({keySize:4,hasher:P,iterations:25e4}),init:function(t){this.cfg=this.cfg.extend(t)},compute:function(t,e){for(var r=this.cfg,i=r1.create(r.hasher,t),o=e1.create(),n=e1.create([1]),s=o.words,c=n.words,a=r.keySize,h=r.iterations;s.length<a;){for(var l=i.update(e).finalize(n),f=(i.reset(),l.words),d=f.length,u=l,p=1;p<h;p++){u=i.finalize(u),i.reset();for(var _=u.words,y=0;y<d;y++)f[y]^=_[y]}o.concat(l),c[0]++}return o.sigBytes=4*a,o}}),p.PBKDF2=function(t,e,r){return i1.create(r).compute(t,e)},w=(u=i).lib,P=w.Base,o1=w.WordArray,w=u.algo,p=w.MD5,n1=w.EvpKDF=P.extend({cfg:P.extend({keySize:4,hasher:p,iterations:1}),init:function(t){this.cfg=this.cfg.extend(t)},compute:function(t,e){for(var r,i=this.cfg,o=i.hasher.create(),n=o1.create(),s=n.words,c=i.keySize,a=i.iterations;s.length<c;){r&&o.update(r),r=o.update(t).finalize(e),o.reset();for(var h=1;h<a;h++)r=o.finalize(r),o.reset();n.concat(r)}return n.sigBytes=4*c,n}}),u.EvpKDF=function(t,e,r){return n1.create(r).compute(t,e)},i.lib.Cipher||(P=(w=i).lib,p=P.Base,s=P.WordArray,s1=P.BufferedBlockAlgorithm,(u=w.enc).Utf8,c1=u.Base64,a1=w.algo.EvpKDF,h1=P.Cipher=s1.extend({cfg:p.extend(),createEncryptor:function(t,e){return this.create(this._ENC_XFORM_MODE,t,e)},createDecryptor:function(t,e){return this.create(this._DEC_XFORM_MODE,t,e)},init:function(t,e,r){this.cfg=this.cfg.extend(r),this._xformMode=t,this._key=e,this.reset()},reset:function(){s1.reset.call(this),this._doReset()},process:function(t){return this._append(t),this._process()},finalize:function(t){return t&&this._append(t),this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(i){return{encrypt:function(t,e,r){return Y1(e).encrypt(i,t,e,r)},decrypt:function(t,e,r){return Y1(e).decrypt(i,t,e,r)}}}}),P.StreamCipher=h1.extend({_doFinalize:function(){return this._process(!0)},blockSize:1}),u=w.mode={},r=P.BlockCipherMode=p.extend({createEncryptor:function(t,e){return this.Encryptor.create(t,e)},createDecryptor:function(t,e){return this.Decryptor.create(t,e)},init:function(t,e){this._cipher=t,this._iv=e}}),r=u.CBC=((u=r.extend()).Encryptor=u.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize;$1.call(this,t,e,i),r.encryptBlock(t,e),this._prevBlock=t.slice(e,e+i)}}),u.Decryptor=u.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,o=t.slice(e,e+i);r.decryptBlock(t,e),$1.call(this,t,e,i),this._prevBlock=o}}),u),u=(w.pad={}).Pkcs7={pad:function(t,e){for(var e=4*e,r=e-t.sigBytes%e,i=r<<24|r<<16|r<<8|r,o=[],n=0;n<r;n+=4)o.push(i);e=s.create(o,r);t.concat(e)},unpad:function(t){var e=255&t.words[t.sigBytes-1>>>2];t.sigBytes-=e}},P.BlockCipher=h1.extend({cfg:h1.cfg.extend({mode:r,padding:u}),reset:function(){h1.reset.call(this);var t,e=this.cfg,r=e.iv,e=e.mode;this._xformMode==this._ENC_XFORM_MODE?t=e.createEncryptor:(t=e.createDecryptor,this._minBufferSize=1),this._mode&&this._mode.__creator==t?this._mode.init(this,r&&r.words):(this._mode=t.call(e,this,r&&r.words),this._mode.__creator=t)},_doProcessBlock:function(t,e){this._mode.processBlock(t,e)},_doFinalize:function(){var t,e=this.cfg.padding;return this._xformMode==this._ENC_XFORM_MODE?(e.pad(this._data,this.blockSize),t=this._process(!0)):(t=this._process(!0),e.unpad(t)),t},blockSize:4}),l1=P.CipherParams=p.extend({init:function(t){this.mixIn(t)},toString:function(t){return(t||this.formatter).stringify(this)}}),r=(w.format={}).OpenSSL={stringify:function(t){var e=t.ciphertext,t=t.salt,t=t?s.create([1398893684,1701076831]).concat(t).concat(e):e;return t.toString(c1)},parse:function(t){var e,t=c1.parse(t),r=t.words;return 1398893684==r[0]&&1701076831==r[1]&&(e=s.create(r.slice(2,4)),r.splice(0,4),t.sigBytes-=16),l1.create({ciphertext:t,salt:e})}},o=P.SerializableCipher=p.extend({cfg:p.extend({format:r}),encrypt:function(t,e,r,i){i=this.cfg.extend(i);var o=t.createEncryptor(r,i),e=o.finalize(e),o=o.cfg;return l1.create({ciphertext:e,key:r,iv:o.iv,algorithm:t,mode:o.mode,padding:o.padding,blockSize:t.blockSize,formatter:i.format})},decrypt:function(t,e,r,i){return i=this.cfg.extend(i),e=this._parse(e,i.format),t.createDecryptor(r,i).finalize(e.ciphertext)},_parse:function(t,e){return"string"==typeof t?e.parse(t,this):t}}),u=(w.kdf={}).OpenSSL={execute:function(t,e,r,i,o){i=i||s.random(8),o=(o?a1.create({keySize:e+r,hasher:o}):a1.create({keySize:e+r})).compute(t,i);t=s.create(o.words.slice(e),4*r);return o.sigBytes=4*e,l1.create({key:o,iv:t,salt:i})}},f1=P.PasswordBasedCipher=o.extend({cfg:o.cfg.extend({kdf:u}),encrypt:function(t,e,r,i){r=(i=this.cfg.extend(i)).kdf.execute(r,t.keySize,t.ivSize,i.salt,i.hasher),i.iv=r.iv,t=o.encrypt.call(this,t,e,r.key,i);return t.mixIn(r),t},decrypt:function(t,e,r,i){i=this.cfg.extend(i),e=this._parse(e,i.format);r=i.kdf.execute(r,t.keySize,t.ivSize,e.salt,i.hasher);return i.iv=r.iv,o.decrypt.call(this,t,e,r.key,i)}})),i.mode.CFB=((p=i.lib.BlockCipherMode.extend()).Encryptor=p.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize;t2.call(this,t,e,i,r),this._prevBlock=t.slice(e,e+i)}}),p.Decryptor=p.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,o=t.slice(e,e+i);t2.call(this,t,e,i,r),this._prevBlock=o}}),p),i.mode.CTR=(r=i.lib.BlockCipherMode.extend(),w=r.Encryptor=r.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,o=this._iv,n=this._counter,s=(o&&(n=this._counter=o.slice(0),this._iv=void 0),n.slice(0));r.encryptBlock(s,0),n[i-1]=n[i-1]+1|0;for(var c=0;c<i;c++)t[e+c]^=s[c]}}),r.Decryptor=w,r),i.mode.CTRGladman=(P=i.lib.BlockCipherMode.extend(),u=P.Encryptor=P.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,o=this._iv,n=this._counter,s=(o&&(n=this._counter=o.slice(0),this._iv=void 0),0===((o=n)[0]=e2(o[0]))&&(o[1]=e2(o[1])),n.slice(0));r.encryptBlock(s,0);for(var c=0;c<i;c++)t[e+c]^=s[c]}}),P.Decryptor=u,P),i.mode.OFB=(p=i.lib.BlockCipherMode.extend(),w=p.Encryptor=p.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,o=this._iv,n=this._keystream;o&&(n=this._keystream=o.slice(0),this._iv=void 0),r.encryptBlock(n,0);for(var s=0;s<i;s++)t[e+s]^=n[s]}}),p.Decryptor=w,p),i.mode.ECB=((u=i.lib.BlockCipherMode.extend()).Encryptor=u.extend({processBlock:function(t,e){this._cipher.encryptBlock(t,e)}}),u.Decryptor=u.extend({processBlock:function(t,e){this._cipher.decryptBlock(t,e)}}),u),i.pad.AnsiX923={pad:function(t,e){var r=t.sigBytes,e=4*e,e=e-r%e,r=r+e-1;t.clamp(),t.words[r>>>2]|=e<<24-r%4*8,t.sigBytes+=e},unpad:function(t){var e=255&t.words[t.sigBytes-1>>>2];t.sigBytes-=e}},i.pad.Iso10126={pad:function(t,e){e*=4,e-=t.sigBytes%e;t.concat(i.lib.WordArray.random(e-1)).concat(i.lib.WordArray.create([e<<24],1))},unpad:function(t){var e=255&t.words[t.sigBytes-1>>>2];t.sigBytes-=e}},i.pad.Iso97971={pad:function(t,e){t.concat(i.lib.WordArray.create([2147483648],1)),i.pad.ZeroPadding.pad(t,e)},unpad:function(t){i.pad.ZeroPadding.unpad(t),t.sigBytes--}},i.pad.ZeroPadding={pad:function(t,e){e*=4;t.clamp(),t.sigBytes+=e-(t.sigBytes%e||e)},unpad:function(t){for(var e=t.words,r=t.sigBytes-1,r=t.sigBytes-1;0<=r;r--)if(e[r>>>2]>>>24-r%4*8&255){t.sigBytes=r+1;break}}},i.pad.NoPadding={pad:function(){},unpad:function(){}},d1=(P=i).lib.CipherParams,u1=P.enc.Hex,P.format.Hex={stringify:function(t){return t.ciphertext.toString(u1)},parse:function(t){t=u1.parse(t);return d1.create({ciphertext:t})}};for(var w=i,p=w.lib.BlockCipher,u=w.algo,k=[],r2=[],i2=[],o2=[],n2=[],s2=[],c2=[],a2=[],h2=[],l2=[],x=[],b=0;b<256;b++)x[b]=b<128?b<<1:b<<1^283;for(var m=0,S=0,b=0;b<256;b++){var E=S^S<<1^S<<2^S<<3^S<<4,f2=(k[m]=E=E>>>8^255&E^99,x[r2[E]=m]),d2=x[f2],u2=x[d2],M=257*x[E]^16843008*E;i2[m]=M<<24|M>>>8,o2[m]=M<<16|M>>>16,n2[m]=M<<8|M>>>24,s2[m]=M,c2[E]=(M=16843009*u2^65537*d2^257*f2^16843008*m)<<24|M>>>8,a2[E]=M<<16|M>>>16,h2[E]=M<<8|M>>>24,l2[E]=M,m?(m=f2^x[x[x[u2^f2]]],S^=x[x[S]]):m=S=1}var p2=[0,1,2,4,8,16,32,64,128,27,54],u=u.AES=p.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var t=this._keyPriorReset=this._key,e=t.words,r=t.sigBytes/4,i=4*(1+(this._nRounds=6+r)),o=this._keySchedule=[],n=0;n<i;n++)n<r?o[n]=e[n]:(a=o[n-1],n%r?6<r&&n%r==4&&(a=k[a>>>24]<<24|k[a>>>16&255]<<16|k[a>>>8&255]<<8|k[255&a]):(a=k[(a=a<<8|a>>>24)>>>24]<<24|k[a>>>16&255]<<16|k[a>>>8&255]<<8|k[255&a],a^=p2[n/r|0]<<24),o[n]=o[n-r]^a);for(var s=this._invKeySchedule=[],c=0;c<i;c++){var a,n=i-c;a=c%4?o[n]:o[n-4],s[c]=c<4||n<=4?a:c2[k[a>>>24]]^a2[k[a>>>16&255]]^h2[k[a>>>8&255]]^l2[k[255&a]]}}},encryptBlock:function(t,e){this._doCryptBlock(t,e,this._keySchedule,i2,o2,n2,s2,k)},decryptBlock:function(t,e){var r=t[e+1],r=(t[e+1]=t[e+3],t[e+3]=r,this._doCryptBlock(t,e,this._invKeySchedule,c2,a2,h2,l2,r2),t[e+1]);t[e+1]=t[e+3],t[e+3]=r},_doCryptBlock:function(t,e,r,i,o,n,s,c){for(var a=this._nRounds,h=t[e]^r[0],l=t[e+1]^r[1],f=t[e+2]^r[2],d=t[e+3]^r[3],u=4,p=1;p<a;p++)var _=i[h>>>24]^o[l>>>16&255]^n[f>>>8&255]^s[255&d]^r[u++],y=i[l>>>24]^o[f>>>16&255]^n[d>>>8&255]^s[255&h]^r[u++],g=i[f>>>24]^o[d>>>16&255]^n[h>>>8&255]^s[255&l]^r[u++],v=i[d>>>24]^o[h>>>16&255]^n[l>>>8&255]^s[255&f]^r[u++],h=_,l=y,f=g,d=v;_=(c[h>>>24]<<24|c[l>>>16&255]<<16|c[f>>>8&255]<<8|c[255&d])^r[u++],y=(c[l>>>24]<<24|c[f>>>16&255]<<16|c[d>>>8&255]<<8|c[255&h])^r[u++],g=(c[f>>>24]<<24|c[d>>>16&255]<<16|c[h>>>8&255]<<8|c[255&l])^r[u++],v=(c[d>>>24]<<24|c[h>>>16&255]<<16|c[l>>>8&255]<<8|c[255&f])^r[u++];t[e]=_,t[e+1]=y,t[e+2]=g,t[e+3]=v},keySize:8}),P=(w.AES=p._createHelper(u),i),_2=(w=P.lib).WordArray,w=w.BlockCipher,p=P.algo,y2=[57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4],g2=[14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32],v2=[1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28],B2=[{0:8421888,268435456:32768,536870912:8421378,805306368:2,1073741824:512,1342177280:8421890,1610612736:8389122,1879048192:8388608,2147483648:514,2415919104:8389120,2684354560:33280,2952790016:8421376,3221225472:32770,3489660928:8388610,3758096384:0,4026531840:33282,134217728:0,402653184:8421890,671088640:33282,939524096:32768,1207959552:8421888,1476395008:512,1744830464:8421378,2013265920:2,2281701376:8389120,2550136832:33280,2818572288:8421376,3087007744:8389122,3355443200:8388610,3623878656:32770,3892314112:514,4160749568:8388608,1:32768,268435457:2,536870913:8421888,805306369:8388608,1073741825:8421378,1342177281:33280,1610612737:512,1879048193:8389122,2147483649:8421890,2415919105:8421376,2684354561:8388610,2952790017:33282,3221225473:514,3489660929:8389120,3758096385:32770,4026531841:0,134217729:8421890,402653185:8421376,671088641:8388608,939524097:512,1207959553:32768,1476395009:8388610,1744830465:2,2013265921:33282,2281701377:32770,2550136833:8389122,2818572289:514,3087007745:8421888,3355443201:8389120,3623878657:0,3892314113:33280,4160749569:8421378},{0:1074282512,16777216:16384,33554432:524288,50331648:1074266128,67108864:1073741840,83886080:1074282496,100663296:1073758208,117440512:16,134217728:540672,150994944:1073758224,167772160:1073741824,184549376:540688,201326592:524304,218103808:0,234881024:16400,251658240:1074266112,8388608:1073758208,25165824:540688,41943040:16,58720256:1073758224,75497472:1074282512,92274688:1073741824,109051904:524288,125829120:1074266128,142606336:524304,159383552:0,176160768:16384,192937984:1074266112,209715200:1073741840,226492416:540672,243269632:1074282496,260046848:16400,268435456:0,285212672:1074266128,301989888:1073758224,318767104:1074282496,335544320:1074266112,352321536:16,369098752:540688,385875968:16384,402653184:16400,419430400:524288,436207616:524304,452984832:1073741840,469762048:540672,486539264:1073758208,503316480:1073741824,520093696:1074282512,276824064:540688,293601280:524288,310378496:1074266112,327155712:16384,343932928:1073758208,360710144:1074282512,377487360:16,394264576:1073741824,411041792:1074282496,427819008:1073741840,444596224:1073758224,461373440:524304,478150656:0,494927872:16400,511705088:1074266128,528482304:540672},{0:260,1048576:0,2097152:67109120,3145728:65796,4194304:65540,5242880:67108868,6291456:67174660,7340032:67174400,8388608:67108864,9437184:67174656,10485760:65792,11534336:67174404,12582912:67109124,13631488:65536,14680064:4,15728640:256,524288:67174656,1572864:67174404,2621440:0,3670016:67109120,4718592:67108868,5767168:65536,6815744:65540,7864320:260,8912896:4,9961472:256,11010048:67174400,12058624:65796,13107200:65792,14155776:67109124,15204352:67174660,16252928:67108864,16777216:67174656,17825792:65540,18874368:65536,19922944:67109120,20971520:256,22020096:67174660,23068672:67108868,24117248:0,25165824:67109124,26214400:67108864,27262976:4,28311552:65792,29360128:67174400,30408704:260,31457280:65796,32505856:67174404,17301504:67108864,18350080:260,19398656:67174656,20447232:0,21495808:65540,22544384:67109120,23592960:256,24641536:67174404,25690112:65536,26738688:67174660,27787264:65796,28835840:67108868,29884416:67109124,30932992:67174400,31981568:4,33030144:65792},{0:2151682048,65536:2147487808,131072:4198464,196608:2151677952,262144:0,327680:4198400,393216:2147483712,458752:4194368,524288:2147483648,589824:4194304,655360:64,720896:2147487744,786432:2151678016,851968:4160,917504:4096,983040:2151682112,32768:2147487808,98304:64,163840:2151678016,229376:2147487744,294912:4198400,360448:2151682112,425984:0,491520:2151677952,557056:4096,622592:2151682048,688128:4194304,753664:4160,819200:2147483648,884736:4194368,950272:4198464,1015808:2147483712,1048576:4194368,1114112:4198400,1179648:2147483712,1245184:0,1310720:4160,1376256:2151678016,1441792:2151682048,1507328:2147487808,1572864:2151682112,1638400:2147483648,1703936:2151677952,1769472:4198464,1835008:2147487744,1900544:4194304,1966080:64,2031616:4096,1081344:2151677952,1146880:2151682112,1212416:0,1277952:4198400,1343488:4194368,1409024:2147483648,1474560:2147487808,1540096:64,1605632:2147483712,1671168:4096,1736704:2147487744,1802240:2151678016,1867776:4160,1933312:2151682048,1998848:4194304,2064384:4198464},{0:128,4096:17039360,8192:262144,12288:536870912,16384:537133184,20480:16777344,24576:553648256,28672:262272,32768:16777216,36864:537133056,40960:536871040,45056:553910400,49152:553910272,53248:0,57344:17039488,61440:553648128,2048:17039488,6144:553648256,10240:128,14336:17039360,18432:262144,22528:537133184,26624:553910272,30720:536870912,34816:537133056,38912:0,43008:553910400,47104:16777344,51200:536871040,55296:553648128,59392:16777216,63488:262272,65536:262144,69632:128,73728:536870912,77824:553648256,81920:16777344,86016:553910272,90112:537133184,94208:16777216,98304:553910400,102400:553648128,106496:17039360,110592:537133056,114688:262272,118784:536871040,122880:0,126976:17039488,67584:553648256,71680:16777216,75776:17039360,79872:537133184,83968:536870912,88064:17039488,92160:128,96256:553910272,100352:262272,104448:553910400,108544:0,112640:553648128,116736:16777344,120832:262144,124928:537133056,129024:536871040},{0:268435464,256:8192,512:270532608,768:270540808,1024:268443648,1280:2097152,1536:2097160,1792:268435456,2048:0,2304:268443656,2560:2105344,2816:8,3072:270532616,3328:2105352,3584:8200,3840:270540800,128:270532608,384:270540808,640:8,896:2097152,1152:2105352,1408:268435464,1664:268443648,1920:8200,2176:2097160,2432:8192,2688:268443656,2944:270532616,3200:0,3456:270540800,3712:2105344,3968:268435456,4096:268443648,4352:270532616,4608:270540808,4864:8200,5120:2097152,5376:268435456,5632:268435464,5888:2105344,6144:2105352,6400:0,6656:8,6912:270532608,7168:8192,7424:268443656,7680:270540800,7936:2097160,4224:8,4480:2105344,4736:2097152,4992:268435464,5248:268443648,5504:8200,5760:270540808,6016:270532608,6272:270540800,6528:270532616,6784:8192,7040:2105352,7296:2097160,7552:0,7808:268435456,8064:268443656},{0:1048576,16:33555457,32:1024,48:1049601,64:34604033,80:0,96:1,112:34603009,128:33555456,144:1048577,160:33554433,176:34604032,192:34603008,208:1025,224:1049600,240:33554432,8:34603009,24:0,40:33555457,56:34604032,72:1048576,88:33554433,104:33554432,120:1025,136:1049601,152:33555456,168:34603008,184:1048577,200:1024,216:34604033,232:1,248:1049600,256:33554432,272:1048576,288:33555457,304:34603009,320:1048577,336:33555456,352:34604032,368:1049601,384:1025,400:34604033,416:1049600,432:1,448:0,464:34603008,480:33554433,496:1024,264:1049600,280:33555457,296:34603009,312:1,328:33554432,344:1048576,360:1025,376:34604032,392:33554433,408:34603008,424:0,440:34604033,456:1049601,472:1024,488:33555456,504:1048577},{0:134219808,1:131072,2:134217728,3:32,4:131104,5:134350880,6:134350848,7:2048,8:134348800,9:134219776,10:133120,11:134348832,12:2080,13:0,14:134217760,15:133152,2147483648:2048,2147483649:134350880,2147483650:134219808,2147483651:134217728,2147483652:134348800,2147483653:133120,2147483654:133152,2147483655:32,2147483656:134217760,2147483657:2080,2147483658:131104,2147483659:134350848,2147483660:0,2147483661:134348832,2147483662:134219776,2147483663:131072,16:133152,17:134350848,18:32,19:2048,20:134219776,21:134217760,22:134348832,23:131072,24:0,25:131104,26:134348800,27:134219808,28:134350880,29:133120,30:2080,31:134217728,2147483664:131072,2147483665:2048,2147483666:134348832,2147483667:133152,2147483668:32,2147483669:134348800,2147483670:134217728,2147483671:134219808,2147483672:134350880,2147483673:134217760,2147483674:134219776,2147483675:0,2147483676:133120,2147483677:2080,2147483678:131104,2147483679:134350848}],w2=[4160749569,528482304,33030144,2064384,129024,8064,504,2147483679],k2=p.DES=w.extend({_doReset:function(){for(var t=this._key.words,e=[],r=0;r<56;r++){var i=y2[r]-1;e[r]=t[i>>>5]>>>31-i%32&1}for(var o=this._subKeys=[],n=0;n<16;n++){for(var s=o[n]=[],c=v2[n],r=0;r<24;r++)s[r/6|0]|=e[(g2[r]-1+c)%28]<<31-r%6,s[4+(r/6|0)]|=e[28+(g2[r+24]-1+c)%28]<<31-r%6;s[0]=s[0]<<1|s[0]>>>31;for(r=1;r<7;r++)s[r]=s[r]>>>4*(r-1)+3;s[7]=s[7]<<5|s[7]>>>27}for(var a=this._invSubKeys=[],r=0;r<16;r++)a[r]=o[15-r]},encryptBlock:function(t,e){this._doCryptBlock(t,e,this._subKeys)},decryptBlock:function(t,e){this._doCryptBlock(t,e,this._invSubKeys)},_doCryptBlock:function(t,e,r){this._lBlock=t[e],this._rBlock=t[e+1],x2.call(this,4,252645135),x2.call(this,16,65535),b2.call(this,2,858993459),b2.call(this,8,16711935),x2.call(this,1,1431655765);for(var i=0;i<16;i++){for(var o=r[i],n=this._lBlock,s=this._rBlock,c=0,a=0;a<8;a++)c|=B2[a][((s^o[a])&w2[a])>>>0];this._lBlock=s,this._rBlock=n^c}var h=this._lBlock;this._lBlock=this._rBlock,this._rBlock=h,x2.call(this,1,1431655765),b2.call(this,8,16711935),b2.call(this,2,858993459),x2.call(this,16,65535),x2.call(this,4,252645135),t[e]=this._lBlock,t[e+1]=this._rBlock},keySize:2,ivSize:2,blockSize:2});function x2(t,e){e=(this._lBlock>>>t^this._rBlock)&e;this._rBlock^=e,this._lBlock^=e<<t}function b2(t,e){e=(this._rBlock>>>t^this._lBlock)&e;this._lBlock^=e,this._rBlock^=e<<t}P.DES=w._createHelper(k2),p=p.TripleDES=w.extend({_doReset:function(){var t=this._key.words;if(2!==t.length&&4!==t.length&&t.length<6)throw new Error("Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.");var e=t.slice(0,2),r=t.length<4?t.slice(0,2):t.slice(2,4),t=t.length<6?t.slice(0,2):t.slice(4,6);this._des1=k2.createEncryptor(_2.create(e)),this._des2=k2.createEncryptor(_2.create(r)),this._des3=k2.createEncryptor(_2.create(t))},encryptBlock:function(t,e){this._des1.encryptBlock(t,e),this._des2.decryptBlock(t,e),this._des3.encryptBlock(t,e)},decryptBlock:function(t,e){this._des3.decryptBlock(t,e),this._des2.encryptBlock(t,e),this._des1.decryptBlock(t,e)},keySize:6,ivSize:2,blockSize:2}),P.TripleDES=w._createHelper(p);var u=i,P=u.lib.StreamCipher,w=u.algo,m2=w.RC4=P.extend({_doReset:function(){for(var t=this._key,e=t.words,r=t.sigBytes,i=this._S=[],o=0;o<256;o++)i[o]=o;for(var o=0,n=0;o<256;o++){var s=o%r,s=e[s>>>2]>>>24-s%4*8&255,n=(n+i[o]+s)%256,s=i[o];i[o]=i[n],i[n]=s}this._i=this._j=0},_doProcessBlock:function(t,e){t[e]^=S2.call(this)},keySize:8,ivSize:0});function S2(){for(var t=this._S,e=this._i,r=this._j,i=0,o=0;o<4;o++){var r=(r+t[e=(e+1)%256])%256,n=t[e];t[e]=t[r],t[r]=n,i|=t[(t[e]+t[r])%256]<<24-8*o}return this._i=e,this._j=r,i}function A2(){for(var t=this._X,e=this._C,r=0;r<8;r++)c[r]=e[r];e[0]=e[0]+1295307597+this._b|0,e[1]=e[1]+3545052371+(e[0]>>>0<c[0]>>>0?1:0)|0,e[2]=e[2]+886263092+(e[1]>>>0<c[1]>>>0?1:0)|0,e[3]=e[3]+1295307597+(e[2]>>>0<c[2]>>>0?1:0)|0,e[4]=e[4]+3545052371+(e[3]>>>0<c[3]>>>0?1:0)|0,e[5]=e[5]+886263092+(e[4]>>>0<c[4]>>>0?1:0)|0,e[6]=e[6]+1295307597+(e[5]>>>0<c[5]>>>0?1:0)|0,e[7]=e[7]+3545052371+(e[6]>>>0<c[6]>>>0?1:0)|0,this._b=e[7]>>>0<c[7]>>>0?1:0;for(r=0;r<8;r++){var i=t[r]+e[r],o=65535&i,n=i>>>16;a[r]=((o*o>>>17)+o*n>>>15)+n*n^((4294901760&i)*i|0)+((65535&i)*i|0)}t[0]=a[0]+(a[7]<<16|a[7]>>>16)+(a[6]<<16|a[6]>>>16)|0,t[1]=a[1]+(a[0]<<8|a[0]>>>24)+a[7]|0,t[2]=a[2]+(a[1]<<16|a[1]>>>16)+(a[0]<<16|a[0]>>>16)|0,t[3]=a[3]+(a[2]<<8|a[2]>>>24)+a[1]|0,t[4]=a[4]+(a[3]<<16|a[3]>>>16)+(a[2]<<16|a[2]>>>16)|0,t[5]=a[5]+(a[4]<<8|a[4]>>>24)+a[3]|0,t[6]=a[6]+(a[5]<<16|a[5]>>>16)+(a[4]<<16|a[4]>>>16)|0,t[7]=a[7]+(a[6]<<8|a[6]>>>24)+a[5]|0}function z2(){for(var t=this._X,e=this._C,r=0;r<8;r++)f[r]=e[r];e[0]=e[0]+1295307597+this._b|0,e[1]=e[1]+3545052371+(e[0]>>>0<f[0]>>>0?1:0)|0,e[2]=e[2]+886263092+(e[1]>>>0<f[1]>>>0?1:0)|0,e[3]=e[3]+1295307597+(e[2]>>>0<f[2]>>>0?1:0)|0,e[4]=e[4]+3545052371+(e[3]>>>0<f[3]>>>0?1:0)|0,e[5]=e[5]+886263092+(e[4]>>>0<f[4]>>>0?1:0)|0,e[6]=e[6]+1295307597+(e[5]>>>0<f[5]>>>0?1:0)|0,e[7]=e[7]+3545052371+(e[6]>>>0<f[6]>>>0?1:0)|0,this._b=e[7]>>>0<f[7]>>>0?1:0;for(r=0;r<8;r++){var i=t[r]+e[r],o=65535&i,n=i>>>16;d[r]=((o*o>>>17)+o*n>>>15)+n*n^((4294901760&i)*i|0)+((65535&i)*i|0)}t[0]=d[0]+(d[7]<<16|d[7]>>>16)+(d[6]<<16|d[6]>>>16)|0,t[1]=d[1]+(d[0]<<8|d[0]>>>24)+d[7]|0,t[2]=d[2]+(d[1]<<16|d[1]>>>16)+(d[0]<<16|d[0]>>>16)|0,t[3]=d[3]+(d[2]<<8|d[2]>>>24)+d[1]|0,t[4]=d[4]+(d[3]<<16|d[3]>>>16)+(d[2]<<16|d[2]>>>16)|0,t[5]=d[5]+(d[4]<<8|d[4]>>>24)+d[3]|0,t[6]=d[6]+(d[5]<<16|d[5]>>>16)+(d[4]<<16|d[4]>>>16)|0,t[7]=d[7]+(d[6]<<8|d[6]>>>24)+d[5]|0}u.RC4=P._createHelper(m2),w=w.RC4Drop=m2.extend({cfg:m2.cfg.extend({drop:192}),_doReset:function(){m2._doReset.call(this);for(var t=this.cfg.drop;0<t;t--)S2.call(this)}}),u.RC4Drop=P._createHelper(w),u=(p=i).lib.StreamCipher,P=p.algo,n=[],c=[],a=[],P=P.Rabbit=u.extend({_doReset:function(){for(var t=this._key.words,e=this.cfg.iv,r=0;r<4;r++)t[r]=16711935&(t[r]<<8|t[r]>>>24)|4278255360&(t[r]<<24|t[r]>>>8);for(var i=this._X=[t[0],t[3]<<16|t[2]>>>16,t[1],t[0]<<16|t[3]>>>16,t[2],t[1]<<16|t[0]>>>16,t[3],t[2]<<16|t[1]>>>16],o=this._C=[t[2]<<16|t[2]>>>16,4294901760&t[0]|65535&t[1],t[3]<<16|t[3]>>>16,4294901760&t[1]|65535&t[2],t[0]<<16|t[0]>>>16,4294901760&t[2]|65535&t[3],t[1]<<16|t[1]>>>16,4294901760&t[3]|65535&t[0]],r=this._b=0;r<4;r++)A2.call(this);for(r=0;r<8;r++)o[r]^=i[r+4&7];if(e){var e=e.words,n=e[0],e=e[1],n=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),e=16711935&(e<<8|e>>>24)|4278255360&(e<<24|e>>>8),s=n>>>16|4294901760&e,c=e<<16|65535&n;o[0]^=n,o[1]^=s,o[2]^=e,o[3]^=c,o[4]^=n,o[5]^=s,o[6]^=e,o[7]^=c;for(r=0;r<4;r++)A2.call(this)}},_doProcessBlock:function(t,e){var r=this._X;A2.call(this),n[0]=r[0]^r[5]>>>16^r[3]<<16,n[1]=r[2]^r[7]>>>16^r[5]<<16,n[2]=r[4]^r[1]>>>16^r[7]<<16,n[3]=r[6]^r[3]>>>16^r[1]<<16;for(var i=0;i<4;i++)n[i]=16711935&(n[i]<<8|n[i]>>>24)|4278255360&(n[i]<<24|n[i]>>>8),t[e+i]^=n[i]},blockSize:4,ivSize:2}),p.Rabbit=u._createHelper(P),p=(w=i).lib.StreamCipher,u=w.algo,h=[],f=[],d=[],u=u.RabbitLegacy=p.extend({_doReset:function(){for(var t=this._key.words,e=this.cfg.iv,r=this._X=[t[0],t[3]<<16|t[2]>>>16,t[1],t[0]<<16|t[3]>>>16,t[2],t[1]<<16|t[0]>>>16,t[3],t[2]<<16|t[1]>>>16],i=this._C=[t[2]<<16|t[2]>>>16,4294901760&t[0]|65535&t[1],t[3]<<16|t[3]>>>16,4294901760&t[1]|65535&t[2],t[0]<<16|t[0]>>>16,4294901760&t[2]|65535&t[3],t[1]<<16|t[1]>>>16,4294901760&t[3]|65535&t[0]],o=this._b=0;o<4;o++)z2.call(this);for(o=0;o<8;o++)i[o]^=r[o+4&7];if(e){var t=e.words,e=t[0],t=t[1],e=16711935&(e<<8|e>>>24)|4278255360&(e<<24|e>>>8),t=16711935&(t<<8|t>>>24)|4278255360&(t<<24|t>>>8),n=e>>>16|4294901760&t,s=t<<16|65535&e;i[0]^=e,i[1]^=n,i[2]^=t,i[3]^=s,i[4]^=e,i[5]^=n,i[6]^=t,i[7]^=s;for(o=0;o<4;o++)z2.call(this)}},_doProcessBlock:function(t,e){var r=this._X;z2.call(this),h[0]=r[0]^r[5]>>>16^r[3]<<16,h[1]=r[2]^r[7]>>>16^r[5]<<16,h[2]=r[4]^r[1]>>>16^r[7]<<16,h[3]=r[6]^r[3]>>>16^r[1]<<16;for(var i=0;i<4;i++)h[i]=16711935&(h[i]<<8|h[i]>>>24)|4278255360&(h[i]<<24|h[i]>>>8),t[e+i]^=h[i]},blockSize:4,ivSize:2}),w.RabbitLegacy=p._createHelper(u);{w=(P=i).lib.BlockCipher,p=P.algo;const F=16,D2=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],E2=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]];var H2={pbox:[],sbox:[]};function C2(t,e){var r=t.sbox[0][e>>24&255]+t.sbox[1][e>>16&255];return r=(r^=t.sbox[2][e>>8&255])+t.sbox[3][255&e]}function R2(e,t,r){let i=t,o=r,n;for(let t=0;t<F;++t)i^=e.pbox[t],o=C2(e,i)^o,n=i,i=o,o=n;return n=i,i=o,o=n,o^=e.pbox[F],{left:i^=e.pbox[F+1],right:o}}p=p.Blowfish=w.extend({_doReset:function(){if(this._keyPriorReset!==this._key){var t=this._keyPriorReset=this._key,n=t.words,t=t.sigBytes/4;{var s=H2,c=n,a=t;for(let e=0;e<4;e++){s.sbox[e]=[];for(let t=0;t<256;t++)s.sbox[e][t]=E2[e][t]}let e=0;for(let t=0;t<F+2;t++)s.pbox[t]=D2[t]^c[e],++e>=a&&(e=0);let r=0,i=0,o=0;for(let t=0;t<F+2;t+=2)o=R2(s,r,i),r=o.left,i=o.right,s.pbox[t]=r,s.pbox[t+1]=i;for(let e=0;e<4;e++)for(let t=0;t<256;t+=2)o=R2(s,r,i),r=o.left,i=o.right,s.sbox[e][t]=r,s.sbox[e][t+1]=i}}},encryptBlock:function(t,e){var r=R2(H2,t[e],t[e+1]);t[e]=r.left,t[e+1]=r.right},decryptBlock:function(t,e){var r=function(e,t,r){let i=t,o=r,n;for(let t=F+1;1<t;--t)i^=e.pbox[t],o=C2(e,i)^o,n=i,i=o,o=n;return n=i,i=o,o=n,o^=e.pbox[1],{left:i^=e.pbox[0],right:o}}(H2,t[e],t[e+1]);t[e]=r.left,t[e+1]=r.right},blockSize:2,keySize:4,ivSize:2}),P.Blowfish=w._createHelper(p)}return i});
\ No newline at end of file
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.MessagePack=t():e.MessagePack=t()}(this,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var s in i)e.o(i,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{DecodeError:()=>o,Decoder:()=>D,EXT_TIMESTAMP:()=>d,Encoder:()=>b,ExtData:()=>r,ExtensionCodec:()=>m,decode:()=>F,decodeArrayStream:()=>j,decodeAsync:()=>$,decodeMulti:()=>C,decodeMultiStream:()=>R,decodeTimestampExtension:()=>g,decodeTimestampToTimeSpec:()=>p,encode:()=>B,encodeDateToTimeSpec:()=>y,encodeTimeSpecToTimestamp:()=>u,encodeTimestampExtension:()=>w});const i=new TextEncoder;function s(e,t,i){let s=t;const n=s+i,r=[];let o="";for(;s<n;){const t=e[s++];if(128&t)if(192==(224&t)){const i=63&e[s++];r.push((31&t)<<6|i)}else if(224==(240&t)){const i=63&e[s++],n=63&e[s++];r.push((31&t)<<12|i<<6|n)}else if(240==(248&t)){let i=(7&t)<<18|(63&e[s++])<<12|(63&e[s++])<<6|63&e[s++];i>65535&&(i-=65536,r.push(i>>>10&1023|55296),i=56320|1023&i),r.push(i)}else r.push(t);else r.push(t);r.length>=4096&&(o+=String.fromCharCode(...r),r.length=0)}return r.length>0&&(o+=String.fromCharCode(...r)),o}const n=new TextDecoder;class r{constructor(e,t){this.type=e,this.data=t}}class o extends Error{constructor(e){super(e);const t=Object.create(o.prototype);Object.setPrototypeOf(this,t),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:o.name})}}const h=4294967295;function a(e,t,i){const s=Math.floor(i/4294967296),n=i;e.setUint32(t,s),e.setUint32(t+4,n)}function c(e,t){return 4294967296*e.getInt32(t)+e.getUint32(t+4)}const d=-1,f=4294967295,l=17179869183;function u({sec:e,nsec:t}){if(e>=0&&t>=0&&e<=l){if(0===t&&e<=f){const t=new Uint8Array(4);return new DataView(t.buffer).setUint32(0,e),t}{const i=e/4294967296,s=4294967295&e,n=new Uint8Array(8),r=new DataView(n.buffer);return r.setUint32(0,t<<2|3&i),r.setUint32(4,s),n}}{const i=new Uint8Array(12),s=new DataView(i.buffer);return s.setUint32(0,t),a(s,4,e),i}}function y(e){const t=e.getTime(),i=Math.floor(t/1e3),s=1e6*(t-1e3*i),n=Math.floor(s/1e9);return{sec:i+n,nsec:s-1e9*n}}function w(e){return e instanceof Date?u(y(e)):null}function p(e){const t=new DataView(e.buffer,e.byteOffset,e.byteLength);switch(e.byteLength){case 4:return{sec:t.getUint32(0),nsec:0};case 8:{const e=t.getUint32(0);return{sec:4294967296*(3&e)+t.getUint32(4),nsec:e>>>2}}case 12:return{sec:c(t,4),nsec:t.getUint32(0)};default:throw new o(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${e.length}`)}}function g(e){const t=p(e);return new Date(1e3*t.sec+t.nsec/1e6)}const U={type:d,encode:w,decode:g};class m{constructor(){this.builtInEncoders=[],this.builtInDecoders=[],this.encoders=[],this.decoders=[],this.register(U)}register({type:e,encode:t,decode:i}){if(e>=0)this.encoders[e]=t,this.decoders[e]=i;else{const s=-1-e;this.builtInEncoders[s]=t,this.builtInDecoders[s]=i}}tryToEncode(e,t){for(let i=0;i<this.builtInEncoders.length;i++){const s=this.builtInEncoders[i];if(null!=s){const n=s(e,t);if(null!=n)return new r(-1-i,n)}}for(let i=0;i<this.encoders.length;i++){const s=this.encoders[i];if(null!=s){const n=s(e,t);if(null!=n)return new r(i,n)}}return e instanceof r?e:null}decode(e,t,i){const s=t<0?this.builtInDecoders[-1-t]:this.decoders[t];return s?s(e,t,i):new r(t,e)}}function x(e){return e instanceof Uint8Array?e:ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):function(e){return e instanceof ArrayBuffer||"undefined"!=typeof SharedArrayBuffer&&e instanceof SharedArrayBuffer}(e)?new Uint8Array(e):Uint8Array.from(e)}m.defaultCodec=new m;class b{constructor(e){this.entered=!1,this.extensionCodec=e?.extensionCodec??m.defaultCodec,this.context=e?.context,this.useBigInt64=e?.useBigInt64??!1,this.maxDepth=e?.maxDepth??100,this.initialBufferSize=e?.initialBufferSize??2048,this.sortKeys=e?.sortKeys??!1,this.forceFloat32=e?.forceFloat32??!1,this.ignoreUndefined=e?.ignoreUndefined??!1,this.forceIntegerToFloat=e?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new b({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(e){if(this.entered)return this.clone().encodeSharedRef(e);try{return this.entered=!0,this.reinitializeState(),this.doEncode(e,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(e){if(this.entered)return this.clone().encode(e);try{return this.entered=!0,this.reinitializeState(),this.doEncode(e,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(e,t){if(t>this.maxDepth)throw new Error(`Too deep objects in depth ${t}`);null==e?this.encodeNil():"boolean"==typeof e?this.encodeBoolean(e):"number"==typeof e?this.forceIntegerToFloat?this.encodeNumberAsFloat(e):this.encodeNumber(e):"string"==typeof e?this.encodeString(e):this.useBigInt64&&"bigint"==typeof e?this.encodeBigInt64(e):this.encodeObject(e,t)}ensureBufferSizeToWrite(e){const t=this.pos+e;this.view.byteLength<t&&this.resizeBuffer(2*t)}resizeBuffer(e){const t=new ArrayBuffer(e),i=new Uint8Array(t),s=new DataView(t);i.set(this.bytes),this.view=s,this.bytes=i}encodeNil(){this.writeU8(192)}encodeBoolean(e){!1===e?this.writeU8(194):this.writeU8(195)}encodeNumber(e){!this.forceIntegerToFloat&&Number.isSafeInteger(e)?e>=0?e<128?this.writeU8(e):e<256?(this.writeU8(204),this.writeU8(e)):e<65536?(this.writeU8(205),this.writeU16(e)):e<4294967296?(this.writeU8(206),this.writeU32(e)):this.useBigInt64?this.encodeNumberAsFloat(e):(this.writeU8(207),this.writeU64(e)):e>=-32?this.writeU8(224|e+32):e>=-128?(this.writeU8(208),this.writeI8(e)):e>=-32768?(this.writeU8(209),this.writeI16(e)):e>=-2147483648?(this.writeU8(210),this.writeI32(e)):this.useBigInt64?this.encodeNumberAsFloat(e):(this.writeU8(211),this.writeI64(e)):this.encodeNumberAsFloat(e)}encodeNumberAsFloat(e){this.forceFloat32?(this.writeU8(202),this.writeF32(e)):(this.writeU8(203),this.writeF64(e))}encodeBigInt64(e){e>=BigInt(0)?(this.writeU8(207),this.writeBigUint64(e)):(this.writeU8(211),this.writeBigInt64(e))}writeStringHeader(e){if(e<32)this.writeU8(160+e);else if(e<256)this.writeU8(217),this.writeU8(e);else if(e<65536)this.writeU8(218),this.writeU16(e);else{if(!(e<4294967296))throw new Error(`Too long string: ${e} bytes in UTF-8`);this.writeU8(219),this.writeU32(e)}}encodeString(e){const t=function(e){const t=e.length;let i=0,s=0;for(;s<t;){let n=e.charCodeAt(s++);if(4294967168&n)if(4294965248&n){if(n>=55296&&n<=56319&&s<t){const t=e.charCodeAt(s);56320==(64512&t)&&(++s,n=((1023&n)<<10)+(1023&t)+65536)}i+=4294901760&n?4:3}else i+=2;else i++}return i}(e);var s,n,r;this.ensureBufferSizeToWrite(5+t),this.writeStringHeader(t),s=e,n=this.bytes,r=this.pos,s.length>50?function(e,t,s){i.encodeInto(e,t.subarray(s))}(s,n,r):function(e,t,i){const s=e.length;let n=i,r=0;for(;r<s;){let i=e.charCodeAt(r++);if(4294967168&i){if(4294965248&i){if(i>=55296&&i<=56319&&r<s){const t=e.charCodeAt(r);56320==(64512&t)&&(++r,i=((1023&i)<<10)+(1023&t)+65536)}4294901760&i?(t[n++]=i>>18&7|240,t[n++]=i>>12&63|128,t[n++]=i>>6&63|128):(t[n++]=i>>12&15|224,t[n++]=i>>6&63|128)}else t[n++]=i>>6&31|192;t[n++]=63&i|128}else t[n++]=i}}(s,n,r),this.pos+=t}encodeObject(e,t){const i=this.extensionCodec.tryToEncode(e,this.context);if(null!=i)this.encodeExtension(i);else if(Array.isArray(e))this.encodeArray(e,t);else if(ArrayBuffer.isView(e))this.encodeBinary(e);else{if("object"!=typeof e)throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(e)}`);this.encodeMap(e,t)}}encodeBinary(e){const t=e.byteLength;if(t<256)this.writeU8(196),this.writeU8(t);else if(t<65536)this.writeU8(197),this.writeU16(t);else{if(!(t<4294967296))throw new Error(`Too large binary: ${t}`);this.writeU8(198),this.writeU32(t)}const i=x(e);this.writeU8a(i)}encodeArray(e,t){const i=e.length;if(i<16)this.writeU8(144+i);else if(i<65536)this.writeU8(220),this.writeU16(i);else{if(!(i<4294967296))throw new Error(`Too large array: ${i}`);this.writeU8(221),this.writeU32(i)}for(const i of e)this.doEncode(i,t+1)}countWithoutUndefined(e,t){let i=0;for(const s of t)void 0!==e[s]&&i++;return i}encodeMap(e,t){const i=Object.keys(e);this.sortKeys&&i.sort();const s=this.ignoreUndefined?this.countWithoutUndefined(e,i):i.length;if(s<16)this.writeU8(128+s);else if(s<65536)this.writeU8(222),this.writeU16(s);else{if(!(s<4294967296))throw new Error(`Too large map object: ${s}`);this.writeU8(223),this.writeU32(s)}for(const s of i){const i=e[s];this.ignoreUndefined&&void 0===i||(this.encodeString(s),this.doEncode(i,t+1))}}encodeExtension(e){if("function"==typeof e.data){const t=e.data(this.pos+6),i=t.length;if(i>=4294967296)throw new Error(`Too large extension object: ${i}`);return this.writeU8(201),this.writeU32(i),this.writeI8(e.type),void this.writeU8a(t)}const t=e.data.length;if(1===t)this.writeU8(212);else if(2===t)this.writeU8(213);else if(4===t)this.writeU8(214);else if(8===t)this.writeU8(215);else if(16===t)this.writeU8(216);else if(t<256)this.writeU8(199),this.writeU8(t);else if(t<65536)this.writeU8(200),this.writeU16(t);else{if(!(t<4294967296))throw new Error(`Too large extension object: ${t}`);this.writeU8(201),this.writeU32(t)}this.writeI8(e.type),this.writeU8a(e.data)}writeU8(e){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,e),this.pos++}writeU8a(e){const t=e.length;this.ensureBufferSizeToWrite(t),this.bytes.set(e,this.pos),this.pos+=t}writeI8(e){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,e),this.pos++}writeU16(e){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,e),this.pos+=2}writeI16(e){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,e),this.pos+=2}writeU32(e){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,e),this.pos+=4}writeI32(e){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,e),this.pos+=4}writeF32(e){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,e),this.pos+=4}writeF64(e){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,e),this.pos+=8}writeU64(e){this.ensureBufferSizeToWrite(8),function(e,t,i){const s=i/4294967296,n=i;e.setUint32(t,s),e.setUint32(t+4,n)}(this.view,this.pos,e),this.pos+=8}writeI64(e){this.ensureBufferSizeToWrite(8),a(this.view,this.pos,e),this.pos+=8}writeBigUint64(e){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,e),this.pos+=8}writeBigInt64(e){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,e),this.pos+=8}}function B(e,t){return new b(t).encodeSharedRef(e)}function S(e){return`${e<0?"-":""}0x${Math.abs(e).toString(16).padStart(2,"0")}`}const I="array",E="map_key",A="map_value",v=e=>{if("string"==typeof e||"number"==typeof e)return e;throw new o("The type of key must be string or number but "+typeof e)};class k{constructor(){this.stack=[],this.stackHeadPosition=-1}get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(e){const t=this.getUninitializedStateFromPool();t.type=I,t.position=0,t.size=e,t.array=new Array(e)}pushMapState(e){const t=this.getUninitializedStateFromPool();t.type=E,t.readCount=0,t.size=e,t.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){const e={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(e)}return this.stack[this.stackHeadPosition]}release(e){if(this.stack[this.stackHeadPosition]!==e)throw new Error("Invalid stack state. Released state is not on top of the stack.");if(e.type===I){const t=e;t.size=0,t.array=void 0,t.position=0,t.type=void 0}if(e.type===E||e.type===A){const t=e;t.size=0,t.map=void 0,t.readCount=0,t.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}const T=new DataView(new ArrayBuffer(0)),L=new Uint8Array(T.buffer);try{T.getInt8(0)}catch(e){if(!(e instanceof RangeError))throw new Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}const z=new RangeError("Insufficient data"),M=new class{constructor(e=16,t=16){this.hit=0,this.miss=0,this.maxKeyLength=e,this.maxLengthPerKey=t,this.caches=[];for(let e=0;e<this.maxKeyLength;e++)this.caches.push([])}canBeCached(e){return e>0&&e<=this.maxKeyLength}find(e,t,i){const s=this.caches[i-1];e:for(const n of s){const s=n.bytes;for(let n=0;n<i;n++)if(s[n]!==e[t+n])continue e;return n.str}return null}store(e,t){const i=this.caches[e.length-1],s={bytes:e,str:t};i.length>=this.maxLengthPerKey?i[Math.random()*i.length|0]=s:i.push(s)}decode(e,t,i){const n=this.find(e,t,i);if(null!=n)return this.hit++,n;this.miss++;const r=s(e,t,i),o=Uint8Array.prototype.slice.call(e,t,t+i);return this.store(o,r),r}};class D{constructor(e){this.totalPos=0,this.pos=0,this.view=T,this.bytes=L,this.headByte=-1,this.stack=new k,this.entered=!1,this.extensionCodec=e?.extensionCodec??m.defaultCodec,this.context=e?.context,this.useBigInt64=e?.useBigInt64??!1,this.rawStrings=e?.rawStrings??!1,this.maxStrLength=e?.maxStrLength??h,this.maxBinLength=e?.maxBinLength??h,this.maxArrayLength=e?.maxArrayLength??h,this.maxMapLength=e?.maxMapLength??h,this.maxExtLength=e?.maxExtLength??h,this.keyDecoder=void 0!==e?.keyDecoder?e.keyDecoder:M,this.mapKeyConverter=e?.mapKeyConverter??v}clone(){return new D({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=-1,this.stack.reset()}setBuffer(e){const t=x(e);this.bytes=t,this.view=new DataView(t.buffer,t.byteOffset,t.byteLength),this.pos=0}appendBuffer(e){if(-1!==this.headByte||this.hasRemaining(1)){const t=this.bytes.subarray(this.pos),i=x(e),s=new Uint8Array(t.length+i.length);s.set(t),s.set(i,t.length),this.setBuffer(s)}else this.setBuffer(e)}hasRemaining(e){return this.view.byteLength-this.pos>=e}createExtraByteError(e){const{view:t,pos:i}=this;return new RangeError(`Extra ${t.byteLength-i} of ${t.byteLength} byte(s) found at buffer[${e}]`)}decode(e){if(this.entered)return this.clone().decode(e);try{this.entered=!0,this.reinitializeState(),this.setBuffer(e);const t=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return t}finally{this.entered=!1}}*decodeMulti(e){if(this.entered){const t=this.clone();yield*t.decodeMulti(e)}else try{for(this.entered=!0,this.reinitializeState(),this.setBuffer(e);this.hasRemaining(1);)yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(e){if(this.entered)return this.clone().decodeAsync(e);try{this.entered=!0;let t,i=!1;for await(const s of e){if(i)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(s);try{t=this.doDecodeSync(),i=!0}catch(e){if(!(e instanceof RangeError))throw e}this.totalPos+=this.pos}if(i){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return t}const{headByte:s,pos:n,totalPos:r}=this;throw new RangeError(`Insufficient data in parsing ${S(s)} at ${r} (${n} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(e){return this.decodeMultiAsync(e,!0)}decodeStream(e){return this.decodeMultiAsync(e,!1)}async*decodeMultiAsync(e,t){if(this.entered){const i=this.clone();yield*i.decodeMultiAsync(e,t)}else try{this.entered=!0;let i=t,s=-1;for await(const n of e){if(t&&0===s)throw this.createExtraByteError(this.totalPos);this.appendBuffer(n),i&&(s=this.readArraySize(),i=!1,this.complete());try{for(;yield this.doDecodeSync(),0!==--s;);}catch(e){if(!(e instanceof RangeError))throw e}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){e:for(;;){const e=this.readHeadByte();let t;if(e>=224)t=e-256;else if(e<192)if(e<128)t=e;else if(e<144){const i=e-128;if(0!==i){this.pushMapState(i),this.complete();continue e}t={}}else if(e<160){const i=e-144;if(0!==i){this.pushArrayState(i),this.complete();continue e}t=[]}else{const i=e-160;t=this.decodeString(i,0)}else if(192===e)t=null;else if(194===e)t=!1;else if(195===e)t=!0;else if(202===e)t=this.readF32();else if(203===e)t=this.readF64();else if(204===e)t=this.readU8();else if(205===e)t=this.readU16();else if(206===e)t=this.readU32();else if(207===e)t=this.useBigInt64?this.readU64AsBigInt():this.readU64();else if(208===e)t=this.readI8();else if(209===e)t=this.readI16();else if(210===e)t=this.readI32();else if(211===e)t=this.useBigInt64?this.readI64AsBigInt():this.readI64();else if(217===e){const e=this.lookU8();t=this.decodeString(e,1)}else if(218===e){const e=this.lookU16();t=this.decodeString(e,2)}else if(219===e){const e=this.lookU32();t=this.decodeString(e,4)}else if(220===e){const e=this.readU16();if(0!==e){this.pushArrayState(e),this.complete();continue e}t=[]}else if(221===e){const e=this.readU32();if(0!==e){this.pushArrayState(e),this.complete();continue e}t=[]}else if(222===e){const e=this.readU16();if(0!==e){this.pushMapState(e),this.complete();continue e}t={}}else if(223===e){const e=this.readU32();if(0!==e){this.pushMapState(e),this.complete();continue e}t={}}else if(196===e){const e=this.lookU8();t=this.decodeBinary(e,1)}else if(197===e){const e=this.lookU16();t=this.decodeBinary(e,2)}else if(198===e){const e=this.lookU32();t=this.decodeBinary(e,4)}else if(212===e)t=this.decodeExtension(1,0);else if(213===e)t=this.decodeExtension(2,0);else if(214===e)t=this.decodeExtension(4,0);else if(215===e)t=this.decodeExtension(8,0);else if(216===e)t=this.decodeExtension(16,0);else if(199===e){const e=this.lookU8();t=this.decodeExtension(e,1)}else if(200===e){const e=this.lookU16();t=this.decodeExtension(e,2)}else{if(201!==e)throw new o(`Unrecognized type byte: ${S(e)}`);{const e=this.lookU32();t=this.decodeExtension(e,4)}}this.complete();const i=this.stack;for(;i.length>0;){const e=i.top();if(e.type===I){if(e.array[e.position]=t,e.position++,e.position!==e.size)continue e;t=e.array,i.release(e)}else{if(e.type===E){if("__proto__"===t)throw new o("The key __proto__ is not allowed");e.key=this.mapKeyConverter(t),e.type=A;continue e}if(e.map[e.key]=t,e.readCount++,e.readCount!==e.size){e.key=null,e.type=E;continue e}t=e.map,i.release(e)}}return t}}readHeadByte(){return-1===this.headByte&&(this.headByte=this.readU8()),this.headByte}complete(){this.headByte=-1}readArraySize(){const e=this.readHeadByte();switch(e){case 220:return this.readU16();case 221:return this.readU32();default:if(e<160)return e-144;throw new o(`Unrecognized array type byte: ${S(e)}`)}}pushMapState(e){if(e>this.maxMapLength)throw new o(`Max length exceeded: map length (${e}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(e)}pushArrayState(e){if(e>this.maxArrayLength)throw new o(`Max length exceeded: array length (${e}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(e)}decodeString(e,t){return!this.rawStrings||this.stateIsMapKey()?this.decodeUtf8String(e,t):this.decodeBinary(e,t)}decodeUtf8String(e,t){if(e>this.maxStrLength)throw new o(`Max length exceeded: UTF-8 byte length (${e}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+t+e)throw z;const i=this.pos+t;let r;return r=this.stateIsMapKey()&&this.keyDecoder?.canBeCached(e)?this.keyDecoder.decode(this.bytes,i,e):function(e,t,i){return i>200?function(e,t,i){const s=e.subarray(t,t+i);return n.decode(s)}(e,t,i):s(e,t,i)}(this.bytes,i,e),this.pos+=t+e,r}stateIsMapKey(){return this.stack.length>0&&this.stack.top().type===E}decodeBinary(e,t){if(e>this.maxBinLength)throw new o(`Max length exceeded: bin length (${e}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(e+t))throw z;const i=this.pos+t,s=this.bytes.subarray(i,i+e);return this.pos+=t+e,s}decodeExtension(e,t){if(e>this.maxExtLength)throw new o(`Max length exceeded: ext length (${e}) > maxExtLength (${this.maxExtLength})`);const i=this.view.getInt8(this.pos+t),s=this.decodeBinary(e,t+1);return this.extensionCodec.decode(s,i,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){const e=this.view.getUint8(this.pos);return this.pos++,e}readI8(){const e=this.view.getInt8(this.pos);return this.pos++,e}readU16(){const e=this.view.getUint16(this.pos);return this.pos+=2,e}readI16(){const e=this.view.getInt16(this.pos);return this.pos+=2,e}readU32(){const e=this.view.getUint32(this.pos);return this.pos+=4,e}readI32(){const e=this.view.getInt32(this.pos);return this.pos+=4,e}readU64(){const e=(t=this.view,i=this.pos,4294967296*t.getUint32(i)+t.getUint32(i+4));var t,i;return this.pos+=8,e}readI64(){const e=c(this.view,this.pos);return this.pos+=8,e}readU64AsBigInt(){const e=this.view.getBigUint64(this.pos);return this.pos+=8,e}readI64AsBigInt(){const e=this.view.getBigInt64(this.pos);return this.pos+=8,e}readF32(){const e=this.view.getFloat32(this.pos);return this.pos+=4,e}readF64(){const e=this.view.getFloat64(this.pos);return this.pos+=8,e}}function F(e,t){return new D(t).decode(e)}function C(e,t){return new D(t).decodeMulti(e)}function P(e){return null!=e[Symbol.asyncIterator]?e:async function*(e){const t=e.getReader();try{for(;;){const{done:e,value:i}=await t.read();if(e)return;yield i}}finally{t.releaseLock()}}(e)}async function $(e,t){const i=P(e);return new D(t).decodeAsync(i)}function j(e,t){const i=P(e);return new D(t).decodeArrayStream(i)}function R(e,t){const i=P(e);return new D(t).decodeStream(i)}return t})()));
//# sourceMappingURL=msgpack.min.js.map
\ No newline at end of file
/*!
* Socket.IO v4.7.5
* (c) 2014-2024 Guillermo Rauch
* Released under the MIT License.
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).io=t()}(this,(function(){"use strict";function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,(i=r.key,o=void 0,"symbol"==typeof(o=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(i,"string"))?o:String(o)),r)}var i,o}function r(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&a(e,t)}function s(e){return s=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},s(e)}function a(e,t){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},a(e,t)}function c(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function u(e,t,n){return u=c()?Reflect.construct.bind():function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&a(i,n.prototype),i},u.apply(null,arguments)}function h(e){var t="function"==typeof Map?new Map:void 0;return h=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return u(e,arguments,s(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),a(r,e)},h(e)}function f(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function l(e){var t=c();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return function(e,t){if(t&&("object"==typeof t||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return f(e)}(this,n)}}function p(){return p="undefined"!=typeof Reflect&&Reflect.get?Reflect.get.bind():function(e,t,n){var r=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=s(e)););return e}(e,t);if(r){var i=Object.getOwnPropertyDescriptor(r,t);return i.get?i.get.call(arguments.length<3?e:n):i.value}},p.apply(this,arguments)}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function y(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return d(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?d(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,s=!0,a=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){a=!0,o=e},f:function(){try{s||null==n.return||n.return()}finally{if(a)throw o}}}}var v=Object.create(null);v.open="0",v.close="1",v.ping="2",v.pong="3",v.message="4",v.upgrade="5",v.noop="6";var g=Object.create(null);Object.keys(v).forEach((function(e){g[v[e]]=e}));var m,b={type:"error",data:"parser error"},k="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),w="function"==typeof ArrayBuffer,_=function(e){return"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer instanceof ArrayBuffer},E=function(e,t,n){var r=e.type,i=e.data;return k&&i instanceof Blob?t?n(i):A(i,n):w&&(i instanceof ArrayBuffer||_(i))?t?n(i):A(new Blob([i]),n):n(v[r]+(i||""))},A=function(e,t){var n=new FileReader;return n.onload=function(){var e=n.result.split(",")[1];t("b"+(e||""))},n.readAsDataURL(e)};function O(e){return e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}for(var T="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",R="undefined"==typeof Uint8Array?[]:new Uint8Array(256),C=0;C<64;C++)R[T.charCodeAt(C)]=C;var B,S="function"==typeof ArrayBuffer,N=function(e,t){if("string"!=typeof e)return{type:"message",data:x(e,t)};var n=e.charAt(0);return"b"===n?{type:"message",data:L(e.substring(1),t)}:g[n]?e.length>1?{type:g[n],data:e.substring(1)}:{type:g[n]}:b},L=function(e,t){if(S){var n=function(e){var t,n,r,i,o,s=.75*e.length,a=e.length,c=0;"="===e[e.length-1]&&(s--,"="===e[e.length-2]&&s--);var u=new ArrayBuffer(s),h=new Uint8Array(u);for(t=0;t<a;t+=4)n=R[e.charCodeAt(t)],r=R[e.charCodeAt(t+1)],i=R[e.charCodeAt(t+2)],o=R[e.charCodeAt(t+3)],h[c++]=n<<2|r>>4,h[c++]=(15&r)<<4|i>>2,h[c++]=(3&i)<<6|63&o;return u}(e);return x(n,t)}return{base64:!0,data:e}},x=function(e,t){return"blob"===t?e instanceof Blob?e:new Blob([e]):e instanceof ArrayBuffer?e:e.buffer},P=String.fromCharCode(30);function j(){return new TransformStream({transform:function(e,t){!function(e,t){k&&e.data instanceof Blob?e.data.arrayBuffer().then(O).then(t):w&&(e.data instanceof ArrayBuffer||_(e.data))?t(O(e.data)):E(e,!1,(function(e){m||(m=new TextEncoder),t(m.encode(e))}))}(e,(function(n){var r,i=n.length;if(i<126)r=new Uint8Array(1),new DataView(r.buffer).setUint8(0,i);else if(i<65536){r=new Uint8Array(3);var o=new DataView(r.buffer);o.setUint8(0,126),o.setUint16(1,i)}else{r=new Uint8Array(9);var s=new DataView(r.buffer);s.setUint8(0,127),s.setBigUint64(1,BigInt(i))}e.data&&"string"!=typeof e.data&&(r[0]|=128),t.enqueue(r),t.enqueue(n)}))}})}function q(e){return e.reduce((function(e,t){return e+t.length}),0)}function D(e,t){if(e[0].length===t)return e.shift();for(var n=new Uint8Array(t),r=0,i=0;i<t;i++)n[i]=e[0][r++],r===e[0].length&&(e.shift(),r=0);return e.length&&r<e[0].length&&(e[0]=e[0].slice(r)),n}function U(e){if(e)return function(e){for(var t in U.prototype)e[t]=U.prototype[t];return e}(e)}U.prototype.on=U.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+e]=this._callbacks["$"+e]||[]).push(t),this},U.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this},U.prototype.off=U.prototype.removeListener=U.prototype.removeAllListeners=U.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n,r=this._callbacks["$"+e];if(!r)return this;if(1==arguments.length)return delete this._callbacks["$"+e],this;for(var i=0;i<r.length;i++)if((n=r[i])===t||n.fn===t){r.splice(i,1);break}return 0===r.length&&delete this._callbacks["$"+e],this},U.prototype.emit=function(e){this._callbacks=this._callbacks||{};for(var t=new Array(arguments.length-1),n=this._callbacks["$"+e],r=1;r<arguments.length;r++)t[r-1]=arguments[r];if(n){r=0;for(var i=(n=n.slice(0)).length;r<i;++r)n[r].apply(this,t)}return this},U.prototype.emitReserved=U.prototype.emit,U.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks["$"+e]||[]},U.prototype.hasListeners=function(e){return!!this.listeners(e).length};var I="undefined"!=typeof self?self:"undefined"!=typeof window?window:Function("return this")();function F(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];return n.reduce((function(t,n){return e.hasOwnProperty(n)&&(t[n]=e[n]),t}),{})}var M=I.setTimeout,V=I.clearTimeout;function H(e,t){t.useNativeTimers?(e.setTimeoutFn=M.bind(I),e.clearTimeoutFn=V.bind(I)):(e.setTimeoutFn=I.setTimeout.bind(I),e.clearTimeoutFn=I.clearTimeout.bind(I))}var K,Y=function(e){o(i,e);var n=l(i);function i(e,r,o){var s;return t(this,i),(s=n.call(this,e)).description=r,s.context=o,s.type="TransportError",s}return r(i)}(h(Error)),W=function(e){o(i,e);var n=l(i);function i(e){var r;return t(this,i),(r=n.call(this)).writable=!1,H(f(r),e),r.opts=e,r.query=e.query,r.socket=e.socket,r}return r(i,[{key:"onError",value:function(e,t,n){return p(s(i.prototype),"emitReserved",this).call(this,"error",new Y(e,t,n)),this}},{key:"open",value:function(){return this.readyState="opening",this.doOpen(),this}},{key:"close",value:function(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this}},{key:"send",value:function(e){"open"===this.readyState&&this.write(e)}},{key:"onOpen",value:function(){this.readyState="open",this.writable=!0,p(s(i.prototype),"emitReserved",this).call(this,"open")}},{key:"onData",value:function(e){var t=N(e,this.socket.binaryType);this.onPacket(t)}},{key:"onPacket",value:function(e){p(s(i.prototype),"emitReserved",this).call(this,"packet",e)}},{key:"onClose",value:function(e){this.readyState="closed",p(s(i.prototype),"emitReserved",this).call(this,"close",e)}},{key:"pause",value:function(e){}},{key:"createUri",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e+"://"+this._hostname()+this._port()+this.opts.path+this._query(t)}},{key:"_hostname",value:function(){var e=this.opts.hostname;return-1===e.indexOf(":")?e:"["+e+"]"}},{key:"_port",value:function(){return this.opts.port&&(this.opts.secure&&Number(443!==this.opts.port)||!this.opts.secure&&80!==Number(this.opts.port))?":"+this.opts.port:""}},{key:"_query",value:function(e){var t=function(e){var t="";for(var n in e)e.hasOwnProperty(n)&&(t.length&&(t+="&"),t+=encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t}(e);return t.length?"?"+t:""}}]),i}(U),z="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),J=64,$={},Q=0,X=0;function G(e){var t="";do{t=z[e%J]+t,e=Math.floor(e/J)}while(e>0);return t}function Z(){var e=G(+new Date);return e!==K?(Q=0,K=e):e+"."+G(Q++)}for(;X<J;X++)$[z[X]]=X;var ee=!1;try{ee="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(e){}var te=ee;function ne(e){var t=e.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!t||te))return new XMLHttpRequest}catch(e){}if(!t)try{return new(I[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(e){}}function re(){}var ie=null!=new ne({xdomain:!1}).responseType,oe=function(e){o(s,e);var n=l(s);function s(e){var r;if(t(this,s),(r=n.call(this,e)).polling=!1,"undefined"!=typeof location){var i="https:"===location.protocol,o=location.port;o||(o=i?"443":"80"),r.xd="undefined"!=typeof location&&e.hostname!==location.hostname||o!==e.port}var a=e&&e.forceBase64;return r.supportsBinary=ie&&!a,r.opts.withCredentials&&(r.cookieJar=void 0),r}return r(s,[{key:"name",get:function(){return"polling"}},{key:"doOpen",value:function(){this.poll()}},{key:"pause",value:function(e){var t=this;this.readyState="pausing";var n=function(){t.readyState="paused",e()};if(this.polling||!this.writable){var r=0;this.polling&&(r++,this.once("pollComplete",(function(){--r||n()}))),this.writable||(r++,this.once("drain",(function(){--r||n()})))}else n()}},{key:"poll",value:function(){this.polling=!0,this.doPoll(),this.emitReserved("poll")}},{key:"onData",value:function(e){var t=this;(function(e,t){for(var n=e.split(P),r=[],i=0;i<n.length;i++){var o=N(n[i],t);if(r.push(o),"error"===o.type)break}return r})(e,this.socket.binaryType).forEach((function(e){if("opening"===t.readyState&&"open"===e.type&&t.onOpen(),"close"===e.type)return t.onClose({description:"transport closed by the server"}),!1;t.onPacket(e)})),"closed"!==this.readyState&&(this.polling=!1,this.emitReserved("pollComplete"),"open"===this.readyState&&this.poll())}},{key:"doClose",value:function(){var e=this,t=function(){e.write([{type:"close"}])};"open"===this.readyState?t():this.once("open",t)}},{key:"write",value:function(e){var t=this;this.writable=!1,function(e,t){var n=e.length,r=new Array(n),i=0;e.forEach((function(e,o){E(e,!1,(function(e){r[o]=e,++i===n&&t(r.join(P))}))}))}(e,(function(e){t.doWrite(e,(function(){t.writable=!0,t.emitReserved("drain")}))}))}},{key:"uri",value:function(){var e=this.opts.secure?"https":"http",t=this.query||{};return!1!==this.opts.timestampRequests&&(t[this.opts.timestampParam]=Z()),this.supportsBinary||t.sid||(t.b64=1),this.createUri(e,t)}},{key:"request",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return i(e,{xd:this.xd,cookieJar:this.cookieJar},this.opts),new se(this.uri(),e)}},{key:"doWrite",value:function(e,t){var n=this,r=this.request({method:"POST",data:e});r.on("success",t),r.on("error",(function(e,t){n.onError("xhr post error",e,t)}))}},{key:"doPoll",value:function(){var e=this,t=this.request();t.on("data",this.onData.bind(this)),t.on("error",(function(t,n){e.onError("xhr poll error",t,n)})),this.pollXhr=t}}]),s}(W),se=function(e){o(i,e);var n=l(i);function i(e,r){var o;return t(this,i),H(f(o=n.call(this)),r),o.opts=r,o.method=r.method||"GET",o.uri=e,o.data=void 0!==r.data?r.data:null,o.create(),o}return r(i,[{key:"create",value:function(){var e,t=this,n=F(this.opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");n.xdomain=!!this.opts.xd;var r=this.xhr=new ne(n);try{r.open(this.method,this.uri,!0);try{if(this.opts.extraHeaders)for(var o in r.setDisableHeaderCheck&&r.setDisableHeaderCheck(!0),this.opts.extraHeaders)this.opts.extraHeaders.hasOwnProperty(o)&&r.setRequestHeader(o,this.opts.extraHeaders[o])}catch(e){}if("POST"===this.method)try{r.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(e){}try{r.setRequestHeader("Accept","*/*")}catch(e){}null===(e=this.opts.cookieJar)||void 0===e||e.addCookies(r),"withCredentials"in r&&(r.withCredentials=this.opts.withCredentials),this.opts.requestTimeout&&(r.timeout=this.opts.requestTimeout),r.onreadystatechange=function(){var e;3===r.readyState&&(null===(e=t.opts.cookieJar)||void 0===e||e.parseCookies(r)),4===r.readyState&&(200===r.status||1223===r.status?t.onLoad():t.setTimeoutFn((function(){t.onError("number"==typeof r.status?r.status:0)}),0))},r.send(this.data)}catch(e){return void this.setTimeoutFn((function(){t.onError(e)}),0)}"undefined"!=typeof document&&(this.index=i.requestsCount++,i.requests[this.index]=this)}},{key:"onError",value:function(e){this.emitReserved("error",e,this.xhr),this.cleanup(!0)}},{key:"cleanup",value:function(e){if(void 0!==this.xhr&&null!==this.xhr){if(this.xhr.onreadystatechange=re,e)try{this.xhr.abort()}catch(e){}"undefined"!=typeof document&&delete i.requests[this.index],this.xhr=null}}},{key:"onLoad",value:function(){var e=this.xhr.responseText;null!==e&&(this.emitReserved("data",e),this.emitReserved("success"),this.cleanup())}},{key:"abort",value:function(){this.cleanup()}}]),i}(U);if(se.requestsCount=0,se.requests={},"undefined"!=typeof document)if("function"==typeof attachEvent)attachEvent("onunload",ae);else if("function"==typeof addEventListener){addEventListener("onpagehide"in I?"pagehide":"unload",ae,!1)}function ae(){for(var e in se.requests)se.requests.hasOwnProperty(e)&&se.requests[e].abort()}var ce="function"==typeof Promise&&"function"==typeof Promise.resolve?function(e){return Promise.resolve().then(e)}:function(e,t){return t(e,0)},ue=I.WebSocket||I.MozWebSocket,he="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),fe=function(e){o(i,e);var n=l(i);function i(e){var r;return t(this,i),(r=n.call(this,e)).supportsBinary=!e.forceBase64,r}return r(i,[{key:"name",get:function(){return"websocket"}},{key:"doOpen",value:function(){if(this.check()){var e=this.uri(),t=this.opts.protocols,n=he?{}:F(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(n.headers=this.opts.extraHeaders);try{this.ws=he?new ue(e,t,n):t?new ue(e,t):new ue(e)}catch(e){return this.emitReserved("error",e)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}}},{key:"addEventListeners",value:function(){var e=this;this.ws.onopen=function(){e.opts.autoUnref&&e.ws._socket.unref(),e.onOpen()},this.ws.onclose=function(t){return e.onClose({description:"websocket connection closed",context:t})},this.ws.onmessage=function(t){return e.onData(t.data)},this.ws.onerror=function(t){return e.onError("websocket error",t)}}},{key:"write",value:function(e){var t=this;this.writable=!1;for(var n=function(){var n=e[r],i=r===e.length-1;E(n,t.supportsBinary,(function(e){try{t.ws.send(e)}catch(e){}i&&ce((function(){t.writable=!0,t.emitReserved("drain")}),t.setTimeoutFn)}))},r=0;r<e.length;r++)n()}},{key:"doClose",value:function(){void 0!==this.ws&&(this.ws.close(),this.ws=null)}},{key:"uri",value:function(){var e=this.opts.secure?"wss":"ws",t=this.query||{};return this.opts.timestampRequests&&(t[this.opts.timestampParam]=Z()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}},{key:"check",value:function(){return!!ue}}]),i}(W),le=function(e){o(i,e);var n=l(i);function i(){return t(this,i),n.apply(this,arguments)}return r(i,[{key:"name",get:function(){return"webtransport"}},{key:"doOpen",value:function(){var e=this;"function"==typeof WebTransport&&(this.transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name]),this.transport.closed.then((function(){e.onClose()})).catch((function(t){e.onError("webtransport error",t)})),this.transport.ready.then((function(){e.transport.createBidirectionalStream().then((function(t){var n=function(e,t){B||(B=new TextDecoder);var n=[],r=0,i=-1,o=!1;return new TransformStream({transform:function(s,a){for(n.push(s);;){if(0===r){if(q(n)<1)break;var c=D(n,1);o=128==(128&c[0]),i=127&c[0],r=i<126?3:126===i?1:2}else if(1===r){if(q(n)<2)break;var u=D(n,2);i=new DataView(u.buffer,u.byteOffset,u.length).getUint16(0),r=3}else if(2===r){if(q(n)<8)break;var h=D(n,8),f=new DataView(h.buffer,h.byteOffset,h.length),l=f.getUint32(0);if(l>Math.pow(2,21)-1){a.enqueue(b);break}i=l*Math.pow(2,32)+f.getUint32(4),r=3}else{if(q(n)<i)break;var p=D(n,i);a.enqueue(N(o?p:B.decode(p),t)),r=0}if(0===i||i>e){a.enqueue(b);break}}}})}(Number.MAX_SAFE_INTEGER,e.socket.binaryType),r=t.readable.pipeThrough(n).getReader(),i=j();i.readable.pipeTo(t.writable),e.writer=i.writable.getWriter();!function t(){r.read().then((function(n){var r=n.done,i=n.value;r||(e.onPacket(i),t())})).catch((function(e){}))}();var o={type:"open"};e.query.sid&&(o.data='{"sid":"'.concat(e.query.sid,'"}')),e.writer.write(o).then((function(){return e.onOpen()}))}))})))}},{key:"write",value:function(e){var t=this;this.writable=!1;for(var n=function(){var n=e[r],i=r===e.length-1;t.writer.write(n).then((function(){i&&ce((function(){t.writable=!0,t.emitReserved("drain")}),t.setTimeoutFn)}))},r=0;r<e.length;r++)n()}},{key:"doClose",value:function(){var e;null===(e=this.transport)||void 0===e||e.close()}}]),i}(W),pe={websocket:fe,webtransport:le,polling:oe},de=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,ye=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function ve(e){var t=e,n=e.indexOf("["),r=e.indexOf("]");-1!=n&&-1!=r&&(e=e.substring(0,n)+e.substring(n,r).replace(/:/g,";")+e.substring(r,e.length));for(var i,o,s=de.exec(e||""),a={},c=14;c--;)a[ye[c]]=s[c]||"";return-1!=n&&-1!=r&&(a.source=t,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,":"),a.authority=a.authority.replace("[","").replace("]","").replace(/;/g,":"),a.ipv6uri=!0),a.pathNames=function(e,t){var n=/\/{2,9}/g,r=t.replace(n,"/").split("/");"/"!=t.slice(0,1)&&0!==t.length||r.splice(0,1);"/"==t.slice(-1)&&r.splice(r.length-1,1);return r}(0,a.path),a.queryKey=(i=a.query,o={},i.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,(function(e,t,n){t&&(o[t]=n)})),o),a}var ge=function(n){o(a,n);var s=l(a);function a(n){var r,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return t(this,a),(r=s.call(this)).binaryType="arraybuffer",r.writeBuffer=[],n&&"object"===e(n)&&(o=n,n=null),n?(n=ve(n),o.hostname=n.host,o.secure="https"===n.protocol||"wss"===n.protocol,o.port=n.port,n.query&&(o.query=n.query)):o.host&&(o.hostname=ve(o.host).host),H(f(r),o),r.secure=null!=o.secure?o.secure:"undefined"!=typeof location&&"https:"===location.protocol,o.hostname&&!o.port&&(o.port=r.secure?"443":"80"),r.hostname=o.hostname||("undefined"!=typeof location?location.hostname:"localhost"),r.port=o.port||("undefined"!=typeof location&&location.port?location.port:r.secure?"443":"80"),r.transports=o.transports||["polling","websocket","webtransport"],r.writeBuffer=[],r.prevBufferLen=0,r.opts=i({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},o),r.opts.path=r.opts.path.replace(/\/$/,"")+(r.opts.addTrailingSlash?"/":""),"string"==typeof r.opts.query&&(r.opts.query=function(e){for(var t={},n=e.split("&"),r=0,i=n.length;r<i;r++){var o=n[r].split("=");t[decodeURIComponent(o[0])]=decodeURIComponent(o[1])}return t}(r.opts.query)),r.id=null,r.upgrades=null,r.pingInterval=null,r.pingTimeout=null,r.pingTimeoutTimer=null,"function"==typeof addEventListener&&(r.opts.closeOnBeforeunload&&(r.beforeunloadEventListener=function(){r.transport&&(r.transport.removeAllListeners(),r.transport.close())},addEventListener("beforeunload",r.beforeunloadEventListener,!1)),"localhost"!==r.hostname&&(r.offlineEventListener=function(){r.onClose("transport close",{description:"network connection lost"})},addEventListener("offline",r.offlineEventListener,!1))),r.open(),r}return r(a,[{key:"createTransport",value:function(e){var t=i({},this.opts.query);t.EIO=4,t.transport=e,this.id&&(t.sid=this.id);var n=i({},this.opts,{query:t,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new pe[e](n)}},{key:"open",value:function(){var e,t=this;if(this.opts.rememberUpgrade&&a.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket"))e="websocket";else{if(0===this.transports.length)return void this.setTimeoutFn((function(){t.emitReserved("error","No transports available")}),0);e=this.transports[0]}this.readyState="opening";try{e=this.createTransport(e)}catch(e){return this.transports.shift(),void this.open()}e.open(),this.setTransport(e)}},{key:"setTransport",value:function(e){var t=this;this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on("drain",this.onDrain.bind(this)).on("packet",this.onPacket.bind(this)).on("error",this.onError.bind(this)).on("close",(function(e){return t.onClose("transport close",e)}))}},{key:"probe",value:function(e){var t=this,n=this.createTransport(e),r=!1;a.priorWebsocketSuccess=!1;var i=function(){r||(n.send([{type:"ping",data:"probe"}]),n.once("packet",(function(e){if(!r)if("pong"===e.type&&"probe"===e.data){if(t.upgrading=!0,t.emitReserved("upgrading",n),!n)return;a.priorWebsocketSuccess="websocket"===n.name,t.transport.pause((function(){r||"closed"!==t.readyState&&(f(),t.setTransport(n),n.send([{type:"upgrade"}]),t.emitReserved("upgrade",n),n=null,t.upgrading=!1,t.flush())}))}else{var i=new Error("probe error");i.transport=n.name,t.emitReserved("upgradeError",i)}})))};function o(){r||(r=!0,f(),n.close(),n=null)}var s=function(e){var r=new Error("probe error: "+e);r.transport=n.name,o(),t.emitReserved("upgradeError",r)};function c(){s("transport closed")}function u(){s("socket closed")}function h(e){n&&e.name!==n.name&&o()}var f=function(){n.removeListener("open",i),n.removeListener("error",s),n.removeListener("close",c),t.off("close",u),t.off("upgrading",h)};n.once("open",i),n.once("error",s),n.once("close",c),this.once("close",u),this.once("upgrading",h),-1!==this.upgrades.indexOf("webtransport")&&"webtransport"!==e?this.setTimeoutFn((function(){r||n.open()}),200):n.open()}},{key:"onOpen",value:function(){if(this.readyState="open",a.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush(),"open"===this.readyState&&this.opts.upgrade)for(var e=0,t=this.upgrades.length;e<t;e++)this.probe(this.upgrades[e])}},{key:"onPacket",value:function(e){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(this.emitReserved("packet",e),this.emitReserved("heartbeat"),this.resetPingTimeout(),e.type){case"open":this.onHandshake(JSON.parse(e.data));break;case"ping":this.sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong");break;case"error":var t=new Error("server error");t.code=e.data,this.onError(t);break;case"message":this.emitReserved("data",e.data),this.emitReserved("message",e.data)}}},{key:"onHandshake",value:function(e){this.emitReserved("handshake",e),this.id=e.sid,this.transport.query.sid=e.sid,this.upgrades=this.filterUpgrades(e.upgrades),this.pingInterval=e.pingInterval,this.pingTimeout=e.pingTimeout,this.maxPayload=e.maxPayload,this.onOpen(),"closed"!==this.readyState&&this.resetPingTimeout()}},{key:"resetPingTimeout",value:function(){var e=this;this.clearTimeoutFn(this.pingTimeoutTimer),this.pingTimeoutTimer=this.setTimeoutFn((function(){e.onClose("ping timeout")}),this.pingInterval+this.pingTimeout),this.opts.autoUnref&&this.pingTimeoutTimer.unref()}},{key:"onDrain",value:function(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emitReserved("drain"):this.flush()}},{key:"flush",value:function(){if("closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){var e=this.getWritablePackets();this.transport.send(e),this.prevBufferLen=e.length,this.emitReserved("flush")}}},{key:"getWritablePackets",value:function(){if(!(this.maxPayload&&"polling"===this.transport.name&&this.writeBuffer.length>1))return this.writeBuffer;for(var e,t=1,n=0;n<this.writeBuffer.length;n++){var r=this.writeBuffer[n].data;if(r&&(t+="string"==typeof(e=r)?function(e){for(var t=0,n=0,r=0,i=e.length;r<i;r++)(t=e.charCodeAt(r))<128?n+=1:t<2048?n+=2:t<55296||t>=57344?n+=3:(r++,n+=4);return n}(e):Math.ceil(1.33*(e.byteLength||e.size))),n>0&&t>this.maxPayload)return this.writeBuffer.slice(0,n);t+=2}return this.writeBuffer}},{key:"write",value:function(e,t,n){return this.sendPacket("message",e,t,n),this}},{key:"send",value:function(e,t,n){return this.sendPacket("message",e,t,n),this}},{key:"sendPacket",value:function(e,t,n,r){if("function"==typeof t&&(r=t,t=void 0),"function"==typeof n&&(r=n,n=null),"closing"!==this.readyState&&"closed"!==this.readyState){(n=n||{}).compress=!1!==n.compress;var i={type:e,data:t,options:n};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),r&&this.once("flush",r),this.flush()}}},{key:"close",value:function(){var e=this,t=function(){e.onClose("forced close"),e.transport.close()},n=function n(){e.off("upgrade",n),e.off("upgradeError",n),t()},r=function(){e.once("upgrade",n),e.once("upgradeError",n)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",(function(){e.upgrading?r():t()})):this.upgrading?r():t()),this}},{key:"onError",value:function(e){a.priorWebsocketSuccess=!1,this.emitReserved("error",e),this.onClose("transport error",e)}},{key:"onClose",value:function(e,t){"opening"!==this.readyState&&"open"!==this.readyState&&"closing"!==this.readyState||(this.clearTimeoutFn(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),"function"==typeof removeEventListener&&(removeEventListener("beforeunload",this.beforeunloadEventListener,!1),removeEventListener("offline",this.offlineEventListener,!1)),this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this.prevBufferLen=0)}},{key:"filterUpgrades",value:function(e){for(var t=[],n=0,r=e.length;n<r;n++)~this.transports.indexOf(e[n])&&t.push(e[n]);return t}}]),a}(U);ge.protocol=4,ge.protocol;var me="function"==typeof ArrayBuffer,be=function(e){return"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(e):e.buffer instanceof ArrayBuffer},ke=Object.prototype.toString,we="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===ke.call(Blob),_e="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===ke.call(File);function Ee(e){return me&&(e instanceof ArrayBuffer||be(e))||we&&e instanceof Blob||_e&&e instanceof File}function Ae(t,n){if(!t||"object"!==e(t))return!1;if(Array.isArray(t)){for(var r=0,i=t.length;r<i;r++)if(Ae(t[r]))return!0;return!1}if(Ee(t))return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return Ae(t.toJSON(),!0);for(var o in t)if(Object.prototype.hasOwnProperty.call(t,o)&&Ae(t[o]))return!0;return!1}function Oe(e){var t=[],n=e.data,r=e;return r.data=Te(n,t),r.attachments=t.length,{packet:r,buffers:t}}function Te(t,n){if(!t)return t;if(Ee(t)){var r={_placeholder:!0,num:n.length};return n.push(t),r}if(Array.isArray(t)){for(var i=new Array(t.length),o=0;o<t.length;o++)i[o]=Te(t[o],n);return i}if("object"===e(t)&&!(t instanceof Date)){var s={};for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(s[a]=Te(t[a],n));return s}return t}function Re(e,t){return e.data=Ce(e.data,t),delete e.attachments,e}function Ce(t,n){if(!t)return t;if(t&&!0===t._placeholder){if("number"==typeof t.num&&t.num>=0&&t.num<n.length)return n[t.num];throw new Error("illegal attachments")}if(Array.isArray(t))for(var r=0;r<t.length;r++)t[r]=Ce(t[r],n);else if("object"===e(t))for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(t[i]=Ce(t[i],n));return t}var Be,Se=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];!function(e){e[e.CONNECT=0]="CONNECT",e[e.DISCONNECT=1]="DISCONNECT",e[e.EVENT=2]="EVENT",e[e.ACK=3]="ACK",e[e.CONNECT_ERROR=4]="CONNECT_ERROR",e[e.BINARY_EVENT=5]="BINARY_EVENT",e[e.BINARY_ACK=6]="BINARY_ACK"}(Be||(Be={}));var Ne=function(){function e(n){t(this,e),this.replacer=n}return r(e,[{key:"encode",value:function(e){return e.type!==Be.EVENT&&e.type!==Be.ACK||!Ae(e)?[this.encodeAsString(e)]:this.encodeAsBinary({type:e.type===Be.EVENT?Be.BINARY_EVENT:Be.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id})}},{key:"encodeAsString",value:function(e){var t=""+e.type;return e.type!==Be.BINARY_EVENT&&e.type!==Be.BINARY_ACK||(t+=e.attachments+"-"),e.nsp&&"/"!==e.nsp&&(t+=e.nsp+","),null!=e.id&&(t+=e.id),null!=e.data&&(t+=JSON.stringify(e.data,this.replacer)),t}},{key:"encodeAsBinary",value:function(e){var t=Oe(e),n=this.encodeAsString(t.packet),r=t.buffers;return r.unshift(n),r}}]),e}();function Le(e){return"[object Object]"===Object.prototype.toString.call(e)}var xe=function(e){o(i,e);var n=l(i);function i(e){var r;return t(this,i),(r=n.call(this)).reviver=e,r}return r(i,[{key:"add",value:function(e){var t;if("string"==typeof e){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");var n=(t=this.decodeString(e)).type===Be.BINARY_EVENT;n||t.type===Be.BINARY_ACK?(t.type=n?Be.EVENT:Be.ACK,this.reconstructor=new Pe(t),0===t.attachments&&p(s(i.prototype),"emitReserved",this).call(this,"decoded",t)):p(s(i.prototype),"emitReserved",this).call(this,"decoded",t)}else{if(!Ee(e)&&!e.base64)throw new Error("Unknown type: "+e);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");(t=this.reconstructor.takeBinaryData(e))&&(this.reconstructor=null,p(s(i.prototype),"emitReserved",this).call(this,"decoded",t))}}},{key:"decodeString",value:function(e){var t=0,n={type:Number(e.charAt(0))};if(void 0===Be[n.type])throw new Error("unknown packet type "+n.type);if(n.type===Be.BINARY_EVENT||n.type===Be.BINARY_ACK){for(var r=t+1;"-"!==e.charAt(++t)&&t!=e.length;);var o=e.substring(r,t);if(o!=Number(o)||"-"!==e.charAt(t))throw new Error("Illegal attachments");n.attachments=Number(o)}if("/"===e.charAt(t+1)){for(var s=t+1;++t;){if(","===e.charAt(t))break;if(t===e.length)break}n.nsp=e.substring(s,t)}else n.nsp="/";var a=e.charAt(t+1);if(""!==a&&Number(a)==a){for(var c=t+1;++t;){var u=e.charAt(t);if(null==u||Number(u)!=u){--t;break}if(t===e.length)break}n.id=Number(e.substring(c,t+1))}if(e.charAt(++t)){var h=this.tryParse(e.substr(t));if(!i.isPayloadValid(n.type,h))throw new Error("invalid payload");n.data=h}return n}},{key:"tryParse",value:function(e){try{return JSON.parse(e,this.reviver)}catch(e){return!1}}},{key:"destroy",value:function(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}],[{key:"isPayloadValid",value:function(e,t){switch(e){case Be.CONNECT:return Le(t);case Be.DISCONNECT:return void 0===t;case Be.CONNECT_ERROR:return"string"==typeof t||Le(t);case Be.EVENT:case Be.BINARY_EVENT:return Array.isArray(t)&&("number"==typeof t[0]||"string"==typeof t[0]&&-1===Se.indexOf(t[0]));case Be.ACK:case Be.BINARY_ACK:return Array.isArray(t)}}}]),i}(U),Pe=function(){function e(n){t(this,e),this.packet=n,this.buffers=[],this.reconPack=n}return r(e,[{key:"takeBinaryData",value:function(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){var t=Re(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}},{key:"finishedReconstruction",value:function(){this.reconPack=null,this.buffers=[]}}]),e}(),je=Object.freeze({__proto__:null,protocol:5,get PacketType(){return Be},Encoder:Ne,Decoder:xe});function qe(e,t,n){return e.on(t,n),function(){e.off(t,n)}}var De=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1}),Ue=function(e){o(a,e);var n=l(a);function a(e,r,o){var s;return t(this,a),(s=n.call(this)).connected=!1,s.recovered=!1,s.receiveBuffer=[],s.sendBuffer=[],s._queue=[],s._queueSeq=0,s.ids=0,s.acks={},s.flags={},s.io=e,s.nsp=r,o&&o.auth&&(s.auth=o.auth),s._opts=i({},o),s.io._autoConnect&&s.open(),s}return r(a,[{key:"disconnected",get:function(){return!this.connected}},{key:"subEvents",value:function(){if(!this.subs){var e=this.io;this.subs=[qe(e,"open",this.onopen.bind(this)),qe(e,"packet",this.onpacket.bind(this)),qe(e,"error",this.onerror.bind(this)),qe(e,"close",this.onclose.bind(this))]}}},{key:"active",get:function(){return!!this.subs}},{key:"connect",value:function(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}},{key:"open",value:function(){return this.connect()}},{key:"send",value:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.unshift("message"),this.emit.apply(this,t),this}},{key:"emit",value:function(e){if(De.hasOwnProperty(e))throw new Error('"'+e.toString()+'" is a reserved event name');for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];if(n.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(n),this;var i={type:Be.EVENT,data:n,options:{}};if(i.options.compress=!1!==this.flags.compress,"function"==typeof n[n.length-1]){var o=this.ids++,s=n.pop();this._registerAckCallback(o,s),i.id=o}var a=this.io.engine&&this.io.engine.transport&&this.io.engine.transport.writable;return this.flags.volatile&&(!a||!this.connected)||(this.connected?(this.notifyOutgoingListeners(i),this.packet(i)):this.sendBuffer.push(i)),this.flags={},this}},{key:"_registerAckCallback",value:function(e,t){var n,r=this,i=null!==(n=this.flags.timeout)&&void 0!==n?n:this._opts.ackTimeout;if(void 0!==i){var o=this.io.setTimeoutFn((function(){delete r.acks[e];for(var n=0;n<r.sendBuffer.length;n++)r.sendBuffer[n].id===e&&r.sendBuffer.splice(n,1);t.call(r,new Error("operation has timed out"))}),i),s=function(){r.io.clearTimeoutFn(o);for(var e=arguments.length,n=new Array(e),i=0;i<e;i++)n[i]=arguments[i];t.apply(r,n)};s.withError=!0,this.acks[e]=s}else this.acks[e]=t}},{key:"emitWithAck",value:function(e){for(var t=this,n=arguments.length,r=new Array(n>1?n-1:0),i=1;i<n;i++)r[i-1]=arguments[i];return new Promise((function(n,i){var o=function(e,t){return e?i(e):n(t)};o.withError=!0,r.push(o),t.emit.apply(t,[e].concat(r))}))}},{key:"_addToQueue",value:function(e){var t,n=this;"function"==typeof e[e.length-1]&&(t=e.pop());var r={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:i({fromQueue:!0},this.flags)};e.push((function(e){if(r===n._queue[0]){if(null!==e)r.tryCount>n._opts.retries&&(n._queue.shift(),t&&t(e));else if(n._queue.shift(),t){for(var i=arguments.length,o=new Array(i>1?i-1:0),s=1;s<i;s++)o[s-1]=arguments[s];t.apply(void 0,[null].concat(o))}return r.pending=!1,n._drainQueue()}})),this._queue.push(r),this._drainQueue()}},{key:"_drainQueue",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(this.connected&&0!==this._queue.length){var t=this._queue[0];t.pending&&!e||(t.pending=!0,t.tryCount++,this.flags=t.flags,this.emit.apply(this,t.args))}}},{key:"packet",value:function(e){e.nsp=this.nsp,this.io._packet(e)}},{key:"onopen",value:function(){var e=this;"function"==typeof this.auth?this.auth((function(t){e._sendConnectPacket(t)})):this._sendConnectPacket(this.auth)}},{key:"_sendConnectPacket",value:function(e){this.packet({type:Be.CONNECT,data:this._pid?i({pid:this._pid,offset:this._lastOffset},e):e})}},{key:"onerror",value:function(e){this.connected||this.emitReserved("connect_error",e)}},{key:"onclose",value:function(e,t){this.connected=!1,delete this.id,this.emitReserved("disconnect",e,t),this._clearAcks()}},{key:"_clearAcks",value:function(){var e=this;Object.keys(this.acks).forEach((function(t){if(!e.sendBuffer.some((function(e){return String(e.id)===t}))){var n=e.acks[t];delete e.acks[t],n.withError&&n.call(e,new Error("socket has been disconnected"))}}))}},{key:"onpacket",value:function(e){if(e.nsp===this.nsp)switch(e.type){case Be.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case Be.EVENT:case Be.BINARY_EVENT:this.onevent(e);break;case Be.ACK:case Be.BINARY_ACK:this.onack(e);break;case Be.DISCONNECT:this.ondisconnect();break;case Be.CONNECT_ERROR:this.destroy();var t=new Error(e.data.message);t.data=e.data.data,this.emitReserved("connect_error",t)}}},{key:"onevent",value:function(e){var t=e.data||[];null!=e.id&&t.push(this.ack(e.id)),this.connected?this.emitEvent(t):this.receiveBuffer.push(Object.freeze(t))}},{key:"emitEvent",value:function(e){if(this._anyListeners&&this._anyListeners.length){var t,n=y(this._anyListeners.slice());try{for(n.s();!(t=n.n()).done;){t.value.apply(this,e)}}catch(e){n.e(e)}finally{n.f()}}p(s(a.prototype),"emit",this).apply(this,e),this._pid&&e.length&&"string"==typeof e[e.length-1]&&(this._lastOffset=e[e.length-1])}},{key:"ack",value:function(e){var t=this,n=!1;return function(){if(!n){n=!0;for(var r=arguments.length,i=new Array(r),o=0;o<r;o++)i[o]=arguments[o];t.packet({type:Be.ACK,id:e,data:i})}}}},{key:"onack",value:function(e){var t=this.acks[e.id];"function"==typeof t&&(delete this.acks[e.id],t.withError&&e.data.unshift(null),t.apply(this,e.data))}},{key:"onconnect",value:function(e,t){this.id=e,this.recovered=t&&this._pid===t,this._pid=t,this.connected=!0,this.emitBuffered(),this.emitReserved("connect"),this._drainQueue(!0)}},{key:"emitBuffered",value:function(){var e=this;this.receiveBuffer.forEach((function(t){return e.emitEvent(t)})),this.receiveBuffer=[],this.sendBuffer.forEach((function(t){e.notifyOutgoingListeners(t),e.packet(t)})),this.sendBuffer=[]}},{key:"ondisconnect",value:function(){this.destroy(),this.onclose("io server disconnect")}},{key:"destroy",value:function(){this.subs&&(this.subs.forEach((function(e){return e()})),this.subs=void 0),this.io._destroy(this)}},{key:"disconnect",value:function(){return this.connected&&this.packet({type:Be.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}},{key:"close",value:function(){return this.disconnect()}},{key:"compress",value:function(e){return this.flags.compress=e,this}},{key:"volatile",get:function(){return this.flags.volatile=!0,this}},{key:"timeout",value:function(e){return this.flags.timeout=e,this}},{key:"onAny",value:function(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}},{key:"prependAny",value:function(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}},{key:"offAny",value:function(e){if(!this._anyListeners)return this;if(e){for(var t=this._anyListeners,n=0;n<t.length;n++)if(e===t[n])return t.splice(n,1),this}else this._anyListeners=[];return this}},{key:"listenersAny",value:function(){return this._anyListeners||[]}},{key:"onAnyOutgoing",value:function(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(e),this}},{key:"prependAnyOutgoing",value:function(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(e),this}},{key:"offAnyOutgoing",value:function(e){if(!this._anyOutgoingListeners)return this;if(e){for(var t=this._anyOutgoingListeners,n=0;n<t.length;n++)if(e===t[n])return t.splice(n,1),this}else this._anyOutgoingListeners=[];return this}},{key:"listenersAnyOutgoing",value:function(){return this._anyOutgoingListeners||[]}},{key:"notifyOutgoingListeners",value:function(e){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){var t,n=y(this._anyOutgoingListeners.slice());try{for(n.s();!(t=n.n()).done;){t.value.apply(this,e.data)}}catch(e){n.e(e)}finally{n.f()}}}}]),a}(U);function Ie(e){e=e||{},this.ms=e.min||100,this.max=e.max||1e4,this.factor=e.factor||2,this.jitter=e.jitter>0&&e.jitter<=1?e.jitter:0,this.attempts=0}Ie.prototype.duration=function(){var e=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var t=Math.random(),n=Math.floor(t*this.jitter*e);e=0==(1&Math.floor(10*t))?e-n:e+n}return 0|Math.min(e,this.max)},Ie.prototype.reset=function(){this.attempts=0},Ie.prototype.setMin=function(e){this.ms=e},Ie.prototype.setMax=function(e){this.max=e},Ie.prototype.setJitter=function(e){this.jitter=e};var Fe=function(n){o(s,n);var i=l(s);function s(n,r){var o,a;t(this,s),(o=i.call(this)).nsps={},o.subs=[],n&&"object"===e(n)&&(r=n,n=void 0),(r=r||{}).path=r.path||"/socket.io",o.opts=r,H(f(o),r),o.reconnection(!1!==r.reconnection),o.reconnectionAttempts(r.reconnectionAttempts||1/0),o.reconnectionDelay(r.reconnectionDelay||1e3),o.reconnectionDelayMax(r.reconnectionDelayMax||5e3),o.randomizationFactor(null!==(a=r.randomizationFactor)&&void 0!==a?a:.5),o.backoff=new Ie({min:o.reconnectionDelay(),max:o.reconnectionDelayMax(),jitter:o.randomizationFactor()}),o.timeout(null==r.timeout?2e4:r.timeout),o._readyState="closed",o.uri=n;var c=r.parser||je;return o.encoder=new c.Encoder,o.decoder=new c.Decoder,o._autoConnect=!1!==r.autoConnect,o._autoConnect&&o.open(),o}return r(s,[{key:"reconnection",value:function(e){return arguments.length?(this._reconnection=!!e,this):this._reconnection}},{key:"reconnectionAttempts",value:function(e){return void 0===e?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}},{key:"reconnectionDelay",value:function(e){var t;return void 0===e?this._reconnectionDelay:(this._reconnectionDelay=e,null===(t=this.backoff)||void 0===t||t.setMin(e),this)}},{key:"randomizationFactor",value:function(e){var t;return void 0===e?this._randomizationFactor:(this._randomizationFactor=e,null===(t=this.backoff)||void 0===t||t.setJitter(e),this)}},{key:"reconnectionDelayMax",value:function(e){var t;return void 0===e?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,null===(t=this.backoff)||void 0===t||t.setMax(e),this)}},{key:"timeout",value:function(e){return arguments.length?(this._timeout=e,this):this._timeout}},{key:"maybeReconnectOnOpen",value:function(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}},{key:"open",value:function(e){var t=this;if(~this._readyState.indexOf("open"))return this;this.engine=new ge(this.uri,this.opts);var n=this.engine,r=this;this._readyState="opening",this.skipReconnect=!1;var i=qe(n,"open",(function(){r.onopen(),e&&e()})),o=function(n){t.cleanup(),t._readyState="closed",t.emitReserved("error",n),e?e(n):t.maybeReconnectOnOpen()},s=qe(n,"error",o);if(!1!==this._timeout){var a=this._timeout,c=this.setTimeoutFn((function(){i(),o(new Error("timeout")),n.close()}),a);this.opts.autoUnref&&c.unref(),this.subs.push((function(){t.clearTimeoutFn(c)}))}return this.subs.push(i),this.subs.push(s),this}},{key:"connect",value:function(e){return this.open(e)}},{key:"onopen",value:function(){this.cleanup(),this._readyState="open",this.emitReserved("open");var e=this.engine;this.subs.push(qe(e,"ping",this.onping.bind(this)),qe(e,"data",this.ondata.bind(this)),qe(e,"error",this.onerror.bind(this)),qe(e,"close",this.onclose.bind(this)),qe(this.decoder,"decoded",this.ondecoded.bind(this)))}},{key:"onping",value:function(){this.emitReserved("ping")}},{key:"ondata",value:function(e){try{this.decoder.add(e)}catch(e){this.onclose("parse error",e)}}},{key:"ondecoded",value:function(e){var t=this;ce((function(){t.emitReserved("packet",e)}),this.setTimeoutFn)}},{key:"onerror",value:function(e){this.emitReserved("error",e)}},{key:"socket",value:function(e,t){var n=this.nsps[e];return n?this._autoConnect&&!n.active&&n.connect():(n=new Ue(this,e,t),this.nsps[e]=n),n}},{key:"_destroy",value:function(e){for(var t=0,n=Object.keys(this.nsps);t<n.length;t++){var r=n[t];if(this.nsps[r].active)return}this._close()}},{key:"_packet",value:function(e){for(var t=this.encoder.encode(e),n=0;n<t.length;n++)this.engine.write(t[n],e.options)}},{key:"cleanup",value:function(){this.subs.forEach((function(e){return e()})),this.subs.length=0,this.decoder.destroy()}},{key:"_close",value:function(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close"),this.engine&&this.engine.close()}},{key:"disconnect",value:function(){return this._close()}},{key:"onclose",value:function(e,t){this.cleanup(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",e,t),this._reconnection&&!this.skipReconnect&&this.reconnect()}},{key:"reconnect",value:function(){var e=this;if(this._reconnecting||this.skipReconnect)return this;var t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{var n=this.backoff.duration();this._reconnecting=!0;var r=this.setTimeoutFn((function(){t.skipReconnect||(e.emitReserved("reconnect_attempt",t.backoff.attempts),t.skipReconnect||t.open((function(n){n?(t._reconnecting=!1,t.reconnect(),e.emitReserved("reconnect_error",n)):t.onreconnect()})))}),n);this.opts.autoUnref&&r.unref(),this.subs.push((function(){e.clearTimeoutFn(r)}))}}},{key:"onreconnect",value:function(){var e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",e)}}]),s}(U),Me={};function Ve(t,n){"object"===e(t)&&(n=t,t=void 0);var r,i=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2?arguments[2]:void 0,r=e;n=n||"undefined"!=typeof location&&location,null==e&&(e=n.protocol+"//"+n.host),"string"==typeof e&&("/"===e.charAt(0)&&(e="/"===e.charAt(1)?n.protocol+e:n.host+e),/^(https?|wss?):\/\//.test(e)||(e=void 0!==n?n.protocol+"//"+e:"https://"+e),r=ve(e)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var i=-1!==r.host.indexOf(":")?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+i+":"+r.port+t,r.href=r.protocol+"://"+i+(n&&n.port===r.port?"":":"+r.port),r}(t,(n=n||{}).path||"/socket.io"),o=i.source,s=i.id,a=i.path,c=Me[s]&&a in Me[s].nsps;return n.forceNew||n["force new connection"]||!1===n.multiplex||c?r=new Fe(o,n):(Me[s]||(Me[s]=new Fe(o,n)),r=Me[s]),i.query&&!n.query&&(n.query=i.queryKey),r.socket(i.path,n)}return i(Ve,{Manager:Fe,Socket:Ue,io:Ve,connect:Ve}),Ve}));
//# sourceMappingURL=socket.io.min.js.map
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Socket.IO Test</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
background: #f4f6f8;
color: #1f2937;
font-family: Arial, "Microsoft YaHei", sans-serif;
}
main {
width: min(680px, calc(100vw - 32px));
padding: 24px;
background: #fff;
border: 1px solid #d8dee6;
border-radius: 8px;
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.08);
}
h1 {
margin: 0 0 18px;
font-size: 22px;
}
label {
display: block;
margin: 12px 0 6px;
font-size: 14px;
font-weight: 700;
}
input,
textarea {
width: 100%;
padding: 10px;
border: 1px solid #c7d0dc;
border-radius: 6px;
font-size: 14px;
font-family: inherit;
}
input {
height: 38px;
padding-top: 0;
padding-bottom: 0;
}
textarea {
min-height: 110px;
resize: vertical;
font-family: Consolas, Monaco, monospace;
}
.buttons {
display: contents;
gap: 10px;
margin-top: 16px;
flex-wrap: wrap;
}
button {
height: 38px;
padding: 0 14px;
border: 0;
border-radius: 6px;
background: #2563eb;
color: #fff;
font-size: 14px;
cursor: pointer;
}
button[disabled] {
background: #94a3b8;
cursor: not-allowed;
}
button.secondary {
background: #475569;
}
#status {
margin-top: 16px;
padding: 10px;
border-radius: 6px;
background: #eef2ff;
color: #1e3a8a;
font-size: 14px;
}
pre {
min-height: 160px;
margin: 16px 0 0;
padding: 12px;
overflow: auto;
border-radius: 6px;
background: #111827;
color: #d1fae5;
font-size: 13px;
line-height: 1.5;
white-space: pre-wrap;
word-break: break-word;
height: 300px;
}
</style>
</head>
<body>
<main>
<h1>Socket.IO 房间测试</h1>
<label for="serverUrl">后端地址</label>
<input id="serverUrl" value="http://localhost:8082">
<label for="userid">userid</label>
<input id="userid" value="">
<label for="countdownSecs">房间倒计时秒数</label>
<input id="countdownSecs" type="number" min="1" value="3">
<label for="score">分数</label>
<input id="score" type="number" value="100">
<div class="buttons">
<div>
<div style="border:1px solid #eb7d3d;">
管理员:<input type="checkbox" id="isAdmin" style="width:40px;">
</div>
<button type="button" onclick="connectSocket()">连接</button>
<button type="button" onclick="queryRoomState()">查询房间状态</button>
<button type="button" class="secondary" onclick="disconnectSocket()">断开</button>
<button type="button" class="secondary" onclick="clearLog()">清空日志</button>
</div>
<hr />
<button type="button" class="btn_admin" onclick="createRoom()">创建房间(管理人员)</button>
<button type="button" class="btn_admin" onclick="startGame()">开始游戏3秒倒计时(管理人员)</button>
<button type="button" class="btn_admin" onclick="closeRoom()">关闭房间(管理人员/自动)</button>
<button type="button" class="btn_player" onclick="joinRoom()">进入房间(玩家)</button>
<button type="button" class="btn_player" onclick="submitScore()">提交分数(玩家)</button>
</div>
<div id="status">未连接</div>
<pre id="log"></pre>
</main>
<!-- <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@msgpack/msgpack@3.1.2/dist.umd/msgpack.min.js"></script> -->
<script src="assets/socket.io.min.js"></script>
<script src="assets/crypto-js.min.js"></script>
<script src="assets/msgpack.min.js"></script>
<script>
let aesPassphrase = "";
let token = "";
let socket = null;
let stopReconnectAfterRoomClose = false;
const $$ = (id) => Array.from(document.querySelectorAll(id) || []);
async function login(username, password) {
const res = await fetch("/manager/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
});
const data = await res.json();
if (!res.ok || data.state !== 1) {
alert('管理员登录异常')
throw new Error(data.msg || "登录失败");
}
return data.data;
};
$$("#isAdmin")[0].addEventListener("change", function () {
if (this.checked) {
$$(".btn_admin").map(x => x.removeAttribute("disabled"));
$$(".btn_player").map(x => x.setAttribute("disabled", "disabled"));
login('admin', '123456').then(res => {
aesPassphrase = res.passphrase;
token = res.token;
})
} else {
aesPassphrase = "";
token = "";
$$(".btn_admin").map(x => x.setAttribute("disabled", "disabled"));
$$(".btn_player").map(x => x.removeAttribute("disabled"));
}
});
$$("#isAdmin")[0].dispatchEvent(new Event("change"))
function log(message, data) {
const line = `[${new Date().toLocaleTimeString()}] ${message}`;
const extra = data === undefined ? "" : `\n${JSON.stringify(data, null, 2)}`;
document.getElementById("log").textContent += `${line}${extra}\n`;
console.log(message, data);
}
function setStatus(text) {
document.getElementById("status").textContent = text;
}
function decodeMsgpackPayload(payload) {
if (payload instanceof ArrayBuffer) {
return MessagePack.decode(new Uint8Array(payload));
}
if (payload instanceof Uint8Array) {
return MessagePack.decode(payload);
}
return payload;
}
function normalizeServerUrl() {
const input = document.getElementById("serverUrl");
let url = input.value.trim();
if (!url && window.location.origin !== "null") {
url = window.location.origin;
}
if (!url) {
url = "http://127.0.0.1:8082";
}
input.value = url;
return url.replace(/\/$/, "");
}
currentUserId();
function currentUserId() {
let u = document.getElementById("userid");
let userid = u.value.trim();
if (userid) {
return userid;
}
userid = "user_" + Math.random().toString(16).slice(2, 8);
u.value = userid;
return userid;
}
function currentCountdownSecs() {
return Math.max(1, Number(document.getElementById("countdownSecs").value || 3));
}
function currentScore() {
return Number(document.getElementById("score").value || 0);
}
function connectSocket() {
const serverUrl = normalizeServerUrl();
const userid = currentUserId(false);
if (!userid) {
setStatus("请填写 userid");
return;
}
if (socket) {
socket.disconnect();
}
stopReconnectAfterRoomClose = false;
let auth = { userid };
let is_admin = document.getElementById("isAdmin").checked;
if (is_admin) {
auth.userid = token;
auth.validuser = CryptoJS.AES.encrypt(token, aesPassphrase).toString();
}
log("准备连接", {
namespace: "/ws",
path: "/socket.io"
});
socket = io(`/ws`, {
path: "/socket.io",
auth,
transports: ["websocket"],
upgrade: false,
forceNew: true,
timeout: 10000
});
socket.on("connect", () => {
setStatus(`已连接: ${socket.id}`);
log("connect", { id: socket.id });
});
socket.on("disconnect", (reason) => {
setStatus(`已断开: ${reason}`);
log("disconnect", { reason });
if (stopReconnectAfterRoomClose) {
socket = null;
}
});
socket.on("connect_error", (err) => {
setStatus(`连接失败: ${err.message}`);
log("connect_error", { message: err.message });
});
socket.onAny((event, payload) => {
const data = decodeMsgpackPayload(payload);
log(`receive: ${event}`, data);
switch (event) {
// case "connect_result"://游戏未开放
// break;
case "room_close_result"://房间关闭
closeSocketAfterRoomClose(data);
break;
}
});
}
function closeSocketAfterRoomClose(data) {
if (!socket) {
return;
}
stopReconnectAfterRoomClose = true;
socket.io.opts.reconnection = false;
setStatus("房间已关闭,正在断开连接");
log("room_close_result -> disconnect", data);
socket.disconnect();
}
function emitMessage(message, statusText) {
if (!socket || !socket.connected) {
setStatus("请先连接");
return false;
}
socket.emit("message", MessagePack.encode(message));
setStatus(statusText);
log("send message", message);
return true;
}
function createRoom() {
emitMessage({ cmd: "room_create", data: {} }, "已发送: room_create");
}
function joinRoom() {
emitMessage({ cmd: "room_join", data: { "nickname": currentUserId(), "telephone": "", "avatar": "" } }, "已发送: room_join");
}
function startGame() {
emitMessage({ cmd: "game_start", data: currentCountdownSecs() }, "已发送: game_start");
}
function submitScore() {
emitMessage({ cmd: "submit_score", data: { score: currentScore(), time: 10 } }, "已发送: submit_score");
}
function closeRoom() {
emitMessage({ cmd: "room_close", data: {} }, "已发送: room_close");
}
function queryRoomState() {
emitMessage({ cmd: "room_state", data: {} }, "已发送: room_state");
}
function disconnectSocket() {
if (socket) {
socket.disconnect();
socket = null;
}
}
function clearLog() {
document.getElementById("log").textContent = "";
}
</script>
</body>
</html>
\ No newline at end of file
.DS_Store
temp
library
local
release
node_modules
bin/js/bundles
\ No newline at end of file
{
"perFolder": true,
"includeSubFolders": true,
"maxWidth": 2048,
"maxHeight": 2048,
"eachMaxWidth": 512,
"eachMaxHeight": 512,
"format": 0,
"scale": 1,
"pot": false,
"trimImage": true
}
\ No newline at end of file
{
"uuid": "e6f47f36-13e3-4ecc-bc13-9d63b60062b3"
}
\ No newline at end of file
{
"uuid": "60a9086c-a9c2-4e01-a563-355c117b509e",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "d4cfd6a8-0d0a-475b-ac93-d85eaa646936",
"importer": {
"textureType": 2,
"sizeGrid": [
10,
14,
14,
16,
0
],
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "55da1537-1ec8-4cdf-9b6f-f0d4af0431b0",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "f0c051af-cf42-4abc-82e4-59f42ac888ee",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "e3cd8344-3bd6-4059-b771-a0ea99f96aad",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "d58d2a39-1cb4-49a1-a4fa-0664f5265e1a",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "6aa5b064-ff17-4273-a317-9778b9f4f67a",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "e1e83785-4a8e-42a5-a8ac-51d5ff2cb436",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "f64d4387-f2c7-4e48-bea1-a0dfd22a109d",
"importer": {
"textureType": 2,
"sizeGrid": [
0,
74,
0,
17,
0
],
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "2f7b7200-e363-4ffc-b9a4-62437a2302ab",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "d24c1cbc-0657-41fa-a966-471705de2af1",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "5344e14f-1c62-43c8-a00a-5593ca19bdbf",
"importer": {
"textureType": 2,
"stateNum": 3,
"sizeGrid": [
10,
10,
10,
10,
0
]
}
}
\ No newline at end of file
{
"uuid": "34582d14-0e49-41c3-9bac-3d12def95ef9",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "679b3902-4c06-412d-aeef-7efca529bf41",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "59679c29-d461-4664-be07-bc2bd95e4360",
"importer": {
"textureType": 2,
"sizeGrid": [
9,
9,
9,
9,
0
]
}
}
\ No newline at end of file
{
"uuid": "35922f9e-69f5-4993-b37e-dbfc1504aece",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "051feaa7-15db-4143-958c-161475961a6b",
"importer": {
"textureType": 2,
"sizeGrid": [
9,
9,
9,
9,
0
]
}
}
\ No newline at end of file
{
"uuid": "c13c1b8e-c516-4a0f-98ad-e356f45f0365",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "3225dc27-5bcb-446e-8b66-27df87624835",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "b86ab1e4-4348-47f0-96e7-771387714bfc",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "1fc7a268-7071-4e5d-88be-a125afa0e2c8",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "dda0809b-cfe4-41b3-a392-8bd79c456ee1",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "8daa4e1f-cba7-4117-b0d3-eb5c7ad9eefa",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "2123a790-201a-4900-8885-b7ef9a27cfba",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "5c14adcd-87f9-4670-b165-7a77a56f3e00",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "0128a93d-b244-40e4-bc90-48a93a3d87a2",
"importer": {
"textureType": 2,
"sizeGrid": [
0,
18,
0,
23,
0
]
}
}
\ No newline at end of file
{
"uuid": "ae3de75e-ee9f-478d-9f8b-ede75a4fc296",
"importer": {
"textureType": 2,
"sizeGrid": [
0,
21,
0,
17,
0
]
}
}
\ No newline at end of file
{
"uuid": "41488331-0ed3-4c38-959b-6ecc4fdac7e6",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "7db29ccb-50d2-461e-9b1c-8479ff20673f",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "c7ce584a-c256-462a-aa94-a9905f7185aa",
"importer": {
"textureType": 2,
"sizeGrid": [
0,
28,
0,
24,
0
],
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "9eb4836d-78c4-4be3-aa53-70a613fef28d",
"importer": {
"textureType": 2,
"sizeGrid": [
10,
12,
10,
12
]
}
}
\ No newline at end of file
{
"uuid": "87262606-4dfe-490e-8644-7fd6496c2be7",
"importer": {
"textureType": 2,
"sizeGrid": [
10,
12,
10,
12
]
}
}
\ No newline at end of file
{
"uuid": "d79c761b-6bc3-49e0-9e51-bd2ba385cfe0",
"importer": {
"textureType": 2,
"stateNum": 3,
"sizeGrid": [
10,
10,
10,
10,
0
]
}
}
\ No newline at end of file
{
"uuid": "a62dfa59-dd5c-491c-8d7a-346205a51a5b",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "c1da2147-6391-438e-a9a3-6f2dfb6b32d3",
"importer": {
"textureType": 2,
"stateNum": 3
}
}
\ No newline at end of file
{
"uuid": "fc3bb457-8d97-4456-b6b6-304c6b064689",
"importer": {
"textureType": 2,
"sizeGrid": [
11,
9,
11,
9,
0
]
}
}
\ No newline at end of file
{
"uuid": "80000f74-4f4f-4c1c-bb95-49b2cc94c28d",
"importer": {
"textureType": 2,
"stateNum": 3,
"sizeGrid": [
10,
10,
10,
10,
0
]
}
}
\ No newline at end of file
{
"uuid": "a9debde7-d669-4b6a-baae-ca10374f427f",
"importer": {
"textureType": 2,
"sizeGrid": [
9,
9,
9,
9,
0
]
}
}
\ No newline at end of file
{
"uuid": "886b7c67-6f45-441b-9c58-82f98a4cd6e8",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "64ea0b5c-8a4e-4fc3-8019-ada3ef1af1e1",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "ea3a22ca-d808-4508-90c0-5a670d3fd797",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "1ccfa7d1-a0fa-404c-83f9-33441c7da755",
"importer": {
"textureType": 2
}
}
\ No newline at end of file
{
"uuid": "c95ef96a-e095-434f-95a4-58156890681f",
"importer": {
"textureType": 2,
"sRGB": true,
"generateMipmap": true
}
}
\ No newline at end of file
{
"_$ver": 1,
"_$id": "su6vdov1",
"_$type": "Scene",
"left": 0,
"right": 0,
"top": 0,
"bottom": 0,
"name": "Scene2D",
"width": 750,
"height": 1334,
"_$comp": [
{
"_$type": "a8cc1a35-7c2b-445f-ab6c-d17538bdec78",
"scriptPath": "scripts/Scene1.ts",
"text": ""
}
],
"_$child": [
{
"_$id": "q8p6zavc",
"_$type": "Sprite",
"name": "Background",
"width": 750,
"height": 1334,
"texture": {
"_$uuid": "ea3a22ca-d808-4508-90c0-5a670d3fd797",
"_$type": "Texture"
}
},
{
"_$id": "4w2kv0o3",
"_$type": "Area2D",
"name": "SafeRoot",
"width": 750,
"height": 1334
}
]
}
\ No newline at end of file
{
"uuid": "ced3e0b8-68a0-4b07-a953-4b4ac20d14c2"
}
\ No newline at end of file
{
"_$ver": 1,
"_$id": "er21fais",
"_$type": "Scene",
"left": 0,
"right": 0,
"top": 0,
"bottom": 0,
"name": "Scene2D",
"width": 750,
"height": 1334,
"_$comp": [
{
"_$type": "751938ac-3141-4e65-841b-e7a22d6d4225",
"scriptPath": "scripts/Scene2.ts",
"text": ""
}
],
"_$child": [
{
"_$id": "oefu9m15",
"_$type": "Sprite",
"name": "Background",
"width": 750,
"height": 1334,
"texture": {
"_$uuid": "ea3a22ca-d808-4508-90c0-5a670d3fd797",
"_$type": "Texture"
}
},
{
"_$id": "s7li8vi2",
"_$type": "Area2D",
"name": "SafeRoot",
"width": 750,
"height": 1334,
"_$child": [
{
"_$id": "eyvi3kzg",
"_$type": "GImage",
"name": "Picture",
"x": 174,
"y": 502,
"width": 376,
"height": 371,
"src": "res://886b7c67-6f45-441b-9c58-82f98a4cd6e8",
"autoSize": false
}
]
}
]
}
\ No newline at end of file
{
"uuid": "ddc30f5e-6160-46eb-a29d-c487be4745f9"
}
\ No newline at end of file
{
"_$ver": 1,
"_$id": "dg0saqye",
"_$type": "Scene",
"left": 0,
"right": 0,
"top": 0,
"bottom": 0,
"name": "Scene2D",
"width": 750,
"height": 1334,
"_$comp": [
{
"_$type": "a07a37ad-7b93-4ef6-8ddd-73d220a2060e",
"scriptPath": "scripts/Scene3.ts",
"text": ""
}
],
"_$child": [
{
"_$id": "phvmn5qc",
"_$type": "Sprite",
"name": "Background",
"width": 750,
"height": 1334,
"texture": {
"_$uuid": "ea3a22ca-d808-4508-90c0-5a670d3fd797",
"_$type": "Texture"
}
},
{
"_$id": "n2bb71vk",
"_$type": "Area2D",
"name": "SafeRoot",
"width": 750,
"height": 1334
}
]
}
\ No newline at end of file
{
"uuid": "1e5519db-0700-4e4f-8f40-1f159e66cb37"
}
\ No newline at end of file
{
"_$ver": 1,
"_$id": "i5obie21",
"_$type": "Scene",
"left": 0,
"right": 0,
"top": 0,
"bottom": 0,
"name": "Scene2D",
"width": 750,
"height": 1334,
"_$comp": [
{
"_$type": "0dcd39b4-488a-4616-9399-33952cafb075",
"scriptPath": "scripts/Scene4.ts",
"text": ""
}
],
"_$child": [
{
"_$id": "u4qd8nhs",
"_$type": "Sprite",
"name": "Background",
"width": 750,
"height": 1334,
"texture": {
"_$uuid": "ea3a22ca-d808-4508-90c0-5a670d3fd797",
"_$type": "Texture"
}
},
{
"_$id": "qu7p187c",
"_$type": "Area2D",
"name": "SafeRoot",
"width": 750,
"height": 1334
}
]
}
\ No newline at end of file
{
"uuid": "c17b6f7e-6d2c-4b16-9a0b-1898d3c55aba"
}
\ No newline at end of file
{
"_$ver": 1,
"_$id": "wk6y87gu",
"_$type": "Scene",
"left": 0,
"right": 0,
"top": 0,
"bottom": 0,
"name": "Scene2D",
"width": 750,
"height": 1334,
"_$comp": [
{
"_$type": "584f2d9c-b194-4ff2-8ebb-724d9932b1b7",
"scriptPath": "scripts/Scene5.ts",
"text": ""
}
],
"_$child": [
{
"_$id": "2mufmlr8",
"_$type": "Sprite",
"name": "Background",
"width": 750,
"height": 1334,
"texture": {
"_$uuid": "ea3a22ca-d808-4508-90c0-5a670d3fd797",
"_$type": "Texture"
}
},
{
"_$id": "hrhfuebp",
"_$type": "Area2D",
"name": "SafeRoot",
"width": 750,
"height": 1334,
"_$child": [
{
"_$id": "covhu04n",
"_$type": "Area2D",
"name": "Horses",
"x": 2,
"y": 316,
"width": 745,
"height": 607,
"_$child": [
{
"_$id": "maj4if5e",
"_$type": "Animation",
"name": "Horse_0",
"x": 82,
"y": 366,
"width": 160,
"height": 160,
"source": "",
"index": 0,
"interval": 50
}
]
}
]
},
{
"_$id": "m4c3t10r",
"_$type": "Area2D",
"name": "Ring",
"x": 343,
"y": 1026,
"width": 101,
"height": 62
}
]
}
\ No newline at end of file
{
"uuid": "59599a02-b115-4cf8-b85f-5fab814a508b"
}
\ No newline at end of file
{
"_$ver": 1,
"_$id": "x89plgb0",
"_$type": "Scene",
"left": 0,
"right": 0,
"top": 0,
"bottom": 0,
"name": "Scene2D",
"width": 750,
"height": 1334,
"_$comp": [
{
"_$type": "e4bb588d-8f00-4c44-920e-5be473eac223",
"scriptPath": "scripts/Scene6.ts",
"text": ""
}
],
"_$child": [
{
"_$id": "xugxwwm9",
"_$type": "Sprite",
"name": "Background",
"width": 750,
"height": 1334,
"texture": {
"_$uuid": "ea3a22ca-d808-4508-90c0-5a670d3fd797",
"_$type": "Texture"
}
},
{
"_$id": "saferoot1",
"_$type": "Area2D",
"name": "SafeRoot",
"width": 750,
"height": 1334,
"_$child": [
{
"_$id": "m4kzgbb7",
"_$type": "Animation",
"name": "Mole_0",
"x": 164,
"y": 427,
"width": 93,
"height": 91,
"source": "",
"images": [],
"autoPlay": true,
"index": 0,
"interval": 50
},
{
"_$id": "euopi6zq",
"_$type": "Animation",
"name": "Mole_1",
"x": 497,
"y": 427,
"width": 93,
"height": 91,
"source": "",
"images": [],
"autoPlay": true,
"index": 0,
"interval": 50
},
{
"_$id": "drqo92ys",
"_$type": "Animation",
"name": "Mole_2",
"x": 103,
"y": 634,
"width": 93,
"height": 91,
"source": "",
"images": [],
"autoPlay": true,
"index": 0,
"interval": 50
},
{
"_$id": "pagpo6c9",
"_$type": "Animation",
"name": "Mole_3",
"x": 325,
"y": 634,
"width": 93,
"height": 91,
"source": "",
"images": [],
"autoPlay": true,
"index": 0,
"interval": 50
},
{
"_$id": "gldysobm",
"_$type": "Animation",
"name": "Mole_4",
"x": 545,
"y": 634,
"width": 93,
"height": 91,
"source": "",
"images": [],
"autoPlay": true,
"index": 0,
"interval": 50
},
{
"_$id": "1st1816x",
"_$type": "Animation",
"name": "Mole_5",
"x": 149,
"y": 870,
"width": 93,
"height": 91,
"source": "",
"images": [],
"autoPlay": true,
"index": 0,
"interval": 50
},
{
"_$id": "qmphnssw",
"_$type": "Animation",
"name": "Mole_6",
"x": 482,
"y": 870,
"width": 93,
"height": 91,
"source": "",
"images": [],
"autoPlay": true,
"index": 0,
"interval": 50
}
]
}
]
}
\ No newline at end of file
{
"uuid": "3569976b-b864-43be-8207-f89dbd93ffc0"
}
\ No newline at end of file
import { socketIOOptionsConfig } from "../../src/Config";
import { SocketIOClient, SocketIOClientOptions, SocketIOMessage } from "../../src/WS";
export type SpriteSheetAnimationOptions = {
target: Laya.Animation;
urls: string[];
columns: number;
rows: number;
startFrame?: number;
endFrame?: number;
interval?: number;
};
export type SpriteSheetAnimationConfig = {
columns: number;
rows: number;
startFrame?: number;
endFrame?: number;
interval?: number;
};
export type PixelHitInputOptions = {
eventName?: string;
pixelHitTest?: boolean;
alphaThreshold?: number;
hitWhenPixelReadFails?: boolean;
};
type ClickInputHandler = {
eventName: string;
callback: (event: Laya.Event) => void;
};
export type SafeAreaRect = {
x: number;
y: number;
width: number;
height: number;
};
export class BaseScene extends Laya.Script {
declare owner: Laya.Scene;
private static socketClient: SocketIOClient | null = null;
protected bg: Laya.Sprite;
protected safeRoot: Laya.Area2D;
protected designWidth: number = 750;
protected designHeight: number = 1334;
protected showSafeAreaDebug: boolean = true;
private animationFrameHandlers: Map<Laya.Animation, () => void> = new Map();
private clickHandlers: Map<Laya.Sprite, ClickInputHandler> = new Map();
isRunLocal(): boolean {
if (/(?:^file:\/\/)|(?:^blob:\/\/)/.test(window.location.protocol)) {
return true;
}
if (/(?:192\.168)|(?:localhost)/.test(window.location.href)) {
return true;
}
return false;
}
protected initSocket(options: Partial<SocketIOClientOptions> = {}): void {
const socketOptions: SocketIOClientOptions = {
...socketIOOptionsConfig,
...options
};
if (!BaseScene.socketClient) {
BaseScene.socketClient = new SocketIOClient(socketOptions);
} else {
BaseScene.socketClient.updateOptions(socketOptions);
}
BaseScene.socketClient
.onConnect((socket) => {
console.log("socket.io connect", socket.id);
})
.onMessage((eventName, { state, msg, data }) => {
console.log("socket.io message:", eventName, {
state,
msg,
data
});
})
.onDisconnect((reason, details) => {
console.log("socket.io disconnect", {
reason,
details,
time: new Date().toLocaleTimeString()
});
})
.onReconnectAttempt((attempt) => {
console.log("socket.io reconnect", {
attempt
});
})
.onError((err) => {
console.log(err);
});
BaseScene.socketClient.connect();
}
protected sendSocket(message: SocketIOMessage): boolean {
return BaseScene.socketClient?.send(message) ?? false;
}
closeSocket(): void {
BaseScene.socketClient?.disconnect();
BaseScene.socketClient = null;
}
protected get isSocketConnected(): boolean {
return BaseScene.socketClient?.isConnected ?? false;
}
onEnable(): void {
this.initSocket();
Laya.stage.on(Laya.Event.RESIZE, this, this.onStageResize);
Laya.stage.on(Laya.Event.BLUR, this, this.onStageBlur);
Laya.stage.on(Laya.Event.FOCUS, this, this.onStageFocus);
}
onDisable(): void {
Laya.stage.off(Laya.Event.RESIZE, this, this.onStageResize);
Laya.stage.off(Laya.Event.BLUR, this, this.onStageBlur);
Laya.stage.off(Laya.Event.FOCUS, this, this.onStageFocus);
this.clearClickInputs();
this.clearSpriteSheetAnimations();
}
protected onStageResize(): void {
this.resizeBaseSceneLayout();
}
protected onStageBlur(): void {
}
protected onStageFocus(): void {
}
protected setupBaseSceneLayout(): void {
this.bg = this.owner.getChildByName("Background") as Laya.Sprite;
this.safeRoot = this.owner.getChildByName("SafeRoot") as Laya.Area2D;
if (!this.safeRoot) {
this.safeRoot = new Laya.Area2D();
this.safeRoot.name = "SafeRoot";
this.owner.addChild(this.safeRoot);
}
this.resizeBaseSceneLayout();
}
protected onBaseLayoutResized(): void {
}
protected resizeBaseSceneLayout(): void {
this.resizeBackground();
this.resizeSafeRoot();
this.onBaseLayoutResized();
}
protected setupClickInput(
target: Laya.Sprite,
callback: (event: Laya.Event) => void,
options: PixelHitInputOptions = {}
): void {
if (!target) {
return;
}
this.clearClickInput(target);
const eventName = options.eventName || Laya.Event.MOUSE_DOWN;
const pixelHitTest = options.pixelHitTest ?? false;
const alphaThreshold = options.alphaThreshold ?? 10;
const hitWhenPixelReadFails = options.hitWhenPixelReadFails ?? true;
const hitCallback = (event: Laya.Event) => {
if (pixelHitTest && !this.isTexturePixelHit(target, event, alphaThreshold, hitWhenPixelReadFails)) {
return;
}
callback(event);
};
target.mouseEnabled = true;
target.hitArea = new Laya.Rectangle(0, 0, target.width, target.height);
this.clickHandlers.set(target, {
eventName,
callback: hitCallback
});
target.on(eventName, this, hitCallback);
}
protected clearClickInput(target: Laya.Sprite): void {
if (!target) {
return;
}
const handler = this.clickHandlers.get(target);
if (!handler) {
return;
}
target.off(handler.eventName, this, handler.callback);
this.clickHandlers.delete(target);
}
protected setupSpriteSheetAnimation(options: SpriteSheetAnimationOptions): void {
const interval = options.interval || 50;
this.loadFirstTexture(options.urls).then((texture: Laya.Texture) => {
if (!texture) {
console.warn(`Sprite sheet load failed: ${options.urls.join(", ")}`);
return;
}
const frames = this.createSpriteSheetFrames(
texture,
options.columns,
options.rows,
options.startFrame,
options.endFrame
);
if (frames.length === 0) {
return;
}
this.playSpriteSheetAnimation(options.target, frames, interval);
});
}
protected clearSpriteSheetAnimation(target: Laya.Animation): void {
const updateFrame = this.animationFrameHandlers.get(target);
if (!updateFrame) {
return;
}
Laya.timer.clear(this, updateFrame);
this.animationFrameHandlers.delete(target);
}
protected getSceneNode<T extends Laya.Node>(name: string): T {
return (this.safeRoot?.findChild(name) || this.owner.findChild(name)) as T;
}
protected getSafeArea(): SafeAreaRect {
const stageWidth = Laya.stage.width;
const stageHeight = Laya.stage.height;
const defaultArea = { x: 0, y: 0, width: stageWidth, height: stageHeight };
const platform = this.getMiniGamePlatform();
if (!platform?.getSystemInfoSync) {
return defaultArea;
}
const info = platform.getSystemInfoSync();
const safe = info?.safeArea;
if (!safe || !info.windowWidth || !info.windowHeight) {
return defaultArea;
}
const scaleX = stageWidth / info.windowWidth;
const scaleY = stageHeight / info.windowHeight;
return {
x: safe.left * scaleX,
y: safe.top * scaleY,
width: safe.width * scaleX,
height: safe.height * scaleY
};
}
protected drawNodeBorder(node: Laya.Sprite, color: string = "#ff3333"): void {
if (!node) {
return;
}
/// 仅在本地环境下绘制边框,避免线上性能问题和潜在的像素读取失败
if (!this.isRunLocal()) {
return;
}
node.graphics.clear();
node.graphics.drawRect(0, 0, node.width, node.height, null, color, 2);
}
private resizeBackground(): void {
if (!this.bg) {
return;
}
const stageWidth = Laya.stage.width;
const stageHeight = Laya.stage.height;
const scale = Math.max(stageWidth / this.designWidth, stageHeight / this.designHeight);
this.bg.scaleX = scale;
this.bg.scaleY = scale;
this.bg.x = (stageWidth - this.designWidth * scale) * 0.5;
this.bg.y = (stageHeight - this.designHeight * scale) * 0.5;
}
private resizeSafeRoot(): void {
if (!this.safeRoot) {
return;
}
const safeArea = this.getSafeArea();
this.safeRoot.pos(safeArea.x, safeArea.y);
this.safeRoot.size(safeArea.width, safeArea.height);
this.drawSafeAreaDebug(safeArea.width, safeArea.height);
}
private drawSafeAreaDebug(width: number, height: number): void {
this.safeRoot.graphics.clear();
if (!this.showSafeAreaDebug) {
return;
}
this.safeRoot.graphics.drawRect(0, 0, width, height, "rgba(0,255,128,0.12)", "#00ff80", 4);
}
private clearClickInputs(): void {
this.clickHandlers.forEach((handler: ClickInputHandler, target: Laya.Sprite) => {
target.off(handler.eventName, this, handler.callback);
});
this.clickHandlers.clear();
}
private clearSpriteSheetAnimations(): void {
this.animationFrameHandlers.forEach((updateFrame: () => void) => {
Laya.timer.clear(this, updateFrame);
});
this.animationFrameHandlers.clear();
}
private isTexturePixelHit(
target: Laya.Sprite,
event: Laya.Event,
alphaThreshold: number,
hitWhenPixelReadFails: boolean
): boolean {
const texture = target.texture;
if (!texture || target.width <= 0 || target.height <= 0) {
return false;
}
const localPoint = target.globalToLocal(new Laya.Point(event.stageX, event.stageY));
if (
localPoint.x < 0 ||
localPoint.y < 0 ||
localPoint.x >= target.width ||
localPoint.y >= target.height
) {
return false;
}
const textureX = Math.floor(localPoint.x / target.width * texture.width);
const textureY = Math.floor(localPoint.y / target.height * texture.height);
try {
const pixels = texture.getPixels(textureX, textureY, 1, 1);
return !!pixels && pixels.length >= 4 && pixels[3] > alphaThreshold;
} catch (error) {
console.warn("Texture pixel hit test failed", error);
return hitWhenPixelReadFails;
}
}
private async loadFirstTexture(urls: string[]): Promise<Laya.Texture> {
for (const url of urls) {
const cachedTexture = Laya.Loader.getRes(url) as Laya.Texture;
if (cachedTexture) {
return cachedTexture;
}
try {
const texture = await Laya.loader.load(url, Laya.Loader.IMAGE) as Laya.Texture;
if (texture) {
return texture;
}
} catch (error) {
console.warn(`Texture load error: ${url}`, error);
}
}
return null;
}
private createSpriteSheetFrames(
sheet: Laya.Texture,
columns: number,
rows: number,
startFrame: number = 0,
endFrame: number = columns * rows - 1
): Laya.Texture[] {
const frameWidth = sheet.width / columns;
const frameHeight = sheet.height / rows;
const totalFrames = columns * rows;
const firstFrame = Math.max(0, Math.min(startFrame, totalFrames - 1));
const lastFrame = Math.max(firstFrame, Math.min(endFrame, totalFrames - 1));
const frames: Laya.Texture[] = [];
for (let index = firstFrame; index <= lastFrame; index++) {
const column = index % columns;
const row = Math.floor(index / columns);
frames.push(Laya.Texture.create(
sheet,
column * frameWidth,
row * frameHeight,
frameWidth,
frameHeight
));
}
return frames;
}
private playSpriteSheetAnimation(target: Laya.Animation, frames: Laya.Texture[], interval: number): void {
this.clearSpriteSheetAnimation(target);
let frameIndex = 0;
const updateFrame = () => {
target.texture = frames[frameIndex];
frameIndex = (frameIndex + 1) % frames.length;
};
target.interval = interval;
updateFrame();
this.animationFrameHandlers.set(target, updateFrame);
Laya.timer.loop(interval, this, updateFrame);
}
private getMiniGamePlatform(): any {
const globalObj = window as any;
return globalObj.wx || globalObj.tt || globalObj.qq || globalObj.swan || globalObj.my;
}
protected setupMoleAnimation(mole: Laya.Animation, config: SpriteSheetAnimationConfig, urls: string[]): void {
if (!mole) {
return;
}
// this.drawNodeBorder(mole, "#ff3333");
this.setupSpriteSheetAnimation({
target: mole,
urls,
columns: config.columns,
rows: config.rows,
startFrame: config.startFrame,
endFrame: config.endFrame,
interval: config.interval
});
}
}
{
"uuid": "4b175f9d-ffe1-4d7c-8cd6-b5489c88ebc7"
}
import { BaseScene } from "./BaseScene";
const { regClass, property } = Laya;
@regClass()
export class Scene1 extends BaseScene {
@property(String)
public text: string = "";
//组件被激活后执行,此时所有节点和组件均已创建完毕,此方法只执行一次
onAwake(): void {
console.log("Scene1 awake");
this.setupBaseSceneLayout();
}
//组件被启用后执行,例如节点被添加到舞台后
//onEnable(): void {}
//组件被禁用时执行,例如从节点从舞台移除后
//onDisable(): void {}
//第一次执行update之前执行,只会执行一次
//onStart(): void {}
//手动调用节点销毁时执行
//onDestroy(): void {}
//每帧更新时执行,尽量不要在这里写大循环逻辑或者使用getComponent方法
//onUpdate(): void {}
//每帧更新时执行,在update之后执行,尽量不要在这里写大循环逻辑或者使用getComponent方法
//onLateUpdate(): void {}
//鼠标点击后执行。与交互相关的还有onMouseDown等十多个函数,具体请参阅文档。
//onMouseClick(): void {}
}
{
"uuid": "a8cc1a35-7c2b-445f-ab6c-d17538bdec78"
}
\ No newline at end of file
import { BaseScene } from "./BaseScene";
const { regClass, property } = Laya;
@regClass()
export class Scene2 extends BaseScene {
@property(String)
public text: string = "";
private picture: Laya.Sprite;
private isRotatingPicture: boolean = false;
private startPointerAngle: number = 0;
private startPictureRotation: number = 0;
onAwake(): void {
console.log("Scene2 awake");
this.setupBaseSceneLayout();
this.setupPictureRotation();
}
onDisable(): void {
super.onDisable();
this.clearPictureRotation();
}
private setupPictureRotation(): void {
this.picture = this.getSceneNode<Laya.Sprite>("Picture");
if (!this.picture) {
return;
}
this.setPivotWithoutMoving(this.picture, this.picture.width * 0.5, this.picture.height * 0.5);
this.picture.mouseEnabled = true;
this.picture.hitArea = new Laya.Rectangle(0, 0, this.picture.width, this.picture.height);
this.picture.on(Laya.Event.MOUSE_DOWN, this, this.startRotatePicture);
}
private setPivotWithoutMoving(node: Laya.Sprite, pivotX: number, pivotY: number): void {
node.x += pivotX - node.pivotX;
node.y += pivotY - node.pivotY;
node.pivotX = pivotX;
node.pivotY = pivotY;
}
private clearPictureRotation(): void {
if (this.picture) {
this.picture.off(Laya.Event.MOUSE_DOWN, this, this.startRotatePicture);
}
Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.rotatePicture);
Laya.stage.off(Laya.Event.MOUSE_UP, this, this.stopRotatePicture);
Laya.stage.off(Laya.Event.MOUSE_OUT, this, this.stopRotatePicture);
}
private startRotatePicture(event: Laya.Event): void {
if (!this.picture) {
return;
}
this.isRotatingPicture = true;
this.startPointerAngle = this.getPointerAngle(event.stageX, event.stageY);
this.startPictureRotation = this.picture.rotation;
Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.rotatePicture);
Laya.stage.on(Laya.Event.MOUSE_UP, this, this.stopRotatePicture);
Laya.stage.on(Laya.Event.MOUSE_OUT, this, this.stopRotatePicture);
}
private rotatePicture(event: Laya.Event): void {
if (!this.isRotatingPicture || !this.picture) {
return;
}
const currentAngle = this.getPointerAngle(event.stageX, event.stageY);
this.picture.rotation = this.startPictureRotation + currentAngle - this.startPointerAngle;
}
private stopRotatePicture(): void {
this.isRotatingPicture = false;
Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.rotatePicture);
Laya.stage.off(Laya.Event.MOUSE_UP, this, this.stopRotatePicture);
Laya.stage.off(Laya.Event.MOUSE_OUT, this, this.stopRotatePicture);
}
private getPointerAngle(stageX: number, stageY: number): number {
const center = this.picture.localToGlobal(new Laya.Point(
this.picture.width * 0.5,
this.picture.height * 0.5
));
const dx = stageX - center.x;
const dy = stageY - center.y;
return Math.atan2(dy, dx) * 180 / Math.PI;
}
}
{
"uuid": "751938ac-3141-4e65-841b-e7a22d6d4225"
}
\ No newline at end of file
import { BaseScene } from "./BaseScene";
const { regClass, property } = Laya;
type TrackObject = {
node: Laya.Sprite;
lane: number;
depth: number;
};
@regClass()
export class Scene3 extends BaseScene {
@property(String)
public text: string = "";
private readonly horizonY: number = 230;
private readonly nearY: number = 1180;
private readonly farLaneWidth: number = 70;
private readonly nearLaneWidth: number = 250;
private readonly trackTopWidth: number = 150;
private readonly trackBottomWidth: number = 680;
private readonly runSpeed: number = 0.008;
private readonly spawnIntervalMs: number = 900;
private readonly laneCount: number = 3;
private trackLayer: Laya.Sprite;
private objectLayer: Laya.Sprite;
private player: Laya.Sprite;
private playerLane: number = 1;
private obstacles: TrackObject[] = [];
private isRunning: boolean = false;
onAwake(): void {
console.log("Scene3 awake");
this.setupBaseSceneLayout();
this.setupRunnerScene();
this.startRun();
}
onDisable(): void {
super.onDisable();
this.stopRun();
}
protected onBaseLayoutResized(): void {
this.layoutRunnerScene();
}
private setupRunnerScene(): void {
this.trackLayer = new Laya.Sprite();
this.objectLayer = new Laya.Sprite();
this.player = new Laya.Sprite();
this.safeRoot.addChild(this.trackLayer);
this.safeRoot.addChild(this.objectLayer);
this.safeRoot.addChild(this.player);
this.drawPlayer();
this.layoutRunnerScene();
Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.switchLane);
}
private layoutRunnerScene(): void {
if (!this.safeRoot || !this.trackLayer || !this.player) {
return;
}
this.drawTrack();
this.layoutPlayer();
for (const obstacle of this.obstacles) {
this.layoutTrackObject(obstacle);
}
}
private startRun(): void {
this.stopRun();
this.isRunning = true;
Laya.timer.frameLoop(1, this, this.updateRun);
Laya.timer.loop(this.spawnIntervalMs, this, this.spawnObstacle);
}
private stopRun(): void {
this.isRunning = false;
Laya.timer.clear(this, this.updateRun);
Laya.timer.clear(this, this.spawnObstacle);
Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.switchLane);
for (const obstacle of this.obstacles) {
obstacle.node.destroy();
}
this.obstacles.length = 0;
}
private updateRun(): void {
if (!this.isRunning) {
return;
}
for (let i = this.obstacles.length - 1; i >= 0; i--) {
const obstacle = this.obstacles[i];
obstacle.depth += this.runSpeed;
if (obstacle.depth >= 1.08) {
obstacle.node.destroy();
this.obstacles.splice(i, 1);
continue;
}
this.layoutTrackObject(obstacle);
}
}
private spawnObstacle(): void {
if (!this.isRunning || !this.objectLayer) {
return;
}
const obstacleNode = new Laya.Sprite();
this.drawObstacle(obstacleNode);
this.objectLayer.addChild(obstacleNode);
const obstacle: TrackObject = {
node: obstacleNode,
lane: this.getRandomInt(0, this.laneCount - 1),
depth: 0
};
this.obstacles.push(obstacle);
this.layoutTrackObject(obstacle);
}
private drawTrack(): void {
const centerX = this.safeRoot.width * 0.5;
const bottomY = this.nearY;
const topY = this.horizonY;
const topLeft = centerX - this.trackTopWidth * 0.5;
const topRight = centerX + this.trackTopWidth * 0.5;
const bottomLeft = centerX - this.trackBottomWidth * 0.5;
const bottomRight = centerX + this.trackBottomWidth * 0.5;
this.trackLayer.graphics.clear();
this.trackLayer.graphics.drawPoly(0, 0, [
topLeft, topY,
topRight, topY,
bottomRight, bottomY,
bottomLeft, bottomY
], "#444444", "#d8c48a", 4);
for (let lane = 1; lane < this.laneCount; lane++) {
const t = lane / this.laneCount;
const topX = topLeft + this.trackTopWidth * t;
const bottomX = bottomLeft + this.trackBottomWidth * t;
this.trackLayer.graphics.drawLine(topX, topY, bottomX, bottomY, "#d8c48a", 3);
}
}
private drawPlayer(): void {
this.player.graphics.clear();
this.player.graphics.drawCircle(0, 0, 42, "#32d17c", "#ffffff", 4);
}
private drawObstacle(node: Laya.Sprite): void {
node.graphics.clear();
node.graphics.drawRect(-35, -35, 70, 70, "#d94b4b", "#ffffff", 4);
}
private layoutPlayer(): void {
const x = this.getLaneX(this.playerLane, 1);
this.player.pos(x, this.nearY - 80);
this.player.scale(1.1, 1.1);
}
private layoutTrackObject(object: TrackObject): void {
const scale = this.getPerspectiveScale(object.depth);
const x = this.getLaneX(object.lane, object.depth);
const y = this.getPerspectiveY(object.depth);
object.node.pos(x, y);
object.node.scale(scale, scale);
object.node.alpha = Math.min(1, 0.35 + object.depth);
}
private getPerspectiveY(depth: number): number {
const t = this.easeIn(depth);
return this.horizonY + (this.nearY - this.horizonY) * t;
}
private getPerspectiveScale(depth: number): number {
return 0.18 + this.easeIn(depth) * 1.2;
}
private getLaneX(lane: number, depth: number): number {
const centerX = this.safeRoot.width * 0.5;
const t = this.easeIn(depth);
const laneWidth = this.farLaneWidth + (this.nearLaneWidth - this.farLaneWidth) * t;
const laneOffset = lane - (this.laneCount - 1) * 0.5;
return centerX + laneOffset * laneWidth;
}
private easeIn(value: number): number {
const t = Math.max(0, Math.min(1, value));
return t * t;
}
private switchLane(event: Laya.Event): void {
const centerX = this.safeRoot.width * 0.5;
const direction = event.stageX < centerX ? -1 : 1;
this.playerLane = Math.max(0, Math.min(this.laneCount - 1, this.playerLane + direction));
this.layoutPlayer();
}
private getRandomInt(min: number, max: number): number {
const minValue = Math.ceil(min);
const maxValue = Math.floor(max);
return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
}
}
{
"uuid": "a07a37ad-7b93-4ef6-8ddd-73d220a2060e"
}
\ No newline at end of file
import { BaseScene } from "./BaseScene";
const { regClass, property } = Laya;
// 小程序检测到摇一摇后,调用小游戏侧 window.scene4Bridge.onShake()
type Scene4Bridge = {
onShake: () => void;
};
@regClass()
export class Scene4 extends BaseScene {
@property(String)
public text: string = "";
private statusText: Laya.Text;
private shakeCount: number = 0;
private readonly bridgeName: string = "scene4Bridge";
onAwake(): void {
console.log("Scene4 awake");
this.setupBaseSceneLayout();
this.setupStatusText();
this.registerBridge();
}
onDisable(): void {
super.onDisable();
this.unregisterBridge();
}
protected onBaseLayoutResized(): void {
this.layoutStatusText();
}
private registerBridge(): void {
(window as any)[this.bridgeName] = {
onShake: () => {
this.onMiniProgramShake();
}
} as Scene4Bridge;
}
private unregisterBridge(): void {
const globalObj = window as any;
if (globalObj[this.bridgeName]?.onShake) {
delete globalObj[this.bridgeName];
}
}
private onMiniProgramShake(): void {
this.shakeCount += 1;
console.log("Scene4 shake from mini program", this.shakeCount);
this.updateStatusText(`摇中了: ${this.shakeCount}`);
}
private setupStatusText(): void {
this.statusText = new Laya.Text();
this.statusText.width = 560;
this.statusText.height = 80;
this.statusText.fontSize = 32;
this.statusText.color = "#ffffff";
this.statusText.bold = true;
this.statusText.align = "center";
this.statusText.stroke = 4;
this.statusText.strokeColor = "#1f1f1f";
this.safeRoot.addChild(this.statusText);
this.layoutStatusText();
this.updateStatusText("等待小程序调用");
}
private layoutStatusText(): void {
if (!this.statusText || !this.safeRoot) {
return;
}
this.statusText.pos(
(this.safeRoot.width - this.statusText.width) * 0.5,
80
);
}
private updateStatusText(value: string): void {
if (!this.statusText) {
return;
}
this.statusText.text = value;
}
}
{
"uuid": "0dcd39b4-488a-4616-9399-33952cafb075"
}
\ No newline at end of file
import { BaseScene } from "./BaseScene";
const { regClass, property } = Laya;
type HorseSpawnConfig = {
minSpawnIntervalMs: number;
maxSpawnIntervalMs: number;
moveStep: number;
moveIntervalFrames: number;
minY: number;
maxY: number;
};
@regClass()
export class Scene5 extends BaseScene {
@property(String)
public text: string = "";
private readonly horseSheetUrls: string[] = [
"resources/images/5/Basic_Walking_Horses.png"
];
private readonly horseSpawnConfig: HorseSpawnConfig = {
minSpawnIntervalMs: 800,
maxSpawnIntervalMs: 1200,
moveStep: 5,
moveIntervalFrames: 1,
minY: 0,
maxY: 507
};
private horsesRoot: Laya.Area2D;
private horseTemplate: Laya.Animation;
private ring: Laya.Area2D;
private activeHorses: Laya.Animation[] = [];
private horseMoveHandlers: Map<Laya.Animation, () => void> = new Map();
private isHorseSpawning: boolean = false;
onAwake(): void {
console.log("Scene5 awake");
this.setupBaseSceneLayout();
this.horsesRoot = this.getSceneNode<Laya.Area2D>("Horses");
this.horsesRoot.size(this.safeRoot.width, this.horsesRoot.height);
this.drawNodeBorder(this.horsesRoot, "#ffff00");
this.horseTemplate = this.getSceneNode<Laya.Animation>("Horse_0");
this.ring = this.getSceneNode<Laya.Area2D>("Ring");
this.ring.pos((this.safeRoot.width-this.ring.width) * 0.5, this.ring.y);
this.drawRing();
if (!this.horsesRoot || !this.horseTemplate) {
return;
}
this.horseTemplate.visible = false;
this.startHorseSpawning();
}
onDisable(): void {
super.onDisable();
this.clearHorseSpawning();
}
protected onBaseLayoutResized(): void {
this.clipHorsesRoot();
this.clampHorseSpawnYRange();
this.drawRing();
}
protected onStageBlur(): void {
this.stopHorseSpawning();
}
protected onStageFocus(): void {
if (this.horseTemplate) {
this.startHorseSpawning();
}
}
private startHorseSpawning(): void {
this.stopHorseSpawning();
this.isHorseSpawning = true;
this.spawnHorse();
}
private drawRing(): void {
if (!this.ring) {
return;
}
const lineWidth = 8;
const halfLineWidth = lineWidth * 0.5;
const centerX = this.ring.width * 0.5;
const centerY = this.ring.height * 0.5;
const radiusX = Math.max(0, centerX - halfLineWidth);
const radiusY = Math.max(0, centerY - halfLineWidth);
this.ring.graphics.clear();
const points: number[] = [];
const segmentCount = 72;
for (let i = 0; i < segmentCount; i++) {
const angle = Math.PI * 2 * i / segmentCount;
points.push(
centerX + Math.cos(angle) * radiusX,
centerY + Math.sin(angle) * radiusY
);
}
this.ring.graphics.drawPoly(0, 0, points, null, "#ff0000", lineWidth);
}
private scheduleNextHorseSpawn(): void {
const delay = this.getRandomInt(
this.horseSpawnConfig.minSpawnIntervalMs,
this.horseSpawnConfig.maxSpawnIntervalMs
);
Laya.timer.once(delay, this, this.spawnHorse);
}
private spawnHorse(): void {
if (!this.isHorseSpawning || !this.horseTemplate || !this.horsesRoot) {
return;
}
const horse = this.createHorse();
this.horsesRoot.addChild(horse);
this.activeHorses.push(horse);
this.setupMoleAnimation(horse, {
columns: 8,
rows: 4,
startFrame: 0,
endFrame: 7,
interval: 90
}, this.horseSheetUrls);
const moveHandler = () => {
this.moveHorse(horse);
};
this.horseMoveHandlers.set(horse, moveHandler);
Laya.timer.frameLoop(this.horseSpawnConfig.moveIntervalFrames, this, moveHandler);
this.scheduleNextHorseSpawn();
}
private createHorse(): Laya.Animation {
const horse = new Laya.Animation();
horse.name = "Horse";
horse.width = this.horseTemplate.width;
horse.height = this.horseTemplate.height;
horse.scaleX = this.horseTemplate.scaleX;
horse.scaleY = this.horseTemplate.scaleY;
horse.pivotX = this.horseTemplate.pivotX;
horse.pivotY = this.horseTemplate.pivotY;
horse.interval = this.horseTemplate.interval;
const maxY = Math.max(0, this.horsesRoot.height - horse.height);
const y = this.getRandomInt(
Math.max(0, this.horseSpawnConfig.minY),
Math.min(maxY, this.horseSpawnConfig.maxY)
);
horse.pos(-horse.width, y);
return horse;
}
private moveHorse(horse: Laya.Animation): void {
if (!horse || horse.destroyed) {
return;
}
horse.x += this.horseSpawnConfig.moveStep;
if (this.isHorseCaughtByRing(horse)) {
this.catchHorse(horse);
return;
}
if (horse.x > this.horsesRoot.width) {
this.removeHorse(horse);
}
}
private catchHorse(horse: Laya.Animation): void {
console.log("Horse caught");
this.removeHorse(horse);
}
private isHorseCaughtByRing(horse: Laya.Animation): boolean {
if (!this.ring || !horse || horse.destroyed) {
return false;
}
const horseCenter = horse.localToGlobal(new Laya.Point(horse.width * 0.5, horse.height * 0.5));
const ringLocalPoint = this.ring.globalToLocal(horseCenter);
const centerX = this.ring.width * 0.5;
const centerY = this.ring.height * 0.5;
const radiusX = this.ring.width * 0.5;
const radiusY = this.ring.height * 0.5;
if (radiusX <= 0 || radiusY <= 0) {
return false;
}
const normalizedX = (ringLocalPoint.x - centerX) / radiusX;
const normalizedY = (ringLocalPoint.y - centerY) / radiusY;
return normalizedX * normalizedX + normalizedY * normalizedY <= 1;
}
private removeHorse(horse: Laya.Animation): void {
const moveHandler = this.horseMoveHandlers.get(horse);
if (moveHandler) {
Laya.timer.clear(this, moveHandler);
this.horseMoveHandlers.delete(horse);
}
this.clearSpriteSheetAnimation(horse);
const index = this.activeHorses.indexOf(horse);
if (index >= 0) {
this.activeHorses.splice(index, 1);
}
horse.removeSelf();
horse.destroy();
}
private clearHorseSpawning(): void {
this.stopHorseSpawning();
}
private stopHorseSpawning(): void {
this.isHorseSpawning = false;
Laya.timer.clear(this, this.spawnHorse);
for (const horse of this.activeHorses.slice()) {
this.removeHorse(horse);
}
}
private clampHorseSpawnYRange(): void {
if (!this.horsesRoot || !this.horseTemplate) {
return;
}
this.horseSpawnConfig.maxY = Math.min(
this.horseSpawnConfig.maxY,
Math.max(0, this.horsesRoot.height - this.horseTemplate.height)
);
}
private clipHorsesRoot(): void {
if (!this.horsesRoot) {
return;
}
this.horsesRoot.scrollRect = new Laya.Rectangle(0, 0, this.horsesRoot.width, this.horsesRoot.height);
}
private getRandomInt(min: number, max: number): number {
const minValue = Math.ceil(min);
const maxValue = Math.floor(max);
return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
}
}
{
"uuid": "584f2d9c-b194-4ff2-8ebb-724d9932b1b7"
}
\ No newline at end of file
import { BaseScene, SpriteSheetAnimationConfig } from "./BaseScene";
const { regClass, property } = Laya;
type MoleGameConfig = {
minVisibleMoles: number;
maxVisibleMoles: number;
minSpawnIntervalMs: number;
maxSpawnIntervalMs: number;
durationSeconds: number;
};
@regClass()
export class Scene6 extends BaseScene {
@property(String)
public text: string = "";
private mole_list: Laya.Animation[];
private scoreText: Laya.Text;
private timeText: Laya.Text;
private score: number = 0;
private remainingSeconds: number = 0;
private isGameRunning: boolean = false;
private readonly gameConfig: MoleGameConfig = {
minVisibleMoles: 1,
maxVisibleMoles: 3,
minSpawnIntervalMs: 2000,
maxSpawnIntervalMs: 3000,
durationSeconds: 30
};
onAwake(): void {
console.log("Scene6 awake");
this.setupBaseSceneLayout();
this.mole_list = [];
for (let i = 0; i <= 6; i++) {
const mole = this.getSceneNode<Laya.Animation>(`Mole_${i}`);
if (mole) {
this.mole_list.push(mole);
}
}
this.setupHud();
for (const mole of this.mole_list) {
mole.visible = false;
this.setupClickInput(
mole,
(event: Laya.Event) => {
if (this.hitMole(mole)) {
console.log("Hit mole!");
this.sendSocket("hit");
}
},
{ pixelHitTest: false }
);
this.setupMoleAnimation(mole, {
columns: 6,
rows: 8,
startFrame: 0,
endFrame: 7,
interval: 200
}, ["resources/images/6/sprites.png"]);
}
this.startGame(this.gameConfig);
}
onDisable(): void {
super.onDisable();
this.clearGameTimers();
}
protected onBaseLayoutResized(): void {
this.layoutHud();
}
private setupHud(): void {
this.scoreText = this.createHudText();
this.timeText = this.createHudText();
this.safeRoot.addChild(this.scoreText);
this.safeRoot.addChild(this.timeText);
this.layoutHud();
this.updateHud();
}
private createHudText(): Laya.Text {
const text = new Laya.Text();
text.width = 260;
text.height = 48;
text.fontSize = 32;
text.color = "#ffffff";
text.bold = true;
text.stroke = 4;
text.strokeColor = "#1f1f1f";
return text;
}
private layoutHud(): void {
if (!this.scoreText || !this.timeText || !this.safeRoot) {
return;
}
this.scoreText.pos(24, 24);
this.timeText.pos(this.safeRoot.width - this.timeText.width - 24, 24);
}
private startGame(config: MoleGameConfig): void {
this.clearGameTimers();
this.score = 0;
this.remainingSeconds = config.durationSeconds;
this.isGameRunning = true;
this.hideAllMoles();
this.updateHud();
this.showRandomMoles();
Laya.timer.loop(1000, this, this.tickCountdown);
}
private hitMole(mole: Laya.Animation): boolean {
if (!this.isGameRunning || !mole.visible) {
return false;
}
mole.visible = false;
this.score += 1;
this.updateHud();
return true;
}
private showRandomMoles(): void {
if (!this.isGameRunning) {
return;
}
this.hideAllMoles();
const visibleCount = this.getRandomInt(this.gameConfig.minVisibleMoles, this.gameConfig.maxVisibleMoles);
const shuffledMoles = this.shuffle(this.mole_list);
const count = Math.min(visibleCount, shuffledMoles.length);
for (let i = 0; i < count; i++) {
shuffledMoles[i].visible = true;
}
this.scheduleNextMoleSpawn();
}
private scheduleNextMoleSpawn(): void {
const delay = this.getRandomInt(this.gameConfig.minSpawnIntervalMs, this.gameConfig.maxSpawnIntervalMs);
Laya.timer.once(delay, this, this.showRandomMoles);
}
private tickCountdown(): void {
if (!this.isGameRunning) {
return;
}
this.remainingSeconds -= 1;
this.updateHud();
if (this.remainingSeconds <= 0) {
this.endGame();
}
}
private endGame(): void {
this.isGameRunning = false;
this.remainingSeconds = 0;
this.clearGameTimers();
this.hideAllMoles();
this.updateHud();
}
private clearGameTimers(): void {
Laya.timer.clear(this, this.showRandomMoles);
Laya.timer.clear(this, this.tickCountdown);
}
private hideAllMoles(): void {
for (const mole of this.mole_list) {
mole.visible = false;
}
}
private updateHud(): void {
if (this.scoreText) {
this.scoreText.text = `Score: ${this.score}`;
}
if (this.timeText) {
this.timeText.text = `Time: ${Math.max(0, this.remainingSeconds)}`;
}
}
private getRandomInt(min: number, max: number): number {
const minValue = Math.ceil(min);
const maxValue = Math.floor(max);
return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
}
private shuffle<T>(items: T[]): T[] {
const result = items.slice();
for (let i = result.length - 1; i > 0; i--) {
const randomIndex = this.getRandomInt(0, i);
const item = result[i];
result[i] = result[randomIndex];
result[randomIndex] = item;
}
return result;
}
}
{
"uuid": "e4bb588d-8f00-4c44-920e-5be473eac223"
}
\ No newline at end of file
<html>
<head>
<title>{{title}}</title>
<meta charset='utf-8' />
<meta name='renderer' content='webkit' />
<meta name='viewport'
content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no' />
<meta name='apple-mobile-web-app-capable' content='yes' />
<meta name='full-screen' content='true' />
<meta name='x5-fullscreen' content='true' />
<meta name='360-fullscreen' content='true' />
<meta http-equiv='expires' content='0' />
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1' />
<meta http-equiv='expires' content='0' />
<meta http-equiv='Cache-Control' content='no-siteapp' />
</head>
<body style="margin: 0;background-color: {{backgroundColor}};color: #fff;">
<!-- Loading screen start -->
<style type="text/css">
#game-loading {
position: absolute;
height: 100%;
width: 100%;
z-index: 99999999;
transition: opacity ease-in-out 300ms;
transform-origin: left top;
background: linear-gradient(180deg, #eaf7ff 0%, #ffffff 100%);
color: #123047;
font-family: Arial, Helvetica, sans-serif;
}
.loading-inner {
position: absolute;
left: 50%;
top: 46%;
width: min(68vw, 320px);
transform: translate(-50%, -50%);
text-align: center;
}
.loading-title {
margin-bottom: 18px;
font-size: 20px;
font-weight: 700;
}
.loading-spinner {
width: 44px;
height: 44px;
margin: 0 auto 18px;
border: 4px solid rgba(37, 167, 255, 0.2);
border-top-color: #25a7ff;
border-radius: 50%;
animation: loading-spin 900ms linear infinite;
}
.loading-track {
width: 100%;
height: 8px;
overflow: hidden;
border-radius: 999px;
background: rgba(0, 0, 0, 0.12);
}
.loading-bar {
width: 0%;
height: 100%;
border-radius: inherit;
background: #25a7ff;
transition: width ease-out 160ms;
}
.loading-percent {
margin-top: 12px;
font-size: 14px;
color: #666666;
}
@keyframes loading-spin {
to {
transform: rotate(360deg);
}
}
</style>
<div id="game-loading">
<div class="loading-inner">
<div class="loading-spinner"></div>
<div class="loading-title">Loading</div>
<div class="loading-track">
<div class="loading-bar" id="game-loading-bar"></div>
</div>
<div class="loading-percent" id="game-loading-percent">0%</div>
</div>
</div>
<script>
(function() {
let loading = document.getElementById('game-loading');
let bar = document.getElementById('game-loading-bar');
let percent = document.getElementById('game-loading-percent');
let sm = "{{screenMode}}";
let startedAt = performance.now();
let minDuration = 800;
function fit() {
let flag = 0;
if (sm == "horizontal")
flag = window.innerWidth < window.innerHeight ? 1 : 0;
else if (sm == "vertical")
flag = window.innerWidth > window.innerHeight ? 2 : 0;
if (flag != 0) {
loading.style.width = window.innerHeight + "px";
loading.style.height = window.innerWidth + "px";
if (flag == 1) {
loading.style.transform = "rotate(90deg)";
loading.style.left = window.innerWidth;
}
else {
loading.style.transform = "rotate(-90deg)";
loading.style.top = window.innerHeight;
}
}
else {
loading.style.transform = "";
loading.style.width = "100%";
loading.style.height = "100%";
loading.style.left = "0px";
loading.style.top = "0px";
}
}
function hide() {
window.removeEventListener("resize", fit);
delete window.hideSplashScreen;
delete window.onSplashProgress;
onProgress(1);
let delay = Math.max(0, minDuration - (performance.now() - startedAt));
setTimeout(() => {
loading.style.opacity = 0;
setTimeout(() => loading.parentElement && loading.parentElement.removeChild(loading), 300);
}, delay);
}
function onProgress(progress) {
progress = Math.max(0, Math.min(1, Number(progress) || 0));
let value = Math.round(progress * 100);
bar.style.width = value + "%";
percent.innerText = value + "%";
}
window.addEventListener("resize", fit);
window.hideSplashScreen = hide;
window.onSplashProgress = onProgress;
fit();
})();
</script>
{{#libs}}
<script type="{{{type}}}" src="{{{name}}}"></script>
{{/libs}}
{{#bundles}}
<script type="{{{type}}}" src="{{{name}}}"></script>
{{/bundles}}
<script type="text/javascript" src="{{{indexJS}}}"></script>
</body>
</html>
declare module BP {
class BlueprintCreateUtil {
static __init__(): Promise<void>;
static reg(): void;
}
class BlueprintDecorator {
static bpUserMap: Map<Function, TBPDeclaration>;
static initDeclaration(name: string, cls: Function): TBPDeclaration;
/**
* 蓝图装饰器
* @param options
*/
static bpClass(target: any, options: BPDecoratorsOptionClass): TBPDeclaration;
/**
* 蓝图装饰器,属性
*/
static bpProperty(target: any, propertyKey: string, options: BPDecoratorsOptionProp): void;
/**
* 蓝图装饰器,方法
*/
static bpFunction(target: any, propertyKey: string, descriptor: any, options: BPDecoratorsOptionFunction): void;
/**
* 蓝图装饰器,getset
*/
static bpAccessor(target: any, propertyKey: string, descriptor: any, options: BPDecoratorsOptionProp): void;
/**
* 增加一个蓝图枚举
* @param name 枚举名称
* @param members 枚举成员
*/
static createBPEnum(name: string, members: TBPDeclarationMember[]): void;
}
/**
* 蓝图装饰器
* @param options
*/
function bpClass(options: BPDecoratorsOptionClass): (target: any) => void;
/**
* 蓝图装饰器,属性
*/
function bpProperty(options: BPDecoratorsOptionProp): (target: any, propertyKey: string) => void;
/**
* 蓝图装饰器,方法
*/
function bpFunction(options?: BPDecoratorsOptionFunction): (target: any, propertyKey: string, descriptor: any) => void;
/**
* 蓝图装饰器,getset
*/
function bpAccessor(options: BPDecoratorsOptionProp): (target: any, propertyKey: string, descriptor: any) => void;
/**
* 增加一个蓝图枚举
* @param name 枚举名称
* @param members 枚举成员
*/
function createBPEnum(name: string, members: TBPDeclarationMember[]): void;
class BlueprintLoader implements Laya.IResourceLoader {
load(task: Laya.ILoadTask): Promise<BlueprintResource>;
postLoad(task: Laya.ILoadTask, bp: BlueprintResource): Promise<void>;
}
/**
* @blueprintIgnore
*/
class BlueprintResource extends Laya.Resource {
data: IBPSaveData;
dec: TBPDeclaration;
allData: Record<string, any>;
private _cls;
private _bid;
private varMap;
private allNode;
constructor(bid: string);
get cls(): Function;
private _initTarget;
initClass(data: IBPSaveData): void;
parse(): void;
protected _disposeResource(): void;
}
class BlueprintConst {
static MAX_CODELINE: number;
static NULL_NODE: number;
static VERSION: number;
static EXT: string;
static TYPE: string;
static configPath: string;
}
const EXECID = "-1";
const TARGETID = "-2";
class BlueprintData {
/**对当前打开的蓝图数据进行检测的逻辑 */
getConstDataExt: (target: string, dataId: string) => IBPCNode;
static allDataMap: Map<string, Record<string, IBPCNode>>;
private static defFunOut;
private static defFunIn;
private static defTarget;
private static defEventOut;
/**所有的数据 */
/**
* constData里面的数据应该包含customData的数据
*/
constData: Record<string, IBPConstNode>;
/**自動生成的模板數據,這些數據不會在鼠標右鍵菜單中出現,也不會傳輸到ide層去 */
autoCreateData: Record<string, IBPCNode>;
private static readonly funlike;
private static readonly checklike;
private _extendsData;
private _regFunction;
private _getClass;
static formatName(param: TBPDeclarationParam): string;
static formatType(type: Laya.FPropertyType): Laya.FPropertyType;
constructor(extendsData: Record<string, TBPDeclaration>, regFunction?: (fname: string, fun: Function, isMember: boolean, cls: any, target: string) => void, getClass?: (name: string) => any);
get extendsData(): Record<string, TBPDeclaration>;
getExtends(ext: string, arr?: string[]): string[];
getConstDataById(target: string, dataId: string): IBPCNode;
private _getConstData;
/**在引擎执行的时候需要启用catch来提高效率,在ide中不需要,因为ide中有时候会经常变动数据 */
isStartCatch: boolean;
static clone<T>(obj: T): T;
private _getConstByNode;
getConstNode(node: IBPNode): IBPCNode;
private _checkAndPush;
private _checkOverrideProp;
private _initObject;
private _createExtData;
private _createConstData;
isResetData: boolean;
removeData(ext: string): void;
resetData(data: TBPDeclaration, ext: string): void;
initData(data: Record<string, TBPDeclaration>): void;
private static handleCDataTypes;
private static createCData;
static formatData(data: IBPSaveData, assetId: string, dataMap?: Record<string, IBPCNode>, varMap?: Record<string, IBPVariable>): TBPDeclaration;
private static _initTarget;
}
abstract class BlueprintNode<T extends BlueprintPin> {
id: string;
nid: number;
name: string;
type: BPType;
def: IBPCNode;
pins: T[];
constructor();
abstract createPin(def: TBPPinDef): T;
addPin(pin: T): void;
parse(def: IBPCNode): void;
getPropertyItem(key: string): IBPCInput;
getValueType(key: string): "class" | "resource";
isEmptyObj(o: any): boolean;
/**
* 强制写入target的inputValue
* @param node
* @returns
*/
private _checkTarget;
parseLinkData(node: IBPNode, manager: INodeManager<BlueprintNode<T>>): void;
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintNode<T>>): void;
setFunction(fun: Function, isMember: boolean): void;
setType(type: BPType): void;
addInput(input: TBPPinDef[]): void;
addOutput(output: TBPPinDef[]): void;
getPinByName(id: string): T;
}
class BlueprintPin {
private _direction;
get direction(): EPinDirection;
set direction(value: EPinDirection);
id: string;
name: string;
nid: string;
type: EPinType;
otype: string;
linkTo: BlueprintPin[];
value: any;
constructor();
parse(def: TBPPinDef): void;
startLinkTo(e: BlueprintPin): void;
}
class BlueprintUtil {
static classMap: any;
static bpData: BlueprintData;
static onfinishCallbacks: Record<number, [
Function,
any,
any[]
]>;
static resouceMap: Map<string, any>;
static CustomClassFinish: string;
static customModify: boolean;
static clone<T>(obj: T): T;
static getConstNode(node?: IBPNode): IBPCNode;
static getConstDataById(target: string, dataId: string): IBPCNode;
/**
* hook
* @param name
* @param data
*/
static addCustomData(name: string, data: TBPDeclaration): void;
static getDeclaration(name: string): TBPDeclaration;
static initConstNode(): void;
static getClass(ext: any): any;
static regClass(name: string, cls: any): void;
static regResByUUID(uuid: string, res: any): void;
static getResByUUID(uuid: string): any;
static getNameByUUID(uuid: string): string;
}
/**
* 引脚方向
*/
enum EPinDirection {
Input = 0,
Output = 1,
All = 2
}
/**
* 节点类型
*/
enum EBlueNodeType {
Unknow = "unkown",
Event = "event",
Fun = "fun",
Pure = "pure",
GetVariable = "var",
SetVarialbe = "setVar",
Branch = "branch",
Sequnece = "sequnece"
}
/**
* 引脚类型
*/
enum EPinType {
Exec = 0,
BPFun = 1,
Other = 2
}
interface IBluePrintSubclass {
[BlueprintFactory.bpSymbol]: BlueprintRuntime;
[BlueprintFactory.contextSymbol]: IRunAble;
[key: string]: any;
}
interface IExecuteListInfo {
nid: number;
}
interface INodeManager<T> {
getNodeById(id: any): T;
dataMap: Record<string, IBPCNode | IBPVariable>;
}
interface IOutParm {
readonly name: string;
setValue(runId: number, value: any): void;
}
interface IRuntimeDataManager {
getDataById(nid: number): RuntimeNodeData;
setPinData(pin: BlueprintPinRuntime, value: any, runId: number): void;
getPinData(pin: BlueprintPinRuntime, runId: number): any;
getRuntimePinById(id: string): RuntimePinData;
getVar(name: string, runId: number): any;
setVar(name: string, value: any, runId: number): void;
clearVar(runId: number): void;
saveContextData(from: number, to: number): void;
}
type TBPNodeDef = {
name: string;
id: string;
type: BPType;
inPut?: TBPPinDef[];
outPut?: TBPPinDef[];
fun?: Function;
};
type TBPPinDef = {
id: string;
name: string;
type: string;
};
type TBPNodeData = {
id: string;
did: string;
data: Record<string, TBPPinData>;
};
type TBPLinkInfo = {
varname: string;
};
type TBPPinData = {
value?: any;
linkto?: string[];
};
const BlueprintDataList: IBPCNode[];
/**
* 开发者自定义相关
*/
const customData: Record<string, TBPDeclaration>;
const extendsData: Record<string, TBPDeclaration>;
type TBPDecoratorsPropertyType = "function" | "property" | "class";
type TBPDecoratorsFuncType = "pure" | "function" | "event";
type TBPDeclarationType = "Enum" | "Interface" | "Node" | "Component" | "Others";
/** 修饰符 */
type BPModifiers = {
/** 是否是私有 */
isPrivate?: boolean;
/** 是否是公有 */
isPublic?: boolean;
/** 是否是受保护的 */
isProtected?: boolean;
/** 是否是静态 */
isStatic?: boolean;
/** 是否为只读 */
isReadonly?: boolean;
/**
* 是否是自动运行
*/
isAutoRun?: boolean;
};
type TBPDeclaration = {
/** 包名 */
module?: string;
/** 当前描述名 */
name: string;
/** 当前描述的具体类型 */
type?: TBPDeclarationType;
/** 能否被继承 */
canInherited?: boolean;
/** 父类 */
extends?: string;
/** 事件相关 */
events?: TBPDeclarationEvent[];
/** 实现的接口名 */
implements?: string[];
/** 该描述的属性列表 */
props?: TBPDeclarationProp[];
/** 该描述的方法列表 */
funcs?: TBPDeclarationFunction[];
/** 构造函数 */
construct?: TBPDeclarationConstructor;
/** 枚举成员 */
members?: TBPDeclarationMember[];
/** 显示名称,没有默认使用name */
caption?: string;
/** 分组 */
catalog?: string;
/** 提示内容 */
tips?: string;
};
type TBPDeclarationMember = {
/** 枚举名称 */
name: string;
/** 枚举值 */
value: number | string;
/** 显示名称,没有默认使用name */
caption?: string;
/** 分组 */
catalog?: string;
/** 提示内容 */
tips?: string;
};
type TBPDeclarationEvent = {
name: string;
params?: TBPDeclarationEventData[];
};
type TBPDeclarationEventData = {
id?: number;
/** 参数名称 */
name: string;
/** 参数类型 */
type: string;
/** 显示名称,没有默认使用name */
caption?: string;
/** 分组 */
catalog?: string;
/** 提示内容 */
tips?: string;
};
type TBPDeclarationConstructor = {
params?: TBPDeclarationParam[];
/** 显示名称,没有默认使用name */
caption?: string;
/** 分组 */
catalog?: string;
/** 提示内容 */
tips?: string;
};
type TBPDeclarationProp = {
/** 变量名称 */
name: string;
value?: any;
/** 变量类型 */
type?: string;
/** 是否为可选项 */
optional?: boolean;
customId?: string | number;
/** 泛型 */
typeParameters?: any;
/** 修饰符 */
modifiers?: BPModifiers;
/** 是否来自父类 */
fromParent?: string;
/** 显示名称,没有默认使用name */
caption?: string;
/** 分组 */
catalog?: string;
/** 提示内容 */
tips?: string;
};
type TBPDeclarationFunction = {
/** 方法名称 */
name: string;
/**鼠标右键里面的菜单路径,如果填写none则代表不在菜单中显示 */
menuPath?: string;
/** 具体方法类型 */
type?: TBPDecoratorsFuncType;
/** 修饰符 */
modifiers?: BPModifiers;
/** 方法的参数列表 */
params?: TBPDeclarationParam[];
/** 方法的返回类型 */
returnType: string | any[];
/** 方法的返回注释 */
returnTips?: string;
/** 泛型 */
typeParameters?: any;
/** 注册的原始方法 */
originFunc?: Function;
/** 是否来自父类 */
fromParent?: string;
customId?: number | string;
/** 显示名称,没有默认使用name */
caption?: string;
/** 分组 */
catalog?: string;
/** 提示内容 */
tips?: string;
};
type TBPDeclarationParam = {
id?: number;
/** 参数名称 */
name: string;
/** 参数类型 */
type: string;
/** 是否为可选项 */
optional?: boolean;
/** 是否为...方法 */
dotdotdot?: boolean;
/** 显示名称,没有默认使用name */
caption?: string;
/** 分组 */
catalog?: string;
/** 提示内容 */
tips?: string;
};
interface BPDecoratorsOptionBase {
/** 标题,如果不提供将使用name */
caption?: string;
/** 注册对象成员类型 */
propertyType?: TBPDecoratorsPropertyType;
/** 修饰符 */
modifiers?: BPModifiers;
/** 分类 */
catalog?: string;
/** 提示内容 */
tips?: string;
}
interface BPDecoratorsOptionClass extends BPDecoratorsOptionBase {
/** 注册名称 */
name: string;
/** 继承的父类 */
extends?: string;
/** 能否被继承 */
canInherited?: boolean;
/** 构造函数参数 */
construct?: TBPDeclarationConstructor;
/** 事件相关 */
events?: TBPDeclarationEvent[];
}
interface BPDecoratorsOptionFunction extends BPDecoratorsOptionBase {
/** 方法或者构造函数参数,必填 */
params?: TBPDeclarationParam[];
/**
* 方法分类
* @default BPType.Function
*/
type?: TBPDecoratorsFuncType;
/**
* 返回类型
*/
returnType?: string;
}
interface BPDecoratorsOptionProp extends BPDecoratorsOptionBase {
/** 参数类型 */
type: string;
}
interface IBPSaveData {
autoID: number;
preload?: string[];
extends: string;
blueprintArr: Array<IBPStageData>;
variable: IBPVariable[];
functions: IBPStageData[];
events: IBPCNode[];
source?: any;
globalInfo?: Record<string, any>;
}
interface CopyType {
arr: (IBPNode | IBComment)[];
width: number;
height: number;
}
interface IBPVariable extends Partial<IBPCNode> {
name: string;
type: string;
value?: any;
}
interface IBPStageData extends Partial<IBPCNode> {
/** 修饰符 */
modifiers?: BPModifiers;
name: string;
id: number;
uiData?: {
/**场景的x坐标位置 */
x: number;
/**场景的y坐标位置 */
y: number;
/**场景的缩放 */
scale: number;
};
/**临时变量数据 */
variable?: IBPVariable[];
arr: Array<IBPNode>;
comments?: Array<IBComment>;
/**保存的时候不会有这个值,这是build的时候传值用的 */
dataMap?: Record<string, IBPCNode>;
tips?: string;
properties?: Array<IBPCInput>;
output?: IBPCOutput[];
}
interface IBComment {
id: number;
x: number;
y: number;
width: number;
height: number;
desc: string;
fontSize?: number;
color?: {
r: number;
g: number;
b: number;
};
noSticky?: boolean;
}
interface IBPConstNode {
extends?: string;
data: Record<string, IBPCNode>;
caption?: string;
}
interface IBPCNode {
isSelf?: boolean;
/**程序中用到的名字 */
name: string;
caption?: string;
/** */
bpType?: "function" | "event" | "prop" | "construct";
target?: string;
/**target有可能是uuid,所以需要这个别名 */
targetAliasName?: string;
/** 提示内容 */
tips?: string;
module?: string;
/**如果是自定义函数会有这个id号 */
customId?: number;
/**泛型的类型定义 */
typeParameters?: Record<string, {
extends?: string[];
}>;
/** 修饰符 */
modifiers?: BPModifiers;
/** 数据唯一的id号,可以不写,默认为name*/
id?: string | number;
/** 旧的id号,用于兼容旧的版本 */
oldId?: string;
/**该节点的类型,如果是variable则类型为string */
type: BPType | string;
/**鼠标右键里面的菜单路径,如果填写none则代表不在菜单中显示 */
menuPath?: string;
/**版本号 */
ver?: number;
properties: Array<IBPCInput>;
output?: IBPCOutput[];
/**插槽上的默認值 */
inputValue?: Record<string, any>;
/**返回值是否是Promise */
isAsync?: boolean;
}
interface IBPCOutput {
/**插槽的id号,一般用户自定义插槽会有这个值 */
id?: string | number;
/** 插槽名称 */
name?: string;
/**插槽的别名,通常用于自定义函数中 */
caption?: string;
tips?: string;
/** 插槽允许的输出连接类型,输入字符串表示仅能连接该类型,数组表示可连接数组内类型*/
type: Laya.FPropertyType;
}
interface IBPCInput {
id?: string | number;
type?: Laya.FPropertyType;
name?: string;
caption?: string;
tips?: string;
/**input简介提示,UI上显示使用,鼠标挪动到UI上会出现该提示信息 */
alt?: string;
/**inputValue的类型 */
valueType?: "class" | "resource";
isAsset?: boolean;
}
enum BPType {
Event = "event",
Function = "function",
BPEvent = "bpEvent",
Pure = "pure",
Class = "class",
Operator = "operator",
GetValue = "getvalue",
SetValue = "setvalue",
GetTmpValue = "getTmpValue",
SetTmpValue = "setTmpValue",
Branch = "branch",
Block = "Block",
Sequence = "sequence",
NewTarget = "newtarget",
CustomFun = "customFun",
CustomFunStart = "customFunStart",
CustomFunReturn = "customFunReturn",
Expression = "expression",
Assertion = "Assertion"
}
interface IBPNode {
/** 数据唯一的id号*/
id: number;
ver?: number;
/**当前的类 */
target?: string;
name?: string;
/** constData的id号 */
cid: string;
/**var或者event的id */
dataId?: string;
customId?: number;
/**所有UI所用到的数据 */
uiData?: {
/**数据的x坐标位置 */
x: number;
/**数据的y坐标位置 */
y: number;
/**函数注释 */
desc?: any;
/**是否隐藏 */
isHidden?: boolean;
/**是否显示desc的气泡 */
isShowDesc?: boolean;
};
debugType?: number;
input?: Record<string, IBPInput>;
/**对应inputValue的type关键字,如果typeKey发生变化说明inputValue需要被清空 */
typeKey?: string;
/**插槽上的默認值 */
inputValue?: Record<string, any>;
/**动态增加的input节点 */
properties?: Array<IBPCInput>;
/**动态增加的输出节点 */
outputs?: IBPCOutput[];
output?: Record<string, IBPOutput>;
autoReg?: boolean;
}
interface IBPInput {
type?: Laya.FPropertyType;
/**插槽注释 */
desc?: string;
class?: string;
resource?: string;
}
interface IBPOutput {
infoArr: IBPConnType[];
}
interface IBPConnType {
/** 插槽连接到的另一个节点的id */
nodeId: number;
/** 插槽连接到的另一个节点的第n个插槽 */
index?: number;
/**连接到的input或者output的ID号 */
id?: string;
/**连接到的input或者output的name */
name?: string;
}
interface IBPProperty {
title?: string;
type: string;
data: any;
}
/**
* @blueprintable
*/
class BPArray<T> {
length: number;
/** @blueprintPure */
static getItem<T>(arr: Array<T>, index: number): T;
static setItem<T>(arr: Array<T>, index: number, value: T): void;
push(item: T): number;
pop(): T;
splice(start: number, deleteCount?: number): T[];
shift(): T;
unshift(item: T): T;
/** @blueprintPure */
join(separator?: string): string;
/** @blueprintPure */
concat(item: T[]): T[];
}
/**
* @blueprintable @blueprintPure
*/
class BPMathLib {
/**
* @en Add two numbers.
* @param a The first number.
* @param b The second number.
* @returns The sum of the two numbers.
* @zh 两数相加
* @param a 第一个数
* @param b 第二个数
* @returns 两数相加的结果
*/
static add(a: number, b: number): number;
/**
* @en Subtract two numbers.
* @param a The number to be subtracted from.
* @param b The number to subtract.
* @returns The result of the subtraction.
* @zh 两数相减
* @param a 被减数
* @param b 减数
* @returns 两数相减的结果
*/
static subtract(a: number, b: number): number;
/**
* @en Multiply two numbers.
* @param a The first number.
* @param b The second number.
* @returns The product of the two numbers.
* @zh 两数相乘
* @param a 第一个数
* @param b 第二个数
* @returns 两数相乘的结果
*/
static multiply(a: number, b: number): number;
/**
* @en Divide two numbers.
* @param a The dividend.
* @param b The divisor.
* @returns The quotient of the two numbers.
* @zh 两数相除
* @param a 被除数
* @param b 除数
* @returns 两数相除的结果
* @throws 如果除数为0,则抛出错误
*/
static divide(a: number, b: number): number;
/**
* @en Calculate the power of a number.
* @param base The base number.
* @param exponent The exponent.
* @returns The result of raising the base to the exponent.
* @zh 计算数字的幂次方
* @param base 底数
* @param exponent 指数
* @returns 幂次方的结果
*/
static power(base: number, exponent: number): number;
/**
* @en Calculate the square root of a number.
* @param value The number to calculate the square root of.
* @returns The square root of the number.
* @zh 计算平方根
* @param value 数字
* @returns 平方根的结果
* @throws 如果数字为负数,则抛出错误
*/
static sqrt(value: number): number;
/**
* @en Calculate the absolute value of a number.
* @param value The number to calculate the absolute value of.
* @returns The absolute value of the number.
* @zh 计算一个数的绝对值
* @param value 数字
* @returns 数字的绝对值
*/
static abs(value: number): number;
/**
* @en Calculate the sine of an angle in radians.
* @param angle The angle in radians.
* @returns The sine of the angle.
* @zh 计算正弦值
* @param angle 角度
* @returns 正弦值
*/
static sin(angle: number): number;
/**
* @en Calculate the cosine of an angle in radians.
* @param angle The angle in radians.
* @returns The cosine of the angle.
* @zh 计算余弦值
* @param angle 角度
* @returns 余弦值
*/
static cos(angle: number): number;
/**
* @en Calculate the tangent of an angle in radians.
* @param angle The angle in radians.
* @returns The tangent of the angle.
* @zh 计算正切值
* @param angle 角度
* @returns 正切值
*/
static tan(angle: number): number;
/**
* @en Calculate the arcsine of a value.
* @param value The value to calculate the arcsine of.
* @returns The arcsine of the value.
* @zh 计算反正弦值
* @param value 数值
* @returns 反正弦值
*/
static asin(value: number): number;
/**
* @en Calculate the arccosine of a value.
* @param value The value to calculate the arccosine of.
* @returns The arccosine of the value.
* @zh 计算反余弦值
* @param value 数值
* @returns 反余弦值
*/
static acos(value: number): number;
/**
* @en Calculate the arctangent of a value.
* @param value The value to calculate the arctangent of.
* @returns The arctangent of the value.
* @zh 计算反正切值
* @param value 数值
* @returns 反正切值
*/
static atan(value: number): number;
/**
* @en Calculate the arctangent of y/x (in radians).
* @param y The y-coordinate.
* @param x The x-coordinate.
* @returns The angle in radians.
* @zh 计算 y/x(弧度表示)的反正切值
* @param y y 轴坐标
* @param x x 轴坐标
* @returns 弧度
*/
static atan2(y: number, x: number): number;
/**
* @en Calculate the distance between two points (x1, y1) and (x2, y2).
* @param x1 The x-coordinate of the first point.
* @param y1 The y-coordinate of the first point.
* @param x2 The x-coordinate of the second point.
* @param y2 The y-coordinate of the second point.
* @returns The distance between the two points.
* @zh 计算两点之间的距离
* @param x1 第一个点的x坐标
* @param y1 第一个点的y坐标
* @param x2 第二个点的x坐标
* @param y2 第二个点的y坐标
* @returns 两点之间的距离
*/
static distance(x1: number, y1: number, x2: number, y2: number): number;
/**
* @en Round a number to a specified number of decimal places.
* @param value The number to round.
* @param decimals The number of decimal places to round to. Defaults to 0.
* @returns The rounded number.
* @zh 四舍五入到指定的小数位数
* @param value 要四舍五入的数字
* @param decimals 小数位数,默认为0
* @returns 四舍五入后的结果
*/
static round(value: number, decimals?: number): number;
/**
* @en Round a number down to the nearest integer.
* @param value The number to round down.
* @returns The rounded down integer.
* @zh 向下取整
* @param value 数字
* @returns 向下取整后的结果
*/
static floor(value: number): number;
/**
* @en Round a number up to the nearest integer.
* @param value The number to round up.
* @returns The rounded up integer.
* @zh 向上取整
* @param value 数字
* @returns 向上取整后的结果
*/
static ceil(value: number): number;
/**
* @en Calculate the remainder of the division of two numbers.
* @param dividend The number to be divided.
* @param divisor The number to divide by.
* @returns The remainder of the division.
* @zh 计算余数
* @param dividend 被除数
* @param divisor 除数
* @returns 余数
*/
static mod(dividend: number, divisor: number): number;
/**
* @en Calculate the minimum of two numbers.
* @param a The first number.
* @param b The second number.
* @returns The minimum of the two numbers.
* @zh 计算两数的最小值
* @param a 第一个数
* @param b 第二个数
* @returns 两数的最小值
*/
static min(a: number, b: number): number;
/**
* @en Calculate the maximum of two numbers.
* @param a The first number.
* @param b The second number.
* @returns The maximum of the two numbers.
* @zh 计算两数的最大值
* @param a 第一个数
* @param b 第二个数
* @returns 两数的最大值
*/
static max(a: number, b: number): number;
/**
* @en Generate a random number between 0 (inclusive) and 1 (exclusive).
* @returns A random number between 0 and 1.
* @zh 生成一个介于 0(包含)和 1(不包含)之间的随机数。
* @returns 介于 0 和 1
*/
static random(): number;
/**
* @en Generate a random number between min (inclusive) and max (exclusive).
* @param min The minimum value (inclusive).
* @param max The maximum value (exclusive).
* @returns A random number between min and max.
* @zh 生成一个介于 min(包含)和 max(不包含)之间的随机数。
* @param min 最小值(包含)。
* @param max 最大值(不包含)。
* @returns 介于 min 和 max 之间的随机数。
*/
static random(min: number, max: number): number;
/**
* @en Check if a number is greater than another number.
* @param a The first number.
* @param b The second number.
* @returns True if a is greater than b; otherwise, false.
* @zh 判断a是否大于b
* @param a 第一个数字
* @param b 第二个数字
* @returns 如果a大于b,则返回true;否则返回false
*/
static greater(a: number, b: number): boolean;
/**
* @en Check if a number is less than another number.
* @param a The first number.
* @param b The second number.
* @returns True if a is less than b; otherwise, false.
* @zh 判断a是否小于b
* @param a 第一个数字
* @param b 第二个数字
* @returns 如果a小于b,则返回true;否则返回false
*/
static less(a: number, b: number): boolean;
/**
* @en Check if two numbers are equal.
* @param a The first number.
* @param b The second number.
* @returns True if a is equal to b; otherwise, false.
* @zh 判断两个数字是否相同
* @param a 第一个数字
* @param b 第二个数字
* @returns 是否相同
*/
static equal(a: number, b: number): boolean;
/**
* @en Check if a number is greater than or equal to another number.
* @param a The first number.
* @param b The second number.
* @returns True if a is greater than or equal to b; otherwise, false.
* @zh 判断a是否大于等于b
* @param a 第一个数字
* @param b 第二个数字
* @returns 如果a大于等于b,则返回true;否则返回false
*/
static greaterEqual(a: number, b: number): boolean;
/**
* @en Check if a number is less than or equal to another number.
* @param a The first number.
* @param b The second number.
* @returns True if a is less than or equal to b; otherwise, false.
* @zh 判断a是否小于等于b
* @param a 第一个数字
* @param b 第二个数字
* @returns 如果a小于等于b,则返回true;否则返回false
*/
static lessEqual(a: number, b: number): boolean;
/**
* @en Perform bitwise AND operation on two numbers.
* @param a The first number.
* @param b The second number.
* @returns The result of the bitwise AND operation.
* @zh 对两个数字执行按位与操作
* @param a 第一个数字
* @param b 第二个数字
* @returns 按位与操作的结果
*/
static bitAnd(a: number, b: number): number;
/**
* @en Perform bitwise OR operation on two numbers.
* @param a The first number.
* @param b The second number.
* @returns The result of the bitwise OR operation.
* @zh 对两个数字执行按位或操作
* @param a 第一个数字
* @param b 第二个数字
* @returns 按位或操作的结果
*/
static bitOr(a: number, b: number): number;
/**
* @en Perform bitwise XOR operation on two numbers.
* @param a The first number.
* @param b The second number.
* @returns The result of the bitwise XOR operation.
* @zh 对两个数字执行按位异或操作
* @param a 第一个数字
* @param b 第二个数字
* @returns 按位异或操作的结果
*/
static bitXor(a: number, b: number): number;
/**
* @en Perform bitwise NOT operation on a number.
* @param a The number to perform the operation on.
* @returns The result of the bitwise NOT operation.
* @zh 对一个数字执行按位非操作
* @param a 数字
* @returns 按位非操作的结果
*/
static bitNot(a: number): number;
/**
* @en Perform bitwise AND NOT operation on two numbers.
* @param a The first number.
* @param b The second number.
* @returns The result of the bitwise AND NOT operation.
* @zh 对两个数字执行按位与非操作
* @param a 第一个数字
* @param b 第二个数字
* @returns 按位与非操作的结果
*/
static bitAndNot(a: number, b: number): number;
/**
* @en Perform left bitwise shift operation on a number.
* @param a The number to shift.
* @param b The number of bits to shift.
* @returns The result of the left bitwise shift operation.
* @zh 对一个数字执行左移操作
* @param a 数字
* @param b 移动的位数
* @returns 左移操作的结果
*/
static bitLeftShift(a: number, b: number): number;
/**
* @en Perform right bitwise shift operation on a number.
* @param a The number to shift.
* @param b The number of bits to shift.
* @returns The result of the right bitwise shift operation.
* @zh 对一个数字执行右移操作
* @param a 数字
* @param b 移动的位数
* @returns 右移操作的结果
*/
static bitRightShift(a: number, b: number): number;
/**
* @en Perform unsigned right bitwise shift operation on a number.
* @param a The number to shift.
* @param b The number of bits to shift.
* @returns The result of the unsigned right bitwise shift operation.
* @zh 对一个数字执行无符号右移操作
* @param a 数字
* @param b 移动的位数
* @returns 无符号右移操作的结果
*/
static bitUnsignedRightShift(a: number, b: number): number;
}
/**
* @blueprintable @blueprintPure
*/
class BPNumber {
static toFixed(num: number, fractionDigits?: number): string;
static toExponential(num: number, fractionDigits?: number): string;
static toPrecision(num: number, precision?: number): string;
static toString(num: number, radix?: number): string;
}
/**
* @blueprintable
*/
class BPObject<T> {
/** @blueprintPure */
static getItem<T>(obj: Record<string, T>, key: string): T;
static setItem<T>(obj: Record<string, T>, key: string, value: T): void;
static deleteItem<T>(obj: Record<string, T>, key: string): void;
}
/**
* @blueprintable @blueprintPure
*/
class BPString {
static concat(a: string, b: string): string;
static concat(a: string, b: string, c: string): string;
static concat(a: string, b: string, c: string, d: string): string;
static concat(a: string, b: string, c: string, d: string, e: string): string;
static split(str: string, separator: string): string[];
static toUpperCase(str: string): string;
static toLowerCase(str: string): string;
static trim(str: string): string;
static trimStart(str: string): string;
static trimEnd(str: string): string;
static includes(str: string, searchString: string, position?: number): boolean;
static startsWith(str: string, searchString: string): boolean;
static endsWith(str: string, searchString: string): boolean;
static replace(str: string, searchValue: string, newValue: string): string;
static indexOf(str: string, searchValue: string, position?: number): number;
static lastIndexOf(str: string, searchValue: string, position?: number): number;
static repeat(str: string, count: number): string;
static charAt(str: string, index: number): string;
static charCodeAt(str: string, index: number): number;
static substring(str: string, start: number, end?: number): string;
static slice(str: string, start: number, end?: number): string;
static getLength(str: string): number;
static parseInt(str: string, radix?: number): number;
static parseFloat(str: string): number;
}
class ExpressParse {
_catch: Map<string, ExpressTree>;
static brackets: string[];
static brackmap: any;
private static _instance;
static get instance(): ExpressParse;
private isOperator;
private tokenize;
parse(expression: string): ExpressTree;
}
class ExpressTree {
value: any;
left: ExpressTree | null;
right: ExpressTree | null;
static strReg: RegExp;
static realMap: any;
call(context: any): any;
constructor(value: any);
static autoFormat(value: string): any;
equal(value: any, context: any): void;
private static isNumber;
private static isString;
private static isExpress;
private static splitExpress;
clone(): ExpressTree;
static operatorPriority: any;
static _inited: boolean;
static parseProperty(express: string): ExpressTree;
static creatreExpressTree(express: string): ExpressTree;
static init(): void;
}
class ExpressOrgin extends ExpressTree {
constructor(value: any);
call(context: any): any;
}
class ExpressString extends ExpressTree {
constructor(value: any);
call(context: any): any;
}
class ExpressProperty extends ExpressTree {
constructor(value: any);
propertys: string[];
realObj: any;
realKey: string;
equal(value: any, context: any): any;
call(context: any): any;
}
class ExpressFunction extends ExpressProperty {
params: ExpressTree[];
call(context: any): any;
}
class ExpressDict extends ExpressTree {
call(context: any): any;
equal(value: any, context: any): void;
}
const Precedence: any;
class BlueprintExecuteNode extends BlueprintRunBase implements IRunAble {
owner: any;
varDefineMap: Map<string, boolean>;
runtimeDataMgrMap: Map<string | symbol, RuntimeDataManager>;
readCache: boolean;
private _cacheMap;
setCacheAble(node: BlueprintRuntimeBaseNode, runId: number, value: any): void;
getCacheAble(node: BlueprintRuntimeBaseNode, runId: number): boolean;
constructor(data: any);
finish(runtime: IBPRutime): void;
getDataManagerByID(id: string | symbol): IRuntimeDataManager;
initData(key: string | symbol, nodeMap: Map<number, BlueprintRuntimeBaseNode>, localVarMap: Record<string, IBPVariable>, parentId?: string | symbol): void;
debuggerPause: boolean;
pushBack(executeNode: IExecuteListInfo, callback: any): void;
getSelf(): any;
initVar(name: string, value: any): void;
setVar(name: string, value: any): void;
getVar(name: string): any;
getCode(): string;
beginExecute(runtimeNode: BlueprintRuntimeBaseNode, runner: IBPRutime, enableDebugPause: boolean, fromPin: BlueprintPinRuntime, parmsArray: any[], prePin: BlueprintPinRuntime): BlueprintPromise;
endExecute(runtimeNode: BlueprintRuntimeBaseNode): void;
parmFromCustom(parmsArray: any[], parm: any, parmname: string): void;
vars: {
[key: string]: any;
};
parmFromOtherPin(current: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, from: BlueprintPinRuntime, parmsArray: any[], runId: number): void;
parmFromSelf(current: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, parmsArray: any[], runId: number): void;
parmFromOutPut(outPutParmPins: BlueprintPinRuntime[], runtimeDataMgr: IRuntimeDataManager, parmsArray: any[]): void;
executeFun(nativeFun: Function, returnResult: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, caller: any, parmsArray: any[], runId: number): any;
reCall(index: number): void;
}
class RuntimeDataManager implements IRuntimeDataManager {
id: symbol | string;
isInit: boolean;
/**
* 节点数据区Map
*/
nodeMap: Map<number, RuntimeNodeData>;
/**
* 引脚数据Map
*/
pinMap: Map<string, RuntimePinData>;
parmsArray: RuntimePinData[];
localVarObj: any;
localVarMap: Map<number, any>;
constructor(id: symbol | string);
saveContextData(from: number, to: number): void;
private _initGetVarObj;
clearVar(runId: number): void;
getVar(name: string, runId: number): any;
setVar(name: string, value: any, runId: number): void;
getDataById(nid: number): RuntimeNodeData;
getRuntimePinById(id: string): RuntimePinData;
setPinData(pin: BlueprintPinRuntime, value: any, runId: number): void;
getPinData(pin: BlueprintPinRuntime, runId: number): any;
initData(nodeMap: Map<number, BlueprintRuntimeBaseNode>, localVarMap: Record<string, IBPVariable>): void;
}
class BlueprintGenCodeNode extends BlueprintRunBase implements IRunAble {
finish(runtime: IBPRutime): void;
setCacheAble(node: BlueprintRuntimeBaseNode, runId: number, value: any): void;
getCacheAble(node: BlueprintRuntimeBaseNode, runId: number): boolean;
getDataManagerByID(id: string | symbol): IRuntimeDataManager;
initData(key: string | symbol, nodeMap: Map<number, BlueprintRuntimeBaseNode>): void;
debuggerPause: boolean;
readCache: boolean;
pushBack(executeNode: IExecuteListInfo): void;
getSelf(): void;
reCall(index: number): void;
getVar(name: string): void;
initVar(name: string, value: any): void;
setVar(name: string, value: any): void;
find(input: any, outExecutes: BlueprintPinRuntime[]): BlueprintPinRuntime;
codes: string[][];
currentFun: string[];
vars: {
[key: string]: any;
};
blockMap: Map<number, any>;
beginExecute(runtimeNode: BlueprintRuntimeBaseNode): BlueprintPromise;
endExecute(runtimeNode: BlueprintRuntimeBaseNode): void;
parmFromOtherPin(current: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, from: BlueprintPinRuntime, parmsArray: any[], runId: number): void;
parmFromSelf(current: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, parmsArray: any[], runId: number): void;
parmFromOutPut(outPutParmPins: BlueprintPinRuntime[], runtimeDataMgr: IRuntimeDataManager, parmsArray: any[]): void;
parmFromCustom(parmsArray: any[], parm: any, parmname: string): void;
executeFun(nativeFun: Function, returnResult: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, caller: any, parmsArray: any[], runId: number): void;
toString(): string;
getCode(): string;
}
class BlueprintRunBase {
listNode: BlueprintRuntimeBaseNode[];
}
class RuntimeNodeData {
map: Map<number, any[]>;
callFunMap: Map<number, Function>;
eventName: string;
constructor();
getCallFun(runId: number): Function;
setCallFun(runId: number, fun: Function): void;
getParamsArray(runId: number): any[];
}
class RuntimePinData implements IOutParm {
name: string;
private value;
private valueMap;
constructor();
copyValue(runId: number, toRunId: number): void;
initValue(value: any): void;
setValue(runId: number, value: any): void;
private getValueOnly;
getValue(runId: number): any;
}
class BluePrintBlock implements INodeManager<BlueprintRuntimeBaseNode>, IBPRutime {
hasRefAnony: boolean;
localVarMap: Record<string, IBPVariable>;
get blockSourceType(): EBlockSource;
private poolIds;
protected _maxID: number;
/**
* block ID 注释
*/
id: symbol | string;
/**
* block 名称
*/
name: string;
/**
* 节点Map
*/
nodeMap: Map<any, BlueprintRuntimeBaseNode>;
/**
* 执行list
*/
executeList: BlueprintRuntimeBaseNode[];
anonymousfunMap: Map<number, BlueprintEventNode>;
anonymousBlockMap: Map<string, BluePrintEventBlock>;
dataMap: Record<string, IBPVariable | IBPCNode>;
constructor(id: symbol | string);
getDataManagerByID(context: IRunAble): IRuntimeDataManager;
get bpId(): string;
getNodeById(id: any): BlueprintRuntimeBaseNode;
idToIndex: Map<number, number>;
private _addNode;
optimizeByStart(value: BlueprintRuntimeBaseNode, executeAbleList: BlueprintRuntimeBaseNode[]): void;
clear(): void;
optimize(): void;
protected onParse(bpjson: IBPNode[]): void;
append(node: BlueprintRuntimeBaseNode, item: IBPNode): void;
getRunID(): number;
_recoverRunID(id: number, runtimeDataMgr: IRuntimeDataManager): void;
recoverRunID(id: number, runtimeDataMgr: IRuntimeDataManager): void;
runAnonymous(context: IRunAble, event: BlueprintEventNode, parms: any[], cb: Function, runId: number, execId: number, newRunId: number, oldRuntimeDataMgr: IRuntimeDataManager): boolean;
runByContext(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, node: IExecuteListInfo, enableDebugPause: boolean, cb: Function, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime, notRecover?: boolean): boolean;
finish(context: IRunAble): void;
}
enum EBlockSource {
Unknown = 0,
Main = 1,
Function = 2
}
class BluePrintComplexBlock extends BluePrintBlock {
static EventId: number;
private _asList;
private _pendingClass;
private _eventId;
constructor(id: symbol | string);
protected initEventBlockMap(map: Map<number, BlueprintEventNode>, eventMap: Map<string, BluePrintEventBlock>): void;
optimize(): void;
parse(bpjson: Array<IBPNode>, getCNodeByNode: (node: IBPNode) => IBPCNode, varMap: Record<string, IBPVariable>): void;
private _onReParse;
protected onEventParse(eventName: string): void;
private _checkReady;
append(node: BlueprintRuntimeBaseNode, item: IBPNode): void;
finishChild(context: IRunAble, runtime: IBPRutime): void;
}
class BluePrintEventBlock extends BluePrintBlock {
protected parentId: symbol | string;
protected parent: BluePrintComplexBlock;
haRef: boolean;
static findParamPin(node: BlueprintRuntimeBaseNode, nodeMap: Map<any, BlueprintRuntimeBaseNode>, anonymousfunMap: Map<number, BlueprintEventNode>, executeList: BlueprintRuntimeBaseNode[], bluePrintEventBlock: BluePrintEventBlock): void;
init(event: BlueprintEventNode): void;
private _checkRef;
optimizeByBlockMap(parent: BluePrintComplexBlock): void;
getRunID(): number;
recoverRunID(id: number, runtimeDataMgr: IRuntimeDataManager): void;
run(context: IRunAble, event: BlueprintEventNode, parms: any[], cb: Function, runId: number, execId: number): boolean;
getDataManagerByID(context: IRunAble): IRuntimeDataManager;
get bpId(): string;
get blockSourceType(): EBlockSource;
finish(context: IRunAble): void;
}
class BluePrintFunBlock extends BluePrintComplexBlock {
mainBlock: BluePrintMainBlock;
funStart: BlueprintCustomFunStart;
isStatic: boolean;
funBlock: BluePrintFunStartBlock;
get bpId(): string;
get blockSourceType(): EBlockSource;
optimize(): void;
protected onParse(bpjson: IBPNode[]): void;
parse(bpjson: IBPNode[], getCNodeByNode: (node: IBPNode) => IBPCNode, varMap: Record<string, IBPVariable>): void;
run(context: IRunAble, eventName: string, parms: any[], cb: Function, runId: number, execId: number, outExecutes: BlueprintPinRuntime[], runner: IBPRutime, oldRuntimeDataMgr: IRuntimeDataManager): boolean;
}
class BluePrintFunStartBlock extends BluePrintEventBlock {
funEnds: BlueprintCustomFunReturn[];
funStart: BlueprintCustomFunStart;
init(event: BlueprintCustomFunStart): void;
runFun(context: IRunAble, eventName: string, parms: any[], cb: Function, runId: number, execId: number, outExecutes: BlueprintPinRuntime[], runner: IBPRutime, oldRuntimeDataMgr: IRuntimeDataManager): boolean;
}
class BluePrintMainBlock extends BluePrintComplexBlock {
autoAnonymousfuns: BlueprintEventNode[];
autoRunNodes: BlueprintAutoRun[];
eventBlockMap: Map<string, BluePrintEventBlock>;
constructor(id: symbol);
get bpName(): string;
get blockSourceType(): EBlockSource;
eventMap: Map<any, BlueprintEventNode>;
cls: Function;
optimize(): void;
protected onEventParse(eventName: string): void;
append(node: BlueprintRuntimeBaseNode, item: IBPNode): void;
runAuto(context: IRunAble): void;
run(context: IRunAble, event: BlueprintEventNode, parms: any[], cb: Function, runId: number, execId: number): boolean;
finishChild(context: IRunAble, runtime: IBPRutime): void;
}
class BlueprintFactory {
static readonly bpSymbol: unique symbol;
static readonly contextSymbol: unique symbol;
static readonly onChangeSymbol: unique symbol;
static readonly autoRunSymbol: unique symbol;
private static _funMap;
private static _instance;
private static _bpMap;
private static _bpContextMap;
static bpNewMap: Map<string, IBPCNode>;
static BPExecuteCls: any;
static BPRuntimeCls: any;
/**
* 根据节点类型创建相应的对象
* @param type
* @param cls
*/
static regBPClass(type: BPType, cls: new () => BlueprintRuntimeBaseNode): void;
static regFunction(fname: string, fun: Function, isMember?: boolean, cls?: any, target?: string): void;
static getFunction(fname: string, target: string): [
Function,
boolean
];
static regBPContextData(type: BPType, cls: new () => RuntimeNodeData): void;
static getBPContextData(type: BPType): new () => RuntimeNodeData;
/**
* 生成类
* @param name
* @param cls
* @returns
*/
static createCls<T>(name: string, cls: T): T;
/**
* 解析数组
* @param name
* @param isPlaying
* @param newClass
* @param data
* @param funs
* @param varMap
*/
static parseCls(name: string, saveData: IBPSaveData, newClass: any, data: IBPStageData, funs: IBPStageData[], varMap: Record<string, IBPVariable>, preload: string[]): void;
static createClsNew<T>(name: string, saveData: IBPSaveData, cls: T, data: IBPStageData, funs: IBPStageData[], varMap: Record<string, IBPVariable>): T;
static initClassHook(parent: string, cls: Function): void;
static onPropertyChanged_EM(bp: any): void;
static get instance(): BlueprintFactory;
createNew(config: IBPCNode, item: IBPNode): BlueprintRuntimeBaseNode;
}
class BlueprintPinRuntime extends BlueprintPin {
/**
* 所属节点
*/
owner: BlueprintRuntimeBaseNode;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, runner: IBPRutime, runId: number, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise | number;
execute(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, runner: IBPRutime, runId: number): BlueprintPinRuntime;
getValueCode(): any;
}
class BlueprintPromise implements IExecuteListInfo {
nid: number;
enableDebugPause: boolean;
pin: BlueprintPinRuntime;
prePin: BlueprintPinRuntime;
static create(): BlueprintPromise;
private _completed;
private _callback;
/**
* 等待行为完成回调
* @param callback 完成回调接口
*/
wait(callback: (mis: BlueprintPromise) => void): void;
hasCallBack(): boolean;
complete(): void;
recover(): void;
clear(): void;
}
class BlueprintRuntime {
isRunningInIDE: boolean;
mainBlock: BluePrintMainBlock;
funBlockMap: Map<string, BluePrintFunBlock>;
varMap: Record<string, IBPVariable>;
dataMap: Record<string, IBPVariable | IBPCNode>;
constructor();
run(context: IRunAble, event: BlueprintEventNode, parms: any[], cb: Function): void;
/**
* 执行自定义函数
* @param context
* @param funName
* @param parms
*/
runCustomFun(context: IRunAble, funId: string, parms: any[], cb: Function, runId: number, execId: number, outExecutes: BlueprintPinRuntime[], runner: IBPRutime, oldRuntimeDataMgr: IRuntimeDataManager): boolean;
parse(mainBlockData: IBPStageData, getCNodeByNode: (node: IBPNode) => IBPCNode, varMap: Record<string, IBPVariable>, newCls: Function): void;
parseFunction(funData: IBPStageData, getCNodeByNode: (node: IBPNode) => IBPCNode): void;
toCode(context: IRunAble): void;
}
/**
* @blueprintable
*/
class BlueprintStaticFun {
/**
* @en Print a string to the console.
* @param str string to print
* @zh 在控制台打印字符串。
* @param str 字符串内容
*/
static print(str: any): void;
/**
* @en Wait for a specified time in seconds.
* @param second Time in seconds to wait.
* @zh 等待指定的时间(秒)。
* @param second 等待的时间(秒)。
*/
static waitTime(second: number): Promise<boolean>;
/**
* @en Sleep for a specified time in milliseconds.
* @param time Time in milliseconds to sleep.
* @zh 睡眠指定的时间(毫秒)。
* @param time 睡眠的时间(毫秒)。
*/
static sleep(time: number): Promise<void>;
/**
* 执行表达式
* @param express
* @param a
* @param b
* @param c
* @returns
*/
static runExpress(express: string, a: any, b: any, c: any): any;
/**
* @en Destroy an object.
* @param obj Object to destroy.
* @zh 销毁一个对象。
* @param obj 要销毁的对象。
*/
static destroy(obj: any): void;
}
interface IBPRutime {
readonly name: string;
readonly blockSourceType: EBlockSource;
readonly bpId: string;
getDataManagerByID(context: IRunAble): IRuntimeDataManager;
getRunID(): number;
runAnonymous(context: IRunAble, event: BlueprintEventNode, parms: any[], cb: Function, runId: number, execId: number, newRunId: number, oldRuntimeDataMgr: IRuntimeDataManager): boolean;
runByContext(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, node: IExecuteListInfo, enableDebugPause: boolean, cb: Function, runid: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime, notRecover?: boolean): boolean;
}
interface IRunAble {
debuggerPause: boolean;
readCache: boolean;
pushBack(executeNode: IExecuteListInfo, callback: any): void;
readonly vars: {
[key: string]: any;
};
beginExecute(runtimeNode: BlueprintRuntimeBaseNode, runner: IBPRutime, enableDebugPause: boolean, fromPin: BlueprintPinRuntime, parmsArray: any[], prePin: BlueprintPinRuntime): BlueprintPromise;
endExecute(runtimeNode: BlueprintRuntimeBaseNode): void;
parmFromOtherPin(current: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, from: BlueprintPinRuntime, parmsArray: any[], runId: number): void;
parmFromSelf(current: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, parmsArray: any[], runId: number): void;
parmFromOutPut(outPutParmPins: BlueprintPinRuntime[], runtimeDataMgr: IRuntimeDataManager, parmsArray: any[]): void;
parmFromCustom(parmsArray: any[], parm: any, parmname: string): void;
executeFun(nativeFun: Function, returnResult: BlueprintPinRuntime, runtimeDataMgr: IRuntimeDataManager, caller: any, parmsArray: any[], runId: number): any;
getCode(): string;
getVar(name: string): any;
setVar(name: string, value: any): void;
initVar(name: string, value: any): void;
reCall(index: number): void;
getSelf(): any;
initData(key: string | symbol, nodeMap: Map<number, BlueprintRuntimeBaseNode>, localVarMap: Record<string, IBPVariable>, parentId?: string | symbol): void;
getDataManagerByID(id: symbol | string): IRuntimeDataManager;
setCacheAble(node: BlueprintRuntimeBaseNode, runId: number, value: any): void;
getCacheAble(node: BlueprintRuntimeBaseNode, runId: number): boolean;
finish(runtime: IBPRutime): void;
}
class BluePrintAsNode extends BlueprintRuntimeBaseNode {
optimize(): void;
}
class BlueprintAutoRun extends BlueprintRuntimeBaseNode {
protected collectParam(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, inputPins: BlueprintPinRuntime[], runner: IBPRutime, runId: number, prePin: BlueprintPinRuntime): any[];
}
class BluePrintBlockNode extends BlueprintComplexNode {
deal: (inputExecute: BlueprintPinRuntime, inputExecutes: BlueprintPinRuntime[], outExecutes: BlueprintPinRuntime[], outPutParmPins: BlueprintPinRuntime[], context: IRunAble, runner: IBPRutime, runtimeDataMgr: IRuntimeDataManager, runId: number, ...args: any) => BlueprintPinRuntime;
next(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, parmsArray: any[], runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime): BlueprintPinRuntime;
setFunction(fun: Function): void;
}
class BlueprintComplexNode extends BlueprintRuntimeBaseNode {
/**
* 输入引脚
*/
inExecutes: BlueprintPinRuntime[];
constructor();
next(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, parmsArray: any[], runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime): BlueprintPinRuntime;
find: (outExecutes: BlueprintPinRuntime[], ...args: any) => BlueprintPinRuntime;
addPin(pin: BlueprintPinRuntime): void;
setFunction(fun: Function): void;
}
class BlueprintCustomFunNode extends BlueprintFunNode {
/**
* 输入引脚
*/
inExecutes: BlueprintPinRuntime[];
functionID: string;
staticContext: IRunAble;
bpruntime: BlueprintRuntime;
private _isCheck;
constructor();
collectParam(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, inputPins: BlueprintPinRuntime[], runner: IBPRutime, runId: number, prePin: BlueprintPinRuntime): any[];
private _checkFun;
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintFunNode>): void;
protected executeFun(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, runner: IBPRutime, caller: IBluePrintSubclass, parmsArray: any[], runId: number, fromPin: BlueprintPinRuntime): Promise<any>;
protected _executeFun(context: IRunAble, cb: any, parmsArray: any[], runner: IBPRutime): void;
addPin(pin: BlueprintPinRuntime): void;
optimize(): void;
setFunction(fun: Function, isMember: boolean): void;
customFun(parms: any[]): void;
}
class BlueprintCustomFunReturn extends BlueprintRuntimeBaseNode {
/**
* 输入引脚
*/
inExecutes: BlueprintPinRuntime[];
constructor();
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise | number;
initData(runtimeDataMgr: IRuntimeDataManager, curRunId: number, runId: number, parms: any[], offset: number, outExecutes: BlueprintPinRuntime[], runner: IBPRutime, oldRuntimeDataMgr: IRuntimeDataManager): void;
addPin(pin: BlueprintPinRuntime): void;
}
class BlueprintCustomFunReturnContext extends RuntimeNodeData {
returnMap: Map<number, IOutParm[]>;
runIdMap: Map<number, number>;
outExecutesMap: Map<number, BlueprintPinRuntime[]>;
runnerMap: Map<number, [
IBPRutime,
IRuntimeDataManager
]>;
constructor();
initData(curRunId: number, runId: number, parms: any[], offset: number, outExecutes: BlueprintPinRuntime[], runner: IBPRutime, runtimeDataMgr: IRuntimeDataManager): void;
runExecute(runId: number, index: number, context: IRunAble): void;
returnResult(runId: number, curRunId: number): void;
}
class BlueprintCustomFunStart extends BlueprintEventNode {
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintEventNode>): void;
}
class BlueprintEventNode extends BlueprintRuntimeBaseNode {
/**
* 输出引脚
*/
outExecute: BlueprintPinRuntime;
eventName: string;
autoReg: boolean;
isAnonymous: boolean;
constructor();
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintEventNode>): void;
setFunction(fun: Function, isMember: boolean): void;
emptyExecute(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
addPin(pin: BlueprintPinRuntime): void;
optimize(): void;
initData(runtimeDataMgr: IRuntimeDataManager, parms: any[], curRunId: number): void;
}
class BlueprintFunNode extends BlueprintRuntimeBaseNode {
/**
* 输入引脚
*/
inExecute: BlueprintPinRuntime;
/**
* 输出引脚
*/
outExecute: BlueprintPinRuntime;
eventName: string;
constructor();
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintRuntimeBaseNode>): void;
private executeHookFun;
protected executeFun(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, runner: IBPRutime, caller: any, parmsArray: any[], runId: number, fromPin: BlueprintPinRuntime): any;
next(): BlueprintPinRuntime;
addPin(pin: BlueprintPinRuntime): void;
optimize(): void;
}
class BlueprintGetTempVarNode extends BlueprintRuntimeBaseNode {
protected _varKey: string;
constructor();
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintRuntimeBaseNode>): void;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
}
class BlueprintGetVarNode extends BlueprintRuntimeBaseNode {
protected _varKey: string;
constructor();
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintRuntimeBaseNode>): void;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
}
class BlueprintNewTargetNode extends BlueprintRuntimeBaseNode {
cls: ClassDecorator;
parse(def: IBPCNode): void;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
}
class BlueprintRuntimeBaseNode extends BlueprintNode<BlueprintPinRuntime> implements IExecuteListInfo {
private _refNumber;
staticNext: BlueprintPinRuntime;
private static _EMPTY;
nativeFun: Function;
isMember: boolean;
funcode: string;
canCache: boolean;
/**
* 输入参数列表
*/
inPutParmPins: BlueprintPinRuntime[];
/**
* 输出参数列表
*/
outPutParmPins: BlueprintPinRuntime[];
returnValue: BlueprintPinRuntime;
/**
* 输出引脚
*/
outExecutes: BlueprintPinRuntime[];
tryExecute: (context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime) => BlueprintPinRuntime | BlueprintPromise | number;
hasDebugger: boolean;
constructor();
addRef(): void;
getRef(): number;
emptyExecute(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
createPin(def: TBPPinDef): BlueprintPinRuntime;
protected executeFun(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, runner: IBPRutime, caller: any, parmsArray: any[], runId: number, fromPin: BlueprintPinRuntime): any;
protected collectParam(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, inputPins: BlueprintPinRuntime[], runner: IBPRutime, runId: number, prePin: BlueprintPinRuntime): any[];
private _checkRun;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise | number;
checkTarget(temp: any): void;
next(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, parmsArray: any[], runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime): BlueprintPinRuntime;
addPin(pin: BlueprintPinRuntime): void;
optimize(): void;
setFunction(fun: Function, isMember: boolean): void;
protected addNextPIn(): void;
}
class BlueprintSequenceNode extends BlueprintComplexNode {
next(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, parmsArray: any[], runner: IBPRutime, enableDebugPause: boolean, runId: number): BlueprintPinRuntime;
setFunction(fun: Function): void;
}
class BlueprintSetTempVarNode extends BlueprintFunNode {
protected _varKey: string;
constructor();
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintRuntimeBaseNode>): void;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
}
class BlueprintSetVarNode extends BlueprintFunNode {
protected _varKey: string;
constructor();
protected onParseLinkData(node: IBPNode, manager: INodeManager<BlueprintRuntimeBaseNode>): void;
step(context: IRunAble, runtimeDataMgr: IRuntimeDataManager, fromExecute: boolean, runner: IBPRutime, enableDebugPause: boolean, runId: number, fromPin: BlueprintPinRuntime, prePin: BlueprintPinRuntime): BlueprintPinRuntime | BlueprintPromise;
}
class TestBluePrint {
static BPMap: Map<string, TBPNodeDef>;
regBPNode(): void;
testBPNode(): void;
constructor();
}
class test {
constructor();
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
declare module '*.css' {
const value: string
export default value
}
declare module '*.png' {
const value: string
export default value
}
declare module '*.jpg' {
const value: string
export default value
}
declare module '*.jpeg' {
const value: string
export default value
}
declare module '*.gif' {
const value: string
export default value
}
declare module '*.svg' {
const value: string
export default value
}
declare module '*.webp' {
const value: string
export default value
}
declare module '*.ico' {
const value: string
export default value
}
declare module '*.bmp' {
const value: string
export default value
}
declare module '*.woff' {
const value: string
export default value
}
declare module '*.woff2' {
const value: string
export default value
}
declare module '*.ttf' {
const value: string
export default value
}
declare module '*.otf' {
const value: string
export default value
}
declare module '*.eot' {
const value: string
export default value
}
export { };
declare global {
export namespace IEditorClient {
export interface IResourceManager {
/**
* Set the value of the specified property.
* @param obj The resource object.
* @param datapath The data path.
* @param value The value to set.
* @returns Returns true if the value is set, otherwise returns false.
*/
setProps(obj: any, datapath: string[], value: any): Promise<boolean>;
/**
* Get a plain object that contains all properties of the specified object.
*/
getProps(obj: any): any;
}
export type SceneNavToolType = "move" | "orbit" | "orbit_focus" | "zoom" | "obj_move" | "obj_rotate" | "obj_scale" | "obj_transform";
export interface IGameScene {
readonly allNodes: Map<string, WeakRef<Laya.Node>>;
readonly nodesSet_gizmo: Set<Laya.Node>;
readonly nodesSet_cameras: Set<Laya.Camera>;
readonly rootNode2D: Laya.Sprite;
readonly rootNode3D: Laya.Scene3D;
readonly scene3D: Laya.Scene3D;
readonly bridge3DSprite: Laya.Bridge3DSprite;
readonly prefabRootNode: Laya.Node;
readonly worldType: string;
start(): Promise<void>;
readonly selection: Array<Laya.Node>;
readonly topLevelSelection: ReadonlyArray<Laya.Node>;
readonly has3DSelection: boolean;
addSelection(target: Laya.Node, ctrlKey?: boolean): void;
setSelection(nodes: ReadonlyArray<Laya.Node>): void;
removeSelection(node: Laya.Node): void;
clearSelection(): void;
readonly openedBoxChain: ReadonlyArray<Laya.Sprite>;
readonly openedBox: Laya.Sprite;
openBox(box: Laya.Sprite): void;
closeBox(): void;
findBox(node: Laya.Sprite): Laya.Sprite;
isBox(node: Laya.Node): boolean;
getNodeById(id: string): Laya.Node;
registerNode(node: Laya.Node): void;
findNodes(keyword: string, maxResults?: number): Promise<Array<any>>;
setProps(obj: Laya.Node | Laya.Component, datapath: ReadonlyArray<string>, value: any): Promise<boolean>;
setResProps(obj: any, datapath: ReadonlyArray<string>, value: any): Promise<boolean>;
getProps(obj: any): any;
recordObject(node: Laya.Node | Laya.Component, ...propNames: ReadonlyArray<string>): void;
sendChildChanged(node: Laya.Node): void;
sendNameChanged(node: Laya.Node, newName: string): void;
sendFeaturesChanged(node: Laya.Node): void;
}
export interface IEditorClientSingleton {
readonly port: IMyMessagePort;
readonly scene: IGameScene;
readonly typeRegistry: ITypeRegistry;
resourceManager: IResourceManager;
navigationManager: INavigationManager;
d3Manager: ID3Manager;
gizmosManager: IGizmosManager;
pickManager: IPickManager;
vertexPicker: IVertexPicker;
hostPixelRatio: number;
hostViewWidth: number;
hostViewHeight: number;
hostCanvasColor: Laya.Color;
addStartCallback(callback: () => void | Promise<void>): void;
sendMessageToPanel(panelId: string, cmd: string, ...args: Array<any>): Promise<any>;
postMessageToPanel(panelId: string, cmd: string, ...args: Array<any>): Promise<void>;
runUIScript(command: string, ...args: any[]): Promise<any>;
invalidateFrame(): void;
}
/**
* The `MyMessagePort` class is used to create a message port object.
*
* A message port is a communication channel that allows two different processes to communicate with each other.
* @param port The native message port.
* @param queueTask Whether to queue the task. If true, the received messages will be queued and processed sequentially. Defaults to false.
* @see IMyMessagePort
* @see MyMessagePortStatic
*/
const MyMessagePort: (new (port: MessagePort, queueTask?: boolean) => IMyMessagePort) & typeof MyMessagePortStatic;
}
var EditorClient: IEditorClient.IEditorClientSingleton;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
declare module '*.glsl' {
const value: string
export default value
}
declare module '*.vs' {
const value: string
export default value
}
declare module '*.fs' {
const value: string
export default value
}
declare module '*.wgsl' {
const value: string
export default value
}
\ No newline at end of file
declare module spine {
interface StringMap<T> {
[key: string]: T;
}
class IntSet {
array: number[];
add(value: number): boolean;
contains(value: number): boolean;
remove(value: number): void;
clear(): void;
}
class StringSet {
entries: StringMap<boolean>;
size: number;
add(value: string): boolean;
addAll(values: string[]): boolean;
contains(value: string): boolean;
clear(): void;
}
type NumberArrayLike = Array<number> | Float32Array;
type IntArrayLike = Array<number> | Int16Array;
interface Disposable {
dispose(): void;
}
interface Restorable {
restore(): void;
}
class Color {
r: number;
g: number;
b: number;
a: number;
static WHITE: Color;
static RED: Color;
static GREEN: Color;
static BLUE: Color;
static MAGENTA: Color;
constructor(r?: number, g?: number, b?: number, a?: number);
set(r: number, g: number, b: number, a: number): this;
setFromColor(c: Color): this;
setFromString(hex: string): this;
add(r: number, g: number, b: number, a: number): this;
clamp(): this;
static rgba8888ToColor(color: Color, value: number): void;
static rgb888ToColor(color: Color, value: number): void;
toRgb888(): number;
static fromString(hex: string): Color;
}
class MathUtils {
static PI: number;
static PI2: number;
static invPI2: number;
static radiansToDegrees: number;
static radDeg: number;
static degreesToRadians: number;
static degRad: number;
static clamp(value: number, min: number, max: number): number;
static cosDeg(degrees: number): number;
static sinDeg(degrees: number): number;
static atan2Deg(y: number, x: number): number;
static signum(value: number): number;
static toInt(x: number): number;
static cbrt(x: number): number;
static randomTriangular(min: number, max: number): number;
static randomTriangularWith(min: number, max: number, mode: number): number;
static isPowerOfTwo(value: number): boolean;
}
abstract class Interpolation {
protected abstract applyInternal(a: number): number;
apply(start: number, end: number, a: number): number;
}
class Pow extends Interpolation {
protected power: number;
constructor(power: number);
applyInternal(a: number): number;
}
class PowOut extends Pow {
constructor(power: number);
applyInternal(a: number): number;
}
class Utils {
static SUPPORTS_TYPED_ARRAYS: boolean;
static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
static arrayFill<T>(array: ArrayLike<T>, fromIndex: number, toIndex: number, value: T): void;
static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): NumberArrayLike;
static newShortArray(size: number): IntArrayLike;
static toFloatArray(array: Array<number>): number[] | Float32Array;
static toSinglePrecision(value: number): number;
static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
static contains<T>(array: Array<T>, element: T, identity?: boolean): boolean;
static enumValue(type: any, name: string): any;
}
class DebugUtils {
static logBones(skeleton: Skeleton): void;
}
class Pool<T> {
private items;
private instantiator;
constructor(instantiator: () => T);
obtain(): T;
free(item: T): void;
freeAll(items: ArrayLike<T>): void;
clear(): void;
}
class Vector2 {
x: number;
y: number;
constructor(x?: number, y?: number);
set(x: number, y: number): Vector2;
length(): number;
normalize(): this;
}
class TimeKeeper {
maxDelta: number;
framesPerSecond: number;
delta: number;
totalTime: number;
private lastTime;
private frameCount;
private frameTime;
update(): void;
}
interface ArrayLike<T> {
length: number;
[n: number]: T;
}
class WindowedMean {
values: Array<number>;
addedValues: number;
lastValue: number;
mean: number;
dirty: boolean;
constructor(windowSize?: number);
hasEnoughData(): boolean;
addValue(value: number): void;
getMean(): number;
}
}
declare module spine {
class Animation {
name: string;
timelines: Array<Timeline>;
timelineIds: StringSet;
duration: number;
constructor(name: string, timelines: Array<Timeline>, duration: number);
setTimelines(timelines: Array<Timeline>): void;
hasTimeline(ids: string[]): boolean;
apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
enum MixBlend {
setup = 0,
first = 1,
replace = 2,
add = 3
}
enum MixDirection {
mixIn = 0,
mixOut = 1
}
abstract class Timeline {
propertyIds: string[];
frames: NumberArrayLike;
constructor(frameCount: number, propertyIds: string[]);
getPropertyIds(): string[];
getFrameEntries(): number;
getFrameCount(): number;
getDuration(): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event> | null, alpha: number, blend: MixBlend, direction: MixDirection): void;
static search1(frames: NumberArrayLike, time: number): number;
static search(frames: NumberArrayLike, time: number, step: number): number;
}
interface BoneTimeline {
boneIndex: number;
}
interface SlotTimeline {
slotIndex: number;
}
abstract class CurveTimeline extends Timeline {
protected curves: NumberArrayLike;
constructor(frameCount: number, bezierCount: number, propertyIds: string[]);
setLinear(frame: number): void;
setStepped(frame: number): void;
shrink(bezierCount: number): void;
setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, cy2: number, time2: number, value2: number): void;
getBezierValue(time: number, frameIndex: number, valueOffset: number, i: number): number;
}
abstract class CurveTimeline1 extends CurveTimeline {
constructor(frameCount: number, bezierCount: number, propertyId: string);
getFrameEntries(): number;
setFrame(frame: number, time: number, value: number): void;
getCurveValue(time: number): number;
getRelativeValue(time: number, alpha: number, blend: MixBlend, current: number, setup: number): number;
getAbsoluteValue(time: number, alpha: number, blend: MixBlend, current: number, setup: number): number;
getAbsoluteValue2(time: number, alpha: number, blend: MixBlend, current: number, setup: number, value: number): number;
getScaleValue(time: number, alpha: number, blend: MixBlend, direction: MixDirection, current: number, setup: number): number;
}
abstract class CurveTimeline2 extends CurveTimeline {
constructor(frameCount: number, bezierCount: number, propertyId1: string, propertyId2: string);
getFrameEntries(): number;
setFrame(frame: number, time: number, value1: number, value2: number): void;
}
class RotateTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event> | null, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class TranslateTimeline extends CurveTimeline2 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class TranslateXTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class TranslateYTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class ScaleTimeline extends CurveTimeline2 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class ScaleXTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class ScaleYTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class ShearTimeline extends CurveTimeline2 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class ShearXTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class ShearYTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class InheritTimeline extends Timeline implements BoneTimeline {
boneIndex: number;
constructor(frameCount: number, boneIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, inherit: Inherit): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class RGBATimeline extends CurveTimeline implements SlotTimeline {
slotIndex: number;
constructor(frameCount: number, bezierCount: number, slotIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, r: number, g: number, b: number, a: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class RGBTimeline extends CurveTimeline implements SlotTimeline {
slotIndex: number;
constructor(frameCount: number, bezierCount: number, slotIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, r: number, g: number, b: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
slotIndex: number;
constructor(frameCount: number, bezierCount: number, slotIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
slotIndex: number;
constructor(frameCount: number, bezierCount: number, slotIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class RGB2Timeline extends CurveTimeline implements SlotTimeline {
slotIndex: number;
constructor(frameCount: number, bezierCount: number, slotIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, r: number, g: number, b: number, r2: number, g2: number, b2: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class AttachmentTimeline extends Timeline implements SlotTimeline {
slotIndex: number;
attachmentNames: Array<string | null>;
constructor(frameCount: number, slotIndex: number);
getFrameCount(): number;
setFrame(frame: number, time: number, attachmentName: string | null): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
setAttachment(skeleton: Skeleton, slot: Slot, attachmentName: string | null): void;
}
class DeformTimeline extends CurveTimeline implements SlotTimeline {
slotIndex: number;
attachment: VertexAttachment;
vertices: Array<NumberArrayLike>;
constructor(frameCount: number, bezierCount: number, slotIndex: number, attachment: VertexAttachment);
getFrameCount(): number;
setFrame(frame: number, time: number, vertices: NumberArrayLike): void;
setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, cy2: number, time2: number, value2: number): void;
getCurvePercent(time: number, frame: number): number;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class EventTimeline extends Timeline {
static propertyIds: string[];
events: Array<Event>;
constructor(frameCount: number);
getFrameCount(): number;
setFrame(frame: number, event: Event): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class DrawOrderTimeline extends Timeline {
static propertyIds: string[];
drawOrders: Array<Array<number> | null>;
constructor(frameCount: number);
getFrameCount(): number;
setFrame(frame: number, time: number, drawOrder: Array<number> | null): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class IkConstraintTimeline extends CurveTimeline {
constraintIndex: number;
constructor(frameCount: number, bezierCount: number, ikConstraintIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, mix: number, softness: number, bendDirection: number, compress: boolean, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class TransformConstraintTimeline extends CurveTimeline {
constraintIndex: number;
constructor(frameCount: number, bezierCount: number, transformConstraintIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, mixRotate: number, mixX: number, mixY: number, mixScaleX: number, mixScaleY: number, mixShearY: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class PathConstraintPositionTimeline extends CurveTimeline1 {
constraintIndex: number;
constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class PathConstraintSpacingTimeline extends CurveTimeline1 {
constraintIndex: number;
constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class PathConstraintMixTimeline extends CurveTimeline {
constraintIndex: number;
constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number);
getFrameEntries(): number;
setFrame(frame: number, time: number, mixRotate: number, mixX: number, mixY: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
abstract class PhysicsConstraintTimeline extends CurveTimeline1 {
constraintIndex: number;
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number);
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
abstract setup(constraint: PhysicsConstraint): number;
abstract get(constraint: PhysicsConstraint): number;
abstract set(constraint: PhysicsConstraint, value: number): void;
abstract global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintInertiaTimeline extends PhysicsConstraintTimeline {
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number);
setup(constraint: PhysicsConstraint): number;
get(constraint: PhysicsConstraint): number;
set(constraint: PhysicsConstraint, value: number): void;
global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintStrengthTimeline extends PhysicsConstraintTimeline {
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number);
setup(constraint: PhysicsConstraint): number;
get(constraint: PhysicsConstraint): number;
set(constraint: PhysicsConstraint, value: number): void;
global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintDampingTimeline extends PhysicsConstraintTimeline {
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number);
setup(constraint: PhysicsConstraint): number;
get(constraint: PhysicsConstraint): number;
set(constraint: PhysicsConstraint, value: number): void;
global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintMassTimeline extends PhysicsConstraintTimeline {
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number);
setup(constraint: PhysicsConstraint): number;
get(constraint: PhysicsConstraint): number;
set(constraint: PhysicsConstraint, value: number): void;
global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintWindTimeline extends PhysicsConstraintTimeline {
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number);
setup(constraint: PhysicsConstraint): number;
get(constraint: PhysicsConstraint): number;
set(constraint: PhysicsConstraint, value: number): void;
global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number);
setup(constraint: PhysicsConstraint): number;
get(constraint: PhysicsConstraint): number;
set(constraint: PhysicsConstraint, value: number): void;
global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {
constructor(frameCount: number, bezierCount: number, physicsConstraintIndex: number);
setup(constraint: PhysicsConstraint): number;
get(constraint: PhysicsConstraint): number;
set(constraint: PhysicsConstraint, value: number): void;
global(constraint: PhysicsConstraintData): boolean;
}
class PhysicsConstraintResetTimeline extends Timeline {
private static propertyIds;
constraintIndex: number;
constructor(frameCount: number, physicsConstraintIndex: number);
getFrameCount(): number;
setFrame(frame: number, time: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
class SequenceTimeline extends Timeline implements SlotTimeline {
static ENTRIES: number;
static MODE: number;
static DELAY: number;
slotIndex: number;
attachment: HasTextureRegion;
constructor(frameCount: number, slotIndex: number, attachment: HasTextureRegion);
getFrameEntries(): number;
getSlotIndex(): number;
getAttachment(): Attachment;
setFrame(frame: number, time: number, mode: SequenceMode, index: number, delay: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
}
}
declare module spine {
class AnimationState {
static _emptyAnimation: Animation;
private static emptyAnimation;
data: AnimationStateData;
tracks: TrackEntry[];
timeScale: number;
unkeyedState: number;
events: Event[];
listeners: AnimationStateListener[];
queue: EventQueue;
propertyIDs: StringSet;
animationsChanged: boolean;
trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData);
update(delta: number): void;
updateMixingFrom(to: TrackEntry, delta: number): boolean;
apply(skeleton: Skeleton): boolean;
applyMixingFrom(to: TrackEntry, skeleton: Skeleton, blend: MixBlend): number;
applyAttachmentTimeline(timeline: AttachmentTimeline, skeleton: Skeleton, time: number, blend: MixBlend, attachments: boolean): void;
setAttachment(skeleton: Skeleton, slot: Slot, attachmentName: string | null, attachments: boolean): void;
applyRotateTimeline(timeline: RotateTimeline, skeleton: Skeleton, time: number, alpha: number, blend: MixBlend, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
queueEvents(entry: TrackEntry, animationTime: number): void;
clearTracks(): void;
clearTrack(trackIndex: number): void;
setCurrent(index: number, current: TrackEntry, interrupt: boolean): void;
setAnimation(trackIndex: number, animationName: string, loop?: boolean): TrackEntry;
setAnimationWith(trackIndex: number, animation: Animation, loop?: boolean): TrackEntry;
addAnimation(trackIndex: number, animationName: string, loop?: boolean, delay?: number): TrackEntry;
addAnimationWith(trackIndex: number, animation: Animation, loop?: boolean, delay?: number): TrackEntry;
setEmptyAnimation(trackIndex: number, mixDuration?: number): TrackEntry;
addEmptyAnimation(trackIndex: number, mixDuration?: number, delay?: number): TrackEntry;
setEmptyAnimations(mixDuration?: number): void;
expandToIndex(index: number): TrackEntry;
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry | null): TrackEntry;
clearNext(entry: TrackEntry): void;
_animationsChanged(): void;
computeHold(entry: TrackEntry): void;
getCurrent(trackIndex: number): TrackEntry;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
clearListeners(): void;
clearListenerNotifications(): void;
}
class TrackEntry {
animation: Animation | null;
previous: TrackEntry | null;
next: TrackEntry | null;
mixingFrom: TrackEntry | null;
mixingTo: TrackEntry | null;
listener: AnimationStateListener | null;
trackIndex: number;
loop: boolean;
holdPrevious: boolean;
reverse: boolean;
shortestRotation: boolean;
eventThreshold: number;
mixAttachmentThreshold: number;
alphaAttachmentThreshold: number;
mixDrawOrderThreshold: number;
animationStart: number;
animationEnd: number;
animationLast: number;
nextAnimationLast: number;
delay: number;
trackTime: number;
trackLast: number;
nextTrackLast: number;
trackEnd: number;
timeScale: number;
alpha: number;
mixTime: number;
_mixDuration: number;
interruptAlpha: number;
totalAlpha: number;
get mixDuration(): number;
set mixDuration(mixDuration: number);
setMixDurationWithDelay(mixDuration: number, delay: number): void;
mixBlend: MixBlend;
timelineMode: number[];
timelineHoldMix: TrackEntry[];
timelinesRotation: number[];
reset(): void;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
isComplete(): boolean;
resetRotationDirections(): void;
getTrackComplete(): number;
wasApplied(): boolean;
isNextReady(): boolean;
}
class EventQueue {
objects: Array<any>;
drainDisabled: boolean;
animState: AnimationState;
constructor(animState: AnimationState);
start(entry: TrackEntry): void;
interrupt(entry: TrackEntry): void;
end(entry: TrackEntry): void;
dispose(entry: TrackEntry): void;
complete(entry: TrackEntry): void;
event(entry: TrackEntry, event: Event): void;
drain(): void;
clear(): void;
}
enum EventType {
start = 0,
interrupt = 1,
end = 2,
dispose = 3,
complete = 4,
event = 5
}
interface AnimationStateListener {
start?: (entry: TrackEntry) => void;
interrupt?: (entry: TrackEntry) => void;
end?: (entry: TrackEntry) => void;
dispose?: (entry: TrackEntry) => void;
complete?: (entry: TrackEntry) => void;
event?: (entry: TrackEntry, event: Event) => void;
}
abstract class AnimationStateAdapter implements AnimationStateListener {
start(entry: TrackEntry): void;
interrupt(entry: TrackEntry): void;
end(entry: TrackEntry): void;
dispose(entry: TrackEntry): void;
complete(entry: TrackEntry): void;
event(entry: TrackEntry, event: Event): void;
}
const SUBSEQUENT = 0;
const FIRST = 1;
const HOLD_SUBSEQUENT = 2;
const HOLD_FIRST = 3;
const HOLD_MIX = 4;
const SETUP = 1;
const CURRENT = 2;
}
declare module spine {
class AnimationStateData {
skeletonData: SkeletonData;
animationToMixTime: StringMap<number>;
defaultMix: number;
constructor(skeletonData: SkeletonData);
setMix(fromName: string, toName: string, duration: number): void;
setMixWith(from: Animation, to: Animation, duration: number): void;
getMix(from: Animation, to: Animation): number;
}
}
declare module spine {
class AssetManagerBase implements Disposable {
private pathPrefix;
private textureLoader;
private downloader;
private assets;
private errors;
private toLoad;
private loaded;
constructor(textureLoader: (image: HTMLImageElement | ImageBitmap) => Texture, pathPrefix?: string, downloader?: Downloader);
private start;
private success;
private error;
loadAll(): Promise<AssetManagerBase>;
setRawDataURI(path: string, data: string): void;
loadBinary(path: string, success?: (path: string, binary: Uint8Array) => void, error?: (path: string, message: string) => void): void;
loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, message: string) => void): void;
loadJson(path: string, success?: (path: string, object: object) => void, error?: (path: string, message: string) => void): void;
loadTexture(path: string, success?: (path: string, texture: Texture) => void, error?: (path: string, message: string) => void): void;
loadTextureAtlas(path: string, success?: (path: string, atlas: TextureAtlas) => void, error?: (path: string, message: string) => void, fileAlias?: {
[keyword: string]: string;
}): void;
get(path: string): any;
require(path: string): any;
remove(path: string): any;
removeAll(): void;
isLoadingComplete(): boolean;
getToLoad(): number;
getLoaded(): number;
dispose(): void;
hasErrors(): boolean;
getErrors(): StringMap<string>;
}
class Downloader {
private callbacks;
rawDataUris: StringMap<string>;
dataUriToString(dataUri: string): string;
base64ToUint8Array(base64: string): Uint8Array;
dataUriToUint8Array(dataUri: string): Uint8Array;
downloadText(url: string, success: (data: string) => void, error: (status: number, responseText: string) => void): void;
downloadJson(url: string, success: (data: object) => void, error: (status: number, responseText: string) => void): void;
downloadBinary(url: string, success: (data: Uint8Array) => void, error: (status: number, responseText: string) => void): void;
private start;
private finish;
}
}
declare module spine {
class AtlasAttachmentLoader implements AttachmentLoader {
atlas: TextureAtlas;
constructor(atlas: TextureAtlas);
loadSequence(name: string, basePath: string, sequence: Sequence): void;
newRegionAttachment(skin: Skin, name: string, path: string, sequence: Sequence): RegionAttachment;
newMeshAttachment(skin: Skin, name: string, path: string, sequence: Sequence): MeshAttachment;
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
newPathAttachment(skin: Skin, name: string): PathAttachment;
newPointAttachment(skin: Skin, name: string): PointAttachment;
newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
}
}
declare module spine {
abstract class Attachment {
name: string;
constructor(name: string);
abstract copy(): Attachment;
}
abstract class VertexAttachment extends Attachment {
private static nextID;
id: number;
bones: Array<number> | null;
vertices: NumberArrayLike;
worldVerticesLength: number;
timelineAttachment: Attachment;
constructor(name: string);
computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: NumberArrayLike, offset: number, stride: number): void;
copyTo(attachment: VertexAttachment): void;
}
}
declare module spine {
interface AttachmentLoader {
newRegionAttachment(skin: Skin, name: string, path: string, sequence: Sequence | null): RegionAttachment;
newMeshAttachment(skin: Skin, name: string, path: string, sequence: Sequence | null): MeshAttachment;
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
newPathAttachment(skin: Skin, name: string): PathAttachment;
newPointAttachment(skin: Skin, name: string): PointAttachment;
newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
}
}
declare module spine {
class BoundingBoxAttachment extends VertexAttachment {
color: Color;
constructor(name: string);
copy(): Attachment;
}
}
declare module spine {
class ClippingAttachment extends VertexAttachment {
endSlot: SlotData | null;
color: Color;
constructor(name: string);
copy(): Attachment;
}
}
declare module spine {
interface HasTextureRegion {
path: string;
region: TextureRegion | null;
updateRegion(): void;
color: Color;
sequence: Sequence | null;
}
}
declare module spine {
class MeshAttachment extends VertexAttachment implements HasTextureRegion {
region: TextureRegion | null;
path: string;
regionUVs: NumberArrayLike;
uvs: NumberArrayLike;
triangles: Array<number>;
color: Color;
width: number;
height: number;
hullLength: number;
edges: Array<number>;
private parentMesh;
sequence: Sequence | null;
tempColor: Color;
constructor(name: string, path: string);
updateRegion(): void;
getParentMesh(): MeshAttachment;
setParentMesh(parentMesh: MeshAttachment): void;
copy(): Attachment;
computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: NumberArrayLike, offset: number, stride: number): void;
newLinkedMesh(): MeshAttachment;
}
}
declare module spine {
class PathAttachment extends VertexAttachment {
lengths: Array<number>;
closed: boolean;
constantSpeed: boolean;
color: Color;
constructor(name: string);
copy(): Attachment;
}
}
declare module spine {
class PointAttachment extends VertexAttachment {
x: number;
y: number;
rotation: number;
color: Color;
constructor(name: string);
computeWorldPosition(bone: Bone, point: Vector2): Vector2;
computeWorldRotation(bone: Bone): number;
copy(): Attachment;
}
}
declare module spine {
class RegionAttachment extends Attachment implements HasTextureRegion {
x: number;
y: number;
scaleX: number;
scaleY: number;
rotation: number;
width: number;
height: number;
color: Color;
path: string;
region: TextureRegion | null;
sequence: Sequence | null;
offset: number[] | Float32Array;
uvs: number[] | Float32Array;
tempColor: Color;
constructor(name: string, path: string);
updateRegion(): void;
computeWorldVertices(slot: Slot, worldVertices: NumberArrayLike, offset: number, stride: number): void;
copy(): Attachment;
static X1: number;
static Y1: number;
static C1R: number;
static C1G: number;
static C1B: number;
static C1A: number;
static U1: number;
static V1: number;
static X2: number;
static Y2: number;
static C2R: number;
static C2G: number;
static C2B: number;
static C2A: number;
static U2: number;
static V2: number;
static X3: number;
static Y3: number;
static C3R: number;
static C3G: number;
static C3B: number;
static C3A: number;
static U3: number;
static V3: number;
static X4: number;
static Y4: number;
static C4R: number;
static C4G: number;
static C4B: number;
static C4A: number;
static U4: number;
static V4: number;
}
}
declare module spine {
class Sequence {
private static _nextID;
id: number;
regions: TextureRegion[];
start: number;
digits: number;
setupIndex: number;
constructor(count: number);
copy(): Sequence;
apply(slot: Slot, attachment: HasTextureRegion): void;
getPath(basePath: string, index: number): string;
private static nextID;
}
enum SequenceMode {
hold = 0,
once = 1,
loop = 2,
pingpong = 3,
onceReverse = 4,
loopReverse = 5,
pingpongReverse = 6
}
const SequenceModeValues: SequenceMode[];
}
declare module spine {
class Bone implements Updatable {
data: BoneData;
skeleton: Skeleton;
parent: Bone | null;
children: Bone[];
x: number;
y: number;
rotation: number;
scaleX: number;
scaleY: number;
shearX: number;
shearY: number;
ax: number;
ay: number;
arotation: number;
ascaleX: number;
ascaleY: number;
ashearX: number;
ashearY: number;
a: number;
b: number;
c: number;
d: number;
worldY: number;
worldX: number;
inherit: Inherit;
sorted: boolean;
active: boolean;
constructor(data: BoneData, skeleton: Skeleton, parent: Bone | null);
isActive(): boolean;
update(physics: Physics): void;
updateWorldTransform(): void;
updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
setToSetupPose(): void;
updateAppliedTransform(): void;
getWorldRotationX(): number;
getWorldRotationY(): number;
getWorldScaleX(): number;
getWorldScaleY(): number;
worldToLocal(world: Vector2): Vector2;
localToWorld(local: Vector2): Vector2;
worldToParent(world: Vector2): Vector2;
parentToWorld(world: Vector2): Vector2;
worldToLocalRotation(worldRotation: number): number;
localToWorldRotation(localRotation: number): number;
rotateWorld(degrees: number): void;
}
}
declare module spine {
class BoneData {
index: number;
name: string;
parent: BoneData | null;
length: number;
x: number;
y: number;
rotation: number;
scaleX: number;
scaleY: number;
shearX: number;
shearY: number;
inherit: Inherit;
skinRequired: boolean;
color: Color;
icon?: string;
visible: boolean;
constructor(index: number, name: string, parent: BoneData | null);
}
enum Inherit {
Normal = 0,
OnlyTranslation = 1,
NoRotationOrReflection = 2,
NoScale = 3,
NoScaleOrReflection = 4
}
}
declare module spine {
abstract class ConstraintData {
name: string;
order: number;
skinRequired: boolean;
constructor(name: string, order: number, skinRequired: boolean);
}
}
declare module spine {
class Event {
data: EventData;
intValue: number;
floatValue: number;
stringValue: string | null;
time: number;
volume: number;
balance: number;
constructor(time: number, data: EventData);
}
}
declare module spine {
class EventData {
name: string;
intValue: number;
floatValue: number;
stringValue: string | null;
audioPath: string | null;
volume: number;
balance: number;
constructor(name: string);
}
}
declare module spine {
class IkConstraint implements Updatable {
data: IkConstraintData;
bones: Array<Bone>;
target: Bone;
bendDirection: number;
compress: boolean;
stretch: boolean;
mix: number;
softness: number;
active: boolean;
constructor(data: IkConstraintData, skeleton: Skeleton);
isActive(): boolean;
setToSetupPose(): void;
update(physics: Physics): void;
apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, uniform: boolean, softness: number, alpha: number): void;
}
}
declare module spine {
class IkConstraintData extends ConstraintData {
bones: BoneData[];
private _target;
set target(boneData: BoneData);
get target(): BoneData;
bendDirection: number;
compress: boolean;
stretch: boolean;
uniform: boolean;
mix: number;
softness: number;
constructor(name: string);
}
}
declare module spine {
class PathConstraint implements Updatable {
static NONE: number;
static BEFORE: number;
static AFTER: number;
static epsilon: number;
data: PathConstraintData;
bones: Array<Bone>;
target: Slot;
position: number;
spacing: number;
mixRotate: number;
mixX: number;
mixY: number;
spaces: number[];
positions: number[];
world: number[];
curves: number[];
lengths: number[];
segments: number[];
active: boolean;
constructor(data: PathConstraintData, skeleton: Skeleton);
isActive(): boolean;
setToSetupPose(): void;
update(physics: Physics): void;
computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean): number[];
addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
addCurvePosition(p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, out: Array<number>, o: number, tangents: boolean): void;
}
}
declare module spine {
class PathConstraintData extends ConstraintData {
bones: BoneData[];
private _target;
set target(slotData: SlotData);
get target(): SlotData;
positionMode: PositionMode;
spacingMode: SpacingMode;
rotateMode: RotateMode;
offsetRotation: number;
position: number;
spacing: number;
mixRotate: number;
mixX: number;
mixY: number;
constructor(name: string);
}
enum PositionMode {
Fixed = 0,
Percent = 1
}
enum SpacingMode {
Length = 0,
Fixed = 1,
Percent = 2,
Proportional = 3
}
enum RotateMode {
Tangent = 0,
Chain = 1,
ChainScale = 2
}
}
declare module spine {
class PhysicsConstraint implements Updatable {
readonly data: PhysicsConstraintData;
private _bone;
set bone(bone: Bone);
get bone(): Bone;
inertia: number;
strength: number;
damping: number;
massInverse: number;
wind: number;
gravity: number;
mix: number;
_reset: boolean;
ux: number;
uy: number;
cx: number;
cy: number;
tx: number;
ty: number;
xOffset: number;
xVelocity: number;
yOffset: number;
yVelocity: number;
rotateOffset: number;
rotateVelocity: number;
scaleOffset: number;
scaleVelocity: number;
active: boolean;
readonly skeleton: Skeleton;
remaining: number;
lastTime: number;
constructor(data: PhysicsConstraintData, skeleton: Skeleton);
reset(): void;
setToSetupPose(): void;
isActive(): boolean;
update(physics: Physics): void;
translate(x: number, y: number): void;
rotate(x: number, y: number, degrees: number): void;
}
}
declare module spine {
class PhysicsConstraintData extends ConstraintData {
private _bone;
set bone(boneData: BoneData);
get bone(): BoneData;
x: number;
y: number;
rotate: number;
scaleX: number;
shearX: number;
limit: number;
step: number;
inertia: number;
strength: number;
damping: number;
massInverse: number;
wind: number;
gravity: number;
mix: number;
inertiaGlobal: boolean;
strengthGlobal: boolean;
dampingGlobal: boolean;
massGlobal: boolean;
windGlobal: boolean;
gravityGlobal: boolean;
mixGlobal: boolean;
constructor(name: string);
}
}
declare module spine {
class Skeleton {
private static quadTriangles;
static yDown: boolean;
data: SkeletonData;
bones: Array<Bone>;
slots: Array<Slot>;
drawOrder: Array<Slot>;
ikConstraints: Array<IkConstraint>;
transformConstraints: Array<TransformConstraint>;
pathConstraints: Array<PathConstraint>;
physicsConstraints: Array<PhysicsConstraint>;
_updateCache: Updatable[];
skin: Skin | null;
color: Color;
scaleX: number;
private _scaleY;
get scaleY(): number;
set scaleY(scaleY: number);
x: number;
y: number;
time: number;
constructor(data: SkeletonData);
updateCache(): void;
sortIkConstraint(constraint: IkConstraint): void;
sortPathConstraint(constraint: PathConstraint): void;
sortTransformConstraint(constraint: TransformConstraint): void;
sortPathConstraintAttachment(skin: Skin, slotIndex: number, slotBone: Bone): void;
sortPathConstraintAttachmentWith(attachment: Attachment, slotBone: Bone): void;
sortPhysicsConstraint(constraint: PhysicsConstraint): void;
sortBone(bone: Bone): void;
sortReset(bones: Array<Bone>): void;
updateWorldTransform(physics: Physics): void;
updateWorldTransformWith(physics: Physics, parent: Bone): void;
setToSetupPose(): void;
setBonesToSetupPose(): void;
setSlotsToSetupPose(): void;
getRootBone(): Bone;
findBone(boneName: string): Bone;
findSlot(slotName: string): Slot;
setSkinByName(skinName: string): void;
setSkin(newSkin: Skin): void;
getAttachmentByName(slotName: string, attachmentName: string): Attachment | null;
getAttachment(slotIndex: number, attachmentName: string): Attachment | null;
setAttachment(slotName: string, attachmentName: string): void;
findIkConstraint(constraintName: string): IkConstraint;
findTransformConstraint(constraintName: string): TransformConstraint;
findPathConstraint(constraintName: string): PathConstraint;
findPhysicsConstraint(constraintName: string): PhysicsConstraint;
getBoundsRect(): {
x: number;
y: number;
width: number;
height: number;
};
getBounds(offset: Vector2, size: Vector2, temp?: Array<number>, clipper?: SkeletonClipping | null): void;
update(delta: number): void;
physicsTranslate(x: number, y: number): void;
physicsRotate(x: number, y: number, degrees: number): void;
}
enum Physics {
none = 0,
reset = 1,
update = 2,
pose = 3
}
}
declare module spine {
class SkeletonBinary {
scale: number;
attachmentLoader: AttachmentLoader;
private linkedMeshes;
constructor(attachmentLoader: AttachmentLoader);
readSkeletonData(binary: Uint8Array | ArrayBuffer): SkeletonData;
private readSkin;
private readAttachment;
private readSequence;
private readVertices;
private readFloatArray;
private readShortArray;
private readAnimation;
}
class BinaryInput {
strings: string[];
private index;
private buffer;
constructor(data: Uint8Array | ArrayBuffer, strings?: string[], index?: number, buffer?: DataView);
readByte(): number;
readUnsignedByte(): number;
readShort(): number;
readInt32(): number;
readInt(optimizePositive: boolean): number;
readStringRef(): string | null;
readString(): string | null;
readFloat(): number;
readBoolean(): boolean;
}
}
declare module spine {
class SkeletonBounds {
minX: number;
minY: number;
maxX: number;
maxY: number;
boundingBoxes: BoundingBoxAttachment[];
polygons: (number[] | Float32Array)[];
private polygonPool;
update(skeleton: Skeleton, updateAabb: boolean): void;
aabbCompute(): void;
aabbContainsPoint(x: number, y: number): boolean;
aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number): boolean;
aabbIntersectsSkeleton(bounds: SkeletonBounds): boolean;
containsPoint(x: number, y: number): BoundingBoxAttachment | null;
containsPointPolygon(polygon: NumberArrayLike, x: number, y: number): boolean;
intersectsSegment(x1: number, y1: number, x2: number, y2: number): BoundingBoxAttachment;
intersectsSegmentPolygon(polygon: NumberArrayLike, x1: number, y1: number, x2: number, y2: number): boolean;
getPolygon(boundingBox: BoundingBoxAttachment): number[] | Float32Array;
getWidth(): number;
getHeight(): number;
}
}
declare module spine {
class SkeletonClipping {
private triangulator;
private clippingPolygon;
private clipOutput;
clippedVertices: number[];
clippedUVs: number[];
clippedTriangles: number[];
private scratch;
private clipAttachment;
private clippingPolygons;
clipStart(slot: Slot, clip: ClippingAttachment): number;
clipEndWithSlot(slot: Slot): void;
clipEnd(): void;
isClipping(): boolean;
clipTriangles(vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number): void;
clipTriangles(vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean): void;
clipTriangles(vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number): void;
clipTriangles(vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean): void;
private clipTrianglesNoRender;
private clipTrianglesRender;
clipTrianglesUnpacked(vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike): void;
clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
static makeClockwise(polygon: NumberArrayLike): void;
}
}
declare module spine {
class SkeletonData {
name: string | null;
bones: BoneData[];
slots: SlotData[];
skins: Skin[];
defaultSkin: Skin | null;
events: EventData[];
animations: Animation[];
ikConstraints: IkConstraintData[];
transformConstraints: TransformConstraintData[];
pathConstraints: PathConstraintData[];
physicsConstraints: PhysicsConstraintData[];
x: number;
y: number;
width: number;
height: number;
referenceScale: number;
version: string | null;
hash: string | null;
fps: number;
imagesPath: string | null;
audioPath: string | null;
findBone(boneName: string): BoneData;
findSlot(slotName: string): SlotData;
findSkin(skinName: string): Skin;
findEvent(eventDataName: string): EventData;
findAnimation(animationName: string): Animation;
findIkConstraint(constraintName: string): IkConstraintData;
findTransformConstraint(constraintName: string): TransformConstraintData;
findPathConstraint(constraintName: string): PathConstraintData;
findPhysicsConstraint(constraintName: string): PhysicsConstraintData;
}
}
declare module spine {
class SkeletonJson {
attachmentLoader: AttachmentLoader;
scale: number;
private linkedMeshes;
constructor(attachmentLoader: AttachmentLoader);
readSkeletonData(json: string | any): SkeletonData;
readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment | null;
readSequence(map: any): Sequence;
readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
}
}
declare module spine {
class SkinEntry {
slotIndex: number;
name: string;
attachment: Attachment;
constructor(slotIndex: number, name: string, attachment: Attachment);
}
class Skin {
name: string;
attachments: StringMap<Attachment>[];
bones: BoneData[];
constraints: ConstraintData[];
color: Color;
constructor(name: string);
setAttachment(slotIndex: number, name: string, attachment: Attachment): void;
addSkin(skin: Skin): void;
copySkin(skin: Skin): void;
getAttachment(slotIndex: number, name: string): Attachment | null;
removeAttachment(slotIndex: number, name: string): void;
getAttachments(): Array<SkinEntry>;
getAttachmentsForSlot(slotIndex: number, attachments: Array<SkinEntry>): void;
clear(): void;
attachAll(skeleton: Skeleton, oldSkin: Skin): void;
}
}
declare module spine {
class Slot {
data: SlotData;
bone: Bone;
color: Color;
darkColor: Color | null;
attachment: Attachment | null;
attachmentState: number;
sequenceIndex: number;
deform: number[];
constructor(data: SlotData, bone: Bone);
getSkeleton(): Skeleton;
getAttachment(): Attachment | null;
setAttachment(attachment: Attachment | null): void;
setToSetupPose(): void;
}
}
declare module spine {
class SlotData {
index: number;
name: string;
boneData: BoneData;
color: Color;
darkColor: Color | null;
attachmentName: string | null;
blendMode: BlendMode;
visible: boolean;
constructor(index: number, name: string, boneData: BoneData);
}
enum BlendMode {
Normal = 0,
Additive = 1,
Multiply = 2,
Screen = 3
}
}
declare module spine {
abstract class Texture {
protected _image: HTMLImageElement | ImageBitmap | any;
constructor(image: HTMLImageElement | ImageBitmap | any);
getImage(): HTMLImageElement | ImageBitmap | any;
abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
abstract dispose(): void;
}
enum TextureFilter {
Nearest = 9728,
Linear = 9729,
MipMap = 9987,
MipMapNearestNearest = 9984,
MipMapLinearNearest = 9985,
MipMapNearestLinear = 9986,
MipMapLinearLinear = 9987
}
enum TextureWrap {
MirroredRepeat = 33648,
ClampToEdge = 33071,
Repeat = 10497
}
class TextureRegion {
texture: any;
u: number;
v: number;
u2: number;
v2: number;
width: number;
height: number;
degrees: number;
offsetX: number;
offsetY: number;
originalWidth: number;
originalHeight: number;
}
class FakeTexture extends Texture {
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
dispose(): void;
}
}
declare module spine {
class TextureAtlas implements Disposable {
pages: TextureAtlasPage[];
regions: TextureAtlasRegion[];
constructor(atlasText: string);
findRegion(name: string): TextureAtlasRegion | null;
setTextures(assetManager: AssetManagerBase, pathPrefix?: string): void;
dispose(): void;
}
class TextureAtlasPage {
name: string;
minFilter: TextureFilter;
magFilter: TextureFilter;
uWrap: TextureWrap;
vWrap: TextureWrap;
texture: Texture | null;
width: number;
height: number;
pma: boolean;
regions: TextureAtlasRegion[];
constructor(name: string);
setTexture(texture: Texture): void;
}
class TextureAtlasRegion extends TextureRegion {
page: TextureAtlasPage;
name: string;
x: number;
y: number;
offsetX: number;
offsetY: number;
originalWidth: number;
originalHeight: number;
index: number;
degrees: number;
names: string[] | null;
values: number[][] | null;
constructor(page: TextureAtlasPage, name: string);
}
}
declare module spine {
class TransformConstraint implements Updatable {
data: TransformConstraintData;
bones: Array<Bone>;
target: Bone;
mixRotate: number;
mixX: number;
mixY: number;
mixScaleX: number;
mixScaleY: number;
mixShearY: number;
temp: Vector2;
active: boolean;
constructor(data: TransformConstraintData, skeleton: Skeleton);
isActive(): boolean;
setToSetupPose(): void;
update(physics: Physics): void;
applyAbsoluteWorld(): void;
applyRelativeWorld(): void;
applyAbsoluteLocal(): void;
applyRelativeLocal(): void;
}
}
declare module spine {
class TransformConstraintData extends ConstraintData {
bones: BoneData[];
private _target;
set target(boneData: BoneData);
get target(): BoneData;
mixRotate: number;
mixX: number;
mixY: number;
mixScaleX: number;
mixScaleY: number;
mixShearY: number;
offsetRotation: number;
offsetX: number;
offsetY: number;
offsetScaleX: number;
offsetScaleY: number;
offsetShearY: number;
relative: boolean;
local: boolean;
constructor(name: string);
}
}
declare module spine {
class Triangulator {
private convexPolygons;
private convexPolygonsIndices;
private indicesArray;
private isConcaveArray;
private triangles;
private polygonPool;
private polygonIndicesPool;
triangulate(verticesArray: NumberArrayLike): Array<number>;
decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
private static isConcave;
private static positiveArea;
private static winding;
}
}
declare module spine {
interface Updatable {
update(physics: Physics): void;
isActive(): boolean;
}
}
{
"version": "3.4.0-beta.3"
}
\ No newline at end of file
{
"name": "minigame",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@msgpack/msgpack": "^3.1.3",
"socket.io-client": "^4.8.3"
}
},
"node_modules/@msgpack/msgpack": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.1.3.tgz",
"integrity": "sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==",
"license": "ISC",
"engines": {
"node": ">= 18"
}
},
"node_modules/@socket.io/component-emitter": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"license": "MIT"
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/engine.io-client": {
"version": "6.6.5",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.5.tgz",
"integrity": "sha512-QCwxUDULPlXv8F6tqMMKx5dNkTe6OaBYRMPYeXKBlyOoKvAmE0ac6pW7fFhSscJ/5SI7666/U/B+MElbsrJlIg==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.4.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.20.1",
"xmlhttprequest-ssl": "~2.1.1"
}
},
"node_modules/engine.io-parser": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/socket.io-client": {
"version": "4.8.3",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz",
"integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.4.1",
"engine.io-client": "~6.6.1",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz",
"integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.4.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/ws": {
"version": "8.20.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz",
"integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
"engines": {
"node": ">=0.4.0"
}
}
}
}
{
"dependencies": {
"@msgpack/msgpack": "^3.1.3",
"socket.io-client": "^4.8.3"
}
}
{
"name": "minigame",
"startupScene": "res://3569976b-b864-43be-8207-f89dbd93ffc0",
"includedScenes": [
"res://ced3e0b8-68a0-4b07-a953-4b4ac20d14c2",
"res://ddc30f5e-6160-46eb-a29d-c487be4745f9",
"res://1e5519db-0700-4e4f-8f40-1f159e66cb37",
"res://c17b6f7e-6d2c-4b16-9a0b-1898d3c55aba",
"res://59599a02-b115-4cf8-b85f-5fab814a508b",
"res://3569976b-b864-43be-8207-f89dbd93ffc0"
],
"web": {
"keepTextureSourceFile": true,
"compressWasm": true,
"useSafeFileExtensions": true
},
"android": {
"targetArchitectures": {
"ARMv7": false,
"ARM64": true,
"x86": false,
"x86-64": false
},
"exportFormat": "APK"
}
}
\ No newline at end of file
{
"entries": [
"res://7bad1742-6eed-4d8d-81c0-501dc5bf03d6"
],
"mainScript": ""
}
\ No newline at end of file
{
"textureType": 2,
"layers": [
"Default",
"Layer1",
"Layer2",
"Layer3",
"Layer4",
"Layer5",
"Layer6"
]
}
\ No newline at end of file
{
"resolution": {
"designWidth": 750,
"designHeight": 1334,
"backgroundColor": "#ffffff"
},
"2D": {
"useRetinalCanvas": true
},
"modules": {
"laya.ui": true
},
"addons": {
"laya.ui": "ui2"
},
"splash": {
"enabled": false,
"fit": "center"
}
}
\ No newline at end of file
import { SocketIOClientOptions } from "./WS";
export const socketIOOptionsConfig: SocketIOClientOptions = {
url: "http://localhost:8082/ws",
path: "/socket.io",
auth: {
userid: "test123"
}
};
{
"uuid": "637bd740-83f7-44b7-bdcd-0b2ff7287ab8"
}
\ No newline at end of file
const { regClass } = Laya;
type SceneKey = "1" | "2" | "3" | "4" | "5" | "6";
const SceneMap: Record<SceneKey, string> = {
"1": "scenes/Scene1.ls",
"2": "scenes/Scene2.ls",
"3": "scenes/Scene3.ls",
"4": "scenes/Scene4.ls",
"5": "scenes/Scene5.ls",
"6": "scenes/Scene6.ls"
};
function getStartupSceneKey(): SceneKey {
const globalObj = window as any;
const defaultScene: SceneKey = "1";
const scene = globalObj.__gameScene || globalObj.gameScene || getWxScene() || getUrlScene() || defaultScene;
if (scene in SceneMap) {
return scene as SceneKey;
}
return defaultScene;
}
function getWxScene(): string {
const wx = (window as any).wx;
if (!wx?.getLaunchOptionsSync) {
return "";
}
const options = wx.getLaunchOptionsSync();
return options?.query?.scene || options?.query?.game || "";
}
function getUrlScene(): string {
if (!window.location?.search) {
return "";
}
return new URLSearchParams(window.location.search).get("scene") || "";
}
(window as any).$_main_ = () => {
const sceneKey = getStartupSceneKey();
const sceneUrl = SceneMap[sceneKey];
console.log(`Open scene ${sceneKey}: ${sceneUrl}`);
return Laya.Scene.open(sceneUrl, true);
};
// @regClass()
// export class Main extends Laya.Script {
// onStart(): void {
// console.log("Game start");
// }
// }
{
"uuid": "7bad1742-6eed-4d8d-81c0-501dc5bf03d6"
}
\ No newline at end of file
import { io } from "socket.io-client";
import { decode, encode } from "@msgpack/msgpack";
export type SocketIOMessage = string | number | boolean | object | ArrayBuffer | ArrayBufferView | null;
type SocketIOTransport = "websocket" | "polling";
export type SocketIOSocket = {
connected: boolean;
disconnected: boolean;
id?: string;
io?: {
on(eventName: string, callback: (...args: any[]) => void): any;
off(eventName: string, callback?: (...args: any[]) => void): any;
};
connect(): SocketIOSocket;
disconnect(): SocketIOSocket;
emit(eventName: string, ...args: any[]): SocketIOSocket;
on(eventName: string, callback: (...args: any[]) => void): SocketIOSocket;
off(eventName: string, callback?: (...args: any[]) => void): SocketIOSocket;
onAny(callback: (eventName: string, ...args: any[]) => void): SocketIOSocket;
offAny(callback?: (eventName: string, ...args: any[]) => void): SocketIOSocket;
};
export type SocketIOClientOptions = {
url: string;
path?: string;
auth?: Record<string, any> | (() => Record<string, any>);
};
export type SocketIOConnectHandler = (socket: SocketIOSocket) => void;
export type SocketIOMessageHandler = (eventName: string, data: any) => void;
export type SocketIODisconnectHandler = (reason: string, details?: any) => void;
export type SocketIOErrorHandler = (error: any) => void;
export type SocketIOReconnectAttemptHandler = (attempt: number) => void;
type ResolvedSocketIOClientOptions = SocketIOClientOptions;
const SOCKET_EVENT_NAME = "message";
const SOCKET_TRANSPORTS: SocketIOTransport[] = ["websocket"];
const RECONNECT = true;
const RECONNECT_ATTEMPTS = Infinity;
const RECONNECT_DELAY = 1000;
const AUTO_CONNECT = false;
const USE_MESSAGE_PACK = true;
export class SocketIOClient {
private socket: SocketIOSocket | null = null;
private options: ResolvedSocketIOClientOptions;
private connectHandler: SocketIOConnectHandler | null = null;
private messageHandler: SocketIOMessageHandler | null = null;
private disconnectHandler: SocketIODisconnectHandler | null = null;
private errorHandler: SocketIOErrorHandler | null = null;
private reconnectAttemptHandler: SocketIOReconnectAttemptHandler | null = null;
constructor(options: SocketIOClientOptions) {
this.options = this.resolveOptions(options);
}
get isConnected(): boolean {
return this.socket?.connected ?? false;
}
get id(): string {
return this.socket?.id || "";
}
connect(): void {
if (this.socket && !this.socket.disconnected) {
return;
}
this.destroySocket();
const socket = io(this.options.url, this.createNativeOptions());
this.socket = socket;
this.bindEvents(socket);
if (AUTO_CONNECT === false) {
socket.connect();
}
}
disconnect(): void {
this.destroySocket();
}
emit(eventName: string, ...args: any[]): boolean {
if (!this.socket?.connected) {
return false;
}
this.socket.emit(eventName, ...args);
return true;
}
send(message: SocketIOMessage): boolean {
return this.emit(SOCKET_EVENT_NAME, this.encodeMessage(message));
}
onConnect(handler: SocketIOConnectHandler): this {
this.connectHandler = handler;
return this;
}
onMessage(handler: SocketIOMessageHandler): this {
this.messageHandler = handler;
return this;
}
onDisconnect(handler: SocketIODisconnectHandler): this {
this.disconnectHandler = handler;
return this;
}
onError(handler: SocketIOErrorHandler): this {
this.errorHandler = handler;
return this;
}
onReconnectAttempt(handler: SocketIOReconnectAttemptHandler): this {
this.reconnectAttemptHandler = handler;
return this;
}
updateOptions(options: Partial<SocketIOClientOptions>): void {
this.options = this.resolveOptions({
...this.options,
...this.removeUndefined(options)
});
}
private bindEvents(socket: SocketIOSocket): void {
socket.on("connect", this.handleConnect);
socket.onAny(this.handleAnyMessage);
socket.on("disconnect", this.handleDisconnect);
socket.on("connect_error", this.handleError);
socket.on("error", this.handleError);
socket.io?.on("reconnect_attempt", this.handleReconnectAttempt);
}
private unbindEvents(socket: SocketIOSocket): void {
socket.off("connect", this.handleConnect);
socket.offAny(this.handleAnyMessage);
socket.off("disconnect", this.handleDisconnect);
socket.off("connect_error", this.handleError);
socket.off("error", this.handleError);
socket.io?.off("reconnect_attempt", this.handleReconnectAttempt);
}
private destroySocket(): void {
if (!this.socket) {
return;
}
this.unbindEvents(this.socket);
this.socket.disconnect();
this.socket = null;
}
private handleConnect = (): void => {
if (this.socket) {
this.connectHandler?.(this.socket);
}
};
private handleAnyMessage = (eventName: string, ...args: any[]): void => {
const data = this.parseMessage(args[0]);
this.messageHandler?.(eventName, data);
};
private handleDisconnect = (reason: string, details?: any): void => {
this.disconnectHandler?.(reason, details);
};
private handleError = (error: any): void => {
this.errorHandler?.(error);
};
private handleReconnectAttempt = (attempt: number): void => {
this.reconnectAttemptHandler?.(attempt);
};
private createNativeOptions(): Record<string, any> {
const options: Record<string, any> = {
reconnection: RECONNECT,
reconnectionAttempts: RECONNECT_ATTEMPTS,
reconnectionDelay: RECONNECT_DELAY,
autoConnect: AUTO_CONNECT,
path: this.options.path,
auth: this.options.auth,
transports: SOCKET_TRANSPORTS
};
Object.keys(options).forEach((key) => {
if (options[key] === undefined) {
delete options[key];
}
});
return options;
}
private resolveOptions(options: SocketIOClientOptions): ResolvedSocketIOClientOptions {
return options;
}
private removeUndefined<T extends Record<string, any>>(options: T): Partial<T> {
const result: Partial<T> = {};
Object.keys(options).forEach((key) => {
const value = options[key];
if (value !== undefined) {
result[key as keyof T] = value;
}
});
return result;
}
private parseMessage(data: any): any {
if (!USE_MESSAGE_PACK) {
return data;
}
try {
return decode(this.toMessagePackBuffer(data));
} catch {
return data;
}
}
private encodeMessage(message: SocketIOMessage): any {
if (!USE_MESSAGE_PACK) {
return message;
}
return encode(message);
}
private toMessagePackBuffer(data: any): ArrayBuffer | ArrayBufferView {
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
return data;
}
if (data?.buffer instanceof ArrayBuffer) {
return data;
}
throw new Error("MessagePack payload must be ArrayBuffer or typed array.");
}
}
{
"uuid": "4cb81d8f-dcbc-496b-8fdf-1eb9d0573212"
}
\ No newline at end of file
{
"compilerOptions": {
"module": "es6",
"target": "es6",
"strict": true,
"strictNullChecks": false,
"noEmitHelpers": true,
"sourceMap": false,
"experimentalDecorators": true,
"skipLibCheck": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"paths": {
"~/packages/*": [
"./library/packages/*"
]
}
},
"include": [
"./assets",
"./src",
"./engine"
]
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment