├── wms ├── __init__.py ├── utils.py ├── warehouse.py ├── tsp.py └── models.py ├── runtime.txt ├── Procfile ├── requirements.txt ├── README.md ├── static ├── style.css ├── index.html └── grid.js ├── .gitignore ├── app.py └── data └── books.json /wms/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-2.7.14 -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn app:app --log-file=- 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | click==6.7 2 | decorator==4.2.1 3 | Flask==0.12.2 4 | gunicorn==19.7.1 5 | itsdangerous==0.24 6 | Jinja2==2.10 7 | MarkupSafe==1.0 8 | networkx==2.1 9 | numpy==1.14.0 10 | typing==3.6.4 11 | Werkzeug==0.14.1 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Warehouse-Navigation 2 | Web app demonstrating order picking algorithms 3 | 4 | ## Installation 5 | 6 | 1. `git clone https://github.com/GTSupplyChainAR/Warehouse-Navigation.git` 7 | 2. `cd Warehouse-Navigation` 8 | 3. `virtualenv venv` 9 | 4. `pip install -r requirements.txt` 10 | 5. `python app.py` 11 | 6. Open `localhost:5000` 12 | -------------------------------------------------------------------------------- /static/style.css: -------------------------------------------------------------------------------- 1 | .navigable-cell { 2 | fill: #d9d9d9; 3 | } 4 | 5 | .shelving-cell { 6 | fill: #676767; 7 | } 8 | 9 | .source-cell { 10 | fill: #7eff00; 11 | } 12 | 13 | .intermediate-cell { 14 | fill: #00cbff; 15 | } 16 | 17 | .destination-cell { 18 | fill: #ff2b00; 19 | } 20 | 21 | .path-item-to-pick-up-cell { 22 | fill: #fff600; 23 | } -------------------------------------------------------------------------------- /wms/utils.py: -------------------------------------------------------------------------------- 1 | import typing 2 | 3 | 4 | def init_grid(dimensions): # type: (typing.Tuple[int, int]) -> [[None]] 5 | """ 6 | Creates grid in (width, height) dimensions. 7 | """ 8 | width, height = dimensions 9 | grid = [] 10 | for col_num in range(width): 11 | row = [None for row_num in range(height)] 12 | grid.append(row) 13 | return grid 14 | 15 | 16 | def manhattan_distance(first, second): # type: (typing.Tuple[int, int], typing.Tuple[int, int]) -> int 17 | first_x, first_y = first 18 | second_x, second_y = second 19 | return abs(first_x - second_x) + abs(first_y - second_y) 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | .static_storage/ 56 | .media/ 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | # PyCharm 107 | .idea/ 108 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | """ 2 | Initializes server and exposes API endpoints 3 | """ 4 | from flask import Flask, request 5 | import networkx as nx 6 | from wms.warehouse import get_simple_warehouse, get_larger_warehouse, get_georgia_tech_library_warehouse 7 | import json 8 | 9 | app = Flask(__name__) 10 | 11 | WAREHOUSES = { 12 | 'simple': get_simple_warehouse(), 13 | 'larger': get_larger_warehouse(), 14 | 'georgia-tech': get_georgia_tech_library_warehouse(), 15 | } 16 | 17 | 18 | @app.route("/") 19 | def index(): 20 | return app.send_static_file('index.html') 21 | 22 | 23 | @app.route("/api/warehouse//") 24 | def get_warehouse(warehouse_id): 25 | 26 | warehouse = WAREHOUSES[warehouse_id] 27 | 28 | return json.dumps({ 29 | 'dimensions': warehouse.dimensions, 30 | 'graph': nx.node_link_data(warehouse.graph), 31 | }) 32 | 33 | 34 | @app.route("/api/warehouse//find-path/", methods=['POST']) 35 | def find_path(warehouse_id): 36 | warehouse = WAREHOUSES[warehouse_id] 37 | 38 | data = request.get_json() 39 | 40 | from_node = data['source'] 41 | to_node = data['destination'] 42 | 43 | path = warehouse.find_path(from_node, to_node) 44 | 45 | return json.dumps(path) 46 | 47 | 48 | @app.route("/api/warehouse//find-pick-path/", methods=['POST']) 49 | def find_pick_path(warehouse_id): 50 | warehouse = WAREHOUSES[warehouse_id] 51 | 52 | data = request.get_json() 53 | 54 | from_node = tuple(data['source']) 55 | intermediate_nodes = data['items'] 56 | 57 | intermediate_nodes = [tuple(node) for node in intermediate_nodes] 58 | 59 | pick_path = warehouse.find_pick_path(from_node, intermediate_nodes) 60 | 61 | return json.dumps({ 62 | 'items': list(intermediate_nodes), 63 | 'path': pick_path, 64 | }) 65 | 66 | 67 | if __name__ == '__main__': 68 | app.run(debug=True) 69 | -------------------------------------------------------------------------------- /wms/warehouse.py: -------------------------------------------------------------------------------- 1 | """ 2 | Contains layouts for different grid warehouses 3 | """ 4 | 5 | from models import GridWarehouse, NavigableTileCell, ShelvingCell, Direction 6 | import utils 7 | import copy 8 | 9 | 10 | def get_simple_warehouse(): 11 | dimensions = (4, 4) 12 | 13 | grid = utils.init_grid(dimensions) 14 | 15 | # Fill out first column, bottom to top 16 | grid[0][0] = NavigableTileCell() 17 | grid[0][1] = NavigableTileCell() 18 | grid[0][2] = NavigableTileCell() 19 | grid[0][3] = NavigableTileCell() 20 | 21 | # Fill out second column, bottom to top 22 | grid[1][0] = NavigableTileCell() 23 | grid[1][1] = ShelvingCell(Direction.SOUTH) 24 | grid[1][2] = ShelvingCell(Direction.NORTH) 25 | grid[1][3] = NavigableTileCell() 26 | 27 | # Fill out third column, bottom to top 28 | grid[2][0] = NavigableTileCell() 29 | grid[2][1] = ShelvingCell(Direction.SOUTH) 30 | grid[2][2] = ShelvingCell(Direction.NORTH) 31 | grid[2][3] = NavigableTileCell() 32 | 33 | # Fill out fourth column, bottom to top 34 | grid[3][0] = NavigableTileCell() 35 | grid[3][1] = NavigableTileCell() 36 | grid[3][2] = NavigableTileCell() 37 | grid[3][3] = NavigableTileCell() 38 | 39 | warehouse = GridWarehouse(dimensions, grid) 40 | 41 | return warehouse 42 | 43 | 44 | def get_larger_warehouse(): 45 | dimensions = (8, 4) 46 | 47 | grid = utils.init_grid(dimensions) 48 | 49 | for row_num in range(4): 50 | grid[0][row_num] = NavigableTileCell() 51 | 52 | for col_num in range(1, 7): 53 | grid[col_num][0] = NavigableTileCell() 54 | grid[col_num][1] = ShelvingCell(Direction.NORTH) 55 | grid[col_num][2] = ShelvingCell(Direction.SOUTH) 56 | grid[col_num][3] = NavigableTileCell() 57 | 58 | for row_num in range(4): 59 | grid[7][row_num] = NavigableTileCell() 60 | 61 | warehouse = GridWarehouse(dimensions, grid) 62 | 63 | return warehouse 64 | 65 | 66 | def get_georgia_tech_library_warehouse(): 67 | larger_warehouse = get_larger_warehouse() 68 | larger_warehouse_grid = larger_warehouse.grid 69 | 70 | dimensions = (8, 16) 71 | grid = utils.init_grid(dimensions) 72 | 73 | for col_num in range(8): 74 | for row_num in range(16): 75 | grid[col_num][row_num] = copy.copy(larger_warehouse_grid[col_num][row_num % 4]) 76 | 77 | return GridWarehouse(dimensions, grid) 78 | -------------------------------------------------------------------------------- /wms/tsp.py: -------------------------------------------------------------------------------- 1 | """ 2 | Implementation of Christofide's Algorithm for Traveling Salesman Problem! 3 | Author: Pramod Kotipalli (pramodk@gatech.edu) 4 | 5 | Properties: 6 | - Approximation ratio of 3/2 (within 50% of optimal solution) 7 | - O(n ^ 3) time runtime on graph with n nodes 8 | 9 | References: 10 | - https://en.wikipedia.org/wiki/Christofides_algorithm 11 | - https://www.geeksforgeeks.org/backtracking-set-7-hamiltonian-cycle/ 12 | 13 | """ 14 | import networkx as nx 15 | import copy 16 | 17 | 18 | def tsp_circuit(G, source_node): 19 | """ 20 | Christofide's algorithm 21 | """ 22 | # 1. Create an MST 23 | T = nx.minimum_spanning_tree(G) # type: nx.Graph 24 | 25 | # 2. Get all odd nodes 26 | O = _get_nodes_with_odd_degree(T) 27 | 28 | # 3. Induce a sub-graph on the odd nodes 29 | subgraph_on_O = G.subgraph(O) 30 | 31 | # 4. Compute a minimum weight matching on the sub-graph 32 | M = _min_weight_matching(subgraph_on_O) 33 | 34 | # 5. Add the matching's edges to the MST 35 | _add_matching_to_mst(T, M) 36 | 37 | # 6. Compute a Hamiltonian circuit 38 | path = _hamilton_circuit(T, source=source_node) 39 | 40 | return path 41 | 42 | 43 | def _get_nodes_with_odd_degree(G): 44 | nodes = [] 45 | for node in G.nodes: 46 | if nx.degree(G, node) % 2 == 1: 47 | nodes.append(node) 48 | return nodes 49 | 50 | 51 | def _min_weight_matching(G): # type: (nx.Graph) -> set 52 | nodes = copy.deepcopy(set(G.nodes)) 53 | 54 | matching = set() 55 | 56 | while nodes: 57 | v = nodes.pop() 58 | min_weight = float('inf') 59 | closest = None 60 | 61 | if not nodes: 62 | raise ValueError("G has an odd number of nodes") 63 | 64 | for u in nodes: 65 | edge = G.get_edge_data(u, v, default=None) 66 | if edge is not None and edge['weight'] < min_weight: 67 | min_weight = edge['weight'] 68 | closest = u 69 | 70 | matching.add((v, closest, min_weight)) 71 | nodes.remove(closest) 72 | 73 | return matching 74 | 75 | 76 | def _add_matching_to_mst(T, M): 77 | for u, v, weight in M: 78 | T.add_edge(u, v, weight=weight) 79 | 80 | 81 | def _hamilton_circuit(G, source): 82 | ham_path = [source] 83 | 84 | path_found = _hamilton_circuit_helper(G, source, ham_path) 85 | 86 | if not path_found: 87 | return None 88 | 89 | return ham_path 90 | 91 | 92 | def _hamilton_circuit_helper(G, source, ham_path): # type: (nx.Graph, []) -> bool 93 | # If the path has all the nodes of G, check if there is an edge back to the source 94 | if len(ham_path) == G.number_of_nodes(): 95 | edge_back_to_source = G.get_edge_data(ham_path[-1], source, default=None) 96 | if edge_back_to_source is not None: 97 | ham_path.append(source) 98 | return True 99 | else: 100 | return False 101 | 102 | for node in G.nodes: 103 | edge = G.get_edge_data(ham_path[-1], node, default=None) 104 | 105 | if edge is not None and node not in ham_path: 106 | ham_path.append(node) 107 | 108 | if _hamilton_circuit_helper(G, source, ham_path): 109 | return True 110 | 111 | # Else, the path wasn't proper, so backtrack 112 | ham_path.pop(len(ham_path) - 1) 113 | 114 | return False 115 | -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Grid Warehouses 9 | 10 | 11 | 12 |
13 |
14 |
15 |

Grid Warehouse Do you know da wae?

16 |
17 |
18 |
19 | 20 |
21 |
22 |

Configuration

23 | 24 |
25 |
26 | 27 | 34 |
35 | 36 |
37 | 38 |
39 | 40 | 44 |
45 | 46 |
47 | 48 | 52 |
53 | 54 |
55 | 56 |
57 | 58 | 62 |
63 | 64 |
65 | 66 | 69 | 70 |
71 | 72 |
73 |
74 |

Rendering

