@ray-js/robot-map-sdk 0.0.3-beta-3 → 0.0.3-beta-5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/dist/application/AppContainer.js +1 -0
  3. package/dist/application/AppService.js +1 -0
  4. package/dist/application/Interaction.js +1 -0
  5. package/dist/application/MapApplication.js +1 -0
  6. package/dist/application/ViewportContainer.js +1 -0
  7. package/dist/assets/carpet.png.js +1 -0
  8. package/dist/assets/chargingStation.png.js +1 -0
  9. package/dist/assets/checkmark.png.js +1 -0
  10. package/dist/assets/cleanMode0.png.js +1 -0
  11. package/dist/assets/cleanMode1.png.js +1 -0
  12. package/dist/assets/cleanMode2.png.js +1 -0
  13. package/dist/assets/cleanMode3.png.js +1 -0
  14. package/dist/assets/cleanTimes1.png.js +1 -0
  15. package/dist/assets/cleanTimes2.png.js +1 -0
  16. package/dist/assets/controlDelete.png.js +1 -0
  17. package/dist/assets/controlMove.png.js +1 -0
  18. package/dist/assets/controlRotate.png.js +1 -0
  19. package/dist/assets/controlScale.png.js +1 -0
  20. package/dist/assets/fan0.png.js +1 -0
  21. package/dist/assets/fan1.png.js +1 -0
  22. package/dist/assets/fan2.png.js +1 -0
  23. package/dist/assets/fan3.png.js +1 -0
  24. package/dist/assets/fan4.png.js +1 -0
  25. package/dist/assets/floorType.png.js +1 -0
  26. package/dist/assets/robot.png.js +1 -0
  27. package/dist/assets/sleep.json.js +1 -0
  28. package/dist/assets/spot.png.js +1 -0
  29. package/dist/assets/water0.png.js +1 -0
  30. package/dist/assets/water1.png.js +1 -0
  31. package/dist/assets/water2.png.js +1 -0
  32. package/dist/assets/water3.png.js +1 -0
  33. package/dist/components/Base/BaseControlButton.js +1 -0
  34. package/dist/components/Base/Border.js +1 -0
  35. package/dist/components/Base/ControlFill.js +1 -0
  36. package/dist/components/Base/DashLine.js +1 -0
  37. package/dist/components/Base/EndPoint.js +1 -0
  38. package/dist/components/Base/EnhancedAnimatedSprite.js +1 -0
  39. package/dist/components/Base/EnhancedGifSprite.js +1 -0
  40. package/dist/components/Base/EnhancedSprite.js +1 -0
  41. package/dist/components/Base/FixedSizeContainer.js +1 -0
  42. package/dist/components/Base/FixedSizeDOMContainer.js +1 -0
  43. package/dist/components/Base/FixedSizeText.js +1 -0
  44. package/dist/components/Base/MoveControlButton.js +1 -0
  45. package/dist/components/Base/RemoveControlButton.js +1 -0
  46. package/dist/components/Base/Ring.js +1 -0
  47. package/dist/components/Base/RotateControlButton.js +1 -0
  48. package/dist/components/Base/ScaleControlButton.js +1 -0
  49. package/dist/components/Base/Zone.js +1 -0
  50. package/dist/components/ChargingStation/ChargingStationIcon.js +1 -0
  51. package/dist/components/ChargingStation/index.js +1 -0
  52. package/dist/components/Controls/CleanZone.js +1 -0
  53. package/dist/components/Controls/Divider.js +1 -0
  54. package/dist/components/Controls/ForbiddenMopZone.js +1 -0
  55. package/dist/components/Controls/ForbiddenSweepZone.js +1 -0
  56. package/dist/components/Controls/Spot.js +1 -0
  57. package/dist/components/Controls/VirtualWall.js +1 -0
  58. package/dist/components/CustomElements/CustomGif.js +1 -0
  59. package/dist/components/CustomElements/CustomHTML.js +1 -0
  60. package/dist/components/CustomElements/CustomImage.js +1 -0
  61. package/dist/components/DetectedObject/index.js +1 -0
  62. package/dist/components/Heatmap/index.js +1 -0
  63. package/dist/components/Map/Carpet.js +1 -0
  64. package/dist/components/Map/Free.js +1 -0
  65. package/dist/components/Map/Obstacle.js +1 -0
  66. package/dist/components/Map/RoomFill.js +1 -0
  67. package/dist/components/Path/index.js +1 -0
  68. package/dist/components/Robot/RobotIcon.js +1 -0
  69. package/dist/components/Robot/SleepAnimation.js +1 -0
  70. package/dist/components/Robot/index.js +1 -0
  71. package/dist/components/RoomFloorType/index.js +1 -0
  72. package/dist/components/RoomInfo/RoomName.js +1 -0
  73. package/dist/components/RoomInfo/RoomProperty.js +1 -0
  74. package/dist/components/RoomInfo/RoomSelectionIndicator.js +1 -0
  75. package/dist/components/RoomInfo/index.js +1 -0
  76. package/dist/constant/config.js +1 -0
  77. package/dist/constant/index.js +1 -0
  78. package/dist/constant/methods.js +1 -0
  79. package/dist/index.js +1 -0
  80. package/dist/index.rjs.js +1 -0
  81. package/dist/managers/ControlsManager.js +1 -0
  82. package/dist/managers/CustomElementsManager.js +1 -0
  83. package/dist/managers/DetectedObjectManager.js +1 -0
  84. package/dist/managers/HeatmapManager.js +1 -0
  85. package/dist/managers/MapManager.js +1 -0
  86. package/dist/managers/PathManager.js +1 -0
  87. package/dist/managers/RoomManager.js +1 -0
  88. package/dist/mixins/ClickHandler.js +1 -0
  89. package/dist/utils/algorithm.js +1 -0
  90. package/dist/utils/browser.js +1 -0
  91. package/dist/utils/index.js +1 -0
  92. package/dist/utils/logger.js +1 -0
  93. package/dist-docs/404.html +2 -2
  94. package/dist-docs/assets/{app.BjqhSYbb.js → app.DRu3YfJm.js} +1 -1
  95. package/dist-docs/assets/chunks/@localSearchIndexroot.DYDlqEvf.js +1 -0
  96. package/dist-docs/assets/chunks/{VPLocalSearchBox.BzWMSFd6.js → VPLocalSearchBox.rCdV2UMG.js} +1 -1
  97. package/dist-docs/assets/chunks/{theme.DDGgl7pm.js → theme.CKuAZ0Ki.js} +2 -2
  98. package/dist-docs/assets/{guide_getting-started.md.GyXzwIxc.js → guide_getting-started.md.Bn2rTf61.js} +1 -1
  99. package/dist-docs/guide/advanced-usage.html +3 -3
  100. package/dist-docs/guide/concepts.html +3 -3
  101. package/dist-docs/guide/getting-started.html +5 -5
  102. package/dist-docs/hashmap.json +1 -1
  103. package/dist-docs/index.html +3 -3
  104. package/dist-docs/reference/callbacks.html +3 -3
  105. package/dist-docs/reference/config.html +3 -3
  106. package/dist-docs/reference/data.html +3 -3
  107. package/dist-docs/reference/methods.html +3 -3
  108. package/dist-docs/reference/runtime.html +3 -3
  109. package/dist-docs/reference/types.html +3 -3
  110. package/dist-docs/reference/utils.html +3 -3
  111. package/package.json +20 -5
  112. package/dist/index.cjs.js +0 -1
  113. package/dist/index.es.js +0 -1
  114. package/dist-docs/assets/chunks/@localSearchIndexroot.Daqgr44U.js +0 -1
  115. /package/dist-docs/assets/{guide_getting-started.md.GyXzwIxc.lean.js → guide_getting-started.md.Bn2rTf61.lean.js} +0 -0
