Revision history for Geo-Coder-Free

0.47	Fri Oct 16 09:34:18 PM EDT 2026
	[ Enhancements ]
	- Added geocode_many(), the loop a batch caller writes around geocode() 
	  It takes an arrayref of locations and answers with one entry
	  per distinct value - the point it resolved to, or undef - plus lookups (how many values were
	  looked up), resolved and unresolved (which add up to the number of distinct values) and
	  unresolved_values (the values that produced nothing, in the order they were first seen, which
	  is what a caller records as tried-and-failed instead of retrying them on every request).  A
	  value repeated in the batch is one lookup, so a column holding the same handful of places
	  thousands of times costs the handful; a value the module refuses before any backend is touched
	  - a bare number, the empty string, undef, a reference - costs no lookup at all and is counted
	  unresolved, so the count a caller caps its work by is the number of backends asked.  An undef
	  is the empty string and shares its entry; region and on_error are handed to every lookup and
	  mean there what they mean in geocode(), croak by default; and a backend exception is still an
	  exception.  The four keys the answer carries besides the values are reserved, and a value
	  spelled like one is refused by name rather than overwriting a count.  A batch of no values
	  answers with counts of zero
	- The token filter in _find_word_ngrams() asks the shared location rule what a bare number
	  is instead of spelling the rule out again with its own regex.  The answer is the same for
	  every token that can reach it - the text is trimmed and its whitespace collapsed before the
	  split, so no empty token can arise - and the rule is now answered in one place (below)
	- The databases Makefile.PL downloads are fetched with LWP::Simple again, and LWP::Simple::WithCache is
	  no longer used to fetch them.  That module swaps in a caching user agent whose request($request,
	  $file) answers a cache hit, or a 304, straight out of the cache and never writes $file, so
	  getstore() answered 200 and left nothing behind: on any machine whose cache had been warmed by an
	  earlier install no database was fetched at all, while perl Makefile.PL reported "Looks good" and
	  make succeeded.  The failure arrived much later, as "gunzip: cities.csv.gz: No such file or
	  directory" from createdatabase.PL and a failing t/locales.t, so an install that should have worked
	  did not work rather than losing a feature.  HTTP::Cache::Transparent, which caches the file it is
	  asked for, is still used when it is installed
	- Makefile.PL checks the files it downloaded rather than the status codes: after wait_all_children()
	  every destination is looked for in the parent, because a download that fails in a forked child dies
	  with that child and the parent never saw it - which is how the missing databases went unnoticed.  A
	  download that didn't arrive is named by URL and file and stops the build, under AUTOMATED_TESTING
	  it is a warning instead, since a smoker cannot fix the network and the tests that need those files
	  skip, and a build with NO_NETWORK_TESTING says that it is fetching nothing rather than doing it
	  quietly
	- createdatabase.PL no longer runs bin/create_sqlite when cities.csv.gz is absent.  db2sql gunzips
	  that file, so without it the step could only print the gzip error and blame sqlite3 ("perhaps you
	  don't have sqlite3 installed") for a file that was never downloaded; it now names the file that is
	  missing and carries on, cities.sql being optional
	[ Tests ]
	- t/unit.t: the API ledger gains the geocode_many states (the map and the counts, the
	  distinct-value reduction, the region pass-through, the default croak and its message, an undef
	  cell, the reserved key, an empty batch, both calling conventions, the usage errors and a
	  backend that dies), and a subtest drives them against a backend that is asked once per call and
	  answers per location
	- t/edge_cases.t: section 9d runs a 401-row column holding four distinct values to hold "one
	  lookup per distinct value" to two backend calls rather than 397, and a column of nothing but
	  unusable values to zero lookups at all - the backend is mocked to die if it is called for one
	- t/location-rule.t: the location rule is written out in one file and no other.  It scans every
	  module under lib/, every script under bin/ and every program under cgi-bin/ for the rule's
	  question as source text - a negated digit class or an anchored all-digits test - and fails
	  naming the file, the line, the sub and the spelling, so a renamed copy of _valid_location(),
	  or the guard typed straight into a caller, is caught as well as a second copy of the sub.
	  POD, comments and anything after __END__/__DATA__ are masked, since prose that describes the
	  rule is not a copy of it, and regexes that merely resemble it (a postcode, a coordinate,
	  /^\d/, /\d+=\d+/) are not reported.  The scan is run first on source whose answer is known,
	  so it is shown to tell the rule from code that merely uses digits.  Sites that ask one of
	  those questions about something that is not a location - the CGI test number, a cache
	  configuration value - are listed with their reason, and an exemption that no longer names a
	  site fails too, so the table cannot outlive the code it was written for
	- t/vwf-sync.t says what the sync will do with each block of local code instead of only that it
	  is not the master's.  A block is a run of consecutive local lines; each line is compared with
	  the master's lines in the same passage on the words it holds (identifiers and numbers,
	  punctuation and whitespace ignored), and a line sharing at least half its words with one of
	  them is that line in an older revision, which the sync will replace - the master's revision is
	  printed beside ours - while a line sharing that much with none of them is code the master has
	  never had, which the sync will discard.  A line that could be either is reported as local code,
	  the reading that sends the reader to look at their own code, and each file's report ends with
	  the two totals.  The tracked files are unchanged and still fail the test; the difference is in
	  the report, where Display.pm's local %blacklist hash now stands apart from the die() beside it
	  (the master's croak() in an older revision) and Utils.pm's @EXPORT line is shown with the
	  master's shorter list rather than as an addition of ours.  The comparison is run on source
	  whose answer is known as well - a changed line beside an added subroutine, a reworded line, and
	  a local line whose neighbour is an unrelated upstream change - so a report that has lost the
	  distinction fails there first
	- t/locales.t: the geographic subtests skip when the MaxMind databases are absent instead of failing.
	  Those lookups need admin1.db and admin2.db, which Makefile.PL downloads, and a build that was never
	  given them cannot answer the calls at all - the backend croaks "Can't find a file called 'admin1'"
	  - so a machine with OPENADDR_HOME set and no downloaded data to go with it failed five subtests,
	  and with them the install.  The skip names the files that are missing, as t/maxmind.t names the
	  database it needs
	- Added t/downloads.t: the fetch path in Makefile.PL is held to asking LWP::Simple, to waiting for the
	  children that do the downloading and to looking for the file that arrived rather than at the status
	  code, since a download that doesn't happen is invisible in the build and turns up later as a test
	  failing for want of a database
	- t/bin.t drives the CGI's index and meta_data pages, not just the query page, and checks what they
	  render rather than only the coordinates the query page resolves.  The landing page is asked for the
	  title and description its stub configuration gives it and for the form that starts a search; the
	  status page for the site title it was configured with, the domain it was answered for and the
	  figures it counts.  Those figures are the log the pages keep - one entry per visit, and a page
	  records the visit it serves - so the test writes a log of its own making (CGI::Info::logdir()
	  honours LOGDIR) and asserts the counts rendered from it, the four visitor types at two web visits,
	  one mobile, three search engines and no robots, header row and all.  The domain is named
	  (SERVER_NAME) rather than taken from the host, and the log the status page counts is written after
	  the landing page has been served, since serving it is itself a visit.  Both pages render templates
	  this distribution ships - the query page's own template is not one of them, query.txt ships empty,
	  which is why its answer is only in the log - so their output is the page, and it is asserted as
	  such.  bin/testcgibin gained tests 5 and 6 to drive them
	- t/bin.t asserts the site's answer to a client it will not serve, and its answer to one it will.
	  The same query is asked twice, from the same address and with the same everything else, by a
	  client whose user agent Geo::Coder::Free::Allow blacklists (bin/testcgibin test 7) and by one
	  whose agent is an ordinary browser's (test 8): the first is answered with a 403 and the
	  plain-text block page and is not given the position, the second is served the position and gets
	  no block page.  The refusal is read back out of the access log as well - the row the page
	  writes for it carries the reason the user-agent blacklist gave ('zgrab is blacklisted'), which
	  no other layer of the page's access control produces, plus the 403 and the address that was
	  refused - so what is asserted is that layer refusing the client and not the account being
	  written by something else in the stack.  The log every run writes is written into the test's
	  own directory now (LOGDIR, for all the runs rather than only those that read it back) and the
	  page's temporary directory is the test's too (TMPDIR), so the throttle that counts requests is
	  this run's rather than one that carries the count over from the last, and no run leaves an
	  access log or a throttle outside the temporary directory.  The file also points its diagnostics
	  at STDOUT: Log::WarnDie, which the pages need installed, takes STDERR over, and a test's
	  diagnostics go there by default, so before this every failure in t/bin.t was reported as a test
	  name with no detail to say what the page had answered instead

0.46	Thu Oct 15 09:06:24 PM EDT 2026
	[ Enhancements ]
	- Added valid_location(), which answers whether a string is a location at all: the rule geocode()
	  applies before it touches a backend, made public.  A caller working down a spreadsheet column can
	  skip a row whose value is a bare number, or empty, instead of catching the croak that would
	  otherwise end the run.  The regex it replaces was private to this module, so no caller could
	  pre-filter with the module's own rule
	- geocode() takes on_error => 'croak' (the default, and the behaviour every existing caller already
	  has) or 'undef'.  'undef' returns undef - an empty list in list context - for the two documented
	  input errors, invalid_location and invalid_scantext, and for nothing else: a backend that throws
	  still throws, because nothing is wrapped in an eval, and a call with neither a location nor a
	  scantext is still a usage croak.  An on_error with any other value is refused by name rather than
	  ignored, so a caller who misspells it does not ship a batch job that dies on its first bad row
	- Geo::Coder::Free::Provenance reads the accuracy vocabulary from Geo::Location::Point instead of
	  keeping a second copy of it.  The levels a backend reports and the levels a point accepts are now
	  one list - Geo::Location::Point::ACCURACY_LEVELS(), re-exported as Provenance's ACCURACY_LEVELS -
	  so a level added to one cannot go missing from the other, and the prerequisite is Geo::Location::Point
	  0.18, which is the version that defines it.  t/accuracy-vocabulary.t asserts the two names are the
	  same list, that a point accepts every level in it and refuses one outside it, and that every level
	  _accuracy_for() can derive from the fields a backend matches on is one of them
	[ Tests ]
	- t/consumer-contract.t: the declaration now accounts for every accessor Geo::Location::Point
	  documents, and the checker (Test-Consumer-Contract 0.02) fails when the value object gains an
	  accessor that is in none of the declaration's lists.  geocoder, database, confidence and
	  accuracy are named as accessors a consumer may read off a result, country, city and state as
	  documented accessors only some results carry, and new, AUTOLOAD and ACCURACY_LEVELS as
	  documented but not slots of one result.  The four provenance accessors and the three attribute
	  accessors had been absent from the declaration since they were added to the value object, which
	  is the drift the new direction of the check is for

0.45	Thu Oct 15 01:23:24 PM EDT 2026
	[ Enhancements ]
	- Every Geo::Location::Point this distribution returns now carries geocoder, database, confidence and
	  accuracy, so a caller can tell which distribution and
	  which backend produced it, how good the match was and how precise the coordinate is.  geocoder is new
	  and additive, and the existing database values are unchanged for the consumers that match on them
	- Local, MaxMind and OpenAddresses each describe the match they actually made: an OpenAddresses geohash
	  hit is an address and a hand-curated entry a locality, a Local match is graded from the columns that
	  matched rather than the ones the call site offered, and a MaxMind cities row is a city or a region
	- Added provenance(), which returns the distribution, backend, confidence and accuracy of a result, as a
	  list or, in scalar context, as a hashref.  The backends' two spellings of database are reduced to one
	  vocabulary there.  It returns undef rather than guessing for something with no provenance to report,
	  such as a plain hash handed on by another geocoder
	- Added Geo::Coder::Free::Provenance: the GEOCODER constant, the ACCURACY_LEVELS vocabulary and
	  _accuracy_for(), so a backend describes a match without repeating the vocabulary.  They live in a
	  module of their own because Geo::Coder::Free::Utils is synced from VWF master, where a geocoder
	  result has no provenance - an addition there would not survive the next sync
	- Requires Geo::Location::Point 0.16, which stores and returns false values: a confidence of 0 or an
	  empty accuracy used to be discarded on write, so provenance could not have been reported honestly
	[ Tests ]
	- t/unit.t: the API ledger gains the provenance states, and a new section runs the real MaxMind backend
	  (the mock is restored first) to assert that a hit carries all four keys with an accuracy of city or
	  region - a point the test built itself would prove nothing about the stamping
	- t/integration.t: the OpenAddresses path is now asserted end to end - the database lookup is stubbed at
	  the seam _get() uses, so the stamping, the Storable round trip through the result cache and the thawed
	  second lookup are all the code under test
	- t/consumer-contract.t: geocoder, database, confidence and accuracy are declared as guaranteed producer
	  keys, so a backend that stops setting one of them fails here
	- t/bin.t: the skip for a run without OPENADDR_HOME covers the 26 tests the plan declares, not 28, so a
	  configuration that skips the whole file no longer ends with 'Bad plan' and a non-zero exit
	- t/unit.t needs neither the downloaded databases nor an optional address parser: the MaxMind section
	  answers the database lookups itself, Geo::libpostal and Geo::Address::Parser are hidden so that what a
	  location string parses to cannot decide whether a documented state is reachable, and the column scan
	  is driven with the components a dataset row really carries.  Both of those were passing on a machine
	  with the data and the parsers installed and failing in CI, which has neither

0.44	Thu Oct 15 10:22:42 AM EDT 2026
	[ Tests ]
	- Use Test::Log::Abstraction
	- Added t/consumer-contract.t: the reader/producer contract for the Geo::Location::Point this dist returns. It checks that each backend still sets
	  the keys the contract claims, and that every registered consumer in the workspace reads only the keys every backend guarantees - reading a key that
	  only one backend sets is undef for the others, which is how a caller silently takes the wrong branch. A consumer that is not registered fails the
	  discovery test, so the check cannot go stale

0.43	Fri Aug 14 08:24:12 PM EDT 2026
	[ Enhancements ]
	- _normalize rewritten with split to eliminate O(N³) catastrophic backtracking from (.+)\s+(.+)\s+(.+)
	- _find_gb_addresses commas now mandatory between parts to prevent exponential backtracking on comma-free text
	- _find_us_addresses and _find_ca_addresses converted all capturing groups to non-capturing (only $& used)
	- _find_us_addresses and _find_ca_addresses street name pattern bounded to prevent lazy-quantifier O(N²) expansion
	- _normalize_args now croaks on odd-count argument lists longer than 1 (closes logic gap M7)
	- wantarray tautologies in reverse_geocode eliminated (M8)
	- scantext ignore_words passed by reference instead of copying the full hash each call
	- %admin2cache_rev added as inverse of %admin2cache, replacing O(N) value scan with O(1) lookup in _prepare
	[ Tests ]
	- Added new tests
	  t/logic-reducer.t: new test file with partition-based proofs for all M-series reductions
	  t/unit.t: new black-box unit test file covering every public API of Geo::Coder::Free, Local, OpenAddresses, and Utils; uses Test::Mockingbird to mock MaxMind, Test::Returns for schema validation, and an API ledger to guarantee all documented states are exercised
	  t/integration.t: new end-to-end integration test file covering cross-module workflows; tests backend delegation chain, alternatives singleton, concurrency isolation, clone shallow-copy semantics, scantext memoisation, round-trip geocode/reverse, distance calculations, OA known_locations, MaxMind admin cache invariants, optional Geo::libpostal dep, and USA/US normalisation
	  t/edge_cases.t: new destructive/boundary/security test file; covers distance() boundary coordinates, undef/non-numeric/out-of-range inputs, cache hostile configs, purely numeric geocode rejection (M7 regression), SQL/shell/newline injection payloads, global variable isolation, and ReDoS regression tests for _normalize(), _find_gb_addresses(), and the OA city-name pattern
	  t/path.t: new CFG path-coverage test file; maps every unique execution path in GCF::new/geocode/reverse_geocode, Local::geocode/reverse_geocode/_search/_find_geographic_centres/_to_two_letter_state, and the shared helpers _normalize_args/_normalize/_abbreviate/_find_word_ngrams; 97 subtests covering all dispatch branches, guard exits, confidence levels, and mock-contamination hygiene
	  t/transaction.t: new transaction-flow/lifecycle test file; 18 subtests covering Local cache write-through, geocode idempotency, scantext miss memoization, OA exception propagation (no silent swallow), OA→Local delegation chain, all-miss recovery, one-shot __DATA__ lifecycle, alternatives map re-geocode cycle, geocode→reverse round-trip, USA/US normalization idempotency, lazy backend creation, clone shallow-copy state boundary (shared references visible across both sides), and object usability after mid-chain failure

0.42	Fri Jul 10 11:48:02 EDT 2026
	Try Geo::Address::Parser before libpostal() as that uses less memory
	createdatabase.PL - borough parent lookup now uses locality_id from hierarchy to skip intermediate boroughs
	createdatabase.PL - File::Find glob fallback replaced with a pre-built ID->path index, eliminating per-miss tree scans
	createdatabase.PL - fix WhosonFirst index building regex broken by no_chdir => 1
	createdatabase.PL - catch XML parse errors in corrupt OSM files and continue to next file
	createdatabase.PL - eval scope narrowed to re-throw non-XML exceptions (business-logic die was silently swallowed)
	createdatabase.PL - XML::LibXML::Reader constructor moved inside eval so reader-open failures skip the file
	createdatabase.PL - $inserts reset per OSM file to prevent cross-file flush accounting errors
	createdatabase.PL - fix warn inside eval calling ->document->toString(1) which could throw on corrupt documents
	createdatabase.PL - fix operator precedence in DEBUG&DEBUG_GET_WOF && $filename debug print
	createdatabase.PL - add -f guard to WhosonFirst index builder to skip directories matching *.geojson pattern
	Local: Added _find_geographic_centres to add towns to the database where more than 3 places are known
	Improve handling of Australian states
	Ensure known_places are all loaded
	Don't put spaces in digest, helps to find known_places match
	Added test dashboard
	Updated from upstream VWF
	Openstreetmap now uses PBF files
	createdatabase.PL - l1_cache is now an LRU cache

0.41	Mon Jul  7 13:45:41 EDT 2025
	Use Object::Configure
	Attempt improvement on EXT4
	No need to clone Geo::Location::Point objects

0.40	Wed Jun 11 07:32:17 EDT 2025
	Improved the support for Berkeley DB databases
	Don't use IO::AIO on Windows
	Ensure CGI::Info doesn't attempt to read from stdin
	Run if Parallel::ForkManager isn't installed
	Use Params::Get in new()

0.39	Thu Mar 20 12:40:51 EDT 2025
	Use Geo::Hash to store in the database (results in over 10% size reduction)
	Improve US address parser to include NW as in "Pennsylvania Ave. NW"
	Handle arrays that are only one element in size
	Refactor scantext, using a complex regex and other technologies
	Latest upstream changes from VWF
	Use Geo::Hash, reduces SQLite file size by over 10%
	Makefile.PL: Download the files in parallel

0.38	Wed Jan 22 08:37:22 EST 2025
	Latest as_string return code and Utils.pm from VWF
	Added t/30-basics, t/config.t, t/utils.t and t/display.t
	geocode(): croak when input is just a set of numbers
	Local: Replace linear search with a hash search
	Local: Create a cache
	Maxmind: Create a cache
	scantext: set the location field to the string that was matched

0.37	Wed Oct 23 10:09:54 EDT 2024
	Allow new() to take HASH ref
	Slight speed improvements in Local.pm
	Support CircleCI
	Fix testing on a NO_NETWORK_TESTING system
	Port to Haiku
	Added the -f flag to createdatabase.PL to force building
		the database, e.g. after running wof_update
	DR5HN now puts JSON in its own directory

0.36	Fri Jul  5 08:56:52 EDT 2024
	Handle wide characters
	Latest VWF
	Added "exact" to OpenAddresses.pm
	Local.pm - remove empty fields
	Install bin/address_lookup
	Set lng as well as long in the output

0.35	Wed Mar  6 20:48:43 EST 2024
	Fix scantext.t when OSM is installed
	Fix openaddr.t test for not/there
	Rework the GETTING STARTED section of the POD
	Trying different databases since the creation of a database in SQLite
		eats a lot of RAM
	Added mysql support in createdatabase - TODO add support to DB.pm
	Added BUILDMODE to optionally only import from one large database
	Fix usage message in DB.pm
	Added more data cleanup to createdatabase.PL
	Use Database::Abstraction
	Rework key - for me saved about 1/3 of the database size

0.34	Mon Nov  6 16:53:43 EST 2023
	Latest DB.pm from NJH-Snippets
	Latest Display.pm from VWF
	Use HEAD not master to get the list of files
	MaxMind.pm: Try hard to support whatever API that the user wants to use

0.33	Mon  6 Nov 08:31:27 EST 2023
	Calling new on a local object now returns a clone rather than setting the defaults in the new object
	Some support for reverse_geocode
	Added Redis as a prerequisite if REDIS_SERVER is set
	Latest DB.pm from NJH-Snippets
	Change the mode of the cachedir to 2755
	Free.pm/Local.pm: Try hard to support whatever API that the user wants to use
	Local.pm: if libpostal fails, try code without
	Put the README file into the GETTING STARTED section of the POD

0.32	Wed Jun 21 20:31:01 EDT 2023
	Set NA rather than fail on smokers without L:P:https
	It's OK to install modules on Github Actions
	Reduce the number of calls to libpostal in Local.pm
	Only use XML::LibXML::Reader when needed

0.31	Fri Mar 24 17:30:06 EDT 2023
	Calling new on an object now returns a clone rather than setting the defaults in the new object
	Port to Solaris
	Local.pm doesn't contain states/provinces' locations, so quick return on search for those
	Use JSON::MaybeXS instead of JSON
	Fix truncate
	Use perl shell rather than CPAN to install missing modules
	Move temporary downloads to their own directory to stop them being installed
	Some local matches in US missed in the quick lookup
	Die, rather than warn, if the openaddr database can't be opened

0.30	Wed Mar  9 09:47:33 EST 2022
	Fix treating "30 Cross Street" as "30 X St"
	Latest DB.pm from VWF
	Improved handling of house numbers in Local.pm

0.29	Thu Nov 26 14:19:56 EST 2020
	Started work on importing data from OpenStreetMaps
		using planet.osm.bz2 files in $OSM_HOME
	More work to reduce the number of Maxmind results
	Removed some false positives in Local.pm
	Import US and Canadian data from
		https://github.com/dr5hn/countries-states-cities-database.git
		set DR5HN_HOME to where you clone it

0.28	Fri Oct 16 21:51:27 EDT 2020
	Fixed the manifest
	Don't return all the matches in a state/county/province

0.27.1	Thu Oct 15 11:08:18 EDT 2020
	Fix https://github.com/nigelhorne/Geo-Coder-Free/issues/47

0.27	Fri Oct  9 20:44:09 EDT 2020
	Local.pm: Call _normalize when libpostal is installed
	Install LWP::Simple and LWP::Protocol::https if needed

0.26	Thu Oct  8 19:47:45 EDT 2020
	Create the MaxMind database directory to download to
	Use Geo::Coder::Abbreviations

0.25	Wed Sep 30 22:33:06 EDT 2020
	Maxmind: Improved handling of full state names in the US

0.24	Mon Jun 15 11:50:14 EDT 2020
	Deal with
		https://github.com/apache/commons-csv/commit/914f2c41557bdd3dcde8d10d6f128fa3bb307b11
	Makefile.PL: used to not download any file if it exists, now it
		will download the file if it's older than a week

0.23	Sat May 16 22:16:30 EDT 2020
	WhosOnFirst: Use raw geojson files from GitHub
	Don't store items in MaxMind cache when there are more than one match,
		it was causing some subsequent searches to fail
	Sanity check to MaxMind records
	Don't look up where we've already failed to find a location
	Save database in Redis server as well if REDIS_SERVER is set
	Fixed reverse_geocode in Local.pm for UK addresses
	Fixed reverse_geocode in Local.pm when you know the name but not the
		number

0.22	Sat 12 Oct 15:14:01 EDT 2019
	When looking up Tyne and Wear, also lookup Borough of North Tyneside
	Make createdatabase.PL and openaddress.pm agree on how to handle St. Louis, MO

0.21	Tue 16 Jul 20:58:06 EDT 2019
	Remove errant debug statement

0.20	Sun 14 Jul 22:52:42 EDT 2019
	reverse_geocode starts locally then zooms out a bit
	Fix copy and paste error into Local.pm from OpenAddresses.pm

0.19	Wed 17 Apr 17:25:55 EDT 2019
	Added reverse_geocode support to MaxMind and Local

0.18	Wed 20 Mar 17:00:52 EDT 2019
	Added Geo::Coder::Free::Local
	Now return Geo::Location::Point object

0.17	Sat 23 Feb 17:21:41 EST 2019
	Maxmind download of worldcitiespop.txt has been removed

0.16	Tue Jan  1 17:57:37 EST 2019
	Import GeoName's allCountries data
	Remember L:E:AddressParser objects to speed up parsing. RT#127814
	Fix uninitialized variable
	Error if G:S:P can't extract a state name

0.15	Thu Nov 15 21:10:51 EST 2018
	Added alternatives table, for when a place could be listed elsewhere
	Support lookups of British counties e.g. 'Kent, England'

0.14	Fri Sep  7 16:07:39 EDT 2018
	Work on fixing http://www.cpantesters.org/cpan/report/6b68841a-8cc6-11e8-98d5-bb14e5798fec
	Re-enable Lingua::EN::AddressParse usage and prefer over Geo::libpostal
	Don't store cities and location names in the database

0.13	Fri Jul 20 16:48:58 EDT 2018
	Fix handling of cities with spaces in them
	Fix Canadian provinces - everything was going in AB
	Improved handling of "LANE"

0.12	Tue Jun 19 09:02:28 EDT 2018
	Fix "RESTAURANT" insert where street is known but not number
	Improved searches when Geo::Libpostal is not installed
	Improved handling of un-normalized input
	Removed duplicate code
	Add current country on web interface
	Added bin/address_lookup
	No need to give openaddr argument to new() if OPENADDR_HOME is set

0.11	Fri Jun  8 17:27:55 EDT 2018
	Started work on scantext support
	Fixed some calls in list mode which returned a scalar
	Many WOF records were not being imported
	Only fall back to Geo::StreetAddress::US as last resort
	Don't include NULL fields in the JSON output
	Better at finding venues when libpostal is not installed
	Tighten OpenAddresses validation

0.10	Fri 11 May 18:30:54 EDT 2018
	Street numbers were not being indexed
	Add data that I know with the GPS program on my phone
	Support "DR" for "Drive"
	Import GB data from whosonfirst.org data
	Maxmind - no longer croak for bad args

0.09	Tue Apr 17 21:34:01 EDT 2018
	Consolidated date in createdatabase
	Load Australian data
		Added basic Australian search (town, state, country)
	Removed the OLDCODE

0.08	Sun Apr 15 11:49:55 EDT 2018
	Download admin1 and admin2 directly from MaxMind
	Download cities.sql from geocode.nigelhorne.com

0.07	Tue Apr  3 07:40:46 EDT 2018
	Stash results in cache, workaround for very slow libpostal load
		(minutes!!) on scaleway machines
	Fix search for just state/province
	Added the run method

0.06	Thu Mar 29 09:12:56 EDT 2018
	Fix Github issue 14
	Updated to latest MaxMind databases
	Started support for a local copy of results.openaddresses.io
	Fixed Canadian lookups
	Match a street even if the house number isn't known
	Started geocoder website - see cgi-bin

0.05	Sun Jan 28 17:33:33 EST 2018
	Fix http://www.cpantesters.org/cpan/report/b10c956b-6bf9-1014-9a47-dc46d49c4260
	Allow known peculiarities to be found
	Improve handling of US lookups
	Added DISTINCT when only wanting one row

0.04	Thu Oct 26 22:05:54 EDT 2017
	Fix throw in http://www.cpantesters.org/cpan/report/ab86a142-b8d9-11e7-a1cf-bb670eaac09d
	Various speedups
	Fixed uninitialized variable
	Fix http://www.cpantesters.org/cpan/report/26e07a7e-b9e9-11e7-a1cf-bb670eaac09d

0.03	Sun Oct 22 10:46:22 EDT 2017
	Fixed spelling mistake

0.02	Sun Oct 22 10:31:35 EDT 2017
	Mention that reverse isn't supported
	Added createdatabase.PL
	Added ua

0.01	Sun 15 Oct 14:24:23 EDT 2017
	First Version
