import 'dart:math' as math; import 'package:flutter/services.dart'; String bytesToSize(int bytes) { if (bytes == 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; final i = (math.log(bytes) / math.log(k)).floor(); return '${(bytes / math.pow(k, i)).toStringAsFixed(2)} ${sizes[i]}'; } const Map> _copyCommandLineProxyTypes = { 'cmd': {'prefix': 'set ', 'quot': '', 'join': '&&'}, 'bash': {'prefix': 'export ', 'quot': '"', 'join': ' && '}, 'powershell': {'prefix': '\$env:', 'quot': '"', 'join': ';'}, }; Future copyCommandLineProxy(String type, {String? http, String? https}) async { final types = _copyCommandLineProxyTypes[type]; if (types == null) return; final prefix = types['prefix']!; final quot = types['quot']!; final join = types['join']!; List commands = []; if (http != null) commands.add('${prefix}http_proxy=${quot}http://$http$quot'); if (https != null) commands.add('${prefix}https_proxy=${quot}http://$https$quot'); if (commands.isNotEmpty) await Clipboard.setData(ClipboardData(text: commands.join(join))); } extension OrNull on T { T? orNull(bool a) { return a ? this : null; } } extension BindOne on R Function(T a) { R Function() bindOne(T a) { return () => this(a); } } extension BindFirst on R Function(T a, T2 b) { R Function(T2 b) bindFirst(T a) { return (T2 b) => this(a, b); } } extension MapIndex on List { List mapIndex(R Function(int index, T item) fn) { final List list = []; for (int idx = 0; idx < length; idx++) { list.add(fn(idx, this[idx])); } return list; } } enum RunningState { starting, running, stopping, stoped, error, }