Wait. won't "rng.random(1, 5000)" generate a new number on each and every request? If so you could just keep making calls to the site until you have a result you like and show us that or in other words this isn't provably fair.
Also, did you sell all 5000 books? If not, what happens if the winner is a book that hasn't been sold yet?
No, that's not accurate, because it is a seeded PRNG. If the code called rng.random multiple times after initialization it would give new numbers, but reinitializing it and running it will get the same sequence of numbers. By only showing the first number, we always get the same result.
You can test that code with the hash from block 419,000 and you should get number "610" every time, which was the whole point of showing the code, since we don't know what the hash for 420,000 will be, but can't be manipulated, then we can be confident in this outcome.
This is using node.js with "express" and "request" modules
Also, did you sell all 5000 books? If not, what happens if the winner is a book that hasn't been sold yet?
The spreadsheet associates all addresses with a book number (by row), so this is indistinguishable for your request. I haven't posted the spreadsheet yet as I haven't gotten addresses from everyone. Purchasers should be able to see their own address via their browsers "find" function. All the addresses will receive counterparty tokens and the winning address holder will also get the gold bar shipped to them.