Initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
21
app/build/intermediates/apk/debug/output-metadata.json
Normal file
21
app/build/intermediates/apk/debug/output-metadata.json
Normal 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
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#- File Locator -
|
||||
listingFile=../../../../outputs/apk/debug/output-metadata.json
|
||||
@@ -0,0 +1,2 @@
|
||||
#- File Locator -
|
||||
listingFile=../../../../outputs/apk/androidTest/debug/output-metadata.json
|
||||
@@ -0,0 +1,2 @@
|
||||
#- File Locator -
|
||||
listingFile=../../../../../release/output-metadata.json
|
||||
@@ -0,0 +1,2 @@
|
||||
appMetadataVersion=1.1
|
||||
androidGradlePluginVersion=8.13.2
|
||||
@@ -0,0 +1,2 @@
|
||||
appMetadataVersion=1.1
|
||||
androidGradlePluginVersion=8.13.2
|
||||
881
app/build/intermediates/assets/debug/mergeDebugAssets/index.html
Normal file
881
app/build/intermediates/assets/debug/mergeDebugAssets/index.html
Normal 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>
|
||||
@@ -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>
|
||||
Binary file not shown.
Binary file not shown.
@@ -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;->**(**)**
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 3,
|
||||
"artifactType": {
|
||||
"type": "COMPATIBLE_SCREEN_MANIFEST",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "blog.wiwi.hoops",
|
||||
"variantName": "debug",
|
||||
"elements": []
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 3,
|
||||
"artifactType": {
|
||||
"type": "COMPATIBLE_SCREEN_MANIFEST",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "blog.wiwi.hoops",
|
||||
"variantName": "release",
|
||||
"elements": []
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"options":{"minApiLevel":"24","isDebugModeEnabled":false},"version":"8.13.19"}
|
||||
@@ -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.**
|
||||
@@ -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.**
|
||||
@@ -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.**
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/build/intermediates/dex/debug/mergeExtDexDebug/classes.dex
Normal file
BIN
app/build/intermediates/dex/debug/mergeExtDexDebug/classes.dex
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/build/intermediates/dex/release/mergeDexRelease/classes.dex
Normal file
BIN
app/build/intermediates/dex/release/mergeDexRelease/classes.dex
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
31=0/.dm
|
||||
2147483647=0/.dm
|
||||
28=1/.dm
|
||||
29=1/.dm
|
||||
30=1/.dm
|
||||
@@ -0,0 +1 @@
|
||||
3
|
||||
@@ -0,0 +1 @@
|
||||
3
|
||||
@@ -0,0 +1 @@
|
||||
3
|
||||
Binary file not shown.
Binary file not shown.
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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
@@ -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}]
|
||||
@@ -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
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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
@@ -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
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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}]
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string msgid="881409763997275156" name="call_notification_answer_action">"Besvar"</string>
|
||||
<string msgid="8793775615905189152" name="call_notification_answer_video_action">"Video"</string>
|
||||
<string msgid="3229508546291798546" name="call_notification_decline_action">"Afvis"</string>
|
||||
<string msgid="2659457946726154263" name="call_notification_hang_up_action">"Læg på"</string>
|
||||
<string msgid="6107532579223922871" name="call_notification_incoming_text">"Indgående opkald"</string>
|
||||
<string msgid="8623827134497363134" name="call_notification_ongoing_text">"Igangværende opkald"</string>
|
||||
<string msgid="59049573811482460" name="call_notification_screening_text">"Et indgående opkald screenes"</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
Reference in New Issue
Block a user