Initial commit

This commit is contained in:
2026-05-10 10:45:02 +08:00
commit e62384a9c5
1053 changed files with 19615 additions and 0 deletions

53
app/build.gradle.kts Normal file
View File

@@ -0,0 +1,53 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "blog.wiwi.hoops"
compileSdk = 34
defaultConfig {
applicationId = "blog.wiwi.hoops"
minSdk = 24 // Android 7.0+ 才有體面的 WebView 跟 Pointer Events
targetSdk = 34
versionCode = 1
versionName = "1.0.0"
}
buildTypes {
release {
isMinifyEnabled = false
// 不用 proguard這個 app 程式碼太少,混淆只會徒增 F-Droid 審核難度
signingConfig = signingConfigs.getByName("debug") // 自己 sign 時請改
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
// 排除一些不必要的東西,把 APK 壓到最小
packaging {
resources {
excludes += setOf(
"META-INF/*.kotlin_module",
"META-INF/AL2.0",
"META-INF/LGPL2.1",
"kotlin-tooling-metadata.json"
)
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.activity:activity:1.9.0")
// Splash Screen APIAndroid 12+ 是系統 splash舊版會被 backport
implementation("androidx.core:core-splashscreen:1.0.1")
}

View File

@@ -0,0 +1,21 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "blog.wiwi.hoops",
"variantName": "debug",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0.0",
"outputFile": "app-debug.apk"
}
],
"elementType": "File",
"minSdkVersionForDexing": 24
}

View File

@@ -0,0 +1,2 @@
#- File Locator -
listingFile=../../../../outputs/apk/debug/output-metadata.json

View File

@@ -0,0 +1,2 @@
#- File Locator -
listingFile=../../../../outputs/apk/androidTest/debug/output-metadata.json

View File

@@ -0,0 +1,2 @@
#- File Locator -
listingFile=../../../../../release/output-metadata.json

View File

@@ -0,0 +1,2 @@
appMetadataVersion=1.1
androidGradlePluginVersion=8.13.2

View File

@@ -0,0 +1,2 @@
appMetadataVersion=1.1
androidGradlePluginVersion=8.13.2

View File

