function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND, FLOOR_MAP_IMAGE_ELEMENT_KIND } from '@pisell/materials';
import { locales } from '@pisell/utils';
import reservationLocales from "../locales/locales";
var PALETTE_IMAGE_BG_I18N_KEY = 'pisell-reservation.floor-map.palette-image-bg';

/** 合并远程图元种类时识别「旧版图片底图」展示名（各语言 + 历史简体中文） */
var LEGACY_PALETTE_IMAGE_BG_LABELS = new Set([reservationLocales.en[PALETTE_IMAGE_BG_I18N_KEY], reservationLocales['zh-CN'][PALETTE_IMAGE_BG_I18N_KEY], reservationLocales['zh-HK'][PALETTE_IMAGE_BG_I18N_KEY], '图片（底图）']);
var I18N_FLOOR_CATEGORY_BG = 'pisell-reservation.floor-map.category-background';
var I18N_FLOOR_DS_LABEL = 'pisell-reservation.floor-map.data-source-label';
var I18N_PALETTE_IMAGE_BG = PALETTE_IMAGE_BG_I18N_KEY;
var I18N_PALETTE_BUILTIN_SHAPE = 'pisell-floor-map-layout.palette.builtin-shape';
var I18N_ROOM_KIND_BOUND = 'pisell-reservation.room-kind-bound';
var I18N_ROOM_KIND_BOUND_ROUND = 'pisell-reservation.room-kind-bound-round';

/**
 * 与 Story 款 `floorMapImage` 重复的旧版/接口图片图元（合并时整项丢弃，只保留默认里那份）
 */
var LEGACY_IMAGE_ELEMENT_KIND_VALUES = new Set(['image', 'floorMapBg', 'floor_map_image']);
function stripConflictingImageElementKinds(kinds) {
  return kinds.filter(function (k) {
    if (LEGACY_IMAGE_ELEMENT_KIND_VALUES.has(k.value)) return false;
    if (k.value !== FLOOR_MAP_IMAGE_ELEMENT_KIND && LEGACY_PALETTE_IMAGE_BG_LABELS.has(k.label)) {
      return false;
    }
    return true;
  });
}

/** 按 value 去重，保留先出现的项 */
function dedupeElementKindsByValue(kinds) {
  var seen = new Set();
  return kinds.filter(function (k) {
    if (seen.has(k.value)) return false;
    seen.add(k.value);
    return true;
  });
}

/**
 * 父级/接口 elementKinds 与预约默认合并：
 * - 去掉与 Story 图片图元重复的旧版种类；
 * - 远程若已有 `floorMapImage` 也先去掉，统一用 defaults 里那份（避免两套「图片底图」并存）。
 * - 对**同一 value**：用 `{ ...default, ...remote }` 合并，避免远程 JSON 只存了精简字段时
 *   把预约默认里的 `nameAsTitleConfigurable` 等能力位整段丢掉（否则编辑面板不显示「图元名作为标题」勾选）。
 */
export function mergeFloorMapElementKindsWithDefaults(defaults, remote) {
  if (!(remote !== null && remote !== void 0 && remote.length)) return defaults;
  var defaultByValue = new Map(defaults.map(function (d) {
    return [d.value, d];
  }));
  var base = dedupeElementKindsByValue(stripConflictingImageElementKinds(remote)).filter(function (k) {
    return k.value !== FLOOR_MAP_IMAGE_ELEMENT_KIND;
  }).filter(function (k) {
    return k.value !== FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND;
  }).filter(function (k) {
    return !LEGACY_RESERVATION_TABLE_KIND_VALUES.has(k.value);
  }).map(function (k) {
    var _k$nameAsTitleConfigu;
    var d = defaultByValue.get(k.value);
    if (!d) return k;
    return _objectSpread(_objectSpread(_objectSpread({}, d), k), {}, {
      nameAsTitleConfigurable: (_k$nameAsTitleConfigu = k.nameAsTitleConfigurable) !== null && _k$nameAsTitleConfigu !== void 0 ? _k$nameAsTitleConfigu : d.nameAsTitleConfigurable
    });
  });
  var seen = new Set(base.map(function (k) {
    return k.value;
  }));
  var out = _toConsumableArray(base);
  var _iterator = _createForOfIteratorHelper(defaults),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var d = _step.value;
      if (!seen.has(d.value)) {
        out.push(d);
        seen.add(d.value);
      }
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  return dedupeElementKindsByValue(out);
}

