(() => { const t = (key, vars) => window.I18n?.t(key, vars) ?? key; function fileStem(name) { const base = String(name).replace(/^.*[/\\]/, ""); const dot = base.lastIndexOf("."); return dot >= 0 ? base.slice(0, dot) : base; } function isYamlFile(file) { return /\.ya?ml$/i.test(file.name); } function isMapImageFile(file) { return /\.(png|pgm)$/i.test(file.name); } async function matchRosMapFiles(fileList) { const files = Array.from(fileList || []); const yamlFile = files.find(isYamlFile); if (!yamlFile) { throw new Error(t("maps.importNeedYaml")); } let imageFile = files.find((f) => f !== yamlFile && isMapImageFile(f)); try { const yamlText = await yamlFile.text(); const imageRef = yamlText.match(/^image:\s*(\S+)/m)?.[1]; if (imageRef) { const refStem = fileStem(imageRef); const matched = files.find( (f) => f !== yamlFile && isMapImageFile(f) && fileStem(f.name) === refStem, ); if (matched) imageFile = matched; } } catch { /* best-effort stem match */ } if (!imageFile) { throw new Error(t("maps.importNeedImage")); } return { yamlFile, imageFile }; } function buildFormData(yamlFile, imageFile, extras = {}) { const form = new FormData(); form.append("yaml", yamlFile, yamlFile.name); form.append("image", imageFile, imageFile.name); Object.entries(extras).forEach(([key, value]) => { if (value != null && value !== "") form.append(key, value); }); return form; } async function apiImport(path, form) { const res = await fetch(path, { method: "POST", credentials: "include", body: form }); if (!res.ok) { let msg = res.statusText; try { const err = await res.json(); if (err.error) msg = err.error; } catch { /* ignore */ } throw new Error(msg); } return res.json(); } async function importNewMap(fileList, extras = {}) { const { yamlFile, imageFile } = await matchRosMapFiles(fileList); const form = buildFormData(yamlFile, imageFile, { name: extras.name || fileStem(yamlFile.name), site_id: extras.site_id || "", created_by: extras.created_by || "", description: extras.description || "", }); return apiImport("/api/maps/import", form); } async function importOverwriteMap(mapId, fileList) { const { yamlFile, imageFile } = await matchRosMapFiles(fileList); const form = buildFormData(yamlFile, imageFile); return apiImport(`/api/maps/${encodeURIComponent(mapId)}/import`, form); } window.MapImport = { fileStem, isYamlFile, isMapImageFile, matchRosMapFiles, importNewMap, importOverwriteMap, }; })();