@jetta/blocks-allocator 0.0.0-stage → 0.1.0-0

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 (282) hide show
  1. package/README.md +103 -2
  2. package/package.json +67 -5
  3. package/src/Allocation_Attempt.js +135 -0
  4. package/src/Allocation_Error_Handler.js +69 -0
  5. package/src/Allocation_Flow.js +162 -0
  6. package/src/Allocation_Optimization/Allocation_LP.js +150 -0
  7. package/src/Allocation_Optimization/Block_Allocator.js +129 -0
  8. package/src/Allocation_Optimization/Block_Layer_Order.js +50 -0
  9. package/src/Allocation_Optimization/Block_Potential_Weight.js +54 -0
  10. package/src/Allocation_Optimization/Chosen_Blocks_Stock_Cap.js +82 -0
  11. package/src/Allocation_Optimization/block_builder/Allocation_Item_Creator.js +37 -0
  12. package/src/Allocation_Optimization/block_builder/Block_Item_List_Validator.js +18 -0
  13. package/src/Allocation_Optimization/block_builder/Block_Wall_Builder.js +303 -0
  14. package/src/Allocation_Optimization/block_builder/Blocks_Builder.js +40 -0
  15. package/src/Allocation_Optimization/block_builder/Next_Block_Position.js +33 -0
  16. package/src/Allocation_Optimization/block_builder/Slot_Item_Assigner.js +45 -0
  17. package/src/Allocation_Optimization/block_builder/Stacking_Validation.js +30 -0
  18. package/src/Allocation_Optimization/block_builder/assert_tie_ratio_block_matches_orientation_below.js +44 -0
  19. package/src/Allocation_Optimization/block_builder/block_shape_stock.js +129 -0
  20. package/src/Allocation_Optimization/block_builder/exceptions/Empty_Block_Item_List_Exception.js +21 -0
  21. package/src/Allocation_Optimization/block_builder/exceptions/Invalid_Stacking_Exception.js +14 -0
  22. package/src/Allocation_Optimization/block_builder/exceptions/No_Suitable_Item_Exception.js +16 -0
  23. package/src/Allocation_Optimization/block_builder/exceptions/Restricted_Block_Exception.js +21 -0
  24. package/src/Allocation_Optimization/block_builder/should_omit_block_group_id.js +29 -0
  25. package/src/Allocation_Optimization/block_builder/snap_elevated_block_wall_items.js +34 -0
  26. package/src/Allocation_Optimization/block_builder/stacking_rules_input.js +52 -0
  27. package/src/Allocation_Optimization/cap_chosen_blocks_by_shape_stock.js +110 -0
  28. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Preparer.js +21 -0
  29. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Selector.js +55 -0
  30. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Threshold_Resolver.js +28 -0
  31. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Thresholds.js +23 -0
  32. package/src/Allocation_Optimization/density_groups/Container_Utilization.js +67 -0
  33. package/src/Allocation_Optimization/density_groups/Density_Group_Partitioner.js +74 -0
  34. package/src/Allocation_Optimization/density_groups/Density_Group_Scheduler.js +168 -0
  35. package/src/Allocation_Optimization/density_groups/Density_Group_Stock.js +49 -0
  36. package/src/Allocation_Optimization/density_groups/Density_Groups_Strategy.js +26 -0
  37. package/src/Allocation_Optimization/density_groups/Item_Density_Calculator.js +20 -0
  38. package/src/Allocation_Optimization/density_groups/Lock_Weight_Ahead_Release.js +75 -0
  39. package/src/Allocation_Optimization/exceptions/Invalid_Item_Amount_Exception.js +17 -0
  40. package/src/Allocation_Optimization/exceptions/No_Valid_Allocation_Exception.js +14 -0
  41. package/src/Allocation_Optimization/exceptions/Optimization_Infeasible_Exception.js +14 -0
  42. package/src/Allocation_Optimization/functions/Measure_Reader.js +20 -0
  43. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Mode.js +25 -0
  44. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Strategies.js +8 -0
  45. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Combination_Mode_Checkers.js +70 -0
  46. package/src/Allocation_Optimization/functions/Weight_Getter/Translation.js +22 -0
  47. package/src/Allocation_Optimization/functions/Weight_Getter/Variable_Weight_Getter.js +85 -0
  48. package/src/Allocation_Optimization/functions/Weight_Getter/constants.js +16 -0
  49. package/src/Allocation_Optimization/functions/measure_to_optimize.js +6 -0
  50. package/src/Allocation_Optimization/item_consumption_heuristic/Capacity_Bias_Item_Order.js +76 -0
  51. package/src/Allocation_Optimization/item_consumption_heuristic/Choose_Item_Heuristic_Context.js +63 -0
  52. package/src/Allocation_Optimization/item_consumption_heuristic/Item_Chooser.js +159 -0
  53. package/src/Allocation_Optimization/item_consumption_heuristic/Item_For_Slot_Chooser.js +49 -0
  54. package/src/Allocation_Optimization/item_consumption_heuristic/Slot_Compatible_Items_Finder.js +88 -0
  55. package/src/Allocation_Optimization/item_consumption_heuristic/Slots_Items_Assigner.js +182 -0
  56. package/src/Allocation_Optimization/item_consumption_heuristic/Stack_Slot_Calculator.js +87 -0
  57. package/src/Allocation_Optimization/item_consumption_heuristic/Weight_Slot_Distribution.js +72 -0
  58. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Empty_Slot_Exception.js +17 -0
  59. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Item_Taller_Than_Limit_Exception.js +21 -0
  60. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Available_Items_Exception.js +14 -0
  61. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Slots_For_Items_Exception.js +14 -0
  62. package/src/Allocation_Optimization/lp_model/Block_Weight_Calculator.js +31 -0
  63. package/src/Allocation_Optimization/lp_model/LP_Data_Processor.js +42 -0
  64. package/src/Allocation_Optimization/lp_model/LP_Item_Slot_Assignment.js +93 -0
  65. package/src/Allocation_Optimization/lp_model/LP_Result_Mapper.js +47 -0
  66. package/src/Allocation_Optimization/lp_model/model_builder/Dimension_Range_Helper.js +49 -0
  67. package/src/Allocation_Optimization/lp_model/model_builder/Item_Assignment_Variables.js +133 -0
  68. package/src/Allocation_Optimization/lp_model/model_builder/LP_Model_Builder.js +132 -0
  69. package/src/Allocation_Optimization/lp_model/model_builder/exceptions/Missing_Item_Stock_Exception.js +18 -0
  70. package/src/Allocation_Optimization/lp_model/model_builder/goal_function/Goal_Function_Creator.js +83 -0
  71. package/src/Allocation_Optimization/lp_model/model_builder/item_dimension_hashes.js +31 -0
  72. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Block_Item_Amount_Restriction.js +53 -0
  73. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Coherence_Restriction.js +65 -0
  74. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Container_Supported_Weight_Restriction.js +42 -0
  75. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Exact_Pass_Amount_Restriction.js +62 -0
  76. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Group_Restriction.js +97 -0
  77. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Single_Item_Type_Restriction.js +79 -0
  78. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Space_Restriction.js +47 -0
  79. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Unavailable_Block_Restriction.js +27 -0
  80. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Uniform_Block_Measure_Restriction.js +92 -0
  81. package/src/Allocation_Optimization/next_group_id_after_preloaded.js +30 -0
  82. package/src/Allocation_Optimization/preferential_blocks/Preferential_Block_Identifier.js +74 -0
  83. package/src/Allocation_Optimization/preferential_blocks/key_item/Key_Item_Mapper.js +49 -0
  84. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Almost_Unique_Item.js +31 -0
  85. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Cant_Stack_It_Self.js +68 -0
  86. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Rule_Interface.js +26 -0
  87. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Intercalation_State.js +49 -0
  88. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Orientation_Filter.js +33 -0
  89. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Vertical_Stack_Filter.js +20 -0
  90. package/src/Allocation_Optimization/tie_ratio/collect_tie_ratio_orientations_below_footprint.js +64 -0
  91. package/src/Allocation_Optimization/tie_ratio/filter_blocks_by_orientation.js +17 -0
  92. package/src/Allocation_Optimization/tie_ratio/find_orientation_below_space.js +77 -0
  93. package/src/Allocation_Optimization/tie_ratio/loose_on_block/allocated_item_penetrates_any.js +31 -0
  94. package/src/Allocation_Optimization/tie_ratio/loose_on_block/apply_loose_placement_to_allocated_item.js +94 -0
  95. package/src/Allocation_Optimization/tie_ratio/loose_on_block/axis_overlap_length.js +16 -0
  96. package/src/Allocation_Optimization/tie_ratio/loose_on_block/block_local_origin.js +18 -0
  97. package/src/Allocation_Optimization/tie_ratio/loose_on_block/box_fits_inside_container.js +39 -0
  98. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_allocated_item_at_placement.js +18 -0
  99. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_placement_on_generic_supporter.js +64 -0
  100. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_slot_grid_from_cluster.js +66 -0
  101. package/src/Allocation_Optimization/tie_ratio/loose_on_block/compare_group_ids.js +20 -0
  102. package/src/Allocation_Optimization/tie_ratio/loose_on_block/container_with_pending_wall_items.js +26 -0
  103. package/src/Allocation_Optimization/tie_ratio/loose_on_block/empty_space_is_on_floor.js +16 -0
  104. package/src/Allocation_Optimization/tie_ratio/loose_on_block/finalize_loose_item_placement.js +58 -0
  105. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_best_generic_supporter_placement.js +58 -0
  106. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_next_free_slot_index.js +119 -0
  107. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_supporter_directly_below.js +51 -0
  108. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_tie_ratio_supporter_cluster.js +57 -0
  109. package/src/Allocation_Optimization/tie_ratio/loose_on_block/footprint_xz_overlap_area.js +26 -0
  110. package/src/Allocation_Optimization/tie_ratio/loose_on_block/item_fits_supporter_slot.js +22 -0
  111. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_footprint_region_from_options.js +24 -0
  112. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_fits_inside_container.js +21 -0
  113. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_has_geometric_support.js +21 -0
  114. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_on_block_slot_state.js +88 -0
  115. package/src/Allocation_Optimization/tie_ratio/loose_on_block/placement_coords_fit_inside_container.js +34 -0
  116. package/src/Allocation_Optimization/tie_ratio/loose_on_block/read_empilhar_area_igual_from_allocation_item.js +12 -0
  117. package/src/Allocation_Optimization/tie_ratio/loose_on_block/realigned_loose_geometry_gates.js +25 -0
  118. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_on_generic_supporter.js +65 -0
  119. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_placement_position.js +68 -0
  120. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_placement_y_at_slot.js +45 -0
  121. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_without_tie_ratio_cluster.js +79 -0
  122. package/src/Allocation_Optimization/tie_ratio/loose_on_block/select_tie_ratio_slot_placement.js +84 -0
  123. package/src/Allocation_Optimization/tie_ratio/loose_on_block/slot_footprint_collision.js +105 -0
  124. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_cluster_selection.js +119 -0
  125. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_footprint_overlap.js +56 -0
  126. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_placement_plane.js +109 -0
  127. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_supporter_predicate.js +23 -0
  128. package/src/Allocation_Optimization/tie_ratio/loose_on_block/try_tie_ratio_slot_placement.js +62 -0
  129. package/src/Allocation_Optimization/tie_ratio/snap_stacked_items_to_floor_footprints.js +138 -0
  130. package/src/Allocation_Optimization/tie_ratio/supporters_by_top_y_index.js +78 -0
  131. package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_below_empty_space.js +89 -0
  132. package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_from_group.js +48 -0
  133. package/src/Block_Management.js +34 -0
  134. package/src/Blocks_Preparation/Cube_Map_Function.js +27 -0
  135. package/src/Blocks_Wall_Allocation.js +3 -0
  136. package/src/IO/Answer_Status.js +4 -0
  137. package/src/IO/Output_Builder.js +35 -0
  138. package/src/IO/count_allocated_items.js +31 -0
  139. package/src/IO/create_error_response.js +62 -0
  140. package/src/IO/format_allocation_error_message.js +25 -0
  141. package/src/Item_Continuation_Lock.js +129 -0
  142. package/src/Item_Picking_Continuity.js +41 -0
  143. package/src/allocation_flow/chooser_session_state.js +21 -0
  144. package/src/allocation_flow/compound_probe_fallback.js +17 -0
  145. package/src/allocation_flow/container_remaining_capacity.js +23 -0
  146. package/src/allocation_flow/density_group_item_filter.js +31 -0
  147. package/src/allocation_flow/effective_item_fingerprint.js +14 -0
  148. package/src/allocation_flow/item_continuation_lock_gate.js +38 -0
  149. package/src/allocation_flow/no_space_left_recovery.js +48 -0
  150. package/src/allocation_flow/run_allocation_iteration.js +155 -0
  151. package/src/allocation_flow/space_skip_state.js +91 -0
  152. package/src/allocation_flow/try_no_space_left_recovery.js +50 -0
  153. package/src/exceptions/Invalid_Parameter_Exception.js +17 -0
  154. package/src/exceptions/Relational_Allocation_Incomplete_Exception.js +24 -0
  155. package/src/exceptions/Relational_Colocation_Violation_Exception.js +23 -0
  156. package/src/exceptions/Relational_Config_Mismatch_Exception.js +17 -0
  157. package/src/exceptions/There_Is_No_Block_Options_To_Allocate_Exception.js +14 -0
  158. package/src/index.js +6 -0
  159. package/src/input_preparation/Block_Formatter.js +179 -0
  160. package/src/input_preparation/Input_Creator.js +76 -0
  161. package/src/input_preparation/Input_State_Preparation.js +47 -0
  162. package/src/input_preparation/State_Builder.js +27 -0
  163. package/src/input_preparation/block_formatter/align_flush_axis_config.js +36 -0
  164. package/src/input_preparation/block_formatter/align_flush_axis_single_round.js +112 -0
  165. package/src/input_preparation/block_formatter/align_flush_stacked_slots.js +67 -0
  166. package/src/input_preparation/block_formatter/overlapped_slots.js +24 -0
  167. package/src/input_preparation/block_formatter/parallelepiped_shell.js +38 -0
  168. package/src/input_preparation/block_formatter/rectangle_coverage.js +112 -0
  169. package/src/input_preparation/block_formatter/shell_face_coverage.js +64 -0
  170. package/src/input_preparation/block_formatter/shell_snap_convergence.js +104 -0
  171. package/src/input_preparation/block_preparation/Block_Data_To_Object_Transformer.js +57 -0
  172. package/src/input_preparation/block_preparation/Block_Module_Name.js +17 -0
  173. package/src/input_preparation/block_preparation/Blocks_Creator.js +101 -0
  174. package/src/input_preparation/block_preparation/Blocksmith.js +19 -0
  175. package/src/input_preparation/block_preparation/block_modules/create_block_candidates.js +41 -0
  176. package/src/input_preparation/block_preparation/block_modules/manual_blocks.js +10 -0
  177. package/src/input_preparation/block_preparation/block_modules/module_registry.js +20 -0
  178. package/src/input_preparation/block_preparation/block_modules/run_creator.js +34 -0
  179. package/src/input_preparation/block_preparation/block_modules/single_item_blocks.js +12 -0
  180. package/src/input_preparation/block_preparation/block_modules/spiral_blocks.js +12 -0
  181. package/src/input_preparation/block_preparation/block_modules/tie_ratio_blocks.js +12 -0
  182. package/src/input_preparation/block_preparation/block_modules/tower_blocks.js +12 -0
  183. package/src/input_preparation/block_preparation/exceptions/Failed_To_Create_Block_Exception.js +14 -0
  184. package/src/input_preparation/block_preparation/exceptions/Failed_To_Retrieve_Block_Exception.js +17 -0
  185. package/src/input_preparation/block_preparation/exceptions/Missing_Object_Store_Exception.js +10 -0
  186. package/src/input_preparation/block_preparation/exceptions/No_Blocks_Were_Created_Exception.js +14 -0
  187. package/src/input_preparation/block_preparation/input/Input_Creator.js +96 -0
  188. package/src/input_preparation/block_preparation/manual_blocks/Manual_Blocks.js +95 -0
  189. package/src/input_preparation/build_empty_space_finder_options.js +43 -0
  190. package/src/input_preparation/item_preparation/Items_Reader.js +27 -0
  191. package/src/input_preparation/min_extents_from_items.js +29 -0
  192. package/src/input_preparation/stackability_index/Blocks_Stackability_Index_Calculator.js +58 -0
  193. package/src/input_preparation/stackability_index/Slots_Stackability_index_Calculator.js +28 -0
  194. package/src/input_preparation/stackability_index/Stackability_Input_Creator.js +27 -0
  195. package/src/input_preparation/stackability_index/stackability_index_pop_stack.js +81 -0
  196. package/src/input_preparation/stacking_constraints/Weight_Stacking_Validation.js +15 -0
  197. package/src/lp_optimizer_result_status.js +20 -0
  198. package/src/messages/Allocator_Message.js +42 -0
  199. package/src/messages/resolve_error_message_entry.js +57 -0
  200. package/src/models/Allocated_Item.js +136 -0
  201. package/src/models/Allocation_Item.js +219 -0
  202. package/src/models/Block.js +198 -0
  203. package/src/models/Cargo_Profile.js +418 -0
  204. package/src/models/Preloaded_Allocated_Item.js +132 -0
  205. package/src/models/Slot.js +67 -0
  206. package/src/models/Stacking_Rules.js +58 -0
  207. package/src/models/auxiliaryFunctions/Available_Block_Module_List_Creator.js +9 -0
  208. package/src/models/auxiliaryFunctions/Measure_Translator.js +24 -0
  209. package/src/models/auxiliaryFunctions/item_json_reader.js +44 -0
  210. package/src/models/item_json_reader.js +71 -0
  211. package/src/models/placed_item_record.js +70 -0
  212. package/src/models/preloaded_rotation_helpers.js +38 -0
  213. package/src/models/slots_have_same_measure.js +45 -0
  214. package/src/models/transport/Container.js +162 -0
  215. package/src/models/transport/Transport.js +62 -0
  216. package/src/models/transport/build_stacking_feasibility_checker.js +64 -0
  217. package/src/models/transport/container_stacking_checkpoint.js +42 -0
  218. package/src/models/transport/factory/Container_Factory.js +46 -0
  219. package/src/models/transport/factory/Corner_Casting_Factory.js +62 -0
  220. package/src/models/transport/factory/Previously_Allocated_Item_Factory.js +28 -0
  221. package/src/models/transport/factory/Transport_Factory.js +13 -0
  222. package/src/models/transport/items_for_empty_space_finder.js +91 -0
  223. package/src/models/transport/resolve_container_stacking_inputs.js +23 -0
  224. package/src/models/transport/stacking_input_from_wire.js +58 -0
  225. package/src/optimizer_connection_errors.js +50 -0
  226. package/src/relational/Relational_Error_Codes.js +7 -0
  227. package/src/relational/finalize_relational_allocation.js +20 -0
  228. package/src/relational/has_relational_items.js +11 -0
  229. package/src/relational/is_relational_error_code.js +15 -0
  230. package/src/relational/resolve_relational_container_sequences.js +29 -0
  231. package/src/run_core_allocation.js +118 -0
  232. package/src/space_and_block_chooser/Space_And_Blocks_Chooser.js +115 -0
  233. package/src/space_and_block_chooser/blocks_filters/Block_Filter_Interface.js +19 -0
  234. package/src/space_and_block_chooser/blocks_filters/Filter_Runner.js +46 -0
  235. package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Block_With_Overlapped_Slots_Filter.js +14 -0
  236. package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Initial_Blocks_Filter_List.js +19 -0
  237. package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Blocks_Bigger_Than_Space_Filter.js +17 -0
  238. package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Post_Selection_Filter_List.js +9 -0
  239. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Insuficient_Items_Filter.js +81 -0
  240. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Pre_Selection_Filter_List.js +8 -0
  241. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Blocks_Lower_Than_Max_Tower_Height.js +23 -0
  242. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Max_Tower_Height.js +82 -0
  243. package/src/space_and_block_chooser/build_allocated_item_snapshots.js +19 -0
  244. package/src/space_and_block_chooser/compound_first_empty_space_branch.js +61 -0
  245. package/src/space_and_block_chooser/compound_first_with_leftover_fill.js +142 -0
  246. package/src/space_and_block_chooser/compound_first_without_leftover_fill.js +56 -0
  247. package/src/space_and_block_chooser/empty_spaces_where_post_selection_keeps_blocks.js +83 -0
  248. package/src/space_and_block_chooser/exceptions/Invalid_Space_To_Allocate_Exception.js +14 -0
  249. package/src/space_and_block_chooser/leftover_space_memory.js +113 -0
  250. package/src/space_and_block_chooser/leftover_unitary_blocks.js +153 -0
  251. package/src/space_and_block_chooser/leftover_unitary_empty_spaces.js +135 -0
  252. package/src/space_and_block_chooser/probe_set_pool.js +35 -0
  253. package/src/space_and_block_chooser/run_space_and_block_selection_attempt.js +88 -0
  254. package/src/tools/Array_Validator.js +6 -0
  255. package/src/tools/Clone.js +27 -0
  256. package/src/tools/Hash.js +8 -0
  257. package/src/tools/Rounder.js +5 -0
  258. package/src/tools/String_To_Boolean.js +12 -0
  259. package/src/tools/cargo_profile/Cargo_Profile_Field_Value_Resolver.js +44 -0
  260. package/src/tools/compact_items_with_stock.js +9 -0
  261. package/src/tools/mm_to_allocation_domain.js +14 -0
  262. package/src/tracing/Allocation_Tracer.js +52 -0
  263. package/src/tracing/Trace_Context.js +18 -0
  264. package/src/tracing/trace_outcome.js +18 -0
  265. package/src/tracing/traced_step.js +57 -0
  266. package/src/validation/Item_Continuation_Lock_Flag.js +52 -0
  267. package/src/validation/Item_Validation.js +29 -0
  268. package/src/validation/Relational_Colocation_Validator.js +60 -0
  269. package/src/validation/Relational_Completeness_Validator.js +146 -0
  270. package/src/validation/Relational_Continuation_Lock_Validation.js +37 -0
  271. package/src/validation/Relational_Proportional_Normalizer.js +194 -0
  272. package/src/validation/Validation.js +9 -0
  273. package/src/validation/Validation_Runner.js +20 -0
  274. package/src/validation/exceptions/Invalid_Block_Module_Config_Exception.js +14 -0
  275. package/src/validation/exceptions/Invalid_Input_Exception.js +14 -0
  276. package/src/validation/exceptions/Invalid_Input_Type_Exception.js +14 -0
  277. package/src/validation/schemas/allocated_item_schema.js +18 -0
  278. package/src/validation/schemas/allocation_request_schema.js +178 -0
  279. package/src/validation/schemas/container_row_schema.js +16 -0
  280. package/src/validation/schemas/item_schema.js +60 -0
  281. package/src/validation/schemas/transport_env_schema.js +19 -0
  282. package/src/validation/validate_block_module_config.js +147 -0