/** 同上，补全图元分类（如「底图」），避免调色板分组缺失 */
export function mergeFloorMapElementKindCategoriesWithDefaults(defaults, remote) {
  if (!(remote !== null && remote !== void 0 && remote.length)) return defaults;
  var seen = new Set(remote.map(function (c) {
    return c.id;
  }));
  var out = _toConsumableArray(remote);
  var _iterator2 = _createForOfIteratorHelper(defaults),
    _step2;
  try {
    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
      var d = _step2.value;
      if (!seen.has(d.id)) {
        out.push(d);
        seen.add(d.id);
      }
    }
  } catch (err) {
    _iterator2.e(err);
  } finally {
    _iterator2.f();
  }
  return _toConsumableArray(out).sort(function (a, b) {
    var _a$order, _b$order;
    return ((_a$order = a.order) !== null && _a$order !== void 0 ? _a$order : 0) - ((_b$order = b.order) !== null && _b$order !== void 0 ? _b$order : 0);
  });
}

/**
 * 按当前 {@link locales} 刷新调色板分组、图元展示名（底图 / 资源绑定等）。
 * 持久化里若仍使用约定 `categoryId`：`background`、`dining` 与约定 kind value，会覆盖旧快照文案以便随引擎语言切换。
 */
export function applyReservationFloorMapLiveLabels(config) {
  var _config$elementKindCa, _config$elementKinds;
  var nextCats = (_config$elementKindCa = config.elementKindCategories) === null || _config$elementKindCa === void 0 ? void 0 : _config$elementKindCa.map(function (c) {
    if (c.id === 'background') {
      return _objectSpread(_objectSpread({}, c), {}, {
        label: locales.getText(I18N_FLOOR_CATEGORY_BG)
      });
    }
    if (c.id === 'dining') {
      return _objectSpread(_objectSpread({}, c), {}, {
        label: locales.getText(I18N_FLOOR_DS_LABEL)
      });
    }
    return c;
  });
  var nextKinds = (_config$elementKinds = config.elementKinds) === null || _config$elementKinds === void 0 ? void 0 : _config$elementKinds.map(function (k) {
    if (k.value === FLOOR_MAP_IMAGE_ELEMENT_KIND) {
      return _objectSpread(_objectSpread({}, k), {}, {
        label: locales.getText(I18N_PALETTE_IMAGE_BG)
      });
    }
    if (k.value === FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND) {
      return _objectSpread(_objectSpread({}, k), {}, {
        label: locales.getText(I18N_PALETTE_BUILTIN_SHAPE)
      });
    }
    if (k.value === RESERVATION_BOUND_TABLE_ELEMENT_KIND) {
      return _objectSpread(_objectSpread({}, k), {}, {
        label: locales.getText(I18N_ROOM_KIND_BOUND)
      });
    }
    if (k.value === RESERVATION_BOUND_ROUND_TABLE_ELEMENT_KIND) {
      return _objectSpread(_objectSpread({}, k), {}, {
        label: locales.getText(I18N_ROOM_KIND_BOUND_ROUND)
      });
    }
    return k;
  });
  return _objectSpread(_objectSpread({}, config), {}, {
    elementKindCategories: nextCats !== null && nextCats !== void 0 ? nextCats : config.elementKindCategories,
    elementKinds: nextKinds !== null && nextKinds !== void 0 ? nextKinds : config.elementKinds
  });
}