75 | 76 |
77 | 78 | 79 | 80 | 81 | 90 | 91 | 92 | 93 | 94 |
95 |
96 |
97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /wms/models.py: -------------------------------------------------------------------------------- 1 | import typing 2 | import networkx as nx 3 | from tsp import tsp_circuit 4 | from utils import manhattan_distance 5 | 6 | 7 | PositionType = typing.Tuple[int, int] 8 | 9 | 10 | class GridWarehouse(object): 11 | dimensions = None # type: PositionType 12 | grid = None # type: [[GridWarehouseCell]] 13 | graph = None # type: nx.Graph 14 | 15 | def __init__(self, dimensions, grid): # type: (PositionType, [[GridWarehouseCell]]) -> None 16 | self.dimensions = dimensions 17 | self.grid = grid 18 | self.graph = self._construct_graph() 19 | 20 | def find_path(self, from_node, to_node): # type: (PositionType, PositionType) -> [PositionType] 21 | return nx.shortest_path(self.graph, from_node, to_node) 22 | 23 | def find_pick_path(self, from_node, intermediate_nodes): 24 | # type: (PositionType, PositionType, [PositionType]) -> [PositionType] 25 | 26 | # 1. Create a graph on the nodes in this order (removes all nodes from graph not in this path) 27 | nodes = [from_node] + intermediate_nodes 28 | G_tsp = nx.Graph() 29 | for node in nodes: 30 | G_tsp.add_node(node) 31 | # Add edges into the graph corresponding to the manhattan distance between two points 32 | for idx_i, i in enumerate(nodes): 33 | for idx_j, j in enumerate(nodes): 34 | if i is not j: 35 | G_tsp.add_edge(i, j, weight=self.distance(i, j)) 36 | 37 | # 2. Compute the TSP 38 | tsp_tour = tsp_circuit(G_tsp, from_node) 39 | if tsp_tour is None: 40 | raise ValueError("Couldn't find picking path.") 41 | 42 | # 3. Now, re-introduce the intermediate nodes to compute the real path in the warehouse 43 | final_path = [tsp_tour[0]] 44 | for next_cell in tsp_tour[1:]: 45 | # Get the last cell of the path 46 | current_cell = final_path[-1] 47 | # Find the path to the next node (remove the first element with is equal to current_node) 48 | path_to_next_cell = nx.shortest_path(self.graph, current_cell, next_cell)[1:] 49 | # Add in all cells from the path to the next cell 50 | for path_cell in path_to_next_cell: 51 | final_path.append(path_cell) 52 | 53 | return final_path 54 | 55 | 56 | def distance(self, from_cell, to_cell): 57 | """ 58 | Admissible distance heuristic for this warehouse 59 | """ 60 | return manhattan_distance(from_cell, to_cell) 61 | 62 | def __str__(self): 63 | row_strings = [] 64 | for column in self.grid: 65 | column_strings = [] 66 | for cell in column: 67 | if isinstance(cell, NavigableTileCell): 68 | column_strings.append("+") 69 | elif isinstance(cell, ShelvingCell): 70 | column_strings.append("x") 71 | else: 72 | raise TypeError("Unknown cell type: %s" % type(cell)) 73 | row_strings.append("\t".join(column_strings) + "\n") 74 | return \ 75 | "Grid Warehouse (%d height x %d width)\n" % self.dimensions + \ 76 | "".join(row_strings) 77 | 78 | def _construct_graph(self): # type: () -> nx.Graph 79 | graph = nx.Graph() 80 | 81 | # Add all navigable tiles as nodes 82 | for i, row in enumerate(self.grid): 83 | for j, cell in enumerate(row): 84 | if not isinstance(cell, NavigableTileCell): 85 | continue 86 | graph.add_node((i, j)) 87 | 88 | # Add all edges 89 | for i, row in enumerate(self.grid): 90 | for j, cell in enumerate(row): 91 | if not isinstance(cell, NavigableTileCell): 92 | continue 93 | 94 | cell_coordinates = (i, j) 95 | 96 | neighbor_coordinates = self._get_neighboring_navigation_cells(cell_coordinates) 97 | 98 | for neighbor_cell_coordinate in neighbor_coordinates: # type: typing.Tuple(int, int) 99 | graph.add_edge(cell_coordinates, neighbor_cell_coordinate, weight=1) 100 | 101 | return graph 102 | 103 | def _get_neighboring_navigation_cells(self, origin_cell_coordinates): # type: () -> [typing.Tuple(int, int)] 104 | offsets = [ 105 | (-1, 0), 106 | (0, +1), 107 | (+1, 0), 108 | (0, -1), 109 | ] 110 | 111 | neighbors = [] 112 | 113 | for offset_x, offset_y in offsets: 114 | neighbor_coordinate_to_examine = (origin_cell_coordinates[0] + offset_x, origin_cell_coordinates[1] + offset_y) 115 | 116 | if neighbor_coordinate_to_examine[0] < 0 or neighbor_coordinate_to_examine[0] >= self.dimensions[0]: 117 | continue 118 | 119 | if neighbor_coordinate_to_examine[1] < 0 or neighbor_coordinate_to_examine[1] >= self.dimensions[1]: 120 | continue 121 | 122 | neighbor_cell = self.grid[neighbor_coordinate_to_examine[0]][neighbor_coordinate_to_examine[1]] 123 | 124 | if not isinstance(neighbor_cell, NavigableTileCell): 125 | continue 126 | 127 | neighbors.append(neighbor_coordinate_to_examine) 128 | 129 | return neighbors 130 | 131 | 132 | class GridWarehouseCell(object): 133 | pass 134 | 135 | 136 | class Direction(object): 137 | NORTH = 1 138 | EAST = 2 139 | SOUTH = 3 140 | WEST = 4 141 | 142 | 143 | class ShelvingCell(GridWarehouseCell): 144 | items = None # type: [Item] 145 | direction = None # type: Direction 146 | 147 | def __init__(self, direction, items=None): 148 | self.direction = direction 149 | self.items = items or [] 150 | 151 | 152 | class NavigableTileCell(GridWarehouseCell): 153 | pass 154 | 155 | 156 | class Item(object): 157 | name = None # type: str 158 | rfid = None # type: str 159 | 160 | def __init__(self, name, rfid): 161 | self.name = name 162 | self.rfid = rfid 163 | -------------------------------------------------------------------------------- /static/grid.js: -------------------------------------------------------------------------------- 1 | // Based on: https://bl.ocks.org/cagrimmett/07f8c8daea00946b9e704e3efcbd5739 2 | 3 | // Source: https://stackoverflow.com/a/901144 4 | function getQueryStringParameterByName(name, url) { 5 | if (!url) url = window.location.href; 6 | name = name.replace(/[\[\]]/g, "\\$&"); 7 | var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), 8 | results = regex.exec(url); 9 | if (!results) return null; 10 | if (!results[2]) return ''; 11 | return decodeURIComponent(results[2].replace(/\+/g, " ")); 12 | } 13 | 14 | function handleServerError(error) { 15 | alert("Failure!"); 16 | } 17 | 18 | function arraysEqual(a, b) { 19 | if (a === b) return true; 20 | if (a === null || b === null) return false; 21 | if (a.length !== b.length) return false; 22 | 23 | for (var i = 0; i < a.length; ++i) { 24 | if (a[i] !== b[i]) return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | function arrayContains(array, element, equalityMethod) { 31 | for (var i = 0; i < array.length; i++) { 32 | if (equalityMethod(array[i], element)) { 33 | return true; 34 | } 35 | } 36 | return false; 37 | } 38 | 39 | function initializeGrid(dimensions, defaultData) { 40 | var width = dimensions[0]; 41 | var height = dimensions[1]; 42 | var grid = []; 43 | for (var colNum = 0; colNum < width; colNum++) { 44 | var column = []; 45 | for (var rowNum = 0; rowNum < height; rowNum++) { 46 | column.push(defaultData); 47 | } 48 | grid.push(column); 49 | } 50 | return grid; 51 | } 52 | 53 | const GridCellTypeEnum = Object.freeze({ 54 | Navigable: 1, 55 | Shelving: 2, 56 | 57 | PathIntermediate: 3, 58 | PathSource: 4, 59 | PathDestination: 5, 60 | 61 | PathItemToPickUp: 6, 62 | }); 63 | 64 | function Graph(nodeLinkData) { // nodeLinkData from Python's networkx.node_link_data 65 | this.nodes = []; 66 | this.adjacencyList = {}; 67 | 68 | // Add all nodes 69 | for (var i = 0; i < nodeLinkData.nodes.length; i++) { 70 | var node = nodeLinkData.nodes[i]; 71 | this.nodes.push(node.id); 72 | } 73 | 74 | // Add all edges 75 | for (var i = 0; i < nodeLinkData.links.length; i++) { 76 | var link = nodeLinkData.links[i]; 77 | 78 | if (this.adjacencyList[link.source] === undefined) { 79 | this.adjacencyList[link.source] = []; 80 | } 81 | 82 | if (this.adjacencyList[link.target] === undefined) { 83 | this.adjacencyList[link.target] = []; 84 | } 85 | 86 | this.adjacencyList[link.source].push(link.target); 87 | this.adjacencyList[link.target].push(link.source); 88 | } 89 | } 90 | 91 | function GridWarehouse(warehouseId) { 92 | this.warehouseId = warehouseId; 93 | this.dimensions = null; 94 | this.grid = null; 95 | this.graph = null; 96 | 97 | // The last computed path and items 98 | this.activeOrderPickingSession = null; 99 | 100 | this.loadWarehouse = function () { 101 | var _this = this; 102 | 103 | return $.ajax({ 104 | url: '/api/warehouse/' + this.warehouseId + '/', 105 | method: 'GET', 106 | }).done(function (data) { 107 | var graphData = JSON.parse(data); 108 | 109 | // Initialize the grid and graphs 110 | _this.dimensions = graphData.dimensions; 111 | _this.grid = initializeGrid(_this.dimensions, GridCellTypeEnum.Shelving); 112 | _this.graph = new Graph(graphData.graph); 113 | 114 | for (var i = 0; i < _this.graph.nodes.length; i++) { 115 | var node = _this.graph.nodes[i]; 116 | // Indicate that the cell is navigable 117 | _this.grid[node[0]][node[1]] = GridCellTypeEnum.Navigable; 118 | } 119 | }); 120 | }; 121 | 122 | this.findPickPath = function (sourceCell, itemsToPickUp) { 123 | var _this = this; 124 | return $.ajax({ 125 | url: '/api/warehouse/' + this.warehouseId + '/find-pick-path/', 126 | method: 'POST', 127 | data: JSON.stringify({ 128 | source: sourceCell, 129 | items: itemsToPickUp, 130 | }), 131 | contentType: "application/json; charset=utf-8", 132 | dataType: "json", 133 | }).done(function (data) { 134 | var path = data.path; 135 | var items = data.items; 136 | 137 | for (var i = 0; i < path.length; i++) { 138 | var pathCell = path[i]; 139 | 140 | var cellType; 141 | 142 | if (i === 0) { 143 | cellType = GridCellTypeEnum.PathSource; 144 | } else if (i === path.length - 1) { 145 | cellType = GridCellTypeEnum.PathDestination; 146 | } else if (arrayContains(items, pathCell, arraysEqual)) { 147 | cellType = GridCellTypeEnum.PathItemToPickUp; 148 | } else { 149 | cellType = GridCellTypeEnum.PathIntermediate; 150 | } 151 | 152 | _this.grid[pathCell[0]][pathCell[1]] = cellType; 153 | } 154 | 155 | _this.activeOrderPickingSession = { 156 | path: path, 157 | items: items, 158 | } 159 | 160 | }).fail(handleServerError); 161 | }; 162 | 163 | this.render = function () { 164 | // width, height 165 | var cellDimensions = [50, 50]; 166 | 167 | var gridWidth = cellDimensions[0] * gridWarehouse.dimensions[0]; 168 | var gridHeight = cellDimensions[1] * gridWarehouse.dimensions[1]; 169 | 170 | /** 171 | * Generates a 2D array of the same shape of grid containing all the data needed to render a D3 grid 172 | * @param grid - A grid of enums indicating what a cell is 173 | * @param cellDimensions - The pixel height, width of a cell in the grid 174 | */ 175 | function getGridDataForD3(grid, cellDimensions) { 176 | var numCols = grid.length; 177 | var numRows = grid[0].length; 178 | 179 | var data = initializeGrid([numCols, numRows]); 180 | // Dimensions of the cell in pixels 181 | var cellWidth = cellDimensions[0]; 182 | var cellHeight = cellDimensions[1]; 183 | 184 | // iterate for rows 185 | for (var column = 0; column < numCols; column++) { 186 | // iterate for cells/columns inside rows 187 | for (var row = 0; row < numRows; row++) { 188 | var d3Coordinates = computeD3GridCoordinates([column, row]); 189 | data[column][row] = { 190 | x: d3Coordinates[0], 191 | y: d3Coordinates[1], 192 | width: cellWidth, 193 | height: cellHeight, 194 | gridCellType: grid[column][row] 195 | }; 196 | } 197 | } 198 | return data; 199 | } 200 | 201 | function computeD3GridCoordinates(coordinates) { 202 | return [ 203 | cellDimensions[0] * coordinates[0], 204 | (gridHeight - cellDimensions[1]) - cellDimensions[1] * coordinates[1], 205 | ] 206 | } 207 | 208 | function getArrowDataForD3(pickPath, items) { 209 | var symbols = []; 210 | 211 | for (var i = 1; i < pickPath.length; i++) { 212 | var symbol = {}; 213 | 214 | var current = pickPath[i - 1]; 215 | var next = pickPath[i]; 216 | 217 | [symbol.startX, symbol.startY] = computeD3GridCoordinates(current); 218 | [symbol.endX, symbol.endY] = computeD3GridCoordinates(next); 219 | 220 | symbol.startX += cellDimensions[0] / 2; 221 | symbol.startY += cellDimensions[1] / 2; 222 | symbol.endX += cellDimensions[0] / 2; 223 | symbol.endY += cellDimensions[1] / 2; 224 | 225 | symbols.push(symbol); 226 | } 227 | 228 | return symbols; 229 | } 230 | 231 | // Render Grid with D3 232 | 233 | var svg = d3.select("svg"); 234 | svg 235 | .attr("height", gridHeight + "px") 236 | .attr("width", gridWidth + "px"); 237 | 238 | var d3Data = getGridDataForD3(gridWarehouse.grid, cellDimensions); 239 | console.log(d3Data); 240 | 241 | var column = svg.selectAll(".col") 242 | .data(d3Data) 243 | .enter() 244 | .append("g") 245 | .attr("class", "col"); 246 | 247 | var row = column.selectAll(".square") 248 | .data(function (d) { 249 | return d; 250 | }) 251 | .enter() 252 | .append("rect") 253 | .attr("class", "square") 254 | .attr("x", function (d) { 255 | return d.x; 256 | }) 257 | .attr("y", function (d) { 258 | return d.y; 259 | }) 260 | .attr("width", function (d) { 261 | return d.width; 262 | }) 263 | .attr("height", function (d) { 264 | return d.height; 265 | }) 266 | .attr("class", function (d) { 267 | switch (d.gridCellType) { 268 | case GridCellTypeEnum.Navigable: 269 | return "navigable-cell"; 270 | case GridCellTypeEnum.Shelving: 271 | return "shelving-cell"; 272 | case GridCellTypeEnum.PathSource: 273 | return "source-cell"; 274 | case GridCellTypeEnum.PathIntermediate: 275 | return "intermediate-cell"; 276 | case GridCellTypeEnum.PathDestination: 277 | return "destination-cell"; 278 | case GridCellTypeEnum.PathItemToPickUp: 279 | return "path-item-to-pick-up-cell"; 280 | default: 281 | throw new Error("Unknown type"); 282 | } 283 | }) 284 | .style("stroke", "#222"); 285 | 286 | var symbolData = getArrowDataForD3(gridWarehouse.activeOrderPickingSession.path, gridWarehouse.activeOrderPickingSession.items); 287 | column.selectAll(".square") 288 | .data(symbolData) 289 | .enter() 290 | .append('line') 291 | .attr('x1', function (d) {return d.startX}) 292 | .attr('y1', function (d) {return d.startY}) 293 | .attr('x2', function (d) {return d.endX}) 294 | .attr('y2', function (d) {return d.endY}) 295 | .attr("stroke", "#f00") 296 | .attr("stroke-width", 2) 297 | .attr('marker-start', 'url(#arrow)'); 298 | 299 | }; 300 | } 301 | 302 | var gridWarehouse; 303 | $(document).ready(function () { 304 | 305 | var warehouseId = getQueryStringParameterByName('warehouseId'); 306 | var sourceX = parseInt(getQueryStringParameterByName('sourceX')); 307 | var sourceY = parseInt(getQueryStringParameterByName('sourceY')); 308 | var itemsToPickUp = JSON.parse(getQueryStringParameterByName('itemsToPickUp')); 309 | 310 | $('#warehouseId').val(warehouseId); 311 | $('#sourceX').val(sourceX); 312 | $('#sourceY').val(sourceY); 313 | $('#itemsToPickUp').val(JSON.stringify(itemsToPickUp)); 314 | 315 | gridWarehouse = new GridWarehouse(warehouseId); 316 | gridWarehouse 317 | .loadWarehouse() 318 | .then(function () { 319 | gridWarehouse.findPickPath([sourceX, sourceY], itemsToPickUp) 320 | .then(gridWarehouse.render); 321 | }); 322 | 323 | }); -------------------------------------------------------------------------------- /data/books.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "location": { 4 | "aisle": "E", 5 | "column": "100", 6 | "row": "A" 7 | }, 8 | "book": { 9 | "title": "Magician: Apprentice", 10 | "author": "Raymond E. Feist" 11 | } 12 | }, 13 | { 14 | "location": { 15 | "aisle": "E", 16 | "column": "100", 17 | "row": "B" 18 | }, 19 | "book": { 20 | "title": "Firestar", 21 | "author": "Michael Flynn" 22 | } 23 | }, 24 | { 25 | "location": { 26 | "aisle": "D", 27 | "column": "101", 28 | "row": "A" 29 | }, 30 | "book": { 31 | "title": "Changeling", 32 | "author": "Anne McCaffrey, Beth Ann Scarborough " 33 | } 34 | }, 35 | { 36 | "location": { 37 | "aisle": "A", 38 | "column": "100", 39 | "row": "A" 40 | }, 41 | "book": { 42 | "title": "Live Forever ", 43 | "author": "Jack Vance " 44 | } 45 | }, 46 | { 47 | "location": { 48 | "aisle": "D", 49 | "column": "101", 50 | "row": "B" 51 | }, 52 | "book": { 53 | "title": "Dragonsdawn", 54 | "author": "Anne McCaffrey " 55 | } 56 | }, 57 | { 58 | "location": { 59 | "aisle": "C", 60 | "column": "100", 61 | "row": "A" 62 | }, 63 | "book": { 64 | "title": "Odyssey", 65 | "author": "Jack mcdevitt" 66 | } 67 | }, 68 | { 69 | "location": { 70 | "aisle": "A", 71 | "column": "100", 72 | "row": "B" 73 | }, 74 | "book": { 75 | "title": "Titan ", 76 | "author": "John Varley " 77 | } 78 | }, 79 | { 80 | "location": { 81 | "aisle": "D", 82 | "column": "101", 83 | "row": "C" 84 | }, 85 | "book": { 86 | "title": "The Dolphins of Pern", 87 | "author": "Anne McCaffrey " 88 | } 89 | }, 90 | { 91 | "location": { 92 | "aisle": "A", 93 | "column": "100", 94 | "row": "C" 95 | }, 96 | "book": { 97 | "title": "The Snow Queen ", 98 | "author": "Joan D. Vinge " 99 | } 100 | }, 101 | { 102 | "location": { 103 | "aisle": "C", 104 | "column": "100", 105 | "row": "B" 106 | }, 107 | "book": { 108 | "title": "Snow white and the giants", 109 | "author": "JT Mcintosh" 110 | } 111 | }, 112 | { 113 | "location": { 114 | "aisle": "D", 115 | "column": "101", 116 | "row": "D" 117 | }, 118 | "book": { 119 | "title": "Freedom's Ransom", 120 | "author": "Anne McCaffrey " 121 | } 122 | }, 123 | { 124 | "location": { 125 | "aisle": "A", 126 | "column": "100", 127 | "row": "D" 128 | }, 129 | "book": { 130 | "title": "Time's Edge ", 131 | "author": "Rysa Walker " 132 | } 133 | }, 134 | { 135 | "location": { 136 | "aisle": "C", 137 | "column": "100", 138 | "row": "C" 139 | }, 140 | "book": { 141 | "title": "The time shifters", 142 | "author": "Sam merwin JR" 143 | } 144 | }, 145 | { 146 | "location": { 147 | "aisle": "A", 148 | "column": "100", 149 | "row": "E" 150 | }, 151 | "book": { 152 | "title": "The Black Flame ", 153 | "author": "Stanley G. Weinbaum " 154 | } 155 | }, 156 | { 157 | "location": { 158 | "aisle": "G", 159 | "column": "100", 160 | "row": "A" 161 | }, 162 | "book": { 163 | "title": "Chiller", 164 | "author": "Greg Benford" 165 | } 166 | }, 167 | { 168 | "location": { 169 | "aisle": "D", 170 | "column": "101", 171 | "row": "E" 172 | }, 173 | "book": { 174 | "title": "Dinosaur Planet", 175 | "author": "Anne McCaffrey " 176 | } 177 | }, 178 | { 179 | "location": { 180 | "aisle": "A", 181 | "column": "100", 182 | "row": "F" 183 | }, 184 | "book": { 185 | "title": "Dragons of Autumn Twilight", 186 | "author": "Margaret Weis and Tracy Hickman" 187 | } 188 | }, 189 | { 190 | "location": { 191 | "aisle": "C", 192 | "column": "100", 193 | "row": "D" 194 | }, 195 | "book": { 196 | "title": "The bane of lord caladon", 197 | "author": "Craig mills" 198 | } 199 | }, 200 | { 201 | "location": { 202 | "aisle": "B", 203 | "column": "101", 204 | "row": "A" 205 | }, 206 | "book": { 207 | "title": "The Hobbit", 208 | "author": "J.R.R. Tolkien" 209 | } 210 | }, 211 | { 212 | "location": { 213 | "aisle": "A", 214 | "column": "102", 215 | "row": "A" 216 | }, 217 | "book": { 218 | "title": "King's Test", 219 | "author": "Margaret Weis" 220 | } 221 | }, 222 | { 223 | "location": { 224 | "aisle": "G", 225 | "column": "100", 226 | "row": "B" 227 | }, 228 | "book": { 229 | "title": "Golem 100", 230 | "author": "Alfred Bester" 231 | } 232 | }, 233 | { 234 | "location": { 235 | "aisle": "B", 236 | "column": "101", 237 | "row": "B" 238 | }, 239 | "book": { 240 | "title": "Dracula The Un-Dead", 241 | "author": "Dacre Stoker and Ian Holt" 242 | } 243 | }, 244 | { 245 | "location": { 246 | "aisle": "D", 247 | "column": "101", 248 | "row": "F" 249 | }, 250 | "book": { 251 | "title": "The White Dragon ", 252 | "author": "Anne McCaffrey " 253 | } 254 | }, 255 | { 256 | "location": { 257 | "aisle": "E", 258 | "column": "100", 259 | "row": "C" 260 | }, 261 | "book": { 262 | "title": "Cyber Way", 263 | "author": "Alan Dean Foster" 264 | } 265 | }, 266 | { 267 | "location": { 268 | "aisle": "C", 269 | "column": "100", 270 | "row": "E" 271 | }, 272 | "book": { 273 | "title": "The grail war", 274 | "author": "Richard monaco" 275 | } 276 | }, 277 | { 278 | "location": { 279 | "aisle": "F", 280 | "column": "101", 281 | "row": "A" 282 | }, 283 | "book": { 284 | "title": "Paradise is not enough", 285 | "author": "Michael Elder" 286 | } 287 | }, 288 | { 289 | "location": { 290 | "aisle": "B", 291 | "column": "101", 292 | "row": "C" 293 | }, 294 | "book": { 295 | "title": "The City Machine", 296 | "author": "Louis Trimble" 297 | } 298 | }, 299 | { 300 | "location": { 301 | "aisle": "E", 302 | "column": "100", 303 | "row": "D" 304 | }, 305 | "book": { 306 | "title": "Midworld", 307 | "author": "Alan Dean Foster" 308 | } 309 | }, 310 | { 311 | "location": { 312 | "aisle": "G", 313 | "column": "100", 314 | "row": "C" 315 | }, 316 | "book": { 317 | "title": "No Enemy But Time", 318 | "author": "Michael Bishop" 319 | } 320 | }, 321 | { 322 | "location": { 323 | "aisle": "A", 324 | "column": "102", 325 | "row": "B" 326 | }, 327 | "book": { 328 | "title": "The War of the World's", 329 | "author": "H.G.Wells" 330 | } 331 | }, 332 | { 333 | "location": { 334 | "aisle": "D", 335 | "column": "103", 336 | "row": "F" 337 | }, 338 | "book": { 339 | "title": "The Secret of Life", 340 | "author": "Paul McAuley " 341 | } 342 | }, 343 | { 344 | "location": { 345 | "aisle": "B", 346 | "column": "101", 347 | "row": "D" 348 | }, 349 | "book": { 350 | "title": "The Misplaced Legion", 351 | "author": "Harry Turtledove" 352 | } 353 | }, 354 | { 355 | "location": { 356 | "aisle": "A", 357 | "column": "102", 358 | "row": "C" 359 | }, 360 | "book": { 361 | "title": "The picture of Dorian Gray", 362 | "author": "Oscar Wilde" 363 | } 364 | }, 365 | { 366 | "location": { 367 | "aisle": "G", 368 | "column": "100", 369 | "row": "D" 370 | }, 371 | "book": { 372 | "title": "Cities in Flight", 373 | "author": "James Blish" 374 | } 375 | }, 376 | { 377 | "location": { 378 | "aisle": "E", 379 | "column": "100", 380 | "row": "E" 381 | }, 382 | "book": { 383 | "title": "Here Be Demons", 384 | "author": "Esther Frieshner" 385 | } 386 | }, 387 | { 388 | "location": { 389 | "aisle": "F", 390 | "column": "101", 391 | "row": "B" 392 | }, 393 | "book": { 394 | "title": "The house of the scorpion", 395 | "author": "Nancy Farmer" 396 | } 397 | }, 398 | { 399 | "location": { 400 | "aisle": "C", 401 | "column": "100", 402 | "row": "F" 403 | }, 404 | "book": { 405 | "title": "An alien heat", 406 | "author": "Harper & Row" 407 | } 408 | }, 409 | { 410 | "location": { 411 | "aisle": "D", 412 | "column": "103", 413 | "row": "E" 414 | }, 415 | "book": { 416 | "title": "A Dance with Dragons", 417 | "author": "George R. R. Martin" 418 | } 419 | }, 420 | { 421 | "location": { 422 | "aisle": "G", 423 | "column": "100", 424 | "row": "E" 425 | }, 426 | "book": { 427 | "title": "The Cold Between", 428 | "author": "Elizabeth Bonesteel" 429 | } 430 | }, 431 | { 432 | "location": { 433 | "aisle": "B", 434 | "column": "101", 435 | "row": "E" 436 | }, 437 | "book": { 438 | "title": "The Players of Null-A", 439 | "author": "A.E. van Vogt" 440 | } 441 | }, 442 | { 443 | "location": { 444 | "aisle": "E", 445 | "column": "100", 446 | "row": "F" 447 | }, 448 | "book": { 449 | "title": "The Infinite Man", 450 | "author": "Daniel F. Galouye" 451 | } 452 | }, 453 | { 454 | "location": { 455 | "aisle": "A", 456 | "column": "102", 457 | "row": "D" 458 | }, 459 | "book": { 460 | "title": "Saturn returns ", 461 | "author": "Sean Williams " 462 | } 463 | }, 464 | { 465 | "location": { 466 | "aisle": "G", 467 | "column": "100", 468 | "row": "F" 469 | }, 470 | "book": { 471 | "title": "The Immortality Factor", 472 | "author": "Been Bova" 473 | } 474 | }, 475 | { 476 | "location": { 477 | "aisle": "F", 478 | "column": "101", 479 | "row": "C" 480 | }, 481 | "book": { 482 | "title": "Hanged man", 483 | "author": "P. N. Elrod" 484 | } 485 | }, 486 | { 487 | "location": { 488 | "aisle": "D", 489 | "column": "103", 490 | "row": "D" 491 | }, 492 | "book": { 493 | "title": "A Storm of Swords", 494 | "author": "George R. R. Martin" 495 | } 496 | }, 497 | { 498 | "location": { 499 | "aisle": "B", 500 | "column": "101", 501 | "row": "F" 502 | }, 503 | "book": { 504 | "title": "Supermind", 505 | "author": "A.E. van Vogt" 506 | } 507 | }, 508 | { 509 | "location": { 510 | "aisle": "E", 511 | "column": "102", 512 | "row": "A" 513 | }, 514 | "book": { 515 | "title": "With A Finger in My I", 516 | "author": "David Gerrold" 517 | } 518 | }, 519 | { 520 | "location": { 521 | "aisle": "G", 522 | "column": "102", 523 | "row": "A" 524 | }, 525 | "book": { 526 | "title": "Power Plant", 527 | "author": "Been Bova" 528 | } 529 | }, 530 | { 531 | "location": { 532 | "aisle": "A", 533 | "column": "102", 534 | "row": "E" 535 | }, 536 | "book": { 537 | "title": "Journey into the flames", 538 | "author": "T.R. Williams " 539 | } 540 | }, 541 | { 542 | "location": { 543 | "aisle": "C", 544 | "column": "102", 545 | "row": "A" 546 | }, 547 | "book": { 548 | "title": "The sleeping sorceress", 549 | "author": "Michael moorcock" 550 | } 551 | }, 552 | { 553 | "location": { 554 | "aisle": "B", 555 | "column": "103", 556 | "row": "A" 557 | }, 558 | "book": { 559 | "title": "The Primrose Path", 560 | "author": "Bram Stoker" 561 | } 562 | }, 563 | { 564 | "location": { 565 | "aisle": "G", 566 | "column": "102", 567 | "row": "B" 568 | }, 569 | "book": { 570 | "title": "Transhuman", 571 | "author": "Been Bova" 572 | } 573 | }, 574 | { 575 | "location": { 576 | "aisle": "E", 577 | "column": "102", 578 | "row": "B" 579 | }, 580 | "book": { 581 | "title": "Cloud & Ashes", 582 | "author": "Greer Gilman" 583 | } 584 | }, 585 | { 586 | "location": { 587 | "aisle": "F", 588 | "column": "101", 589 | "row": "D" 590 | }, 591 | "book": { 592 | "title": "Ring of lightening", 593 | "author": "James S. Fancher" 594 | } 595 | }, 596 | { 597 | "location": { 598 | "aisle": "A", 599 | "column": "102", 600 | "row": "F" 601 | }, 602 | "book": { 603 | "title": "Spin", 604 | "author": "Robert Charles Wilson" 605 | } 606 | }, 607 | { 608 | "location": { 609 | "aisle": "B", 610 | "column": "103", 611 | "row": "B" 612 | }, 613 | "book": { 614 | "title": "The Perfect Host", 615 | "author": "Theodore Sturgeon" 616 | } 617 | }, 618 | { 619 | "location": { 620 | "aisle": "E", 621 | "column": "102", 622 | "row": "C" 623 | }, 624 | "book": { 625 | "title": "Mississippi Blues", 626 | "author": "Kathleen Ann Goonan" 627 | } 628 | }, 629 | { 630 | "location": { 631 | "aisle": "G", 632 | "column": "102", 633 | "row": "C" 634 | }, 635 | "book": { 636 | "title": "Dandelion Wine", 637 | "author": "Ray Bradbury" 638 | } 639 | }, 640 | { 641 | "location": { 642 | "aisle": "C", 643 | "column": "102", 644 | "row": "B" 645 | }, 646 | "book": { 647 | "title": "Mind trap", 648 | "author": "Dan morgan" 649 | } 650 | }, 651 | { 652 | "location": { 653 | "aisle": "D", 654 | "column": "103", 655 | "row": "C" 656 | }, 657 | "book": { 658 | "title": "The Cassini Division", 659 | "author": "Ken Macleod " 660 | } 661 | }, 662 | { 663 | "location": { 664 | "aisle": "B", 665 | "column": "103", 666 | "row": "C" 667 | }, 668 | "book": { 669 | "title": "Case and The Dreamer", 670 | "author": "Theodore Sturgeon" 671 | } 672 | }, 673 | { 674 | "location": { 675 | "aisle": "G", 676 | "column": "102", 677 | "row": "D" 678 | }, 679 | "book": { 680 | "title": "Exile's Song", 681 | "author": "Marion Bradley" 682 | } 683 | }, 684 | { 685 | "location": { 686 | "aisle": "F", 687 | "column": "101", 688 | "row": "E" 689 | }, 690 | "book": { 691 | "title": "Gods of riverworld", 692 | "author": "Philip Jose Farmer" 693 | } 694 | }, 695 | { 696 | "location": { 697 | "aisle": "C", 698 | "column": "102", 699 | "row": "C" 700 | }, 701 | "book": { 702 | "title": "Seekers of tomorrow", 703 | "author": "Sam moskowitz" 704 | } 705 | }, 706 | { 707 | "location": { 708 | "aisle": "E", 709 | "column": "102", 710 | "row": "D" 711 | }, 712 | "book": { 713 | "title": "Cowboy Heavan", 714 | "author": "Ron Goulart" 715 | } 716 | }, 717 | { 718 | "location": { 719 | "aisle": "B", 720 | "column": "103", 721 | "row": "D" 722 | }, 723 | "book": { 724 | "title": "Vacuum Flowers", 725 | "author": "Michael Swanwick" 726 | } 727 | }, 728 | { 729 | "location": { 730 | "aisle": "A", 731 | "column": "104", 732 | "row": "A" 733 | }, 734 | "book": { 735 | "title": "Castleview", 736 | "author": "Gene Wolfe " 737 | } 738 | }, 739 | { 740 | "location": { 741 | "aisle": "G", 742 | "column": "102", 743 | "row": "E" 744 | }, 745 | "book": { 746 | "title": "First House", 747 | "author": "Marion Bradley" 748 | } 749 | }, 750 | { 751 | "location": { 752 | "aisle": "D", 753 | "column": "103", 754 | "row": "B" 755 | }, 756 | "book": { 757 | "title": "Shallows of Night", 758 | "author": "Eric van Lustbader" 759 | } 760 | }, 761 | { 762 | "location": { 763 | "aisle": "C", 764 | "column": "102", 765 | "row": "D" 766 | }, 767 | "book": { 768 | "title": "The light bearer", 769 | "author": "Sam nicholson" 770 | } 771 | }, 772 | { 773 | "location": { 774 | "aisle": "E", 775 | "column": "102", 776 | "row": "E" 777 | }, 778 | "book": { 779 | "title": "The Ravens of the Moon", 780 | "author": "Charles L. Grant" 781 | } 782 | }, 783 | { 784 | "location": { 785 | "aisle": "F", 786 | "column": "101", 787 | "row": "F" 788 | }, 789 | "book": { 790 | "title": "Case of the kidnapped angel", 791 | "author": "E. V. Cunningham" 792 | } 793 | }, 794 | { 795 | "location": { 796 | "aisle": "B", 797 | "column": "103", 798 | "row": "E" 799 | }, 800 | "book": { 801 | "title": "Necromancer Nine", 802 | "author": "Sheri S. Tepper" 803 | } 804 | }, 805 | { 806 | "location": { 807 | "aisle": "A", 808 | "column": "104", 809 | "row": "B" 810 | }, 811 | "book": { 812 | "title": "Night unto night", 813 | "author": "Wylie" 814 | } 815 | }, 816 | { 817 | "location": { 818 | "aisle": "G", 819 | "column": "102", 820 | "row": "F" 821 | }, 822 | "book": { 823 | "title": "The Shattered Chain", 824 | "author": "Marion Bradley" 825 | } 826 | }, 827 | { 828 | "location": { 829 | "aisle": "C", 830 | "column": "102", 831 | "row": "E" 832 | }, 833 | "book": { 834 | "title": "A gift from earth", 835 | "author": "Larry niven" 836 | } 837 | }, 838 | { 839 | "location": { 840 | "aisle": "E", 841 | "column": "102", 842 | "row": "F" 843 | }, 844 | "book": { 845 | "title": "The Magic Cup", 846 | "author": "Andrew M. Greeley" 847 | } 848 | }, 849 | { 850 | "location": { 851 | "aisle": "B", 852 | "column": "103", 853 | "row": "F" 854 | }, 855 | "book": { 856 | "title": "Iron Master", 857 | "author": "Patrick Tilley" 858 | } 859 | }, 860 | { 861 | "location": { 862 | "aisle": "A", 863 | "column": "104", 864 | "row": "C" 865 | }, 866 | "book": { 867 | "title": "Start wars thrawn", 868 | "author": "Timothy zahn " 869 | } 870 | }, 871 | { 872 | "location": { 873 | "aisle": "G", 874 | "column": "104", 875 | "row": "A" 876 | }, 877 | "book": { 878 | "title": "Earth", 879 | "author": "David Brin" 880 | } 881 | }, 882 | { 883 | "location": { 884 | "aisle": "C", 885 | "column": "102", 886 | "row": "F" 887 | }, 888 | "book": { 889 | "title": "Limits", 890 | "author": "Larry niven" 891 | } 892 | }, 893 | { 894 | "location": { 895 | "aisle": "D", 896 | "column": "103", 897 | "row": "A" 898 | }, 899 | "book": { 900 | "title": "Crawling Chaos", 901 | "author": "H. P. Lovecraft" 902 | } 903 | }, 904 | { 905 | "location": { 906 | "aisle": "E", 907 | "column": "104", 908 | "row": "A" 909 | }, 910 | "book": { 911 | "title": "The Warrior Enchanted", 912 | "author": "Sharon Green" 913 | } 914 | }, 915 | { 916 | "location": { 917 | "aisle": "C", 918 | "column": "104", 919 | "row": "A" 920 | }, 921 | "book": { 922 | "title": "Neutron star", 923 | "author": "Larry niven" 924 | } 925 | }, 926 | { 927 | "location": { 928 | "aisle": "B", 929 | "column": "105", 930 | "row": "A" 931 | }, 932 | "book": { 933 | "title": "The Warlock Enraged", 934 | "author": "Christopher Stasheff" 935 | } 936 | }, 937 | { 938 | "location": { 939 | "aisle": "D", 940 | "column": "105", 941 | "row": "A" 942 | }, 943 | "book": { 944 | "title": "The Birthgrave", 945 | "author": "Tanith Lee" 946 | } 947 | }, 948 | { 949 | "location": { 950 | "aisle": "F", 951 | "column": "103", 952 | "row": "A" 953 | }, 954 | "book": { 955 | "title": "This day all gods die", 956 | "author": "Stephen R. Donaldson" 957 | } 958 | }, 959 | { 960 | "location": { 961 | "aisle": "G", 962 | "column": "104", 963 | "row": "B" 964 | }, 965 | "book": { 966 | "title": "Glory Season", 967 | "author": "David Brin" 968 | } 969 | }, 970 | { 971 | "location": { 972 | "aisle": "A", 973 | "column": "104", 974 | "row": "D" 975 | }, 976 | "book": { 977 | "title": "The courts of chaos", 978 | "author": "Roger Zelazny " 979 | } 980 | }, 981 | { 982 | "location": { 983 | "aisle": "E", 984 | "column": "104", 985 | "row": "B" 986 | }, 987 | "book": { 988 | "title": "The Hidden Realms", 989 | "author": "Sharon Green" 990 | } 991 | }, 992 | { 993 | "location": { 994 | "aisle": "C", 995 | "column": "104", 996 | "row": "B" 997 | }, 998 | "book": { 999 | "title": "Outlaw of gor", 1000 | "author": "John norman" 1001 | } 1002 | }, 1003 | { 1004 | "location": { 1005 | "aisle": "B", 1006 | "column": "105", 1007 | "row": "B" 1008 | }, 1009 | "book": { 1010 | "title": "The Warlock Heretical", 1011 | "author": "Christopher Stasheff" 1012 | } 1013 | }, 1014 | { 1015 | "location": { 1016 | "aisle": "E", 1017 | "column": "104", 1018 | "row": "C" 1019 | }, 1020 | "book": { 1021 | "title": "All My Sins Remembered", 1022 | "author": "Joe Haldeman" 1023 | } 1024 | }, 1025 | { 1026 | "location": { 1027 | "aisle": "A", 1028 | "column": "104", 1029 | "row": "E" 1030 | }, 1031 | "book": { 1032 | "title": "Eye of cat ", 1033 | "author": "Roger Zelazny" 1034 | } 1035 | }, 1036 | { 1037 | "location": { 1038 | "aisle": "C", 1039 | "column": "104", 1040 | "row": "C" 1041 | }, 1042 | "book": { 1043 | "title": "The crosaroads of time", 1044 | "author": "Andre norton" 1045 | } 1046 | }, 1047 | { 1048 | "location": { 1049 | "aisle": "F", 1050 | "column": "103", 1051 | "row": "B" 1052 | }, 1053 | "book": { 1054 | "title": "Strangers", 1055 | "author": "Gardner Dozois" 1056 | } 1057 | }, 1058 | { 1059 | "location": { 1060 | "aisle": "B", 1061 | "column": "105", 1062 | "row": "C" 1063 | }, 1064 | "book": { 1065 | "title": "A Wizard in Absentia", 1066 | "author": "Christopher Stasheff" 1067 | } 1068 | }, 1069 | { 1070 | "location": { 1071 | "aisle": "A", 1072 | "column": "104", 1073 | "row": "F" 1074 | }, 1075 | "book": { 1076 | "title": "Sign of the unicorn", 1077 | "author": "Roger Zelazny " 1078 | } 1079 | }, 1080 | { 1081 | "location": { 1082 | "aisle": "B", 1083 | "column": "105", 1084 | "row": "D" 1085 | }, 1086 | "book": { 1087 | "title": "Holy Fire", 1088 | "author": "Bruce Sterling" 1089 | } 1090 | }, 1091 | { 1092 | "location": { 1093 | "aisle": "G", 1094 | "column": "104", 1095 | "row": "C" 1096 | }, 1097 | "book": { 1098 | "title": "Helix ", 1099 | "author": "Eric Brown" 1100 | } 1101 | }, 1102 | { 1103 | "location": { 1104 | "aisle": "E", 1105 | "column": "104", 1106 | "row": "D" 1107 | }, 1108 | "book": { 1109 | "title": "Dragonsbane", 1110 | "author": "Barbara Hambly" 1111 | } 1112 | }, 1113 | { 1114 | "location": { 1115 | "aisle": "F", 1116 | "column": "103", 1117 | "row": "C" 1118 | }, 1119 | "book": { 1120 | "title": "Elom", 1121 | "author": "William H. Drinkard" 1122 | } 1123 | }, 1124 | { 1125 | "location": { 1126 | "aisle": "C", 1127 | "column": "104", 1128 | "row": "D" 1129 | }, 1130 | "book": { 1131 | "title": "The defiant agents", 1132 | "author": "Andre norton" 1133 | } 1134 | }, 1135 | { 1136 | "location": { 1137 | "aisle": "B", 1138 | "column": "105", 1139 | "row": "E" 1140 | }, 1141 | "book": { 1142 | "title": "The Hollow Hills", 1143 | "author": "Mary Stewart" 1144 | } 1145 | }, 1146 | { 1147 | "location": { 1148 | "aisle": "C", 1149 | "column": "104", 1150 | "row": "E" 1151 | }, 1152 | "book": { 1153 | "title": "Iron cage", 1154 | "author": "Andre norton" 1155 | } 1156 | }, 1157 | { 1158 | "location": { 1159 | "aisle": "D", 1160 | "column": "105", 1161 | "row": "B" 1162 | }, 1163 | "book": { 1164 | "title": "The Big Time", 1165 | "author": "Fritz Leiber" 1166 | } 1167 | }, 1168 | { 1169 | "location": { 1170 | "aisle": "G", 1171 | "column": "104", 1172 | "row": "D" 1173 | }, 1174 | "book": { 1175 | "title": "From These Ashes", 1176 | "author": "Fredric Brown" 1177 | } 1178 | }, 1179 | { 1180 | "location": { 1181 | "aisle": "A", 1182 | "column": "106", 1183 | "row": "A" 1184 | }, 1185 | "book": { 1186 | "title": "Hollow earth", 1187 | "author": "David Standish" 1188 | } 1189 | }, 1190 | { 1191 | "location": { 1192 | "aisle": "E", 1193 | "column": "104", 1194 | "row": "E" 1195 | }, 1196 | "book": { 1197 | "title": "Starwolf", 1198 | "author": "Edmond Hamilton" 1199 | } 1200 | }, 1201 | { 1202 | "location": { 1203 | "aisle": "C", 1204 | "column": "104", 1205 | "row": "F" 1206 | }, 1207 | "book": { 1208 | "title": "Quag keep", 1209 | "author": "Andre norton" 1210 | } 1211 | }, 1212 | { 1213 | "location": { 1214 | "aisle": "D", 1215 | "column": "105", 1216 | "row": "C" 1217 | }, 1218 | "book": { 1219 | "title": "The Wanderer", 1220 | "author": "Fritz Leiber" 1221 | } 1222 | }, 1223 | { 1224 | "location": { 1225 | "aisle": "G", 1226 | "column": "104", 1227 | "row": "E" 1228 | }, 1229 | "book": { 1230 | "title": "The Crucible of Time", 1231 | "author": "John Brunner" 1232 | } 1233 | }, 1234 | { 1235 | "location": { 1236 | "aisle": "F", 1237 | "column": "103", 1238 | "row": "D" 1239 | }, 1240 | "book": { 1241 | "title": "Regenesis", 1242 | "author": "Julia Ecklar" 1243 | } 1244 | }, 1245 | { 1246 | "location": { 1247 | "aisle": "E", 1248 | "column": "104", 1249 | "row": "F" 1250 | }, 1251 | "book": { 1252 | "title": "The Dreaming Void", 1253 | "author": "Peter M. Hamilton" 1254 | } 1255 | }, 1256 | { 1257 | "location": { 1258 | "aisle": "A", 1259 | "column": "106", 1260 | "row": "B" 1261 | }, 1262 | "book": { 1263 | "title": "Creations", 1264 | "author": "Issac Asimov, George Zebrowski, Martin Greenberg " 1265 | } 1266 | }, 1267 | { 1268 | "location": { 1269 | "aisle": "B", 1270 | "column": "105", 1271 | "row": "F" 1272 | }, 1273 | "book": { 1274 | "title": "Goosebumps #13: Piano Lessons Can Be Murder", 1275 | "author": "R.L. Stine" 1276 | } 1277 | }, 1278 | { 1279 | "location": { 1280 | "aisle": "C", 1281 | "column": "106", 1282 | "row": "A" 1283 | }, 1284 | "book": { 1285 | "title": "Unchartered stars", 1286 | "author": "Andre norton" 1287 | } 1288 | }, 1289 | { 1290 | "location": { 1291 | "aisle": "E", 1292 | "column": "106", 1293 | "row": "A" 1294 | }, 1295 | "book": { 1296 | "title": "Wasteland of Flint", 1297 | "author": "Thomas Harlan" 1298 | } 1299 | }, 1300 | { 1301 | "location": { 1302 | "aisle": "G", 1303 | "column": "104", 1304 | "row": "F" 1305 | }, 1306 | "book": { 1307 | "title": "The Jagged Orbit", 1308 | "author": "John Brunner" 1309 | } 1310 | }, 1311 | { 1312 | "location": { 1313 | "aisle": "D", 1314 | "column": "105", 1315 | "row": "D" 1316 | }, 1317 | "book": { 1318 | "title": "Rosemary's Baby", 1319 | "author": "Ira Levin" 1320 | } 1321 | }, 1322 | { 1323 | "location": { 1324 | "aisle": "C", 1325 | "column": "106", 1326 | "row": "B" 1327 | }, 1328 | "book": { 1329 | "title": "The zero stone", 1330 | "author": "Andre norton" 1331 | } 1332 | }, 1333 | { 1334 | "location": { 1335 | "aisle": "A", 1336 | "column": "106", 1337 | "row": "C" 1338 | }, 1339 | "book": { 1340 | "title": "Three times infinity", 1341 | "author": "Leo Marguilies " 1342 | } 1343 | }, 1344 | { 1345 | "location": { 1346 | "aisle": "C", 1347 | "column": "106", 1348 | "row": "C" 1349 | }, 1350 | "book": { 1351 | "title": "Time and robbery", 1352 | "author": "Rebecca ore" 1353 | } 1354 | }, 1355 | { 1356 | "location": { 1357 | "aisle": "E", 1358 | "column": "106", 1359 | "row": "B" 1360 | }, 1361 | "book": { 1362 | "title": "Dead Until Dark", 1363 | "author": "Charlaine Harris" 1364 | } 1365 | }, 1366 | { 1367 | "location": { 1368 | "aisle": "F", 1369 | "column": "103", 1370 | "row": "E" 1371 | }, 1372 | "book": { 1373 | "title": "A fish dinner in Memison", 1374 | "author": "E. R. Eddison" 1375 | } 1376 | }, 1377 | { 1378 | "location": { 1379 | "aisle": "D", 1380 | "column": "105", 1381 | "row": "E" 1382 | }, 1383 | "book": { 1384 | "title": "The Paper Managerie", 1385 | "author": "Ken Liu" 1386 | } 1387 | }, 1388 | { 1389 | "location": { 1390 | "aisle": "E", 1391 | "column": "106", 1392 | "row": "C" 1393 | }, 1394 | "book": { 1395 | "title": "West of Eden", 1396 | "author": "Harry Harrison" 1397 | } 1398 | }, 1399 | { 1400 | "location": { 1401 | "aisle": "C", 1402 | "column": "106", 1403 | "row": "D" 1404 | }, 1405 | "book": { 1406 | "title": "Davy", 1407 | "author": "Edgar pangborn" 1408 | } 1409 | }, 1410 | { 1411 | "location": { 1412 | "aisle": "A", 1413 | "column": "106", 1414 | "row": "D" 1415 | }, 1416 | "book": { 1417 | "title": "Mutants and mystics", 1418 | "author": "Jeffrey J. kripal " 1419 | } 1420 | }, 1421 | { 1422 | "location": { 1423 | "aisle": "G", 1424 | "column": "106", 1425 | "row": "A" 1426 | }, 1427 | "book": { 1428 | "title": "Territory", 1429 | "author": "Emma Bull" 1430 | } 1431 | }, 1432 | { 1433 | "location": { 1434 | "aisle": "F", 1435 | "column": "103", 1436 | "row": "F" 1437 | }, 1438 | "book": { 1439 | "title": "Zendegi", 1440 | "author": "Greg Egan" 1441 | } 1442 | }, 1443 | { 1444 | "location": { 1445 | "aisle": "D", 1446 | "column": "105", 1447 | "row": "F" 1448 | }, 1449 | "book": { 1450 | "title": "City of Baraboo", 1451 | "author": "Barry B. Longyear" 1452 | } 1453 | }, 1454 | { 1455 | "location": { 1456 | "aisle": "E", 1457 | "column": "106", 1458 | "row": "D" 1459 | }, 1460 | "book": { 1461 | "title": "The Wizards of 4th Street", 1462 | "author": "Simon Hawke" 1463 | } 1464 | }, 1465 | { 1466 | "location": { 1467 | "aisle": "A", 1468 | "column": "106", 1469 | "row": "E" 1470 | }, 1471 | "book": { 1472 | "title": "Hobos, elves and wizards ", 1473 | "author": "Micheal N. Stanton " 1474 | } 1475 | }, 1476 | { 1477 | "location": { 1478 | "aisle": "C", 1479 | "column": "106", 1480 | "row": "E" 1481 | }, 1482 | "book": { 1483 | "title": "Brain twister ", 1484 | "author": "Mark phillips" 1485 | } 1486 | }, 1487 | { 1488 | "location": { 1489 | "aisle": "G", 1490 | "column": "106", 1491 | "row": "B" 1492 | }, 1493 | "book": { 1494 | "title": "Diplomatic Immunity", 1495 | "author": "Lois McMaster Bujold" 1496 | } 1497 | }, 1498 | { 1499 | "location": { 1500 | "aisle": "E", 1501 | "column": "106", 1502 | "row": "E" 1503 | }, 1504 | "book": { 1505 | "title": "Black Wings", 1506 | "author": "Christina Henry" 1507 | } 1508 | }, 1509 | { 1510 | "location": { 1511 | "aisle": "F", 1512 | "column": "105", 1513 | "row": "A" 1514 | }, 1515 | "book": { 1516 | "title": "Martian time-slip", 1517 | "author": "Phillip K. Dick" 1518 | } 1519 | }, 1520 | { 1521 | "location": { 1522 | "aisle": "A", 1523 | "column": "106", 1524 | "row": "F" 1525 | }, 1526 | "book": { 1527 | "title": "On SF ", 1528 | "author": "Thomas N. Disch " 1529 | } 1530 | }, 1531 | { 1532 | "location": { 1533 | "aisle": "C", 1534 | "column": "106", 1535 | "row": "F" 1536 | }, 1537 | "book": { 1538 | "title": "A billion days of earth", 1539 | "author": "Doris piserchia" 1540 | } 1541 | }, 1542 | { 1543 | "location": { 1544 | "aisle": "G", 1545 | "column": "106", 1546 | "row": "C" 1547 | }, 1548 | "book": { 1549 | "title": "Proud Man", 1550 | "author": "Katharine Burdekin" 1551 | } 1552 | }, 1553 | { 1554 | "location": { 1555 | "aisle": "E", 1556 | "column": "106", 1557 | "row": "F" 1558 | }, 1559 | "book": { 1560 | "title": "Friday", 1561 | "author": "Robert A. Heinlein" 1562 | } 1563 | }, 1564 | { 1565 | "location": { 1566 | "aisle": "F", 1567 | "column": "105", 1568 | "row": "B" 1569 | }, 1570 | "book": { 1571 | "title": "Blade runner", 1572 | "author": "Philip K. Dick" 1573 | } 1574 | }, 1575 | { 1576 | "location": { 1577 | "aisle": "D", 1578 | "column": "107", 1579 | "row": "F" 1580 | }, 1581 | "book": { 1582 | "title": "Unlocking the Air", 1583 | "author": "Ursula K. Le Guin" 1584 | } 1585 | }, 1586 | { 1587 | "location": { 1588 | "aisle": "C", 1589 | "column": "108", 1590 | "row": "A" 1591 | }, 1592 | "book": { 1593 | "title": "Gateway", 1594 | "author": "Frederik pohl" 1595 | } 1596 | }, 1597 | { 1598 | "location": { 1599 | "aisle": "B", 1600 | "column": "107", 1601 | "row": "A" 1602 | }, 1603 | "book": { 1604 | "title": "Lord of Darkness", 1605 | "author": "Robert Silverberg" 1606 | } 1607 | }, 1608 | { 1609 | "location": { 1610 | "aisle": "E", 1611 | "column": "108", 1612 | "row": "A" 1613 | }, 1614 | "book": { 1615 | "title": "Stranger in a Strange Land", 1616 | "author": "Robert A. Heinlein" 1617 | } 1618 | }, 1619 | { 1620 | "location": { 1621 | "aisle": "C", 1622 | "column": "108", 1623 | "row": "B" 1624 | }, 1625 | "book": { 1626 | "title": "Man plus", 1627 | "author": "Frederik pohl" 1628 | } 1629 | }, 1630 | { 1631 | "location": { 1632 | "aisle": "G", 1633 | "column": "106", 1634 | "row": "D" 1635 | }, 1636 | "book": { 1637 | "title": "A Vision of Battlements", 1638 | "author": "Anthony Burgess" 1639 | } 1640 | }, 1641 | { 1642 | "location": { 1643 | "aisle": "F", 1644 | "column": "105", 1645 | "row": "C" 1646 | }, 1647 | "book": { 1648 | "title": "Dragon of the border", 1649 | "author": "Gordon R. Dickson" 1650 | } 1651 | }, 1652 | { 1653 | "location": { 1654 | "aisle": "B", 1655 | "column": "107", 1656 | "row": "B" 1657 | }, 1658 | "book": { 1659 | "title": "A Heritage of Stars", 1660 | "author": "Clifford D. Simak" 1661 | } 1662 | }, 1663 | { 1664 | "location": { 1665 | "aisle": "A", 1666 | "column": "108", 1667 | "row": "A" 1668 | }, 1669 | "book": { 1670 | "title": "Out of this world", 1671 | "author": "Julius Fast " 1672 | } 1673 | }, 1674 | { 1675 | "location": { 1676 | "aisle": "D", 1677 | "column": "107", 1678 | "row": "E" 1679 | }, 1680 | "book": { 1681 | "title": "Tehanu", 1682 | "author": "Ursula K. Le Guin" 1683 | } 1684 | }, 1685 | { 1686 | "location": { 1687 | "aisle": "E", 1688 | "column": "108", 1689 | "row": "B" 1690 | }, 1691 | "book": { 1692 | "title": "Pilgramage", 1693 | "author": "Zenna Henderson" 1694 | } 1695 | }, 1696 | { 1697 | "location": { 1698 | "aisle": "B", 1699 | "column": "107", 1700 | "row": "C" 1701 | }, 1702 | "book": { 1703 | "title": "Hyperion", 1704 | "author": "Dan Simmons" 1705 | } 1706 | }, 1707 | { 1708 | "location": { 1709 | "aisle": "G", 1710 | "column": "106", 1711 | "row": "E" 1712 | }, 1713 | "book": { 1714 | "title": "The Land That Time Forgot", 1715 | "author": "Edgar Ride Burroughs" 1716 | } 1717 | }, 1718 | { 1719 | "location": { 1720 | "aisle": "E", 1721 | "column": "108", 1722 | "row": "C" 1723 | }, 1724 | "book": { 1725 | "title": "Children of Dune", 1726 | "author": "Frank Herbert" 1727 | } 1728 | }, 1729 | { 1730 | "location": { 1731 | "aisle": "D", 1732 | "column": "107", 1733 | "row": "D" 1734 | }, 1735 | "book": { 1736 | "title": "Ancillary Sword", 1737 | "author": "Ann Leckie" 1738 | } 1739 | }, 1740 | { 1741 | "location": { 1742 | "aisle": "B", 1743 | "column": "107", 1744 | "row": "D" 1745 | }, 1746 | "book": { 1747 | "title": "The Fourth \"R\"", 1748 | "author": "George O. Smith" 1749 | } 1750 | }, 1751 | { 1752 | "location": { 1753 | "aisle": "A", 1754 | "column": "108", 1755 | "row": "B" 1756 | }, 1757 | "book": { 1758 | "title": "The last man on earth ", 1759 | "author": "Issac Asimov" 1760 | } 1761 | }, 1762 | { 1763 | "location": { 1764 | "aisle": "E", 1765 | "column": "108", 1766 | "row": "D" 1767 | }, 1768 | "book": { 1769 | "title": "Destination: Void", 1770 | "author": "Frank Herbert" 1771 | } 1772 | }, 1773 | { 1774 | "location": { 1775 | "aisle": "D", 1776 | "column": "107", 1777 | "row": "C" 1778 | }, 1779 | "book": { 1780 | "title": "Worlds of the Imperium", 1781 | "author": "Keith Laumer" 1782 | } 1783 | }, 1784 | { 1785 | "location": { 1786 | "aisle": "G", 1787 | "column": "106", 1788 | "row": "F" 1789 | }, 1790 | "book": { 1791 | "title": "The Cinder Spires", 1792 | "author": "Jim Butcher" 1793 | } 1794 | }, 1795 | { 1796 | "location": { 1797 | "aisle": "B", 1798 | "column": "107", 1799 | "row": "E" 1800 | }, 1801 | "book": { 1802 | "title": "The Silver Sun", 1803 | "author": "Nancy Springer" 1804 | } 1805 | }, 1806 | { 1807 | "location": { 1808 | "aisle": "F", 1809 | "column": "105", 1810 | "row": "D" 1811 | }, 1812 | "book": { 1813 | "title": "The space swimmers", 1814 | "author": "Gordon R. Dickson" 1815 | } 1816 | }, 1817 | { 1818 | "location": { 1819 | "aisle": "E", 1820 | "column": "108", 1821 | "row": "E" 1822 | }, 1823 | "book": { 1824 | "title": "The Lazarus Effect", 1825 | "author": "Frank Herbert" 1826 | } 1827 | }, 1828 | { 1829 | "location": { 1830 | "aisle": "G", 1831 | "column": "108", 1832 | "row": "A" 1833 | }, 1834 | "book": { 1835 | "title": "Patterns", 1836 | "author": "Part Cadigan" 1837 | } 1838 | }, 1839 | { 1840 | "location": { 1841 | "aisle": "A", 1842 | "column": "108", 1843 | "row": "C" 1844 | }, 1845 | "book": { 1846 | "title": "Space Odysseys ", 1847 | "author": "Brian W. aldiss " 1848 | } 1849 | }, 1850 | { 1851 | "location": { 1852 | "aisle": "D", 1853 | "column": "107", 1854 | "row": "B" 1855 | }, 1856 | "book": { 1857 | "title": "The Galaxy Builder", 1858 | "author": "Keith Laumer" 1859 | } 1860 | }, 1861 | { 1862 | "location": { 1863 | "aisle": "B", 1864 | "column": "107", 1865 | "row": "F" 1866 | }, 1867 | "book": { 1868 | "title": "Odd John", 1869 | "author": "Olaf Stapledon" 1870 | } 1871 | }, 1872 | { 1873 | "location": { 1874 | "aisle": "F", 1875 | "column": "105", 1876 | "row": "E" 1877 | }, 1878 | "book": { 1879 | "title": "For the win", 1880 | "author": "Cory Doctorow" 1881 | } 1882 | }, 1883 | { 1884 | "location": { 1885 | "aisle": "A", 1886 | "column": "108", 1887 | "row": "D" 1888 | }, 1889 | "book": { 1890 | "title": "The Bradbury chronicles", 1891 | "author": "Sam weller " 1892 | } 1893 | }, 1894 | { 1895 | "location": { 1896 | "aisle": "B", 1897 | "column": "109", 1898 | "row": "A" 1899 | }, 1900 | "book": { 1901 | "title": "A Tale of 2 Clocks", 1902 | "author": "James H. Schmitz" 1903 | } 1904 | }, 1905 | { 1906 | "location": { 1907 | "aisle": "G", 1908 | "column": "108", 1909 | "row": "B" 1910 | }, 1911 | "book": { 1912 | "title": "A Darkling Sea", 1913 | "author": "James L. Cambias" 1914 | } 1915 | }, 1916 | { 1917 | "location": { 1918 | "aisle": "C", 1919 | "column": "108", 1920 | "row": "F" 1921 | }, 1922 | "book": { 1923 | "title": "The blue star", 1924 | "author": "Fletcher pratt" 1925 | } 1926 | }, 1927 | { 1928 | "location": { 1929 | "aisle": "D", 1930 | "column": "107", 1931 | "row": "A" 1932 | }, 1933 | "book": { 1934 | "title": "Escapement", 1935 | "author": "Jay Lake" 1936 | } 1937 | }, 1938 | { 1939 | "location": { 1940 | "aisle": "A", 1941 | "column": "108", 1942 | "row": "E" 1943 | }, 1944 | "book": { 1945 | "title": "World war Z ", 1946 | "author": "Max brooks" 1947 | } 1948 | }, 1949 | { 1950 | "location": { 1951 | "aisle": "G", 1952 | "column": "108", 1953 | "row": "C" 1954 | }, 1955 | "book": { 1956 | "title": "Earth Afire", 1957 | "author": "Orson Scott Card" 1958 | } 1959 | }, 1960 | { 1961 | "location": { 1962 | "aisle": "C", 1963 | "column": "108", 1964 | "row": "E" 1965 | }, 1966 | "book": { 1967 | "title": "Equal rites ", 1968 | "author": "Terry pratchet" 1969 | } 1970 | }, 1971 | { 1972 | "location": { 1973 | "aisle": "F", 1974 | "column": "105", 1975 | "row": "F" 1976 | }, 1977 | "book": { 1978 | "title": "The illearth war", 1979 | "author": "Stephen R. Donaldson" 1980 | } 1981 | }, 1982 | { 1983 | "location": { 1984 | "aisle": "B", 1985 | "column": "109", 1986 | "row": "B" 1987 | }, 1988 | "book": { 1989 | "title": "Medusa's Children", 1990 | "author": "Bob Shaw" 1991 | } 1992 | }, 1993 | { 1994 | "location": { 1995 | "aisle": "D", 1996 | "column": "109", 1997 | "row": "A" 1998 | }, 1999 | "book": { 2000 | "title": "Bag of Bones", 2001 | "author": "Stephen King " 2002 | } 2003 | }, 2004 | { 2005 | "location": { 2006 | "aisle": "A", 2007 | "column": "108", 2008 | "row": "F" 2009 | }, 2010 | "book": { 2011 | "title": "Before the golden age", 2012 | "author": "Issac Asimov" 2013 | } 2014 | }, 2015 | { 2016 | "location": { 2017 | "aisle": "E", 2018 | "column": "108", 2019 | "row": "F" 2020 | }, 2021 | "book": { 2022 | "title": "Gray Matters", 2023 | "author": "William Hjortsberg" 2024 | } 2025 | }, 2026 | { 2027 | "location": { 2028 | "aisle": "G", 2029 | "column": "108", 2030 | "row": "D" 2031 | }, 2032 | "book": { 2033 | "title": "Maps in a Mirror", 2034 | "author": "Orson Scott Card" 2035 | } 2036 | }, 2037 | { 2038 | "location": { 2039 | "aisle": "B", 2040 | "column": "109", 2041 | "row": "C" 2042 | }, 2043 | "book": { 2044 | "title": "Options", 2045 | "author": "Robert Sheckley" 2046 | } 2047 | }, 2048 | { 2049 | "location": { 2050 | "aisle": "D", 2051 | "column": "109", 2052 | "row": "B" 2053 | }, 2054 | "book": { 2055 | "title": "False Memory ", 2056 | "author": "Dean Koontz" 2057 | } 2058 | }, 2059 | { 2060 | "location": { 2061 | "aisle": "G", 2062 | "column": "108", 2063 | "row": "E" 2064 | }, 2065 | "book": { 2066 | "title": "Xenocide", 2067 | "author": "Orson Scott Card" 2068 | } 2069 | }, 2070 | { 2071 | "location": { 2072 | "aisle": "F", 2073 | "column": "107", 2074 | "row": "A" 2075 | }, 2076 | "book": { 2077 | "title": "Possession", 2078 | "author": "L. P. Davies" 2079 | } 2080 | }, 2081 | { 2082 | "location": { 2083 | "aisle": "A", 2084 | "column": "110", 2085 | "row": "A" 2086 | }, 2087 | "book": { 2088 | "title": "Universe 3 ", 2089 | "author": "Terry Carr " 2090 | } 2091 | }, 2092 | { 2093 | "location": { 2094 | "aisle": "E", 2095 | "column": "110", 2096 | "row": "A" 2097 | }, 2098 | "book": { 2099 | "title": "Inherit the Stars", 2100 | "author": "James P. Hogan" 2101 | } 2102 | }, 2103 | { 2104 | "location": { 2105 | "aisle": "C", 2106 | "column": "108", 2107 | "row": "D" 2108 | }, 2109 | "book": { 2110 | "title": "West of honoe ", 2111 | "author": "Jerry pournelle" 2112 | } 2113 | }, 2114 | { 2115 | "location": { 2116 | "aisle": "D", 2117 | "column": "109", 2118 | "row": "C" 2119 | }, 2120 | "book": { 2121 | "title": "The Historian ", 2122 | "author": "Elizabeth Kostova" 2123 | } 2124 | }, 2125 | { 2126 | "location": { 2127 | "aisle": "G", 2128 | "column": "108", 2129 | "row": "F" 2130 | }, 2131 | "book": { 2132 | "title": "The Wizard of Zao", 2133 | "author": "Look Carter" 2134 | } 2135 | }, 2136 | { 2137 | "location": { 2138 | "aisle": "B", 2139 | "column": "109", 2140 | "row": "D" 2141 | }, 2142 | "book": { 2143 | "title": "Frankenstein", 2144 | "author": "Mary Shelley" 2145 | } 2146 | }, 2147 | { 2148 | "location": { 2149 | "aisle": "E", 2150 | "column": "110", 2151 | "row": "B" 2152 | }, 2153 | "book": { 2154 | "title": "Wonder-Makers 2", 2155 | "author": "Robert Hoskins" 2156 | } 2157 | }, 2158 | { 2159 | "location": { 2160 | "aisle": "A", 2161 | "column": "110", 2162 | "row": "B" 2163 | }, 2164 | "book": { 2165 | "title": "Galactic Empires ", 2166 | "author": "Brian W. Aldis s " 2167 | } 2168 | }, 2169 | { 2170 | "location": { 2171 | "aisle": "F", 2172 | "column": "107", 2173 | "row": "B" 2174 | }, 2175 | "book": { 2176 | "title": "The hostage of zir", 2177 | "author": "L.Sprague de Camp" 2178 | } 2179 | }, 2180 | { 2181 | "location": { 2182 | "aisle": "B", 2183 | "column": "109", 2184 | "row": "E" 2185 | }, 2186 | "book": { 2187 | "title": "Up The Line", 2188 | "author": "Robert Silverberg" 2189 | } 2190 | }, 2191 | { 2192 | "location": { 2193 | "aisle": "D", 2194 | "column": "109", 2195 | "row": "D" 2196 | }, 2197 | "book": { 2198 | "title": "The Bishop's Heir", 2199 | "author": "Katherine Kurtz " 2200 | } 2201 | }, 2202 | { 2203 | "location": { 2204 | "aisle": "G", 2205 | "column": "110", 2206 | "row": "A" 2207 | }, 2208 | "book": { 2209 | "title": "The Four Lords of the Diamond", 2210 | "author": "Jack L. Chalker" 2211 | } 2212 | }, 2213 | { 2214 | "location": { 2215 | "aisle": "E", 2216 | "column": "110", 2217 | "row": "C" 2218 | }, 2219 | "book": { 2220 | "title": "The Wool Omnibus", 2221 | "author": "Hugh Howey" 2222 | } 2223 | }, 2224 | { 2225 | "location": { 2226 | "aisle": "C", 2227 | "column": "108", 2228 | "row": "C" 2229 | }, 2230 | "book": { 2231 | "title": "Slave ship", 2232 | "author": "Frederik pohl" 2233 | } 2234 | }, 2235 | { 2236 | "location": { 2237 | "aisle": "B", 2238 | "column": "109", 2239 | "row": "F" 2240 | }, 2241 | "book": { 2242 | "title": "Regan's Planet", 2243 | "author": "Robert Silverberg" 2244 | } 2245 | }, 2246 | { 2247 | "location": { 2248 | "aisle": "A", 2249 | "column": "110", 2250 | "row": "C" 2251 | }, 2252 | "book": { 2253 | "title": "Realms of wizardry", 2254 | "author": "Lin carter" 2255 | } 2256 | }, 2257 | { 2258 | "location": { 2259 | "aisle": "F", 2260 | "column": "107", 2261 | "row": "C" 2262 | }, 2263 | "book": { 2264 | "title": "The little country", 2265 | "author": "Charles de Lint" 2266 | } 2267 | }, 2268 | { 2269 | "location": { 2270 | "aisle": "G", 2271 | "column": "110", 2272 | "row": "B" 2273 | }, 2274 | "book": { 2275 | "title": "The Run to the Chaos Sweep", 2276 | "author": "Jack L. Chalker" 2277 | } 2278 | }, 2279 | { 2280 | "location": { 2281 | "aisle": "C", 2282 | "column": "110", 2283 | "row": "A" 2284 | }, 2285 | "book": { 2286 | "title": "Journey", 2287 | "author": "Marta randall" 2288 | } 2289 | }, 2290 | { 2291 | "location": { 2292 | "aisle": "B", 2293 | "column": "111", 2294 | "row": "A" 2295 | }, 2296 | "book": { 2297 | "title": "Red Mars", 2298 | "author": "Kim Stanley Robinson" 2299 | } 2300 | }, 2301 | { 2302 | "location": { 2303 | "aisle": "D", 2304 | "column": "109", 2305 | "row": "E" 2306 | }, 2307 | "book": { 2308 | "title": "High Deryni", 2309 | "author": "Katherine Kurtz " 2310 | } 2311 | }, 2312 | { 2313 | "location": { 2314 | "aisle": "E", 2315 | "column": "110", 2316 | "row": "D" 2317 | }, 2318 | "book": { 2319 | "title": "Through the Eye of Time", 2320 | "author": "Trevor Hoyle" 2321 | } 2322 | }, 2323 | { 2324 | "location": { 2325 | "aisle": "C", 2326 | "column": "110", 2327 | "row": "B" 2328 | }, 2329 | "book": { 2330 | "title": "The branch", 2331 | "author": "Mike resnick" 2332 | } 2333 | }, 2334 | { 2335 | "location": { 2336 | "aisle": "F", 2337 | "column": "107", 2338 | "row": "D" 2339 | }, 2340 | "book": { 2341 | "title": "Attack from Atlantis", 2342 | "author": "Lester del Rey" 2343 | } 2344 | }, 2345 | { 2346 | "location": { 2347 | "aisle": "A", 2348 | "column": "110", 2349 | "row": "D" 2350 | }, 2351 | "book": { 2352 | "title": "Trips in time", 2353 | "author": "Robert silverberg " 2354 | } 2355 | }, 2356 | { 2357 | "location": { 2358 | "aisle": "E", 2359 | "column": "110", 2360 | "row": "E" 2361 | }, 2362 | "book": { 2363 | "title": "Blood Lines", 2364 | "author": "Tanya Huff" 2365 | } 2366 | }, 2367 | { 2368 | "location": { 2369 | "aisle": "G", 2370 | "column": "110", 2371 | "row": "C" 2372 | }, 2373 | "book": { 2374 | "title": "Start Loot", 2375 | "author": "A. Bertram Chandler" 2376 | } 2377 | }, 2378 | { 2379 | "location": { 2380 | "aisle": "D", 2381 | "column": "109", 2382 | "row": "F" 2383 | }, 2384 | "book": { 2385 | "title": "Sacred Ground", 2386 | "author": "Mercedes Lackey " 2387 | } 2388 | }, 2389 | { 2390 | "location": { 2391 | "aisle": "C", 2392 | "column": "110", 2393 | "row": "C" 2394 | }, 2395 | "book": { 2396 | "title": "Earth unaware", 2397 | "author": "Mack reynolds" 2398 | } 2399 | }, 2400 | { 2401 | "location": { 2402 | "aisle": "B", 2403 | "column": "111", 2404 | "row": "B" 2405 | }, 2406 | "book": { 2407 | "title": "The World is Round", 2408 | "author": "Tony Rothman" 2409 | } 2410 | }, 2411 | { 2412 | "location": { 2413 | "aisle": "F", 2414 | "column": "107", 2415 | "row": "E" 2416 | }, 2417 | "book": { 2418 | "title": "Dhalgren", 2419 | "author": "Samuel R. Delany" 2420 | } 2421 | }, 2422 | { 2423 | "location": { 2424 | "aisle": "D", 2425 | "column": "111", 2426 | "row": "F" 2427 | }, 2428 | "book": { 2429 | "title": "Hearts in Atlantis ", 2430 | "author": "Stephen King " 2431 | } 2432 | }, 2433 | { 2434 | "location": { 2435 | "aisle": "E", 2436 | "column": "110", 2437 | "row": "F" 2438 | }, 2439 | "book": { 2440 | "title": "Systemic Shock", 2441 | "author": "Dean Ing" 2442 | } 2443 | }, 2444 | { 2445 | "location": { 2446 | "aisle": "A", 2447 | "column": "110", 2448 | "row": "E" 2449 | }, 2450 | "book": { 2451 | "title": "The chick is in the mail", 2452 | "author": "Esther Fresner " 2453 | } 2454 | }, 2455 | { 2456 | "location": { 2457 | "aisle": "B", 2458 | "column": "111", 2459 | "row": "C" 2460 | }, 2461 | "book": { 2462 | "title": "The Zanzibar Cat", 2463 | "author": "Joanna Russ" 2464 | } 2465 | }, 2466 | { 2467 | "location": { 2468 | "aisle": "C", 2469 | "column": "110", 2470 | "row": "D" 2471 | }, 2472 | "book": { 2473 | "title": "Once departed", 2474 | "author": "Mack reynolds" 2475 | } 2476 | }, 2477 | { 2478 | "location": { 2479 | "aisle": "D", 2480 | "column": "111", 2481 | "row": "E" 2482 | }, 2483 | "book": { 2484 | "title": "Four Past Midnight ", 2485 | "author": "Stephen King " 2486 | } 2487 | }, 2488 | { 2489 | "location": { 2490 | "aisle": "G", 2491 | "column": "110", 2492 | "row": "D" 2493 | }, 2494 | "book": { 2495 | "title": "Hunter of the Worlds", 2496 | "author": "C. J. Cherryh" 2497 | } 2498 | }, 2499 | { 2500 | "location": { 2501 | "aisle": "A", 2502 | "column": "110", 2503 | "row": "F" 2504 | }, 2505 | "book": { 2506 | "title": "The shape of things", 2507 | "author": "Damon Knight " 2508 | } 2509 | }, 2510 | { 2511 | "location": { 2512 | "aisle": "F", 2513 | "column": "107", 2514 | "row": "F" 2515 | }, 2516 | "book": { 2517 | "title": "The jewels of aptor", 2518 | "author": "Samuel R. Delany" 2519 | } 2520 | }, 2521 | { 2522 | "location": { 2523 | "aisle": "C", 2524 | "column": "110", 2525 | "row": "E" 2526 | }, 2527 | "book": { 2528 | "title": "The chalk giants", 2529 | "author": "Keith roberts" 2530 | } 2531 | }, 2532 | { 2533 | "location": { 2534 | "aisle": "B", 2535 | "column": "111", 2536 | "row": "D" 2537 | }, 2538 | "book": { 2539 | "title": "Octagon", 2540 | "author": "Fred Saberhagen" 2541 | } 2542 | }, 2543 | { 2544 | "location": { 2545 | "aisle": "D", 2546 | "column": "111", 2547 | "row": "D" 2548 | }, 2549 | "book": { 2550 | "title": "Days of Blood and Fire", 2551 | "author": "Katherine Kerr" 2552 | } 2553 | }, 2554 | { 2555 | "location": { 2556 | "aisle": "C", 2557 | "column": "110", 2558 | "row": "F" 2559 | }, 2560 | "book": { 2561 | "title": "Pavane", 2562 | "author": "Keith roberts" 2563 | } 2564 | }, 2565 | { 2566 | "location": { 2567 | "aisle": "B", 2568 | "column": "111", 2569 | "row": "E" 2570 | }, 2571 | "book": { 2572 | "title": "Contact", 2573 | "author": "Carl Sagan" 2574 | } 2575 | }, 2576 | { 2577 | "location": { 2578 | "aisle": "G", 2579 | "column": "110", 2580 | "row": "E" 2581 | }, 2582 | "book": { 2583 | "title": "Foreigner", 2584 | "author": "C. J. Cherryh" 2585 | } 2586 | }, 2587 | { 2588 | "location": { 2589 | "aisle": "F", 2590 | "column": "109", 2591 | "row": "A" 2592 | }, 2593 | "book": { 2594 | "title": "Monitor found in orbit", 2595 | "author": "Michael G. Coney" 2596 | } 2597 | }, 2598 | { 2599 | "location": { 2600 | "aisle": "B", 2601 | "column": "111", 2602 | "row": "F" 2603 | }, 2604 | "book": { 2605 | "title": "The Godmother", 2606 | "author": "Elizabeth Ann Scarborough" 2607 | } 2608 | }, 2609 | { 2610 | "location": { 2611 | "aisle": "D", 2612 | "column": "111", 2613 | "row": "C" 2614 | }, 2615 | "book": { 2616 | "title": "The Wizard of Anharitte", 2617 | "author": "Colin Kapp" 2618 | } 2619 | }, 2620 | { 2621 | "location": { 2622 | "aisle": "D", 2623 | "column": "111", 2624 | "row": "B" 2625 | }, 2626 | "book": { 2627 | "title": "Life", 2628 | "author": "Gwyneth Jones" 2629 | } 2630 | }, 2631 | { 2632 | "location": { 2633 | "aisle": "F", 2634 | "column": "109", 2635 | "row": "B" 2636 | }, 2637 | "book": { 2638 | "title": "Abandon\\u2019s gate", 2639 | "author": "James S.A. Corey" 2640 | } 2641 | }, 2642 | { 2643 | "location": { 2644 | "aisle": "D", 2645 | "column": "111", 2646 | "row": "A" 2647 | }, 2648 | "book": { 2649 | "title": "Twin Worlds", 2650 | "author": "Neil R. Jones" 2651 | } 2652 | }, 2653 | { 2654 | "location": { 2655 | "aisle": "F", 2656 | "column": "109", 2657 | "row": "C" 2658 | }, 2659 | "book": { 2660 | "title": "The terminal man", 2661 | "author": "Michael Crichton" 2662 | } 2663 | }, 2664 | { 2665 | "location": { 2666 | "aisle": "H", 2667 | "column": "105", 2668 | "row": "A" 2669 | }, 2670 | "book": { 2671 | "title": "Feed", 2672 | "author": "M.T. Anderson " 2673 | } 2674 | }, 2675 | { 2676 | "location": { 2677 | "aisle": "H", 2678 | "column": "101", 2679 | "row": "A" 2680 | }, 2681 | "book": { 2682 | "title": "Castle of Wizardry", 2683 | "author": "David Eddings" 2684 | } 2685 | }, 2686 | { 2687 | "location": { 2688 | "aisle": "H", 2689 | "column": "105", 2690 | "row": "B" 2691 | }, 2692 | "book": { 2693 | "title": "The quantum rose", 2694 | "author": "Catherine Asaro" 2695 | } 2696 | }, 2697 | { 2698 | "location": { 2699 | "aisle": "F", 2700 | "column": "109", 2701 | "row": "D" 2702 | }, 2703 | "book": { 2704 | "title": "Will save the galaxy for food", 2705 | "author": "Yahtzee Croshaw" 2706 | } 2707 | }, 2708 | { 2709 | "location": { 2710 | "aisle": "H", 2711 | "column": "111", 2712 | "row": "A" 2713 | }, 2714 | "book": { 2715 | "title": "Inter Ice Age", 2716 | "author": "Kobo Abe" 2717 | } 2718 | }, 2719 | { 2720 | "location": { 2721 | "aisle": "H", 2722 | "column": "101", 2723 | "row": "B" 2724 | }, 2725 | "book": { 2726 | "title": "Half Past Human", 2727 | "author": "T.J. Bass" 2728 | } 2729 | }, 2730 | { 2731 | "location": { 2732 | "aisle": "H", 2733 | "column": "105", 2734 | "row": "C" 2735 | }, 2736 | "book": { 2737 | "title": "The radiant seas", 2738 | "author": "Catherine asaro " 2739 | } 2740 | }, 2741 | { 2742 | "location": { 2743 | "aisle": "F", 2744 | "column": "109", 2745 | "row": "E" 2746 | }, 2747 | "book": { 2748 | "title": "Engine summer", 2749 | "author": "John Crowley" 2750 | } 2751 | }, 2752 | { 2753 | "location": { 2754 | "aisle": "H", 2755 | "column": "109", 2756 | "row": "A" 2757 | }, 2758 | "book": { 2759 | "title": "Fire Time", 2760 | "author": "Poul Anderson" 2761 | } 2762 | }, 2763 | { 2764 | "location": { 2765 | "aisle": "H", 2766 | "column": "111", 2767 | "row": "B" 2768 | }, 2769 | "book": { 2770 | "title": "Interface", 2771 | "author": "Mark Adlard" 2772 | } 2773 | }, 2774 | { 2775 | "location": { 2776 | "aisle": "H", 2777 | "column": "101", 2778 | "row": "C" 2779 | }, 2780 | "book": { 2781 | "title": "Foundations and Chaos", 2782 | "author": "Greg Bear" 2783 | } 2784 | }, 2785 | { 2786 | "location": { 2787 | "aisle": "H", 2788 | "column": "105", 2789 | "row": "D" 2790 | }, 2791 | "book": { 2792 | "title": "Robots and empire", 2793 | "author": "Issac Asimov" 2794 | } 2795 | }, 2796 | { 2797 | "location": { 2798 | "aisle": "F", 2799 | "column": "109", 2800 | "row": "F" 2801 | }, 2802 | "book": { 2803 | "title": "The kill order", 2804 | "author": "James Dashner" 2805 | } 2806 | }, 2807 | { 2808 | "location": { 2809 | "aisle": "H", 2810 | "column": "109", 2811 | "row": "B" 2812 | }, 2813 | "book": { 2814 | "title": "The Long Way Home", 2815 | "author": "Poul Anderson" 2816 | } 2817 | }, 2818 | { 2819 | "location": { 2820 | "aisle": "H", 2821 | "column": "101", 2822 | "row": "D" 2823 | }, 2824 | "book": { 2825 | "title": "Moving Mars", 2826 | "author": "Greg Bear" 2827 | } 2828 | }, 2829 | { 2830 | "location": { 2831 | "aisle": "H", 2832 | "column": "103", 2833 | "row": "A" 2834 | }, 2835 | "book": { 2836 | "title": "Lucky Star and the Moons of Jupiter", 2837 | "author": "Issac Asimov" 2838 | } 2839 | }, 2840 | { 2841 | "location": { 2842 | "aisle": "H", 2843 | "column": "111", 2844 | "row": "C" 2845 | }, 2846 | "book": { 2847 | "title": "Cryptozoic!", 2848 | "author": "Brian W. Aldiss" 2849 | } 2850 | }, 2851 | { 2852 | "location": { 2853 | "aisle": "H", 2854 | "column": "109", 2855 | "row": "C" 2856 | }, 2857 | "book": { 2858 | "title": "The Star Fox", 2859 | "author": "Poul Anderson" 2860 | } 2861 | }, 2862 | { 2863 | "location": { 2864 | "aisle": "H", 2865 | "column": "105", 2866 | "row": "E" 2867 | }, 2868 | "book": { 2869 | "title": "Nine Tommorrows ", 2870 | "author": "Issac Asimov" 2871 | } 2872 | }, 2873 | { 2874 | "location": { 2875 | "aisle": "H", 2876 | "column": "101", 2877 | "row": "E" 2878 | }, 2879 | "book": { 2880 | "title": "Artifact", 2881 | "author": "Gregory Benford" 2882 | } 2883 | }, 2884 | { 2885 | "location": { 2886 | "aisle": "H", 2887 | "column": "103", 2888 | "row": "B" 2889 | }, 2890 | "book": { 2891 | "title": "Triangle", 2892 | "author": "Issac Asimov" 2893 | } 2894 | }, 2895 | { 2896 | "location": { 2897 | "aisle": "F", 2898 | "column": "111", 2899 | "row": "A" 2900 | }, 2901 | "book": { 2902 | "title": "The city of gold and lead", 2903 | "author": "John Christopher" 2904 | } 2905 | }, 2906 | { 2907 | "location": { 2908 | "aisle": "H", 2909 | "column": "103", 2910 | "row": "C" 2911 | }, 2912 | "book": { 2913 | "title": "The Plains of Passage", 2914 | "author": "Jean M. Auel" 2915 | } 2916 | }, 2917 | { 2918 | "location": { 2919 | "aisle": "H", 2920 | "column": "109", 2921 | "row": "D" 2922 | }, 2923 | "book": { 2924 | "title": "Was of the Gods", 2925 | "author": "Poul Anderson" 2926 | } 2927 | }, 2928 | { 2929 | "location": { 2930 | "aisle": "H", 2931 | "column": "111", 2932 | "row": "D" 2933 | }, 2934 | "book": { 2935 | "title": "The Long Afternoon of Earth", 2936 | "author": "Nelson Doubleday " 2937 | } 2938 | }, 2939 | { 2940 | "location": { 2941 | "aisle": "H", 2942 | "column": "107", 2943 | "row": "A" 2944 | }, 2945 | "book": { 2946 | "title": "Juxtaposition", 2947 | "author": "Piers Anthony" 2948 | } 2949 | }, 2950 | { 2951 | "location": { 2952 | "aisle": "H", 2953 | "column": "103", 2954 | "row": "D" 2955 | }, 2956 | "book": { 2957 | "title": "The Empress of Mars", 2958 | "author": "Kage Baker" 2959 | } 2960 | }, 2961 | { 2962 | "location": { 2963 | "aisle": "F", 2964 | "column": "111", 2965 | "row": "B" 2966 | }, 2967 | "book": { 2968 | "title": "2001 a space odyssey", 2969 | "author": "Arthur C. Clarke" 2970 | } 2971 | }, 2972 | { 2973 | "location": { 2974 | "aisle": "H", 2975 | "column": "103", 2976 | "row": "E" 2977 | }, 2978 | "book": { 2979 | "title": "Terminal Beach", 2980 | "author": "J. G. Ballard" 2981 | } 2982 | }, 2983 | { 2984 | "location": { 2985 | "aisle": "H", 2986 | "column": "109", 2987 | "row": "E" 2988 | }, 2989 | "book": { 2990 | "title": "Immortal Monster", 2991 | "author": "Joseph D. Andriano" 2992 | } 2993 | }, 2994 | { 2995 | "location": { 2996 | "aisle": "H", 2997 | "column": "107", 2998 | "row": "B" 2999 | }, 3000 | "book": { 3001 | "title": "Nightmare", 3002 | "author": "Piers Anthony" 3003 | } 3004 | }, 3005 | { 3006 | "location": { 3007 | "aisle": "F", 3008 | "column": "111", 3009 | "row": "C" 3010 | }, 3011 | "book": { 3012 | "title": "Ghost from the grand banks", 3013 | "author": "Arthur C. Clarke" 3014 | } 3015 | }, 3016 | { 3017 | "location": { 3018 | "aisle": "H", 3019 | "column": "111", 3020 | "row": "E" 3021 | }, 3022 | "book": { 3023 | "title": "Taran Wanderer ", 3024 | "author": "Lloyd Alexander " 3025 | } 3026 | }, 3027 | { 3028 | "location": { 3029 | "aisle": "H", 3030 | "column": "107", 3031 | "row": "C" 3032 | }, 3033 | "book": { 3034 | "title": "Orn", 3035 | "author": "Piers Anthony" 3036 | } 3037 | }, 3038 | { 3039 | "location": { 3040 | "aisle": "H", 3041 | "column": "103", 3042 | "row": "F" 3043 | }, 3044 | "book": { 3045 | "title": "The Enchanted Planet", 3046 | "author": "Pierre Barbet" 3047 | } 3048 | }, 3049 | { 3050 | "location": { 3051 | "aisle": "H", 3052 | "column": "109", 3053 | "row": "F" 3054 | }, 3055 | "book": { 3056 | "title": "But What of Earth", 3057 | "author": "Piers Anthony" 3058 | } 3059 | }, 3060 | { 3061 | "location": { 3062 | "aisle": "H", 3063 | "column": "107", 3064 | "row": "D" 3065 | }, 3066 | "book": { 3067 | "title": "Race Against Time", 3068 | "author": "Piers Anthony" 3069 | } 3070 | }, 3071 | { 3072 | "location": { 3073 | "aisle": "H", 3074 | "column": "111", 3075 | "row": "F" 3076 | }, 3077 | "book": { 3078 | "title": "Cold Victory", 3079 | "author": "Poul Anderson" 3080 | } 3081 | }, 3082 | { 3083 | "location": { 3084 | "aisle": "F", 3085 | "column": "111", 3086 | "row": "D" 3087 | }, 3088 | "book": { 3089 | "title": "The songs of distant earth ", 3090 | "author": "Arthur C. Clarke" 3091 | } 3092 | }, 3093 | { 3094 | "location": { 3095 | "aisle": "H", 3096 | "column": "107", 3097 | "row": "E" 3098 | }, 3099 | "book": { 3100 | "title": "Vale of the Vole", 3101 | "author": "Piers Anthony" 3102 | } 3103 | }, 3104 | { 3105 | "location": { 3106 | "aisle": "F", 3107 | "column": "111", 3108 | "row": "E" 3109 | }, 3110 | "book": { 3111 | "title": "Close to critical", 3112 | "author": "Hal Clement" 3113 | } 3114 | }, 3115 | { 3116 | "location": { 3117 | "aisle": "F", 3118 | "column": "111", 3119 | "row": "F" 3120 | }, 3121 | "book": { 3122 | "title": "The Fold", 3123 | "author": "Peter Clines" 3124 | } 3125 | } 3126 | ] 3127 | --------------------------------------------------------------------------------