@@ -0,0 +1,881 @@
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>Hoops</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
width: 100%; height: 100%;
background: #fafaf7;
overflow: hidden;
overscroll-behavior: none;
user-select: none; -webkit-user-select: none;
touch-action: none;
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}
#stage {
position: fixed; inset: 0;
display: flex; align-items: center; justify-content: center;
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
#wrap {
position: relative;
/* 取畫面上能擺進的最大正方形 */
width: min(100vw, 100vh);
height: min(100vw, 100vh);
}
canvas {
display: block;
width: 100%; height: 100%;
background: #fafaf7;
touch-action: none;
}
.hint {
position: absolute;
left: 50%; bottom: 8px;
transform: translateX(-50%);
font-size: 5px;
letter-spacing: 0.01em;
opacity: 0.45;
color: #555;
white-space: nowrap;
pointer-events: none;
}
</style>
</head>
<body>
<div id="stage">
<div id="wrap">
<canvas id="game"></canvas>
<div class="hint">by Wiwi Kuan, https://wiwi.blog</div>
</div>
</div>
<script>
// =============================================================================
// CONFIG — 跟原本完全一樣
// =============================================================================
const DEFAULT_CONFIG = {
GAME_DURATION: 60,
COOLDOWN: 0.5,
JUMP_DURATION: 0.5,
JUMP_HEIGHT_RATIO: 0.25,
PERFECT_WINDOW_T: 0.28,
PERFECT_TOLERANCE: 0.001,
MAX_DRIFT_T: 0.35,
GRAVITY_RATIO: 5,
BALL_RADIUS_RATIO: 0.03,
RESTITUTION_RIM: 0.65,
RESTITUTION_BOARD: 0.7,
RESTITUTION_BALL: 0.7,
AIR_DRAG: 0,
SHOT_TARGET_TIME: 0.75,
SHOT_DRIFT_VEL: 0.4,
SHOT_DRIFT_ANGLE: 0.6,
BALL_IMG_SRC: null,
PERFECT_JITTER_VEL: 0.0025,
PERFECT_JITTER_ANGLE: 0.003,
EULER_COMPENSATION: 0.012,
};
const COLORS = {
ink: '#1a1a1a',
paper: '#fafaf7',
ball: '#c2410c',
rim: '#991b1b',
net: '#999',
gray: '#ccc',
};
const PHASE = { TITLE: 'title', PLAYING: 'playing', OVER: 'over' };
const MODE = { TIMED: 'timed', PRACTICE: 'practice' };
// =============================================================================
// 遊戲主體 — 接收 canvas + config,回傳 cleanup function
// 注意:原本是用 parent.clientWidth 取尺寸,這裡改成 wrap 元素的尺寸(其實一樣)
// 並且讓畫布是「正方形 = min(視窗寬, 視窗高)」,跟原本邏輯一致
// =============================================================================
function initGame(canvas, userConfig) {
const CONFIG = Object.assign({}, DEFAULT_CONFIG, userConfig || {});
const ctx = canvas.getContext('2d');
let W = 0, H = 0, DPR = 1;
function resize() {
const parent = canvas.parentElement;
const parentW = parent ? parent.clientWidth : 600;
const parentH = parent ? parent.clientHeight : 600;
// 取較小邊作為正方形邊長
const px = Math.max(280, Math.floor(Math.min(parentW, parentH)));
DPR = Math.max(1, Math.min(2, window.devicePixelRatio || 1));
canvas.style.width = px + 'px';
canvas.style.height = px + 'px';
canvas.width = Math.floor(px * DPR);
canvas.height = Math.floor(px * DPR);
ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
W = px; H = px;
}
resize();
let ballImg = null;
if (CONFIG.BALL_IMG_SRC) {
const img = new Image();
img.onload = () => { ballImg = img; };
img.src = CONFIG.BALL_IMG_SRC;
}
// ===== Audio =====
let actx = null;
function audio() {
if (!actx) {
try { actx = new (window.AudioContext || window.webkitAudioContext)(); }
catch (e) { actx = null; }
}
return actx;
}
function blip({ freq = 440, dur = 0.08, type = 'sine', vol = 0.15, sweep = 0, delay = 0 } = {}) {
const a = audio(); if (!a) return;
const t0 = a.currentTime + delay;
const o = a.createOscillator();
const g = a.createGain();
o.type = type;
o.frequency.setValueAtTime(freq, t0);
if (sweep) o.frequency.exponentialRampToValueAtTime(Math.max(40, freq + sweep), t0 + dur);
g.gain.setValueAtTime(0.0001, t0);
g.gain.exponentialRampToValueAtTime(vol, t0 + 0.005);
g.gain.exponentialRampToValueAtTime(0.0001, t0 + dur);
o.connect(g).connect(a.destination);
o.start(t0); o.stop(t0 + dur + 0.02);
}
const SFX = {
jump: () => blip({ freq: 220, dur: 0.06, type: 'triangle', vol: 0.08, sweep: 60 }),
shoot: () => blip({ freq: 380, dur: 0.09, type: 'square', vol: 0.07, sweep: 200 }),
rim: () => blip({ freq: 900, dur: 0.05, type: 'square', vol: 0.06, sweep: -300 }),
board: () => blip({ freq: 140, dur: 0.07, type: 'sine', vol: 0.12, sweep: -40 }),
swish: () => {
blip({ freq: 660, dur: 0.08, type: 'sine', vol: 0.10 });
blip({ freq: 990, dur: 0.10, type: 'sine', vol: 0.08, delay: 0.04 });
blip({ freq: 1320, dur: 0.12, type: 'sine', vol: 0.06, delay: 0.09 });
},
score: () => {
blip({ freq: 523, dur: 0.10, type: 'triangle', vol: 0.10 });
blip({ freq: 784, dur: 0.14, type: 'triangle', vol: 0.10, delay: 0.08 });
},
end: () => {
blip({ freq: 220, dur: 0.18, type: 'sawtooth', vol: 0.08 });
blip({ freq: 165, dur: 0.22, type: 'sawtooth', vol: 0.08, delay: 0.12 });
},
};
function geom() {
const hoopX = W * 0.78;
const hoopW = W * 0.085;
const rimR = W * 0.008;
const armLength = W * 0.018;
return {
ballR: W * CONFIG.BALL_RADIUS_RATIO,
ballX: W * 0.18,
groundY: H * 0.72,
hoopX, hoopY: H * 0.42, hoopW, rimR, armLength,
boardX: hoopX + hoopW / 2 + rimR + armLength,
boardTop: H * 0.42 - H * 0.18,
boardBot: H * 0.42 + H * 0.04,
netDepth: H * 0.06,
};
}
const state = {
phase: PHASE.TITLE,
mode: MODE.TIMED,
timeLeft: CONFIG.GAME_DURATION,
score: 0,
attempts: 0,
lastScoreFlash: 0,
holding: false,
holdT: 0,
holdStartTime: 0,
jumpDone: false,
cooldown: 0,
ready: true,
balls: [],
netPhase: 0,
netImpulse: 0,
nextBallId: 1,
};
// 給想作弊的讀者
if (typeof window !== 'undefined') window.__hoops = { state, CONFIG };
let titleButtons = null;
let exitButton = null;
function startGame(mode) {
state.phase = PHASE.PLAYING;
state.mode = mode;
state.timeLeft = CONFIG.GAME_DURATION;
state.score = 0;
state.attempts = 0;
state.lastScoreFlash = 0;
state.holding = false;
state.holdT = 0;
state.holdStartTime = 0;
state.jumpDone = false;
state.cooldown = 0;
state.ready = true;
state.balls = [];
state.netImpulse = 0;
}
function backToTitle() {
state.phase = PHASE.TITLE;
state.holding = false;
state.jumpDone = false;
state.balls = [];
}
function pressDown(pointerPos) {
audio();
if (state.phase === PHASE.OVER) {
backToTitle();
return;
}
if (state.phase === PHASE.TITLE) {
if (pointerPos && titleButtons) {
const { x, y } = pointerPos;
const inBtn = (b) => x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h;
if (inBtn(titleButtons.timed)) { startGame(MODE.TIMED); return; }
if (inBtn(titleButtons.practice)) { startGame(MODE.PRACTICE); return; }
}
return;
}
if (state.mode === MODE.PRACTICE && pointerPos && exitButton) {
const { x, y } = pointerPos;
const b = exitButton;
if (x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h) {
backToTitle();
return;
}
}
if (!state.ready || state.holding) return;
state.holding = true;
state.holdT = 0;
state.holdStartTime = performance.now();
state.jumpDone = false;
SFX.jump();
}
function pressUp() {
if (!state.holding) return;
state.holding = false;
if (state.jumpDone) return;
const realHoldT = (performance.now() - state.holdStartTime) / 1000;
releaseShot(Math.min(realHoldT, CONFIG.JUMP_DURATION));
}
// ===== Event handlers =====
// App 內不需要擔心捲頁鍵盤事件保留給有實體鍵盤的裝置藍牙鍵盤、Chromebook
const isEditableTarget = (target) => {
if (!target) return false;
const tag = target.tagName || '';
return tag === 'INPUT' || tag === 'TEXTAREA' || target.isContentEditable;
};
const onKeyDown = (e) => {
if (isEditableTarget(e.target)) return;
if (state.phase === PHASE.TITLE) {
if (e.code === 'Digit1' || e.code === 'Numpad1') {
e.preventDefault(); if (e.repeat) return;
audio(); startGame(MODE.TIMED); return;
}
if (e.code === 'Digit2' || e.code === 'Numpad2') {
e.preventDefault(); if (e.repeat) return;
audio(); startGame(MODE.PRACTICE); return;
}
if (e.code === 'Space') e.preventDefault();
return;
}
if (state.phase === PHASE.OVER) {
if (e.code === 'Space') {
e.preventDefault(); if (e.repeat) return;
audio(); backToTitle();
}
return;
}
if (state.mode === MODE.PRACTICE && e.code === 'Escape') {
e.preventDefault(); if (e.repeat) return;
backToTitle(); return;
}
if (e.code !== 'Space') return;
e.preventDefault();
if (e.repeat) return;
pressDown();
};
const onKeyUp = (e) => {
if (e.code !== 'Space') return;
if (isEditableTarget(e.target)) return;
e.preventDefault();
if (state.phase !== PHASE.PLAYING) return;
pressUp();
};
const getPointerPos = (e) => {
const rect = canvas.getBoundingClientRect();
return { x: e.clientX - rect.left, y: e.clientY - rect.top };
};
const onPointerDown = (e) => {
if (e.pointerType === 'mouse' && e.button !== 0) return;
e.preventDefault();
try { canvas.setPointerCapture(e.pointerId); } catch (err) {}
pressDown(getPointerPos(e));
};
const onPointerUp = (e) => {
if (!state.holding) return;
e.preventDefault();
pressUp();
};
const onPointerCancel = () => {
if (state.holding) { state.holding = false; state.jumpDone = false; }
};
const onResize = () => resize();
window.addEventListener('keydown', onKeyDown);
window.addEventListener('keyup', onKeyUp);
window.addEventListener('resize', onResize);
canvas.addEventListener('pointerdown', onPointerDown);
canvas.addEventListener('pointerup', onPointerUp);
canvas.addEventListener('pointercancel', onPointerCancel);
// ===== Game logic — 100% 跟原本一樣 =====
function releaseShot(holdT) {
const g = geom();
const tNorm = Math.min(1, holdT / CONFIG.JUMP_DURATION);
const offset = tNorm - CONFIG.PERFECT_WINDOW_T;
const absOff = Math.abs(offset);
const jumpY = jumpOffset(tNorm) * (W * CONFIG.JUMP_HEIGHT_RATIO);
const bx = g.ballX;
const by = g.groundY - jumpY;
const tx = g.hoopX;
const ty = g.hoopY;
const T = CONFIG.SHOT_TARGET_TIME;
const vx0 = (tx - bx) / T;
const G = W * CONFIG.GRAVITY_RATIO;
const vy0 = (ty - by - 0.5 * G * T * T) / T - G * CONFIG.EULER_COMPENSATION;
const driftMag = absOff < CONFIG.PERFECT_TOLERANCE
? 0
: Math.min(1, (absOff - CONFIG.PERFECT_TOLERANCE) / (CONFIG.MAX_DRIFT_T - CONFIG.PERFECT_TOLERANCE));
const sign = Math.sign(offset) || (Math.random() < 0.5 ? -1 : 1);
const rand = (Math.random() - 0.5) * 0.4;
const speed = Math.hypot(vx0, vy0);
const angle = Math.atan2(vy0, vx0);
const baseJitter = (Math.random() - 0.5) * 2;
const baseJitter2 = (Math.random() - 0.5) * 2;
const driftMagCurved = driftMag ** 0.4;
const driftSpeed = (sign * driftMag * CONFIG.SHOT_DRIFT_VEL) + rand * 1 * (driftMag ** 3);
const driftAngle = (sign * driftMag * CONFIG.SHOT_DRIFT_ANGLE) + rand * 0.4 * driftMagCurved;
const newSpeed = speed * (1 + baseJitter * CONFIG.PERFECT_JITTER_VEL) * (1 + driftSpeed);
const newAngle = angle + baseJitter2 * CONFIG.PERFECT_JITTER_ANGLE + driftAngle;
const vx = Math.cos(newAngle) * newSpeed;
const vy = Math.sin(newAngle) * newSpeed;
state.balls.push({
id: state.nextBallId++,
x: bx, y: by, vx, vy,
r: g.ballR,
spin: (Math.random() - 0.5) * 8,
rot: 0,
passedRimTopAt: null,
scored: false,
lastBoardHit: 0,
lastRimHit: 0,
bornAt: performance.now(),
});
state.attempts += 1;
state.cooldown = CONFIG.COOLDOWN;
state.ready = false;
SFX.shoot();
}
function jumpOffset(tNorm) {
if (tNorm <= 0 || tNorm >= 1) return 0;
return Math.sin(tNorm * Math.PI);
}
function step(dt) {
if (state.phase !== PHASE.PLAYING) return;
if (state.mode === MODE.TIMED) {
state.timeLeft -= dt;
if (state.timeLeft <= 0) {
state.timeLeft = 0;
state.phase = PHASE.OVER;
SFX.end();
}
}
if (state.holding) {
state.holdT += dt;
if (state.holdT >= CONFIG.JUMP_DURATION) {
state.holdT = CONFIG.JUMP_DURATION;
state.jumpDone = true;
}
}
if (state.cooldown > 0) {
state.cooldown -= dt;
if (state.cooldown <= 0) { state.cooldown = 0; state.ready = true; }
}
const g = geom();
for (const b of state.balls) {
b.prevX = b.x;
b.prevY = b.y;
b.vy += W * CONFIG.GRAVITY_RATIO * dt;
b.vx *= (1 - CONFIG.AIR_DRAG * dt * 60);
b.vy *= (1 - CONFIG.AIR_DRAG * dt * 60);
b.x += b.vx * dt;
b.y += b.vy * dt;
b.rot += b.spin * dt;
collideBackboard(b, g);
collideRim(b, g);
detectScore(b, g);
}
for (let i = 0; i < state.balls.length; i++) {
for (let j = i + 1; j < state.balls.length; j++) {
collideBalls(state.balls[i], state.balls[j]);
}
}
state.balls = state.balls.filter(b => {
const margin = b.r * 4;
return b.x > -margin && b.x < W + margin && b.y < H + margin;
});
state.netImpulse *= Math.exp(-dt * 4);
state.netPhase += dt * 14;
if (state.lastScoreFlash > 0) state.lastScoreFlash -= dt;
}
function collideBackboard(b, g) {
if (b.x + b.r < g.boardX) return;
if (b.x - b.r > g.boardX) return;
if (b.y < g.boardTop - b.r || b.y > g.boardBot + b.r) return;
const cy = Math.max(g.boardTop, Math.min(g.boardBot, b.y));
const dx = b.x - g.boardX;
const dy = b.y - cy;
const d = Math.hypot(dx, dy);
if (d > b.r) return;
if (d === 0) return;
const nx = dx / d, ny = dy / d;
const overlap = b.r - d;
b.x += nx * overlap;
b.y += ny * overlap;
const vn = b.vx * nx + b.vy * ny;
if (vn < 0) {
b.vx -= (1 + CONFIG.RESTITUTION_BOARD) * vn * nx;
b.vy -= (1 + CONFIG.RESTITUTION_BOARD) * vn * ny;
const now = performance.now();
if (now - b.lastBoardHit > 80) { SFX.board(); b.lastBoardHit = now; }
}
}
function collideRim(b, g) {
const front = { x: g.hoopX - g.hoopW / 2, y: g.hoopY };
const back = { x: g.hoopX + g.hoopW / 2, y: g.hoopY };
for (const p of [front, back]) {
const dx = b.x - p.x;
const dy = b.y - p.y;
const d = Math.hypot(dx, dy);
const minD = b.r + g.rimR;
if (d < minD && d > 0) {
const nx = dx / d, ny = dy / d;
const overlap = minD - d;
b.x += nx * overlap;
b.y += ny * overlap;
const vn = b.vx * nx + b.vy * ny;
if (vn < 0) {
b.vx -= (1 + CONFIG.RESTITUTION_RIM) * vn * nx;
b.vy -= (1 + CONFIG.RESTITUTION_RIM) * vn * ny;
const now = performance.now();
if (now - b.lastRimHit > 80) { SFX.rim(); b.lastRimHit = now; }
}
}
}
const armLeft = back.x;
const armRight = g.boardX;
if (b.x > armLeft - b.r && b.x < armRight + b.r) {
const cx = Math.max(armLeft, Math.min(armRight, b.x));
const dx = b.x - cx;
const dy = b.y - g.hoopY;
const d = Math.hypot(dx, dy);
if (d < b.r && d > 0) {
const nx = dx / d, ny = dy / d;
const overlap = b.r - d;
b.x += nx * overlap;
b.y += ny * overlap;
const vn = b.vx * nx + b.vy * ny;
if (vn < 0) {
b.vx -= (1 + CONFIG.RESTITUTION_RIM) * vn * nx;
b.vy -= (1 + CONFIG.RESTITUTION_RIM) * vn * ny;
const now = performance.now();
if (now - b.lastRimHit > 80) { SFX.rim(); b.lastRimHit = now; }
}
}
}
}
function detectScore(b, g) {
if (b.scored) return;
const rimY = g.hoopY;
const xL = g.hoopX - g.hoopW / 2 + g.rimR;
const xR = g.hoopX + g.hoopW / 2 - g.rimR;
if (b.passedRimTopAt === null && b.y < rimY && b.x > xL - b.r && b.x < xR + b.r) {
b.passedRimTopAt = b.y;
}
const prevY = b.prevY != null ? b.prevY : b.y;
if (
!b.scored &&
b.passedRimTopAt !== null &&
b.vy > 0 &&
prevY <= rimY &&
b.y > rimY
) {
if (b.x > xL && b.x < xR) {
b.scored = true;
state.score += 1;
state.lastScoreFlash = 0.5;
state.netImpulse = 1;
const now = performance.now();
const recentlyHit = (now - b.lastRimHit < 250) || (now - b.lastBoardHit < 250);
if (recentlyHit) SFX.score(); else SFX.swish();
}
}
}
function collideBalls(a, b) {
const dx = b.x - a.x;
const dy = b.y - a.y;
const d = Math.hypot(dx, dy);
const minD = a.r + b.r;
if (d >= minD || d === 0) return;
const nx = dx / d, ny = dy / d;
const overlap = minD - d;
a.x -= nx * overlap / 2;
a.y -= ny * overlap / 2;
b.x += nx * overlap / 2;
b.y += ny * overlap / 2;
const rvx = b.vx - a.vx, rvy = b.vy - a.vy;
const vn = rvx * nx + rvy * ny;
if (vn > 0) return;
const e = CONFIG.RESTITUTION_BALL;
const j = -(1 + e) * vn / 2;
a.vx -= j * nx; a.vy -= j * ny;
b.vx += j * nx; b.vy += j * ny;
}
// ===== Rendering =====
function draw() {
const g = geom();
ctx.clearRect(0, 0, W, H);
drawFrame();
drawScore();
drawBottomRight();
drawHoop(g);
drawShooterBall(g);
for (const b of state.balls) drawBall(b);
if (state.phase === PHASE.PLAYING) drawAccuracyBottomLeft();
if (state.phase === PHASE.TITLE) drawTitle();
else if (state.phase === PHASE.OVER) drawGameOver();
}
function drawFrame() {
ctx.save();
ctx.strokeStyle = COLORS.ink;
ctx.lineWidth = 2;
ctx.strokeRect(0.5, 0.5, W - 1, H - 1);
ctx.restore();
}
function drawScore() {
ctx.save();
ctx.fillStyle = COLORS.ink;
const flash = Math.max(0, state.lastScoreFlash);
const scale = 1 + flash * 0.4;
const fontSize = Math.floor(W * 0.085 * scale);
ctx.font = `700 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.fillText(String(state.score), W / 2, H * 0.05);
ctx.restore();
}
function drawBottomRight() {
if (state.phase !== PHASE.PLAYING) { exitButton = null; return; }
ctx.save();
if (state.mode === MODE.TIMED) {
ctx.fillStyle = COLORS.ink;
const fontSize = Math.floor(W * 0.05);
ctx.font = `500 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
const t = Math.max(0, state.timeLeft);
const m = Math.floor(t / 60);
const s = Math.floor(t % 60);
const txt = `${m}:${String(s).padStart(2, '0')}`;
ctx.fillText(txt, W - W * 0.05, H - H * 0.04);
exitButton = null;
} else {
// 練習模式:手機沒有 esc 鍵,所以改寫成「回主畫面」
const label = '回主畫面';
const fontSize = Math.floor(W * 0.026);
ctx.font = `500 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
const padX = W * 0.018;
const padY = W * 0.012;
const textW = ctx.measureText(label).width;
const btnW = textW + padX * 2;
const btnH = fontSize + padY * 2;
const btnX = W - W * 0.05 - btnW;
const btnY = H * 0.04;
exitButton = { x: btnX, y: btnY, w: btnW, h: btnH };
ctx.lineWidth = Math.max(1, W * 0.002);
ctx.strokeStyle = COLORS.gray;
ctx.fillStyle = COLORS.paper;
ctx.beginPath();
ctx.rect(btnX, btnY, btnW, btnH);
ctx.fill(); ctx.stroke();
ctx.fillStyle = COLORS.gray;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(label, btnX + btnW / 2, btnY + btnH / 2);
}
ctx.restore();
}
function drawAccuracyBottomLeft() {
ctx.save();
ctx.fillStyle = COLORS.gray;
const fontSize = Math.floor(W * 0.035);
ctx.font = `500 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.textAlign = 'left';
ctx.textBaseline = 'bottom';
const pct = state.attempts > 0 ? Math.round((state.score / state.attempts) * 100) : 0;
const txt = `${state.score}/${state.attempts} (${pct}%)`;
ctx.fillText(txt, W * 0.05, H - H * 0.06);
ctx.restore();
}
function drawHoop(g) {
ctx.save();
ctx.strokeStyle = COLORS.ink;
ctx.lineWidth = Math.max(2, W * 0.005);
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(g.boardX, g.boardTop);
ctx.lineTo(g.boardX, g.boardBot);
ctx.stroke();
ctx.strokeStyle = COLORS.ink;
ctx.lineWidth = Math.max(1, W * 0.003);
ctx.beginPath();
ctx.moveTo(g.hoopX + g.hoopW / 2, g.hoopY);
ctx.lineTo(g.boardX, g.hoopY);
ctx.stroke();
ctx.strokeStyle = COLORS.rim;
ctx.lineWidth = Math.max(2, W * 0.006);
ctx.beginPath();
ctx.moveTo(g.hoopX - g.hoopW / 2, g.hoopY);
ctx.lineTo(g.hoopX + g.hoopW / 2, g.hoopY);
ctx.stroke();
ctx.strokeStyle = COLORS.net;
ctx.lineWidth = Math.max(1, W * 0.0025);
const netLines = 7;
const baseY = g.hoopY;
const bottomY = g.hoopY + g.netDepth;
const leftX = g.hoopX - g.hoopW / 2;
const rightX = g.hoopX + g.hoopW / 2;
const wiggle = state.netImpulse * 4;
for (let i = 0; i <= netLines; i++) {
const t = i / netLines;
const topX = leftX + t * (rightX - leftX);
const bx = leftX + g.hoopW * 0.2 + t * (g.hoopW * 0.6);
const phaseOff = i * 0.7;
const dx = Math.sin(state.netPhase + phaseOff) * wiggle;
ctx.beginPath();
ctx.moveTo(topX, baseY);
ctx.lineTo(bx + dx, bottomY + Math.abs(dx) * 0.3);
ctx.stroke();
}
for (let k = 1; k <= 2; k++) {
const yy = baseY + (g.netDepth * k / 3);
ctx.beginPath();
const dx = Math.sin(state.netPhase + k) * wiggle * 0.6;
ctx.moveTo(leftX + g.hoopW * 0.08 * k, yy);
ctx.lineTo(rightX - g.hoopW * 0.08 * k + dx, yy);
ctx.stroke();
}
ctx.restore();
}
function drawShooterBall(g) {
if (state.phase !== PHASE.PLAYING) return;
if (!state.ready && !state.holding) return;
let yOff = 0;
if (state.holding) {
const tNorm = Math.min(1, state.holdT / CONFIG.JUMP_DURATION);
yOff = jumpOffset(tNorm) * (W * CONFIG.JUMP_HEIGHT_RATIO);
}
drawBallAt(g.ballX, g.groundY - yOff, g.ballR, 0);
}
function drawBall(b) { drawBallAt(b.x, b.y, b.r, b.rot); }
function drawBallAt(x, y, r, rot) {
ctx.save();
if (ballImg) {
ctx.translate(x, y);
ctx.rotate(rot);
ctx.drawImage(ballImg, -r, -r, r * 2, r * 2);
} else {
ctx.fillStyle = COLORS.ball;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fill();
ctx.strokeStyle = 'rgba(0,0,0,0.25)';
ctx.lineWidth = Math.max(1, r * 0.08);
ctx.beginPath();
ctx.arc(x, y, r * 0.75, rot, rot + Math.PI);
ctx.stroke();
}
ctx.restore();
}
function drawTitle() {
ctx.save();
ctx.fillStyle = 'rgba(250,250,247,0.85)';
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = COLORS.ink;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `700 ${Math.floor(W * 0.14)}px sans-serif`;
ctx.fillText('🏀🏀🏀', W / 2, H * 0.22);
const btnW = W * 0.7;
const btnH = H * 0.11;
const btnX = (W - btnW) / 2;
const btnGap = H * 0.025;
const btn1Y = H * 0.4;
const btn2Y = btn1Y + btnH + btnGap;
titleButtons = {
timed: { x: btnX, y: btn1Y, w: btnW, h: btnH },
practice: { x: btnX, y: btn2Y, w: btnW, h: btnH },
};
const drawBtn = (b, label, sub) => {
ctx.lineWidth = Math.max(1.5, W * 0.003);
ctx.strokeStyle = COLORS.ink;
ctx.fillStyle = COLORS.paper;
ctx.beginPath();
ctx.rect(b.x, b.y, b.w, b.h);
ctx.fill(); ctx.stroke();
ctx.fillStyle = COLORS.ink;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `600 ${Math.floor(W * 0.04)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText(label, b.x + b.w / 2, b.y + b.h / 2 - W * 0.012);
ctx.font = `400 ${Math.floor(W * 0.026)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText(sub, b.x + b.w / 2, b.y + b.h / 2 + W * 0.022);
};
drawBtn(titleButtons.timed, '1. 限時模式', `${CONFIG.GAME_DURATION} 秒內投進越多越好`);
drawBtn(titleButtons.practice, '2. 練習模式', '不限時,自由輕鬆投');
ctx.font = `400 ${Math.floor(W * 0.027)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillStyle = 'rgba(26,26,26,0.55)';
ctx.fillText('點按鈕選擇模式', W / 2, H * 0.88);
ctx.restore();
}
function drawGameOver() {
ctx.save();
ctx.fillStyle = 'rgba(250,250,247,0.9)';
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = COLORS.ink;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `500 ${Math.floor(W * 0.045)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText('時間到', W / 2, H * 0.36);
ctx.font = `700 ${Math.floor(W * 0.22)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText(String(state.score), W / 2, H * 0.5);
ctx.font = `400 ${Math.floor(W * 0.03)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText('點任何地方再玩一次', W / 2, H * 0.66);
ctx.restore();
}
// ===== Loop =====
let last = performance.now();
let rafId = 0;
function frame(now) {
let dt = (now - last) / 1000;
last = now;
if (dt > 0.05) dt = 0.05;
step(dt);
draw();
rafId = requestAnimationFrame(frame);
}
rafId = requestAnimationFrame(frame);
return () => {
cancelAnimationFrame(rafId);
window.removeEventListener('keydown', onKeyDown);
window.removeEventListener('keyup', onKeyUp);
window.removeEventListener('resize', onResize);
canvas.removeEventListener('pointerdown', onPointerDown);
canvas.removeEventListener('pointerup', onPointerUp);
canvas.removeEventListener('pointercancel', onPointerCancel);
if (actx && actx.state !== 'closed') actx.close().catch(() => {});
};
}
// 啟動!
initGame(document.getElementById('game'), {});
</script>
</body>
</html>

View File

@@ -0,0 +1,881 @@
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>Hoops</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
width: 100%; height: 100%;
background: #fafaf7;
overflow: hidden;
overscroll-behavior: none;
user-select: none; -webkit-user-select: none;
touch-action: none;
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}
#stage {
position: fixed; inset: 0;
display: flex; align-items: center; justify-content: center;
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
#wrap {
position: relative;
/* 取畫面上能擺進的最大正方形 */
width: min(100vw, 100vh);
height: min(100vw, 100vh);
}
canvas {
display: block;
width: 100%; height: 100%;
background: #fafaf7;
touch-action: none;
}
.hint {
position: absolute;
left: 50%; bottom: 8px;
transform: translateX(-50%);
font-size: 5px;
letter-spacing: 0.01em;
opacity: 0.45;
color: #555;
white-space: nowrap;
pointer-events: none;
}
</style>
</head>
<body>
<div id="stage">
<div id="wrap">
<canvas id="game"></canvas>
<div class="hint">by Wiwi Kuan, https://wiwi.blog</div>
</div>
</div>
<script>
// =============================================================================
// CONFIG — 跟原本完全一樣
// =============================================================================
const DEFAULT_CONFIG = {
GAME_DURATION: 60,
COOLDOWN: 0.5,
JUMP_DURATION: 0.5,
JUMP_HEIGHT_RATIO: 0.25,
PERFECT_WINDOW_T: 0.28,
PERFECT_TOLERANCE: 0.001,
MAX_DRIFT_T: 0.35,
GRAVITY_RATIO: 5,
BALL_RADIUS_RATIO: 0.03,
RESTITUTION_RIM: 0.65,
RESTITUTION_BOARD: 0.7,
RESTITUTION_BALL: 0.7,
AIR_DRAG: 0,
SHOT_TARGET_TIME: 0.75,
SHOT_DRIFT_VEL: 0.4,
SHOT_DRIFT_ANGLE: 0.6,
BALL_IMG_SRC: null,
PERFECT_JITTER_VEL: 0.0025,
PERFECT_JITTER_ANGLE: 0.003,
EULER_COMPENSATION: 0.012,
};
const COLORS = {
ink: '#1a1a1a',
paper: '#fafaf7',
ball: '#c2410c',
rim: '#991b1b',
net: '#999',
gray: '#ccc',
};
const PHASE = { TITLE: 'title', PLAYING: 'playing', OVER: 'over' };
const MODE = { TIMED: 'timed', PRACTICE: 'practice' };
// =============================================================================
// 遊戲主體 — 接收 canvas + config,回傳 cleanup function
// 注意:原本是用 parent.clientWidth 取尺寸,這裡改成 wrap 元素的尺寸(其實一樣)
// 並且讓畫布是「正方形 = min(視窗寬, 視窗高)」,跟原本邏輯一致
// =============================================================================
function initGame(canvas, userConfig) {
const CONFIG = Object.assign({}, DEFAULT_CONFIG, userConfig || {});
const ctx = canvas.getContext('2d');
let W = 0, H = 0, DPR = 1;
function resize() {
const parent = canvas.parentElement;
const parentW = parent ? parent.clientWidth : 600;
const parentH = parent ? parent.clientHeight : 600;
// 取較小邊作為正方形邊長
const px = Math.max(280, Math.floor(Math.min(parentW, parentH)));
DPR = Math.max(1, Math.min(2, window.devicePixelRatio || 1));
canvas.style.width = px + 'px';
canvas.style.height = px + 'px';
canvas.width = Math.floor(px * DPR);
canvas.height = Math.floor(px * DPR);
ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
W = px; H = px;
}
resize();
let ballImg = null;
if (CONFIG.BALL_IMG_SRC) {
const img = new Image();
img.onload = () => { ballImg = img; };
img.src = CONFIG.BALL_IMG_SRC;
}
// ===== Audio =====
let actx = null;
function audio() {
if (!actx) {
try { actx = new (window.AudioContext || window.webkitAudioContext)(); }
catch (e) { actx = null; }
}
return actx;
}
function blip({ freq = 440, dur = 0.08, type = 'sine', vol = 0.15, sweep = 0, delay = 0 } = {}) {
const a = audio(); if (!a) return;
const t0 = a.currentTime + delay;
const o = a.createOscillator();
const g = a.createGain();
o.type = type;
o.frequency.setValueAtTime(freq, t0);
if (sweep) o.frequency.exponentialRampToValueAtTime(Math.max(40, freq + sweep), t0 + dur);
g.gain.setValueAtTime(0.0001, t0);
g.gain.exponentialRampToValueAtTime(vol, t0 + 0.005);
g.gain.exponentialRampToValueAtTime(0.0001, t0 + dur);
o.connect(g).connect(a.destination);
o.start(t0); o.stop(t0 + dur + 0.02);
}
const SFX = {
jump: () => blip({ freq: 220, dur: 0.06, type: 'triangle', vol: 0.08, sweep: 60 }),
shoot: () => blip({ freq: 380, dur: 0.09, type: 'square', vol: 0.07, sweep: 200 }),
rim: () => blip({ freq: 900, dur: 0.05, type: 'square', vol: 0.06, sweep: -300 }),
board: () => blip({ freq: 140, dur: 0.07, type: 'sine', vol: 0.12, sweep: -40 }),
swish: () => {
blip({ freq: 660, dur: 0.08, type: 'sine', vol: 0.10 });
blip({ freq: 990, dur: 0.10, type: 'sine', vol: 0.08, delay: 0.04 });
blip({ freq: 1320, dur: 0.12, type: 'sine', vol: 0.06, delay: 0.09 });
},
score: () => {
blip({ freq: 523, dur: 0.10, type: 'triangle', vol: 0.10 });
blip({ freq: 784, dur: 0.14, type: 'triangle', vol: 0.10, delay: 0.08 });
},
end: () => {
blip({ freq: 220, dur: 0.18, type: 'sawtooth', vol: 0.08 });
blip({ freq: 165, dur: 0.22, type: 'sawtooth', vol: 0.08, delay: 0.12 });
},
};
function geom() {
const hoopX = W * 0.78;
const hoopW = W * 0.085;
const rimR = W * 0.008;
const armLength = W * 0.018;
return {
ballR: W * CONFIG.BALL_RADIUS_RATIO,
ballX: W * 0.18,
groundY: H * 0.72,
hoopX, hoopY: H * 0.42, hoopW, rimR, armLength,
boardX: hoopX + hoopW / 2 + rimR + armLength,
boardTop: H * 0.42 - H * 0.18,
boardBot: H * 0.42 + H * 0.04,
netDepth: H * 0.06,
};
}
const state = {
phase: PHASE.TITLE,
mode: MODE.TIMED,
timeLeft: CONFIG.GAME_DURATION,
score: 0,
attempts: 0,
lastScoreFlash: 0,
holding: false,
holdT: 0,
holdStartTime: 0,
jumpDone: false,
cooldown: 0,
ready: true,
balls: [],
netPhase: 0,
netImpulse: 0,
nextBallId: 1,
};
// 給想作弊的讀者
if (typeof window !== 'undefined') window.__hoops = { state, CONFIG };
let titleButtons = null;
let exitButton = null;
function startGame(mode) {
state.phase = PHASE.PLAYING;
state.mode = mode;
state.timeLeft = CONFIG.GAME_DURATION;
state.score = 0;
state.attempts = 0;
state.lastScoreFlash = 0;
state.holding = false;
state.holdT = 0;
state.holdStartTime = 0;
state.jumpDone = false;
state.cooldown = 0;
state.ready = true;
state.balls = [];
state.netImpulse = 0;
}
function backToTitle() {
state.phase = PHASE.TITLE;
state.holding = false;
state.jumpDone = false;
state.balls = [];
}
function pressDown(pointerPos) {
audio();
if (state.phase === PHASE.OVER) {
backToTitle();
return;
}
if (state.phase === PHASE.TITLE) {
if (pointerPos && titleButtons) {
const { x, y } = pointerPos;
const inBtn = (b) => x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h;
if (inBtn(titleButtons.timed)) { startGame(MODE.TIMED); return; }
if (inBtn(titleButtons.practice)) { startGame(MODE.PRACTICE); return; }
}
return;
}
if (state.mode === MODE.PRACTICE && pointerPos && exitButton) {
const { x, y } = pointerPos;
const b = exitButton;
if (x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h) {
backToTitle();
return;
}
}
if (!state.ready || state.holding) return;
state.holding = true;
state.holdT = 0;
state.holdStartTime = performance.now();
state.jumpDone = false;
SFX.jump();
}
function pressUp() {
if (!state.holding) return;
state.holding = false;
if (state.jumpDone) return;
const realHoldT = (performance.now() - state.holdStartTime) / 1000;
releaseShot(Math.min(realHoldT, CONFIG.JUMP_DURATION));
}
// ===== Event handlers =====
// App 內不需要擔心捲頁鍵盤事件保留給有實體鍵盤的裝置藍牙鍵盤、Chromebook
const isEditableTarget = (target) => {
if (!target) return false;
const tag = target.tagName || '';
return tag === 'INPUT' || tag === 'TEXTAREA' || target.isContentEditable;
};
const onKeyDown = (e) => {
if (isEditableTarget(e.target)) return;
if (state.phase === PHASE.TITLE) {
if (e.code === 'Digit1' || e.code === 'Numpad1') {
e.preventDefault(); if (e.repeat) return;
audio(); startGame(MODE.TIMED); return;
}
if (e.code === 'Digit2' || e.code === 'Numpad2') {
e.preventDefault(); if (e.repeat) return;
audio(); startGame(MODE.PRACTICE); return;
}
if (e.code === 'Space') e.preventDefault();
return;
}
if (state.phase === PHASE.OVER) {
if (e.code === 'Space') {
e.preventDefault(); if (e.repeat) return;
audio(); backToTitle();
}
return;
}
if (state.mode === MODE.PRACTICE && e.code === 'Escape') {
e.preventDefault(); if (e.repeat) return;
backToTitle(); return;
}
if (e.code !== 'Space') return;
e.preventDefault();
if (e.repeat) return;
pressDown();
};
const onKeyUp = (e) => {
if (e.code !== 'Space') return;
if (isEditableTarget(e.target)) return;
e.preventDefault();
if (state.phase !== PHASE.PLAYING) return;
pressUp();
};
const getPointerPos = (e) => {
const rect = canvas.getBoundingClientRect();
return { x: e.clientX - rect.left, y: e.clientY - rect.top };
};
const onPointerDown = (e) => {
if (e.pointerType === 'mouse' && e.button !== 0) return;
e.preventDefault();
try { canvas.setPointerCapture(e.pointerId); } catch (err) {}
pressDown(getPointerPos(e));
};
const onPointerUp = (e) => {
if (!state.holding) return;
e.preventDefault();
pressUp();
};
const onPointerCancel = () => {
if (state.holding) { state.holding = false; state.jumpDone = false; }
};
const onResize = () => resize();
window.addEventListener('keydown', onKeyDown);
window.addEventListener('keyup', onKeyUp);
window.addEventListener('resize', onResize);
canvas.addEventListener('pointerdown', onPointerDown);
canvas.addEventListener('pointerup', onPointerUp);
canvas.addEventListener('pointercancel', onPointerCancel);
// ===== Game logic — 100% 跟原本一樣 =====
function releaseShot(holdT) {
const g = geom();
const tNorm = Math.min(1, holdT / CONFIG.JUMP_DURATION);
const offset = tNorm - CONFIG.PERFECT_WINDOW_T;
const absOff = Math.abs(offset);
const jumpY = jumpOffset(tNorm) * (W * CONFIG.JUMP_HEIGHT_RATIO);
const bx = g.ballX;
const by = g.groundY - jumpY;
const tx = g.hoopX;
const ty = g.hoopY;
const T = CONFIG.SHOT_TARGET_TIME;
const vx0 = (tx - bx) / T;
const G = W * CONFIG.GRAVITY_RATIO;
const vy0 = (ty - by - 0.5 * G * T * T) / T - G * CONFIG.EULER_COMPENSATION;
const driftMag = absOff < CONFIG.PERFECT_TOLERANCE
? 0
: Math.min(1, (absOff - CONFIG.PERFECT_TOLERANCE) / (CONFIG.MAX_DRIFT_T - CONFIG.PERFECT_TOLERANCE));
const sign = Math.sign(offset) || (Math.random() < 0.5 ? -1 : 1);
const rand = (Math.random() - 0.5) * 0.4;
const speed = Math.hypot(vx0, vy0);
const angle = Math.atan2(vy0, vx0);
const baseJitter = (Math.random() - 0.5) * 2;
const baseJitter2 = (Math.random() - 0.5) * 2;
const driftMagCurved = driftMag ** 0.4;
const driftSpeed = (sign * driftMag * CONFIG.SHOT_DRIFT_VEL) + rand * 1 * (driftMag ** 3);
const driftAngle = (sign * driftMag * CONFIG.SHOT_DRIFT_ANGLE) + rand * 0.4 * driftMagCurved;
const newSpeed = speed * (1 + baseJitter * CONFIG.PERFECT_JITTER_VEL) * (1 + driftSpeed);
const newAngle = angle + baseJitter2 * CONFIG.PERFECT_JITTER_ANGLE + driftAngle;
const vx = Math.cos(newAngle) * newSpeed;
const vy = Math.sin(newAngle) * newSpeed;
state.balls.push({
id: state.nextBallId++,
x: bx, y: by, vx, vy,
r: g.ballR,
spin: (Math.random() - 0.5) * 8,
rot: 0,
passedRimTopAt: null,
scored: false,
lastBoardHit: 0,
lastRimHit: 0,
bornAt: performance.now(),
});
state.attempts += 1;
state.cooldown = CONFIG.COOLDOWN;
state.ready = false;
SFX.shoot();
}
function jumpOffset(tNorm) {
if (tNorm <= 0 || tNorm >= 1) return 0;
return Math.sin(tNorm * Math.PI);
}
function step(dt) {
if (state.phase !== PHASE.PLAYING) return;
if (state.mode === MODE.TIMED) {
state.timeLeft -= dt;
if (state.timeLeft <= 0) {
state.timeLeft = 0;
state.phase = PHASE.OVER;
SFX.end();
}
}
if (state.holding) {
state.holdT += dt;
if (state.holdT >= CONFIG.JUMP_DURATION) {
state.holdT = CONFIG.JUMP_DURATION;
state.jumpDone = true;
}
}
if (state.cooldown > 0) {
state.cooldown -= dt;
if (state.cooldown <= 0) { state.cooldown = 0; state.ready = true; }
}
const g = geom();
for (const b of state.balls) {
b.prevX = b.x;
b.prevY = b.y;
b.vy += W * CONFIG.GRAVITY_RATIO * dt;
b.vx *= (1 - CONFIG.AIR_DRAG * dt * 60);
b.vy *= (1 - CONFIG.AIR_DRAG * dt * 60);
b.x += b.vx * dt;
b.y += b.vy * dt;
b.rot += b.spin * dt;
collideBackboard(b, g);
collideRim(b, g);
detectScore(b, g);
}
for (let i = 0; i < state.balls.length; i++) {
for (let j = i + 1; j < state.balls.length; j++) {
collideBalls(state.balls[i], state.balls[j]);
}
}
state.balls = state.balls.filter(b => {
const margin = b.r * 4;
return b.x > -margin && b.x < W + margin && b.y < H + margin;
});
state.netImpulse *= Math.exp(-dt * 4);
state.netPhase += dt * 14;
if (state.lastScoreFlash > 0) state.lastScoreFlash -= dt;
}
function collideBackboard(b, g) {
if (b.x + b.r < g.boardX) return;
if (b.x - b.r > g.boardX) return;
if (b.y < g.boardTop - b.r || b.y > g.boardBot + b.r) return;
const cy = Math.max(g.boardTop, Math.min(g.boardBot, b.y));
const dx = b.x - g.boardX;
const dy = b.y - cy;
const d = Math.hypot(dx, dy);
if (d > b.r) return;
if (d === 0) return;
const nx = dx / d, ny = dy / d;
const overlap = b.r - d;
b.x += nx * overlap;
b.y += ny * overlap;
const vn = b.vx * nx + b.vy * ny;
if (vn < 0) {
b.vx -= (1 + CONFIG.RESTITUTION_BOARD) * vn * nx;
b.vy -= (1 + CONFIG.RESTITUTION_BOARD) * vn * ny;
const now = performance.now();
if (now - b.lastBoardHit > 80) { SFX.board(); b.lastBoardHit = now; }
}
}
function collideRim(b, g) {
const front = { x: g.hoopX - g.hoopW / 2, y: g.hoopY };
const back = { x: g.hoopX + g.hoopW / 2, y: g.hoopY };
for (const p of [front, back]) {
const dx = b.x - p.x;
const dy = b.y - p.y;
const d = Math.hypot(dx, dy);
const minD = b.r + g.rimR;
if (d < minD && d > 0) {
const nx = dx / d, ny = dy / d;
const overlap = minD - d;
b.x += nx * overlap;
b.y += ny * overlap;
const vn = b.vx * nx + b.vy * ny;
if (vn < 0) {
b.vx -= (1 + CONFIG.RESTITUTION_RIM) * vn * nx;
b.vy -= (1 + CONFIG.RESTITUTION_RIM) * vn * ny;
const now = performance.now();
if (now - b.lastRimHit > 80) { SFX.rim(); b.lastRimHit = now; }
}
}
}
const armLeft = back.x;
const armRight = g.boardX;
if (b.x > armLeft - b.r && b.x < armRight + b.r) {
const cx = Math.max(armLeft, Math.min(armRight, b.x));
const dx = b.x - cx;
const dy = b.y - g.hoopY;
const d = Math.hypot(dx, dy);
if (d < b.r && d > 0) {
const nx = dx / d, ny = dy / d;
const overlap = b.r - d;
b.x += nx * overlap;
b.y += ny * overlap;
const vn = b.vx * nx + b.vy * ny;
if (vn < 0) {
b.vx -= (1 + CONFIG.RESTITUTION_RIM) * vn * nx;
b.vy -= (1 + CONFIG.RESTITUTION_RIM) * vn * ny;
const now = performance.now();
if (now - b.lastRimHit > 80) { SFX.rim(); b.lastRimHit = now; }
}
}
}
}
function detectScore(b, g) {
if (b.scored) return;
const rimY = g.hoopY;
const xL = g.hoopX - g.hoopW / 2 + g.rimR;
const xR = g.hoopX + g.hoopW / 2 - g.rimR;
if (b.passedRimTopAt === null && b.y < rimY && b.x > xL - b.r && b.x < xR + b.r) {
b.passedRimTopAt = b.y;
}
const prevY = b.prevY != null ? b.prevY : b.y;
if (
!b.scored &&
b.passedRimTopAt !== null &&
b.vy > 0 &&
prevY <= rimY &&
b.y > rimY
) {
if (b.x > xL && b.x < xR) {
b.scored = true;
state.score += 1;
state.lastScoreFlash = 0.5;
state.netImpulse = 1;
const now = performance.now();
const recentlyHit = (now - b.lastRimHit < 250) || (now - b.lastBoardHit < 250);
if (recentlyHit) SFX.score(); else SFX.swish();
}
}
}
function collideBalls(a, b) {
const dx = b.x - a.x;
const dy = b.y - a.y;
const d = Math.hypot(dx, dy);
const minD = a.r + b.r;
if (d >= minD || d === 0) return;
const nx = dx / d, ny = dy / d;
const overlap = minD - d;
a.x -= nx * overlap / 2;
a.y -= ny * overlap / 2;
b.x += nx * overlap / 2;
b.y += ny * overlap / 2;
const rvx = b.vx - a.vx, rvy = b.vy - a.vy;
const vn = rvx * nx + rvy * ny;
if (vn > 0) return;
const e = CONFIG.RESTITUTION_BALL;
const j = -(1 + e) * vn / 2;
a.vx -= j * nx; a.vy -= j * ny;
b.vx += j * nx; b.vy += j * ny;
}
// ===== Rendering =====
function draw() {
const g = geom();
ctx.clearRect(0, 0, W, H);
drawFrame();
drawScore();
drawBottomRight();
drawHoop(g);
drawShooterBall(g);
for (const b of state.balls) drawBall(b);
if (state.phase === PHASE.PLAYING) drawAccuracyBottomLeft();
if (state.phase === PHASE.TITLE) drawTitle();
else if (state.phase === PHASE.OVER) drawGameOver();
}
function drawFrame() {
ctx.save();
ctx.strokeStyle = COLORS.ink;
ctx.lineWidth = 2;
ctx.strokeRect(0.5, 0.5, W - 1, H - 1);
ctx.restore();
}
function drawScore() {
ctx.save();
ctx.fillStyle = COLORS.ink;
const flash = Math.max(0, state.lastScoreFlash);
const scale = 1 + flash * 0.4;
const fontSize = Math.floor(W * 0.085 * scale);
ctx.font = `700 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.fillText(String(state.score), W / 2, H * 0.05);
ctx.restore();
}
function drawBottomRight() {
if (state.phase !== PHASE.PLAYING) { exitButton = null; return; }
ctx.save();
if (state.mode === MODE.TIMED) {
ctx.fillStyle = COLORS.ink;
const fontSize = Math.floor(W * 0.05);
ctx.font = `500 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
const t = Math.max(0, state.timeLeft);
const m = Math.floor(t / 60);
const s = Math.floor(t % 60);
const txt = `${m}:${String(s).padStart(2, '0')}`;
ctx.fillText(txt, W - W * 0.05, H - H * 0.04);
exitButton = null;
} else {
// 練習模式:手機沒有 esc 鍵,所以改寫成「回主畫面」
const label = '回主畫面';
const fontSize = Math.floor(W * 0.026);
ctx.font = `500 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
const padX = W * 0.018;
const padY = W * 0.012;
const textW = ctx.measureText(label).width;
const btnW = textW + padX * 2;
const btnH = fontSize + padY * 2;
const btnX = W - W * 0.05 - btnW;
const btnY = H * 0.04;
exitButton = { x: btnX, y: btnY, w: btnW, h: btnH };
ctx.lineWidth = Math.max(1, W * 0.002);
ctx.strokeStyle = COLORS.gray;
ctx.fillStyle = COLORS.paper;
ctx.beginPath();
ctx.rect(btnX, btnY, btnW, btnH);
ctx.fill(); ctx.stroke();
ctx.fillStyle = COLORS.gray;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(label, btnX + btnW / 2, btnY + btnH / 2);
}
ctx.restore();
}
function drawAccuracyBottomLeft() {
ctx.save();
ctx.fillStyle = COLORS.gray;
const fontSize = Math.floor(W * 0.035);
ctx.font = `500 ${fontSize}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.textAlign = 'left';
ctx.textBaseline = 'bottom';
const pct = state.attempts > 0 ? Math.round((state.score / state.attempts) * 100) : 0;
const txt = `${state.score}/${state.attempts} (${pct}%)`;
ctx.fillText(txt, W * 0.05, H - H * 0.06);
ctx.restore();
}
function drawHoop(g) {
ctx.save();
ctx.strokeStyle = COLORS.ink;
ctx.lineWidth = Math.max(2, W * 0.005);
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(g.boardX, g.boardTop);
ctx.lineTo(g.boardX, g.boardBot);
ctx.stroke();
ctx.strokeStyle = COLORS.ink;
ctx.lineWidth = Math.max(1, W * 0.003);
ctx.beginPath();
ctx.moveTo(g.hoopX + g.hoopW / 2, g.hoopY);
ctx.lineTo(g.boardX, g.hoopY);
ctx.stroke();
ctx.strokeStyle = COLORS.rim;
ctx.lineWidth = Math.max(2, W * 0.006);
ctx.beginPath();
ctx.moveTo(g.hoopX - g.hoopW / 2, g.hoopY);
ctx.lineTo(g.hoopX + g.hoopW / 2, g.hoopY);
ctx.stroke();
ctx.strokeStyle = COLORS.net;
ctx.lineWidth = Math.max(1, W * 0.0025);
const netLines = 7;
const baseY = g.hoopY;
const bottomY = g.hoopY + g.netDepth;
const leftX = g.hoopX - g.hoopW / 2;
const rightX = g.hoopX + g.hoopW / 2;
const wiggle = state.netImpulse * 4;
for (let i = 0; i <= netLines; i++) {
const t = i / netLines;
const topX = leftX + t * (rightX - leftX);
const bx = leftX + g.hoopW * 0.2 + t * (g.hoopW * 0.6);
const phaseOff = i * 0.7;
const dx = Math.sin(state.netPhase + phaseOff) * wiggle;
ctx.beginPath();
ctx.moveTo(topX, baseY);
ctx.lineTo(bx + dx, bottomY + Math.abs(dx) * 0.3);
ctx.stroke();
}
for (let k = 1; k <= 2; k++) {
const yy = baseY + (g.netDepth * k / 3);
ctx.beginPath();
const dx = Math.sin(state.netPhase + k) * wiggle * 0.6;
ctx.moveTo(leftX + g.hoopW * 0.08 * k, yy);
ctx.lineTo(rightX - g.hoopW * 0.08 * k + dx, yy);
ctx.stroke();
}
ctx.restore();
}
function drawShooterBall(g) {
if (state.phase !== PHASE.PLAYING) return;
if (!state.ready && !state.holding) return;
let yOff = 0;
if (state.holding) {
const tNorm = Math.min(1, state.holdT / CONFIG.JUMP_DURATION);
yOff = jumpOffset(tNorm) * (W * CONFIG.JUMP_HEIGHT_RATIO);
}
drawBallAt(g.ballX, g.groundY - yOff, g.ballR, 0);
}
function drawBall(b) { drawBallAt(b.x, b.y, b.r, b.rot); }
function drawBallAt(x, y, r, rot) {
ctx.save();
if (ballImg) {
ctx.translate(x, y);
ctx.rotate(rot);
ctx.drawImage(ballImg, -r, -r, r * 2, r * 2);
} else {
ctx.fillStyle = COLORS.ball;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fill();
ctx.strokeStyle = 'rgba(0,0,0,0.25)';
ctx.lineWidth = Math.max(1, r * 0.08);
ctx.beginPath();
ctx.arc(x, y, r * 0.75, rot, rot + Math.PI);
ctx.stroke();
}
ctx.restore();
}
function drawTitle() {
ctx.save();
ctx.fillStyle = 'rgba(250,250,247,0.85)';
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = COLORS.ink;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `700 ${Math.floor(W * 0.14)}px sans-serif`;
ctx.fillText('🏀🏀🏀', W / 2, H * 0.22);
const btnW = W * 0.7;
const btnH = H * 0.11;
const btnX = (W - btnW) / 2;
const btnGap = H * 0.025;
const btn1Y = H * 0.4;
const btn2Y = btn1Y + btnH + btnGap;
titleButtons = {
timed: { x: btnX, y: btn1Y, w: btnW, h: btnH },
practice: { x: btnX, y: btn2Y, w: btnW, h: btnH },
};
const drawBtn = (b, label, sub) => {
ctx.lineWidth = Math.max(1.5, W * 0.003);
ctx.strokeStyle = COLORS.ink;
ctx.fillStyle = COLORS.paper;
ctx.beginPath();
ctx.rect(b.x, b.y, b.w, b.h);
ctx.fill(); ctx.stroke();
ctx.fillStyle = COLORS.ink;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `600 ${Math.floor(W * 0.04)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText(label, b.x + b.w / 2, b.y + b.h / 2 - W * 0.012);
ctx.font = `400 ${Math.floor(W * 0.026)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText(sub, b.x + b.w / 2, b.y + b.h / 2 + W * 0.022);
};
drawBtn(titleButtons.timed, '1. 限時模式', `${CONFIG.GAME_DURATION} 秒內投進越多越好`);
drawBtn(titleButtons.practice, '2. 練習模式', '不限時,自由輕鬆投');
ctx.font = `400 ${Math.floor(W * 0.027)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillStyle = 'rgba(26,26,26,0.55)';
ctx.fillText('點按鈕選擇模式', W / 2, H * 0.88);
ctx.restore();
}
function drawGameOver() {
ctx.save();
ctx.fillStyle = 'rgba(250,250,247,0.9)';
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = COLORS.ink;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `500 ${Math.floor(W * 0.045)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText('時間到', W / 2, H * 0.36);
ctx.font = `700 ${Math.floor(W * 0.22)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText(String(state.score), W / 2, H * 0.5);
ctx.font = `400 ${Math.floor(W * 0.03)}px ui-monospace, "SF Mono", Menlo, monospace`;
ctx.fillText('點任何地方再玩一次', W / 2, H * 0.66);
ctx.restore();
}
// ===== Loop =====
let last = performance.now();
let rafId = 0;
function frame(now) {
let dt = (now - last) / 1000;
last = now;
if (dt > 0.05) dt = 0.05;
step(dt);
draw();
rafId = requestAnimationFrame(frame);
}
rafId = requestAnimationFrame(frame);
return () => {
cancelAnimationFrame(rafId);
window.removeEventListener('keydown', onKeyDown);
window.removeEventListener('keyup', onKeyUp);
window.removeEventListener('resize', onResize);
canvas.removeEventListener('pointerdown', onPointerDown);
canvas.removeEventListener('pointerup', onPointerUp);
canvas.removeEventListener('pointercancel', onPointerCancel);
if (actx && actx.state !== 'closed') actx.close().catch(() => {});
};
}
// 啟動!
initGame(document.getElementById('game'), {});
</script>
</body>
</html>

View File

@@ -0,0 +1,342 @@
# Baseline profiles for androidx.activity
HSPLandroidx/activity/ComponentActivity$1;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$2;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$3;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$3;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/activity/ComponentActivity$4;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$4;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/activity/ComponentActivity$5;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$5;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/activity/ComponentActivity$6;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$7;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$7;->onContextAvailable(Landroid/content/Context;)V
HSPLandroidx/activity/ComponentActivity;-><init>()V
HSPLandroidx/activity/ComponentActivity;->addOnContextAvailableListener(Landroidx/activity/contextaware/OnContextAvailableListener;)V
HSPLandroidx/activity/ComponentActivity;->ensureViewModelStore()V
HSPLandroidx/activity/ComponentActivity;->getActivityResultRegistry()Landroidx/activity/result/ActivityResultRegistry;
HSPLandroidx/activity/ComponentActivity;->getLifecycle()Landroidx/lifecycle/Lifecycle;
HSPLandroidx/activity/ComponentActivity;->getOnBackPressedDispatcher()Landroidx/activity/OnBackPressedDispatcher;
HSPLandroidx/activity/ComponentActivity;->getSavedStateRegistry()Landroidx/savedstate/SavedStateRegistry;
HSPLandroidx/activity/ComponentActivity;->getViewModelStore()Landroidx/lifecycle/ViewModelStore;
HSPLandroidx/activity/ComponentActivity;->onCreate(Landroid/os/Bundle;)V
HSPLandroidx/activity/OnBackPressedCallback;-><init>(Z)V
HSPLandroidx/activity/OnBackPressedCallback;->addCancellable(Landroidx/activity/Cancellable;)V
HSPLandroidx/activity/OnBackPressedCallback;->remove()V
HSPLandroidx/activity/OnBackPressedCallback;->setEnabled(Z)V
HSPLandroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;-><init>(Landroidx/activity/OnBackPressedDispatcher;Landroidx/lifecycle/Lifecycle;Landroidx/activity/OnBackPressedCallback;)V
HSPLandroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/activity/OnBackPressedDispatcher$OnBackPressedCancellable;-><init>(Landroidx/activity/OnBackPressedDispatcher;Landroidx/activity/OnBackPressedCallback;)V
HSPLandroidx/activity/OnBackPressedDispatcher;-><init>(Ljava/lang/Runnable;)V
HSPLandroidx/activity/OnBackPressedDispatcher;->addCallback(Landroidx/lifecycle/LifecycleOwner;Landroidx/activity/OnBackPressedCallback;)V
HSPLandroidx/activity/OnBackPressedDispatcher;->addCancellableCallback(Landroidx/activity/OnBackPressedCallback;)Landroidx/activity/Cancellable;
HSPLandroidx/activity/contextaware/ContextAwareHelper;-><init>()V
HSPLandroidx/activity/contextaware/ContextAwareHelper;->addOnContextAvailableListener(Landroidx/activity/contextaware/OnContextAvailableListener;)V
HSPLandroidx/activity/contextaware/ContextAwareHelper;->dispatchOnContextAvailable(Landroid/content/Context;)V
HSPLandroidx/activity/result/ActivityResultLauncher;-><init>()V
HSPLandroidx/activity/result/ActivityResultRegistry$3;-><init>(Landroidx/activity/result/ActivityResultRegistry;Ljava/lang/String;ILandroidx/activity/result/contract/ActivityResultContract;)V
HSPLandroidx/activity/result/ActivityResultRegistry$CallbackAndContract;-><init>(Landroidx/activity/result/ActivityResultCallback;Landroidx/activity/result/contract/ActivityResultContract;)V
HSPLandroidx/activity/result/ActivityResultRegistry;-><init>()V
HSPLandroidx/activity/result/ActivityResultRegistry;->bindRcKey(ILjava/lang/String;)V
HSPLandroidx/activity/result/ActivityResultRegistry;->generateRandomNumber()I
HSPLandroidx/activity/result/ActivityResultRegistry;->register(Ljava/lang/String;Landroidx/activity/result/contract/ActivityResultContract;Landroidx/activity/result/ActivityResultCallback;)Landroidx/activity/result/ActivityResultLauncher;
HSPLandroidx/activity/result/ActivityResultRegistry;->registerKey(Ljava/lang/String;)I
HSPLandroidx/activity/result/contract/ActivityResultContract;-><init>()V
HSPLandroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions;-><init>()V
HSPLandroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;-><init>()V
Landroidx/activity/Cancellable;
Landroidx/activity/ComponentActivity$1;
Landroidx/activity/ComponentActivity$2;
Landroidx/activity/ComponentActivity$3;
Landroidx/activity/ComponentActivity$4;
Landroidx/activity/ComponentActivity$5;
Landroidx/activity/ComponentActivity$6;
Landroidx/activity/ComponentActivity$7;
Landroidx/activity/ComponentActivity$NonConfigurationInstances;
Landroidx/activity/ComponentActivity;
Landroidx/activity/OnBackPressedCallback;
Landroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;
Landroidx/activity/OnBackPressedDispatcher$OnBackPressedCancellable;
Landroidx/activity/OnBackPressedDispatcher;
Landroidx/activity/OnBackPressedDispatcherOwner;
Landroidx/activity/contextaware/ContextAware;
Landroidx/activity/contextaware/ContextAwareHelper;
Landroidx/activity/contextaware/OnContextAvailableListener;
Landroidx/activity/result/ActivityResult;
Landroidx/activity/result/ActivityResultCallback;
Landroidx/activity/result/ActivityResultCaller;
Landroidx/activity/result/ActivityResultLauncher;
Landroidx/activity/result/ActivityResultRegistry$3;
Landroidx/activity/result/ActivityResultRegistry$CallbackAndContract;
Landroidx/activity/result/ActivityResultRegistry;
Landroidx/activity/result/ActivityResultRegistryOwner;
Landroidx/activity/result/contract/ActivityResultContract;
Landroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions;
Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;
PLandroidx/activity/ComponentActivity$1;->run()V
PLandroidx/activity/ComponentActivity;->access$001(Landroidx/activity/ComponentActivity;)V
PLandroidx/activity/ComponentActivity;->onBackPressed()V
PLandroidx/activity/OnBackPressedCallback;->isEnabled()Z
PLandroidx/activity/OnBackPressedCallback;->removeCancellable(Landroidx/activity/Cancellable;)V
PLandroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;->cancel()V
PLandroidx/activity/OnBackPressedDispatcher$OnBackPressedCancellable;->cancel()V
PLandroidx/activity/OnBackPressedDispatcher;->onBackPressed()V
PLandroidx/activity/contextaware/ContextAwareHelper;->clearAvailableContext()V
PLandroidx/activity/result/ActivityResultRegistry$3;->unregister()V
PLandroidx/activity/result/ActivityResultRegistry;->unregister(Ljava/lang/String;)V
Landroidx/activity/Cancellable;
Landroidx/activity/ComponentActivity;
HSPLandroidx/activity/ComponentActivity;-><init>()V
HSPLandroidx/activity/ComponentActivity;-><init>(I)V
HSPLandroidx/activity/ComponentActivity;->addOnContextAvailableListener(Landroidx/activity/contextaware/OnContextAvailableListener;)V
HSPLandroidx/activity/ComponentActivity;->createFullyDrawnExecutor()Landroidx/activity/ComponentActivity$ReportFullyDrawnExecutor;
HSPLandroidx/activity/ComponentActivity;->ensureViewModelStore()V
HSPLandroidx/activity/ComponentActivity;->getActivityResultRegistry()Landroidx/activity/result/ActivityResultRegistry;
HSPLandroidx/activity/ComponentActivity;->getDefaultViewModelCreationExtras()Landroidx/lifecycle/viewmodel/CreationExtras;
HSPLandroidx/activity/ComponentActivity;->getLifecycle()Landroidx/lifecycle/Lifecycle;
HSPLandroidx/activity/ComponentActivity;->getOnBackPressedDispatcher()Landroidx/activity/OnBackPressedDispatcher;
HSPLandroidx/activity/ComponentActivity;->getSavedStateRegistry()Landroidx/savedstate/SavedStateRegistry;
HSPLandroidx/activity/ComponentActivity;->getViewModelStore()Landroidx/lifecycle/ViewModelStore;
HSPLandroidx/activity/ComponentActivity;->lambda$new$2$androidx-activity-ComponentActivity(Landroid/content/Context;)V
HSPLandroidx/activity/ComponentActivity;->onCreate(Landroid/os/Bundle;)V
HSPLandroidx/activity/ComponentActivity;->onTrimMemory(I)V
Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda0;
HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda0;-><init>(Landroidx/activity/ComponentActivity;)V
Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda1;
HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda1;-><init>(Landroidx/activity/ComponentActivity;)V
Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda2;
HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda2;-><init>(Landroidx/activity/ComponentActivity;)V
Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda3;
HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda3;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda3;->onContextAvailable(Landroid/content/Context;)V
Landroidx/activity/ComponentActivity$1;
HSPLandroidx/activity/ComponentActivity$1;-><init>(Landroidx/activity/ComponentActivity;)V
Landroidx/activity/ComponentActivity$2;
HSPLandroidx/activity/ComponentActivity$2;-><init>(Landroidx/activity/ComponentActivity;)V
Landroidx/activity/ComponentActivity$3;
HSPLandroidx/activity/ComponentActivity$3;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$3;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
Landroidx/activity/ComponentActivity$4;
HSPLandroidx/activity/ComponentActivity$4;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$4;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
Landroidx/activity/ComponentActivity$5;
HSPLandroidx/activity/ComponentActivity$5;-><init>(Landroidx/activity/ComponentActivity;)V
HSPLandroidx/activity/ComponentActivity$5;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
Landroidx/activity/ComponentActivity$Api33Impl;
HSPLandroidx/activity/ComponentActivity$Api33Impl;->getOnBackInvokedDispatcher(Landroid/app/Activity;)Landroid/window/OnBackInvokedDispatcher;
Landroidx/activity/ComponentActivity$NonConfigurationInstances;
Landroidx/activity/ComponentActivity$ReportFullyDrawnExecutor;
Landroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl;
HSPLandroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl;-><init>(Landroidx/activity/ComponentActivity;)V
Landroidx/activity/ComponentDialog$$ExternalSyntheticApiModelOutline0;
HSPLandroidx/activity/ComponentDialog$$ExternalSyntheticApiModelOutline0;->m$1(Landroid/view/Window;I)V
HSPLandroidx/activity/ComponentDialog$$ExternalSyntheticApiModelOutline0;->m$1(Landroid/view/Window;Z)V
HSPLandroidx/activity/ComponentDialog$$ExternalSyntheticApiModelOutline0;->m(Landroid/view/Window;I)V
HSPLandroidx/activity/ComponentDialog$$ExternalSyntheticApiModelOutline0;->m(Landroid/view/Window;Z)V
Landroidx/activity/EdgeToEdge;
HSPLandroidx/activity/EdgeToEdge;-><clinit>()V
HSPLandroidx/activity/EdgeToEdge;->enable$default(Landroidx/activity/ComponentActivity;Landroidx/activity/SystemBarStyle;Landroidx/activity/SystemBarStyle;ILjava/lang/Object;)V
HSPLandroidx/activity/EdgeToEdge;->enable(Landroidx/activity/ComponentActivity;Landroidx/activity/SystemBarStyle;Landroidx/activity/SystemBarStyle;)V
Landroidx/activity/EdgeToEdgeApi29;
HSPLandroidx/activity/EdgeToEdgeApi29;-><init>()V
HSPLandroidx/activity/EdgeToEdgeApi29;->setUp(Landroidx/activity/SystemBarStyle;Landroidx/activity/SystemBarStyle;Landroid/view/Window;Landroid/view/View;ZZ)V
Landroidx/activity/EdgeToEdgeImpl;
Landroidx/activity/FullyDrawnReporter;
HSPLandroidx/activity/FullyDrawnReporter;-><init>(Ljava/util/concurrent/Executor;Lkotlin/jvm/functions/Function0;)V
Landroidx/activity/FullyDrawnReporter$$ExternalSyntheticLambda0;
HSPLandroidx/activity/FullyDrawnReporter$$ExternalSyntheticLambda0;-><init>(Landroidx/activity/FullyDrawnReporter;)V
Landroidx/activity/FullyDrawnReporterOwner;
Landroidx/activity/OnBackPressedCallback;
HSPLandroidx/activity/OnBackPressedCallback;-><init>(Z)V
HSPLandroidx/activity/OnBackPressedCallback;->addCancellable(Landroidx/activity/Cancellable;)V
HSPLandroidx/activity/OnBackPressedCallback;->isEnabled()Z
HSPLandroidx/activity/OnBackPressedCallback;->setEnabled(Z)V
HSPLandroidx/activity/OnBackPressedCallback;->setEnabledChangedCallback$activity_release(Lkotlin/jvm/functions/Function0;)V
Landroidx/activity/OnBackPressedDispatcher;
HSPLandroidx/activity/OnBackPressedDispatcher;-><init>(Ljava/lang/Runnable;)V
HSPLandroidx/activity/OnBackPressedDispatcher;->addCallback(Landroidx/lifecycle/LifecycleOwner;Landroidx/activity/OnBackPressedCallback;)V
HSPLandroidx/activity/OnBackPressedDispatcher;->addCancellableCallback$activity_release(Landroidx/activity/OnBackPressedCallback;)Landroidx/activity/Cancellable;
HSPLandroidx/activity/OnBackPressedDispatcher;->hasEnabledCallbacks()Z
HSPLandroidx/activity/OnBackPressedDispatcher;->setOnBackInvokedDispatcher(Landroid/window/OnBackInvokedDispatcher;)V
HSPLandroidx/activity/OnBackPressedDispatcher;->updateBackInvokedCallbackState$activity_release()V
Landroidx/activity/OnBackPressedDispatcher$1;
HSPLandroidx/activity/OnBackPressedDispatcher$1;-><init>(Landroidx/activity/OnBackPressedDispatcher;)V
HSPLandroidx/activity/OnBackPressedDispatcher$1;->invoke()Ljava/lang/Object;
HSPLandroidx/activity/OnBackPressedDispatcher$1;->invoke()V
Landroidx/activity/OnBackPressedDispatcher$2;
HSPLandroidx/activity/OnBackPressedDispatcher$2;-><init>(Landroidx/activity/OnBackPressedDispatcher;)V
Landroidx/activity/OnBackPressedDispatcher$Api33Impl;
HSPLandroidx/activity/OnBackPressedDispatcher$Api33Impl;-><clinit>()V
HSPLandroidx/activity/OnBackPressedDispatcher$Api33Impl;-><init>()V
HSPLandroidx/activity/OnBackPressedDispatcher$Api33Impl;->createOnBackInvokedCallback(Lkotlin/jvm/functions/Function0;)Landroid/window/OnBackInvokedCallback;
Landroidx/activity/OnBackPressedDispatcher$Api33Impl$$ExternalSyntheticLambda0;
HSPLandroidx/activity/OnBackPressedDispatcher$Api33Impl$$ExternalSyntheticLambda0;-><init>(Lkotlin/jvm/functions/Function0;)V
Landroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;
HSPLandroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;-><init>(Landroidx/activity/OnBackPressedDispatcher;Landroidx/lifecycle/Lifecycle;Landroidx/activity/OnBackPressedCallback;)V
HSPLandroidx/activity/OnBackPressedDispatcher$LifecycleOnBackPressedCancellable;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
Landroidx/activity/OnBackPressedDispatcher$OnBackPressedCancellable;
HSPLandroidx/activity/OnBackPressedDispatcher$OnBackPressedCancellable;-><init>(Landroidx/activity/OnBackPressedDispatcher;Landroidx/activity/OnBackPressedCallback;)V
Landroidx/activity/OnBackPressedDispatcherOwner;
Landroidx/activity/R$id;
Landroidx/activity/SystemBarStyle;
HSPLandroidx/activity/SystemBarStyle;-><clinit>()V
HSPLandroidx/activity/SystemBarStyle;-><init>(III)V
HSPLandroidx/activity/SystemBarStyle;-><init>(IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
HSPLandroidx/activity/SystemBarStyle;->getNightMode$activity_release()I
HSPLandroidx/activity/SystemBarStyle;->getScrimWithEnforcedContrast$activity_release(Z)I
HSPLandroidx/activity/SystemBarStyle;->isDark$activity_release(Landroid/content/res/Resources;)Z
Landroidx/activity/SystemBarStyle$Companion;
HSPLandroidx/activity/SystemBarStyle$Companion;-><init>()V
HSPLandroidx/activity/SystemBarStyle$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
HSPLandroidx/activity/SystemBarStyle$Companion;->auto(II)Landroidx/activity/SystemBarStyle;
Landroidx/activity/ViewTreeOnBackPressedDispatcherOwner;
HSPLandroidx/activity/ViewTreeOnBackPressedDispatcherOwner;->set(Landroid/view/View;Landroidx/activity/OnBackPressedDispatcherOwner;)V
Landroidx/activity/contextaware/ContextAware;
Landroidx/activity/contextaware/ContextAwareHelper;
HSPLandroidx/activity/contextaware/ContextAwareHelper;-><init>()V
HSPLandroidx/activity/contextaware/ContextAwareHelper;->addOnContextAvailableListener(Landroidx/activity/contextaware/OnContextAvailableListener;)V
HSPLandroidx/activity/contextaware/ContextAwareHelper;->dispatchOnContextAvailable(Landroid/content/Context;)V
Landroidx/activity/contextaware/OnContextAvailableListener;
Landroidx/activity/result/ActivityResult;
Landroidx/activity/result/ActivityResultCallback;
Landroidx/activity/result/ActivityResultCaller;
Landroidx/activity/result/ActivityResultLauncher;
HSPLandroidx/activity/result/ActivityResultLauncher;-><init>()V
Landroidx/activity/result/ActivityResultRegistry;
HSPLandroidx/activity/result/ActivityResultRegistry;-><init>()V
HSPLandroidx/activity/result/ActivityResultRegistry;->bindRcKey(ILjava/lang/String;)V
HSPLandroidx/activity/result/ActivityResultRegistry;->generateRandomNumber()I
HSPLandroidx/activity/result/ActivityResultRegistry;->register(Ljava/lang/String;Landroidx/activity/result/contract/ActivityResultContract;Landroidx/activity/result/ActivityResultCallback;)Landroidx/activity/result/ActivityResultLauncher;
HSPLandroidx/activity/result/ActivityResultRegistry;->registerKey(Ljava/lang/String;)V
Landroidx/activity/result/ActivityResultRegistry$3;
HSPLandroidx/activity/result/ActivityResultRegistry$3;-><init>(Landroidx/activity/result/ActivityResultRegistry;Ljava/lang/String;Landroidx/activity/result/contract/ActivityResultContract;)V
Landroidx/activity/result/ActivityResultRegistry$CallbackAndContract;
HSPLandroidx/activity/result/ActivityResultRegistry$CallbackAndContract;-><init>(Landroidx/activity/result/ActivityResultCallback;Landroidx/activity/result/contract/ActivityResultContract;)V
Landroidx/activity/result/ActivityResultRegistryOwner;
Landroidx/activity/result/contract/ActivityResultContract;
HSPLandroidx/activity/result/contract/ActivityResultContract;-><init>()V
Landroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions;
HSPLandroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions;-><clinit>()V
HSPLandroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions;-><init>()V
Landroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions$Companion;
HSPLandroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions$Companion;-><init>()V
HSPLandroidx/activity/result/contract/ActivityResultContracts$RequestMultiplePermissions$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;
HSPLandroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;-><clinit>()V
HSPLandroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult;-><init>()V
Landroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult$Companion;
HSPLandroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult$Companion;-><init>()V
HSPLandroidx/activity/result/contract/ActivityResultContracts$StartActivityForResult$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
# Baseline profiles for lifecycle-livedata-core
HSPLandroidx/lifecycle/LiveData$1;-><init>(Landroidx/lifecycle/LiveData;)V
HSPLandroidx/lifecycle/LiveData$1;->run()V
HSPLandroidx/lifecycle/LiveData$AlwaysActiveObserver;-><init>(Landroidx/lifecycle/LiveData;Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/LiveData$AlwaysActiveObserver;->shouldBeActive()Z
HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;-><init>(Landroidx/lifecycle/LiveData;Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->shouldBeActive()Z
HSPLandroidx/lifecycle/LiveData$ObserverWrapper;-><init>(Landroidx/lifecycle/LiveData;Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/LiveData$ObserverWrapper;->activeStateChanged(Z)V
HSPLandroidx/lifecycle/LiveData$ObserverWrapper;->detachObserver()V
HSPLandroidx/lifecycle/LiveData;-><clinit>()V
HSPLandroidx/lifecycle/LiveData;-><init>()V
HSPLandroidx/lifecycle/LiveData;->assertMainThread(Ljava/lang/String;)V
HSPLandroidx/lifecycle/LiveData;->changeActiveCounter(I)V
HSPLandroidx/lifecycle/LiveData;->considerNotify(Landroidx/lifecycle/LiveData$ObserverWrapper;)V
HSPLandroidx/lifecycle/LiveData;->dispatchingValue(Landroidx/lifecycle/LiveData$ObserverWrapper;)V
HSPLandroidx/lifecycle/LiveData;->getValue()Ljava/lang/Object;
HSPLandroidx/lifecycle/LiveData;->getVersion()I
HSPLandroidx/lifecycle/LiveData;->hasActiveObservers()Z
HSPLandroidx/lifecycle/LiveData;->observe(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/LiveData;->observeForever(Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/LiveData;->onActive()V
HSPLandroidx/lifecycle/LiveData;->onInactive()V
HSPLandroidx/lifecycle/LiveData;->postValue(Ljava/lang/Object;)V
HSPLandroidx/lifecycle/LiveData;->removeObserver(Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/LiveData;->setValue(Ljava/lang/Object;)V
HSPLandroidx/lifecycle/MediatorLiveData$Source;-><init>(Landroidx/lifecycle/LiveData;Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/MediatorLiveData$Source;->onChanged(Ljava/lang/Object;)V
HSPLandroidx/lifecycle/MediatorLiveData$Source;->plug()V
HSPLandroidx/lifecycle/MediatorLiveData$Source;->unplug()V
HSPLandroidx/lifecycle/MediatorLiveData;-><init>()V
HSPLandroidx/lifecycle/MediatorLiveData;->addSource(Landroidx/lifecycle/LiveData;Landroidx/lifecycle/Observer;)V
HSPLandroidx/lifecycle/MediatorLiveData;->onActive()V
HSPLandroidx/lifecycle/MediatorLiveData;->onInactive()V
HSPLandroidx/lifecycle/MediatorLiveData;->removeSource(Landroidx/lifecycle/LiveData;)V
HSPLandroidx/lifecycle/MutableLiveData;-><init>()V
HSPLandroidx/lifecycle/MutableLiveData;->setValue(Ljava/lang/Object;)V
PLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->detachObserver()V
# Baseline profiles for Lifecycle ViewModel
HSPLandroidx/lifecycle/ViewModel;-><init>()V
HSPLandroidx/lifecycle/ViewModelLazy;-><init>(Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
HSPLandroidx/lifecycle/ViewModelLazy;->getValue()Landroidx/lifecycle/ViewModel;
HSPLandroidx/lifecycle/ViewModelLazy;->getValue()Ljava/lang/Object;
HSPLandroidx/lifecycle/ViewModelProvider;-><init>(Landroidx/lifecycle/ViewModelStore;Landroidx/lifecycle/ViewModelProvider$Factory;)V
HSPLandroidx/lifecycle/ViewModelProvider;->get(Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
HSPLandroidx/lifecycle/ViewModelProvider;->get(Ljava/lang/String;Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
HSPLandroidx/lifecycle/ViewModelStore;-><init>()V
HSPLandroidx/lifecycle/ViewModelStore;->get(Ljava/lang/String;)Landroidx/lifecycle/ViewModel;
HSPLandroidx/lifecycle/ViewModelStore;->put(Ljava/lang/String;Landroidx/lifecycle/ViewModel;)V
PLandroidx/lifecycle/ViewModel;->clear()V
PLandroidx/lifecycle/ViewModel;->onCleared()V
PLandroidx/lifecycle/ViewModelStore;->clear()V
# Baseline Profile rules for lifecycle-runtime
HPLandroidx/lifecycle/LifecycleRegistry;->backwardPass(Landroidx/lifecycle/LifecycleOwner;)V
HSPLandroidx/lifecycle/LifecycleRegistry$ObserverWithState;-><init>(Landroidx/lifecycle/LifecycleObserver;Landroidx/lifecycle/Lifecycle$State;)V
HSPLandroidx/lifecycle/LifecycleRegistry$ObserverWithState;->dispatchEvent(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/lifecycle/LifecycleRegistry;-><init>(Landroidx/lifecycle/LifecycleOwner;)V
HSPLandroidx/lifecycle/LifecycleRegistry;-><init>(Landroidx/lifecycle/LifecycleOwner;Z)V
HSPLandroidx/lifecycle/LifecycleRegistry;->addObserver(Landroidx/lifecycle/LifecycleObserver;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->calculateTargetState(Landroidx/lifecycle/LifecycleObserver;)Landroidx/lifecycle/Lifecycle$State;
HSPLandroidx/lifecycle/LifecycleRegistry;->enforceMainThreadIfNeeded(Ljava/lang/String;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->forwardPass(Landroidx/lifecycle/LifecycleOwner;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->getCurrentState()Landroidx/lifecycle/Lifecycle$State;
HSPLandroidx/lifecycle/LifecycleRegistry;->handleLifecycleEvent(Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->isSynced()Z
HSPLandroidx/lifecycle/LifecycleRegistry;->min(Landroidx/lifecycle/Lifecycle$State;Landroidx/lifecycle/Lifecycle$State;)Landroidx/lifecycle/Lifecycle$State;
HSPLandroidx/lifecycle/LifecycleRegistry;->moveToState(Landroidx/lifecycle/Lifecycle$State;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->popParentState()V
HSPLandroidx/lifecycle/LifecycleRegistry;->pushParentState(Landroidx/lifecycle/Lifecycle$State;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->removeObserver(Landroidx/lifecycle/LifecycleObserver;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->setCurrentState(Landroidx/lifecycle/Lifecycle$State;)V
HSPLandroidx/lifecycle/LifecycleRegistry;->sync()V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;-><init>()V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPostCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPostResumed(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPostStarted(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityResumed(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityStarted(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->registerIn(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/ReportFragment;-><init>()V
HSPLandroidx/lifecycle/ReportFragment;->dispatch(Landroid/app/Activity;Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/lifecycle/ReportFragment;->dispatch(Landroidx/lifecycle/Lifecycle$Event;)V
HSPLandroidx/lifecycle/ReportFragment;->dispatchCreate(Landroidx/lifecycle/ReportFragment$ActivityInitializationListener;)V
HSPLandroidx/lifecycle/ReportFragment;->dispatchResume(Landroidx/lifecycle/ReportFragment$ActivityInitializationListener;)V
HSPLandroidx/lifecycle/ReportFragment;->dispatchStart(Landroidx/lifecycle/ReportFragment$ActivityInitializationListener;)V
HSPLandroidx/lifecycle/ReportFragment;->injectIfNeededIn(Landroid/app/Activity;)V
HSPLandroidx/lifecycle/ReportFragment;->onActivityCreated(Landroid/os/Bundle;)V
HSPLandroidx/lifecycle/ReportFragment;->onResume()V
HSPLandroidx/lifecycle/ReportFragment;->onStart()V
HSPLandroidx/lifecycle/ViewTreeLifecycleOwner;->set(Landroid/view/View;Landroidx/lifecycle/LifecycleOwner;)V
HSPLandroidx/lifecycle/ViewTreeViewModelStoreOwner;->set(Landroid/view/View;Landroidx/lifecycle/ViewModelStoreOwner;)V
PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityDestroyed(Landroid/app/Activity;)V
PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPaused(Landroid/app/Activity;)V
PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPreDestroyed(Landroid/app/Activity;)V
PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPrePaused(Landroid/app/Activity;)V
PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPreStopped(Landroid/app/Activity;)V
PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityStopped(Landroid/app/Activity;)V
PLandroidx/lifecycle/ReportFragment;->onDestroy()V
PLandroidx/lifecycle/ReportFragment;->onPause()V
PLandroidx/lifecycle/ReportFragment;->onStop()V
# Baseline Profile Rules for androidx.startup
Landroidx/startup/AppInitializer;
HSPLandroidx/startup/AppInitializer;->**(**)**

View File

@@ -0,0 +1,10 @@
{
"version": 3,
"artifactType": {
"type": "COMPATIBLE_SCREEN_MANIFEST",
"kind": "Directory"
},
"applicationId": "blog.wiwi.hoops",
"variantName": "debug",
"elements": []
}

View File

@@ -0,0 +1,10 @@
{
"version": 3,
"artifactType": {
"type": "COMPATIBLE_SCREEN_MANIFEST",
"kind": "Directory"
},
"applicationId": "blog.wiwi.hoops",
"variantName": "release",
"elements": []
}

View File

@@ -0,0 +1 @@
{"options":{"minApiLevel":"24","isDebugModeEnabled":false},"version":"8.13.19"}

View File

@@ -0,0 +1,89 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimizations: If you don't want to optimize, use the proguard-android.txt configuration file
# instead of this one, which turns off the optimization flags.
-allowaccessmodification
# Preserve some attributes that may be required for reflection.
-keepattributes AnnotationDefault,
EnclosingMethod,
InnerClasses,
RuntimeVisibleAnnotations,
RuntimeVisibleParameterAnnotations,
RuntimeVisibleTypeAnnotations,
Signature
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keep public class com.google.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
-dontnote com.google.vending.licensing.ILicensingService
-dontnote com.google.android.vending.licensing.ILicensingService
# For native methods, see https://www.guardsquare.com/manual/configuration/examples#native
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see https://www.guardsquare.com/manual/configuration/examples#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontnote androidx.**
-dontwarn android.support.**
-dontwarn androidx.**
# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
# These classes are duplicated between android.jar and org.apache.http.legacy.jar.
-dontnote org.apache.http.**
-dontnote android.net.http.**
# These classes are duplicated between android.jar and core-lambda-stubs.jar.
-dontnote java.lang.invoke.**

View File

@@ -0,0 +1,95 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize steps (and performs some
# of these optimizations on its own).
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
-dontoptimize
# Preserve some attributes that may be required for reflection.
-keepattributes AnnotationDefault,
EnclosingMethod,
InnerClasses,
RuntimeVisibleAnnotations,
RuntimeVisibleParameterAnnotations,
RuntimeVisibleTypeAnnotations,
Signature
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keep public class com.google.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
-dontnote com.google.vending.licensing.ILicensingService
-dontnote com.google.android.vending.licensing.ILicensingService
# For native methods, see https://www.guardsquare.com/manual/configuration/examples#native
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see https://www.guardsquare.com/manual/configuration/examples#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontnote androidx.**
-dontwarn android.support.**
-dontwarn androidx.**
# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
# These classes are duplicated between android.jar and org.apache.http.legacy.jar.
-dontnote org.apache.http.**
-dontnote android.net.http.**
# These classes are duplicated between android.jar and core-lambda-stubs.jar.
-dontnote java.lang.invoke.**

View File

@@ -0,0 +1,89 @@
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimizations can be turned on and off in the 'postProcessing' DSL block.
# The configuration below is applied if optimizations are enabled.
-allowaccessmodification
# Preserve some attributes that may be required for reflection.
-keepattributes AnnotationDefault,
EnclosingMethod,
InnerClasses,
RuntimeVisibleAnnotations,
RuntimeVisibleParameterAnnotations,
RuntimeVisibleTypeAnnotations,
Signature
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keep public class com.google.android.vending.licensing.ILicensingService
-dontnote com.android.vending.licensing.ILicensingService
-dontnote com.google.vending.licensing.ILicensingService
-dontnote com.google.android.vending.licensing.ILicensingService
# For native methods, see https://www.guardsquare.com/manual/configuration/examples#native
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see https://www.guardsquare.com/manual/configuration/examples#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontnote androidx.**
-dontwarn android.support.**
-dontwarn androidx.**
# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
# These classes are duplicated between android.jar and org.apache.http.legacy.jar.
-dontnote org.apache.http.**
-dontnote android.net.http.**
# These classes are duplicated between android.jar and core-lambda-stubs.jar.
-dontnote java.lang.invoke.**

View File

@@ -0,0 +1,5 @@
31=0/.dm
2147483647=0/.dm
28=1/.dm
29=1/.dm
30=1/.dm

View File

@@ -0,0 +1 @@
[{"key":"androidx/startup/AppInitializer.class","name":"androidx/startup/AppInitializer.class","size":7553,"crc":870624420},{"key":"androidx/startup/InitializationProvider.class","name":"androidx/startup/InitializationProvider.class","size":2530,"crc":-159478496},{"key":"androidx/startup/Initializer.class","name":"androidx/startup/Initializer.class","size":555,"crc":-1348991370},{"key":"androidx/startup/StartupException.class","name":"androidx/startup/StartupException.class","size":1051,"crc":-464023827},{"key":"androidx/startup/StartupLogger.class","name":"androidx/startup/StartupLogger.class","size":1324,"crc":1793103804},{"key":"META-INF/androidx.startup_startup-runtime.version","name":"META-INF/androidx.startup_startup-runtime.version","size":6,"crc":1557790284}]

View File

@@ -0,0 +1 @@
[{"key":"META-INF/MANIFEST.MF","name":"META-INF/MANIFEST.MF","size":25,"crc":-301826126},{"key":"META-INF/kotlinx-coroutines-android.kotlin_module","name":"META-INF/kotlinx-coroutines-android.kotlin_module","size":75,"crc":284142387},{"key":"kotlinx/coroutines/android/HandlerContext$scheduleResumeAfterDelay$$inlined$Runnable$1.class","name":"kotlinx/coroutines/android/HandlerContext$scheduleResumeAfterDelay$$inlined$Runnable$1.class","size":2078,"crc":-395684579},{"key":"kotlinx/coroutines/android/HandlerContext$scheduleResumeAfterDelay$1.class","name":"kotlinx/coroutines/android/HandlerContext$scheduleResumeAfterDelay$1.class","size":1831,"crc":804274569},{"key":"kotlinx/coroutines/android/HandlerDispatcherKt.class","name":"kotlinx/coroutines/android/HandlerDispatcherKt.class","size":9480,"crc":245039586},{"key":"kotlinx/coroutines/android/HandlerDispatcherKt$awaitFrame$lambda-3$$inlined$Runnable$1.class","name":"kotlinx/coroutines/android/HandlerDispatcherKt$awaitFrame$lambda-3$$inlined$Runnable$1.class","size":1526,"crc":1247786088},{"key":"kotlinx/coroutines/android/AndroidDispatcherFactory.class","name":"kotlinx/coroutines/android/AndroidDispatcherFactory.class","size":2203,"crc":-1412015008},{"key":"kotlinx/coroutines/android/HandlerDispatcher.class","name":"kotlinx/coroutines/android/HandlerDispatcher.class","size":2358,"crc":-1159760937},{"key":"kotlinx/coroutines/android/AndroidExceptionPreHandler.class","name":"kotlinx/coroutines/android/AndroidExceptionPreHandler.class","size":2871,"crc":-227947537},{"key":"kotlinx/coroutines/android/HandlerContext.class","name":"kotlinx/coroutines/android/HandlerContext.class","size":7940,"crc":800098068},{"key":"META-INF/services/kotlinx.coroutines.CoroutineExceptionHandler","name":"META-INF/services/kotlinx.coroutines.CoroutineExceptionHandler","size":54,"crc":-1889973424},{"key":"META-INF/services/kotlinx.coroutines.internal.MainDispatcherFactory","name":"META-INF/services/kotlinx.coroutines.internal.MainDispatcherFactory","size":52,"crc":1268078975},{"key":"META-INF/com.android.tools/r8-from-1.6.0/coroutines.pro","name":"META-INF/com.android.tools/r8-from-1.6.0/coroutines.pro","size":899,"crc":2032253094},{"key":"META-INF/com.android.tools/r8-upto-3.0.0/coroutines.pro","name":"META-INF/com.android.tools/r8-upto-3.0.0/coroutines.pro","size":558,"crc":1737114335},{"key":"META-INF/com.android.tools/proguard/coroutines.pro","name":"META-INF/com.android.tools/proguard/coroutines.pro","size":300,"crc":-477435061},{"key":"META-INF/proguard/coroutines.pro","name":"META-INF/proguard/coroutines.pro","size":419,"crc":77044690},{"key":"META-INF/kotlinx_coroutines_android.version","name":"META-INF/kotlinx_coroutines_android.version","size":5,"crc":282843805}]

View File

@@ -0,0 +1 @@
[{"key":"androidx/profileinstaller/BenchmarkOperation$Api21ContextHelper.class","name":"androidx/profileinstaller/BenchmarkOperation$Api21ContextHelper.class","size":784,"crc":910408423},{"key":"androidx/profileinstaller/BenchmarkOperation$Api24ContextHelper.class","name":"androidx/profileinstaller/BenchmarkOperation$Api24ContextHelper.class","size":898,"crc":-1846908175},{"key":"androidx/profileinstaller/BenchmarkOperation.class","name":"androidx/profileinstaller/BenchmarkOperation.class","size":2217,"crc":-235143906},{"key":"androidx/profileinstaller/DeviceProfileWriter.class","name":"androidx/profileinstaller/DeviceProfileWriter.class","size":9901,"crc":1761970309},{"key":"androidx/profileinstaller/DexProfileData.class","name":"androidx/profileinstaller/DexProfileData.class","size":1352,"crc":-447897183},{"key":"androidx/profileinstaller/Encoding.class","name":"androidx/profileinstaller/Encoding.class","size":6317,"crc":-122203374},{"key":"androidx/profileinstaller/FileSectionType.class","name":"androidx/profileinstaller/FileSectionType.class","size":2112,"crc":-2058888424},{"key":"androidx/profileinstaller/ProfileInstallReceiver$ResultDiagnostics.class","name":"androidx/profileinstaller/ProfileInstallReceiver$ResultDiagnostics.class","size":1333,"crc":1824621369},{"key":"androidx/profileinstaller/ProfileInstallReceiver.class","name":"androidx/profileinstaller/ProfileInstallReceiver.class","size":4379,"crc":882371370},{"key":"androidx/profileinstaller/ProfileInstaller$1.class","name":"androidx/profileinstaller/ProfileInstaller$1.class","size":898,"crc":2051655691},{"key":"androidx/profileinstaller/ProfileInstaller$2.class","name":"androidx/profileinstaller/ProfileInstaller$2.class","size":2193,"crc":-26531924},{"key":"androidx/profileinstaller/ProfileInstaller$DiagnosticCode.class","name":"androidx/profileinstaller/ProfileInstaller$DiagnosticCode.class","size":661,"crc":936946104},{"key":"androidx/profileinstaller/ProfileInstaller$DiagnosticsCallback.class","name":"androidx/profileinstaller/ProfileInstaller$DiagnosticsCallback.class","size":445,"crc":-1798863824},{"key":"androidx/profileinstaller/ProfileInstaller$ResultCode.class","name":"androidx/profileinstaller/ProfileInstaller$ResultCode.class","size":653,"crc":1328959836},{"key":"androidx/profileinstaller/ProfileInstaller.class","name":"androidx/profileinstaller/ProfileInstaller.class","size":11365,"crc":-1864137789},{"key":"androidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl.class","name":"androidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl.class","size":1730,"crc":893634560},{"key":"androidx/profileinstaller/ProfileInstallerInitializer$Handler28Impl.class","name":"androidx/profileinstaller/ProfileInstallerInitializer$Handler28Impl.class","size":824,"crc":-353792601},{"key":"androidx/profileinstaller/ProfileInstallerInitializer$Result.class","name":"androidx/profileinstaller/ProfileInstallerInitializer$Result.class","size":471,"crc":-146462361},{"key":"androidx/profileinstaller/ProfileInstallerInitializer.class","name":"androidx/profileinstaller/ProfileInstallerInitializer.class","size":4426,"crc":-941791835},{"key":"androidx/profileinstaller/ProfileTranscoder.class","name":"androidx/profileinstaller/ProfileTranscoder.class","size":21736,"crc":-141864366},{"key":"androidx/profileinstaller/ProfileVerifier$Api33Impl.class","name":"androidx/profileinstaller/ProfileVerifier$Api33Impl.class","size":1385,"crc":-36032257},{"key":"androidx/profileinstaller/ProfileVerifier$Cache.class","name":"androidx/profileinstaller/ProfileVerifier$Cache.class","size":2936,"crc":431451052},{"key":"androidx/profileinstaller/ProfileVerifier$CompilationStatus$ResultCode.class","name":"androidx/profileinstaller/ProfileVerifier$CompilationStatus$ResultCode.class","size":761,"crc":-438192104},{"key":"androidx/profileinstaller/ProfileVerifier$CompilationStatus.class","name":"androidx/profileinstaller/ProfileVerifier$CompilationStatus.class","size":1698,"crc":2010065732},{"key":"androidx/profileinstaller/ProfileVerifier.class","name":"androidx/profileinstaller/ProfileVerifier.class","size":5863,"crc":-1786324660},{"key":"androidx/profileinstaller/ProfileVersion.class","name":"androidx/profileinstaller/ProfileVersion.class","size":1474,"crc":-1261108376},{"key":"androidx/profileinstaller/WritableFileSection.class","name":"androidx/profileinstaller/WritableFileSection.class","size":815,"crc":984045749},{"key":"META-INF/androidx.profileinstaller_profileinstaller.version","name":"META-INF/androidx.profileinstaller_profileinstaller.version","size":6,"crc":-154126649}]

View File

@@ -0,0 +1 @@
[{"key":"androidx/core/splashscreen/MaskedDrawable.class","name":"androidx/core/splashscreen/MaskedDrawable.class","size":2773,"crc":-1354262820},{"key":"androidx/core/splashscreen/SplashScreen$Companion.class","name":"androidx/core/splashscreen/SplashScreen$Companion.class","size":1675,"crc":-2140462775},{"key":"androidx/core/splashscreen/SplashScreen$Impl$setKeepOnScreenCondition$1.class","name":"androidx/core/splashscreen/SplashScreen$Impl$setKeepOnScreenCondition$1.class","size":2545,"crc":-741237898},{"key":"androidx/core/splashscreen/SplashScreen$Impl$setOnExitAnimationListener$2.class","name":"androidx/core/splashscreen/SplashScreen$Impl$setOnExitAnimationListener$2.class","size":2567,"crc":-807334360},{"key":"androidx/core/splashscreen/SplashScreen$Impl.class","name":"androidx/core/splashscreen/SplashScreen$Impl.class","size":10669,"crc":-2114397847},{"key":"androidx/core/splashscreen/SplashScreen$Impl31$hierarchyListener$1.class","name":"androidx/core/splashscreen/SplashScreen$Impl31$hierarchyListener$1.class","size":2140,"crc":-1883408448},{"key":"androidx/core/splashscreen/SplashScreen$Impl31$setKeepOnScreenCondition$1.class","name":"androidx/core/splashscreen/SplashScreen$Impl31$setKeepOnScreenCondition$1.class","size":1815,"crc":71590791},{"key":"androidx/core/splashscreen/SplashScreen$Impl31.class","name":"androidx/core/splashscreen/SplashScreen$Impl31.class","size":8184,"crc":-201717473},{"key":"androidx/core/splashscreen/SplashScreen$KeepOnScreenCondition.class","name":"androidx/core/splashscreen/SplashScreen$KeepOnScreenCondition.class","size":669,"crc":-1257153274},{"key":"androidx/core/splashscreen/SplashScreen$OnExitAnimationListener.class","name":"androidx/core/splashscreen/SplashScreen$OnExitAnimationListener.class","size":922,"crc":-2077345969},{"key":"androidx/core/splashscreen/SplashScreen.class","name":"androidx/core/splashscreen/SplashScreen.class","size":3325,"crc":1433295160},{"key":"androidx/core/splashscreen/SplashScreenViewProvider$ViewImpl$_splashScreenView$2.class","name":"androidx/core/splashscreen/SplashScreenViewProvider$ViewImpl$_splashScreenView$2.class","size":2014,"crc":-66962808},{"key":"androidx/core/splashscreen/SplashScreenViewProvider$ViewImpl.class","name":"androidx/core/splashscreen/SplashScreenViewProvider$ViewImpl.class","size":3428,"crc":-1844359143},{"key":"androidx/core/splashscreen/SplashScreenViewProvider$ViewImpl31.class","name":"androidx/core/splashscreen/SplashScreenViewProvider$ViewImpl31.class","size":3701,"crc":-1166735816},{"key":"androidx/core/splashscreen/SplashScreenViewProvider.class","name":"androidx/core/splashscreen/SplashScreenViewProvider.class","size":2972,"crc":-18991217},{"key":"androidx/core/splashscreen/ThemeUtils$Api31.class","name":"androidx/core/splashscreen/ThemeUtils$Api31.class","size":2566,"crc":490424245},{"key":"androidx/core/splashscreen/ThemeUtils.class","name":"androidx/core/splashscreen/ThemeUtils.class","size":857,"crc":1948239097},{"key":"META-INF/androidx.core_core-splashscreen.version","name":"META-INF/androidx.core_core-splashscreen.version","size":6,"crc":-463103703},{"key":"META-INF/core-splashscreen_release.kotlin_module","name":"META-INF/core-splashscreen_release.kotlin_module","size":24,"crc":-1697843264}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"key":"META-INF/MANIFEST.MF","name":"META-INF/MANIFEST.MF","size":225,"crc":1334212140},{"key":"META-INF/versions/9/module-info.class","name":"META-INF/versions/9/module-info.class","size":287,"crc":-1907208598}]

View File

@@ -0,0 +1 @@
[{"key":"androidx/interpolator/view/animation/FastOutLinearInInterpolator.class","name":"androidx/interpolator/view/animation/FastOutLinearInInterpolator.class","size":2893,"crc":-586218538},{"key":"androidx/interpolator/view/animation/FastOutSlowInInterpolator.class","name":"androidx/interpolator/view/animation/FastOutSlowInInterpolator.class","size":2876,"crc":-1344934723},{"key":"androidx/interpolator/view/animation/LinearOutSlowInInterpolator.class","name":"androidx/interpolator/view/animation/LinearOutSlowInInterpolator.class","size":2882,"crc":-733508970},{"key":"androidx/interpolator/view/animation/LookupTableInterpolator.class","name":"androidx/interpolator/view/animation/LookupTableInterpolator.class","size":907,"crc":-26214147},{"key":"META-INF/androidx.interpolator_interpolator.version","name":"META-INF/androidx.interpolator_interpolator.version","size":6,"crc":-42031000}]

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"key":"androidx/savedstate/Recreator$Companion.class","name":"androidx/savedstate/Recreator$Companion.class","size":881,"crc":-2099199957},{"key":"androidx/savedstate/Recreator$SavedStateProvider.class","name":"androidx/savedstate/Recreator$SavedStateProvider.class","size":2367,"crc":1821800407},{"key":"androidx/savedstate/Recreator.class","name":"androidx/savedstate/Recreator.class","size":5559,"crc":-533493763},{"key":"androidx/savedstate/SavedStateRegistry$AutoRecreated.class","name":"androidx/savedstate/SavedStateRegistry$AutoRecreated.class","size":784,"crc":567056175},{"key":"androidx/savedstate/SavedStateRegistry$Companion.class","name":"androidx/savedstate/SavedStateRegistry$Companion.class","size":887,"crc":900872896},{"key":"androidx/savedstate/SavedStateRegistry$SavedStateProvider.class","name":"androidx/savedstate/SavedStateRegistry$SavedStateProvider.class","size":709,"crc":-309935901},{"key":"androidx/savedstate/SavedStateRegistry.class","name":"androidx/savedstate/SavedStateRegistry.class","size":10105,"crc":788600212},{"key":"androidx/savedstate/SavedStateRegistryController$Companion.class","name":"androidx/savedstate/SavedStateRegistryController$Companion.class","size":1607,"crc":-1819286630},{"key":"androidx/savedstate/SavedStateRegistryController.class","name":"androidx/savedstate/SavedStateRegistryController.class","size":4330,"crc":-287729808},{"key":"androidx/savedstate/SavedStateRegistryOwner.class","name":"androidx/savedstate/SavedStateRegistryOwner.class","size":755,"crc":-979039875},{"key":"androidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$1.class","name":"androidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$1.class","size":1846,"crc":423512158},{"key":"androidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$2.class","name":"androidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$2.class","size":2045,"crc":-1356874610},{"key":"androidx/savedstate/ViewTreeSavedStateRegistryOwner.class","name":"androidx/savedstate/ViewTreeSavedStateRegistryOwner.class","size":2543,"crc":1459979664},{"key":"META-INF/androidx.savedstate_savedstate.version","name":"META-INF/androidx.savedstate_savedstate.version","size":6,"crc":1315721634},{"key":"META-INF/savedstate_release.kotlin_module","name":"META-INF/savedstate_release.kotlin_module","size":80,"crc":-912612184}]

View File

@@ -0,0 +1 @@
[{"key":"androidx/versionedparcelable/CustomVersionedParcelable.class","name":"androidx/versionedparcelable/CustomVersionedParcelable.class","size":915,"crc":-363159068},{"key":"androidx/versionedparcelable/NonParcelField.class","name":"androidx/versionedparcelable/NonParcelField.class","size":676,"crc":1361393714},{"key":"androidx/versionedparcelable/ParcelField.class","name":"androidx/versionedparcelable/ParcelField.class","size":762,"crc":-355164638},{"key":"androidx/versionedparcelable/ParcelImpl$1.class","name":"androidx/versionedparcelable/ParcelImpl$1.class","size":1191,"crc":-60532325},{"key":"androidx/versionedparcelable/ParcelImpl.class","name":"androidx/versionedparcelable/ParcelImpl.class","size":1979,"crc":1919067054},{"key":"androidx/versionedparcelable/ParcelUtils.class","name":"androidx/versionedparcelable/ParcelUtils.class","size":5523,"crc":-1129855369},{"key":"androidx/versionedparcelable/VersionedParcel$1.class","name":"androidx/versionedparcelable/VersionedParcel$1.class","size":1546,"crc":-1038307129},{"key":"androidx/versionedparcelable/VersionedParcel$ParcelException.class","name":"androidx/versionedparcelable/VersionedParcel$ParcelException.class","size":538,"crc":1830934000},{"key":"androidx/versionedparcelable/VersionedParcel.class","name":"androidx/versionedparcelable/VersionedParcel.class","size":29325,"crc":142272959},{"key":"androidx/versionedparcelable/VersionedParcelParcel.class","name":"androidx/versionedparcelable/VersionedParcelParcel.class","size":7429,"crc":-328586236},{"key":"androidx/versionedparcelable/VersionedParcelStream$1.class","name":"androidx/versionedparcelable/VersionedParcelStream$1.class","size":1613,"crc":1775874054},{"key":"androidx/versionedparcelable/VersionedParcelStream$FieldBuffer.class","name":"androidx/versionedparcelable/VersionedParcelStream$FieldBuffer.class","size":1288,"crc":1505456534},{"key":"androidx/versionedparcelable/VersionedParcelStream.class","name":"androidx/versionedparcelable/VersionedParcelStream.class","size":13823,"crc":-1859752855},{"key":"androidx/versionedparcelable/VersionedParcelable.class","name":"androidx/versionedparcelable/VersionedParcelable.class","size":148,"crc":752656910},{"key":"androidx/versionedparcelable/VersionedParcelize.class","name":"androidx/versionedparcelable/VersionedParcelize.class","size":964,"crc":886842821},{"key":"META-INF/androidx.versionedparcelable_versionedparcelable.version","name":"META-INF/androidx.versionedparcelable_versionedparcelable.version","size":6,"crc":1557790284}]

View File

@@ -0,0 +1 @@
[{"key":"androidx/lifecycle/Observer.class","name":"androidx/lifecycle/Observer.class","size":581,"crc":-1645925231},{"key":"androidx/lifecycle/LiveData$1.class","name":"androidx/lifecycle/LiveData$1.class","size":967,"crc":1624229709},{"key":"androidx/lifecycle/LiveData$AlwaysActiveObserver.class","name":"androidx/lifecycle/LiveData$AlwaysActiveObserver.class","size":1024,"crc":2056042322},{"key":"androidx/lifecycle/LiveData$LifecycleBoundObserver.class","name":"androidx/lifecycle/LiveData$LifecycleBoundObserver.class","size":2882,"crc":499156433},{"key":"androidx/lifecycle/LiveData$ObserverWrapper.class","name":"androidx/lifecycle/LiveData$ObserverWrapper.class","size":1588,"crc":-1223836256},{"key":"androidx/lifecycle/LiveData.class","name":"androidx/lifecycle/LiveData.class","size":8921,"crc":899075882},{"key":"androidx/lifecycle/MutableLiveData.class","name":"androidx/lifecycle/MutableLiveData.class","size":946,"crc":-710747396},{"key":"META-INF/androidx.lifecycle_lifecycle-livedata-core.version","name":"META-INF/androidx.lifecycle_lifecycle-livedata-core.version","size":78,"crc":1772768774},{"key":"META-INF/lifecycle-livedata-core_release.kotlin_module","name":"META-INF/lifecycle-livedata-core_release.kotlin_module","size":24,"crc":1613429616}]

View File

@@ -0,0 +1 @@
[{"key":"META-INF/MANIFEST.MF","name":"META-INF/MANIFEST.MF","size":25,"crc":-301826126},{"key":"androidx/collection/ArrayMap$1.class","name":"androidx/collection/ArrayMap$1.class","size":2268,"crc":2119754508},{"key":"androidx/collection/ArrayMap.class","name":"androidx/collection/ArrayMap.class","size":3510,"crc":-1266570172},{"key":"androidx/collection/ArraySet$1.class","name":"androidx/collection/ArraySet$1.class","size":2270,"crc":467012598},{"key":"androidx/collection/ArraySet.class","name":"androidx/collection/ArraySet.class","size":11832,"crc":284151195},{"key":"androidx/collection/CircularArray.class","name":"androidx/collection/CircularArray.class","size":4178,"crc":-646150562},{"key":"androidx/collection/CircularIntArray.class","name":"androidx/collection/CircularIntArray.class","size":2996,"crc":-1809371816},{"key":"androidx/collection/ContainerHelpers.class","name":"androidx/collection/ContainerHelpers.class","size":1711,"crc":1459012494},{"key":"androidx/collection/LongSparseArray.class","name":"androidx/collection/LongSparseArray.class","size":7060,"crc":-249107820},{"key":"androidx/collection/LruCache.class","name":"androidx/collection/LruCache.class","size":6572,"crc":-1323386586},{"key":"androidx/collection/MapCollections$ArrayIterator.class","name":"androidx/collection/MapCollections$ArrayIterator.class","size":1678,"crc":-1282301111},{"key":"androidx/collection/MapCollections$EntrySet.class","name":"androidx/collection/MapCollections$EntrySet.class","size":4584,"crc":-1095945835},{"key":"androidx/collection/MapCollections$KeySet.class","name":"androidx/collection/MapCollections$KeySet.class","size":3760,"crc":251514751},{"key":"androidx/collection/MapCollections$MapIterator.class","name":"androidx/collection/MapCollections$MapIterator.class","size":3542,"crc":1838648568},{"key":"androidx/collection/MapCollections$ValuesCollection.class","name":"androidx/collection/MapCollections$ValuesCollection.class","size":3783,"crc":25099165},{"key":"androidx/collection/MapCollections.class","name":"androidx/collection/MapCollections.class","size":5551,"crc":525100092},{"key":"androidx/collection/SimpleArrayMap.class","name":"androidx/collection/SimpleArrayMap.class","size":10631,"crc":41097503},{"key":"androidx/collection/SparseArrayCompat.class","name":"androidx/collection/SparseArrayCompat.class","size":7216,"crc":1400669519}]

View File

@@ -0,0 +1 @@
[{"key":"androidx/annotation/OptIn.class","name":"androidx/annotation/OptIn.class","size":1252,"crc":2044678581},{"key":"androidx/annotation/RequiresOptIn$Level.class","name":"androidx/annotation/RequiresOptIn$Level.class","size":1487,"crc":-1945499205},{"key":"androidx/annotation/RequiresOptIn.class","name":"androidx/annotation/RequiresOptIn.class","size":1119,"crc":1571113326},{"key":"androidx/annotation/experimental/Experimental$Level.class","name":"androidx/annotation/experimental/Experimental$Level.class","size":1570,"crc":-1659833789},{"key":"androidx/annotation/experimental/Experimental.class","name":"androidx/annotation/experimental/Experimental.class","size":1426,"crc":-1756277940},{"key":"androidx/annotation/experimental/UseExperimental.class","name":"androidx/annotation/experimental/UseExperimental.class","size":1521,"crc":-1036664509},{"key":"META-INF/androidx.annotation_annotation-experimental.version","name":"META-INF/androidx.annotation_annotation-experimental.version","size":6,"crc":1914453823},{"key":"META-INF/annotation-experimental_release.kotlin_module","name":"META-INF/annotation-experimental_release.kotlin_module","size":24,"crc":1197092421}]

View File

@@ -0,0 +1 @@
[{"key":"androidx/lifecycle/AbstractSavedStateViewModelFactory$Companion.class","name":"androidx/lifecycle/AbstractSavedStateViewModelFactory$Companion.class","size":981,"crc":-856004234},{"key":"androidx/lifecycle/AbstractSavedStateViewModelFactory.class","name":"androidx/lifecycle/AbstractSavedStateViewModelFactory.class","size":6633,"crc":1887362684},{"key":"androidx/lifecycle/LegacySavedStateHandleController$OnRecreation.class","name":"androidx/lifecycle/LegacySavedStateHandleController$OnRecreation.class","size":3023,"crc":1352335096},{"key":"androidx/lifecycle/LegacySavedStateHandleController$tryToAddRecreator$1.class","name":"androidx/lifecycle/LegacySavedStateHandleController$tryToAddRecreator$1.class","size":2215,"crc":-1110321192},{"key":"androidx/lifecycle/LegacySavedStateHandleController.class","name":"androidx/lifecycle/LegacySavedStateHandleController.class","size":4229,"crc":2063421456},{"key":"androidx/lifecycle/SavedStateHandle$Companion.class","name":"androidx/lifecycle/SavedStateHandle$Companion.class","size":3880,"crc":-1386044437},{"key":"androidx/lifecycle/SavedStateHandle$SavingStateLiveData.class","name":"androidx/lifecycle/SavedStateHandle$SavingStateLiveData.class","size":2785,"crc":1239087543},{"key":"androidx/lifecycle/SavedStateHandle.class","name":"androidx/lifecycle/SavedStateHandle.class","size":13780,"crc":996357302},{"key":"androidx/lifecycle/SavedStateHandleAttacher.class","name":"androidx/lifecycle/SavedStateHandleAttacher.class","size":2410,"crc":-1934335314},{"key":"androidx/lifecycle/SavedStateHandleController.class","name":"androidx/lifecycle/SavedStateHandleController.class","size":3933,"crc":-1321318372},{"key":"androidx/lifecycle/SavedStateHandleSupport$DEFAULT_ARGS_KEY$1.class","name":"androidx/lifecycle/SavedStateHandleSupport$DEFAULT_ARGS_KEY$1.class","size":1015,"crc":424264501},{"key":"androidx/lifecycle/SavedStateHandleSupport$SAVED_STATE_REGISTRY_OWNER_KEY$1.class","name":"androidx/lifecycle/SavedStateHandleSupport$SAVED_STATE_REGISTRY_OWNER_KEY$1.class","size":1095,"crc":1523009794},{"key":"androidx/lifecycle/SavedStateHandleSupport$VIEW_MODEL_STORE_OWNER_KEY$1.class","name":"androidx/lifecycle/SavedStateHandleSupport$VIEW_MODEL_STORE_OWNER_KEY$1.class","size":1077,"crc":-702670968},{"key":"androidx/lifecycle/SavedStateHandleSupport$savedStateHandlesVM$1$1.class","name":"androidx/lifecycle/SavedStateHandleSupport$savedStateHandlesVM$1$1.class","size":1899,"crc":1635032056},{"key":"androidx/lifecycle/SavedStateHandleSupport.class","name":"androidx/lifecycle/SavedStateHandleSupport.class","size":9836,"crc":1960161047},{"key":"androidx/lifecycle/SavedStateHandlesProvider$viewModel$2.class","name":"androidx/lifecycle/SavedStateHandlesProvider$viewModel$2.class","size":1569,"crc":-295120749},{"key":"androidx/lifecycle/SavedStateHandlesProvider.class","name":"androidx/lifecycle/SavedStateHandlesProvider.class","size":5980,"crc":1046935854},{"key":"androidx/lifecycle/SavedStateHandlesVM.class","name":"androidx/lifecycle/SavedStateHandlesVM.class","size":1202,"crc":1705824530},{"key":"androidx/lifecycle/SavedStateViewModelFactory.class","name":"androidx/lifecycle/SavedStateViewModelFactory.class","size":8807,"crc":-1676903485},{"key":"androidx/lifecycle/SavedStateViewModelFactoryKt.class","name":"androidx/lifecycle/SavedStateViewModelFactoryKt.class","size":5061,"crc":2029493689},{"key":"META-INF/androidx.lifecycle_lifecycle-viewmodel-savedstate.version","name":"META-INF/androidx.lifecycle_lifecycle-viewmodel-savedstate.version","size":85,"crc":-1370551005},{"key":"META-INF/lifecycle-viewmodel-savedstate_release.kotlin_module","name":"META-INF/lifecycle-viewmodel-savedstate_release.kotlin_module","size":101,"crc":-1891795020}]

View File

@@ -0,0 +1 @@
[{"key":"META-INF/androidx.tracing_tracing.version","name":"META-INF/androidx.tracing_tracing.version","size":6,"crc":-42031000},{"key":"androidx/tracing/TraceApi18Impl.class","name":"androidx/tracing/TraceApi18Impl.class","size":719,"crc":-735196291},{"key":"androidx/tracing/TraceApi29Impl.class","name":"androidx/tracing/TraceApi29Impl.class","size":975,"crc":-372479716},{"key":"androidx/tracing/Trace.class","name":"androidx/tracing/Trace.class","size":4760,"crc":1193004678}]

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"key":"META-INF/MANIFEST.MF","name":"META-INF/MANIFEST.MF","size":25,"crc":-301826126},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$1.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$1.class","size":276,"crc":-940893964},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$AtomicHelper.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$AtomicHelper.class","size":2208,"crc":1918496937},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$Cancellation.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$Cancellation.class","size":1041,"crc":886782754},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$Failure$1.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$Failure$1.class","size":737,"crc":-471209672},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$Failure.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$Failure.class","size":951,"crc":-1760206701},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$Listener.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$Listener.class","size":873,"crc":402316535},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$SafeAtomicHelper.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$SafeAtomicHelper.class","size":5564,"crc":-1818562924},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$SetFuture.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$SetFuture.class","size":2033,"crc":286080067},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$SynchronizedHelper.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$SynchronizedHelper.class","size":3421,"crc":-1182687467},{"key":"androidx/concurrent/futures/AbstractResolvableFuture$Waiter.class","name":"androidx/concurrent/futures/AbstractResolvableFuture$Waiter.class","size":1723,"crc":226188834},{"key":"androidx/concurrent/futures/AbstractResolvableFuture.class","name":"androidx/concurrent/futures/AbstractResolvableFuture.class","size":18591,"crc":-370636094},{"key":"androidx/concurrent/futures/CallbackToFutureAdapter$Completer.class","name":"androidx/concurrent/futures/CallbackToFutureAdapter$Completer.class","size":3784,"crc":2035088105},{"key":"androidx/concurrent/futures/CallbackToFutureAdapter$FutureGarbageCollectedException.class","name":"androidx/concurrent/futures/CallbackToFutureAdapter$FutureGarbageCollectedException.class","size":706,"crc":-1609752935},{"key":"androidx/concurrent/futures/CallbackToFutureAdapter$Resolver.class","name":"androidx/concurrent/futures/CallbackToFutureAdapter$Resolver.class","size":831,"crc":142665041},{"key":"androidx/concurrent/futures/CallbackToFutureAdapter$SafeFuture$1.class","name":"androidx/concurrent/futures/CallbackToFutureAdapter$SafeFuture$1.class","size":1829,"crc":555402729},{"key":"androidx/concurrent/futures/CallbackToFutureAdapter$SafeFuture.class","name":"androidx/concurrent/futures/CallbackToFutureAdapter$SafeFuture.class","size":3934,"crc":1212043617},{"key":"androidx/concurrent/futures/CallbackToFutureAdapter.class","name":"androidx/concurrent/futures/CallbackToFutureAdapter.class","size":2370,"crc":1014408157},{"key":"androidx/concurrent/futures/DirectExecutor.class","name":"androidx/concurrent/futures/DirectExecutor.class","size":1661,"crc":-2104738324},{"key":"androidx/concurrent/futures/ResolvableFuture.class","name":"androidx/concurrent/futures/ResolvableFuture.class","size":1867,"crc":-254057077}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"key":"androidx/arch/core/executor/ArchTaskExecutor.class","name":"androidx/arch/core/executor/ArchTaskExecutor.class","size":2950,"crc":-173664277},{"key":"androidx/arch/core/executor/DefaultTaskExecutor$1.class","name":"androidx/arch/core/executor/DefaultTaskExecutor$1.class","size":1445,"crc":-1550744660},{"key":"androidx/arch/core/executor/DefaultTaskExecutor$Api28Impl.class","name":"androidx/arch/core/executor/DefaultTaskExecutor$Api28Impl.class","size":834,"crc":1774766260},{"key":"androidx/arch/core/executor/DefaultTaskExecutor.class","name":"androidx/arch/core/executor/DefaultTaskExecutor.class","size":3293,"crc":-1256626107},{"key":"androidx/arch/core/executor/TaskExecutor.class","name":"androidx/arch/core/executor/TaskExecutor.class","size":1053,"crc":1399542030},{"key":"META-INF/androidx.arch.core_core-runtime.version","name":"META-INF/androidx.arch.core_core-runtime.version","size":67,"crc":1307063212}]

View File

@@ -0,0 +1 @@
[{"key":"META-INF/MANIFEST.MF","name":"META-INF/MANIFEST.MF","size":25,"crc":-301826126},{"key":"androidx/arch/core/internal/FastSafeIterableMap.class","name":"androidx/arch/core/internal/FastSafeIterableMap.class","size":2907,"crc":2116950419},{"key":"androidx/arch/core/internal/SafeIterableMap$AscendingIterator.class","name":"androidx/arch/core/internal/SafeIterableMap$AscendingIterator.class","size":1775,"crc":-347866117},{"key":"androidx/arch/core/internal/SafeIterableMap$DescendingIterator.class","name":"androidx/arch/core/internal/SafeIterableMap$DescendingIterator.class","size":1779,"crc":1644932214},{"key":"androidx/arch/core/internal/SafeIterableMap$Entry.class","name":"androidx/arch/core/internal/SafeIterableMap$Entry.class","size":2378,"crc":1824924906},{"key":"androidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions.class","name":"androidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions.class","size":2551,"crc":1452189535},{"key":"androidx/arch/core/internal/SafeIterableMap$ListIterator.class","name":"androidx/arch/core/internal/SafeIterableMap$ListIterator.class","size":2977,"crc":-1002357144},{"key":"androidx/arch/core/internal/SafeIterableMap$SupportRemove.class","name":"androidx/arch/core/internal/SafeIterableMap$SupportRemove.class","size":1208,"crc":1494321347},{"key":"androidx/arch/core/internal/SafeIterableMap.class","name":"androidx/arch/core/internal/SafeIterableMap.class","size":7303,"crc":1636361416},{"key":"androidx/arch/core/util/Function.class","name":"androidx/arch/core/util/Function.class","size":280,"crc":896912248}]

View File

@@ -0,0 +1 @@
[{"key":"META-INF/MANIFEST.MF","name":"META-INF/MANIFEST.MF","size":225,"crc":1808098489},{"key":"META-INF/versions/9/module-info.class","name":"META-INF/versions/9/module-info.class","size":257,"crc":-1911524020}]

View File

@@ -0,0 +1 @@
[{"key":"META-INF/MANIFEST.MF","name":"META-INF/MANIFEST.MF","size":108,"crc":1316044605},{"key":"com/google/common/util/concurrent/ListenableFuture.class","name":"com/google/common/util/concurrent/ListenableFuture.class","size":358,"crc":-1374437012},{"key":"META-INF/maven/com.google.guava/listenablefuture/pom.xml","name":"META-INF/maven/com.google.guava/listenablefuture/pom.xml","size":2226,"crc":65817035},{"key":"META-INF/maven/com.google.guava/listenablefuture/pom.properties","name":"META-INF/maven/com.google.guava/listenablefuture/pom.properties","size":96,"crc":1661854904}]

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"key":"androidx/lifecycle/LifecycleRegistry$Companion.class","name":"androidx/lifecycle/LifecycleRegistry$Companion.class","size":2203,"crc":881149842},{"key":"androidx/lifecycle/LifecycleRegistry$ObserverWithState.class","name":"androidx/lifecycle/LifecycleRegistry$ObserverWithState.class","size":3221,"crc":577649636},{"key":"androidx/lifecycle/LifecycleRegistry.class","name":"androidx/lifecycle/LifecycleRegistry.class","size":11316,"crc":1825754494},{"key":"androidx/lifecycle/ReportFragment$ActivityInitializationListener.class","name":"androidx/lifecycle/ReportFragment$ActivityInitializationListener.class","size":672,"crc":137325557},{"key":"androidx/lifecycle/ReportFragment$Companion.class","name":"androidx/lifecycle/ReportFragment$Companion.class","size":3889,"crc":353864254},{"key":"androidx/lifecycle/ReportFragment$LifecycleCallbacks$Companion.class","name":"androidx/lifecycle/ReportFragment$LifecycleCallbacks$Companion.class","size":1657,"crc":-2035159275},{"key":"androidx/lifecycle/ReportFragment$LifecycleCallbacks.class","name":"androidx/lifecycle/ReportFragment$LifecycleCallbacks.class","size":4134,"crc":-1042517223},{"key":"androidx/lifecycle/ReportFragment.class","name":"androidx/lifecycle/ReportFragment.class","size":4770,"crc":-1685581092},{"key":"androidx/lifecycle/ViewTreeLifecycleOwner$findViewTreeLifecycleOwner$1.class","name":"androidx/lifecycle/ViewTreeLifecycleOwner$findViewTreeLifecycleOwner$1.class","size":1786,"crc":1189804573},{"key":"androidx/lifecycle/ViewTreeLifecycleOwner$findViewTreeLifecycleOwner$2.class","name":"androidx/lifecycle/ViewTreeLifecycleOwner$findViewTreeLifecycleOwner$2.class","size":1957,"crc":1482960673},{"key":"androidx/lifecycle/ViewTreeLifecycleOwner.class","name":"androidx/lifecycle/ViewTreeLifecycleOwner.class","size":2382,"crc":-1814616098},{"key":"androidx/lifecycle/LifecycleRegistryOwner.class","name":"androidx/lifecycle/LifecycleRegistryOwner.class","size":628,"crc":-858790333},{"key":"META-INF/androidx.lifecycle_lifecycle-runtime.version","name":"META-INF/androidx.lifecycle_lifecycle-runtime.version","size":72,"crc":1585985631},{"key":"META-INF/lifecycle-runtime_release.kotlin_module","name":"META-INF/lifecycle-runtime_release.kotlin_module","size":70,"crc":1413782649}]

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
#Sun May 10 10:16:07 CST 2026
blog.wiwi.hoops.app-main-19\:/drawable/ic_launcher_foreground.xml=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/drawable_ic_launcher_foreground.xml.flat
blog.wiwi.hoops.app-main-19\:/drawable/splash_icon.xml=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/drawable_splash_icon.xml.flat
blog.wiwi.hoops.app-main-19\:/mipmap-anydpi-v26/ic_launcher.xml=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-anydpi-v26_ic_launcher.xml.flat
blog.wiwi.hoops.app-main-19\:/mipmap-anydpi-v26/ic_launcher_round.xml=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-anydpi-v26_ic_launcher_round.xml.flat
blog.wiwi.hoops.app-main-19\:/mipmap-hdpi/ic_launcher.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-hdpi_ic_launcher.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-hdpi/ic_launcher_round.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-hdpi_ic_launcher_round.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-mdpi/ic_launcher.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-mdpi_ic_launcher.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-mdpi/ic_launcher_round.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-mdpi_ic_launcher_round.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-xhdpi/ic_launcher.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-xhdpi_ic_launcher.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-xhdpi/ic_launcher_round.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-xhdpi_ic_launcher_round.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-xxhdpi/ic_launcher.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-xxhdpi_ic_launcher.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-xxhdpi/ic_launcher_round.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-xxhdpi_ic_launcher_round.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-xxxhdpi/ic_launcher.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-xxxhdpi_ic_launcher.png.flat
blog.wiwi.hoops.app-main-19\:/mipmap-xxxhdpi/ic_launcher_round.png=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/mipmap-xxxhdpi_ic_launcher_round.png.flat
blog.wiwi.hoops.app-main-19\:/xml/backup_rules.xml=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/xml_backup_rules.xml.flat
blog.wiwi.hoops.app-main-19\:/xml/data_extraction_rules.xml=/home/wiwi/Documents/Hoops-android/hoops-android/app/build/intermediates/merged_res/debug/mergeDebugResources/xml_data_extraction_rules.xml.flat

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Antwoord"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Video"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"Wys af"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Lui af"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Inkomende oproep"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Oproep aan die gang"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"Keur tans \'n inkomende oproep"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"መልስ"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"ቪዲዮ"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"አትቀበል"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"ስልኩን ዝጋ"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"ገቢ ጥሪ"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"እየተካሄደ ያለ ጥሪ"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"ገቢ ጥሪ ማጣራት"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"ردّ"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"فيديو"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"رفض"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"قطع الاتصال"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"مكالمة واردة"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"مكالمة جارية"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"يتم فحص المكالمة الواردة"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"উত্তৰ দিয়ক"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"ভিডিঅ’"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"প্ৰত্যাখ্যান কৰক"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"কল কাটি দিয়ক"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"অন্তৰ্গামী কল"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"চলি থকা কল"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"এটা অন্তৰ্গামী কলৰ পৰীক্ষা কৰি থকা হৈছে"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"৯৯৯+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Cavab verin"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Video"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"İmtina edin"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Dəstəyi asın"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Gələn zəng"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Davam edən zəng"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"Gələn zəng göstərilir"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Odgovori"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Video"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"Odbij"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Prekini vezu"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Dolazni poziv"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Poziv je u toku"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"Proverava se dolazni poziv"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Адказаць"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Відэа"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"Адхіліць"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Завяршыць"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Уваходны выклік"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Бягучы выклік"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"Фільтраванне ўваходнага выкліку"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Отговор"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Видеообаждане"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"Отхвърляне"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Затваряне"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Входящо обаждане"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Текущо обаждане"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"Преглежда се входящо обаждане"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"উত্তর দিন"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"ভিডিও"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"বাতিল করুন"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"কল কেটে দিন"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"ইনকামিং কল"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"চালু থাকা কল"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"ইনকামিং কল স্ক্রিনিং করা হচ্ছে"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"৯৯৯+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Odgovori"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Video"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"Odbaci"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Prekini vezu"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Dolazni poziv"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Poziv u toku"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"Filtriranje dolaznog poziva"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Respon"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Vídeo"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"Rebutja"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Penja"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Trucada entrant"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Trucada en curs"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"S\'està filtrant una trucada entrant"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string msgid="881409763997275156" name="call_notification_answer_action">"Přijmout"</string>
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Video"</string>
<string msgid="3229508546291798546" name="call_notification_decline_action">"Odmítnout"</string>
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Zavěsit"</string>
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Příchozí hovor"</string>
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Probíhající hovor"</string>
<string msgid="59049573811482460" name="call_notification_screening_text">"Prověřování příchozího hovoru"</string>
<string msgid="6277540029070332960" name="status_bar_notification_info_overflow">"999+"</string>
</resources>

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