/** 默认画布展示名（与 reservation locales 中 canvas.* 文案对齐） */
var RESERVATION_CANVAS_NAME_MAIN = {
  en: 'Main Area',
  'zh-CN': '主区域',
  'zh-HK': '主區域',
  ja: 'Main Area',
  pt: 'Main Area'
};
var RESERVATION_CANVAS_NAME_SECONDARY = {
  en: 'Secondary Area',
  'zh-CN': '副区域',
  'zh-HK': '副區域',
  ja: 'Secondary Area',
  pt: 'Secondary Area'
};
var RESERVATION_CANVAS_NAME_VIP = {
  en: 'VIP Area',
  'zh-CN': 'VIP 区',
  'zh-HK': 'VIP 區',
  ja: 'VIP Area',
  pt: 'VIP Area'
};

/**
 * 预约平面图「绑定桌位」唯一图元 value（与底图 `floorMapImage` 并存）。
 * 旧版方桌 / 长条 / 吧台图元仍可从接口 scene 回显，渲染走同一套房间卡片。
 */
export var RESERVATION_BOUND_TABLE_ELEMENT_KIND = 'reservationBoundTable';

/** 绑定圆桌位：与方桌同一数据源与卡片逻辑，默认 `shape: circle` */
export var RESERVATION_BOUND_ROUND_TABLE_ELEMENT_KIND = 'reservationBoundRoundTable';
var LEGACY_RESERVATION_TABLE_KIND_VALUES = new Set(['reservationTable', 'reservationPartyBench', 'reservationBarSeat']);

