import 'dart:async'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter_flow_chart/flutter_flow_chart.dart'; import 'package:oc_front/models/abstract.dart'; const List _emptyComputing = []; const List _emptyData = []; const List _emptyCompute = []; const List _emptyStorage = []; class Search extends SerializerDeserializer { Search({ this.computing = _emptyComputing, this.compute = _emptyCompute, this.data = _emptyData, this.storage = _emptyStorage, }); List computing; List compute; List data; List storage; @override deserialize(dynamic json) { json = json as Map; return Search( computing: json.containsKey("processing") ? fromListJson(json["processing"], ProcessingItem()) : [], compute: json.containsKey("compute") ? fromListJson(json["compute"], ComputeItem()) : [], data: json.containsKey("data") ? fromListJson(json["data"], DataItem()) : [], storage: json.containsKey("storage") ? fromListJson(json["storage"], StorageItem()) : [], ); } @override Map serialize() => { "processing": toListJson(computing), "compute": toListJson(compute), "data": toListJson(data), "storage": toListJson(storage), }; } const List _empty = []; class Resource implements SerializerDeserializer { List datas = []; List processings = []; List storages = []; List computes = []; List workflows = []; Resource({ this.datas = const [], this.processings = const [], this.storages = const [], this.computes = const [], this.workflows = const [], }); @override Resource deserialize(json) { try { json = json as Map; } catch (e) { return Resource(); } return Resource( computes: json.containsKey("compute_resource") ? fromListJson(json["compute_resource"], ComputeItem()) : [], datas: json.containsKey("data_resource") ? fromListJson(json["data_resource"], DataItem()) : [], processings: json.containsKey("processing_resource") ? fromListJson(json["processing_resource"], ProcessingItem()) : [], storages: json.containsKey("storage_resource") ? fromListJson(json["storage_resource"], StorageItem()) : [], workflows: json.containsKey("workflow_resource") ? fromListJson(json["workflow_resource"], WorkflowItem()) : [], ); } @override Map serialize() { return { "compute_resource": toListJson(computes), "data_resource": toListJson(datas), "processing_resource": toListJson(processings), "storage_resource": toListJson(storages), "workflow_resource": toListJson(workflows), }; } } abstract class AbstractItem extends FlowData implements SerializerDeserializer { String? id; String? name; String? logo; String? owner; String? ownerLogo; String? source; String? description; String? shortDescription; double? price; String? licence; List inputs = []; List outputs = []; ResourceModel? model; String topic = ""; AbstractItem({ this.id, this.name, this.logo, this.owner, this.ownerLogo, this.price, this.source, this.licence, this.description, this.model, this.shortDescription, this.inputs = const [], this.outputs = const [], }); @override String getID() { return id ?? ""; } @override String getName() { return name ?? ""; } } class Model extends SerializerDeserializer { dynamic value; String? type; bool readonly = false; Model({ this.value, this.type, this.readonly = false, }); @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return Model(); } return Model( value: json.containsKey("value") ? json["value"] : null, type: json.containsKey("type") ? json["type"] : null, readonly: json.containsKey("readonly") ? json["readonly"] : false, ); } @override Map serialize() => { "value": value, "type": type, "readonly": readonly, }; } class ResourceModel extends SerializerDeserializer { String? id; String? type; Map refs; Map>? model; ResourceModel({ this.id, this.type, this.refs = const {}, this.model, }); @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return ResourceModel(); } var w = ResourceModel( id: json.containsKey("id") ? json["id"] : null, type: json.containsKey("type") ? json["type"] : null, refs: json.containsKey("var_refs") ? json["var_refs"] : {}, ); if (json.containsKey("model")) { w.model = {}; for (var key in (json["model"] as Map).keys) { w.model![key] = {}; for (var k2 in (json["model"][key] as Map).keys) { w.model![key]![k2] = Model().deserialize(json["model"][key][k2]); } } } return w; } @override Map serialize() { Map t = { "id": id, "type": type, "var_refs": refs, }; t["model"] = {}; if (model != null) { for (var key in model!.keys) { t["model"][key] = {}; for (var k2 in model![key]!.keys) { t["model"][key]![k2] = model![key]![k2]!.serialize(); } } } return t; } } Type? getTopicType(String topic) { if (topic == "processing") { return ProcessingItem; } else if (topic == "data") { return DataItem; } else if (topic == "compute") { return ComputeItem; } else if (topic == "storage") { return StorageItem; } else if (topic == "workflow") { return WorkflowItem; } else { return null; } } String getTopic(Type type) { if (type == AbstractItem) { return "resource"; } if (type == ProcessingItem) { return "processing"; } if (type == DataItem) { return "data"; } if (type == ComputeItem) { return "compute"; } if (type == StorageItem) { return "storage"; } if (type == WorkflowItem) { return "workflow"; } return ""; } bool isComputing(String topic) => topic == "processing"; bool isData(String topic) => topic == "data"; bool isCompute(String topic) => topic == "compute"; bool isStorage(String topic) => topic == "storage"; bool isWorkflow(String topic) => topic == "workflow"; class Expose extends SerializerDeserializer { Expose({ this.PAT, this.port, this.path, }); int? port; int? PAT; String? path; @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return Expose(); } return Expose( port: json.containsKey("port") ? json["port"] : null, PAT: json.containsKey("PAT") ? json["PAT"] : null, path: json.containsKey("reverse") ? json["reverse"] : null, ); } @override Map serialize() => { "port": port, "PAT": PAT, "reverse": path, }; } class Containered extends SerializerDeserializer { Containered({ this.image, this.args, this.command, this.env, this.volumes, }); String? args; String? image; String? command; Map? env; Map? volumes; @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return Containered(); } return Containered( args: json.containsKey("args") ? json["args"] : null, image: json.containsKey("image") ? json["image"] : null, command: json.containsKey("command") ? json["command"] : null, env: json.containsKey("env") ? json["env"] : null, volumes: json.containsKey("volumes") ? json["volumes"] : null, ); } @override Map serialize() { var w = { "args": args, "image": image, "command": command, "env": env, "volumes": volumes, }; return w; } } class ProcessingItem extends SerializerDeserializer implements AbstractItem { ProcessingItem({ this.id, this.name, this.logo, this.owner, this.ownerLogo, this.price, this.source, this.licence, this.description, this.shortDescription, this.inputs = _empty, this.outputs = _empty, this.cpus = const [], this.gpus = const [], this.ram, this.storage, this.parrallel = false, this.scallingModel, this.diskIO, this.expose = const [], this.container, this.model, }); @override ResourceModel? model; @override String? id; @override String? name; @override String? logo; @override String? source; @override String? ownerLogo; @override String? owner; @override String topic = "processing"; @override double? price; @override String? licence; @override List inputs; @override List outputs; @override String? description; @override String? shortDescription; Containered? container; List expose = []; // Special Attributes List cpus = []; List gpus = []; RAM? ram; int? storage; bool parrallel = false; int? scallingModel; String? diskIO; @override String getID() { return id ?? ""; } @override String getName() { return name ?? ""; } double? width; double? height; @override double? getWidth() { return width; } @override double? getHeight() { return height; } @override Map setVariable(List keys, dynamic value, Map map) { if (keys.isEmpty) { return map; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { map[key] = setVariable(keys.sublist(1), value, map[key]); } else { map[key] = value; } return map; } @override dynamic getVariable(List keys, Map map) { if (keys.isEmpty) { return null; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { return getVariable(keys.sublist(1), map[key]); } return map[key]; } @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return ProcessingItem(); } var w = ProcessingItem( id: json.containsKey("id") ? json["id"] : null, name: json.containsKey("name") ? json["name"] : null, logo: json.containsKey("logo") ? json["logo"] : null, owner: json.containsKey("owner") ? json["owner"] : null, ownerLogo: json.containsKey("owner_logo") ? json["owner_logo"] : null, price: json.containsKey("price") ? json["price"]?.toDouble() : null, licence: json.containsKey("licence") ? json["licence"] : null, description: json.containsKey("description") ? json["description"] : null, shortDescription: json.containsKey("short_description") ? json["short_description"] : null, inputs: json["inputs"] ?? [], outputs: json["outputs"] ?? [], source: json.containsKey("source") ? json["source"] : null, expose: json.containsKey("expose") ? fromListJson(json["expose"], Expose()) : [], container: json.containsKey("container") ? Containered().deserialize(json["container"]) : null, model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null, cpus: json.containsKey("cpus") ? fromListJson(json["cpus"], CPU()) : [], gpus: json.containsKey("gpus") ? fromListJson(json["gpus"], GPU()) : [], ram: json.containsKey("ram") ? RAM().deserialize(json["ram"]) : null, storage: json.containsKey("storage") ? json["storage"] : null, parrallel: json.containsKey("parrallel") ? json["parrallel"] : false, scallingModel: json.containsKey("scalling_model") ? json["scalling_model"] : null, diskIO: json.containsKey("disk_io") ? json["disk_io"] : null, ); if (w.logo != null) { var image = Image.network(w.logo!); image.image .resolve(const ImageConfiguration()) .addListener( ImageStreamListener( (ImageInfo info, bool _) { w.width = info.image.width.toDouble(); w.height = info.image.height.toDouble(); })); } return w; } @override Map serialize() { return { "id": id, "name": name, "logo": logo, "owner": owner, "owner_logo": ownerLogo, "price": price, "licence": licence, "description": description, "short_description": shortDescription, "inputs": inputs, "outputs": outputs, "source": source, "resource_model": model?.serialize(), "cpus": toListJson(cpus), "gpus": toListJson(gpus), "ram": ram?.serialize(), "storage": storage, "parrallel": parrallel, "scalling_model": scallingModel, "disk_io": diskIO, "" "expose": toListJson(expose), "container": container?.serialize(), }; } } class WorkflowItem extends SerializerDeserializer implements AbstractItem { WorkflowItem({ this.id, this.name, this.logo, this.owner, this.ownerLogo, this.price, this.source, this.licence, this.description, this.shortDescription, this.inputs = _empty, this.outputs = _empty, this.model, this.workflowID, }); @override ResourceModel? model; @override String? id; @override String? name; @override String? logo; @override String? source; @override String? ownerLogo; @override String? owner; @override String topic = "workflow"; @override double? price; @override String? licence; @override List inputs; @override List outputs; @override String? description; @override String? shortDescription; String? workflowID; @override String getID() { return id ?? ""; } double? width; double? height; @override double? getWidth() { return width; } @override double? getHeight() { return height; } @override String getName() { return name ?? ""; } @override Map setVariable(List keys, dynamic value, Map map) { if (keys.isEmpty) { return map; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { map[key] = setVariable(keys.sublist(1), value, map[key]); } else { map[key] = value; } return map; } @override dynamic getVariable(List keys, Map map) { if (keys.isEmpty) { return null; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { return getVariable(keys.sublist(1), map[key]); } return map[key]; } @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return WorkflowItem(); } var w = WorkflowItem( id: json.containsKey("id") ? json["id"] : null, name: json.containsKey("name") ? json["name"] : null, logo: json.containsKey("logo") ? json["logo"] : null, owner: json.containsKey("owner") ? json["owner"] : null, ownerLogo: json.containsKey("owner_logo") ? json["owner_logo"] : null, price: json.containsKey("price") ? json["price"]?.toDouble() : null, licence: json.containsKey("licence") ? json["licence"] : null, description: json.containsKey("description") ? json["description"] : null, shortDescription: json.containsKey("short_description") ? json["short_description"] : null, inputs: json["inputs"] ?? [], outputs: json["outputs"] ?? [], source: json.containsKey("source") ? json["source"] : null, model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null, workflowID: json.containsKey("workflow_id") ? json["workflow_id"] : null, ); if (w.logo != null) { // var image = Image.network(w.logo!); image.image .resolve(const ImageConfiguration()) .addListener( ImageStreamListener( (ImageInfo info, bool _) { w.width = info.image.width.toDouble(); w.height = info.image.height.toDouble(); })); } return w; } @override Map serialize() => { "id": id, "name": name, "logo": logo, "owner": owner, "owner_logo": ownerLogo, "price": price, "licence": licence, "description": description, "short_description": shortDescription, "inputs": inputs, "outputs": outputs, "source": source, "resource_model": model?.serialize(), "workflow_id": workflowID, }; } class DataItem extends SerializerDeserializer implements AbstractItem { DataItem({ this.id, this.name, this.logo, this.owner, this.ownerLogo, this.price, this.source, this.licence, this.description, this.shortDescription, this.inputs = _empty, this.outputs = _empty, this.model, this.protocol, this.path, this.protocols = const [], this.type, this.exemple, }); @override String? id; @override String? name; @override String? logo; @override String? source; @override String? ownerLogo; @override String? owner; @override String topic = "data"; @override double? price; @override String? licence; @override List inputs; @override List outputs; @override String? description; @override String? shortDescription; @override ResourceModel? model; // Special Attributes List protocols = []; String? type; String? protocol; String? path; String? exemple; @override String getName() { return name ?? ""; } @override String getID() { return id ?? ""; } double? width; double? height; @override double? getWidth() { return width; } @override double? getHeight() { return height; } @override Map setVariable(List keys, dynamic value, Map map) { if (keys.isEmpty) { return map; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { map[key] = setVariable(keys.sublist(1), value, map[key]); } else { map[key] = value; } return map; } @override dynamic getVariable(List keys, Map map) { if (keys.isEmpty) { return null; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { return getVariable(keys.sublist(1), map[key]); } return map[key]; } @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return DataItem(); } var w = DataItem( id: json.containsKey("id") ? json["id"] : null, name: json.containsKey("name") ? json["name"] : null, logo: json.containsKey("logo") ? json["logo"] : null, owner: json.containsKey("owner") ? json["owner"] : null, ownerLogo: json.containsKey("owner_logo") ? json["owner_logo"] : null, price: json.containsKey("price") ? json["price"]?.toDouble() : null, licence: json.containsKey("licence") ? json["licence"] : null, description: json.containsKey("description") ? json["description"] : null, shortDescription: json.containsKey("short_description") ? json["short_description"] : null, inputs: json["inputs"] ?? [], outputs: json["outputs"] ?? [], source: json.containsKey("source") ? json["source"] : null, model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null, protocols: json.containsKey("protocols") ? json["protocols"] : [], type: json.containsKey("type") ? json["type"] : null, protocol: json.containsKey("protocol") ? json["protocol"] : null, path: json.containsKey("path") ? json["path"] : null, exemple: json.containsKey("exemple") ? json["exemple"] : null, ); if (w.logo != null) { // var image = Image.network(w.logo!); image.image .resolve(const ImageConfiguration()) .addListener( ImageStreamListener( (ImageInfo info, bool _) { w.width = info.image.width.toDouble(); w.height = info.image.height.toDouble(); })); } return w; } @override Map serialize() => { "id": id, "name": name, "logo": logo, "owner": owner, "owner_logo": ownerLogo, "price": price, "licence": licence, "description": description, "short_description": shortDescription, "inputs": inputs, "outputs": outputs, "source": source, "resource_model": model?.serialize(), "protocols": protocols, "type": type, "protocol": protocol, "path": path, "exemple": exemple, }; } class ComputeItem extends SerializerDeserializer implements AbstractItem { ComputeItem({ this.id, this.name, this.logo, this.owner, this.ownerLogo, this.price, this.source, this.licence, this.description, this.shortDescription, this.inputs = _empty, this.outputs = _empty, this.model, this.cpus = const [], this.gpus = const [], this.ram, this.technology, this.access, this.architecture, this.localisation, this.isService = false, }); @override String? id; @override String? name; @override String? logo; @override String? source; @override String? ownerLogo; @override String? owner; @override String topic = "compute"; @override double? price; @override String? licence; @override List inputs; @override List outputs; @override String? description; @override String? shortDescription; @override ResourceModel? model; bool isService = false; String? architecture; int? access; String? localisation; // Special Attributes List cpus = []; List gpus = []; int? technology; RAM? ram; @override String getID() { return id ?? ""; } @override String getName() { return name ?? ""; } double? width; double? height; @override double? getWidth() { return width; } @override double? getHeight() { return height; } String getTechnology() { if (technology == 0) { return "docker"; } if (technology == 1) { return "kubernetes"; } if (technology == 2) { return "slurm"; } if (technology == 3) { return "hardware"; } if (technology == 4) { return "condor"; } return ""; } String getAccess() { if (access == 0) { return "ssh"; } if (access == 1) { return "ssh kube api"; } if (access == 2) { return "ssh slurm"; } if (access == 3) { return "ssh docker"; } if (access == 4) { return "opencloud"; } if (access == 5) { return "vpn"; } return ""; } @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return ComputeItem(); } var w = ComputeItem( isService: json.containsKey("is_service") ? json["is_service"] : false, id: json.containsKey("id") ? json["id"] : null, name: json.containsKey("name") ? json["name"] : null, logo: json.containsKey("logo") ? json["logo"] : null, technology: json.containsKey("technology") ? json["technology"] : null, owner: json.containsKey("owner") ? json["owner"] : null, ownerLogo: json.containsKey("owner_logo") ? json["owner_logo"] : null, price: json.containsKey("price") ? json["price"]?.toDouble() : null, licence: json.containsKey("licence") ? json["licence"] : null, description: json.containsKey("description") ? json["description"] : null, shortDescription: json.containsKey("short_description") ? json["short_description"] : null, access: json.containsKey("access") ? json["access"] : null, architecture: json.containsKey("architecture") ? json["architecture"] : null, localisation: json.containsKey("localisation") ? json["localisation"] : null, inputs: json["inputs"] ?? [], outputs: json["outputs"] ?? [], source: json.containsKey("source") ? json["source"] : null, model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null, cpus: json.containsKey("cpus") ? fromListJson(json["cpus"], CPU()) : [], gpus: json.containsKey("gpus") ? fromListJson(json["gpus"], GPU()) : [], ram: json.containsKey("ram") ? RAM().deserialize(json["ram"]) : null, ); if (w.logo != null) { // var image = Image.network(w.logo!); image.image .resolve(const ImageConfiguration()) .addListener( ImageStreamListener( (ImageInfo info, bool _) { w.width = info.image.width.toDouble(); w.height = info.image.height.toDouble(); })); } return w; } @override Map setVariable(List keys, dynamic value, Map map) { if (keys.isEmpty) { return map; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { map[key] = setVariable(keys.sublist(1), value, map[key]); } else { map[key] = value; } return map; } @override dynamic getVariable(List keys, Map map) { if (keys.isEmpty) { return null; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { return getVariable(keys.sublist(1), map[key]); } return map[key]; } @override Map serialize() => { "id": id, "name": name, "logo": logo, "owner": owner, "owner_logo": ownerLogo, "price": price, "is_service": isService, "licence": licence, "access": access, "architecture": architecture, "localisation": localisation, "description": description, "short_description": shortDescription, "inputs": inputs, "outputs": outputs, "source": source, "technology": technology, "resource_model": model?.serialize(), "cpus": toListJson(cpus), "gpus": toListJson(gpus), "ram": ram?.serialize(), }; } class CPU extends SerializerDeserializer { CPU({ this.cores, this.platform, this.architecture, this.minimumMemory, this.shared = false, }); double? cores; String? platform; bool shared = false; String? architecture; double? minimumMemory; @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return CPU(); } return CPU( cores: json.containsKey("cores") ? json["cores"]?.toDouble() : null, platform: json.containsKey("platform") ? json["platform"] : null, architecture: json.containsKey("architecture") ? json["architecture"] : null, minimumMemory: json.containsKey("minimumMemory") ? json["minimumMemory"]?.toDouble() : null, shared: json.containsKey("shared") ? json["shared"] : false, ); } @override Map serialize() => { "cores": cores, "platform": platform, "architecture": architecture, "minimumMemory": minimumMemory, "shared": shared, }; } class GPU extends SerializerDeserializer { GPU({ this.cudaCores, this.memory, this.model, this.tensorCores, }); double? cudaCores; double? memory; String? model; double? tensorCores; @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return GPU(); } return GPU( cudaCores: json.containsKey("cuda_cores") ? json["cuda_cores"]?.toDouble() : null, memory: json.containsKey("memory") ? json["memory"]?.toDouble() : null, model: json.containsKey("model") ? json["model"] : null, tensorCores: json.containsKey("tensor_cores") ? json["tensor_cores"]?.toDouble() : null, ); } @override Map serialize() => { "cuda_cores": cudaCores, "memory": memory, "model": model, "tensor_cores": tensorCores, }; } class RAM extends SerializerDeserializer { RAM({ this.ecc = false, this.size, }); bool ecc = false; double? size; @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return RAM(); } return RAM( ecc: json.containsKey("ecc") ? json["ecc"] : false, size: json.containsKey("size") ? json["size"]?.toDouble() : null, ); } @override Map serialize() => { "ecc": ecc, "size": size, }; } class StorageItem extends SerializerDeserializer implements AbstractItem { StorageItem({ this.id, this.name, this.logo, this.owner, this.ownerLogo, this.price, this.source, this.licence, this.description, this.shortDescription, this.inputs = _empty, this.outputs = _empty, this.acronym, this.type, this.size, this.path, this.protocol, this.encryption = false, this.redundancy, this.throughput, this.model, this.local = false, }); bool local = false; @override String? id; @override String? name; @override String? logo; @override String? source; @override String? ownerLogo; @override String? owner; @override String topic = "storage"; @override double? price; @override String? licence; @override List inputs; @override List outputs; @override String? description; @override String? shortDescription; @override ResourceModel? model; // special attributes String? acronym; String? type; String? path; String? protocol; int? size; bool encryption = false; String? redundancy; String? throughput; @override String getName() { return name ?? ""; } @override String getID() { return id ?? ""; } double? width; double? height; @override double? getWidth() { return width; } @override double? getHeight() { return height; } @override dynamic getVariable(List keys, Map map) { if (keys.isEmpty) { return null; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { return getVariable(keys.sublist(1), map[key]); } return map[key]; } @override Map setVariable(List keys, dynamic value, Map map) { if (keys.isEmpty) { return map; } var key = keys[0]; if (keys.length > 1 && map[key] != null) { map[key] = setVariable(keys.sublist(1), value, map[key]); } else { map[key] = value; } return map; } @override deserialize(dynamic json) { try { json = json as Map; } catch (e) { return StorageItem(); } var w = StorageItem( id: json.containsKey("id") ? json["id"] : null, name: json.containsKey("name") ? json["name"] : null, logo: json.containsKey("logo") ? json["logo"] : null, owner: json.containsKey("owner") ? json["owner"] : null, ownerLogo: json.containsKey("owner_logo") ? json["owner_logo"] : null, price: json.containsKey("price") ? json["price"]?.toDouble() : null, licence: json.containsKey("licence") ? json["licence"] : null, description: json.containsKey("description") ? json["description"] : null, shortDescription: json.containsKey("short_description") ? json["short_description"] : null, local: json.containsKey("local") ? json["local"] : false, inputs: json["inputs"] ?? [], outputs: json["outputs"] ?? [], source: json.containsKey("source") ? json["source"] : null, model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null, acronym: json.containsKey("acronym") ? json["acronym"] : null, type: json.containsKey("type") ? json["type"] : null, size: json.containsKey("size") ? json["size"] : null, path: json.containsKey("path") ? json["path"] : null, protocol: json.containsKey("protocol") ? json["protocol"] : null, encryption: json.containsKey("encryption") ? json["encryption"] : false, redundancy: json.containsKey("redundancy") ? json["redundancy"] : null, throughput: json.containsKey("throughput") ? json["throughput"] : null, ); if (w.logo != null) { // var image = Image.network(w.logo!); image.image .resolve(const ImageConfiguration()) .addListener( ImageStreamListener( (ImageInfo info, bool _) { w.width = info.image.width.toDouble(); w.height = info.image.height.toDouble(); })); } return w; } @override Map serialize() => { "id": id, "name": name, "logo": logo, "owner": owner, "owner_logo": ownerLogo, "price": price, "local": local, "licence": licence, "description": description, "short_description": shortDescription, "inputs": inputs, "outputs": outputs, "source": source, "resource_model": model?.serialize(), "acronym": acronym, "type": type, "size": size, "path": path, "protocol": protocol, "encryption": encryption, "redundancy": redundancy, "throughput": throughput, }; }