@@ -0,0 +1 @@
1
+ import{LAYER_CONTROLS as e}from"../application/AppContainer.js";import{subscribeKey as t}from"valtio/vanilla/utils";import{ForbiddenSweepZone as o}from"../components/Controls/ForbiddenSweepZone.js";import{ForbiddenMopZone as i}from"../components/Controls/ForbiddenMopZone.js";import{CleanZone as a}from"../components/Controls/CleanZone.js";import{VirtualWall as n}from"../components/Controls/VirtualWall.js";import{Spot as r}from"../components/Controls/Spot.js";import{Divider as s}from"../components/Controls/Divider.js";import{Logger as l}from"../utils/logger.js";import{useAppService as d}from"../application/AppService.js";class p{forbiddenSweepZoneMap=new Map;forbiddenMopZoneMap=new Map;cleanZoneMap=new Map;virtualWallMap=new Map;spotMap=new Map;divider=null;unsubscribeFns=[];constructor(){const e=d(),o=t(e.runtime,"editingForbiddenSweepZoneIds",e=>{l.log(`[runtime] editingForbiddenSweepZoneIds: ${e}`),this.updateZonesEditState(this.forbiddenSweepZoneMap)}),i=t(e.runtime,"editingForbiddenMopZoneIds",e=>{l.log(`[runtime] editingForbiddenMopZoneIds: ${e}`),this.updateZonesEditState(this.forbiddenMopZoneMap)}),a=t(e.runtime,"editingCleanZoneIds",e=>{l.log(`[runtime] editingCleanZoneIds: ${e}`),this.updateZonesEditState(this.cleanZoneMap)}),n=t(e.runtime,"editingVirtualWallIds",e=>{l.log(`[runtime] editingVirtualWallIds: ${e}`),this.updateVirtualWallsEditState(this.virtualWallMap)}),r=t(e.runtime,"editingSpotIds",e=>{l.log(`[runtime] editingSpotIds: ${e}`),this.updateSpotsEditState(this.spotMap)}),s=t(e.runtime,"dividingRoomId",e=>{l.log(`[runtime] dividingRoomId: ${e}`),this.handleDividingRoomIdChange(e)});this.unsubscribeFns.push(o,i,a,n,r,s)}updatePositionByOrigin(t,o){const i=d().appContainer.getLayer(e);i&&i.position.set(t,o)}drawForbiddenSweepZones(e){this.drawZones(e,this.forbiddenSweepZoneMap,e=>o.create(e))}getForbiddenSweepZones(){return this.getZonesData(this.forbiddenSweepZoneMap)}clearAllForbiddenSweepZones(){this.clearAllZones(this.forbiddenSweepZoneMap)}drawForbiddenMopZones(e){this.drawZones(e,this.forbiddenMopZoneMap,e=>i.create(e))}getForbiddenMopZones(){return this.getZonesData(this.forbiddenMopZoneMap)}clearAllForbiddenMopZones(){this.clearAllZones(this.forbiddenMopZoneMap)}drawCleanZones(e){this.drawZones(e,this.cleanZoneMap,e=>a.create(e))}getCleanZones(){return this.getZonesData(this.cleanZoneMap)}clearAllCleanZones(){this.clearAllZones(this.cleanZoneMap)}drawVirtualWalls(t){const o=d(),i=this.virtualWallMap,a=new Set(t.map(e=>e.id));for(const[t,n]of i)a.has(t)||(o.appContainer.removeFromLayer(e,n),n.destroy(),i.delete(t));t.forEach(t=>{const a=i.get(t.id);if(a)this.isWallDataEqual(a.getWallData(),t)||a.updateWallData(t);else{const a=new n({wallData:t,events:{onRemove:e=>{o.events?.onRemoveVirtualWall?.(e)},onUpdate:e=>{o.events?.onUpdateVirtualWall?.(e)},onClick:e=>{o.events?.onClickVirtualWall?.(e)}}});i.set(t.id,a),o.appContainer.addToLayer(e,a)}})}getVirtualWalls(){return this.getWallsData(this.virtualWallMap)}clearAllVirtualWalls(){this.clearAllWalls(this.virtualWallMap)}drawSpots(e){const t=this.spotMap;if(!e||0===e.length)return void this.clearAllSpotsInternal(t);const o=new Set(t.keys()),i=new Set(e.map(e=>e.id));for(const e of o)i.has(e)||this.removeSpot(e,t);e.forEach(e=>{const o=t.get(e.id);o?this.isSpotDataEqual(o.getSpotData(),e)||o.updateSpotData(e):this.addNewSpot(e,t)})}getSpots(){return this.getSpotsData(this.spotMap)}clearAllSpots(){this.clearAllSpotsInternal(this.spotMap)}drawZones(e,t,o){if(!e||0===e.length)return void this.clearAllZones(t);const i=new Set(t.keys()),a=new Set(e.map(e=>e.id));for(const e of i)a.has(e)||this.removeZone(e,t);e.forEach(e=>{const i=t.get(e.id);i?this.isZoneDataEqual(i.getZoneData(),e)||i.updateZoneData(e):this.addNewZone(e,t,o)})}addNewZone(t,o,i){const a=d(),n=i(t);o.set(t.id,n),a.appContainer.addToLayer(e,n)}removeZone(t,o){const i=d(),a=o.get(t);a&&(i.appContainer.removeFromLayer(e,a),a.destroy(),o.delete(t))}getZonesData(e){const t=[];return e.forEach(e=>{t.push(e.getZoneData())}),t}clearAllZones(e){e.forEach((t,o)=>{const i=e.get(o);i&&(i.parent?.removeChild(i),i.destroy())}),e.clear()}updateZonesEditState(e){e.forEach(e=>{e.updateEditState()})}updateVirtualWallsEditState(e){e.forEach(e=>{e.updateEditingState()})}isZoneDataEqual(e,t){if(e.id!==t.id)return!1;if(e.points.length!==t.points.length)return!1;for(let o=0;o<e.points.length;o++){const i=e.points[o],a=t.points[o];if(Math.abs(i.x-a.x)>.1||Math.abs(i.y-a.y)>.1)return!1}return!0}getWallsData(e){return Array.from(e.values()).map(e=>e.getWallData())}clearAllWalls(e){for(const t of e.values())t.destroy();e.clear()}isWallDataEqual(e,t){if(e.id!==t.id)return!1;if(e.points.length!==t.points.length)return!1;for(let o=0;o<e.points.length;o++){const i=e.points[o],a=t.points[o];if(Math.abs(i.x-a.x)>.1||Math.abs(i.y-a.y)>.1)return!1}return!0}addNewSpot(t,o){const i=d(),a=r.create(t);o.set(t.id,a),i.appContainer.addToLayer(e,a)}removeSpot(t,o){const i=d(),a=o.get(t);a&&(i.appContainer.removeFromLayer(e,a),a.destroy(),o.delete(t))}getSpotsData(e){const t=[];return e.forEach(e=>{t.push(e.getSpotData())}),t}clearAllSpotsInternal(e){e.forEach((t,o)=>{const i=e.get(o);i&&(i.parent?.removeChild(i),i.destroy())}),e.clear()}updateSpotsEditState(e){e.forEach(e=>{e.updateEditState()})}isSpotDataEqual(e,t){if(e.id!==t.id)return!1;const o=e.point,i=t.point;return!(Math.abs(o.x-i.x)>.1||Math.abs(o.y-i.y)>.1)}handleDividingRoomIdChange(e){null!=e&&this.getRoomGeometry(e)?this.createDefaultDivider(e):this.clearDivider()}getRoomGeometry(e){return d().mapManager.getRoomById(e)}createDefaultDivider(t){const o=d();this.clearDivider(),this.divider=new s({roomId:t,events:{onUpdate:e=>{o.events?.onUpdateDivider?.(e)}}}),o.appContainer.addToLayer(e,this.divider)}clearDivider(){this.divider&&(d().appContainer.removeFromLayer(e,this.divider),this.divider.destroy(),this.divider=null)}getDividerEndPoints(){return this.divider?this.divider.getDividerEndPoints():null}getEffectiveDividerPoints(){return this.divider?this.divider.getEffectiveDividerPoints():null}destroy(){this.clearAllForbiddenSweepZones(),this.clearAllForbiddenMopZones(),this.clearAllCleanZones(),this.clearAllVirtualWalls(),this.clearAllSpots(),this.clearDivider(),this.unsubscribeFns.forEach(e=>e()),this.unsubscribeFns=[]}}export{p as ControlsManager};
@@ -0,0 +1 @@
1
+ import{Assets as e,Ticker as t}from"pixi.js";import{CustomImage as i}from"../components/CustomElements/CustomImage.js";import{CustomGif as s}from"../components/CustomElements/CustomGif.js";import{CustomHTML as a}from"../components/CustomElements/CustomHTML.js";import{LAYER_CUSTOM_ELEMENT as n,LAYER_CUSTOM_ELEMENT_GIF as r}from"../application/AppContainer.js";import{Logger as o}from"../utils/logger.js";import{useAppService as m}from"../application/AppService.js";class p{customElementsMap=new Map;gifTicker=null;gifElements=new Set;constructor(){}updatePositionByOrigin(e,t){const i=m(),s=i.appContainer.getLayer(n),a=i.appContainer.getLayer(r);s&&s.position.set(e,t),a&&a.position.set(e,t)}async drawCustomElements(e){if(!e||0===e.length)return void this.clearAllCustomElements();const t=new Set(e.map(e=>e.id)),i=Array.from(this.customElementsMap.keys());for(const e of i)t.has(e)||this.removeCustomElement(e);const s=e.map(async e=>{const t=this.customElementsMap.get(e.id);t?this.isSameData(t,e)||("gif"===e.type&&t.getElementData().src!==e.src?(this.removeCustomElement(e.id),await this.addNewCustomElement(e)):await this.updateElementData(t,e)):await this.addNewCustomElement(e)});await Promise.all(s),this.updateGifTicker()}clearAllCustomElements(){const e=m();this.customElementsMap.forEach(t=>{t instanceof s?e.appContainer.removeFromLayer(r,t):e.appContainer.removeFromLayer(n,t),t.destroy()}),this.customElementsMap.clear(),this.gifElements.clear(),this.stopGifTicker()}async addNewCustomElement(t){const o=m();let p;switch(t.type){case"image":p=new i(t);break;case"gif":{const i=await e.load(t.src);p=new s(i,t);break}case"html":p=new a(t);break;default:throw new Error(`Unsupported custom element type: ${t.type}`)}await p.initialize(),this.customElementsMap.set(t.id,p),p instanceof s?(o.appContainer.addToLayer(r,p),this.gifElements.add(p)):o.appContainer.addToLayer(n,p)}removeCustomElement(e){const t=m(),i=this.customElementsMap.get(e);i&&(i instanceof s?(this.gifElements.delete(i),t.appContainer.removeFromLayer(r,i)):t.appContainer.removeFromLayer(n,i),i.destroy(),this.customElementsMap.delete(e))}isSameData(e,t){return e.getElementData().type===t.type&&("image"===t.type&&e instanceof i||"gif"===t.type&&e instanceof s||"html"===t.type&&e instanceof a)&&e.isSameData(t)}async updateElementData(e,t){if("image"===t.type&&e instanceof i)await e.updateElementData(t);else if("gif"===t.type&&e instanceof s)await e.updateElementData(t);else{if(!("html"===t.type&&e instanceof a))throw new Error("Element type mismatch during update");await e.updateElementData(t)}}updateGifTicker(){this.gifElements.size>0?this.startGifTicker():this.stopGifTicker()}startGifTicker(){this.gifTicker?.started||(this.gifTicker?this.gifTicker.maxFPS=1:(this.gifTicker=new t,this.gifTicker.maxFPS=1,this.gifTicker.add(()=>{this.renderGifContainer()})),this.gifTicker.start())}stopGifTicker(){this.gifTicker?.started&&(o.log("⏸️ [GifTicker] 停止 GIF 专用渲染"),this.gifTicker.stop())}renderGifContainer(){const e=m();if(0===this.gifElements.size)return;const t=e.getApp();t.renderer.render(t.stage)}destroy(){this.stopGifTicker(),this.gifTicker&&(this.gifTicker.destroy(),this.gifTicker=null),this.clearAllCustomElements()}}export{p as CustomElementsManager};
@@ -0,0 +1 @@
1
+ import{LAYER_DETECTED_OBJECT as e}from"../application/AppContainer.js";import{DetectedObject as t}from"../components/DetectedObject/index.js";import{useAppService as a}from"../application/AppService.js";class c{detectedObjectMap=new Map;updatePositionByOrigin(t,c){const i=a().appContainer.getLayer(e);i&&i.position.set(t,c)}async drawDetectedObjects(e){if(!e||0===e.length)return void this.clearAllDetectedObjects();const t=new Set(e.map(e=>e.id)),a=Array.from(this.detectedObjectMap.keys());for(const e of a)t.has(e)||this.removeDetectedObject(e);for(const t of e){const e=this.detectedObjectMap.get(t.id);e?e.isSameData(t)||await e.updateObjectData(t):await this.addNewDetectedObject(t)}}clearAllDetectedObjects(){const t=a();this.detectedObjectMap.forEach(a=>{t.appContainer.removeFromLayer(e,a),a.destroy()}),this.detectedObjectMap.clear()}async addNewDetectedObject(c){const i=a(),o=new t(c);await o.initializeSprite(),this.detectedObjectMap.set(c.id,o),i.appContainer.addToLayer(e,o)}removeDetectedObject(t){const c=a(),i=this.detectedObjectMap.get(t);i&&(c.appContainer.removeFromLayer(e,i),i.destroy(),this.detectedObjectMap.delete(t))}destroy(){this.clearAllDetectedObjects()}}export{c as DetectedObjectManager};
@@ -0,0 +1 @@
1
+ import{Heatmap as t}from"../components/Heatmap/index.js";import{useAppService as i}from"../application/AppService.js";class a{heatmap=new t;pointsTopLeftOrigin=[];signalGrid=[];cellSize=2;maxDistance=14;smoothIterations=10;heatmapAlpha=.8;constructor(){const t=i().heatMapConfig;this.cellSize=t.cellSize,this.maxDistance=t.maxDistance,this.smoothIterations=t.smoothIterations,this.heatmapAlpha=t.heatmapAlpha}draw({mapData:t,heatmapPoints:a,useGradient:e=!0}){const s=i(),l=t.origin[0],n=t.origin[1],{minX:o,minY:h}=s.mapManager.mapBounds,r=a.map(t=>({x:+(l+t.x-o).toFixed(0),y:+(n+t.y-h).toFixed(0),signal:t.signal}));this.signalGrid=this.calculateInterpolatedSignal(r),this.heatmap.draw(this.signalGrid,e,this.heatmapAlpha)}calculateInterpolatedSignal(t){const a=i(),{minX:e,minY:s,maxX:l,maxY:n}=a.mapManager.mapBounds,o=Math.ceil((n-s)/this.cellSize),h=Math.ceil((l-e)/this.cellSize),r=Array(o).fill(null).map(()=>Array(h).fill(null));for(let i=0;i<o;i++){const a=s+i*this.cellSize+this.cellSize/2,o=Math.min(this.cellSize,n-(a-this.cellSize/2));for(let s=0;s<h;s++){const n=e+s*this.cellSize+this.cellSize/2,h=Math.min(this.cellSize,l-(n-this.cellSize/2));let c=0,m=!1;for(let i=0;i<t.length;i++){const e=t[i];if(Math.abs(n-e.x)<=h/2&&Math.abs(a-e.y)<=o/2){const t=1-e.signal/7;c=Math.round(10*Math.max(c,t))/10,m=!0}}r[i][s]={x:n,y:a,signal:c,hasPoint:m}}}const c=(i,a)=>{if(0===t.length)return 0;let e=0,s=0;for(const l of t){const t=Math.sqrt((i-l.x)**2+(a-l.y)**2);if(t<=this.maxDistance){const i=1/(1+t);s+=i*(1-l.signal/7),e+=i}}return 0===e?0:Math.round(s/e*1e3)/1e3};for(let t=0;t<o;t++)for(let i=0;i<h;i++){const a=r[t][i];a.hasPoint||(a.signal=c(a.x,a.y))}return((t,i=1)=>{for(let a=0;a<i;a++){const i=t.map(t=>[...t]);for(let a=1;a<o-1;a++)for(let e=1;e<h-1;e++)if(!t[a][e].hasPoint){let s=0,l=0;const n=4;for(let i=-n;i<=n;i++)for(let r=-n;r<=n;r++){if(0===i&&0===r)continue;const n=a+i,c=e+r;if(n>=0&&n<o&&c>=0&&c<h){const a=1/(1+.3*Math.sqrt(i*i+r*r));s+=t[n][c].signal*a,l+=a}}if(l>0){const n=s/l,o=.6,h=.4;i[a][e].signal=t[a][e].signal*o+n*h,i[a][e].signal>.1&&(i[a][e].signal=Math.max(i[a][e].signal,.2))}}for(let a=0;a<o;a++)for(let e=0;e<h;e++)t[a][e].signal=i[a][e].signal}})(r,this.smoothIterations),r}}export{a as HeatmapManager};
@@ -0,0 +1 @@
1
+ import{isEqual as t}from"lodash-es";import{Logger as o}from"../utils/logger.js";import{Rectangle as e}from"pixi.js";import{calculateRasterMapBounds as s,generateOutlineData as a,calculateRoomCenterPoint as r,mergeBounds as i,calculateRasterRoomCenter as n}from"../utils/algorithm.js";import{Obstacle as m}from"../components/Map/Obstacle.js";import{Free as h}from"../components/Map/Free.js";import{RoomFill as c}from"../components/Map/RoomFill.js";import{Carpet as p}from"../components/Map/Carpet.js";import{ChargingStation as l}from"../components/ChargingStation/index.js";import{subscribeKey as u}from"valtio/vanilla/utils";import{SPECIAL_ROOM_IDS as d}from"@ray-js/robot-protocol";import{useAppService as g}from"../application/AppService.js";class f{obstacle=new m;free=new h;roomFill=new c;carpet=new p;chargingStation=new l;mapBounds={minX:0,minY:0,maxX:0,maxY:0};hasAutoFitted=!1;roomGeometryMap=new Map;carpetData=null;unsubscribeFns=[];constructor(){const t=g(),e=u(t.runtime,"enableRoomSelection",e=>{if(o.log(`[runtime] enableRoomSelection: ${e}`),e){this.roomFill.setAllRoomsState(!1);const o=t.runtimeSnapshot.selectRoomIds;this.roomFill.setRoomStateBySelectIds(o)}else this.roomFill.setAllRoomsState(!0)}),s=u(t.runtime,"selectRoomIds",t=>{o.log(`[runtime] selectRoomIds: ${t}`),this.roomFill.setRoomStateBySelectIds(t)}),a=u(t.runtime,"showChargingStation",t=>{o.log(`[runtime] showChargingStation: ${t}`),this.chargingStation.visible=t}),r=u(t.runtime,"showCarpet",t=>{o.log(`[runtime] showCarpet: ${t}`),t?this.createCarpet():this.carpet.clearCarpet()});this.unsubscribeFns.push(e,s,a,r)}async drawMap(e){const s=g(),{obstacles:a,free:r,rooms:i,charger:n,carpet:m}=e;this.clearComponents(),this.resetGeometryData();const h=this.processRoomsGeometry(i);this.roomFill.draw(h),this.free.draw(r),this.obstacle.draw(a),this.carpetData={type:"structured",carpetData:m},this.createCarpet();const c=this.mergeLayerBounds();t(c,this.mapBounds)||(o.debug("[Map] Map bounds updated:",c),this.mapBounds=c,this.hasAutoFitted||(s.getApp().fitMapToView(this.mapBounds),this.hasAutoFitted=!0));const p=((e.charger.angle??0)+s.chargingStationConfig.rotationCorrection)*Math.PI/180;return await this.chargingStation.draw({x:n.coordinate[0],y:n.coordinate[1],rotation:p}),s.roomsManager.refresh(),!0}async drawRasterMap(e,a){const r=g();this.clearComponents();const{width:i,height:n,charger:m,chargerDirection:h}=a;o.debug("[Map] Parsed Raster Map Data",e),this.obstacle.drawRaster(e.obstacles,i),this.carpetData={type:"raster",carpetPixels:e.carpet,mapWidth:i},this.createCarpet();const c=this.processRasterData(e);this.roomFill.drawRaster(c);const p=s(e,i,n);t(p,this.mapBounds)||(o.debug("[Map] Raster map bounds updated:",p),this.mapBounds=p,this.hasAutoFitted||(r.getApp().fitMapToView(this.mapBounds),this.hasAutoFitted=!0));const l=(h+r.chargingStationConfig.rotationCorrection)*Math.PI/180;return await this.chargingStation.draw({x:m.x,y:m.y,rotation:l}),this.generateRoomGeometryFromRaster(e),r.roomsManager.refresh(),!0}resetGeometryData(){this.roomGeometryMap.clear(),this.mapBounds={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}async createCarpet(){if(g().runtimeSnapshot.showCarpet&&this.carpetData)if("raster"===this.carpetData.type){const{carpetPixels:t,mapWidth:o}=this.carpetData;await this.carpet.createCarpetFromRasterData(t,o)}else if("structured"===this.carpetData.type){const{carpetData:t}=this.carpetData;await this.carpet.createCarpetFromStructuredData(t)}}processRoomsGeometry(t){if(!t)return[];const o=g(),{active:s}=o.roomConfig.colors,i=o.roomConfig.colors[d.UNKNOWN_ROOM];if(0===Object.keys(t).length)return this.mapBounds={minX:0,minY:0,maxX:0,maxY:0},[];const n=Object.keys(t).sort((t,o)=>Number(t)-Number(o)),m=n.filter(t=>Number(t)<255),h=n.filter(t=>Number(t)>=255),c=[];return m.forEach((o,i)=>{const{coordinates:n}=t[o];if(n.length<4)return;const m=Number(o),h=i%s.length,p=s[h];let l=1/0,u=1/0,d=-1/0,g=-1/0;const f=[];for(let t=0;t<n.length;t+=2){const o=n[t],e=n[t+1];l=Math.min(l,o),u=Math.min(u,e),d=Math.max(d,o),g=Math.max(g,e),f.push({x:o,y:e})}const y=new e(l,u,d-l+1,g-u+1),b=a(f),M=b.flatMap(t=>[t.x+.5,t.y+.5]),x={id:m,color:p,boundingBox:y,points:f,outlinePoints:b,polyPoints:M,centerPoint:r(b,l,u,d,g)};this.roomGeometryMap.set(m,x),c.push(x),this.mapBounds.minX=Math.min(this.mapBounds.minX,l),this.mapBounds.minY=Math.min(this.mapBounds.minY,u),this.mapBounds.maxX=Math.max(this.mapBounds.maxX,d),this.mapBounds.maxY=Math.max(this.mapBounds.maxY,g)}),h.forEach(o=>{const{coordinates:s}=t[o];if(s.length<4)return;const n=Number(o);let m=1/0,h=1/0,p=-1/0,l=-1/0;const u=[];for(let t=0;t<s.length;t+=2){const o=s[t],e=s[t+1];m=Math.min(m,o),h=Math.min(h,e),p=Math.max(p,o),l=Math.max(l,e),u.push({x:o,y:e})}const d=new e(m,h,p-m+1,l-h+1),g=a(u),f=g.flatMap(t=>[t.x+.5,t.y+.5]),y=r(g,m,h,p,l),b={id:n,color:i,boundingBox:d,points:u,outlinePoints:g,polyPoints:f,centerPoint:y};c.push(b),this.mapBounds.minX=Math.min(this.mapBounds.minX,m),this.mapBounds.minY=Math.min(this.mapBounds.minY,h),this.mapBounds.maxX=Math.max(this.mapBounds.maxX,p),this.mapBounds.maxY=Math.max(this.mapBounds.maxY,l)}),c}mergeLayerBounds(){let t={...this.mapBounds};if(this.obstacle.bounds&&(t=i(t,this.obstacle.bounds)),this.roomFill.children.length>0){const o=this.roomFill.getLocalBounds();o.width>0&&o.height>0&&(t=i(t,{minX:o.x,minY:o.y,maxX:o.x+o.width,maxY:o.y+o.height}))}return t}getRoomById(t){return this.roomGeometryMap.get(t)}clearComponents(){this.obstacle.clear(),this.obstacle.destroy(),this.obstacle=new m,this.free.clear(),this.free.destroy(),this.free=new h,this.carpet.clearCarpet(),this.carpetData=null,this.roomFill.removeChildren(),this.roomFill.destroy(),this.roomFill=new c}processRasterData(t){const o=g().roomConfig,e=[],s=[];t.rooms.forEach((t,o)=>{"number"==typeof o?e.push([o,t]):s.push([o,t])}),e.sort(([t],[o])=>t-o);const a=[...e.map(([t,e],s)=>{const a=s%o.colors.active.length,r=s%o.colors.inactive.length;return{roomId:t,pixelIndices:e,activeColor:o.colors.active[a],inactiveColor:o.colors.inactive[r]}}),...s.map(([t,e])=>{const s=o.colors[t]||"#ebebeb";return{roomId:t,pixelIndices:e,activeColor:s,inactiveColor:s}})];return{obstacles:t.obstacles,carpet:t.carpet,sortedRooms:a,width:t.width,height:t.height,totalPixels:t.totalPixels}}generateRoomGeometryFromRaster(t){const o=g();this.roomGeometryMap.clear();const{active:s}=o.roomConfig.colors,a=[];t.rooms.forEach((t,o)=>{"number"==typeof o&&a.push(o)}),a.sort((t,o)=>t-o),a.forEach((o,a)=>{const r=t.rooms.get(o);let i=1/0,m=1/0,h=-1/0,c=-1/0;for(let o=0;o<r.length;o++){const e=r[o],s=e%t.width,a=Math.floor(e/t.width);i=Math.min(i,s),m=Math.min(m,a),h=Math.max(h,s),c=Math.max(c,a)}const p=n(r,t.width,i,m,h,c),l=a%s.length,u={id:o,color:s[l],boundingBox:new e(i,m,h-i+1,c-m+1),points:[],outlinePoints:[],polyPoints:[],centerPoint:p};this.roomGeometryMap.set(o,u)})}destroy(){this.obstacle.destroy(),this.free.destroy(),this.roomFill.destroy(),this.carpet.destroy(),this.chargingStation.destroy(),this.unsubscribeFns.forEach(t=>t()),this.unsubscribeFns=[]}}export{f as MapManager};
@@ -0,0 +1 @@
1
+ import{subscribeKey as t}from"valtio/vanilla/utils";import{Path as o}from"../components/Path/index.js";import{Robot as i}from"../components/Robot/index.js";import{Logger as s}from"../utils/logger.js";import{useAppService as a}from"../application/AppService.js";class n{path;robot;unsubscribeFns=[];lastDrawnPathData=null;constructor(){const n=a();this.path=new o,this.robot=new i;const r=t(n.runtime,"showPath",t=>{s.log(`[runtime] showPath: ${t}`),this.path.visible=t,this.robot.visible=t});this.unsubscribeFns.push(r)}draw(t){this.shouldUseIncrementalDraw(t)?this.incrementalDraw(t):this.fullDraw(t),this.lastDrawnPathData=t}shouldUseIncrementalDraw(t){const o=a();if(!this.lastDrawnPathData)return!1;const i=t.pathHeader?.pathId,s=this.lastDrawnPathData.pathHeader?.pathId;if(i!==s)return!1;const n=(t.pathPoints?.length||0)-(this.lastDrawnPathData.pathPoints?.length||0),r=o.pathConfig.incrementalThreshold;return!(n<=0||n>r)}fullDraw(t){if(this.path.stopRealTimeDrawing(),this.path.drawFull(t),t.pathPoints&&t.pathPoints.length>0){const o=t.pathPoints[t.pathPoints.length-1];this.moveRobotToPoint(o,t.pathHeader.direction,!1)}}convertToRobotPoint(t,o){const i=o+a().robotConfig.rotationCorrection;return{x:t.x,y:t.y,rotation:i*Math.PI/180,type:t.type}}moveRobotToPoint(t,o,i=!0){const s=this.convertToRobotPoint(t,o);i?this.robot.moveTo(s):(this.robot.remove(),this.robot.draw(s))}incrementalDraw(t){const o=a();if(!this.lastDrawnPathData||!t.pathPoints)return;this.path.drawIncremental(t);const i=this.lastDrawnPathData.pathPoints?.length||0,s=t.pathPoints.slice(i);if(0!==s.length)if(o.robotConfig.speed>0)s.forEach(o=>{this.moveRobotToPoint(o,t.pathHeader.direction,!0)});else{const o=s[s.length-1];this.moveRobotToPoint(o,t.pathHeader.direction,!1)}}batchProcessRobotQueue(t=!1){this.robot.batchProcessQueue(t)}updatePositionByOrigin(t,o){this.path.updatePositionByOrigin(t,o),this.robot.updatePositionByOrigin(t,o)}destroy(){this.unsubscribeFns.forEach(t=>t()),this.unsubscribeFns=[],this.path.destroy(),this.robot.destroy()}}export{n as PathManager};
@@ -0,0 +1 @@
1
+ import{Container as o}from"pixi.js";import{LAYER_ROOM_INFO as t}from"../application/AppContainer.js";import{RoomInfo as i}from"../components/RoomInfo/index.js";import{RoomFloorType as e}from"../components/RoomFloorType/index.js";import{subscribeKey as r}from"valtio/vanilla/utils";import{Logger as s}from"../utils/logger.js";import{useAppService as n}from"../application/AppService.js";class a{unsubscribeFns=[];roomInfoContainer=new o;roomInfoMap=new Map;roomDisplayMap=new Map;roomFloorType=new e;constructor(){const o=n();o.appContainer.addToLayer(t,this.roomInfoContainer);const i=r(o.runtime,"showRoomFloorType",o=>{s.log(`[runtime] showRoomFloorType: ${o}`),o?this.updateFloorTypes():this.roomFloorType.clearFloorTypes()}),e=r(o.runtime,"showRoomProperty",o=>{s.log(`[runtime] showRoomProperty: ${o}`),this.updateAllRoomPropertyVisibility()}),a=r(o.runtime,"showRoomOrder",o=>{s.log(`[runtime] showRoomOrder: ${o}`),this.updateAllRoomPropertyVisibility()}),m=r(o.runtime,"roomPropertyFoldIds",o=>{s.log(`[runtime] roomPropertyFoldIds: ${o}`),this.updateAllRoomPropertyVisibility()}),l=r(o.runtime,"showRoomName",o=>{s.log(`[runtime] showRoomName: ${o}`),this.updateAllRoomNameVisibility(o)}),p=r(o.runtime,"enableRoomSelection",o=>{s.log(`[runtime] enableRoomSelection: ${o}`),this.updateAllRoomPropertyVisibility(),this.updateAllRoomSelectionIndicatorVisibility()}),c=r(o.runtime,"selectRoomIds",o=>{s.log(`[runtime] selectRoomIds: ${o}`),this.updateAllRoomSelectionIndicatorVisibility()}),h=r(o.runtime,"roomSelectionMode",o=>{s.log(`[runtime] roomSelectionMode: ${o}`),this.updateAllRoomPropertyVisibility(),this.updateAllRoomSelectionIndicatorVisibility()});this.unsubscribeFns.push(i,e,a,m,l,p,c,h)}drawRoomProperty(o){const t=n();return this.roomDisplayMap.clear(),o.forEach((o,i)=>{const e=t.mapManager.getRoomById(o.id),r={...o,centerPoint:e?.centerPoint||null,index:i};this.roomDisplayMap.set(o.id,r)}),this.updateRoomInfoDisplay(),this.updateFloorTypes(),!0}updateRoomInfoDisplay(){if(0===this.roomDisplayMap.size)return;const o=Array.from(this.roomDisplayMap.values()).filter(o=>null!==o.centerPoint);this.clearRoomInfos(),o.forEach(o=>{this.createRoomInfo(o)})}createRoomInfo(o){const t=new i(o);this.roomInfoContainer.addChild(t),this.roomInfoMap.set(o.id,t)}updateRoomName(o,t){const i=this.roomInfoMap.get(o);i&&i.updateName(t)}updateRoomPosition(o,t){const i=this.roomDisplayMap.get(o);i&&(i.centerPoint=t);const e=this.roomInfoMap.get(o);e&&e.updatePosition(t)}clearRoomInfos(){this.roomInfoMap.forEach(o=>{o.destroy()}),this.roomInfoMap.clear(),this.roomInfoContainer.removeChildren()}getRoomPropertyById(o){return this.roomDisplayMap.get(o)}refresh(){const o=n();this.roomDisplayMap.forEach((t,i)=>{const e=o.mapManager.getRoomById(i),r=e?.centerPoint||null;if(t.centerPoint!==r){t.centerPoint=r;const o=this.roomInfoMap.get(i);o&&r&&o.updatePosition(r)}}),this.updateRoomInfoDisplay(),this.updateFloorTypes()}updateAllRoomPropertyVisibility(){this.roomInfoMap.forEach(o=>{o.updateRoomPropertyVisibility()})}updateAllRoomNameVisibility(o){this.roomInfoMap.forEach(t=>{t.updateRoomNameVisibility(o)})}updateAllRoomSelectionIndicatorVisibility(){this.roomInfoMap.forEach(o=>{o.updateRoomSelectionIndicatorVisibility()})}async updateFloorTypes(){const o=n(),t=o.mapManager.roomFill.getRoomGraphicsMap();t.size>0&&(await this.roomFloorType.createFloorTypes(t),o.getApp().renderOnceNextFrame())}destroy(){this.clearRoomInfos(),this.roomInfoContainer.destroy(),this.roomFloorType.destroy(),this.unsubscribeFns.forEach(o=>o()),this.unsubscribeFns=[]}}export{a as RoomManager};
@@ -0,0 +1 @@
1
+ class t{target;isPointerDown=!1;pointerDownPos=null;clickThreshold;stopPropagation;clickCallback=null;constructor(t,i={}){this.target=t,this.clickThreshold=i.clickThreshold??10,this.stopPropagation=i.stopPropagation??!1,this.clickCallback=i.onClick||null,this.setup()}setup(){this.target.interactive=!0,this.target.eventMode="static",this.target.on("pointerdown",this.handlePointerDown.bind(this)),this.target.on("pointermove",this.handlePointerMove.bind(this)),this.target.on("pointerup",this.handlePointerUp.bind(this)),this.target.on("pointerupoutside",this.handlePointerUpOutside.bind(this))}handlePointerDown(t){this.stopPropagation&&t.stopPropagation(),this.isPointerDown=!0,this.pointerDownPos={x:t.globalX,y:t.globalY}}handlePointerMove(t){if(this.stopPropagation&&t.stopPropagation(),this.isPointerDown&&this.pointerDownPos){const i=t.globalX-this.pointerDownPos.x,o=t.globalY-this.pointerDownPos.y;Math.sqrt(i*i+o*o)>this.clickThreshold&&(this.isPointerDown=!1,this.pointerDownPos=null)}}handlePointerUp(t){if(this.stopPropagation&&t.stopPropagation(),this.isPointerDown&&this.pointerDownPos){const i=t.globalX-this.pointerDownPos.x,o=t.globalY-this.pointerDownPos.y;Math.sqrt(i*i+o*o)<=this.clickThreshold&&this.clickCallback&&this.clickCallback(t,this.target)}this.isPointerDown=!1,this.pointerDownPos=null}handlePointerUpOutside(){this.isPointerDown=!1,this.pointerDownPos=null}setClickCallback(t){return this.clickCallback=t,this}setClickThreshold(t){return this.clickThreshold=t,this}getTarget(){return this.target}isInteracting(){return this.isPointerDown}destroy(){this.target.off("pointerdown",this.handlePointerDown),this.target.off("pointermove",this.handlePointerMove),this.target.off("pointerup",this.handlePointerUp),this.target.off("pointerupoutside",this.handlePointerUpOutside),this.clickCallback=null}}export{t as ClickHandler};
@@ -0,0 +1 @@
1
+ const t=t=>{if(t.length<=1)return[...t];const r=n(t),y=r.slice(1).map((t,n)=>({prev:r[n],current:t})),e=new Map;return y.forEach(({prev:t,current:n})=>{x(t,n).forEach(t=>{const n=`${t.x},${t.y}`;e.has(n)||e.set(n,t)})}),Array.from(e.values())},n=t=>{if(t.length<=1)return[...t];const n=t[0],x=t[t.length-1];return n.x===x.x&&n.y===x.y?[...t]:[...t,n]},x=(t,n)=>{const x=[],r=Math.abs(n.x-t.x),y=Math.abs(n.y-t.y),e=t.x<n.x?1:-1,a=t.y<n.y?1:-1;let h=r-y,o=t.x,s=t.y;for(;x.push({x:o,y:s}),o!==n.x||s!==n.y;){const t=2*h;t>-y&&(h-=y,o+=e),t<r&&(h+=r,s+=a)}return x},r=(t,n,x=1,r=2e3)=>{const y=[],e=n.x-t.x,a=n.y-t.y,h=Math.sqrt(e*e+a*a);if(0===h)return[t];const o=Math.min(Math.max(Math.ceil(h/x),2),r);for(let n=0;n<=o;n++){const x=n/o,r={x:t.x+x*e,y:t.y+x*a};y.push(r)}return y},y=(t,n,x,r,y,h=8)=>{const s={x:(n+r)/2,y:(x+y)/2},i=r-n,m=y-x,c=Math.min(h,.2*Math.min(i,m));return o(s,t)&&a(s,t)>=c?s:e(t,s,c)},e=(t,n,x)=>{const{minX:r,minY:y,maxX:e,maxY:h}=m(t),s=e-r,i=h-y,c=n.x,u=n.y,M=Math.min(.5,.05*Math.min(s,i)),f=[];if(o({x:c,y:u},t)){const n=a({x:c,y:u},t);f.push({point:{x:c,y:u},distance:n,centerDistance:0})}const g=.6*Math.max(s,i),p=Math.PI/16;for(let n=M;n<=g;n+=M){const s=p*(1+n/g);for(let i=0;i<2*Math.PI;i+=s){const s=c+n*Math.cos(i),m=u+n*Math.sin(i);if(s>=r&&s<=e&&m>=y&&m<=h){const n={x:s,y:m};if(o(n,t)){const r=a(n,t),y=l({x:s,y:m},{x:c,y:u});r>=x&&f.push({point:n,distance:r,centerDistance:y})}}}if(f.length>=15)break}if(f.length>0){const t=f.map(t=>({...t,score:1.5*t.distance-.5*t.centerDistance}));return t.sort((t,n)=>n.score-t.score),t[0].point}if(0===f.length){let n={x:c,y:u},x=0;const s=2*M;for(let i=r;i<=e;i+=s)for(let r=y;r<=h;r+=s){const y={x:i,y:r};if(o(y,t)){const r=a(y,t);r>x&&(x=r,n=y)}}return n}return{x:c,y:u}},a=(t,n)=>{let x=1/0;for(let r=0,y=n.length-1;r<n.length;y=r++){const e=n[y],a=n[r],o=h(t,e,a);x=Math.min(x,o)}return x},h=(t,n,x)=>{const r=(n.x-x.x)**2+(n.y-x.y)**2;if(0===r)return l(t,n);const y=Math.max(0,Math.min(1,((t.x-n.x)*(x.x-n.x)+(t.y-n.y)*(x.y-n.y))/r)),e=n.x+y*(x.x-n.x),a=n.y+y*(x.y-n.y);return l(t,{x:e,y:a})},o=(t,n,x=!1)=>{if(n.length<3)return!1;if(x&&s(t,n))return!0;let r=!1;for(let x=0,y=n.length-1;x<n.length;y=x++){const e=n[x].x,a=n[x].y,h=n[y].x,o=n[y].y;a>t.y!=o>t.y&&t.x<(h-e)*(t.y-a)/(o-a)+e&&(r=!r)}return r},s=(t,n)=>{if(n.length<2)return!1;for(let x=0;x<n.length;x++){const r=(x+1)%n.length;if(i(t,n[x],n[r]))return!0}return!1},i=(t,n,x,r=.5)=>{if(h(t,n,x)>r)return!1;const y=Math.min(n.x,x.x)-r,e=Math.max(n.x,x.x)+r,a=Math.min(n.y,x.y)-r,o=Math.max(n.y,x.y)+r;return t.x>=y&&t.x<=e&&t.y>=a&&t.y<=o},m=t=>{if(0===t.length)return{minX:0,minY:0,maxX:0,maxY:0};let n=1/0,x=1/0,r=-1/0,y=-1/0;for(const e of t)n=Math.min(n,e.x),x=Math.min(x,e.y),r=Math.max(r,e.x),y=Math.max(y,e.y);return{minX:n,minY:x,maxX:r,maxY:y}},c=t=>{const n=t.reduce((t,n)=>({x:t.x+n.x,y:t.y+n.y}),{x:0,y:0});return{x:n.x/t.length,y:n.y/t.length}},u=t=>{if(4!==t.length)return t;const n=c(t),x=l(t[0],t[1]),r=l(t[1],t[2]),y=Math.atan2(t[1].y-t[0].y,t[1].x-t[0].x),e=[{x:-x/2,y:-r/2},{x:x/2,y:-r/2},{x:x/2,y:r/2},{x:-x/2,y:r/2}],a=Math.cos(y),h=Math.sin(y);return e.map(t=>({x:t.x*a-t.y*h+n.x,y:t.x*h+t.y*a+n.y}))},M=(t,n,x,r=10)=>{if(0===x)return 1;const y=(t.x*n.x+t.y*n.y)/x/x,e=r/x;return y<=0?e:Math.max(y,e)},l=(t,n)=>{const x=t.x-n.x,r=t.y-n.y;return Math.sqrt(x*x+r*r)},f=t=>Math.sqrt(t.x*t.x+t.y*t.y),g=(t,n)=>({x:n.x-t.x,y:n.y-t.y}),p=t=>{const n=f(t);return 0===n?{x:0,y:0}:{x:t.x/n,y:t.y/n}},X=(t,n)=>{const x=g(t,n);return p(x)},Y=t=>({x:-t.y,y:t.x}),d=(t,n)=>{const x=X(t,n);return Y(x)},w=(t,n)=>{const x=p(t),r=p(n),y={x:(x.x+r.x)/2,y:(x.y+r.y)/2};return p(y)},b=(t,n)=>{const x=g(t,n);let r=Math.atan2(x.y,x.x);return(r>Math.PI/2||r<-Math.PI/2)&&(r+=Math.PI),r},q=(t,n,x)=>{const r=c([t,n]),y=d(t,n);return{x:r.x+y.x*x,y:r.y+y.y*x}},I=(t,n,x)=>{const r=Math.cos(x),y=Math.sin(x),e=t.x-n.x,a=t.y-n.y;return{x:e*r-a*y+n.x,y:e*y+a*r+n.y}},P=(t,n,x)=>t.map(t=>I(t,n,x)),E=(t,n,x)=>{if(0===l(t,n))return[t,t,t,t];const r=X(t,n),y=Y(r),e=t.x-r.x*x,a=t.y-r.y*x,h=n.x+r.x*x,o=n.y+r.y*x;return[{x:e+y.x*x,y:a+y.y*x},{x:h+y.x*x,y:o+y.y*x},{x:h-y.x*x,y:o-y.y*x},{x:e-y.x*x,y:a-y.y*x}]},v=(t,n)=>{if(t.length<3)return t;const x=[];for(let r=0;r<t.length;r++){const y=t[r],e=t[(r+1)%t.length],a=t[(r-1+t.length)%t.length],h=g(y,e);if(0===f(h)){x.push(y);continue}const o=p(h),s={x:o.y,y:-o.x},i=g(a,y);let m={x:0,y:0};if(f(i)>0){const t=p(i);m={x:t.y,y:-t.x}}const c=w(m,s),u=m.x*s.x+m.y*s.y,M=1/Math.max(.1,Math.sqrt((1+u)/2)),l={x:y.x+c.x*n*M,y:y.y+c.y*n*M};x.push(l)}return x},D=(t,n,x)=>{if(0===l(t,n))return[];const r=d(t,n),y=x/2;return[t.x+r.x*y,t.y+r.y*y,n.x+r.x*y,n.y+r.y*y,n.x-r.x*y,n.y-r.y*y,t.x-r.x*y,t.y-r.y*y]},$=(t,n,x,r)=>{const y=g(t,n),e=g(t,x),a=w(y,e),h=-a.x,o=-a.y;return{x:t.x+h*r,y:t.y+o*r}},k=(t,n,x,r,y,e)=>{const a=new Set(t),h=z(t,n);return A(h,a,n,x,r,y,e)||h},z=(t,n)=>{let x=0,r=0;for(let y=0;y<t.length;y++){const e=t[y];x+=e%n,r+=Math.floor(e/n)}return{x:x/t.length,y:r/t.length}},A=(t,n,x,r,y,e,a)=>{const h={x:r-10,y:t.y},o={x:e+10,y:t.y},s={x:e,y:y},i={x:e,y:a},m=S(h,o,{x:r,y:y},{x:r,y:a}),c=S(h,o,s,i);if(!m||!c)return null;const u=[],M=Math.max(r,Math.min(m.x,c.x)),l=Math.min(e,Math.max(m.x,c.x)),f=Math.round(t.y);for(let t=Math.round(M);t<=Math.round(l);t++){const r=f*x+t;n.has(r)&&u.push({x:t,y:f})}if(u.length>=2){const t=j(u),r={x:(t.min.x+t.max.x)/2,y:(t.min.y+t.max.y)/2},y=Math.round(r.y)*x+Math.round(r.x);if(n.has(y))return r}return null},S=(t,n,x,r)=>{const y=(t.x-x.x)*(n.y-x.y)-(t.y-x.y)*(n.x-x.x),e=(t.x-r.x)*(n.y-r.y)-(t.y-r.y)*(n.x-r.x);if(y*e>=0)return null;const a=(x.x-t.x)*(r.y-t.y)-(x.y-t.y)*(r.x-t.x);if(a*(a+y-e)>=0)return null;const h=a/(e-y),o=h*(n.x-t.x),s=h*(n.y-t.y);return{x:t.x+o,y:t.y+s}},j=t=>{if(!t||0===t.length)return{min:{x:0,y:0},max:{x:0,y:0}};let n=t[0],x=t[0];const r=t=>t.x-t.y;for(let y=1;y<t.length;y++){const e=t[y];r(e)<r(n)&&(n=e),r(e)>r(x)&&(x=e)}return{min:n,max:x}},B=(t,n)=>({minX:Math.min(t.minX,n.minX),minY:Math.min(t.minY,n.minY),maxX:Math.max(t.maxX,n.maxX),maxY:Math.max(t.maxY,n.maxY)}),C=t=>{if(0===t.length)return{x:0,y:0,width:0,height:0};let n=t[0].x,x=t[0].y,r=t[0].x+t[0].width,y=t[0].y+t[0].height;return t.forEach(t=>{n=Math.min(n,t.x),x=Math.min(x,t.y),r=Math.max(r,t.x+t.width),y=Math.max(y,t.y+t.height)}),{x:n,y:x,width:r-n,height:y-x}},F=(t,n,x)=>{let r=1/0,y=1/0,e=-1/0,a=-1/0;for(let x=0;x<t.obstacles.length;x++){const h=t.obstacles[x],o=h%n,s=Math.floor(h/n);r=Math.min(r,o),y=Math.min(y,s),e=Math.max(e,o),a=Math.max(a,s)}return t.rooms.forEach(t=>{for(let x=0;x<t.length;x++){const h=t[x],o=h%n,s=Math.floor(h/n);r=Math.min(r,o),y=Math.min(y,s),e=Math.max(e,o),a=Math.max(a,s)}}),r===1/0?{minX:0,minY:0,maxX:n,maxY:x}:{minX:Math.max(0,r),minY:Math.max(0,y),maxX:Math.min(n,e),maxY:Math.min(x,a)}},G=(t,n,x,r,y,e)=>{const a=x+y,h=r+e,o=Math.min(t.x,n.x),s=Math.max(t.x,n.x),i=Math.min(t.y,n.y),m=Math.max(t.y,n.y);if(s<x||o>a||m<r||i>h)return!1;if(H(t,x,r,y,e)||H(n,x,r,y,e))return!0;const c=[{x:x,y:r},{x:a,y:r},{x:a,y:h},{x:x,y:h}];for(let x=0;x<4;x++)if(S(t,n,c[x],c[(x+1)%4]))return!0;return!1},H=(t,n,x,r,y)=>t.x>=n&&t.x<=n+r&&t.y>=x&&t.y<=x+y,J=(t,n,x,r)=>{const y=x/2;return"horizontal"===r?[{x:t-y,y:n},{x:t+y,y:n}]:[{x:t,y:n-y},{x:t,y:n+y}]},K=(t,n,x)=>{const r=n.x-t.x,y=n.y-t.y,e=Math.sqrt(r*r+y*y);if(0===e)return[t,n];const a=r/e,h=y/e;return[{x:t.x-a*x,y:t.y-h*x},{x:n.x+a*x,y:n.y+h*x}]};export{m as calculateBoundingBox,c as calculateCenter,x as calculateCoordinatesBetweenPoints,$ as calculateCornerExtension,J as calculateLineEndpoints,q as calculateLineMidpointOffset,D as calculateLineSegmentHitArea,E as calculateLineSegmentOutline,C as calculateMergedBounds,a as calculateMinDistanceToBoundary,z as calculatePixelWeightedCenter,v as calculatePolygonOutline,F as calculateRasterMapBounds,k as calculateRasterRoomCenter,y as calculateRoomCenterPoint,M as calculateScaleRatio,b as calculateUprightLineAngle,g as createVector,n as ensureClosedPath,K as extendLineSegment,e as findBestInnerPoint,j as findExtremePoints,t as generateOutlineData,w as getBisectorDirection,l as getDistance,d as getPerpendicularUnitVector,Y as getPerpendicularVector,X as getUnitVector,f as getVectorLength,H as isPointInBox,o as isPointInPolygon,i as isPointOnLineSegment,s as isPointOnPolygonBoundary,G as lineIntersectsBox,S as lineSegmentsIntersection,B as mergeBounds,u as normalizeToRectangle,p as normalizeVector,A as optimizeRasterCenterWithLineIntersection,h as pointToSegmentDistance,I as rotatePointAroundCenter,P as rotatePointsAroundCenter,r as sampleLinePoints};
@@ -0,0 +1 @@
1
+ import{isMobile as t}from"pixi.js";navigator?.userAgent?.includes("tuya-ark-ide")||navigator?.userAgent?.includes("miniProgram");const e=()=>{if(!t.any)return!0;const e=navigator.userAgent.toLowerCase();let r=!1;if(/iphone|ipad|ipod/.test(e)){const t=e.match(/os (\d+)_/)?.[1];r=(t?parseInt(t):0)>=12}else if(/android/.test(e)){const t=e.match(/android (\d+)/)?.[1];r=(t?parseInt(t):0)>=10}return r&&(()=>{const t=navigator.deviceMemory;return!t||t>=4})()};export{e as getOptimalAntialiasingStrategy};
@@ -0,0 +1 @@
1
+ function e(e){return e<.5?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1}import{decodeMapRooms as o}from"@ray-js/robot-protocol";const r=(e,r)=>(o(e)??[]).map(e=>({id:e.roomId,name:e.name,cleanTimes:e.sweepTimes,order:e.order,floorType:e.floorMaterial,yMop:e.yMop?1:0,suction:e.suction,cistern:e.cistern,cleanMode:e.sweepForbidden||e.mopForbidden?e.sweepForbidden?2:1:0,...r?.(e.reservedStr)??{}}));export{r as decodeRoomProperties,e as easeInOutCubic};
@@ -0,0 +1 @@
1
+ const o={log(o,...r){console.log(`%c[ray-2d-laser-map-sdk]%c ${o}`,"background: #2196F3; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;","color: #2196F3;",...r)},warn(o,...r){},error(o,...r){console.error(`%c[ray-2d-laser-map-sdk]%c ${o}`,"background: #F44336; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;","color: #F44336;",...r)},debug(o,...r){console.log(`%c[ray-2d-laser-map-sdk:DEBUG]%c ${o}`,"background: #9C27B0; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;","color: #9C27B0;",...r)},success(o,...r){console.log(`%c[ray-2d-laser-map-sdk]%c ${o}`,"background: #4CAF50; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;","color: #4CAF50;",...r)}};export{o as Logger};
@@ -9,14 +9,14 @@
9
9
  <link rel="preload stylesheet" href="/assets/style.CN_tJoU2.css" as="style">
10
10
  <link rel="preload stylesheet" href="/vp-icons.css" as="style">
11
11
 
12
- <script type="module" src="/assets/app.BjqhSYbb.js"></script>
12
+ <script type="module" src="/assets/app.DRu3YfJm.js"></script>
13
13
  <link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
14
14
  <script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
15
15
  <script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
16
16
  </head>
17
17
  <body>
18
18
  <div id="app"></div>
19
- <script>window.__VP_HASH_MAP__=JSON.parse("{\"guide_advanced-usage.md\":\"ChUH15VJ\",\"guide_concepts.md\":\"GEw3xVjc\",\"guide_getting-started.md\":\"GyXzwIxc\",\"index.md\":\"Sm6vD2Gl\",\"reference_callbacks.md\":\"-S6uhkXO\",\"reference_config.md\":\"BOXwJsHq\",\"reference_data.md\":\"B8JfrRhl\",\"reference_methods.md\":\"BkU-PXMt\",\"reference_runtime.md\":\"UJkdf65W\",\"reference_types.md\":\"CteNuaxc\",\"reference_utils.md\":\"DU5CMWXW\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Tuya Robot Map\",\"description\":\"涂鸦扫地机地图组件\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"siteTitle\":\"Tuya Robot Map\",\"outline\":{\"level\":[2,5],\"label\":\"页面导航\"},\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"指南\",\"link\":\"/guide/concepts\"},{\"text\":\"参考\",\"link\":\"/reference/data.md\"}],\"sidebar\":{\"/guide/\":[{\"text\":\"指南\",\"items\":[{\"text\":\"基本概念\",\"link\":\"/guide/concepts\"},{\"text\":\"快速开始\",\"link\":\"/guide/getting-started\"},{\"text\":\"进阶使用\",\"link\":\"/guide/advanced-usage\"}]}],\"/reference/\":[{\"text\":\"组件Props\",\"items\":[{\"text\":\"数据\",\"link\":\"/reference/data\"},{\"text\":\"配置\",\"link\":\"/reference/config\"},{\"text\":\"运行时\",\"link\":\"/reference/runtime\"},{\"text\":\"地图事件回调\",\"link\":\"/reference/callbacks\"}]},{\"text\":\"方法\",\"items\":[{\"text\":\"地图方法\",\"link\":\"/reference/methods\"},{\"text\":\"工具方法\",\"link\":\"/reference/utils\"}]},{\"text\":\"类型定义\",\"items\":[{\"text\":\"类型定义\",\"link\":\"/reference/types\"}]}]},\"search\":{\"provider\":\"local\"},\"lastUpdated\":{\"text\":\"最后更新于\",\"formatOptions\":{\"dateStyle\":\"short\",\"timeStyle\":\"short\"}}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
19
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"guide_advanced-usage.md\":\"ChUH15VJ\",\"guide_concepts.md\":\"GEw3xVjc\",\"guide_getting-started.md\":\"Bn2rTf61\",\"index.md\":\"Sm6vD2Gl\",\"reference_callbacks.md\":\"-S6uhkXO\",\"reference_config.md\":\"BOXwJsHq\",\"reference_data.md\":\"B8JfrRhl\",\"reference_methods.md\":\"BkU-PXMt\",\"reference_runtime.md\":\"UJkdf65W\",\"reference_types.md\":\"CteNuaxc\",\"reference_utils.md\":\"DU5CMWXW\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Tuya Robot Map\",\"description\":\"涂鸦扫地机地图组件\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"siteTitle\":\"Tuya Robot Map\",\"outline\":{\"level\":[2,5],\"label\":\"页面导航\"},\"nav\":[{\"text\":\"首页\",\"link\":\"/\"},{\"text\":\"指南\",\"link\":\"/guide/concepts\"},{\"text\":\"参考\",\"link\":\"/reference/data.md\"}],\"sidebar\":{\"/guide/\":[{\"text\":\"指南\",\"items\":[{\"text\":\"基本概念\",\"link\":\"/guide/concepts\"},{\"text\":\"快速开始\",\"link\":\"/guide/getting-started\"},{\"text\":\"进阶使用\",\"link\":\"/guide/advanced-usage\"}]}],\"/reference/\":[{\"text\":\"组件Props\",\"items\":[{\"text\":\"数据\",\"link\":\"/reference/data\"},{\"text\":\"配置\",\"link\":\"/reference/config\"},{\"text\":\"运行时\",\"link\":\"/reference/runtime\"},{\"text\":\"地图事件回调\",\"link\":\"/reference/callbacks\"}]},{\"text\":\"方法\",\"items\":[{\"text\":\"地图方法\",\"link\":\"/reference/methods\"},{\"text\":\"工具方法\",\"link\":\"/reference/utils\"}]},{\"text\":\"类型定义\",\"items\":[{\"text\":\"类型定义\",\"link\":\"/reference/types\"}]}]},\"search\":{\"provider\":\"local\"},\"lastUpdated\":{\"text\":\"最后更新于\",\"formatOptions\":{\"dateStyle\":\"short\",\"timeStyle\":\"short\"}}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
20
20
 
21
21
  </body>
22
22
  </html>
@@ -1 +1 @@
1
- import{t as p}from"./chunks/theme.DDGgl7pm.js";import{R as s,a2 as i,a3 as u,a4 as c,a5 as l,a6 as f,a7 as d,a8 as m,a9 as h,aa as g,ab as A,d as v,u as y,v as C,s as P,ac as b,ad as w,ae as R,af as E}from"./chunks/framework.DRADY2L-.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=y();return C(()=>{P(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&b(),w(),R(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};
1
+ import{t as p}from"./chunks/theme.CKuAZ0Ki.js";import{R as s,a2 as i,a3 as u,a4 as c,a5 as l,a6 as f,a7 as d,a8 as m,a9 as h,aa as g,ab as A,d as v,u as y,v as C,s as P,ac as b,ad as w,ae as R,af as E}from"./chunks/framework.DRADY2L-.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=y();return C(()=>{P(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&b(),w(),R(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};