/** 与设计稿一致的预约桌位 mock（表格 + 平面图同源） */
export var defaultReservationTableRows = [{
  id: 't1',
  code: 'VIP 1号厅',
  area: 'Main',
  cardStatus: 'occupied',
  guestName: '张总',
  guestPhone: '135****6789',
  time: '13:00',
  timeEnd: '15:30',
  partySize: 8,
  capacityLabel: '12',
  priceDisplay: '$ 1288',
  isPaid: true,
  delayMinutes: 13,
  progress: 0.62,
  progressTone: 'warning',
  nextGuest: 'Alex',
  nextTime: '14:30'
}, {
  id: 't2',
  code: 'T-2',
  area: 'Main',
  cardStatus: 'occupied',
  guestName: 'Tom',
  guestPhone: '138****1024',
  time: '13:30',
  partySize: 4,
  priceDisplay: '$ 680',
  isPaid: false,
  topAccentOrange: true,
  elapsedLabel: '1h45m',
  progress: 0.35,
  progressTone: 'success'
}, {
  id: 't3',
  code: 'T-3',
  area: 'Main',
  cardStatus: 'booked',
  guestName: 'Grace',
  time: '14:08',
  partySize: 5,
  startsInMinutes: 8
}, {
  id: 't4',
  code: 'T-4',
  area: 'Main',
  cardStatus: 'booked',
  guestName: 'Rachel Wu',
  guestPhone: '186****5511',
  time: '14:00',
  partySize: 4,
  lateMinutes: 8,
  nextGuest: 'David',
  nextTime: '15:00'
}, {
  id: 't5',
  code: 'T-5',
  area: 'Main',
  cardStatus: 'booked',
  guestName: 'Sophia',
  time: '12:00',
  partySize: 4
}, {
  id: 't6',
  code: '大包 C2',
  area: 'Main',
  cardStatus: 'booked',
  capacityLabel: '10',
  slots: [{
    name: 'James',
    time: '10:00-12:00',
    progress: 0.45
  }, {
    name: 'Wang Li',
    time: '12:30-14:00',
    progress: 0.28
  }],
  moreCount: 4
}, {
  id: 't7',
  code: 'T-7',
  area: 'Main',
  cardStatus: 'available'
}, {
  id: 't8',
  code: 'T-8',
  area: 'Main',
  cardStatus: 'maintenance',
  capacityLabel: '6p'
}, {
  id: 'p1',
  code: 'P-1',
  area: 'Private',
  cardStatus: 'occupied',
  slots: [{
    name: 'Michael',
    time: '13:45'
  }, {
    name: 'Grace',
    time: '14:00'
  }],
  moreCount: 3
}, {
  id: 'p2',
  code: 'P-2',
  area: 'Private',
  cardStatus: 'booked',
  guestName: 'Mark',
  time: '13:00',
  partySize: 2
}, {
  id: 'b1',
  code: 'B-1',
  area: 'Bar',
  cardStatus: 'barBusy',
  time: '14:00',
  partySize: 2,
  barRemainingLabel: '1h10m'
}, {
  id: 'b2',
  code: 'B-2',
  area: 'Bar',
  cardStatus: 'occupied',
  time: '13:45',
  partySize: 1,
  barRemainingLabel: '55m'
}, {
  id: 'b3',
  code: 'B-3',
  area: 'Bar',
  cardStatus: 'booked',
  time: '13:30',
  partySize: 4
}, {
  id: 'b4',
  code: 'B-4',
  area: 'Bar',
  cardStatus: 'occupied',
  barSlots: [{
    name: 'Sarah',
    time: '13:50'
  }, {
    name: 'Kevin',
    time: '14:15'
  }]
}, {
  id: 'b5',
  code: 'B-5',
  area: 'Bar',
  cardStatus: 'available'
}, {
  id: 'b6',
  code: 'B-6',
  area: 'Bar',
  cardStatus: 'booked',
  time: '13:30',
  partySize: 4
}, {
  id: 'b7',
  code: 'B-7',
  area: 'Bar',
  cardStatus: 'maintenance'
},
// --- 大屏资源墙演示：名称带 Mock· 前缀，便于在筛选里勾选对比 ---
{
  id: 'mock-rw-available',
  code: 'Mock·空场(绿)',
  area: 'WallDemo',
  cardStatus: 'available'
}, {
  id: 'mock-rw-ending',
  code: 'Mock·将结束(橙)',
  area: 'WallDemo',
  cardStatus: 'occupied',
  guestName: '倒计时≤10分',
  time: '14:00',
  delayMinutes: 56
}, {
  id: 'mock-rw-expired',
  code: 'Mock·已超时(红)',
  area: 'WallDemo',
  cardStatus: 'occupied',
  guestName: '应已清场',
  time: '11:00',
  delayMinutes: 60
}, {
  id: 'mock-rw-maint',
  code: 'Mock·维护态',
  area: 'WallDemo',
  cardStatus: 'maintenance',
  capacityLabel: '8p'
}, {
  id: 'mock-rw-lights-off',
  code: 'Mock·灯已关',
  area: 'WallDemo',
  cardStatus: 'occupied',
  guestName: '场上无人',
  time: '13:00',
  delayMinutes: 30,
  resourceWallLightState: 'off'
}, {
  id: 'mock-rw-lights-off-soon',
  code: 'Mock·即将关灯',
  area: 'WallDemo',
  cardStatus: 'occupied',
  guestName: '场上进行中',
  time: '15:00',
  delayMinutes: 25,
  resourceWallLightState: 'on_soon_off',
  resourceWallLightOffInMin: 6
}, {
  id: 'mock-rw-lights-on-soon',
  code: 'Mock·即将开灯',
  area: 'WallDemo',
  cardStatus: 'booked',
  guestName: '下一场将开',
  time: '16:00',
  startsInMinutes: 12,
  resourceWallLightState: 'off_soon_on',
  resourceWallLightOnInMin: 8,
  nextGuest: '下一场·李娜',
  nextTime: '16:00'
}];
var DS = 'tables';
var CANVAS_MAIN = 'main';
function getReservationElementKindCategories() {
  return [{
    id: 'background',
    label: locales.getText(I18N_FLOOR_CATEGORY_BG),
    order: 0
  }, {
    id: 'dining',
    label: locales.getText(I18N_FLOOR_DS_LABEL),
    order: 1
  }];
}
function getReservationPaletteElementKinds() {
  return [{
    value: FLOOR_MAP_IMAGE_ELEMENT_KIND,
    label: locales.getText(I18N_PALETTE_IMAGE_BG),
    categoryId: 'background',
    dataBindingPolicy: 'none',
    showInPalette: true
  }, {
    /**
     * 内置图形图元：与图片图元并列在「背景」分类下，但用 `builtinShapeKey` 在内置
     * 预设（厕所/分隔/柱子/沙发/大门）中选择，无需 URL，落点即可见图形。
     */
    value: FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND,
    label: locales.getText(I18N_PALETTE_BUILTIN_SHAPE),
    categoryId: 'background',
    dataBindingPolicy: 'none',
    showInPalette: true
  }, {
    value: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
    label: locales.getText(I18N_ROOM_KIND_BOUND),
    categoryId: 'dining',
    dataBindingPolicy: 'optional',
    allowedDataSourceKeys: [DS],
    showInPalette: true,
    /**
     * 允许编辑面板出现「将图元名作为资源标题」勾选项；
     * 不勾选时仍按 row.main_field / row.code 为主，行为与历史一致。
     */
    nameAsTitleConfigurable: true
  }, {
    value: RESERVATION_BOUND_ROUND_TABLE_ELEMENT_KIND,
    label: locales.getText(I18N_ROOM_KIND_BOUND_ROUND),
    categoryId: 'dining',
    dataBindingPolicy: 'optional',
    allowedDataSourceKeys: [DS],
    defaultShape: 'circle',
    showInPalette: true,
    nameAsTitleConfigurable: true
  }];
}
var CANVAS_SECONDARY = 'secondary';
var CANVAS_VIP = 'vip';