@@ -0,0 +1,303 @@
1
+ const assign_item_to_slots = require('./Slot_Item_Assigner')
2
+ const calculate_next_block_position = require('./Next_Block_Position')
3
+ const create_allocated_item_from_block = require('./Allocation_Item_Creator')
4
+ const { assert_non_empty_item_list } = require('./Block_Item_List_Validator')
5
+ const Cargo_Profile = require('../../models/Cargo_Profile')
6
+ const apply_loose_placement_to_allocated_item = require('../tie_ratio/loose_on_block/apply_loose_placement_to_allocated_item')
7
+ const { finalize_loose_item_placement } = require('../tie_ratio/loose_on_block/finalize_loose_item_placement')
8
+ const { create_loose_on_block_slot_state } = require('../tie_ratio/loose_on_block/loose_on_block_slot_state')
9
+ const No_Suitable_Item_Exception = require('./exceptions/No_Suitable_Item_Exception')
10
+ const Restricted_Block_Exception = require('./exceptions/Restricted_Block_Exception')
11
+ const { ALLOCATOR_MESSAGE } = require('../../messages/Allocator_Message')
12
+ const assert_tie_ratio_block_matches_orientation_below = require('./assert_tie_ratio_block_matches_orientation_below')
13
+ const snap_elevated_block_wall_items = require('./snap_elevated_block_wall_items')
14
+ const should_omit_block_group_id = require('./should_omit_block_group_id')
15
+ const allocated_items_weight_sum = (item_list) => item_list.reduce((acc, item) => acc + item.get_weight(), 0)
16
+
17
+ /**
18
+ * Builds all block instances for one optimized wall layer.
19
+ * @param {object} wall_data
20
+ * @param {number} [wall_data.next_group_id=0] - Seed for the first block group id in this wall.
21
+ * @returns {object} Wall output including `next_group_id` after the last built block.
22
+ */
23
+ function build_allocated_wall(wall_data)
24
+ {
25
+ const output = create_empty_wall_output()
26
+ let state = create_initial_wall_state(wall_data)
27
+ for (const choice of wall_data.optimized_block_layer.chosen_blocks)
28
+ {
29
+ state = build_blocks_for_choice(choice, wall_data, state, output)
30
+ }
31
+ output.last_allocated_item_id = Cargo_Profile.prefer_block_with_same_item()
32
+ ? (state.last_chosen_item_id ?? null)
33
+ : null
34
+ output.next_group_id = state.next_group_id
35
+ return output
36
+ }
37
+
38
+ function create_empty_wall_output()
39
+ {
40
+ return {
41
+ allocated_item_list: [],
42
+ item_to_find_space_list: [],
43
+ single_slot_allocated_item_ids: new Set(),
44
+ last_allocated_item_id: null,
45
+ placed_tie_ratio_block: false
46
+ }
47
+ }
48
+
49
+ function create_initial_wall_state(wall_data)
50
+ {
51
+ return {
52
+ current_block_position: wall_data.space_to_allocate,
53
+ container_supported_weight: wall_data.container.supported_weight(),
54
+ item_position: get_item_position(wall_data.space_to_allocate),
55
+ last_chosen_item_id: resolve_continuity_seed(wall_data.picking_continuity_seed),
56
+ next_group_id: wall_data.next_group_id ?? 0,
57
+ loose_on_block_slot_state: create_loose_on_block_slot_state()
58
+ }
59
+ }
60
+
61
+ function resolve_continuity_seed(seed_item_id)
62
+ {
63
+ if (!Cargo_Profile.prefer_block_with_same_item())
64
+ {
65
+ return undefined
66
+ }
67
+ return seed_item_id ?? undefined
68
+ }
69
+
70
+ function get_item_position(space)
71
+ {
72
+ return { x: space.get_x(), y: space.get_y(), z: space.get_z() }
73
+ }
74
+
75
+ function build_blocks_for_choice(choice, wall_data, state, output)
76
+ {
77
+ const chosen_block = choice.block
78
+ const amount = choice.amount | 0
79
+ const is_single_slot = chosen_block.get_slot_list().length === 1
80
+ let next_state = state
81
+ for (let index = 0; index < amount; index++)
82
+ {
83
+ next_state = build_one_block_instance(chosen_block, is_single_slot, wall_data, next_state, output)
84
+ }
85
+ return next_state
86
+ }
87
+
88
+ function build_one_block_instance(chosen_block, is_single_slot, wall_data, state, output)
89
+ {
90
+ const builder_output = build_a_block(
91
+ chosen_block,
92
+ is_single_slot,
93
+ state,
94
+ wall_data,
95
+ output.allocated_item_list
96
+ )
97
+ assert_non_empty_item_list(chosen_block, builder_output.item_in_block_list)
98
+ append_block_to_output(builder_output, is_single_slot, chosen_block, wall_data, output)
99
+ if (typeof chosen_block.is_tie_ratio_block === 'function' && chosen_block.is_tie_ratio_block())
100
+ {
101
+ output.placed_tie_ratio_block = true
102
+ }
103
+ return advance_wall_state(state, builder_output)
104
+ }
105
+
106
+ function build_a_block(chosen_block, is_single_slot, state, wall_data, pending_wall_allocated_items)
107
+ {
108
+ const item_position = resolve_single_slot_item_position(state, wall_data, is_single_slot)
109
+ try
110
+ {
111
+ assert_tie_ratio_block_matches_orientation_below(
112
+ wall_data.container,
113
+ item_position,
114
+ chosen_block
115
+ )
116
+ }
117
+ catch (error)
118
+ {
119
+ throw_restricted_block_exception(error, wall_data, chosen_block)
120
+ }
121
+ const item_in_block_list = assign_item_to_slots(
122
+ wall_data.heuristic,
123
+ chosen_block,
124
+ wall_data.allocated_blocks_amount,
125
+ state.container_supported_weight,
126
+ item_position,
127
+ state.last_chosen_item_id
128
+ )
129
+ let realigned_item_list = item_in_block_list
130
+ try
131
+ {
132
+ const snapped_item_list = skip_elevated_snap_for_loose_unitary(is_single_slot)
133
+ ? item_in_block_list
134
+ : snap_elevated_block_wall_items(
135
+ item_in_block_list,
136
+ wall_data,
137
+ pending_wall_allocated_items
138
+ )
139
+ realigned_item_list = realign_single_slot_loose_items(
140
+ snapped_item_list,
141
+ is_single_slot,
142
+ wall_data,
143
+ state,
144
+ pending_wall_allocated_items
145
+ )
146
+ }
147
+ catch (error)
148
+ {
149
+ throw_restricted_block_exception(error, wall_data, chosen_block)
150
+ }
151
+ const group_id = allocate_next_group_id(chosen_block, state, wall_data)
152
+ const block_as_item = create_allocated_item_from_block(
153
+ group_id,
154
+ chosen_block,
155
+ realigned_item_list,
156
+ state.current_block_position
157
+ )
158
+ const next_block_position = calculate_next_block_position(
159
+ state.current_block_position,
160
+ chosen_block
161
+ )
162
+ return { item_in_block_list: realigned_item_list, block_as_item, next_block_position }
163
+ }
164
+
165
+ function skip_elevated_snap_for_loose_unitary(is_single_slot)
166
+ {
167
+ return is_single_slot === true && Cargo_Profile.stack_loose_on_tie_ratio_blocks()
168
+ }
169
+
170
+ function throw_restricted_block_exception(error, wall_data, chosen_block)
171
+ {
172
+ if (!(error instanceof No_Suitable_Item_Exception))
173
+ {
174
+ throw error
175
+ }
176
+ const block_id = chosen_block.get_id()
177
+ const max_amount = wall_data.allocated_blocks_amount[block_id] ?? 0
178
+ throw new Restricted_Block_Exception({ id: block_id, restrict_to: max_amount })
179
+ }
180
+
181
+ function realign_single_slot_loose_items(
182
+ item_in_block_list,
183
+ is_single_slot,
184
+ wall_data,
185
+ state,
186
+ pending_wall_allocated_items
187
+ )
188
+ {
189
+ if (!is_single_slot || !Cargo_Profile.stack_loose_on_tie_ratio_blocks())
190
+ {
191
+ return item_in_block_list
192
+ }
193
+ return item_in_block_list.map(allocated_item =>
194
+ {
195
+ const relocated_item = apply_loose_placement_to_allocated_item(
196
+ allocated_item,
197
+ wall_data.container,
198
+ wall_data.space_to_allocate,
199
+ state.loose_on_block_slot_state,
200
+ wall_data.supporters_by_top_y_index,
201
+ pending_wall_allocated_items
202
+ )
203
+ if (relocated_item === undefined)
204
+ {
205
+ throw new No_Suitable_Item_Exception(ALLOCATOR_MESSAGE.LOOSE_ON_TIE_RATIO_FAILED)
206
+ }
207
+ const finalized_item = finalize_loose_item_placement(
208
+ relocated_item,
209
+ wall_data,
210
+ pending_wall_allocated_items
211
+ )
212
+ if (finalized_item === undefined)
213
+ {
214
+ throw new No_Suitable_Item_Exception(ALLOCATOR_MESSAGE.LOOSE_ON_TIE_RATIO_FAILED)
215
+ }
216
+ return finalized_item
217
+ })
218
+ }
219
+
220
+ function resolve_single_slot_item_position(state, _wall_data, _is_single_slot)
221
+ {
222
+ return state.item_position
223
+ }
224
+
225
+ function allocate_next_group_id(chosen_block, state, wall_data)
226
+ {
227
+ const wall_height_y = wall_data.space_to_allocate.get_y()
228
+ if (should_omit_block_group_id(chosen_block, wall_height_y))
229
+ {
230
+ return undefined
231
+ }
232
+ state.next_group_id += 1
233
+ return state.next_group_id
234
+ }
235
+
236
+ function append_block_to_output(builder_output, is_single_slot, chosen_block, wall_data, output)
237
+ {
238
+ output.allocated_item_list.push(...builder_output.item_in_block_list)
239
+ register_single_slot_item(output.single_slot_allocated_item_ids, is_single_slot, builder_output.item_in_block_list)
240
+ register_successful_block(wall_data.allocated_blocks_amount, chosen_block)
241
+ append_find_space_items(output.item_to_find_space_list, builder_output)
242
+ }
243
+
244
+ function advance_wall_state(state, builder_output)
245
+ {
246
+ const last_item = builder_output.item_in_block_list.at(-1)
247
+ const next_seed = resolve_continuity_seed(last_item.get_id())
248
+ return {
249
+ current_block_position: builder_output.next_block_position,
250
+ container_supported_weight: state.container_supported_weight
251
+ - allocated_items_weight_sum(builder_output.item_in_block_list),
252
+ item_position: update_item_position(builder_output.next_block_position),
253
+ last_chosen_item_id: next_seed,
254
+ next_group_id: state.next_group_id,
255
+ loose_on_block_slot_state: state.loose_on_block_slot_state
256
+ }
257
+ }
258
+
259
+ function register_single_slot_item(set, is_single_slot, item_list)
260
+ {
261
+ if (!is_single_slot || item_list.length === 0)
262
+ {
263
+ return
264
+ }
265
+ set.add(item_list[0].get_id())
266
+ }
267
+
268
+ function register_successful_block(amount_map, block)
269
+ {
270
+ if (!block)
271
+ {
272
+ return
273
+ }
274
+ const block_id = block.get_id()
275
+ amount_map[block_id] = (amount_map[block_id] ?? 0) + 1
276
+ }
277
+
278
+ function update_item_position(position)
279
+ {
280
+ return { x: position.get_x(), y: position.get_y(), z: position.get_z() }
281
+ }
282
+
283
+ function append_find_space_items(list, builder_output)
284
+ {
285
+ const block_item = builder_output.block_as_item
286
+ const use_outline = should_use_block_outline(block_item)
287
+ if (use_outline)
288
+ {
289
+ list.push(block_item)
290
+ return
291
+ }
292
+ list.push(...builder_output.item_in_block_list)
293
+ }
294
+
295
+ function should_use_block_outline(block_item)
296
+ {
297
+ const spiral_enabled = Cargo_Profile.enable_to_find_empty_space_from_spiral_block_of_same_measure()
298
+ const block_enabled = Cargo_Profile.enable_to_find_empty_space_block()
299
+ const uniform_slots = block_item.is_block_with_slots_of_same_measure()
300
+ return block_enabled || (spiral_enabled && uniform_slots)
301
+ }
302
+
303
+ module.exports = { build_allocated_wall }
@@ -0,0 +1,40 @@
1
+ const Slots_Items_Assigner = require('../item_consumption_heuristic/Slots_Items_Assigner')
2
+ const { build_allocated_wall } = require('./Block_Wall_Builder')
3
+ const { traced_step_sync } = require('../../tracing/traced_step')
4
+ const { TRACE_CONTEXT } = require('../../tracing/Trace_Context')
5
+
6
+ module.exports = class Block_Builder
7
+ {
8
+ #wall_data
9
+
10
+ constructor(block_builder_data)
11
+ {
12
+ this.#wall_data = {
13
+ space_to_allocate: block_builder_data.space_to_allocate,
14
+ optimized_block_layer: block_builder_data.optimized_block_layer,
15
+ container: block_builder_data.container,
16
+ picking_continuity_seed: block_builder_data.picking_continuity_seed,
17
+ block_instance_item_queues: block_builder_data.block_instance_item_queues ?? new Map(),
18
+ heuristic: new Slots_Items_Assigner(
19
+ block_builder_data.space_to_allocate,
20
+ block_builder_data.item_list,
21
+ block_builder_data.item_amount_map.copy(),
22
+ block_builder_data.container
23
+ ),
24
+ allocated_blocks_amount: {},
25
+ next_group_id: block_builder_data.next_group_id ?? 0
26
+ }
27
+ }
28
+
29
+ /**
30
+ * @returns {object}
31
+ */
32
+ get_allocated_item_list()
33
+ {
34
+ return traced_step_sync(TRACE_CONTEXT.ITEM_SELECTION_POSITIONING, () =>
35
+ traced_step_sync(TRACE_CONTEXT.CHOSEN_BLOCK_STACKING_VALIDATION, () =>
36
+ build_allocated_wall(this.#wall_data)
37
+ )
38
+ )
39
+ }
40
+ }
@@ -0,0 +1,33 @@
1
+ const { Space } = require('@jetta/empty-spaces-manager')
2
+ const { LENGTH, WIDTH } = require('../functions/measure_to_optimize')
3
+ const round = require('../../tools/Rounder')
4
+ const { read_measure_to_be_optimized } = require('../functions/Measure_Reader')
5
+
6
+ module.exports = function next_block_position(current_block_position, block)
7
+ {
8
+ switch (read_measure_to_be_optimized())
9
+ {
10
+ case LENGTH:
11
+ const block_length = Number(block.get_length())
12
+ return create_space(current_block_position, block_length, LENGTH)
13
+ case WIDTH:
14
+ default:
15
+ const block_width = Number(block.get_width())
16
+ return create_space(current_block_position, block_width, WIDTH)
17
+ }
18
+ }
19
+
20
+ function create_space(current_space, increase, type)
21
+ {
22
+ const x = type === WIDTH ? round(current_space.get_x() + increase) : current_space.get_x()
23
+ const z = type === LENGTH ? round(current_space.get_z() + increase) : current_space.get_z()
24
+
25
+ return new Space({
26
+ x,
27
+ y: current_space.get_y(),
28
+ z,
29
+ width: current_space.get_width(),
30
+ height: current_space.get_height(),
31
+ length: current_space.get_length()
32
+ })
33
+ }
@@ -0,0 +1,45 @@
1
+ const Restricted_Block_Exception = require('./exceptions/Restricted_Block_Exception')
2
+ const No_Suitable_Item_Exception = require('./exceptions/No_Suitable_Item_Exception')
3
+ const { Logger } = require('@jetta/logger')
4
+ const logger = new Logger('Slot Item Assigner')
5
+
6
+ module.exports = function assign_item_to_slots(
7
+ heuristic,
8
+ block,
9
+ allocated_blocks_amount,
10
+ container_supported_weight,
11
+ item_position,
12
+ picking_continuity_seed
13
+ )
14
+ {
15
+ try
16
+ {
17
+ const assigned_item_list = heuristic.assign_items_to_slots(
18
+ block,
19
+ container_supported_weight,
20
+ item_position,
21
+ picking_continuity_seed
22
+ )
23
+ return assigned_item_list
24
+ }
25
+ catch (error)
26
+ {
27
+ throw_restricted_block_exception(error, allocated_blocks_amount, block)
28
+ }
29
+ }
30
+
31
+ function throw_restricted_block_exception(error, allocated_blocks_amount, block)
32
+ {
33
+ if (error instanceof No_Suitable_Item_Exception)
34
+ {
35
+ logger.warn(error.message)
36
+ const sucessfull_blocks_amount = allocated_blocks_amount[block.get_id()]
37
+ const max_amount = sucessfull_blocks_amount == undefined ? 0 : sucessfull_blocks_amount
38
+ const block_to_restrict = {
39
+ 'id':block.get_id(),
40
+ 'restrict_to': max_amount
41
+ }
42
+ throw new Restricted_Block_Exception(block_to_restrict)
43
+ }
44
+ throw error
45
+ }
@@ -0,0 +1,30 @@
1
+ const { get_stacking_rules_input } = require('./stacking_rules_input')
2
+
3
+ function resolve_stacking_source(item)
4
+ {
5
+ if (typeof item.get_stacking_source_item === 'function')
6
+ {
7
+ return item.get_stacking_source_item()
8
+ }
9
+ if (typeof item.get_stacking_info === 'function')
10
+ {
11
+ return item
12
+ }
13
+ return item.get_allocation_item()
14
+ }
15
+
16
+ function create_input(item)
17
+ {
18
+ return {
19
+ itemId: item.get_id(),
20
+ x: item.get_x(),
21
+ y: item.get_y(),
22
+ z: item.get_z(),
23
+ width: item.get_width(),
24
+ height: item.get_height(),
25
+ length: item.get_length(),
26
+ stackingRules: get_stacking_rules_input(resolve_stacking_source(item))
27
+ }
28
+ }
29
+
30
+ module.exports = create_input
@@ -0,0 +1,44 @@
1
+ const No_Suitable_Item_Exception = require('./exceptions/No_Suitable_Item_Exception')
2
+ const { ALLOCATOR_MESSAGE } = require('../../messages/Allocator_Message')
3
+ const { build_supporters_by_top_y_index } = require('../tie_ratio/supporters_by_top_y_index')
4
+ const { tie_ratio_orientation_below_placement } = require('../tie_ratio/tie_ratio_orientation_below_empty_space')
5
+
6
+ /**
7
+ * Rejects tie-ratio blocks whose orientation does not match the supporter below this footprint.
8
+ * @param {object} container
9
+ * @param {{ x: number, y: number, z: number }} placement_origin
10
+ * @param {object} chosen_block
11
+ */
12
+ function assert_tie_ratio_block_matches_orientation_below(
13
+ container,
14
+ placement_origin,
15
+ chosen_block
16
+ )
17
+ {
18
+ if (typeof chosen_block.is_tie_ratio_block !== 'function' || !chosen_block.is_tie_ratio_block())
19
+ {
20
+ return
21
+ }
22
+
23
+ const supporters_by_top_y_index = build_supporters_by_top_y_index(
24
+ container.get_allocated_items?.() ?? []
25
+ )
26
+ const required_orientation = tie_ratio_orientation_below_placement(
27
+ container,
28
+ placement_origin,
29
+ chosen_block.get_width(),
30
+ chosen_block.get_length(),
31
+ supporters_by_top_y_index
32
+ )
33
+ if (required_orientation === undefined)
34
+ {
35
+ return
36
+ }
37
+
38
+ if (chosen_block.get_tie_ratio_orientation() !== required_orientation)
39
+ {
40
+ throw new No_Suitable_Item_Exception(ALLOCATOR_MESSAGE.TIE_RATIO_ORIENTATION_MISMATCH)
41
+ }
42
+ }
43
+
44
+ module.exports = assert_tie_ratio_block_matches_orientation_below
@@ -0,0 +1,129 @@
1
+ const { cube_map_function } = require('../../Blocks_Preparation/Cube_Map_Function')
2
+
3
+ /**
4
+ * @param {object} block
5
+ * @returns {Map<string, number>}
6
+ */
7
+ function build_required_shape_amounts(block)
8
+ {
9
+ const required_shapes = new Map()
10
+ for (const slot of block.get_slot_list())
11
+ {
12
+ const shape_hash = cube_map_function(slot)
13
+ required_shapes.set(shape_hash, (required_shapes.get(shape_hash) || 0) + 1)
14
+ }
15
+ return required_shapes
16
+ }
17
+
18
+ /**
19
+ * Counts each item's amount once per unique rotation shape (no rotation inflation).
20
+ * @param {object} item_map - id → item
21
+ * @param {object} item_amount_map - controller with get_item_amount(item)
22
+ * @returns {Map<string, number>}
23
+ */
24
+ function build_available_shape_amounts(item_map, item_amount_map)
25
+ {
26
+ const available_shapes = new Map()
27
+ for (const item_id of Object.keys(item_map))
28
+ {
29
+ const item = item_map[item_id]
30
+ const amount = item_amount_map.get_item_amount(item)
31
+ if (amount <= 0)
32
+ {
33
+ continue
34
+ }
35
+ const unique_hashes = new Set()
36
+ for (const rotated_item of item.get_all_rotated_options())
37
+ {
38
+ unique_hashes.add(cube_map_function(rotated_item))
39
+ }
40
+ for (const shape_hash of unique_hashes)
41
+ {
42
+ available_shapes.set(shape_hash, (available_shapes.get(shape_hash) || 0) + amount)
43
+ }
44
+ }
45
+ return available_shapes
46
+ }
47
+
48
+ /**
49
+ * True when stock can cover the block: total capable units ≥ slot count, and each shape
50
+ * has enough under unique-rotation counting (same rule as Insuficient_Items_Filter).
51
+ * @param {object} block
52
+ * @param {object} item_map
53
+ * @param {object} item_amount_map
54
+ * @returns {boolean}
55
+ */
56
+ function block_has_sufficient_shape_stock(block, item_map, item_amount_map)
57
+ {
58
+ const required_shapes = build_required_shape_amounts(block)
59
+ if (required_shapes.size === 0)
60
+ {
61
+ return false
62
+ }
63
+ let total_required = 0
64
+ for (const required_amount of required_shapes.values())
65
+ {
66
+ total_required += required_amount
67
+ }
68
+ if (count_capable_item_amount(required_shapes, item_map, item_amount_map) < total_required)
69
+ {
70
+ return false
71
+ }
72
+ const available_shapes = build_available_shape_amounts(item_map, item_amount_map)
73
+ for (const [shape_hash, required_amount] of required_shapes)
74
+ {
75
+ if ((available_shapes.get(shape_hash) || 0) < required_amount)
76
+ {
77
+ return false
78
+ }
79
+ }
80
+ return true
81
+ }
82
+
83
+ /**
84
+ * @param {Map<string, number>} required_shapes
85
+ * @param {object} item_map
86
+ * @param {object} item_amount_map
87
+ * @returns {number}
88
+ */
89
+ function count_capable_item_amount(required_shapes, item_map, item_amount_map)
90
+ {
91
+ let capable_amount = 0
92
+ for (const item_id of Object.keys(item_map))
93
+ {
94
+ const item = item_map[item_id]
95
+ const amount = item_amount_map.get_item_amount(item)
96
+ if (amount <= 0)
97
+ {
98
+ continue
99
+ }
100
+ if (item_can_form_any_required_shape(item, required_shapes))
101
+ {
102
+ capable_amount += amount
103
+ }
104
+ }
105
+ return capable_amount
106
+ }
107
+
108
+ /**
109
+ * @param {object} item
110
+ * @param {Map<string, number>} required_shapes
111
+ * @returns {boolean}
112
+ */
113
+ function item_can_form_any_required_shape(item, required_shapes)
114
+ {
115
+ for (const rotated_item of item.get_all_rotated_options())
116
+ {
117
+ if (required_shapes.has(cube_map_function(rotated_item)))
118
+ {
119
+ return true
120
+ }
121
+ }
122
+ return false
123
+ }
124
+
125
+ module.exports = {
126
+ block_has_sufficient_shape_stock,
127
+ build_required_shape_amounts,
128
+ build_available_shape_amounts
129
+ }
@@ -0,0 +1,21 @@
1
+ const { build_message_entry } = require('../../../messages/resolve_error_message_entry')
2
+ const { ALLOCATOR_MESSAGE } = require('../../../messages/Allocator_Message')
3
+
4
+ class Empty_Block_Item_List_Exception extends Error
5
+ {
6
+ /**
7
+ * @param {string|number} block_id
8
+ * @param {number} slot_count
9
+ */
10
+ constructor(block_id, slot_count)
11
+ {
12
+ const message_key = ALLOCATOR_MESSAGE.EMPTY_BLOCK_ITEM_LIST
13
+ super(message_key)
14
+ this.message_entry = build_message_entry(
15
+ message_key,
16
+ [String(block_id), String(slot_count)]
17
+ )
18
+ }
19
+ }
20
+
21
+ module.exports = Empty_Block_Item_List_Exception
@@ -0,0 +1,14 @@
1
+ const { build_message_entry } = require('../../../messages/resolve_error_message_entry')
2
+ const { ALLOCATOR_MESSAGE } = require('../../../messages/Allocator_Message')
3
+
4
+ class Invalid_Stacking_Exception extends Error
5
+ {
6
+ constructor()
7
+ {
8
+ const message_key = ALLOCATOR_MESSAGE.INVALID_STACKING
9
+ super(message_key)
10
+ this.message_entry = build_message_entry(message_key)
11
+ }
12
+ }
13
+
14
+ module.exports = Invalid_Stacking_Exception
@@ -0,0 +1,16 @@
1
+ const { build_message_entry } = require('../../../messages/resolve_error_message_entry')
2
+
3
+ class No_Suitable_Item_Exception extends Error
4
+ {
5
+ /**
6
+ * @param {string} message_key
7
+ * @param {string[]} [params=[]]
8
+ */
9
+ constructor(message_key, params = [])
10
+ {
11
+ super(message_key)
12
+ this.message_entry = build_message_entry(message_key, params)
13
+ }
14
+ }
15
+
16
+ module.exports = No_Suitable_Item_Exception