rebuild translations

This commit is contained in:
zjs81
2026-08-11 00:15:45 -07:00
parent eee72b4c65
commit cf6c93c50a
63 changed files with 6584 additions and 4040 deletions
+16 -19
View File
@@ -384,7 +384,8 @@ class ImageChunkHeader {
bool get isParity => index == total;
@override
String toString() => 'ImageChunkHeader(sender: 0x'
String toString() =>
'ImageChunkHeader(sender: 0x'
'${senderPrefix.toRadixString(16).padLeft(4, '0')}, img: $imgId, '
'idx: $index/$total${isParity ? ' parity' : ''})';
}
@@ -549,7 +550,7 @@ class ImageIdAllocator {
int _next;
ImageIdAllocator({int? seed, math.Random? random})
: _next = seed ?? (random ?? math.Random()).nextInt(256);
: _next = seed ?? (random ?? math.Random()).nextInt(256);
int next() {
final id = _next & 0xFF;
@@ -585,7 +586,8 @@ class ImageStreamKey {
int get hashCode => Object.hash(senderPrefix, imgId, channelIndex);
@override
String toString() => 'ImageStreamKey(0x'
String toString() =>
'ImageStreamKey(0x'
'${senderPrefix.toRadixString(16).padLeft(4, '0')}/$imgId@$channelIndex)';
}
@@ -625,7 +627,6 @@ enum ImageReassemblyFailureReason {
/// Evicted to keep the pending map inside its size cap.
overflow,
/// Reassembled but the metadata byte was undecodable
/// ([ImageChunkStatus.unsupportedFormat]).
unsupportedFormat,
@@ -647,7 +648,6 @@ class ImageReassemblyResult {
/// Number of data chunks in the image.
final int chunkCount;
const ImageReassemblyResult({
required this.key,
required this.metadata,
@@ -688,7 +688,8 @@ class ImageReassemblyFailure {
reason == ImageReassemblyFailureReason.unsupportedFormat;
@override
String toString() => 'ImageReassemblyFailure($key, '
String toString() =>
'ImageReassemblyFailure($key, '
'$receivedDataChunks/$total, parity: $hadParity, ${reason.name})';
}
@@ -966,11 +967,7 @@ class ImageReassembler {
),
);
}
return ImageChunkOutcome(
finish.status,
header: header,
result: result,
);
return ImageChunkOutcome(finish.status, header: header, result: result);
}
return ImageChunkOutcome(
conflicted ? ImageChunkStatus.conflicting : ImageChunkStatus.accepted,
@@ -1061,8 +1058,10 @@ class ImageReassembler {
if (!entry.isRecoverable) return null;
// Exactly one data chunk missing and we hold parity: rebuild it.
final missing =
List<int>.generate(entry.total, (i) => i).firstWhere((i) => !entry.bodies.containsKey(i));
final missing = List<int>.generate(
entry.total,
(i) => i,
).firstWhere((i) => !entry.bodies.containsKey(i));
final parity = entry.parityBody!;
var lengthXor = parity[0] & 0xFF;
final xor = Uint8List(kImageChunkBodyBytes);
@@ -1134,8 +1133,8 @@ class _FinishOutcome {
const _FinishOutcome.failed(this.status, this.reason) : result = null;
const _FinishOutcome.delivered(ImageReassemblyResult this.result)
: status = ImageChunkStatus.completed,
reason = null;
: status = ImageChunkStatus.completed,
reason = null;
}
bool _sameBytes(Uint8List a, Uint8List b) {
@@ -1232,10 +1231,8 @@ ParsedChannelData? parseChannelDataFrame(Uint8List frame) {
///
/// Implemented by the connector-facing adapter; kept as a typedef so the
/// transport itself never imports the connector (and stays testable).
typedef ChannelBlobSender = Future<void> Function(
Uint8List blob,
int channelIndex,
);
typedef ChannelBlobSender =
Future<void> Function(Uint8List blob, int channelIndex);
/// Progress report while an image is going out.
class ImageSendProgress {
+16 -8
View File
@@ -300,9 +300,15 @@ class OnnxImageCodecBackend implements ImageCodecBackend {
// The path must be the `.onnx` graph, with its `.onnx.data`
// external-weights sibling present in the same directory under exactly the
// filename the graph records. See `ImageCodecModelSpec`.
final session = await _runtime.createSession(_requireBundle().decoderGraphPath);
final session = await _runtime.createSession(
_requireBundle().decoderGraphPath,
);
_decoder = session;
_inputName = _pick(session.inputNames, kImageCodecDecoderInputName, 'input');
_inputName = _pick(
session.inputNames,
kImageCodecDecoderInputName,
'input',
);
_outputName = _pick(
session.outputNames,
kImageCodecDecoderOutputName,
@@ -735,9 +741,10 @@ class OnnxAeicEntropyNetwork implements AeicEntropyNetwork {
Float32List(kBaseElements),
kBaseShape,
),
kStageInput: await OrtValue.fromList(Int32List.fromList(<int>[
kHyperStage,
]), <int>[1]),
kStageInput: await OrtValue.fromList(
Int32List.fromList(<int>[kHyperStage]),
<int>[1],
),
});
try {
return await _floats(result, kBase0Output);
@@ -766,9 +773,10 @@ class OnnxAeicEntropyNetwork implements AeicEntropyNetwork {
final result = await _run(session, <String, OrtValue>{
kZqInput: await OrtValue.fromList(Float32List(kZqElements), kZqShape),
kBaseInput: await OrtValue.fromList(base, kBaseShape),
kStageInput: await OrtValue.fromList(Int32List.fromList(<int>[
stage,
]), <int>[1]),
kStageInput: await OrtValue.fromList(
Int32List.fromList(<int>[stage]),
<int>[1],
),
});
try {
// Already masked by the graph. `AeicEntropyCodec` masks again, which is
+7 -4
View File
@@ -239,9 +239,8 @@ class AeicMaskSet {
for (var y = 0; y < geometry.yHeight; y++) {
for (var x = 0; x < w; x++) {
final group = liveGroupAt(stage, y, x);
out[(group * cq + c) * plane + y * w + x] = squeezed[c * plane +
y * w +
x];
out[(group * cq + c) * plane + y * w + x] =
squeezed[c * plane + y * w + x];
}
}
}
@@ -272,7 +271,11 @@ class AeicMaskSet {
///
/// `stageLatent` must already be masked (it is the output of [unsqueeze]), so
/// this is a select, not an add — which is what keeps it exact in float32.
Float32List mergeContext(Float32List base, Float32List stageLatent, int stage) {
Float32List mergeContext(
Float32List base,
Float32List stageLatent,
int stage,
) {
final out = Float32List.fromList(base);
final plane = geometry.yHeight * geometry.yWidth;
final cq = geometry.squeezedChannels;
+21 -7
View File
@@ -4,7 +4,9 @@ import '../models/image_codec_support.dart';
class ImageCodecFileStore {
Future<String> modelDirectoryPath() async {
throw UnsupportedError('Local codec model storage is not supported on web.');
throw UnsupportedError(
'Local codec model storage is not supported on web.',
);
}
Future<List<ImageCodecModelRecord>> scanDownloadedModels() async {
@@ -19,15 +21,21 @@ class ImageCodecFileStore {
required String fileName,
required Stream<List<int>> chunks,
}) async {
throw UnsupportedError('Local codec model storage is not supported on web.');
throw UnsupportedError(
'Local codec model storage is not supported on web.',
);
}
Future<String> chunkFilePath(String fileName, int index) async {
throw UnsupportedError('Local codec model storage is not supported on web.');
throw UnsupportedError(
'Local codec model storage is not supported on web.',
);
}
Future<String> modelFilePath(String fileName) async {
throw UnsupportedError('Local codec model storage is not supported on web.');
throw UnsupportedError(
'Local codec model storage is not supported on web.',
);
}
Future<void> deletePartialDownloads(String fileName) async {}
@@ -38,11 +46,15 @@ class ImageCodecFileStore {
required String path,
required Stream<List<int>> chunks,
}) async {
throw UnsupportedError('Local codec model storage is not supported on web.');
throw UnsupportedError(
'Local codec model storage is not supported on web.',
);
}
Future<String> sha256OfFile(String path) async {
throw UnsupportedError('Local codec model storage is not supported on web.');
throw UnsupportedError(
'Local codec model storage is not supported on web.',
);
}
Future<Uint8List> readFileBytes(String path) async {
@@ -53,7 +65,9 @@ class ImageCodecFileStore {
required String fileName,
required List<String> chunkPaths,
}) async {
throw UnsupportedError('Local codec model storage is not supported on web.');
throw UnsupportedError(
'Local codec model storage is not supported on web.',
);
}
}
+7 -5
View File
@@ -285,7 +285,10 @@ class ImageCodecService extends ChangeNotifier implements ImageSendCodec {
final spec = _specForId(model.id);
final directory = _directoryOf(model.localPath);
String? pathFor(ImageCodecAssetRole role, bool Function(String) looksRight) {
String? pathFor(
ImageCodecAssetRole role,
bool Function(String) looksRight,
) {
// 1. What the installer recorded this file AS. Exact, and the only source
// that can tell the two entropy graphs apart.
final recorded = model.fileNameForRole(role);
@@ -430,7 +433,8 @@ class ImageCodecService extends ChangeNotifier implements ImageSendCodec {
assetFileNames: present,
assetRoles: {
for (final asset in spec.assets)
if (onDisk.containsKey(asset.fileName)) asset.fileName: asset.role,
if (onDisk.containsKey(asset.fileName))
asset.fileName: asset.role,
},
bundleVersion: complete ? kImageCodecBundleVersion : 0,
),
@@ -669,9 +673,7 @@ class ImageCodecService extends ChangeNotifier implements ImageSendCodec {
// The only place the role of each downloaded file is known for
// certain. Recorded now so nothing downstream has to infer it from a
// filename see [ImageCodecModelRecord.assetRoles].
assetRoles: {
for (final asset in assets) asset.fileName: asset.role,
},
assetRoles: {for (final asset in assets) asset.fileName: asset.role},
bundleVersion: bundleVersion,
);
final updated = [
+4 -1
View File
@@ -61,7 +61,10 @@ class PrefsImageCodecSettingsStore implements ImageCodecSettingsStore {
_preferences = preferences;
_loaded = true;
try {
await PrefsManager.instance.setString(_key, jsonEncode(preferences.toJson()));
await PrefsManager.instance.setString(
_key,
jsonEncode(preferences.toJson()),
);
} catch (error) {
appLogger.warn('Image codec settings save failed: $error');
}
+14 -4
View File
@@ -85,7 +85,9 @@ class FileReceivedImageBlobStore implements ReceivedImageBlobStore {
Future<String> _resolve() async {
final base = await _baseDirectory();
final dir = Directory('${base.path}${Platform.pathSeparator}$directoryName');
final dir = Directory(
'${base.path}${Platform.pathSeparator}$directoryName',
);
if (!dir.existsSync()) {
await dir.create(recursive: true);
}
@@ -112,7 +114,11 @@ class FileReceivedImageBlobStore implements ReceivedImageBlobStore {
}
}
Future<void> _write(String streamId, String extension, Uint8List bytes) async {
Future<void> _write(
String streamId,
String extension,
Uint8List bytes,
) async {
try {
final path = await _pathFor(streamId, extension);
if (path == null) {
@@ -121,7 +127,9 @@ class FileReceivedImageBlobStore implements ReceivedImageBlobStore {
}
await File(path).writeAsBytes(bytes, flush: true);
} catch (error) {
debugPrint('received_image_blob_store: write $streamId$extension: $error');
debugPrint(
'received_image_blob_store: write $streamId$extension: $error',
);
}
}
@@ -132,7 +140,9 @@ class FileReceivedImageBlobStore implements ReceivedImageBlobStore {
final file = File(path);
if (file.existsSync()) await file.delete();
} catch (error) {
debugPrint('received_image_blob_store: delete $streamId$extension: $error');
debugPrint(
'received_image_blob_store: delete $streamId$extension: $error',
);
}
}
+10 -6
View File
@@ -74,7 +74,8 @@ class ReceivedImageRef {
static String encode(String streamId) => '$scheme$streamId';
/// Returns the stream id, or null when [text] is not an image sentinel.
static String? parse(String text) => _pattern.firstMatch(text.trim())?.group(1);
static String? parse(String text) =>
_pattern.firstMatch(text.trim())?.group(1);
/// `%04x%02x%08x` 4 hex sender prefix, 2 hex img id, 8 hex epoch seconds.
///
@@ -391,7 +392,8 @@ abstract class ReceivedImageBlobStore {
(await readBitstream(streamId))?.length;
/// Byte length of the stored PNG, or null when there is none.
Future<int?> pngSize(String streamId) async => (await readPng(streamId))?.length;
Future<int?> pngSize(String streamId) async =>
(await readPng(streamId))?.length;
/// Sidecar write must be atomic (tmp + rename) so a kill cannot leave a
/// half-written record that `readSidecars` then discards.
@@ -574,7 +576,8 @@ class ReceivedImageStore extends ChangeNotifier {
final DateTime Function() _clock;
final Map<String, ReceivedImageEntry> _entries = <String, ReceivedImageEntry>{};
final Map<String, ReceivedImageEntry> _entries =
<String, ReceivedImageEntry>{};
final Map<ImageStreamKey, String> _byKey = <ImageStreamKey, String>{};
final Map<String, ValueNotifier<ReceivedImageEntry?>> _listenables =
<String, ValueNotifier<ReceivedImageEntry?>>{};
@@ -636,8 +639,7 @@ class ReceivedImageStore extends ChangeNotifier {
int get totalBytes =>
_entries.values.fold<int>(0, (sum, e) => sum + e.storedBytes);
int get storedImageCount =>
_entries.values.where((e) => e.pngStored).length;
int get storedImageCount => _entries.values.where((e) => e.pngStored).length;
/// Stream ids waiting for an automatic decode, oldest request first.
List<String> get decodeQueue => List<String>.unmodifiable(_queue);
@@ -1271,7 +1273,9 @@ class ReceivedImageStore extends ChangeNotifier {
if (!entry.pngStored) return null;
final bytes = await blobs.readPng(streamId);
if (bytes == null) {
await _store(entry.copyWith(state: ReceivedImageState.evicted, pngStored: false));
await _store(
entry.copyWith(state: ReceivedImageState.evicted, pngStored: false),
);
return null;
}
await _store(entry.copyWith(pngBytes: bytes, pngByteCount: bytes.length));