/**
 * 默认平面图图元（唯一真相源）。
 * 有 floorMapConfig 时 PisellFloorMapLayout 强制 itemUnit=pixel，故 x/y/width/height 均为「像素」，非格子数。
 */
export var defaultReservationSceneElements = [{
  instanceId: 'res_t1',
  canvasId: CANVAS_MAIN,
  x: 40,
  y: 40,
  width: 150,
  height: 100,
  name: 'T-1',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't1'
  }
}, {
  instanceId: 'res_t2',
  canvasId: CANVAS_MAIN,
  x: 210,
  y: 40,
  width: 150,
  height: 100,
  name: 'T-2',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't2'
  }
}, {
  instanceId: 'res_t3',
  canvasId: CANVAS_MAIN,
  x: 380,
  y: 40,
  width: 150,
  height: 100,
  name: 'T-3',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't3'
  }
}, {
  instanceId: 'res_p2',
  canvasId: CANVAS_MAIN,
  x: 550,
  y: 40,
  width: 140,
  height: 100,
  name: 'P-2',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'p2'
  }
}, {
  instanceId: 'res_t4',
  canvasId: CANVAS_MAIN,
  x: 40,
  y: 170,
  width: 150,
  height: 100,
  name: 'T-4',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't4'
  }
}, {
  instanceId: 'res_t5',
  canvasId: CANVAS_MAIN,
  x: 210,
  y: 170,
  width: 150,
  height: 100,
  name: 'T-5',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't5'
  }
}, {
  instanceId: 'res_t6',
  canvasId: CANVAS_MAIN,
  x: 380,
  y: 170,
  width: 150,
  height: 100,
  name: 'T-6',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't6'
  }
}, {
  instanceId: 'res_p1',
  canvasId: CANVAS_MAIN,
  x: 710,
  y: 40,
  width: 240,
  height: 240,
  name: 'P-1',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'p1'
  }
}, {
  instanceId: 'res_t7',
  canvasId: CANVAS_MAIN,
  x: 40,
  y: 300,
  width: 150,
  height: 100,
  name: 'T-7',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't7'
  }
}, {
  instanceId: 'res_t8',
  canvasId: CANVAS_MAIN,
  x: 210,
  y: 300,
  width: 150,
  height: 100,
  name: 'T-8',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 't8'
  }
}, {
  instanceId: 'res_b1',
  canvasId: CANVAS_MAIN,
  x: 40,
  y: 440,
  width: 90,
  height: 90,
  name: 'B-1',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'b1'
  }
}, {
  instanceId: 'res_b2',
  canvasId: CANVAS_MAIN,
  x: 150,
  y: 440,
  width: 90,
  height: 90,
  name: 'B-2',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'b2'
  }
}, {
  instanceId: 'res_b3',
  canvasId: CANVAS_MAIN,
  x: 260,
  y: 440,
  width: 90,
  height: 90,
  name: 'B-3',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'b3'
  }
}, {
  instanceId: 'res_b4',
  canvasId: CANVAS_MAIN,
  x: 370,
  y: 440,
  width: 90,
  height: 90,
  name: 'B-4',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'b4'
  }
}, {
  instanceId: 'res_b5',
  canvasId: CANVAS_MAIN,
  x: 480,
  y: 440,
  width: 90,
  height: 90,
  name: 'B-5',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'b5'
  }
}, {
  instanceId: 'res_b6',
  canvasId: CANVAS_MAIN,
  x: 590,
  y: 440,
  width: 90,
  height: 90,
  name: 'B-6',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'b6'
  }
}, {
  instanceId: 'res_b7',
  canvasId: CANVAS_MAIN,
  x: 700,
  y: 440,
  width: 90,
  height: 90,
  name: 'B-7',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'b7'
  }
},
// 与 defaultReservationTableRows 中 mock-rw-* 对齐，进入日历/资源墙资源顺序与平面图绑定
{
  instanceId: 'res_mock_rw_available',
  canvasId: CANVAS_MAIN,
  x: 30,
  y: 560,
  width: 100,
  height: 80,
  name: 'Mock·空场',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'mock-rw-available'
  }
}, {
  instanceId: 'res_mock_rw_ending',
  canvasId: CANVAS_MAIN,
  x: 148,
  y: 560,
  width: 100,
  height: 80,
  name: 'Mock·将结束',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'mock-rw-ending'
  }
}, {
  instanceId: 'res_mock_rw_expired',
  canvasId: CANVAS_MAIN,
  x: 266,
  y: 560,
  width: 100,
  height: 80,
  name: 'Mock·超时',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'mock-rw-expired'
  }
}, {
  instanceId: 'res_mock_rw_maint',
  canvasId: CANVAS_MAIN,
  x: 384,
  y: 560,
  width: 100,
  height: 80,
  name: 'Mock·维护',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'mock-rw-maint'
  }
}, {
  instanceId: 'res_mock_rw_lights_off',
  canvasId: CANVAS_MAIN,
  x: 502,
  y: 560,
  width: 100,
  height: 80,
  name: 'Mock·灯关',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'mock-rw-lights-off'
  }
}, {
  instanceId: 'res_mock_rw_lights_off_soon',
  canvasId: CANVAS_MAIN,
  x: 620,
  y: 560,
  width: 100,
  height: 80,
  name: 'Mock·将关灯',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'mock-rw-lights-off-soon'
  }
}, {
  instanceId: 'res_mock_rw_lights_on_soon',
  canvasId: CANVAS_MAIN,
  x: 738,
  y: 560,
  width: 100,
  height: 80,
  name: 'Mock·将开灯',
  zIndex: 0,
  elementKind: RESERVATION_BOUND_TABLE_ELEMENT_KIND,
  dataBinding: {
    dataSourceKey: DS,
    recordId: 'mock-rw-lights-on-soon'
  }
}];

/** 由 sceneElements 派生的落位摘要（数值与 sceneElements 一致，均为像素；兼容旧引用） */
export var reservationDataSourcePlacements = defaultReservationSceneElements.map(function (el) {
  var _el$name, _el$elementKind;
  var placement = {
    dataSourceKey: el.dataBinding.dataSourceKey,
    id: String(el.dataBinding.recordId),
    floorMapId: el.canvasId,
    x: el.x,
    y: el.y,
    name: String((_el$name = el.name) !== null && _el$name !== void 0 ? _el$name : ''),
    width: el.width,
    height: el.height,
    elementKind: String((_el$elementKind = el.elementKind) !== null && _el$elementKind !== void 0 ? _el$elementKind : '')
  };
  if (el.shape === 'circle') placement.shape = 'circle';
  return placement;
});
function cloneSceneElements(els) {
  return els.map(function (el) {
    return _objectSpread(_objectSpread({}, el), {}, {
      dataBinding: el.dataBinding ? _objectSpread({}, el.dataBinding) : undefined
    });
  });
}

/**
 * 将落位表转为 sceneElements（外部自定义 placements 时用）。
 * 与 RecordBoard 平面图一致时，x/y/width/height 应为像素（floorMap 视图下 itemUnit 为 pixel）。
 */
export function reservationPlacementsToSceneElements(placements) {
  return placements.map(function (p) {
    var el = {
      instanceId: "res_".concat(p.id),
      canvasId: p.floorMapId,
      x: p.x,
      y: p.y,
      width: p.width,
      height: p.height,
      name: p.name,
      zIndex: 0,
      elementKind: p.elementKind,
      dataBinding: {
        dataSourceKey: p.dataSourceKey,
        recordId: p.id
      }
    };
    if (p.shape === 'circle') el.shape = 'circle';
    return el;
  });
}
/**
 * 预约页默认平面图壳子：画布/图元种类与 mock 一致，但不带演示 sceneElements。
 * 生产态布局以 floor-plan 接口与编辑保存为准。
 */
export function getReservationFloorMapShellConfig() {
  return {
    canvases: [{
      id: CANVAS_MAIN,
      name: RESERVATION_CANVAS_NAME_MAIN,
      order: 0,
      enabled: true
    }, {
      id: CANVAS_SECONDARY,
      name: RESERVATION_CANVAS_NAME_SECONDARY,
      order: 1,
      enabled: true
    }, {
      id: CANVAS_VIP,
      name: RESERVATION_CANVAS_NAME_VIP,
      order: 2,
      enabled: true
    }],
    canvasUi: {
      canCreate: true,
      canEdit: true
    },
    elementKindCategories: getReservationElementKindCategories(),
    elementKinds: getReservationPaletteElementKinds(),
    sceneElements: []
  };
}

/** 平面图初始配置：sceneElements 使用上方完整 width/height，勿仅依赖派生表 */
export function getDefaultReservationFloorMapConfig() {
  return {
    canvases: [{
      id: CANVAS_MAIN,
      name: RESERVATION_CANVAS_NAME_MAIN,
      order: 0,
      enabled: true
    }, {
      id: CANVAS_SECONDARY,
      name: RESERVATION_CANVAS_NAME_SECONDARY,
      order: 1,
      enabled: true
    }, {
      id: CANVAS_VIP,
      name: RESERVATION_CANVAS_NAME_VIP,
      order: 2,
      enabled: true
    }],
    canvasUi: {
      canCreate: true,
      canEdit: true
    },
    elementKindCategories: getReservationElementKindCategories(),
    elementKinds: getReservationPaletteElementKinds(),
    sceneElements: cloneSceneElements(defaultReservationSceneElements)
  };
}

/** 平面图侧栏数据源记录表单列（随当前语言刷新） */
export function getReservationDataSourceFormColumns() {
  return [{
    key: 'code',
    label: locales.getText('pisell-reservation.grid.code'),
    type: 'string'
  }, {
    key: 'guestName',
    label: locales.getText('pisell-reservation.grid.guest'),
    type: 'string'
  }, {
    key: 'time',
    label: locales.getText('pisell-reservation.grid.time'),
    type: 'string'
  }, {
    key: 'partySize',
    label: locales.getText('pisell-reservation.grid.party'),
    type: 'number'
  }, {
    key: 'cardStatus',
    label: locales.getText('pisell-reservation.resource-grid.card-status'),
    type: 'string'
  }, {
    key: 'area',
    label: locales.getText('pisell-reservation.grid.area'),
    type: 'string'
  }];
}