diff --git a/CHANGELOG.md b/CHANGELOG.md index d85801a7..2ea5d24d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,19 +7,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + - Add `ArrayBytes`, `RawBytes`, `RawBytesOffsets`, and `ArrayBytesError` + - These can represent array data with fixed and variable length data types + - Add `array::Element[Owned]` traits representing array elements + - Supports conversion to and from `ArrayBytes` + - Add `array::ElementFixedLength` marker trait + - Add experimental `vlen` and `vlen_v2` codec for variable length data types + - `vlen_v2` is for legacy support of Zarr V2 `vlen-utf8`/`vlen-bytes`/`vlen-array` codecs + - Add `DataType::{String,Binary}` data types + - These are likely to become standardised in the future and are not feature gated + - Add `ArraySubset::contains()` + - Add `FillValueMetadata::{String,Unsupported}` + - `ArrayMetadata` can be serialised and deserialised with an unsupported `fill_value`, but `Array` creation will fail. + - Implement `From<{[u8; N],&[u8; N],String,&str}>` for `FillValue` + - Add `ArraySize` and `DataTypeSize` + - Add `DataType::fixed_size()` that returns `Option`. Returns `None` for variable length data types. + - Add `ArrayError::IncompatibleElementType` (replaces `ArrayError::IncompatibleElementSize`) + - Add `ArrayError::InvalidElementValue` + - Add `ChunkShape::num_elements_u64` + ### Changed - Use `[async_]retrieve_array_subset_opt` internally in `Array::[async_]retrieve_chunks_opt` - **Breaking**: Replace `[Async]ArrayPartialDecoderTraits::element_size()` with `data_type()` + - Array `_store` methods now use `impl Into>` instead of `&[u8]` for the input bytes + - **Breaking**: Array `_store_{elements,ndarray}` methods now use `T: Element` instead of `T: bytemuck::Pod` + - **Breaking**: Array `_retrieve_{elements,ndarray}` methods now use `T: ElementOwned` instead of `T: bytemuck::Pod` + - Optimised `Array::[async_]store_array_subset_opt` when the subset is a subset of a single chunk + - Make `transmute_to_bytes` public + - Relax `ndarray_into_vec` from `T: bytemuck:Pod` to `T: Clone` + - **Breaking**: `DataType::size()` now returns a `DataTypeSize` instead of `usize` + - **Breaking**: `ArrayCodecTraits::{encode/decode}` have been specialised into `ArrayTo{Array,Bytes}CodecTraits::{encode/decode}` ### Removed - **Breaking**: Remove `into_array_view` array and codec API - This was not fully utilised, not applicable to variable sized data types, and quite unsafe for a public API - - Remove internal `ChunksPerShardError` and just use `CodecError::Other` + - **Breaking**: Remove internal `ChunksPerShardError` and just use `CodecError::Other` + - **Breaking**: Remove `array_subset::{ArrayExtractBytesError,ArrayStoreBytesError}` + - **Breaking**: Remove `ArraySubset::{extract,store}_bytes[_unchecked]`, they are replaced by methods in `ArrayBytes` + - **Breaking**: Remove `array::validate_element_size` and `ArrayError::IncompatibleElementSize` + - The internal validation in array `_element` methods is now more strict than just matching the element size + - Example: `u16` must match `uint16` data type and will not match `int16` or `float16` ### Fixed - Fix an unnecessary copy in `async_store_set_partial_values` - Fix error when `bytes` metadata is encoded without a configuration, even if empty - Fix an error in `ChunkGrid` docs + - Fixed `[async_]store_set_partial_values` and `MemoryStore::set` to correctly truncate the bytes of store value if they shrink ## [0.15.1] - 2024-07-11 diff --git a/Cargo.toml b/Cargo.toml index c2d450b7..348470b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ async-lock = { version = "3.2.0", optional = true } async-recursion = { version = "1.0.5", optional = true } async-trait = { version = "0.1.74", optional = true } blosc-sys = { version = "0.3.4", package = "blosc-src", features = ["snappy", "lz4", "zlib", "zstd"], optional = true } -bytemuck = { version = "1.14.0", features = ["extern_crate_alloc", "must_cast"] } +bytemuck = { version = "1.14.0", features = ["extern_crate_alloc", "must_cast", "min_const_generics"] } bytes = "1.6.0" bzip2 = { version = "0.4.4", optional = true, features = ["static"] } crc32c = { version = "0.6.5", optional = true } @@ -75,6 +75,10 @@ zfp-sys = {version = "0.1.15", features = ["static"], optional = true } zip = { version = "2.1.3", optional = true } zstd = { version = "0.13.1", features = ["zstdmt"], optional = true } +[dependencies.num-complex] +version = "0.4.3" +features = ["bytemuck"] + [dev-dependencies] chrono = "0.4" criterion = "0.5.1" @@ -93,6 +97,11 @@ name = "array_write_read_ndarray" required-features = ["ndarray"] doc-scrape-examples = true +[[example]] +name = "array_write_read_string" +required-features = ["ndarray"] +doc-scrape-examples = true + [[example]] name = "async_array_write_read" required-features = ["ndarray", "async", "object_store"] diff --git a/benches/codecs.rs b/benches/codecs.rs index 25441c0c..f44bfaff 100644 --- a/benches/codecs.rs +++ b/benches/codecs.rs @@ -8,9 +8,10 @@ use zarrs::array::{ codec::{ array_to_bytes::bytes::Endianness, bytes_to_bytes::blosc::{BloscCompressor, BloscShuffleMode}, - ArrayCodecTraits, BloscCodec, BytesCodec, BytesToBytesCodecTraits, CodecOptions, + ArrayCodecTraits, ArrayToBytesCodecTraits, BloscCodec, BytesCodec, BytesToBytesCodecTraits, + CodecOptions, }, - BytesRepresentation, ChunkRepresentation, DataType, + BytesRepresentation, ChunkRepresentation, DataType, Element, }; fn codec_bytes(c: &mut Criterion) { @@ -35,12 +36,13 @@ fn codec_bytes(c: &mut Criterion) { .unwrap(); let data = vec![0u8; size3.try_into().unwrap()]; + let bytes = Element::into_array_bytes(&DataType::UInt8, &data).unwrap(); group.throughput(Throughput::Bytes(size3)); // encode and decode have the same implementation group.bench_function(BenchmarkId::new("encode_decode", size3), |b| { b.iter(|| { codec - .encode(Cow::Borrowed(&data), &rep, &CodecOptions::default()) + .encode(bytes.clone(), &rep, &CodecOptions::default()) .unwrap() }); }); diff --git a/doc/status/codecs.md b/doc/status/codecs.md index a4587c7c..f7a3dd93 100644 --- a/doc/status/codecs.md +++ b/doc/status/codecs.md @@ -1,16 +1,18 @@ -| Codec Type | Codec | ZEP | V3 | V2 | Feature Flag* | -| -------------- | ------------------------- | ----------------- | ------- | ------- | ------------- | -| Array to Array | [transpose] | [ZEP0001] | ✓ | | **transpose** | -| | [bitround] (experimental) | | ✓ | | bitround | -| Array to Bytes | [bytes] | [ZEP0001] | ✓ | | | -| | [sharding_indexed] | [ZEP0002] | ✓ | | **sharding** | -| | [zfp] (experimental) | | ✓ | | zfp | -| | [pcodec] (experimental) | | ✓ | | pcodec | -| Bytes to Bytes | [blosc] | [ZEP0001] | ✓ | ✓ | **blosc** | -| | [gzip] | [ZEP0001] | ✓ | ✓ | **gzip** | -| | [crc32c] | [ZEP0002] | ✓ | | **crc32c** | -| | [zstd] | [zarr-specs #256] | ✓ | | zstd | -| | [bz2] (experimental) | | ✓ | ✓ | bz2 | +| Codec Type | Codec | ZEP | V3 | V2 | Feature Flag* | +| -------------- | ------------------------------------------------- | ----------------- | ------- | ------- | ------------- | +| Array to Array | [transpose] | [ZEP0001] | ✓ | | **transpose** | +| | [bitround] (experimental) | | ✓ | | bitround | +| Array to Bytes | [bytes] | [ZEP0001] | ✓ | | | +| | [sharding_indexed] | [ZEP0002] | ✓ | | **sharding** | +| | [zfp] (experimental) | | ✓ | | zfp | +| | [pcodec] (experimental) | | ✓ | | pcodec | +| | [vlen] (experimental) | | ✓ | | | +| | [vlen_v2] (experimental)
`vlen-*` in Zarr V2 | | ✓ | ✓ | | +| Bytes to Bytes | [blosc] | [ZEP0001] | ✓ | ✓ | **blosc** | +| | [gzip] | [ZEP0001] | ✓ | ✓ | **gzip** | +| | [crc32c] | [ZEP0002] | ✓ | | **crc32c** | +| | [zstd] | [zarr-specs #256] | ✓ | | zstd | +| | [bz2] (experimental) | | ✓ | ✓ | bz2 | \* Bolded feature flags are part of the default set of features.
@@ -31,12 +33,16 @@ [crc32c]: crate::array::codec::bytes_to_bytes::crc32c [zstd]: crate::array::codec::bytes_to_bytes::zstd [bz2]: crate::array::codec::bytes_to_bytes::bz2 +[vlen]: crate::array::codec::array_to_bytes::vlen +[vlen_v2]: crate::array::codec::array_to_bytes::vlen_v2 The `"name"` of of experimental codecs in array metadata links the codec documentation in this crate. -| Experimental Codec | Name / URI | -| ------------------ | ------------------------------------------------- | -| `bitround` | | -| `zfp` | | -| `pcodec` | | -| `bz2` | | +| Experimental Codec | Name / URI | +| ------------------ | -------------------------------------------------------- | +| `bitround` | | +| `zfp` | | +| `pcodec` | | +| `bz2` | | +| `vlen` | | +| `vlen_v2` | | diff --git a/doc/status/data_types.md b/doc/status/data_types.md index 05875056..bf66c75a 100644 --- a/doc/status/data_types.md +++ b/doc/status/data_types.md @@ -1,8 +1,12 @@ -| Data Type | ZEP | V3 | V2 | Feature Flag | +| Data Type | ZEP | V3 | V2 | Feature Flag | | --------- | --- | ----- | -- | ------------ | | [bool]
[int8] [int16] [int32] [int64] [uint8] [uint16] [uint32] [uint64]
[float16] [float32] [float64]
[complex64] [complex128] | [ZEP0001] | ✓ | ✓ | | [r* (raw bits)] | [ZEP0001] | ✓ | | | | [bfloat16] | [zarr-specs #130] | ✓ | | | +| [string] (experimental) | [ZEP0007 (draft)] | ✓ | | | +| [binary] (experimental) | [ZEP0007 (draft)] | ✓ | | | + +† Experimental data types are recommended for evaluation only. [bool]: crate::array::data_type::DataType::Bool [int8]: crate::array::data_type::DataType::Int8 @@ -20,6 +24,9 @@ [complex128]: crate::array::data_type::DataType::Complex128 [bfloat16]: crate::array::data_type::DataType::BFloat16 [r* (raw bits)]: crate::array::data_type::DataType::RawBits +[string]: crate::array::data_type::DataType::String +[binary]: crate::array::data_type::DataType::Binary [ZEP0001]: https://zarr.dev/zeps/accepted/ZEP0001.html [zarr-specs #130]: https://github.com/zarr-developers/zarr-specs/issues/130 +[ZEP0007 (draft)]: https://github.com/zarr-developers/zeps/pull/47 diff --git a/examples/array_write_read_string.rs b/examples/array_write_read_string.rs new file mode 100644 index 00000000..97f1444a --- /dev/null +++ b/examples/array_write_read_string.rs @@ -0,0 +1,119 @@ +use itertools::Itertools; +use ndarray::{array, Array2, ArrayD}; +use zarrs::storage::{ + storage_transformer::{StorageTransformerExtension, UsageLogStorageTransformer}, + ReadableWritableListableStorage, +}; + +fn array_write_read() -> Result<(), Box> { + use std::sync::Arc; + use zarrs::{ + array::{DataType, FillValue}, + array_subset::ArraySubset, + storage::store, + }; + + // Create a store + // let path = tempfile::TempDir::new()?; + // let mut store: ReadableWritableListableStorage = Arc::new(store::FilesystemStore::new(path.path())?); + // let mut store: ReadableWritableListableStorage = Arc::new(store::FilesystemStore::new( + // "tests/data/array_write_read.zarr", + // )?); + let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new()); + if let Some(arg1) = std::env::args().collect::>().get(1) { + if arg1 == "--usage-log" { + let log_writer = Arc::new(std::sync::Mutex::new( + // std::io::BufWriter::new( + std::io::stdout(), + // ) + )); + let usage_log = Arc::new(UsageLogStorageTransformer::new(log_writer, || { + chrono::Utc::now().format("[%T%.3f] ").to_string() + })); + store = usage_log + .clone() + .create_readable_writable_listable_transformer(store); + } + } + + // Create a group + let group_path = "/group"; + let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?; + + // Update group metadata + group + .attributes_mut() + .insert("foo".into(), serde_json::Value::String("bar".into())); + + // Write group metadata to store + group.store_metadata()?; + + println!( + "The group metadata is:\n{}\n", + serde_json::to_string_pretty(&group.metadata()).unwrap() + ); + + // Create an array + let array_path = "/group/array"; + let array = zarrs::array::ArrayBuilder::new( + vec![4, 4], // array shape + DataType::String, + vec![2, 2].try_into()?, // regular chunk shape + FillValue::from("_"), + ) + // .bytes_to_bytes_codecs(vec![]) // uncompressed + .dimension_names(["y", "x"].into()) + // .storage_transformers(vec![].into()) + .build(store.clone(), array_path)?; + + // Write array metadata to store + array.store_metadata()?; + + println!( + "The array metadata is:\n{}\n", + serde_json::to_string_pretty(&array.metadata()).unwrap() + ); + + // Write some chunks + array.store_chunk_ndarray( + &[0, 0], + ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["a", "bb", "ccc", "dddd"]).unwrap(), + )?; + array.store_chunk_ndarray( + &[0, 1], + ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["4444", "333", "22", "1"]).unwrap(), + )?; + let subset_all = ArraySubset::new_with_shape(array.shape().to_vec()); + let data_all = array.retrieve_array_subset_ndarray::(&subset_all)?; + println!("store_chunk [0, 0] and [0, 1]:\n{data_all}\n"); + + // Write a subset spanning multiple chunks, including updating chunks already written + let ndarray_subset: Array2<&str> = array![["!", "@@"], ["###", "$$$$"]]; + array.store_array_subset_ndarray( + ArraySubset::new_with_ranges(&[1..3, 1..3]).start(), + ndarray_subset, + )?; + let data_all = array.retrieve_array_subset_ndarray::(&subset_all)?; + println!("store_array_subset [1..3, 1..3]:\nndarray::ArrayD\n{data_all}"); + + // Retrieve bytes directly, convert into a single string allocation, create a &str ndarray + // TODO: Add a convenience function for this? + let data_all = array.retrieve_array_subset(&subset_all)?; + let (bytes, offsets) = data_all.into_variable()?; + let string = String::from_utf8(bytes.into_owned())?; + let elements = offsets + .iter() + .tuple_windows() + .map(|(&curr, &next)| &string[curr..next]) + .collect::>(); + let ndarray = ArrayD::<&str>::from_shape_vec(subset_all.shape_usize(), elements)?; + println!("ndarray::ArrayD<&str>:\n{ndarray}"); + + Ok(()) +} + +fn main() { + if let Err(err) = array_write_read() { + println!("{:?}", err); + } +} diff --git a/examples/sharded_array_write_read.rs b/examples/sharded_array_write_read.rs index d312e8c5..5a05368c 100644 --- a/examples/sharded_array_write_read.rs +++ b/examples/sharded_array_write_read.rs @@ -137,15 +137,15 @@ fn sharded_array_write_read() -> Result<(), Box> { ArraySubset::new_with_start_shape(vec![0, 4], inner_chunk_shape.clone())?, ]; let decoded_inner_chunks_bytes = partial_decoder.partial_decode(&inner_chunks_to_decode)?; - let decoded_inner_chunks_ndarray = decoded_inner_chunks_bytes - .into_iter() - .map(|bytes| bytes_to_ndarray::(&inner_chunk_shape, bytes.to_vec())) - .collect::, _>>()?; println!("Decoded inner chunks:"); for (inner_chunk_subset, decoded_inner_chunk) in - std::iter::zip(inner_chunks_to_decode, decoded_inner_chunks_ndarray) + std::iter::zip(inner_chunks_to_decode, decoded_inner_chunks_bytes) { - println!("{inner_chunk_subset}\n{decoded_inner_chunk}\n"); + let ndarray = bytes_to_ndarray::( + &inner_chunk_shape, + decoded_inner_chunk.into_fixed()?.into_owned(), + )?; + println!("{inner_chunk_subset}\n{ndarray}\n"); } // Show the hierarchy diff --git a/src/array.rs b/src/array.rs index f7f46bdc..4599af0f 100644 --- a/src/array.rs +++ b/src/array.rs @@ -22,6 +22,7 @@ //! The documentation for [`Array`] details how to interact with arrays. mod array_builder; +mod array_bytes; mod array_errors; mod array_metadata_options; mod array_representation; @@ -33,6 +34,7 @@ pub mod codec; pub mod concurrency; pub mod data_type; mod dimension_name; +mod element; mod endianness; mod fill_value; mod nan_representations; @@ -47,9 +49,10 @@ use std::sync::Arc; pub use self::{ array_builder::ArrayBuilder, + array_bytes::{ArrayBytes, ArrayBytesError, RawBytes, RawBytesOffsets}, array_errors::{ArrayCreateError, ArrayError}, array_metadata_options::ArrayMetadataOptions, - array_representation::{ArrayRepresentation, ChunkRepresentation}, + array_representation::{ArrayRepresentation, ArraySize, ChunkRepresentation}, bytes_representation::BytesRepresentation, chunk_grid::ChunkGrid, chunk_key_encoding::{ChunkKeyEncoding, ChunkKeySeparator}, @@ -57,8 +60,9 @@ pub use self::{ codec::ArrayCodecTraits, codec::CodecChain, concurrency::RecommendedConcurrency, - data_type::DataType, + data_type::{DataType, DataTypeSize}, dimension_name::DimensionName, + element::{Element, ElementFixedLength}, endianness::{Endianness, NATIVE_ENDIAN}, fill_value::FillValue, nan_representations::{ZARR_NAN_BF16, ZARR_NAN_F16, ZARR_NAN_F32, ZARR_NAN_F64}, @@ -641,9 +645,7 @@ impl Array { #[cfg(feature = "ndarray")] /// Convert an ndarray into a vec with standard layout -fn ndarray_into_vec( - array: ndarray::Array, -) -> Vec { +fn ndarray_into_vec(array: ndarray::Array) -> Vec { if array.is_standard_layout() { array } else { @@ -695,7 +697,7 @@ pub fn transmute_to_bytes_vec(from: Vec) -> Vec { /// Transmute from `&[T]` to `&[u8]`. #[must_use] -fn transmute_to_bytes(from: &[T]) -> &[u8] { +pub fn transmute_to_bytes(from: &[T]) -> &[u8] { bytemuck::must_cast_slice(from) } @@ -733,17 +735,6 @@ fn iter_u64_to_usize<'a, I: Iterator>(iter: I) -> Vec { .collect::>() } -fn validate_element_size(data_type: &DataType) -> Result<(), ArrayError> { - if data_type.size() == std::mem::size_of::() { - Ok(()) - } else { - Err(ArrayError::IncompatibleElementSize( - data_type.size(), - std::mem::size_of::(), - )) - } -} - #[cfg(feature = "ndarray")] /// Convert a vector of elements to an [`ndarray::ArrayD`]. /// diff --git a/src/array/array_async_readable.rs b/src/array/array_async_readable.rs index 7bb48eb1..e037d6c3 100644 --- a/src/array/array_async_readable.rs +++ b/src/array/array_async_readable.rs @@ -13,15 +13,16 @@ use crate::{ }; use super::{ + array_bytes::{merge_chunks_vlen, update_bytes_flen}, codec::{ - options::CodecOptions, ArrayCodecTraits, ArrayToBytesCodecTraits, - AsyncArrayPartialDecoderTraits, AsyncStoragePartialDecoder, + options::CodecOptions, ArrayToBytesCodecTraits, AsyncArrayPartialDecoderTraits, + AsyncStoragePartialDecoder, }, concurrency::concurrency_chunks_and_codec, - transmute_from_bytes_vec, + element::ElementOwned, unsafe_cell_slice::UnsafeCellSlice, - validate_element_size, Array, ArrayCreateError, ArrayError, ArrayMetadata, ArrayMetadataV2, - ArrayMetadataV3, + Array, ArrayBytes, ArrayCreateError, ArrayError, ArrayMetadata, ArrayMetadataV2, + ArrayMetadataV3, ArraySize, DataTypeSize, }; #[cfg(feature = "ndarray")] @@ -93,14 +94,14 @@ impl Array { pub async fn async_retrieve_chunk_if_exists( &self, chunk_indices: &[u64], - ) -> Result>, ArrayError> { + ) -> Result>, ArrayError> { self.async_retrieve_chunk_if_exists_opt(chunk_indices, &CodecOptions::default()) .await } /// Async variant of [`retrieve_chunk_elements_if_exists`](Array::retrieve_chunk_elements_if_exists). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunk_elements_if_exists( + pub async fn async_retrieve_chunk_elements_if_exists( &self, chunk_indices: &[u64], ) -> Result>, ArrayError> { @@ -111,7 +112,7 @@ impl Array { #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunk_ndarray_if_exists`](Array::retrieve_chunk_ndarray_if_exists). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunk_ndarray_if_exists( + pub async fn async_retrieve_chunk_ndarray_if_exists( &self, chunk_indices: &[u64], ) -> Result>, ArrayError> { @@ -144,14 +145,17 @@ impl Array { /// Async variant of [`retrieve_chunk`](Array::retrieve_chunk). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunk(&self, chunk_indices: &[u64]) -> Result, ArrayError> { + pub async fn async_retrieve_chunk( + &self, + chunk_indices: &[u64], + ) -> Result, ArrayError> { self.async_retrieve_chunk_opt(chunk_indices, &CodecOptions::default()) .await } /// Async variant of [`retrieve_chunk_elements`](Array::retrieve_chunk_elements). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunk_elements( + pub async fn async_retrieve_chunk_elements( &self, chunk_indices: &[u64], ) -> Result, ArrayError> { @@ -162,7 +166,7 @@ impl Array { #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunk_ndarray`](Array::retrieve_chunk_ndarray). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunk_ndarray( + pub async fn async_retrieve_chunk_ndarray( &self, chunk_indices: &[u64], ) -> Result, ArrayError> { @@ -172,14 +176,17 @@ impl Array { /// Async variant of [`retrieve_chunks`](Array::retrieve_chunks). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { + pub async fn async_retrieve_chunks( + &self, + chunks: &ArraySubset, + ) -> Result, ArrayError> { self.async_retrieve_chunks_opt(chunks, &CodecOptions::default()) .await } /// Async variant of [`retrieve_chunks_elements`](Array::retrieve_chunks_elements). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunks_elements( + pub async fn async_retrieve_chunks_elements( &self, chunks: &ArraySubset, ) -> Result, ArrayError> { @@ -190,7 +197,7 @@ impl Array { #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunks_ndarray`](Array::retrieve_chunks_ndarray). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunks_ndarray( + pub async fn async_retrieve_chunks_ndarray( &self, chunks: &ArraySubset, ) -> Result, ArrayError> { @@ -204,14 +211,14 @@ impl Array { &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.async_retrieve_chunk_subset_opt(chunk_indices, chunk_subset, &CodecOptions::default()) .await } /// Async variant of [`retrieve_chunk_subset_elements`](Array::retrieve_chunk_subset_elements). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunk_subset_elements( + pub async fn async_retrieve_chunk_subset_elements( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, @@ -227,7 +234,7 @@ impl Array { #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunk_subset_ndarray`](Array::retrieve_chunk_subset_ndarray). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_chunk_subset_ndarray( + pub async fn async_retrieve_chunk_subset_ndarray( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, @@ -245,14 +252,14 @@ impl Array { pub async fn async_retrieve_array_subset( &self, array_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.async_retrieve_array_subset_opt(array_subset, &CodecOptions::default()) .await } /// Async variant of [`retrieve_array_subset_elements`](Array::retrieve_array_subset_elements). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_array_subset_elements( + pub async fn async_retrieve_array_subset_elements( &self, array_subset: &ArraySubset, ) -> Result, ArrayError> { @@ -263,7 +270,7 @@ impl Array { #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_array_subset_ndarray`](Array::retrieve_array_subset_ndarray). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_retrieve_array_subset_ndarray( + pub async fn async_retrieve_array_subset_ndarray( &self, array_subset: &ArraySubset, ) -> Result, ArrayError> { @@ -291,7 +298,7 @@ impl Array { &self, chunk_indices: &[u64], options: &CodecOptions, - ) -> Result>, ArrayError> { + ) -> Result>, ArrayError> { if chunk_indices.len() != self.dimensionality() { return Err(ArrayError::InvalidChunkGridIndicesError( chunk_indices.to_vec(), @@ -311,7 +318,7 @@ impl Array { .map_err(ArrayError::StorageError)?; if let Some(chunk_encoded) = chunk_encoded { let chunk_representation = self.chunk_array_representation(chunk_indices)?; - let chunk_decoded = self + let bytes = self .codecs() .decode( Cow::Borrowed(&chunk_encoded), @@ -319,16 +326,11 @@ impl Array { options, ) .map_err(ArrayError::CodecError)?; - let chunk_decoded_size = - chunk_representation.num_elements_usize() * chunk_representation.data_type().size(); - if chunk_decoded.len() == chunk_decoded_size { - Ok(Some(chunk_decoded.into_owned())) - } else { - Err(ArrayError::UnexpectedChunkDecodedSize( - chunk_decoded.len(), - chunk_decoded_size, - )) - } + bytes.validate( + chunk_representation.num_elements(), + chunk_representation.data_type().size(), + )?; + Ok(Some(bytes.into_owned())) } else { Ok(None) } @@ -340,51 +342,56 @@ impl Array { &self, chunk_indices: &[u64], options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { let chunk = self .async_retrieve_chunk_if_exists_opt(chunk_indices, options) .await?; if let Some(chunk) = chunk { Ok(chunk) } else { - let chunk_representation = self.chunk_array_representation(chunk_indices)?; - let fill_value = chunk_representation.fill_value().as_ne_bytes(); - Ok(fill_value.repeat(chunk_representation.num_elements_usize())) + let chunk_shape = self.chunk_shape(chunk_indices)?; + let array_size = + ArraySize::new(self.data_type().size(), chunk_shape.num_elements_u64()); + Ok(ArrayBytes::new_fill_value(array_size, self.fill_value())) } } /// Async variant of [`retrieve_chunk_elements_if_exists_opt`](Array::retrieve_chunk_elements_if_exists_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunk_elements_if_exists_opt( + pub async fn async_retrieve_chunk_elements_if_exists_opt( &self, chunk_indices: &[u64], options: &CodecOptions, ) -> Result>, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self + if let Some(bytes) = self .async_retrieve_chunk_if_exists_opt(chunk_indices, options) - .await?; - Ok(bytes.map(|bytes| transmute_from_bytes_vec::(bytes))) + .await? + { + let elements = T::from_array_bytes(self.data_type(), bytes)?; + Ok(Some(elements)) + } else { + Ok(None) + } } /// Async variant of [`retrieve_chunk_elements_opt`](Array::retrieve_chunk_elements_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunk_elements_opt( + pub async fn async_retrieve_chunk_elements_opt( &self, chunk_indices: &[u64], options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; let bytes = self .async_retrieve_chunk_opt(chunk_indices, options) .await?; - Ok(transmute_from_bytes_vec::(bytes)) + let elements = T::from_array_bytes(self.data_type(), bytes)?; + Ok(elements) } #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunk_ndarray_if_exists_opt`](Array::retrieve_chunk_ndarray_if_exists_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunk_ndarray_if_exists_opt( + pub async fn async_retrieve_chunk_ndarray_if_exists_opt( &self, chunk_indices: &[u64], options: &CodecOptions, @@ -407,7 +414,7 @@ impl Array { #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunk_ndarray_opt`](Array::retrieve_chunk_ndarray_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunk_ndarray_opt( + pub async fn async_retrieve_chunk_ndarray_opt( &self, chunk_indices: &[u64], options: &CodecOptions, @@ -467,7 +474,7 @@ impl Array { &self, chunks: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { if chunks.dimensionality() != self.dimensionality() { return Err(ArrayError::InvalidArraySubset( chunks.clone(), @@ -482,25 +489,24 @@ impl Array { /// Async variant of [`retrieve_chunks_elements_opt`](Array::retrieve_chunks_elements_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunks_elements_opt( + pub async fn async_retrieve_chunks_elements_opt( &self, chunks: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; let bytes = self.async_retrieve_chunks_opt(chunks, options).await?; - Ok(transmute_from_bytes_vec::(bytes)) + let elements = T::from_array_bytes(self.data_type(), bytes)?; + Ok(elements) } #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunks_ndarray_opt`](Array::retrieve_chunks_ndarray_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunks_ndarray_opt( + pub async fn async_retrieve_chunks_ndarray_opt( &self, chunks: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; let array_subset = self.chunks_subset(chunks)?; let elements = self .async_retrieve_chunks_elements_opt(chunks, options) @@ -515,7 +521,7 @@ impl Array { &self, array_subset: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { if array_subset.dimensionality() != self.dimensionality() { return Err(ArrayError::InvalidArraySubset( array_subset.clone(), @@ -535,10 +541,11 @@ impl Array { // Retrieve chunk bytes let num_chunks = chunks.num_elements_usize(); match num_chunks { - 0 => Ok(self - .fill_value() - .as_ne_bytes() - .repeat(array_subset.num_elements_usize())), + 0 => { + let array_size = + ArraySize::new(self.data_type().size(), array_subset.num_elements()); + Ok(ArrayBytes::new_fill_value(array_size, self.fill_value())) + } 1 => { let chunk_indices = chunks.start(); let chunk_subset = self.chunk_subset(chunk_indices)?; @@ -557,11 +564,6 @@ impl Array { } } _ => { - // Decode chunks and copy to output - let size_output = - usize::try_from(array_subset.num_elements() * self.data_type().size() as u64) - .unwrap(); - // Calculate chunk/codec concurrency let chunk_representation = self.chunk_array_representation(&vec![0; self.dimensionality()])?; @@ -574,84 +576,109 @@ impl Array { &codec_concurrency, ); - // let mut output = vec![0; size_output]; - // let output_slice = output.as_mut_slice(); - let mut output = Vec::with_capacity(size_output); - { - let output = UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut output); - let retrieve_chunk = |chunk_indices: Vec| { - let options = options.clone(); - async move { - let chunk_subset = self.chunk_subset(&chunk_indices)?; - let chunk_subset_overlap = chunk_subset.overlap(array_subset)?; - let chunk_subset_bytes = self - .async_retrieve_chunk_subset_opt( - &chunk_indices, - &chunk_subset_overlap.relative_to(chunk_subset.start())?, - &options, + match chunk_representation.data_type().size() { + DataTypeSize::Variable => { + let retrieve_chunk = |chunk_indices: Vec| { + let options = options.clone(); + async move { + let chunk_subset = self.chunk_subset(&chunk_indices)?; + let chunk_subset_overlap = chunk_subset.overlap(array_subset)?; + Ok::<_, ArrayError>(( + self.async_retrieve_chunk_subset_opt( + &chunk_indices, + &chunk_subset_overlap.relative_to(chunk_subset.start())?, + &options, + ) + .await?, + chunk_subset_overlap.relative_to(array_subset.start())?, + )) + } + }; + + // TODO: chunk_concurrent_limit + let chunk_bytes_and_subsets = futures::future::try_join_all( + chunks.indices().iter().map(retrieve_chunk), + ) + .await?; + + Ok(merge_chunks_vlen( + chunk_bytes_and_subsets, + array_subset.shape(), + )?) + } + DataTypeSize::Fixed(data_type_size) => { + let size_output = + usize::try_from(array_subset.num_elements() * data_type_size as u64) + .unwrap(); + let mut output = Vec::with_capacity(size_output); + { + let output = + UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut output); + let retrieve_chunk = |chunk_indices: Vec| { + let options = options.clone(); + async move { + let chunk_subset = self.chunk_subset(&chunk_indices)?; + let chunk_subset_overlap = + chunk_subset.overlap(array_subset)?; + let chunk_subset_bytes = self + .async_retrieve_chunk_subset_opt( + &chunk_indices, + &chunk_subset_overlap + .relative_to(chunk_subset.start())?, + &options, + ) + .await?; + let chunk_subset_bytes = chunk_subset_bytes.into_fixed()?; + let output = unsafe { output.get() }; + update_bytes_flen( + output, + array_subset.shape(), + &chunk_subset_bytes, + &chunk_subset_overlap.relative_to(array_subset.start())?, + data_type_size, + ); + Ok::<_, ArrayError>(()) + } + }; + + futures::stream::iter(&chunks.indices()) + .map(Ok) + .try_for_each_concurrent( + Some(chunk_concurrent_limit), + retrieve_chunk, ) .await?; - let contiguous_indices = unsafe { - chunk_subset_overlap - .relative_to(array_subset.start())? - .contiguous_linearised_indices_unchecked(array_subset.shape()) - }; - let element_size = self.data_type().size(); - let length = - contiguous_indices.contiguous_elements_usize() * element_size; - let mut decoded_offset = 0; - // FIXME: Par iteration? - let output = unsafe { output.get() }; - for (array_subset_element_index, _num_elements) in &contiguous_indices { - let output_offset = usize::try_from(array_subset_element_index) - .unwrap() - * element_size; - debug_assert!((output_offset + length) <= output.len()); - debug_assert!( - (decoded_offset + length) <= chunk_subset_bytes.len() - ); - output[output_offset..output_offset + length].copy_from_slice( - &chunk_subset_bytes[decoded_offset..decoded_offset + length], - ); - decoded_offset += length; - } - Ok::<_, ArrayError>(()) } - }; - futures::stream::iter(&chunks.indices()) - .map(Ok) - .try_for_each_concurrent(Some(chunk_concurrent_limit), retrieve_chunk) - .await?; + unsafe { output.set_len(size_output) }; + Ok(ArrayBytes::from(output)) + } } - unsafe { output.set_len(size_output) }; - Ok(output) } } } /// Async variant of [`retrieve_array_subset_elements_opt`](Array::retrieve_array_subset_elements_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_array_subset_elements_opt( + pub async fn async_retrieve_array_subset_elements_opt( &self, array_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; let bytes = self .async_retrieve_array_subset_opt(array_subset, options) .await?; - Ok(transmute_from_bytes_vec::(bytes)) + let elements = T::from_array_bytes(self.data_type(), bytes)?; + Ok(elements) } #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_array_subset_ndarray_opt`](Array::retrieve_array_subset_ndarray_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_array_subset_ndarray_opt( + pub async fn async_retrieve_array_subset_ndarray_opt( &self, array_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - // validate_element_size::(self.data_type())?; // in async_retrieve_array_subset_elements let elements = self .async_retrieve_array_subset_elements_opt(array_subset, options) .await?; @@ -665,7 +692,7 @@ impl Array { chunk_indices: &[u64], chunk_subset: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { let chunk_representation = self.chunk_array_representation(chunk_indices)?; if !chunk_subset.inbounds(&chunk_representation.shape_u64()) { return Err(ArrayError::InvalidArraySubset( @@ -683,52 +710,42 @@ impl Array { data_key(self.path(), chunk_indices, self.chunk_key_encoding()), )); - let partial_decoder = self + let bytes = self .codecs() .async_partial_decoder(input_handle, &chunk_representation, options) - .await?; - let decoded_bytes = partial_decoder + .await? .partial_decode_opt(&[chunk_subset.clone()], options) .await? - .pop() - .unwrap(); - - let expected_size = chunk_subset.num_elements_usize() * self.data_type().size(); - if decoded_bytes.len() == chunk_subset.num_elements_usize() * self.data_type().size() { - Ok(decoded_bytes.into_owned()) - } else { - Err(ArrayError::UnexpectedChunkDecodedSize( - decoded_bytes.len(), - expected_size, - )) - } + .remove(0) + .into_owned(); + bytes.validate(chunk_subset.num_elements(), self.data_type().size())?; + Ok(bytes) } /// Async variant of [`retrieve_chunk_subset_elements_opt`](Array::retrieve_chunk_subset_elements_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunk_subset_elements_opt( + pub async fn async_retrieve_chunk_subset_elements_opt( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; let bytes = self .async_retrieve_chunk_subset_opt(chunk_indices, chunk_subset, options) .await?; - Ok(transmute_from_bytes_vec::(bytes)) + let elements = T::from_array_bytes(self.data_type(), bytes)?; + Ok(elements) } #[cfg(feature = "ndarray")] /// Async variant of [`retrieve_chunk_subset_ndarray_opt`](Array::retrieve_chunk_subset_ndarray_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_retrieve_chunk_subset_ndarray_opt( + pub async fn async_retrieve_chunk_subset_ndarray_opt( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - // validate_element_size::(self.data_type())?; // in async_retrieve_chunk_subset_elements let elements = self .async_retrieve_chunk_subset_elements_opt(chunk_indices, chunk_subset, options) .await?; diff --git a/src/array/array_async_readable_writable.rs b/src/array/array_async_readable_writable.rs index 575c7cd8..bf948731 100644 --- a/src/array/array_async_readable_writable.rs +++ b/src/array/array_async_readable_writable.rs @@ -1,22 +1,22 @@ use futures::{StreamExt, TryStreamExt}; use crate::{ - array::validate_element_size, array_subset::ArraySubset, - storage::AsyncReadableWritableStorageTraits, + array::ArrayBytes, array_subset::ArraySubset, storage::AsyncReadableWritableStorageTraits, }; use super::{ - codec::options::CodecOptions, concurrency::concurrency_chunks_and_codec, Array, ArrayError, + array_bytes::update_array_bytes, codec::options::CodecOptions, + concurrency::concurrency_chunks_and_codec, Array, ArrayError, Element, }; impl Array { /// Async variant of [`store_chunk_subset`](Array::store_chunk_subset). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_store_chunk_subset( + pub async fn async_store_chunk_subset<'a>( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - chunk_subset_bytes: &[u8], + chunk_subset_bytes: impl Into>, ) -> Result<(), ArrayError> { self.async_store_chunk_subset_opt( chunk_indices, @@ -29,7 +29,7 @@ impl Array( + pub async fn async_store_chunk_subset_elements( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, @@ -48,7 +48,7 @@ impl Array> + Send, D: ndarray::Dimension, >( @@ -68,10 +68,10 @@ impl Array( &self, array_subset: &ArraySubset, - subset_bytes: &[u8], + subset_bytes: impl Into>, ) -> Result<(), ArrayError> { self.async_store_array_subset_opt(array_subset, subset_bytes, &CodecOptions::default()) .await @@ -79,7 +79,7 @@ impl Array( + pub async fn async_store_array_subset_elements( &self, array_subset: &ArraySubset, subset_elements: &[T], @@ -96,7 +96,7 @@ impl Array> + Send, D: ndarray::Dimension, >( @@ -118,11 +118,11 @@ impl Array( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - chunk_subset_bytes: &[u8], + chunk_subset_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { let chunk_shape = self @@ -138,75 +138,58 @@ impl Array() * self.data_type().size() as u64; - if chunk_subset_bytes.len() as u64 != expected_length { - return Err(ArrayError::InvalidBytesInputSize( - chunk_subset_bytes.len(), - expected_length, - )); - } if chunk_subset.shape() == chunk_shape && chunk_subset.start().iter().all(|&x| x == 0) { // The subset spans the whole chunk, so store the bytes directly and skip decoding self.async_store_chunk_opt(chunk_indices, chunk_subset_bytes, options) .await } else { + let chunk_subset_bytes = chunk_subset_bytes.into(); + chunk_subset_bytes.validate(chunk_subset.num_elements(), self.data_type().size())?; + // Lock the chunk // let key = data_key(self.path(), chunk_indices, self.chunk_key_encoding()); // let mutex = self.storage.mutex(&key).await?; // let _lock = mutex.lock(); // Decode the entire chunk - let mut chunk_bytes = self + let chunk_bytes_old = self .async_retrieve_chunk_opt(chunk_indices, options) .await?; - // Update the intersecting subset of the chunk - let element_size = self.data_type().size(); - let mut offset = 0; - let contiguous_indices = - unsafe { chunk_subset.contiguous_linearised_indices_unchecked(&chunk_shape) }; - let length = contiguous_indices.contiguous_elements_usize() * element_size; - for (chunk_element_index, _num_elements) in &contiguous_indices { - let chunk_offset = usize::try_from(chunk_element_index).unwrap() * element_size; - debug_assert!(chunk_offset + length <= chunk_bytes.len()); - debug_assert!(offset + length <= chunk_subset_bytes.len()); - chunk_bytes[chunk_offset..chunk_offset + length] - .copy_from_slice(&chunk_subset_bytes[offset..offset + length]); - offset += length; - } + // Update the chunk + let chunk_bytes_new = update_array_bytes( + chunk_bytes_old, + chunk_shape, + chunk_subset_bytes, + chunk_subset, + self.data_type().size(), + ); // Store the updated chunk - self.async_store_chunk_opt(chunk_indices, &chunk_bytes, options) + self.async_store_chunk_opt(chunk_indices, chunk_bytes_new, options) .await } } /// Async variant of [`store_chunk_subset_elements_opt`](Array::store_chunk_subset_elements_opt). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub async fn async_store_chunk_subset_elements_opt( + pub async fn async_store_chunk_subset_elements_opt( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, chunk_subset_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let chunk_subset_elements = crate::array::transmute_to_bytes(chunk_subset_elements); - self.async_store_chunk_subset_opt( - chunk_indices, - chunk_subset, - chunk_subset_elements, - options, - ) - .await + let chunk_subset_bytes = T::into_array_bytes(self.data_type(), chunk_subset_elements)?; + self.async_store_chunk_subset_opt(chunk_indices, chunk_subset, chunk_subset_bytes, options) + .await } /// Async variant of [`store_chunk_subset_ndarray_opt`](Array::store_chunk_subset_ndarray_opt). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] pub async fn async_store_chunk_subset_ndarray_opt< - T: bytemuck::Pod + Send + Sync, + T: Element + Send + Sync, TArray: Into> + Send, D: ndarray::Dimension, >( @@ -216,7 +199,6 @@ impl Array Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let chunk_subset_array: ndarray::Array = chunk_subset_array.into(); let subset = ArraySubset::new_with_start_shape( chunk_subset_start.to_vec(), @@ -239,10 +221,10 @@ impl Array( &self, array_subset: &ArraySubset, - subset_bytes: &[u8], + subset_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { // Validation @@ -252,13 +234,6 @@ impl Array Array Array| { - let chunk_subset_in_array = unsafe { - self.chunk_grid() - .subset_unchecked(&chunk_indices, self.shape()) - .unwrap() - }; - let overlap = unsafe { array_subset.overlap_unchecked(&chunk_subset_in_array) }; + let chunk_subset = self.chunk_subset(&chunk_indices).unwrap(); // FIXME: unwrap + let overlap = unsafe { array_subset.overlap_unchecked(&chunk_subset) }; let chunk_subset_in_array_subset = unsafe { overlap.relative_to_unchecked(array_subset.start()) }; let array_subset_in_chunk_subset = - unsafe { overlap.relative_to_unchecked(chunk_subset_in_array.start()) }; - let chunk_subset_bytes = unsafe { - chunk_subset_in_array_subset.extract_bytes_unchecked( - subset_bytes, + unsafe { overlap.relative_to_unchecked(chunk_subset.start()) }; + let chunk_subset_bytes = subset_bytes + .extract_array_subset( + &chunk_subset_in_array_subset, array_subset.shape(), - self.data_type().size(), + self.data_type(), ) - }; + .unwrap(); // FIXME: unwrap let options = options.clone(); async move { self.async_store_chunk_subset_opt( &chunk_indices, &array_subset_in_chunk_subset, - &chunk_subset_bytes, + chunk_subset_bytes, &options, ) .await @@ -356,15 +313,14 @@ impl Array( + pub async fn async_store_array_subset_elements_opt( &self, array_subset: &ArraySubset, subset_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let subset_elements = crate::array::transmute_to_bytes(subset_elements); - self.async_store_array_subset_opt(array_subset, subset_elements, options) + let subset_bytes = T::into_array_bytes(self.data_type(), subset_elements)?; + self.async_store_array_subset_opt(array_subset, subset_bytes, options) .await } @@ -372,7 +328,7 @@ impl Array> + Send, D: ndarray::Dimension, >( @@ -381,7 +337,6 @@ impl Array Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let subset_array: ndarray::Array = subset_array.into(); let subset = ArraySubset::new_with_start_shape( subset_start.to_vec(), diff --git a/src/array/array_async_writable.rs b/src/array/array_async_writable.rs index 2e4701f4..cb22ee5c 100644 --- a/src/array/array_async_writable.rs +++ b/src/array/array_async_writable.rs @@ -1,9 +1,9 @@ -use std::{borrow::Cow, sync::Arc}; +use std::sync::Arc; use futures::{StreamExt, TryStreamExt}; use crate::{ - array::validate_element_size, + array::ArrayBytes, array_subset::ArraySubset, metadata::MetadataEraseVersion, storage::{ @@ -13,9 +13,9 @@ use crate::{ }; use super::{ - codec::{options::CodecOptions, ArrayCodecTraits}, + codec::{options::CodecOptions, ArrayToBytesCodecTraits}, concurrency::concurrency_chunks_and_codec, - Array, ArrayError, ArrayMetadata, ArrayMetadataOptions, + Array, ArrayError, ArrayMetadata, ArrayMetadataOptions, Element, }; impl Array { @@ -44,10 +44,10 @@ impl Array { /// Async variant of [`store_chunk`](Array::store_chunk). #[allow(clippy::missing_errors_doc)] - pub async fn async_store_chunk( + pub async fn async_store_chunk<'a>( &self, chunk_indices: &[u64], - chunk_bytes: &[u8], + chunk_bytes: impl Into>, ) -> Result<(), ArrayError> { self.async_store_chunk_opt(chunk_indices, chunk_bytes, &CodecOptions::default()) .await @@ -55,7 +55,7 @@ impl Array { /// Async variant of [`store_chunk_elements`](Array::store_chunk_elements). #[allow(clippy::missing_errors_doc)] - pub async fn async_store_chunk_elements( + pub async fn async_store_chunk_elements( &self, chunk_indices: &[u64], chunk_elements: &[T], @@ -68,7 +68,7 @@ impl Array { /// Async variant of [`store_chunk_ndarray`](Array::store_chunk_ndarray). #[allow(clippy::missing_errors_doc)] pub async fn async_store_chunk_ndarray< - T: bytemuck::Pod + Send + Sync, + T: Element + Send + Sync, TArray: Into> + Send, D: ndarray::Dimension, >( @@ -83,10 +83,10 @@ impl Array { /// Async variant of [`store_chunks`](Array::store_chunks). #[allow(clippy::missing_errors_doc)] #[allow(clippy::similar_names)] - pub async fn async_store_chunks( + pub async fn async_store_chunks<'a>( &self, chunks: &ArraySubset, - chunks_bytes: &[u8], + chunks_bytes: impl Into>, ) -> Result<(), ArrayError> { self.async_store_chunks_opt(chunks, chunks_bytes, &CodecOptions::default()) .await @@ -94,7 +94,7 @@ impl Array { /// Async variant of [`store_chunks_elements`](Array::store_chunks_elements). #[allow(clippy::missing_errors_doc)] - pub async fn async_store_chunks_elements( + pub async fn async_store_chunks_elements( &self, chunks: &ArraySubset, chunks_elements: &[T], @@ -107,7 +107,7 @@ impl Array { /// Async variant of [`store_chunks_ndarray`](Array::store_chunks_ndarray). #[allow(clippy::missing_errors_doc)] pub async fn async_store_chunks_ndarray< - T: bytemuck::Pod + Send + Sync, + T: Element + Send + Sync, TArray: Into> + Send, D: ndarray::Dimension, >( @@ -213,24 +213,25 @@ impl Array { /// Async variant of [`store_chunk_opt`](Array::store_chunk_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_store_chunk_opt( + pub async fn async_store_chunk_opt<'a>( &self, chunk_indices: &[u64], - chunk_bytes: &[u8], + chunk_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { + let chunk_bytes = chunk_bytes.into(); + // Validation let chunk_array_representation = self.chunk_array_representation(chunk_indices)?; - if chunk_bytes.len() as u64 != chunk_array_representation.size() { - return Err(ArrayError::InvalidBytesInputSize( - chunk_bytes.len(), - chunk_array_representation.size(), - )); - } + chunk_bytes.validate( + chunk_array_representation.num_elements(), + chunk_array_representation.data_type().size(), + )?; - if !options.store_empty_chunks() && self.fill_value().equals_all(chunk_bytes) { + let is_fill_value = + !options.store_empty_chunks() && chunk_bytes.is_fill_value(self.fill_value()); + if is_fill_value { self.async_erase_chunk(chunk_indices).await?; - Ok(()) } else { let storage_handle = Arc::new(StorageHandle::new(self.storage.clone())); let storage_transformer = self @@ -238,11 +239,7 @@ impl Array { .create_async_writable_transformer(storage_handle); let chunk_encoded = self .codecs() - .encode( - Cow::Borrowed(chunk_bytes), - &chunk_array_representation, - options, - ) + .encode(chunk_bytes, &chunk_array_representation, options) .map_err(ArrayError::CodecError)?; let chunk_encoded = AsyncBytes::from(chunk_encoded.to_vec()); crate::storage::async_store_chunk( @@ -252,22 +249,21 @@ impl Array { self.chunk_key_encoding(), chunk_encoded, ) - .await - .map_err(ArrayError::StorageError) + .await?; } + Ok(()) } /// Async variant of [`store_chunk_elements_opt`](Array::store_chunk_elements_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_store_chunk_elements_opt( + pub async fn async_store_chunk_elements_opt( &self, chunk_indices: &[u64], chunk_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let chunk_elements = crate::array::transmute_to_bytes(chunk_elements); - self.async_store_chunk_opt(chunk_indices, chunk_elements, options) + let bytes = T::into_array_bytes(self.data_type(), chunk_elements)?; + self.async_store_chunk_opt(chunk_indices, bytes, options) .await } @@ -275,7 +271,7 @@ impl Array { /// Async variant of [`store_chunk_ndarray_opt`](Array::store_chunk_ndarray_opt). #[allow(clippy::missing_errors_doc)] pub async fn async_store_chunk_ndarray_opt< - T: bytemuck::Pod + Send + Sync, + T: Element + Send + Sync, TArray: Into> + Send, D: ndarray::Dimension, >( @@ -284,7 +280,6 @@ impl Array { chunk_array: TArray, options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let chunk_array: ndarray::Array = chunk_array.into(); let chunk_shape = self.chunk_shape_usize(chunk_indices)?; if chunk_array.shape() == chunk_shape { @@ -302,30 +297,27 @@ impl Array { /// Async variant of [`store_chunks_opt`](Array::store_chunks_opt). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] #[allow(clippy::similar_names)] - pub async fn async_store_chunks_opt( + pub async fn async_store_chunks_opt<'a>( &self, chunks: &ArraySubset, - chunks_bytes: &[u8], + chunks_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { let num_chunks = chunks.num_elements_usize(); match num_chunks { - 0 => {} + 0 => { + let chunks_bytes = chunks_bytes.into(); + chunks_bytes.validate(0, self.data_type().size())?; + } 1 => { let chunk_indices = chunks.start(); self.async_store_chunk_opt(chunk_indices, chunks_bytes, options) .await?; } _ => { + let chunks_bytes = chunks_bytes.into(); let array_subset = self.chunks_subset(chunks)?; - let element_size = self.data_type().size(); - let expected_size = element_size as u64 * array_subset.num_elements(); - if chunks_bytes.len() as u64 != expected_size { - return Err(ArrayError::InvalidBytesInputSize( - chunks_bytes.len(), - expected_size, - )); - } + chunks_bytes.validate(array_subset.num_elements(), self.data_type().size())?; // Calculate chunk/codec concurrency let chunk_representation = @@ -340,30 +332,17 @@ impl Array { ); let store_chunk = |chunk_indices: Vec| { - let chunk_subset_in_array = unsafe { - self.chunk_grid() - .subset_unchecked(&chunk_indices, self.shape()) - .unwrap() // FIXME: Unwrap - }; - let overlap = unsafe { array_subset.overlap_unchecked(&chunk_subset_in_array) }; - let chunk_subset_in_array_subset = - unsafe { overlap.relative_to_unchecked(array_subset.start()) }; - let chunk_bytes = unsafe { - chunk_subset_in_array_subset.extract_bytes_unchecked( - chunks_bytes, + let chunk_subset = self.chunk_subset(&chunk_indices).unwrap(); // FIXME: unwrap + let chunk_bytes = chunks_bytes + .extract_array_subset( + &chunk_subset.relative_to(array_subset.start()).unwrap(), // FIXME: unwrap array_subset.shape(), - element_size, + self.data_type(), ) - }; - - debug_assert_eq!( - chunk_subset_in_array.num_elements(), - chunk_subset_in_array_subset.num_elements() - ); - + .unwrap(); // FIXME: unwrap let options = options.clone(); async move { - self.async_store_chunk_opt(&chunk_indices, &chunk_bytes, &options) + self.async_store_chunk_opt(&chunk_indices, chunk_bytes, &options) .await } }; @@ -379,15 +358,14 @@ impl Array { /// Async variant of [`store_chunks_elements_opt`](Array::store_chunks_elements_opt). #[allow(clippy::missing_errors_doc)] - pub async fn async_store_chunks_elements_opt( + pub async fn async_store_chunks_elements_opt( &self, chunks: &ArraySubset, chunks_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let chunks_elements = crate::array::transmute_to_bytes(chunks_elements); - self.async_store_chunks_opt(chunks, chunks_elements, options) + let chunks_bytes = T::into_array_bytes(self.data_type(), chunks_elements)?; + self.async_store_chunks_opt(chunks, chunks_bytes, options) .await } @@ -395,7 +373,7 @@ impl Array { /// Async variant of [`store_chunks_ndarray_opt`](Array::store_chunks_ndarray_opt). #[allow(clippy::missing_errors_doc)] pub async fn async_store_chunks_ndarray_opt< - T: bytemuck::Pod + Send + Sync, + T: Element + Send + Sync, TArray: Into> + Send, D: ndarray::Dimension, >( @@ -404,7 +382,6 @@ impl Array { chunks_array: TArray, options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let chunks_array: ndarray::Array = chunks_array.into(); let chunks_subset = self.chunks_subset(chunks)?; let chunks_shape = chunks_subset.shape_usize(); diff --git a/src/array/array_builder.rs b/src/array/array_builder.rs index cc74e11c..255b8def 100644 --- a/src/array/array_builder.rs +++ b/src/array/array_builder.rs @@ -5,7 +5,8 @@ use crate::{metadata::v3::AdditionalFields, node::NodePath, storage::StorageTran use super::{ chunk_key_encoding::{ChunkKeyEncoding, DefaultChunkKeyEncoding}, codec::{ - ArrayToArrayCodecTraits, ArrayToBytesCodecTraits, BytesCodec, BytesToBytesCodecTraits, + array_to_bytes::vlen::VlenCodec, ArrayToArrayCodecTraits, ArrayToBytesCodecTraits, + BytesCodec, BytesToBytesCodecTraits, }, data_type::IncompatibleFillValueError, Array, ArrayCreateError, ArrayMetadata, ArrayMetadataV3, ArrayShape, ChunkGrid, @@ -93,6 +94,7 @@ impl ArrayBuilder { chunk_grid: ChunkGrid, fill_value: FillValue, ) -> Self { + let is_fixed_size = data_type.fixed_size().is_some(); Self { shape, data_type, @@ -100,7 +102,12 @@ impl ArrayBuilder { chunk_key_encoding: ChunkKeyEncoding::new(DefaultChunkKeyEncoding::default()), fill_value, array_to_array_codecs: Vec::default(), - array_to_bytes_codec: Box::::default(), + array_to_bytes_codec: if is_fixed_size { + Box::::default() + } else { + Box::::default() + // Box::::default() + }, bytes_to_bytes_codecs: Vec::default(), attributes: serde_json::Map::default(), storage_transformers: StorageTransformerChain::default(), @@ -287,12 +294,15 @@ impl ArrayBuilder { )); } } - if self.data_type.size() != self.fill_value.size() { - return Err(IncompatibleFillValueError::new( - self.data_type.name(), - self.fill_value.clone(), - ) - .into()); + + if let Some(data_type_size) = self.data_type.fixed_size() { + if data_type_size != self.fill_value.size() { + return Err(IncompatibleFillValueError::new( + self.data_type.name(), + self.fill_value.clone(), + ) + .into()); + } } let codec_chain = CodecChain::new( diff --git a/src/array/array_bytes.rs b/src/array/array_bytes.rs new file mode 100644 index 00000000..0cd34ea8 --- /dev/null +++ b/src/array/array_bytes.rs @@ -0,0 +1,609 @@ +use std::borrow::Cow; + +use itertools::Itertools; +use thiserror::Error; + +use crate::{ + array_subset::{ArraySubset, IncompatibleArraySubsetAndShapeError}, + byte_range::extract_byte_ranges_concat_unchecked, +}; + +use super::{ + codec::CodecError, ravel_indices, ArrayShape, ArraySize, DataType, DataTypeSize, FillValue, +}; + +/// Array element bytes. +pub type RawBytes<'a> = Cow<'a, [u8]>; + +/// Array element byte offsets. +pub type RawBytesOffsets<'a> = Cow<'a, [usize]>; + +/// Fixed or variable length array bytes. +/// +/// Offsets are [`None`] if bytes are composed of fixed size data types. +#[derive(Clone, Debug, PartialEq)] +pub enum ArrayBytes<'a> { + /// Bytes for a fixed length array. + Fixed(RawBytes<'a>), + /// Bytes and element byte offsets for a variable length array. + Variable(RawBytes<'a>, RawBytesOffsets<'a>), +} + +/// Errors related to [`ArrayBytes<'_>`] and [`ArrayBytes`]. +#[derive(Debug, Error)] +pub enum ArrayBytesError { + /// Invalid use of a fixed length method. + #[error("Used a fixed length (flen) method on a variable length (vlen) array")] + UsedFixedLengthMethodOnVariableLengthArray, +} + +impl<'a> ArrayBytes<'a> { + /// Create a new fixed length array bytes from `bytes`. + pub fn new_flen(bytes: impl Into>) -> Self { + Self::Fixed(bytes.into()) + } + + /// Create a new variable length array bytes from `bytes` and `offsets`. + pub fn new_vlen( + bytes: impl Into>, + offsets: impl Into>, + ) -> Self { + Self::Variable(bytes.into(), offsets.into()) + } + + /// Create a new [`ArrayBytes`] with `num_elements` composed entirely of the `fill_value`. + /// + /// # Panics + /// Panics if the number of elements in `array_size` exceeds [`usize::MAX`]. + #[must_use] + pub fn new_fill_value(array_size: ArraySize, fill_value: &FillValue) -> Self { + match array_size { + ArraySize::Fixed { + num_elements, + data_type_size: _, + } => { + let num_elements = usize::try_from(num_elements).unwrap(); + Self::new_flen(fill_value.as_ne_bytes().repeat(num_elements)) + } + ArraySize::Variable { num_elements } => { + let num_elements = usize::try_from(num_elements).unwrap(); + Self::new_vlen( + fill_value.as_ne_bytes().repeat(num_elements), + (0..=num_elements) + .map(|i| i * fill_value.size()) + .collect::>(), + ) + } + } + } + + /// Convert the array bytes into fixed size bytes. + /// + /// # Errors + /// Returns a [`CodecError::ExpectedFixedLengthBytes`] if the bytes are variable length. + pub fn into_fixed(self) -> Result, CodecError> { + match self { + Self::Fixed(bytes) => Ok(bytes), + Self::Variable(_, _) => Err(CodecError::ExpectedFixedLengthBytes), + } + } + + /// Convert the array bytes into variable sized bytes and element byte offsets. + /// + /// # Errors + /// Returns a [`CodecError::ExpectedVariableLengthBytes`] if the bytes are fixed length. + pub fn into_variable(self) -> Result<(RawBytes<'a>, RawBytesOffsets<'a>), CodecError> { + match self { + Self::Fixed(_) => Err(CodecError::ExpectedVariableLengthBytes), + Self::Variable(bytes, offsets) => Ok((bytes, offsets)), + } + } + + /// Returns the size (in bytes) of the underlying element bytes. + /// + /// This only considers the size of the element bytes, and does not include the elemenet offsets for a variable sized array. + #[must_use] + pub fn size(&self) -> usize { + match self { + Self::Fixed(bytes) | Self::Variable(bytes, _) => bytes.len(), + } + } + + /// Return the byte offsets for variable sized bytes. Returns [`None`] for fixed size bytes. + #[must_use] + pub fn offsets(&self) -> Option<&RawBytesOffsets<'a>> { + match self { + Self::Fixed(_) => None, + Self::Variable(_, offsets) => Some(offsets), + } + } + + /// Convert into owned [`ArrayBytes<'_>`]. + #[must_use] + pub fn into_owned<'b>(self) -> ArrayBytes<'b> { + match self { + Self::Fixed(bytes) => ArrayBytes::<'b>::new_flen(bytes.into_owned()), + Self::Variable(bytes, offsets) => { + ArrayBytes::<'b>::new_vlen(bytes.into_owned(), offsets.into_owned()) + } + } + } + + /// Validate that the array has a valid encoding. + /// + /// For a fixed-length array, check it matches the expected size. + /// For a variable-length array, check that the offsets are monotonically increasing and the largest offset is equal to the array length. + /// Always returns without error for an array with fixed-length data. + /// + /// # Errors + /// Returns an error if the array is not valid. + pub fn validate( + &self, + num_elements: u64, + data_type_size: DataTypeSize, + ) -> Result<(), CodecError> { + validate_bytes(self, num_elements, data_type_size) + } + + /// Returns [`true`] if the array is empty for the given fill value. + #[must_use] + pub fn is_fill_value(&self, fill_value: &FillValue) -> bool { + match self { + Self::Fixed(bytes) => fill_value.equals_all(bytes), + Self::Variable(bytes, _offsets) => fill_value.equals_all(bytes), + } + } + + /// Extract a subset of the array bytes. + /// + /// # Errors + /// Returns a [`CodecError::InvalidArraySubsetError`] if the `array_shape` is incompatible with `subset`. + /// + /// # Panics + /// Panics if indices in the subset exceed [`usize::MAX`]. + pub fn extract_array_subset( + &self, + subset: &ArraySubset, + array_shape: &[u64], + data_type: &DataType, + ) -> Result, CodecError> { + match self { + ArrayBytes::Variable(bytes, offsets) => { + let indices = subset.linearised_indices(array_shape).map_err(|_| { + IncompatibleArraySubsetAndShapeError::new(subset.clone(), array_shape.to_vec()) + })?; + let mut bytes_length = 0; + for index in &indices { + let index = usize::try_from(index).unwrap(); + let curr = offsets[index]; + let next = offsets[index + 1]; + debug_assert!(next >= curr); + bytes_length += next - curr; + } + let mut ss_bytes = Vec::with_capacity(bytes_length); + let mut ss_offsets = Vec::with_capacity(1 + indices.len()); + for index in &indices { + let index = usize::try_from(index).unwrap(); + let curr = offsets[index]; + let next = offsets[index + 1]; + ss_offsets.push(ss_bytes.len()); + ss_bytes.extend_from_slice(&bytes[curr..next]); + } + ss_offsets.push(ss_bytes.len()); + Ok(ArrayBytes::new_vlen(ss_bytes, ss_offsets)) + } + ArrayBytes::Fixed(bytes) => { + let byte_ranges = + subset.byte_ranges(array_shape, data_type.fixed_size().unwrap())?; + let bytes = unsafe { extract_byte_ranges_concat_unchecked(bytes, &byte_ranges) }; + Ok(ArrayBytes::new_flen(bytes)) + } + } + } +} + +/// Validate fixed length array bytes for a given array size. +fn validate_bytes_flen(bytes: &RawBytes, array_size: u64) -> Result<(), CodecError> { + if bytes.len() as u64 == array_size { + Ok(()) + } else { + Err(CodecError::UnexpectedChunkDecodedSize( + bytes.len(), + array_size, + )) + } +} + +/// Validate variable length array bytes for an array with `num_elements`. +fn validate_bytes_vlen( + bytes: &RawBytes, + offsets: &RawBytesOffsets, + num_elements: u64, +) -> Result<(), CodecError> { + if offsets.len() as u64 != num_elements + 1 { + return Err(CodecError::InvalidVariableSizedArrayOffsets); + } + let len = bytes.len(); + let mut offset_last = 0; + for offset in offsets.iter() { + if *offset < offset_last || *offset > len { + return Err(CodecError::InvalidVariableSizedArrayOffsets); + } + offset_last = *offset; + } + if offset_last == len { + Ok(()) + } else { + Err(CodecError::InvalidVariableSizedArrayOffsets) + } +} + +/// Validate array bytes. +fn validate_bytes( + bytes: &ArrayBytes<'_>, + num_elements: u64, + data_type_size: DataTypeSize, +) -> Result<(), CodecError> { + match (bytes, data_type_size) { + (ArrayBytes::Fixed(bytes), DataTypeSize::Fixed(data_type_size)) => { + validate_bytes_flen(bytes, num_elements * data_type_size as u64) + } + (ArrayBytes::Variable(bytes, offsets), DataTypeSize::Variable) => { + validate_bytes_vlen(bytes, offsets, num_elements) + } + (ArrayBytes::Fixed(_), DataTypeSize::Variable) => Err(CodecError::Other( + "Used fixed length array bytes with a variable sized data type.".to_string(), + )), + (ArrayBytes::Variable(_, _), DataTypeSize::Fixed(_)) => Err(CodecError::Other( + "Used variable length array bytes with a fixed length data type.".to_string(), + )), + } +} + +/// This function is used internally by various array/codec methods to write the bytes of a chunk subset into an output with an associated array subset. +/// This approach only works for fixed length data types. +pub(crate) fn update_bytes_flen( + output_bytes: &mut [u8], + output_shape: &[u64], + subset_bytes: &RawBytes, + subset: &ArraySubset, + data_type_size: usize, +) { + debug_assert_eq!( + output_bytes.len(), + usize::try_from(output_shape.iter().product::()).unwrap() * data_type_size + ); + debug_assert_eq!( + subset_bytes.len(), + subset.num_elements_usize() * data_type_size, + ); + + let contiguous_indices = + unsafe { subset.contiguous_linearised_indices_unchecked(output_shape) }; + let length = contiguous_indices.contiguous_elements_usize() * data_type_size; + let mut decoded_offset = 0; + // TODO: Par iteration? + for (array_subset_element_index, _num_elements) in &contiguous_indices { + let output_offset = usize::try_from(array_subset_element_index).unwrap() * data_type_size; + debug_assert!((output_offset + length) <= output_bytes.len()); + debug_assert!((decoded_offset + length) <= subset_bytes.len()); + output_bytes[output_offset..output_offset + length] + .copy_from_slice(&subset_bytes[decoded_offset..decoded_offset + length]); + decoded_offset += length; + } +} + +pub(crate) fn update_bytes_vlen<'a>( + output_bytes: &RawBytes, + output_offsets: &RawBytesOffsets, + output_shape: ArrayShape, + subset_bytes: &RawBytes, + subset_offsets: &RawBytesOffsets, + subset: &ArraySubset, +) -> ArrayBytes<'a> { + // Get the current and new length of the bytes in the chunk subset + let size_subset_new = { + let chunk_subset_indices = ArraySubset::new_with_shape(subset.shape().to_vec()) + .linearised_indices(subset.shape()) + .unwrap(); + chunk_subset_indices + .iter() + .map(|index| { + let index = usize::try_from(index).unwrap(); + subset_offsets[index + 1] - subset_offsets[index] + }) + .sum::() + }; + let size_subset_old = { + let chunk_indices = subset.linearised_indices(&output_shape).unwrap(); + chunk_indices + .iter() + .map(|index| { + let index = usize::try_from(index).unwrap(); + output_offsets[index + 1] - output_offsets[index] + }) + .sum::() + }; + + // Populate new offsets and bytes + let mut offsets_new = Vec::with_capacity(output_offsets.len()); + let bytes_new_len = (output_bytes.len() + size_subset_new) + .checked_sub(size_subset_old) + .unwrap(); + let mut bytes_new = Vec::with_capacity(bytes_new_len); + let indices = ArraySubset::new_with_shape(output_shape).indices(); + for (chunk_index, indices) in indices.iter().enumerate() { + offsets_new.push(bytes_new.len()); + if subset.contains(&indices) { + let subset_indices = indices + .iter() + .zip(subset.start()) + .map(|(i, s)| i - s) + .collect::>(); + let subset_index = + usize::try_from(ravel_indices(&subset_indices, subset.shape())).unwrap(); + let start = subset_offsets[subset_index]; + let end = subset_offsets[subset_index + 1]; + bytes_new.extend_from_slice(&subset_bytes[start..end]); + } else { + let start = output_offsets[chunk_index]; + let end = output_offsets[chunk_index + 1]; + bytes_new.extend_from_slice(&output_bytes[start..end]); + } + } + offsets_new.push(bytes_new.len()); + + ArrayBytes::new_vlen(bytes_new, offsets_new) +} + +/// Update the intersecting subset of the chunk +/// This function is used internally by [`store_chunk_subset_opt`] and [`async_store_chunk_subset_opt`] +pub(crate) fn update_array_bytes<'a>( + output_bytes: ArrayBytes, + output_shape: ArrayShape, + subset_bytes: ArrayBytes, + subset: &ArraySubset, + data_type_size: DataTypeSize, +) -> ArrayBytes<'a> { + match (output_bytes, subset_bytes, data_type_size) { + ( + ArrayBytes::Variable(chunk_bytes, chunk_offsets), + ArrayBytes::Variable(chunk_subset_bytes, chunk_subset_offsets), + DataTypeSize::Variable, + ) => update_bytes_vlen( + &chunk_bytes, + &chunk_offsets, + output_shape, + &chunk_subset_bytes, + &chunk_subset_offsets, + subset, + ), + ( + ArrayBytes::Fixed(chunk_bytes), + ArrayBytes::Fixed(chunk_subset_bytes), + DataTypeSize::Fixed(data_type_size), + ) => { + let mut chunk_bytes = chunk_bytes.into_owned(); + update_bytes_flen( + &mut chunk_bytes, + &output_shape, + &chunk_subset_bytes, + subset, + data_type_size, + ); + ArrayBytes::new_flen(chunk_bytes) + } + (_, _, _) => { + unreachable!("Validation should occur outside of this function") + } + } +} + +/// Merge a set of chunks into an array subset. +/// +/// This function is used internally by [`retrieve_array_subset_opt`] and [`async_retrieve_array_subset_opt`]. +pub(crate) fn merge_chunks_vlen<'a>( + chunk_bytes_and_subsets: Vec<(ArrayBytes<'_>, ArraySubset)>, + array_shape: &[u64], +) -> Result, CodecError> { + let num_elements = usize::try_from(array_shape.iter().product::()).unwrap(); + + #[cfg(debug_assertions)] + { + // Validate the input + let mut element_in_input = vec![0; num_elements]; + for (_, chunk_subset) in &chunk_bytes_and_subsets { + // println!("{chunk_subset:?}"); + let indices = chunk_subset.linearised_indices(array_shape).unwrap(); + for idx in &indices { + let idx = usize::try_from(idx).unwrap(); + element_in_input[idx] += 1; + } + } + assert!(element_in_input.iter().all(|v| *v == 1)); + } + + // Get the size of each element + // TODO: Go parallel + let mut element_sizes = vec![0; num_elements]; + for (chunk_bytes, chunk_subset) in &chunk_bytes_and_subsets { + let chunk_offsets = chunk_bytes.offsets().unwrap(); + debug_assert_eq!(chunk_offsets.len() as u64, chunk_subset.num_elements() + 1); + let indices = chunk_subset.linearised_indices(array_shape).unwrap(); + debug_assert_eq!(chunk_offsets.len(), indices.len() + 1); + for (subset_idx, (curr, next)) in indices.iter().zip(chunk_offsets.iter().tuple_windows()) { + debug_assert!(next >= curr); + let subset_idx = usize::try_from(subset_idx).unwrap(); + element_sizes[subset_idx] = next - curr; + } + } + + // Convert to offsets with a cumulative sum + // TODO: Parallel cum sum + let mut offsets = Vec::with_capacity(element_sizes.len() + 1); + offsets.push(0); // first offset is always zero + offsets.extend(element_sizes.iter().scan(0, |acc, &sz| { + *acc += sz; + Some(*acc) + })); + + // Write bytes + // TODO: Go parallel + let mut bytes = vec![0; *offsets.last().unwrap()]; + for (chunk_bytes, chunk_subset) in chunk_bytes_and_subsets { + let (chunk_bytes, chunk_offsets) = chunk_bytes.into_variable()?; + let indices = chunk_subset.linearised_indices(array_shape).unwrap(); + for (subset_idx, (&chunk_curr, &chunk_next)) in + indices.iter().zip(chunk_offsets.iter().tuple_windows()) + { + let subset_idx = usize::try_from(subset_idx).unwrap(); + let subset_curr = offsets[subset_idx]; + let subset_next = offsets[subset_idx + 1]; + bytes[subset_curr..subset_next].copy_from_slice(&chunk_bytes[chunk_curr..chunk_next]); + } + } + + Ok(ArrayBytes::new_vlen(bytes, offsets)) +} + +pub(crate) fn extract_decoded_regions_vlen<'a>( + bytes: &[u8], + offsets: &[usize], + decoded_regions: &[ArraySubset], + array_shape: &[u64], +) -> Result>, CodecError> { + let mut out = Vec::with_capacity(decoded_regions.len()); + for decoded_region in decoded_regions { + let indices = decoded_region.linearised_indices(array_shape)?; + let mut region_bytes_len = 0; + for index in &indices { + let index = usize::try_from(index).unwrap(); + let curr = offsets[index]; + let next = offsets[index + 1]; + debug_assert!(next >= curr); + region_bytes_len += next - curr; + } + let mut region_offsets = Vec::with_capacity(decoded_region.num_elements_usize() + 1); + let mut region_bytes = Vec::with_capacity(region_bytes_len); + for index in &indices { + region_offsets.push(region_bytes.len()); + let index = usize::try_from(index).unwrap(); + let curr = offsets[index]; + let next = offsets[index + 1]; + region_bytes.extend_from_slice(&bytes[curr..next]); + } + region_offsets.push(region_bytes.len()); + out.push(ArrayBytes::new_vlen(region_bytes, region_offsets)); + } + Ok(out) +} + +impl<'a> From> for ArrayBytes<'a> { + fn from(bytes: RawBytes<'a>) -> Self { + Self::new_flen(bytes) + } +} + +// impl<'a, 'b> From<&ArrayBytes<'a>> for ArrayBytes<'b> { +// fn from(bytes: &ArrayBytes<'a>) -> Self { +// match bytes { +// Self::Fixed(bytes) => { +// let bytes = bytes.to_vec(); +// ArrayBytes::<'b>::new_flen(bytes) +// }, +// Self::Variable(bytes, offsets) => { +// let bytes: RawBytes<'b> = bytes.to_vec().into(); +// let offsets: RawBytesOffsets<'b> = offsets.to_vec().into(); +// ArrayBytes::new_vlen(bytes, offsets) +// } +// } +// } +// } + +// impl<'a> From> for ArrayBytes<'a> { +// fn from(bytes: ArrayBytes<'_>) -> Self { +// match bytes { +// ArrayBytes::Fixed(bytes) => ArrayBytes::new_flen(bytes) +// ArrayBytes::Variable(bytes, offsets) => ArrayBytes::new_vlen(bytes, offsets) +// } +// } +// } + +impl<'a> From<&'a [u8]> for ArrayBytes<'a> { + fn from(bytes: &'a [u8]) -> Self { + ArrayBytes::new_flen(bytes) + } +} + +impl From> for ArrayBytes<'_> { + fn from(bytes: Vec) -> Self { + ArrayBytes::new_flen(bytes) + } +} + +impl<'a, const N: usize> From<&'a [u8; N]> for ArrayBytes<'a> { + fn from(bytes: &'a [u8; N]) -> Self { + // NOTE: as_slice() is needed for rust <1.77 + ArrayBytes::new_flen(bytes.as_slice()) + } +} + +#[cfg(test)] +mod tests { + use std::error::Error; + use std::mem::size_of; + + use crate::array::Element; + + use super::*; + + #[test] + fn array_bytes_flen() -> Result<(), Box> { + let data = [0u32, 1, 2, 3, 4]; + let bytes = Element::into_array_bytes(&DataType::UInt32, &data)?; + let ArrayBytes::Fixed(bytes) = bytes else { + panic!() + }; + assert_eq!(bytes.len(), size_of::() * data.len()); + + Ok(()) + } + + #[test] + fn array_bytes_str() -> Result<(), Box> { + let data = ["a", "bb", "ccc"]; + let bytes = Element::into_array_bytes(&DataType::String, &data)?; + let ArrayBytes::Variable(bytes, offsets) = bytes else { + panic!() + }; + assert_eq!(bytes, "abbccc".as_bytes()); + assert_eq!(*offsets, [0, 1, 3, 6]); + + Ok(()) + } + + #[test] + fn test_flen_update_subset() { + let mut bytes_array = vec![0u8; 4 * 4]; + update_bytes_flen( + &mut bytes_array, + &vec![4, 4], + &vec![1u8, 2].into(), + &ArraySubset::new_with_ranges(&[1..2, 1..3]), + 1, + ); + + update_bytes_flen( + &mut bytes_array, + &vec![4, 4], + &vec![3u8, 4].into(), + &ArraySubset::new_with_ranges(&[3..4, 0..2]), + 1, + ); + + debug_assert_eq!( + bytes_array, + vec![0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 3, 4, 0, 0] + ); + } +} diff --git a/src/array/array_errors.rs b/src/array/array_errors.rs index 7d078fac..ff628d6d 100644 --- a/src/array/array_errors.rs +++ b/src/array/array_errors.rs @@ -97,9 +97,16 @@ pub enum ArrayError { #[error("got chunk decoded shape {_0:?}, expected {_1:?}")] UnexpectedChunkDecodedShape(ArrayShape, ArrayShape), /// Incompatible element size. - #[error("got element size {_0}, expected {_1}")] - IncompatibleElementSize(usize, usize), + #[error("the element types does not match the data type")] + IncompatibleElementType, /// Invalid data shape. #[error("data has shape {_0:?}, expected {_1:?}")] InvalidDataShape(Vec, Vec), + /// Invalid element value. + /// + /// For example + /// - a bool array with a value not equal to 0 (false) or 1 (true). + /// - a string with invalid utf-8 encoding. + #[error("Invalid element value")] + InvalidElementValue, } diff --git a/src/array/array_representation.rs b/src/array/array_representation.rs index 51897f29..175c126a 100644 --- a/src/array/array_representation.rs +++ b/src/array/array_representation.rs @@ -1,6 +1,9 @@ use std::num::NonZeroU64; -use super::{data_type::IncompatibleFillValueError, ArrayShape, DataType, FillValue}; +use super::{ + data_type::{DataTypeSize, IncompatibleFillValueError}, + ArrayShape, DataType, FillValue, +}; use derive_more::Display; /// The shape, data type, and fill value of an `array`. @@ -24,6 +27,37 @@ pub type ArrayRepresentation = ArrayRepresentationBase; /// The array representation of a chunk, which must have nonzero dimensions. pub type ChunkRepresentation = ArrayRepresentationBase; +/// The size of an array/chunk. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ArraySize { + /// Fixed size. + Fixed { + /// The number of elements. + num_elements: u64, + /// The data type size (in bytes). + data_type_size: usize, + }, + /// Variable sized. + Variable { + /// The number of elements. + num_elements: u64, + }, +} + +impl ArraySize { + /// Create a new [`ArraySize`] from a data type size and number of elements. + #[must_use] + pub fn new(data_type_size: DataTypeSize, num_elements: u64) -> Self { + match data_type_size { + DataTypeSize::Fixed(data_type_size) => Self::Fixed { + num_elements, + data_type_size, + }, + DataTypeSize::Variable => Self::Variable { num_elements }, + } + } +} + impl ArrayRepresentationBase where TDim: Into + core::fmt::Debug + Copy, @@ -38,17 +72,26 @@ where data_type: DataType, fill_value: FillValue, ) -> Result { - if data_type.size() == fill_value.size() { - Ok(Self { + match data_type.size() { + DataTypeSize::Fixed(size) => { + if size == fill_value.size() { + Ok(Self { + array_shape, + data_type, + fill_value, + }) + } else { + Err(IncompatibleFillValueError::new( + data_type.name(), + fill_value, + )) + } + } + DataTypeSize::Variable => Ok(Self { array_shape, data_type, fill_value, - }) - } else { - Err(IncompatibleFillValueError::new( - data_type.name(), - fill_value, - )) + }), } } @@ -62,7 +105,9 @@ where data_type: DataType, fill_value: FillValue, ) -> Self { - debug_assert_eq!(data_type.size(), fill_value.size()); + if let Some(data_type_size) = data_type.fixed_size() { + debug_assert_eq!(data_type_size, fill_value.size()); + } Self { array_shape, data_type, @@ -123,23 +168,26 @@ where /// Return the element size. #[must_use] - pub fn element_size(&self) -> usize { - self.fill_value.size() + pub fn element_size(&self) -> DataTypeSize { + self.data_type().size() } - /// Return the total size in bytes. - /// - /// Equal to the product of each element of its shape and the element size. + /// Returns the element size in bytes with a fixed-size data type, otherwise returns [`None`]. #[must_use] - pub fn size(&self) -> u64 { - self.num_elements() * self.element_size() as u64 + pub fn fixed_element_size(&self) -> Option { + self.data_type().fixed_size() } - /// Return the total size in bytes as a [`usize`]. - /// - /// Equal to the product of each element of its shape and the element size. + /// Return the array size. #[must_use] - pub fn size_usize(&self) -> usize { - self.num_elements_usize() * self.element_size() + pub fn size(&self) -> ArraySize { + let num_elements = self.num_elements(); + match self.element_size() { + DataTypeSize::Fixed(data_type_size) => ArraySize::Fixed { + num_elements, + data_type_size, + }, + DataTypeSize::Variable => ArraySize::Variable { num_elements }, + } } } diff --git a/src/array/array_sync_readable.rs b/src/array/array_sync_readable.rs index 8004473e..4b41d968 100644 --- a/src/array/array_sync_readable.rs +++ b/src/array/array_sync_readable.rs @@ -4,7 +4,7 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon_iter_concurrent_limit::iter_concurrent_limit; use crate::{ - array::ArrayMetadataV2, + array::{ArrayBytes, ArrayMetadataV2}, array_subset::ArraySubset, metadata::MetadataRetrieveVersion, node::NodePath, @@ -15,14 +15,15 @@ use crate::{ }; use super::{ + array_bytes::{merge_chunks_vlen, update_bytes_flen}, codec::{ - options::CodecOptions, ArrayCodecTraits, ArrayPartialDecoderTraits, - ArrayToBytesCodecTraits, StoragePartialDecoder, + options::CodecOptions, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, + StoragePartialDecoder, }, concurrency::concurrency_chunks_and_codec, - transmute_from_bytes_vec, + element::ElementOwned, unsafe_cell_slice::UnsafeCellSlice, - validate_element_size, Array, ArrayCreateError, ArrayError, ArrayMetadata, ArrayMetadataV3, + Array, ArrayCreateError, ArrayError, ArrayMetadata, ArrayMetadataV3, ArraySize, DataTypeSize, }; #[cfg(feature = "ndarray")] @@ -105,7 +106,7 @@ impl Array { pub fn retrieve_chunk_if_exists( &self, chunk_indices: &[u64], - ) -> Result>, ArrayError> { + ) -> Result>, ArrayError> { self.retrieve_chunk_if_exists_opt(chunk_indices, &CodecOptions::default()) } @@ -118,7 +119,7 @@ impl Array { /// - `chunk_indices` are invalid, /// - there is a codec decoding error, or /// - an underlying store error. - pub fn retrieve_chunk_elements_if_exists( + pub fn retrieve_chunk_elements_if_exists( &self, chunk_indices: &[u64], ) -> Result>, ArrayError> { @@ -138,7 +139,7 @@ impl Array { /// /// # Panics /// Will panic if a chunk dimension is larger than `usize::MAX`. - pub fn retrieve_chunk_ndarray_if_exists( + pub fn retrieve_chunk_ndarray_if_exists( &self, chunk_indices: &[u64], ) -> Result>, ArrayError> { @@ -178,7 +179,7 @@ impl Array { /// /// # Panics /// Panics if the number of elements in the chunk exceeds `usize::MAX`. - pub fn retrieve_chunk(&self, chunk_indices: &[u64]) -> Result, ArrayError> { + pub fn retrieve_chunk(&self, chunk_indices: &[u64]) -> Result, ArrayError> { self.retrieve_chunk_opt(chunk_indices, &CodecOptions::default()) } @@ -191,7 +192,7 @@ impl Array { /// - `chunk_indices` are invalid, /// - there is a codec decoding error, or /// - an underlying store error. - pub fn retrieve_chunk_elements( + pub fn retrieve_chunk_elements( &self, chunk_indices: &[u64], ) -> Result, ArrayError> { @@ -211,7 +212,7 @@ impl Array { /// /// # Panics /// Will panic if a chunk dimension is larger than `usize::MAX`. - pub fn retrieve_chunk_ndarray( + pub fn retrieve_chunk_ndarray( &self, chunk_indices: &[u64], ) -> Result, ArrayError> { @@ -264,7 +265,7 @@ impl Array { /// /// # Panics /// Panics if the number of array elements in the chunk exceeds `usize::MAX`. - pub fn retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { + pub fn retrieve_chunks(&self, chunks: &ArraySubset) -> Result, ArrayError> { self.retrieve_chunks_opt(chunks, &CodecOptions::default()) } @@ -275,7 +276,7 @@ impl Array { /// /// # Panics /// Panics if the number of array elements in the chunks exceeds `usize::MAX`. - pub fn retrieve_chunks_elements( + pub fn retrieve_chunks_elements( &self, chunks: &ArraySubset, ) -> Result, ArrayError> { @@ -290,7 +291,7 @@ impl Array { /// /// # Panics /// Panics if the number of array elements in the chunks exceeds `usize::MAX`. - pub fn retrieve_chunks_ndarray( + pub fn retrieve_chunks_ndarray( &self, chunks: &ArraySubset, ) -> Result, ArrayError> { @@ -312,7 +313,7 @@ impl Array { &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { self.retrieve_chunk_subset_opt(chunk_indices, chunk_subset, &CodecOptions::default()) } @@ -324,7 +325,7 @@ impl Array { /// - the chunk subset is invalid, /// - there is a codec decoding error, or /// - an underlying store error. - pub fn retrieve_chunk_subset_elements( + pub fn retrieve_chunk_subset_elements( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, @@ -348,7 +349,7 @@ impl Array { /// /// # Panics /// Will panic if the number of elements in `chunk_subset` is `usize::MAX` or larger. - pub fn retrieve_chunk_subset_ndarray( + pub fn retrieve_chunk_subset_ndarray( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, @@ -373,7 +374,10 @@ impl Array { /// /// # Panics /// Panics if attempting to reference a byte beyond `usize::MAX`. - pub fn retrieve_array_subset(&self, array_subset: &ArraySubset) -> Result, ArrayError> { + pub fn retrieve_array_subset( + &self, + array_subset: &ArraySubset, + ) -> Result, ArrayError> { self.retrieve_array_subset_opt(array_subset, &CodecOptions::default()) } @@ -386,7 +390,7 @@ impl Array { /// - an array subset is invalid or out of bounds of the array, /// - there is a codec decoding error, or /// - an underlying store error. - pub fn retrieve_array_subset_elements( + pub fn retrieve_array_subset_elements( &self, array_subset: &ArraySubset, ) -> Result, ArrayError> { @@ -404,7 +408,7 @@ impl Array { /// /// # Panics /// Will panic if any dimension in `chunk_subset` is `usize::MAX` or larger. - pub fn retrieve_array_subset_ndarray( + pub fn retrieve_array_subset_ndarray( &self, array_subset: &ArraySubset, ) -> Result, ArrayError> { @@ -432,7 +436,7 @@ impl Array { &self, chunk_indices: &[u64], options: &CodecOptions, - ) -> Result>, ArrayError> { + ) -> Result>, ArrayError> { if chunk_indices.len() != self.dimensionality() { return Err(ArrayError::InvalidChunkGridIndicesError( chunk_indices.to_vec(), @@ -451,7 +455,7 @@ impl Array { .map_err(ArrayError::StorageError)?; if let Some(chunk_encoded) = chunk_encoded { let chunk_representation = self.chunk_array_representation(chunk_indices)?; - let chunk_decoded = self + let bytes = self .codecs() .decode( Cow::Borrowed(&chunk_encoded), @@ -459,16 +463,11 @@ impl Array { options, ) .map_err(ArrayError::CodecError)?; - let chunk_decoded_size = - chunk_representation.num_elements_usize() * chunk_representation.data_type().size(); - if chunk_decoded.len() == chunk_decoded_size { - Ok(Some(chunk_decoded.into_owned())) - } else { - Err(ArrayError::UnexpectedChunkDecodedSize( - chunk_decoded.len(), - chunk_decoded_size, - )) - } + bytes.validate( + chunk_representation.num_elements(), + chunk_representation.data_type().size(), + )?; + Ok(Some(bytes.into_owned())) } else { Ok(None) } @@ -480,50 +479,53 @@ impl Array { &self, chunk_indices: &[u64], options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { let chunk = self.retrieve_chunk_if_exists_opt(chunk_indices, options)?; if let Some(chunk) = chunk { Ok(chunk) } else { - let chunk_representation = self.chunk_array_representation(chunk_indices)?; - let fill_value = chunk_representation.fill_value().as_ne_bytes(); - Ok(fill_value.repeat(chunk_representation.num_elements_usize())) + let chunk_shape = self.chunk_shape(chunk_indices)?; + let array_size = + ArraySize::new(self.data_type().size(), chunk_shape.num_elements_u64()); + Ok(ArrayBytes::new_fill_value(array_size, self.fill_value())) } } /// Explicit options version of [`retrieve_chunk_elements_if_exists`](Array::retrieve_chunk_elements_if_exists). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunk_elements_if_exists_opt( + pub fn retrieve_chunk_elements_if_exists_opt( &self, chunk_indices: &[u64], options: &CodecOptions, ) -> Result>, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_chunk_if_exists_opt(chunk_indices, options)?; - Ok(bytes.map(|bytes| transmute_from_bytes_vec::(bytes))) + if let Some(bytes) = self.retrieve_chunk_if_exists_opt(chunk_indices, options)? { + Ok(Some(T::from_array_bytes(self.data_type(), bytes)?)) + } else { + Ok(None) + } } /// Explicit options version of [`retrieve_chunk_elements`](Array::retrieve_chunk_elements). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunk_elements_opt( + pub fn retrieve_chunk_elements_opt( &self, chunk_indices: &[u64], options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_chunk_opt(chunk_indices, options)?; - Ok(transmute_from_bytes_vec::(bytes)) + T::from_array_bytes( + self.data_type(), + self.retrieve_chunk_opt(chunk_indices, options)?, + ) } #[cfg(feature = "ndarray")] /// Explicit options version of [`retrieve_chunk_ndarray_if_exists`](Array::retrieve_chunk_ndarray_if_exists). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunk_ndarray_if_exists_opt( + pub fn retrieve_chunk_ndarray_if_exists_opt( &self, chunk_indices: &[u64], options: &CodecOptions, ) -> Result>, ArrayError> { - // validate_element_size::(self.data_type())?; // in retrieve_chunk_elements_if_exists let shape = self .chunk_grid() .chunk_shape_u64(chunk_indices, self.shape())? @@ -539,12 +541,11 @@ impl Array { #[cfg(feature = "ndarray")] /// Explicit options version of [`retrieve_chunk_ndarray`](Array::retrieve_chunk_ndarray). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunk_ndarray_opt( + pub fn retrieve_chunk_ndarray_opt( &self, chunk_indices: &[u64], options: &CodecOptions, ) -> Result, ArrayError> { - // validate_element_size::(self.data_type())?; // in retrieve_chunk_elements let shape = self .chunk_grid() .chunk_shape_u64(chunk_indices, self.shape())? @@ -561,7 +562,7 @@ impl Array { &self, chunks: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { if chunks.dimensionality() != self.dimensionality() { return Err(ArrayError::InvalidArraySubset( chunks.clone(), @@ -575,25 +576,22 @@ impl Array { /// Explicit options version of [`retrieve_chunks_elements`](Array::retrieve_chunks_elements). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunks_elements_opt( + pub fn retrieve_chunks_elements_opt( &self, chunks: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_chunks_opt(chunks, options)?; - Ok(transmute_from_bytes_vec::(bytes)) + T::from_array_bytes(self.data_type(), self.retrieve_chunks_opt(chunks, options)?) } #[cfg(feature = "ndarray")] /// Explicit options version of [`retrieve_chunks_ndarray`](Array::retrieve_chunks_ndarray). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunks_ndarray_opt( + pub fn retrieve_chunks_ndarray_opt( &self, chunks: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - // validate_element_size::(self.data_type())?; // in retrieve_chunks_elements_opt let array_subset = self.chunks_subset(chunks)?; let elements = self.retrieve_chunks_elements_opt::(chunks, options)?; elements_to_ndarray(array_subset.shape(), elements) @@ -601,11 +599,12 @@ impl Array { /// Explicit options version of [`retrieve_array_subset`](Array::retrieve_array_subset). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] + #[allow(clippy::too_many_lines)] pub fn retrieve_array_subset_opt( &self, array_subset: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { if array_subset.dimensionality() != self.dimensionality() { return Err(ArrayError::InvalidArraySubset( array_subset.clone(), @@ -625,10 +624,11 @@ impl Array { // Retrieve chunk bytes let num_chunks = chunks.num_elements_usize(); match num_chunks { - 0 => Ok(self - .fill_value() - .as_ne_bytes() - .repeat(array_subset.num_elements_usize())), + 0 => { + let array_size = + ArraySize::new(self.data_type().size(), array_subset.num_elements()); + Ok(ArrayBytes::new_fill_value(array_size, self.fill_value())) + } 1 => { let chunk_indices = chunks.start(); let chunk_subset = self.chunk_subset(chunk_indices)?; @@ -646,13 +646,10 @@ impl Array { } } _ => { - // Allocate the output - let size_output = array_subset.num_elements_usize() * self.data_type().size(); - let mut output = Vec::with_capacity(size_output); - - // Calculate chunk/codec concurrency let chunk_representation = self.chunk_array_representation(&vec![0; self.dimensionality()])?; + + // Calculate chunk/codec concurrency let codec_concurrency = self.recommended_codec_concurrency(&chunk_representation)?; let (chunk_concurrent_limit, options) = concurrency_chunks_and_codec( @@ -662,73 +659,100 @@ impl Array { &codec_concurrency, ); - { - let output = UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut output); - let retrieve_chunk = |chunk_indices: Vec| { - let chunk_subset = self.chunk_subset(&chunk_indices)?; - let chunk_subset_overlap = chunk_subset.overlap(array_subset)?; - let chunk_subset_bytes = self.retrieve_chunk_subset_opt( - &chunk_indices, - &chunk_subset_overlap.relative_to(chunk_subset.start())?, - &options, - )?; - let contiguous_indices = unsafe { - chunk_subset_overlap - .relative_to(array_subset.start())? - .contiguous_linearised_indices_unchecked(array_subset.shape()) + match chunk_representation.data_type().size() { + DataTypeSize::Variable => { + // Retrieve all the chunks + let retrieve_chunk = |chunk_indices: Vec| -> Result< + (ArrayBytes<'_>, ArraySubset), + ArrayError, + > { + let chunk_subset = self.chunk_subset(&chunk_indices)?; + let chunk_subset_overlap = chunk_subset.overlap(array_subset)?; + Ok(( + self.retrieve_chunk_subset_opt( + &chunk_indices, + &chunk_subset_overlap.relative_to(chunk_subset.start())?, + &options, + )?, + chunk_subset_overlap.relative_to(array_subset.start())?, + )) }; - let element_size = self.data_type().size(); - let length = contiguous_indices.contiguous_elements_usize() * element_size; - let mut decoded_offset = 0; - // FIXME: Par iteration? - let output = unsafe { output.get() }; - for (array_subset_element_index, _num_elements) in &contiguous_indices { - let output_offset = - usize::try_from(array_subset_element_index).unwrap() * element_size; - debug_assert!((output_offset + length) <= output.len()); - debug_assert!((decoded_offset + length) <= chunk_subset_bytes.len()); - output[output_offset..output_offset + length].copy_from_slice( - &chunk_subset_bytes[decoded_offset..decoded_offset + length], - ); - decoded_offset += length; + let chunk_indices = chunks.indices(); + let chunk_bytes_and_subsets = iter_concurrent_limit!( + chunk_concurrent_limit, + chunk_indices, + map, + retrieve_chunk + ) + .collect::, _>>()?; + + Ok(merge_chunks_vlen( + chunk_bytes_and_subsets, + array_subset.shape(), + )?) + } + DataTypeSize::Fixed(data_type_size) => { + // Allocate the output + let size_output = array_subset.num_elements_usize() * data_type_size; + let mut output = Vec::with_capacity(size_output); + + { + let output = + UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut output); + let retrieve_chunk = |chunk_indices: Vec| { + let chunk_subset = self.chunk_subset(&chunk_indices)?; + let chunk_subset_overlap = chunk_subset.overlap(array_subset)?; + let chunk_subset_bytes = self.retrieve_chunk_subset_opt( + &chunk_indices, + &chunk_subset_overlap.relative_to(chunk_subset.start())?, + &options, + )?; + update_bytes_flen( + unsafe { output.get() }, + array_subset.shape(), + &chunk_subset_bytes.into_fixed()?, + &chunk_subset_overlap.relative_to(array_subset.start())?, + data_type_size, + ); + Ok::<_, ArrayError>(()) + }; + let indices = chunks.indices(); + iter_concurrent_limit!( + chunk_concurrent_limit, + indices, + try_for_each, + retrieve_chunk + )?; } - Ok::<_, ArrayError>(()) - }; - let indices = chunks.indices(); - iter_concurrent_limit!( - chunk_concurrent_limit, - indices, - try_for_each, - retrieve_chunk - )?; + unsafe { output.set_len(size_output) }; + Ok(ArrayBytes::from(output)) + } } - unsafe { output.set_len(size_output) }; - Ok(output) } } } /// Explicit options version of [`retrieve_array_subset_elements`](Array::retrieve_array_subset_elements). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_array_subset_elements_opt( + pub fn retrieve_array_subset_elements_opt( &self, array_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_array_subset_opt(array_subset, options)?; - Ok(transmute_from_bytes_vec::(bytes)) + T::from_array_bytes( + self.data_type(), + self.retrieve_array_subset_opt(array_subset, options)?, + ) } #[cfg(feature = "ndarray")] /// Explicit options version of [`retrieve_array_subset_ndarray`](Array::retrieve_array_subset_ndarray). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_array_subset_ndarray_opt( + pub fn retrieve_array_subset_ndarray_opt( &self, array_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - // validate_element_size::(self.data_type())?; // in retrieve_array_subset_elements_opt let elements = self.retrieve_array_subset_elements_opt::(array_subset, options)?; elements_to_ndarray(array_subset.shape(), elements) } @@ -740,7 +764,7 @@ impl Array { chunk_indices: &[u64], chunk_subset: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result, ArrayError> { let chunk_representation = self.chunk_array_representation(chunk_indices)?; if !chunk_subset.inbounds(&chunk_representation.shape_u64()) { return Err(ArrayError::InvalidArraySubset( @@ -749,7 +773,7 @@ impl Array { )); } - let decoded_bytes = if chunk_subset.start().iter().all(|&o| o == 0) + let bytes = if chunk_subset.start().iter().all(|&o| o == 0) && chunk_subset.shape() == chunk_representation.shape_u64() { // Fast path if `chunk_subset` encompasses the whole chunk @@ -764,51 +788,39 @@ impl Array { data_key(self.path(), chunk_indices, self.chunk_key_encoding()), )); - unsafe { - self.codecs() - .partial_decoder(input_handle, &chunk_representation, options)? - .partial_decode_opt(&[chunk_subset.clone()], options)? - .pop() - .unwrap_unchecked() - .into_owned() - } + self.codecs() + .partial_decoder(input_handle, &chunk_representation, options)? + .partial_decode_opt(&[chunk_subset.clone()], options)? + .remove(0) + .into_owned() }; - - let total_size = decoded_bytes.len(); - let expected_size = chunk_subset.num_elements_usize() * self.data_type().size(); - if total_size == chunk_subset.num_elements_usize() * self.data_type().size() { - Ok(decoded_bytes) - } else { - Err(ArrayError::UnexpectedChunkDecodedSize( - total_size, - expected_size, - )) - } + bytes.validate(chunk_subset.num_elements(), self.data_type().size())?; + Ok(bytes) } /// Explicit options version of [`retrieve_chunk_subset_elements`](Array::retrieve_chunk_subset_elements). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunk_subset_elements_opt( + pub fn retrieve_chunk_subset_elements_opt( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_chunk_subset_opt(chunk_indices, chunk_subset, options)?; - Ok(transmute_from_bytes_vec::(bytes)) + T::from_array_bytes( + self.data_type(), + self.retrieve_chunk_subset_opt(chunk_indices, chunk_subset, options)?, + ) } #[cfg(feature = "ndarray")] /// Explicit options version of [`retrieve_chunk_subset_ndarray`](Array::retrieve_chunk_subset_ndarray). #[allow(clippy::missing_errors_doc)] - pub fn retrieve_chunk_subset_ndarray_opt( + pub fn retrieve_chunk_subset_ndarray_opt( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - // validate_element_size::(self.data_type())?; // in retrieve_chunk_subset_elements let elements = self.retrieve_chunk_subset_elements_opt::(chunk_indices, chunk_subset, options)?; elements_to_ndarray(chunk_subset.shape(), elements) diff --git a/src/array/array_sync_readable_writable.rs b/src/array/array_sync_readable_writable.rs index f728c889..28dc1185 100644 --- a/src/array/array_sync_readable_writable.rs +++ b/src/array/array_sync_readable_writable.rs @@ -1,11 +1,10 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator}; -use crate::{ - array::validate_element_size, array_subset::ArraySubset, storage::ReadableWritableStorageTraits, -}; +use crate::{array::ArrayBytes, array_subset::ArraySubset, storage::ReadableWritableStorageTraits}; use super::{ - codec::options::CodecOptions, concurrency::concurrency_chunks_and_codec, Array, ArrayError, + array_bytes::update_array_bytes, codec::options::CodecOptions, + concurrency::concurrency_chunks_and_codec, Array, ArrayError, Element, }; impl Array { @@ -23,11 +22,11 @@ impl Array /// # Panics /// Panics if attempting to reference a byte beyond `usize::MAX`. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_chunk_subset( + pub fn store_chunk_subset<'a>( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - chunk_subset_bytes: &[u8], + chunk_subset_bytes: impl Into>, ) -> Result<(), ArrayError> { self.store_chunk_subset_opt( chunk_indices, @@ -47,7 +46,7 @@ impl Array /// - the size of `T` does not match the data type size, or /// - a [`store_chunk_subset`](Array::store_chunk_subset) error condition is met. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_chunk_subset_elements( + pub fn store_chunk_subset_elements( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, @@ -70,7 +69,7 @@ impl Array /// # Errors /// Returns an [`ArrayError`] if a [`store_chunk_subset_elements`](Array::store_chunk_subset_elements) error condition is met. pub fn store_chunk_subset_ndarray< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -99,10 +98,10 @@ impl Array /// - there is a codec encoding error, or /// - an underlying store error. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_array_subset( + pub fn store_array_subset<'a>( &self, array_subset: &ArraySubset, - subset_bytes: &[u8], + subset_bytes: impl Into>, ) -> Result<(), ArrayError> { self.store_array_subset_opt(array_subset, subset_bytes, &CodecOptions::default()) } @@ -117,7 +116,7 @@ impl Array /// - the size of `T` does not match the data type size, or /// - a [`store_array_subset`](Array::store_array_subset) error condition is met. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_array_subset_elements( + pub fn store_array_subset_elements( &self, array_subset: &ArraySubset, subset_elements: &[T], @@ -139,7 +138,7 @@ impl Array /// Returns an [`ArrayError`] if a [`store_array_subset_elements`](Array::store_array_subset_elements) error condition is met. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] pub fn store_array_subset_ndarray< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -156,11 +155,11 @@ impl Array /// Explicit options version of [`store_chunk_subset`](Array::store_chunk_subset). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_chunk_subset_opt( + pub fn store_chunk_subset_opt<'a>( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, - chunk_subset_bytes: &[u8], + chunk_subset_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { let chunk_shape = self @@ -176,67 +175,55 @@ impl Array chunk_shape, )); } - let expected_length = - chunk_subset.shape().iter().product::() * self.data_type().size() as u64; - if chunk_subset_bytes.len() as u64 != expected_length { - return Err(ArrayError::InvalidBytesInputSize( - chunk_subset_bytes.len(), - expected_length, - )); - } if chunk_subset.shape() == chunk_shape && chunk_subset.start().iter().all(|&x| x == 0) { // The subset spans the whole chunk, so store the bytes directly and skip decoding self.store_chunk_opt(chunk_indices, chunk_subset_bytes, options) } else { + let chunk_subset_bytes = chunk_subset_bytes.into(); + chunk_subset_bytes.validate(chunk_subset.num_elements(), self.data_type().size())?; + // Lock the chunk // let key = data_key(self.path(), chunk_indices, self.chunk_key_encoding()); // let mutex = self.storage.mutex(&key)?; // let _lock = mutex.lock(); // Decode the entire chunk - let mut chunk_bytes = self.retrieve_chunk_opt(chunk_indices, options)?; + let chunk_bytes_old = self.retrieve_chunk_opt(chunk_indices, options)?; + chunk_bytes_old.validate(chunk_shape.iter().product(), self.data_type().size())?; - // Update the intersecting subset of the chunk - let element_size = self.data_type().size(); - let mut offset = 0; - let contiguous_indices = - unsafe { chunk_subset.contiguous_linearised_indices_unchecked(&chunk_shape) }; - let length = contiguous_indices.contiguous_elements_usize() * element_size; - // FIXME: Par iter? - for (chunk_element_index, _num_elements) in &contiguous_indices { - let chunk_offset = usize::try_from(chunk_element_index).unwrap() * element_size; - debug_assert!(chunk_offset + length <= chunk_bytes.len()); - debug_assert!(offset + length <= chunk_subset_bytes.len()); - chunk_bytes[chunk_offset..chunk_offset + length] - .copy_from_slice(&chunk_subset_bytes[offset..offset + length]); - offset += length; - } + // Update the chunk + let chunk_bytes_new = update_array_bytes( + chunk_bytes_old, + chunk_shape, + chunk_subset_bytes, + chunk_subset, + self.data_type().size(), + ); // Store the updated chunk - self.store_chunk_opt(chunk_indices, &chunk_bytes, options) + self.store_chunk_opt(chunk_indices, chunk_bytes_new, options) } } /// Explicit options version of [`store_chunk_subset_elements`](Array::store_chunk_subset_elements). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_chunk_subset_elements_opt( + pub fn store_chunk_subset_elements_opt( &self, chunk_indices: &[u64], chunk_subset: &ArraySubset, chunk_subset_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let chunk_subset_elements = crate::array::transmute_to_bytes(chunk_subset_elements); - self.store_chunk_subset_opt(chunk_indices, chunk_subset, chunk_subset_elements, options) + let chunk_subset_bytes = T::into_array_bytes(self.data_type(), chunk_subset_elements)?; + self.store_chunk_subset_opt(chunk_indices, chunk_subset, chunk_subset_bytes, options) } #[cfg(feature = "ndarray")] /// Explicit options version of [`store_chunk_subset_ndarray`](Array::store_chunk_subset_ndarray). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] pub fn store_chunk_subset_ndarray_opt< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -246,7 +233,6 @@ impl Array chunk_subset_array: TArray, options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let chunk_subset_array: ndarray::Array = chunk_subset_array.into(); let subset = ArraySubset::new_with_start_shape( chunk_subset_start.to_vec(), @@ -262,10 +248,11 @@ impl Array /// Explicit options version of [`store_array_subset`](Array::store_array_subset). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_array_subset_opt( + #[allow(clippy::too_many_lines)] + pub fn store_array_subset_opt<'a>( &self, array_subset: &ArraySubset, - subset_bytes: &[u8], + subset_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { // Validation @@ -275,13 +262,6 @@ impl Array self.shape().to_vec(), )); } - let expected_size = array_subset.num_elements() * self.data_type().size() as u64; - if subset_bytes.len() as u64 != expected_size { - return Err(ArrayError::InvalidBytesInputSize( - subset_bytes.len(), - expected_size, - )); - } // Find the chunks intersecting this array subset let chunks = self.chunks_in_array_subset(array_subset)?; @@ -294,38 +274,23 @@ impl Array let num_chunks = chunks.num_elements_usize(); if num_chunks == 1 { let chunk_indices = chunks.start(); - let chunk_subset_in_array = unsafe { - self.chunk_grid() - .subset_unchecked(chunk_indices, self.shape()) - .unwrap() - }; - if array_subset == &chunk_subset_in_array { + let chunk_subset = self.chunk_subset(chunk_indices)?; + if array_subset == &chunk_subset { // A fast path if the array subset matches the chunk subset // This skips the internal decoding occurring in store_chunk_subset self.store_chunk_opt(chunk_indices, subset_bytes, options)?; } else { - let overlap = unsafe { array_subset.overlap_unchecked(&chunk_subset_in_array) }; - let chunk_subset_in_array_subset = - unsafe { overlap.relative_to_unchecked(array_subset.start()) }; - let chunk_subset_bytes = unsafe { - chunk_subset_in_array_subset.extract_bytes_unchecked( - subset_bytes, - array_subset.shape(), - self.data_type().size(), - ) - }; - // Store the chunk subset - let array_subset_in_chunk_subset = - unsafe { overlap.relative_to_unchecked(chunk_subset_in_array.start()) }; self.store_chunk_subset_opt( chunk_indices, - &array_subset_in_chunk_subset, - &chunk_subset_bytes, + &array_subset.relative_to(chunk_subset.start())?, + subset_bytes, options, )?; } } else { + let subset_bytes = subset_bytes.into(); + subset_bytes.validate(array_subset.num_elements(), self.data_type().size())?; // Calculate chunk/codec concurrency let chunk_representation = self.chunk_array_representation(&vec![0; self.dimensionality()])?; @@ -338,27 +303,21 @@ impl Array ); let store_chunk = |chunk_indices: Vec| -> Result<(), ArrayError> { - let chunk_subset_in_array = unsafe { - self.chunk_grid() - .subset_unchecked(&chunk_indices, self.shape()) - .unwrap() - }; + let chunk_subset_in_array = self.chunk_subset(&chunk_indices)?; let overlap = unsafe { array_subset.overlap_unchecked(&chunk_subset_in_array) }; let chunk_subset_in_array_subset = unsafe { overlap.relative_to_unchecked(array_subset.start()) }; + let chunk_subset_bytes = subset_bytes.extract_array_subset( + &chunk_subset_in_array_subset, + array_subset.shape(), + self.data_type(), + )?; let array_subset_in_chunk_subset = unsafe { overlap.relative_to_unchecked(chunk_subset_in_array.start()) }; - let chunk_subset_bytes = unsafe { - chunk_subset_in_array_subset.extract_bytes_unchecked( - subset_bytes, - array_subset.shape(), - self.data_type().size(), - ) - }; self.store_chunk_subset_opt( &chunk_indices, &array_subset_in_chunk_subset, - &chunk_subset_bytes, + chunk_subset_bytes, &options, ) }; @@ -376,22 +335,21 @@ impl Array /// Explicit options version of [`store_array_subset_elements`](Array::store_array_subset_elements). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_array_subset_elements_opt( + pub fn store_array_subset_elements_opt( &self, array_subset: &ArraySubset, subset_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let subset_elements = crate::array::transmute_to_bytes(subset_elements); - self.store_array_subset_opt(array_subset, subset_elements, options) + let subset_bytes = T::into_array_bytes(self.data_type(), subset_elements)?; + self.store_array_subset_opt(array_subset, subset_bytes, options) } #[cfg(feature = "ndarray")] /// Explicit options version of [`store_array_subset_ndarray`](Array::store_array_subset_ndarray). #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] pub fn store_array_subset_ndarray_opt< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -400,7 +358,6 @@ impl Array subset_array: TArray, options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let subset_array: ndarray::Array = subset_array.into(); let subset = ArraySubset::new_with_start_shape( subset_start.to_vec(), diff --git a/src/array/array_sync_sharded_readable_ext.rs b/src/array/array_sync_sharded_readable_ext.rs index c9207829..7c6ac1b2 100644 --- a/src/array/array_sync_sharded_readable_ext.rs +++ b/src/array/array_sync_sharded_readable_ext.rs @@ -3,10 +3,13 @@ use std::{collections::HashMap, sync::Arc}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon_iter_concurrent_limit::iter_concurrent_limit; +use super::array_bytes::{merge_chunks_vlen, update_bytes_flen}; +use super::element::ElementOwned; use super::{ - codec::CodecOptions, concurrency::concurrency_chunks_and_codec, transmute_from_bytes_vec, - validate_element_size, Array, ArrayError, ArrayShardedExt, ChunkGrid, UnsafeCellSlice, + codec::CodecOptions, concurrency::concurrency_chunks_and_codec, Array, ArrayError, + ArrayShardedExt, ChunkGrid, UnsafeCellSlice, }; +use super::{ArrayBytes, ArraySize, DataTypeSize}; use crate::storage::ReadableStorageTraits; use crate::{array::codec::ArrayPartialDecoderTraits, array_subset::ArraySubset}; @@ -93,13 +96,13 @@ pub trait ArrayShardedReadableExt, inner_chunk_indices: &[u64], options: &CodecOptions, - ) -> Result, ArrayError>; + ) -> Result; /// Read and decode the inner chunk at `chunk_indices` into a vector of its elements. /// /// See [`Array::retrieve_chunk_elements_opt`]. #[allow(clippy::missing_errors_doc)] - fn retrieve_inner_chunk_elements_opt<'a, T: bytemuck::Pod>( + fn retrieve_inner_chunk_elements_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunk_indices: &[u64], @@ -111,7 +114,7 @@ pub trait ArrayShardedReadableExt( + fn retrieve_inner_chunk_ndarray_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunk_indices: &[u64], @@ -127,13 +130,13 @@ pub trait ArrayShardedReadableExt, inner_chunks: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError>; + ) -> Result; /// Read and decode the inner chunks at `inner_chunks` into a vector of their elements. /// /// See [`Array::retrieve_chunks_elements_opt`]. #[allow(clippy::missing_errors_doc)] - fn retrieve_inner_chunks_elements_opt<'a, T: bytemuck::Pod>( + fn retrieve_inner_chunks_elements_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunks: &ArraySubset, @@ -145,7 +148,7 @@ pub trait ArrayShardedReadableExt( + fn retrieve_inner_chunks_ndarray_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunks: &ArraySubset, @@ -161,13 +164,13 @@ pub trait ArrayShardedReadableExt, array_subset: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError>; + ) -> Result; /// Read and decode the `array_subset` of array into a vector of its elements. /// /// See [`Array::retrieve_array_subset_elements_opt`]. #[allow(clippy::missing_errors_doc)] - fn retrieve_array_subset_elements_sharded_opt<'a, T: bytemuck::Pod>( + fn retrieve_array_subset_elements_sharded_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, array_subset: &ArraySubset, @@ -179,7 +182,7 @@ pub trait ArrayShardedReadableExt( + fn retrieve_array_subset_ndarray_sharded_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, array_subset: &ArraySubset, @@ -195,7 +198,7 @@ impl ArrayShardedReadableExt cache: &ArrayShardedReadableExtCache<'a>, inner_chunk_indices: &[u64], options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result { if cache.array_is_sharded() { let array_subset = cache .inner_chunk_grid() @@ -217,29 +220,30 @@ impl ArrayShardedReadableExt let shard_subset = array_subset.relative_to(&shard_origin)?; let partial_decoder = cache.retrieve(self, shard_indices)?; - Ok(partial_decoder + let bytes = partial_decoder .partial_decode_opt(&[shard_subset], options)? - .pop() - .expect("partial_decode_opt called with one subset, returned without error") - .into_owned()) + .remove(0) + .into_owned(); + Ok(bytes) } else { self.retrieve_chunk_opt(inner_chunk_indices, options) } } - fn retrieve_inner_chunk_elements_opt<'a, T: bytemuck::Pod>( + fn retrieve_inner_chunk_elements_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunk_indices: &[u64], options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_inner_chunk_opt(cache, inner_chunk_indices, options)?; - Ok(transmute_from_bytes_vec::(bytes)) + T::from_array_bytes( + self.data_type(), + self.retrieve_inner_chunk_opt(cache, inner_chunk_indices, options)?, + ) } #[cfg(feature = "ndarray")] - fn retrieve_inner_chunk_ndarray_opt<'a, T: bytemuck::Pod>( + fn retrieve_inner_chunk_ndarray_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunk_indices: &[u64], @@ -260,7 +264,7 @@ impl ArrayShardedReadableExt cache: &ArrayShardedReadableExtCache<'a>, inner_chunks: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result { if cache.array_is_sharded() { let inner_chunk_grid = cache.inner_chunk_grid(); let array_subset = inner_chunk_grid @@ -280,19 +284,20 @@ impl ArrayShardedReadableExt } } - fn retrieve_inner_chunks_elements_opt<'a, T: bytemuck::Pod>( + fn retrieve_inner_chunks_elements_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunks: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_inner_chunks_opt(cache, inner_chunks, options)?; - Ok(transmute_from_bytes_vec::(bytes)) + T::from_array_bytes( + self.data_type(), + self.retrieve_inner_chunks_opt(cache, inner_chunks, options)?, + ) } #[cfg(feature = "ndarray")] - fn retrieve_inner_chunks_ndarray_opt<'a, T: bytemuck::Pod>( + fn retrieve_inner_chunks_ndarray_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, inner_chunks: &ArraySubset, @@ -315,12 +320,13 @@ impl ArrayShardedReadableExt super::elements_to_ndarray(array_subset.shape(), elements) } + #[allow(clippy::too_many_lines)] fn retrieve_array_subset_sharded_opt<'a>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, array_subset: &ArraySubset, options: &CodecOptions, - ) -> Result, ArrayError> { + ) -> Result { if cache.array_is_sharded() { // Find the shards intersecting this array subset let shards = self.chunks_in_array_subset(array_subset)?; @@ -334,15 +340,10 @@ impl ArrayShardedReadableExt // Retrieve chunk bytes let num_shards = shards.num_elements_usize(); if num_shards == 0 { - Ok(self - .fill_value() - .as_ne_bytes() - .repeat(array_subset.num_elements_usize())) + let array_size = + ArraySize::new(self.data_type().size(), array_subset.num_elements()); + Ok(ArrayBytes::new_fill_value(array_size, self.fill_value())) } else { - // Allocate the output - let size_output = array_subset.num_elements_usize() * self.data_type().size(); - let mut output = Vec::with_capacity(size_output); - // Calculate chunk/codec concurrency let chunk_representation = self.chunk_array_representation(&vec![0; self.dimensionality()])?; @@ -355,77 +356,106 @@ impl ArrayShardedReadableExt &codec_concurrency, ); - { - let output = UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut output); - let retrieve_shard = |shard_indices: Vec| { - let shard_subset = self.chunk_subset(&shard_indices)?; - let shard_subset_overlap = shard_subset.overlap(array_subset)?; - // let shard_subset_bytes = self.retrieve_chunk_subset_opt( - // &shard_indices, - // &shard_subset_overlap.relative_to(shard_subset.start())?, - // &options, - // )?; - let shard_subset_bytes = cache - .retrieve(self, &shard_indices)? - .partial_decode_opt( - &[shard_subset_overlap.relative_to(shard_subset.start())?], - &options, - )? - .pop() - .unwrap() - .into_owned(); - - let contiguous_indices = unsafe { - shard_subset_overlap - .relative_to(array_subset.start())? - .contiguous_linearised_indices_unchecked(array_subset.shape()) + match self.data_type().size() { + DataTypeSize::Variable => { + let retrieve_inner_chunk = |shard_indices: Vec| -> Result< + (ArrayBytes<'_>, ArraySubset), + ArrayError, + > { + let shard_subset = self.chunk_subset(&shard_indices)?; + let shard_subset_overlap = shard_subset.overlap(array_subset)?; + let bytes = cache + .retrieve(self, &shard_indices)? + .partial_decode_opt( + &[shard_subset_overlap.relative_to(shard_subset.start())?], + &options, + )? + .remove(0) + .into_owned(); + Ok(( + bytes, + shard_subset_overlap.relative_to(array_subset.start())?, + )) }; - let element_size = self.data_type().size(); - let length = contiguous_indices.contiguous_elements_usize() * element_size; - let mut decoded_offset = 0; - // FIXME: Par iteration? - let output = unsafe { output.get() }; - for (array_subset_element_index, _num_elements) in &contiguous_indices { - let output_offset = - usize::try_from(array_subset_element_index).unwrap() * element_size; - debug_assert!((output_offset + length) <= output.len()); - debug_assert!((decoded_offset + length) <= shard_subset_bytes.len()); - output[output_offset..output_offset + length].copy_from_slice( - &shard_subset_bytes[decoded_offset..decoded_offset + length], - ); - decoded_offset += length; + + let indices = shards.indices(); + let chunk_bytes_and_subsets = iter_concurrent_limit!( + chunk_concurrent_limit, + indices, + map, + retrieve_inner_chunk + ) + .collect::, _>>()?; + + Ok(merge_chunks_vlen( + chunk_bytes_and_subsets, + array_subset.shape(), + )?) + } + DataTypeSize::Fixed(data_type_size) => { + let size_output = array_subset.num_elements_usize() * data_type_size; + let mut output = Vec::with_capacity(size_output); + { + let output = + UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut output); + let retrieve_shard_into_slice = |shard_indices: Vec| { + let shard_subset = self.chunk_subset(&shard_indices)?; + let shard_subset_overlap = shard_subset.overlap(array_subset)?; + // let shard_subset_bytes = self.retrieve_chunk_subset_opt( + // &shard_indices, + // &shard_subset_overlap.relative_to(shard_subset.start())?, + // &options, + // )?; + let bytes = cache + .retrieve(self, &shard_indices)? + .partial_decode_opt( + &[shard_subset_overlap + .relative_to(shard_subset.start())?], + &options, + )? + .remove(0) + .into_owned(); + update_bytes_flen( + unsafe { output.get() }, + array_subset.shape(), + &bytes.into_fixed()?, + &shard_subset_overlap.relative_to(array_subset.start())?, + data_type_size, + ); + Ok::<_, ArrayError>(()) + }; + let indices = shards.indices(); + iter_concurrent_limit!( + chunk_concurrent_limit, + indices, + try_for_each, + retrieve_shard_into_slice + )?; } - Ok::<_, ArrayError>(()) - }; - let indices = shards.indices(); - iter_concurrent_limit!( - chunk_concurrent_limit, - indices, - try_for_each, - retrieve_shard - )?; + unsafe { output.set_len(size_output) }; + Ok(ArrayBytes::from(output)) + } } - unsafe { output.set_len(size_output) }; - Ok(output) } } else { self.retrieve_array_subset_opt(array_subset, options) } } - fn retrieve_array_subset_elements_sharded_opt<'a, T: bytemuck::Pod>( + fn retrieve_array_subset_elements_sharded_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, array_subset: &ArraySubset, options: &CodecOptions, ) -> Result, ArrayError> { - validate_element_size::(self.data_type())?; - let bytes = self.retrieve_array_subset_sharded_opt(cache, array_subset, options)?; - Ok(transmute_from_bytes_vec::(bytes)) + T::from_array_bytes( + self.data_type(), + self.retrieve_array_subset_sharded_opt(cache, array_subset, options)?, + ) } #[cfg(feature = "ndarray")] - fn retrieve_array_subset_ndarray_sharded_opt<'a, T: bytemuck::Pod>( + fn retrieve_array_subset_ndarray_sharded_opt<'a, T: ElementOwned>( &'a self, cache: &ArrayShardedReadableExtCache<'a>, array_subset: &ArraySubset, diff --git a/src/array/array_sync_writable.rs b/src/array/array_sync_writable.rs index acbf074b..971dccbd 100644 --- a/src/array/array_sync_writable.rs +++ b/src/array/array_sync_writable.rs @@ -1,10 +1,10 @@ -use std::{borrow::Cow, sync::Arc}; +use std::sync::Arc; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon_iter_concurrent_limit::iter_concurrent_limit; use crate::{ - array::validate_element_size, + array::ArrayBytes, array_subset::ArraySubset, metadata::MetadataEraseVersion, storage::{ @@ -14,9 +14,9 @@ use crate::{ }; use super::{ - codec::{options::CodecOptions, ArrayCodecTraits}, + codec::{options::CodecOptions, ArrayToBytesCodecTraits}, concurrency::concurrency_chunks_and_codec, - Array, ArrayError, ArrayMetadata, ArrayMetadataOptions, + Array, ArrayError, ArrayMetadata, ArrayMetadataOptions, Element, }; impl Array { @@ -58,7 +58,11 @@ impl Array { /// - the length of `chunk_bytes` is not equal to the expected length (the product of the number of elements in the chunk and the data type size in bytes), /// - there is a codec encoding error, or /// - an underlying store error. - pub fn store_chunk(&self, chunk_indices: &[u64], chunk_bytes: &[u8]) -> Result<(), ArrayError> { + pub fn store_chunk<'a>( + &self, + chunk_indices: &[u64], + chunk_bytes: impl Into>, + ) -> Result<(), ArrayError> { self.store_chunk_opt(chunk_indices, chunk_bytes, &CodecOptions::default()) } @@ -71,7 +75,7 @@ impl Array { /// Returns an [`ArrayError`] if /// - the size of `T` does not match the data type size, or /// - a [`store_chunk`](Array::store_chunk) error condition is met. - pub fn store_chunk_elements( + pub fn store_chunk_elements( &self, chunk_indices: &[u64], chunk_elements: &[T], @@ -90,7 +94,7 @@ impl Array { /// - a [`store_chunk_elements`](Array::store_chunk_elements) error condition is met. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] pub fn store_chunk_ndarray< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -114,10 +118,10 @@ impl Array { /// - an underlying store error. #[allow(clippy::similar_names)] #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_chunks( + pub fn store_chunks<'a>( &self, chunks: &ArraySubset, - chunks_bytes: &[u8], + chunks_bytes: impl Into>, ) -> Result<(), ArrayError> { self.store_chunks_opt(chunks, chunks_bytes, &CodecOptions::default()) } @@ -129,7 +133,7 @@ impl Array { /// - the size of `T` does not match the data type size, or /// - a [`store_chunks`](Array::store_chunks) error condition is met. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] - pub fn store_chunks_elements( + pub fn store_chunks_elements( &self, chunks: &ArraySubset, chunks_elements: &[T], @@ -146,7 +150,7 @@ impl Array { /// - a [`store_chunks_elements`](Array::store_chunks_elements) error condition is met. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] pub fn store_chunks_ndarray< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -242,24 +246,25 @@ impl Array { /// Explicit options version of [`store_chunk`](Array::store_chunk). #[allow(clippy::missing_errors_doc)] - pub fn store_chunk_opt( + pub fn store_chunk_opt<'a>( &self, chunk_indices: &[u64], - chunk_bytes: &[u8], + chunk_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { + let chunk_bytes = chunk_bytes.into(); + // Validation let chunk_array_representation = self.chunk_array_representation(chunk_indices)?; - if chunk_bytes.len() as u64 != chunk_array_representation.size() { - return Err(ArrayError::InvalidBytesInputSize( - chunk_bytes.len(), - chunk_array_representation.size(), - )); - } + chunk_bytes.validate( + chunk_array_representation.num_elements(), + chunk_array_representation.data_type().size(), + )?; - if !options.store_empty_chunks() && self.fill_value().equals_all(chunk_bytes) { + let is_fill_value = + !options.store_empty_chunks() && chunk_bytes.is_fill_value(self.fill_value()); + if is_fill_value { self.erase_chunk(chunk_indices)?; - Ok(()) } else { let storage_handle = Arc::new(StorageHandle::new(self.storage.clone())); let storage_transformer = self @@ -267,11 +272,7 @@ impl Array { .create_writable_transformer(storage_handle); let chunk_encoded = self .codecs() - .encode( - Cow::Borrowed(chunk_bytes), - &chunk_array_representation, - options, - ) + .encode(chunk_bytes, &chunk_array_representation, options) .map_err(ArrayError::CodecError)?; crate::storage::store_chunk( &*storage_transformer, @@ -279,29 +280,28 @@ impl Array { chunk_indices, self.chunk_key_encoding(), Bytes::from(chunk_encoded.into_owned()), - ) - .map_err(ArrayError::StorageError) + )?; } + Ok(()) } /// Explicit options version of [`store_chunk_elements`](Array::store_chunk_elements). #[allow(clippy::missing_errors_doc)] - pub fn store_chunk_elements_opt( + pub fn store_chunk_elements_opt( &self, chunk_indices: &[u64], chunk_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let chunk_elements = crate::array::transmute_to_bytes(chunk_elements); - self.store_chunk_opt(chunk_indices, chunk_elements, options) + let chunk_bytes = T::into_array_bytes(self.data_type(), chunk_elements)?; + self.store_chunk_opt(chunk_indices, chunk_bytes, options) } #[cfg(feature = "ndarray")] /// Explicit options version of [`store_chunk_ndarray`](Array::store_chunk_ndarray). #[allow(clippy::missing_errors_doc)] pub fn store_chunk_ndarray_opt< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -310,12 +310,11 @@ impl Array { chunk_array: TArray, options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let chunk_array: ndarray::Array = chunk_array.into(); let chunk_shape = self.chunk_shape_usize(chunk_indices)?; if chunk_array.shape() == chunk_shape { let chunk_array = super::ndarray_into_vec(chunk_array); - self.store_chunk_elements_opt(chunk_indices, &chunk_array, options) + self.store_chunk_elements_opt(chunk_indices, chunk_array.as_slice(), options) } else { Err(ArrayError::InvalidDataShape( chunk_array.shape().to_vec(), @@ -326,30 +325,27 @@ impl Array { /// Explicit options version of [`store_chunks`](Array::store_chunks). #[allow(clippy::similar_names)] - #[allow(clippy::missing_errors_doc)] - pub fn store_chunks_opt( + #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] + pub fn store_chunks_opt<'a>( &self, chunks: &ArraySubset, - chunks_bytes: &[u8], + chunks_bytes: impl Into>, options: &CodecOptions, ) -> Result<(), ArrayError> { let num_chunks = chunks.num_elements_usize(); match num_chunks { - 0 => {} + 0 => { + let chunks_bytes = chunks_bytes.into(); + chunks_bytes.validate(0, self.data_type().size())?; + } 1 => { let chunk_indices = chunks.start(); self.store_chunk_opt(chunk_indices, chunks_bytes, options)?; } _ => { + let chunks_bytes = chunks_bytes.into(); let array_subset = self.chunks_subset(chunks)?; - let element_size = self.data_type().size(); - let expected_size = element_size as u64 * array_subset.num_elements(); - if chunks_bytes.len() as u64 != expected_size { - return Err(ArrayError::InvalidBytesInputSize( - chunks_bytes.len(), - expected_size, - )); - } + chunks_bytes.validate(array_subset.num_elements(), self.data_type().size())?; // Calculate chunk/codec concurrency let chunk_representation = @@ -364,32 +360,15 @@ impl Array { ); let store_chunk = |chunk_indices: Vec| -> Result<(), ArrayError> { - let chunk_subset_in_array = unsafe { - self.chunk_grid() - .subset_unchecked(&chunk_indices, self.shape()) - .ok_or_else(|| { - ArrayError::InvalidChunkGridIndicesError(chunk_indices.clone()) - })? - }; - let overlap = unsafe { array_subset.overlap_unchecked(&chunk_subset_in_array) }; - let chunk_subset_in_array_subset = - unsafe { overlap.relative_to_unchecked(array_subset.start()) }; - #[allow(clippy::similar_names)] - let chunk_bytes = unsafe { - chunk_subset_in_array_subset.extract_bytes_unchecked( - chunks_bytes, - array_subset.shape(), - element_size, - ) - }; - - debug_assert_eq!( - chunk_subset_in_array.num_elements(), - chunk_subset_in_array_subset.num_elements() - ); - - self.store_chunk_opt(&chunk_indices, &chunk_bytes, &options) + let chunk_subset = self.chunk_subset(&chunk_indices)?; + let chunk_bytes = chunks_bytes.extract_array_subset( + &chunk_subset.relative_to(array_subset.start())?, + array_subset.shape(), + self.data_type(), + )?; + self.store_chunk_opt(&chunk_indices, chunk_bytes, &options) }; + let indices = chunks.indices(); iter_concurrent_limit!(chunk_concurrent_limit, indices, try_for_each, store_chunk)?; } @@ -400,22 +379,21 @@ impl Array { /// Explicit options version of [`store_chunks_elements`](Array::store_chunks_elements). #[allow(clippy::missing_errors_doc)] - pub fn store_chunks_elements_opt( + pub fn store_chunks_elements_opt( &self, chunks: &ArraySubset, chunks_elements: &[T], options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; - let chunks_elements = crate::array::transmute_to_bytes(chunks_elements); - self.store_chunks_opt(chunks, chunks_elements, options) + let chunks_bytes = T::into_array_bytes(self.data_type(), chunks_elements)?; + self.store_chunks_opt(chunks, chunks_bytes, options) } #[cfg(feature = "ndarray")] /// Explicit options version of [`store_chunks_ndarray`](Array::store_chunks_ndarray). #[allow(clippy::missing_errors_doc)] pub fn store_chunks_ndarray_opt< - T: bytemuck::Pod, + T: Element, TArray: Into>, D: ndarray::Dimension, >( @@ -424,13 +402,12 @@ impl Array { chunks_array: TArray, options: &CodecOptions, ) -> Result<(), ArrayError> { - validate_element_size::(self.data_type())?; let chunks_array: ndarray::Array = chunks_array.into(); let chunks_subset = self.chunks_subset(chunks)?; let chunks_shape = chunks_subset.shape_usize(); if chunks_array.shape() == chunks_shape { let chunks_array = super::ndarray_into_vec(chunks_array); - self.store_chunks_elements_opt(chunks, &chunks_array, options) + self.store_chunks_elements_opt(chunks, chunks_array.as_slice(), options) } else { Err(ArrayError::InvalidDataShape( chunks_array.shape().to_vec(), diff --git a/src/array/chunk_shape.rs b/src/array/chunk_shape.rs index 1ee384c0..a2edfd0f 100644 --- a/src/array/chunk_shape.rs +++ b/src/array/chunk_shape.rs @@ -17,7 +17,7 @@ impl ChunkShape { pub fn num_elements(&self) -> NonZeroU64 { unsafe { // Multiplying NonZeroU64 must result in NonZeroU64 - NonZeroU64::new_unchecked(self.0.iter().copied().map(NonZeroU64::get).product::()) + NonZeroU64::new_unchecked(self.num_elements_u64()) } } @@ -30,13 +30,19 @@ impl ChunkShape { #[must_use] pub fn num_elements_nonzero_usize(&self) -> NonZeroUsize { unsafe { - NonZeroUsize::new_unchecked( - usize::try_from(self.0.iter().copied().map(NonZeroU64::get).product::()) - .unwrap(), - ) + // Multiplying NonZeroU64 must result in NonZeroUsize + NonZeroUsize::new_unchecked(usize::try_from(self.num_elements_u64()).unwrap()) } } + /// Return the number of elements as a u64. + /// + /// Equal to the product of the components of its shape. + #[must_use] + pub fn num_elements_u64(&self) -> u64 { + self.0.iter().copied().map(NonZeroU64::get).product::() + } + /// Return the number of elements as a usize. /// /// Equal to the product of the components of its shape. @@ -45,7 +51,7 @@ impl ChunkShape { /// Panics if the number of elements exceeds [`usize::MAX`]. #[must_use] pub fn num_elements_usize(&self) -> usize { - usize::try_from(self.0.iter().copied().map(NonZeroU64::get).product::()).unwrap() + usize::try_from(self.num_elements_u64()).unwrap() } } diff --git a/src/array/codec.rs b/src/array/codec.rs index 4207b1c1..212a1c49 100644 --- a/src/array/codec.rs +++ b/src/array/codec.rs @@ -90,6 +90,7 @@ use super::{ concurrency::RecommendedConcurrency, ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, ChunkShape, DataType, }; +use super::{ArrayBytes, RawBytes}; /// A codec plugin. pub type CodecPlugin = Plugin; @@ -208,28 +209,6 @@ pub trait ArrayCodecTraits: CodecTraits { decoded_representation: &ChunkRepresentation, ) -> Result; - /// Encode a chunk. - /// - /// # Errors - /// Returns [`CodecError`] if a codec fails or `decoded_value` is incompatible with `decoded_representation`. - fn encode<'a>( - &self, - decoded_value: Cow<'a, [u8]>, - decoded_representation: &ChunkRepresentation, - options: &CodecOptions, - ) -> Result, CodecError>; - - /// Decode a chunk. - /// - /// # Errors - /// Returns [`CodecError`] if a codec fails or the decoded output is incompatible with `decoded_representation`. - fn decode<'a>( - &self, - encoded_value: Cow<'a, [u8]>, - decoded_representation: &ChunkRepresentation, - options: &CodecOptions, - ) -> Result, CodecError>; - /// Return the partial decode granularity. /// /// This represents the shape of the smallest subset of a chunk that can be efficiently decoded if the chunk were subdivided into a regular grid. @@ -255,7 +234,7 @@ pub trait BytesPartialDecoderTraits: Send + Sync { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError>; + ) -> Result>>, CodecError>; /// Partially decode bytes and concatenate. /// @@ -269,7 +248,7 @@ pub trait BytesPartialDecoderTraits: Send + Sync { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { Ok(self .partial_decode(decoded_regions, options)? .map(|vecs| Cow::Owned(vecs.concat()))) @@ -281,7 +260,7 @@ pub trait BytesPartialDecoderTraits: Send + Sync { /// /// # Errors /// Returns [`CodecError`] if a codec fails. - fn decode(&self, options: &CodecOptions) -> Result>, CodecError> { + fn decode(&self, options: &CodecOptions) -> Result>, CodecError> { Ok(self .partial_decode(&[ByteRange::FromStart(0, None)], options)? .map(|mut v| v.remove(0))) @@ -302,7 +281,7 @@ pub trait AsyncBytesPartialDecoderTraits: Send + Sync { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError>; + ) -> Result>>, CodecError>; /// Partially decode bytes and concatenate. /// @@ -314,8 +293,7 @@ pub trait AsyncBytesPartialDecoderTraits: Send + Sync { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>, CodecError> { - // FIXME: Remove default implementation in the next major release and implement for each codec to reduce internal allocations + ) -> Result>, CodecError> { Ok(self .partial_decode(decoded_regions, options) .await? @@ -328,7 +306,7 @@ pub trait AsyncBytesPartialDecoderTraits: Send + Sync { /// /// # Errors /// Returns [`CodecError`] if a codec fails. - async fn decode(&self, options: &CodecOptions) -> Result>, CodecError> { + async fn decode(&self, options: &CodecOptions) -> Result>, CodecError> { Ok(self .partial_decode(&[ByteRange::FromStart(0, None)], options) .await? @@ -351,7 +329,7 @@ pub trait ArrayPartialDecoderTraits: Send + Sync { fn partial_decode( &self, array_subsets: &[ArraySubset], - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { self.partial_decode_opt(array_subsets, &CodecOptions::default()) } @@ -361,7 +339,7 @@ pub trait ArrayPartialDecoderTraits: Send + Sync { &self, array_subsets: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError>; + ) -> Result>, CodecError>; } #[cfg(feature = "async")] @@ -378,7 +356,7 @@ pub trait AsyncArrayPartialDecoderTraits: Send + Sync { async fn partial_decode( &self, array_subsets: &[ArraySubset], - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { self.partial_decode_opt(array_subsets, &CodecOptions::default()) .await } @@ -388,7 +366,7 @@ pub trait AsyncArrayPartialDecoderTraits: Send + Sync { &self, array_subsets: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError>; + ) -> Result>, CodecError>; } /// A [`ReadableStorage`] store value partial decoder. @@ -409,7 +387,7 @@ impl BytesPartialDecoderTraits for StoragePartialDecoder { &self, decoded_regions: &[ByteRange], _options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(self .storage .get_partial_values_key(&self.key, decoded_regions)? @@ -444,7 +422,7 @@ impl AsyncBytesPartialDecoderTraits for AsyncStoragePartialDecoder { &self, decoded_regions: &[ByteRange], _options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(self .storage .get_partial_values_key(&self.key, decoded_regions) @@ -473,6 +451,28 @@ pub trait ArrayToArrayCodecTraits: decoded_representation: &ChunkRepresentation, ) -> Result; + /// Encode a chunk. + /// + /// # Errors + /// Returns [`CodecError`] if a codec fails or `bytes` is incompatible with `decoded_representation`. + fn encode<'a>( + &self, + bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError>; + + /// Decode a chunk. + /// + /// # Errors + /// Returns [`CodecError`] if a codec fails or the decoded output is incompatible with `decoded_representation`. + fn decode<'a>( + &self, + bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError>; + /// Initialise a partial decoder. /// /// `parallel` only affects parallelism on initialisation, which is irrelevant for most codecs. @@ -519,6 +519,28 @@ pub trait ArrayToBytesCodecTraits: decoded_representation: &ChunkRepresentation, ) -> Result; + /// Encode a chunk. + /// + /// # Errors + /// Returns [`CodecError`] if a codec fails or `bytes` is incompatible with `decoded_representation`. + fn encode<'a>( + &self, + bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError>; + + /// Decode a chunk. + /// + /// # Errors + /// Returns [`CodecError`] if a codec fails or the decoded output is incompatible with `decoded_representation`. + fn decode<'a>( + &self, + bytes: RawBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError>; + /// Initialise a partial decoder. /// /// # Errors @@ -569,9 +591,9 @@ pub trait BytesToBytesCodecTraits: CodecTraits + dyn_clone::DynClone + core::fmt /// Returns [`CodecError`] if a codec fails. fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + decoded_value: RawBytes<'a>, options: &CodecOptions, - ) -> Result, CodecError>; + ) -> Result, CodecError>; /// Decode chunk bytes. // @@ -579,10 +601,10 @@ pub trait BytesToBytesCodecTraits: CodecTraits + dyn_clone::DynClone + core::fmt /// Returns [`CodecError`] if a codec fails. fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + encoded_value: RawBytes<'a>, decoded_representation: &BytesRepresentation, options: &CodecOptions, - ) -> Result, CodecError>; + ) -> Result, CodecError>; /// Initialises a partial decoder. /// @@ -615,7 +637,7 @@ impl BytesPartialDecoderTraits for std::io::Cursor<&[u8]> { &self, decoded_regions: &[ByteRange], _parallel: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(Some( extract_byte_ranges_read_seek(&mut self.clone(), decoded_regions)? .into_iter() @@ -625,12 +647,12 @@ impl BytesPartialDecoderTraits for std::io::Cursor<&[u8]> { } } -impl BytesPartialDecoderTraits for std::io::Cursor> { +impl BytesPartialDecoderTraits for std::io::Cursor> { fn partial_decode( &self, decoded_regions: &[ByteRange], _parallel: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(Some( extract_byte_ranges_read_seek(&mut self.clone(), decoded_regions)? .into_iter() @@ -645,7 +667,7 @@ impl BytesPartialDecoderTraits for std::io::Cursor> { &self, decoded_regions: &[ByteRange], _parallel: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(Some( extract_byte_ranges_read_seek(&mut self.clone(), decoded_regions)? .into_iter() @@ -662,7 +684,7 @@ impl AsyncBytesPartialDecoderTraits for std::io::Cursor<&[u8]> { &self, decoded_regions: &[ByteRange], _parallel: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(Some( extract_byte_ranges_read_seek(&mut self.clone(), decoded_regions)? .into_iter() @@ -674,12 +696,12 @@ impl AsyncBytesPartialDecoderTraits for std::io::Cursor<&[u8]> { #[cfg(feature = "async")] #[async_trait::async_trait] -impl AsyncBytesPartialDecoderTraits for std::io::Cursor> { +impl AsyncBytesPartialDecoderTraits for std::io::Cursor> { async fn partial_decode( &self, decoded_regions: &[ByteRange], _parallel: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(Some( extract_byte_ranges_read_seek(&mut self.clone(), decoded_regions)? .into_iter() @@ -696,7 +718,7 @@ impl AsyncBytesPartialDecoderTraits for std::io::Cursor> { &self, decoded_regions: &[ByteRange], _parallel: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(Some( extract_byte_ranges_read_seek(&mut self.clone(), decoded_regions)? .into_iter() @@ -733,9 +755,21 @@ pub enum CodecError { /// Unsupported data type #[error("Unsupported data type {0} for codec {1}")] UnsupportedDataType(DataType, String), + /// Offsets are not [`None`] with a fixed length data type. + #[error("Offsets are invalid or are not compatible with the data type (e.g. fixed-sized data types)")] + InvalidOffsets, /// Other #[error("{_0}")] Other(String), + /// Invalid variable sized array offsets. + #[error("Invalid variable sized array offsets")] + InvalidVariableSizedArrayOffsets, + /// Expected fixed length bytes. + #[error("Expected fixed length array bytes")] + ExpectedFixedLengthBytes, + /// Expected variable length bytes. + #[error("Expected variable length array bytes")] + ExpectedVariableLengthBytes, } impl From<&str> for CodecError { diff --git a/src/array/codec/array_partial_decoder_cache.rs b/src/array/codec/array_partial_decoder_cache.rs index 6ed0858b..d83c37e7 100644 --- a/src/array/codec/array_partial_decoder_cache.rs +++ b/src/array/codec/array_partial_decoder_cache.rs @@ -1,11 +1,6 @@ //! A cache for partial decoders. -use std::{borrow::Cow, marker::PhantomData}; - -use crate::{ - array::{ChunkRepresentation, DataType}, - array_subset::IncompatibleArraySubsetAndShapeError, -}; +use crate::array::{ArrayBytes, ChunkRepresentation, DataType}; use super::{ArrayPartialDecoderTraits, ArraySubset, CodecError, CodecOptions}; @@ -15,8 +10,7 @@ use super::AsyncArrayPartialDecoderTraits; /// A cache for an [`ArrayPartialDecoderTraits`] partial decoder. pub struct ArrayPartialDecoderCache<'a> { decoded_representation: ChunkRepresentation, - cache: Vec, - phantom: PhantomData<&'a ()>, + cache: ArrayBytes<'a>, } impl<'a> ArrayPartialDecoderCache<'a> { @@ -29,7 +23,7 @@ impl<'a> ArrayPartialDecoderCache<'a> { decoded_representation: ChunkRepresentation, options: &CodecOptions, ) -> Result { - let cache = input_handle + let bytes = input_handle .partial_decode_opt( &[ArraySubset::new_with_shape( decoded_representation.shape_u64(), @@ -40,8 +34,7 @@ impl<'a> ArrayPartialDecoderCache<'a> { .into_owned(); Ok(Self { decoded_representation, - cache, - phantom: PhantomData, + cache: bytes, }) } @@ -55,7 +48,7 @@ impl<'a> ArrayPartialDecoderCache<'a> { decoded_representation: ChunkRepresentation, options: &CodecOptions, ) -> Result, CodecError> { - let cache = input_handle + let bytes = input_handle .partial_decode_opt( &[ArraySubset::new_with_shape( decoded_representation.shape_u64(), @@ -67,8 +60,7 @@ impl<'a> ArrayPartialDecoderCache<'a> { .into_owned(); Ok(Self { decoded_representation, - cache, - phantom: PhantomData, + cache: bytes, }) } } @@ -82,21 +74,15 @@ impl<'a> ArrayPartialDecoderTraits for ArrayPartialDecoderCache<'a> { &self, decoded_regions: &[ArraySubset], _options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { let mut out = Vec::with_capacity(decoded_regions.len()); let array_shape = self.decoded_representation.shape_u64(); - let element_size = self.decoded_representation.element_size(); for array_subset in decoded_regions { - out.push(Cow::Owned( - array_subset - .extract_bytes(&self.cache, &array_shape, element_size) - .map_err(|_| { - IncompatibleArraySubsetAndShapeError::from(( - array_subset.clone(), - self.decoded_representation.shape_u64(), - )) - })?, - )); + out.push(self.cache.extract_array_subset( + array_subset, + &array_shape, + self.decoded_representation.data_type(), + )?); } Ok(out) } @@ -113,7 +99,7 @@ impl<'a> AsyncArrayPartialDecoderTraits for ArrayPartialDecoderCache<'a> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { ArrayPartialDecoderTraits::partial_decode_opt(self, decoded_regions, options) } } diff --git a/src/array/codec/array_to_array/bitround.rs b/src/array/codec/array_to_array/bitround.rs index 9da4292f..56f01e39 100644 --- a/src/array/codec/array_to_array/bitround.rs +++ b/src/array/codec/array_to_array/bitround.rs @@ -175,7 +175,7 @@ fn round_bytes(bytes: &mut [u8], data_type: &DataType, keepbits: u32) -> Result< #[cfg(test)] mod tests { - use std::{borrow::Cow, num::NonZeroU64}; + use std::num::NonZeroU64; use array_representation::ChunkRepresentation; use itertools::Itertools; @@ -183,10 +183,8 @@ mod tests { use crate::{ array::{ array_representation, - codec::{ - ArrayCodecTraits, ArrayToArrayCodecTraits, ArrayToBytesCodecTraits, BytesCodec, - CodecOptions, - }, + codec::{ArrayToArrayCodecTraits, ArrayToBytesCodecTraits, BytesCodec, CodecOptions}, + ArrayBytes, }, array_subset::ArraySubset, }; @@ -217,25 +215,24 @@ mod tests { 98765.43210, ]; let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes = ArrayBytes::from(bytes); let codec_configuration: BitroundCodecConfiguration = serde_json::from_str(JSON).unwrap(); let codec = BitroundCodec::new_with_configuration(&codec_configuration); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) .unwrap(); let decoded = codec - .decode( - Cow::Borrowed(&encoded), - &chunk_representation, - &CodecOptions::default(), - ) + .decode(encoded, &chunk_representation, &CodecOptions::default()) .unwrap(); - let decoded_elements = crate::array::transmute_from_bytes_vec::(decoded.to_vec()); + let decoded_elements = crate::array::transmute_from_bytes_vec::( + decoded.into_fixed().unwrap().into_owned(), + ); assert_eq!(decoded_elements, &[0.0f32, 1.25f32, -8.0f32, 98304.0f32]); } @@ -250,25 +247,24 @@ mod tests { .unwrap(); let elements: Vec = vec![0, 1024, 1280, 1664, 1685, 123145182, 4294967295]; let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes = ArrayBytes::from(bytes); let codec_configuration: BitroundCodecConfiguration = serde_json::from_str(JSON).unwrap(); let codec = BitroundCodec::new_with_configuration(&codec_configuration); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) .unwrap(); let decoded = codec - .decode( - Cow::Borrowed(&encoded), - &chunk_representation, - &CodecOptions::default(), - ) + .decode(encoded, &chunk_representation, &CodecOptions::default()) .unwrap(); - let decoded_elements = crate::array::transmute_from_bytes_vec::(decoded.to_vec()); + let decoded_elements = crate::array::transmute_from_bytes_vec::( + decoded.into_fixed().unwrap().into_owned(), + ); for element in &decoded_elements { println!("{element} -> {element:#b}"); } @@ -289,25 +285,24 @@ mod tests { .unwrap(); let elements: Vec = vec![0, 3, 7, 15, 17, 54, 89, 128, 255]; let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes = ArrayBytes::from(bytes); let codec_configuration: BitroundCodecConfiguration = serde_json::from_str(JSON).unwrap(); let codec = BitroundCodec::new_with_configuration(&codec_configuration); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) .unwrap(); let decoded = codec - .decode( - Cow::Borrowed(&encoded), - &chunk_representation, - &CodecOptions::default(), - ) + .decode(encoded, &chunk_representation, &CodecOptions::default()) .unwrap(); - let decoded_elements = crate::array::transmute_from_bytes_vec::(decoded.to_vec()); + let decoded_elements = crate::array::transmute_from_bytes_vec::( + decoded.into_fixed().unwrap().into_owned(), + ); for element in &decoded_elements { println!("{element} -> {element:#b}"); } @@ -327,20 +322,21 @@ mod tests { 0.0f32.into(), ) .unwrap(); - let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = crate::array::transmute_to_bytes_vec(elements).into(); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) - .unwrap(); + .unwrap() + .into_owned(); let decoded_regions = [ ArraySubset::new_with_ranges(&[3..5]), ArraySubset::new_with_ranges(&[17..21]), ]; - let input_handle = Box::new(std::io::Cursor::new(encoded)); + let input_handle = Box::new(std::io::Cursor::new(encoded.into_fixed().unwrap())); let bytes_codec = BytesCodec::default(); let input_handle = bytes_codec .partial_decoder( @@ -361,7 +357,11 @@ mod tests { .unwrap(); let decoded_partial_chunk = decoded_partial_chunk .into_iter() - .map(|bytes| crate::array::convert_from_bytes_slice::(&bytes)) + .map(|bytes| { + crate::array::transmute_from_bytes_vec::( + bytes.into_fixed().unwrap().into_owned(), + ) + }) .collect_vec(); let answer: &[Vec] = &[vec![3.0, 4.0], vec![16.0, 16.0, 20.0, 20.0]]; assert_eq!(answer, decoded_partial_chunk); @@ -382,10 +382,11 @@ mod tests { ) .unwrap(); let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes = ArrayBytes::from(bytes); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -394,7 +395,7 @@ mod tests { ArraySubset::new_with_ranges(&[3..5]), ArraySubset::new_with_ranges(&[17..21]), ]; - let input_handle = Box::new(std::io::Cursor::new(encoded)); + let input_handle = Box::new(std::io::Cursor::new(encoded.into_fixed().unwrap())); let bytes_codec = BytesCodec::default(); let input_handle = bytes_codec .async_partial_decoder( @@ -418,7 +419,11 @@ mod tests { .unwrap(); let decoded_partial_chunk = decoded_partial_chunk .into_iter() - .map(|bytes| crate::array::convert_from_bytes_slice::(&bytes)) + .map(|bytes| { + crate::array::transmute_from_bytes_vec::( + bytes.into_fixed().unwrap().into_owned(), + ) + }) .collect_vec(); let answer: &[Vec] = &[vec![3.0, 4.0], vec![16.0, 16.0, 20.0, 20.0]]; assert_eq!(answer, decoded_partial_chunk); diff --git a/src/array/codec/array_to_array/bitround/bitround_codec.rs b/src/array/codec/array_to_array/bitround/bitround_codec.rs index 31611eab..c467cbb4 100644 --- a/src/array/codec/array_to_array/bitround/bitround_codec.rs +++ b/src/array/codec/array_to_array/bitround/bitround_codec.rs @@ -1,9 +1,7 @@ -use std::borrow::Cow; - use crate::{ array::{ codec::{ - options::CodecOptions, ArrayCodecTraits, ArrayPartialDecoderTraits, + options::CodecOptions, ArrayBytes, ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToArrayCodecTraits, CodecError, CodecTraits, RecommendedConcurrency, }, ArrayMetadataOptions, ChunkRepresentation, DataType, @@ -76,33 +74,34 @@ impl ArrayCodecTraits for BitroundCodec { // TODO: bitround is well suited to multithread, when is it optimal to kick in? Ok(RecommendedConcurrency::new_maximum(1)) } +} +#[cfg_attr(feature = "async", async_trait::async_trait)] +impl ArrayToArrayCodecTraits for BitroundCodec { fn encode<'a>( &self, - mut decoded_value: Cow<'a, [u8]>, + bytes: ArrayBytes<'a>, decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { + let mut bytes = bytes.into_fixed()?; round_bytes( - decoded_value.to_mut(), + bytes.to_mut(), decoded_representation.data_type(), self.keepbits, )?; - Ok(decoded_value) + Ok(ArrayBytes::from(bytes)) } fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + bytes: ArrayBytes<'a>, _decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { - Ok(encoded_value) + ) -> Result, CodecError> { + Ok(bytes) } -} -#[cfg_attr(feature = "async", async_trait::async_trait)] -impl ArrayToArrayCodecTraits for BitroundCodec { fn partial_decoder<'a>( &'a self, input_handle: Box, diff --git a/src/array/codec/array_to_array/bitround/bitround_partial_decoder.rs b/src/array/codec/array_to_array/bitround/bitround_partial_decoder.rs index 678abc99..1d520d27 100644 --- a/src/array/codec/array_to_array/bitround/bitround_partial_decoder.rs +++ b/src/array/codec/array_to_array/bitround/bitround_partial_decoder.rs @@ -1,8 +1,6 @@ -use std::borrow::Cow; - use crate::{ array::{ - codec::{ArrayPartialDecoderTraits, CodecError, CodecOptions}, + codec::{ArrayBytes, ArrayPartialDecoderTraits, CodecError, CodecOptions}, DataType, }, array_subset::ArraySubset, @@ -61,16 +59,19 @@ impl ArrayPartialDecoderTraits for BitroundPartialDecoder<'_> { &self, array_subsets: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { - let mut bytes = self + ) -> Result>, CodecError> { + let bytes = self .input_handle .partial_decode_opt(array_subsets, options)?; - for bytes in &mut bytes { + let mut bytes_out = Vec::with_capacity(bytes.len()); + for bytes in bytes { + let mut bytes = bytes.into_fixed()?; round_bytes(bytes.to_mut(), &self.data_type, self.keepbits)?; + bytes_out.push(bytes.into()); } - Ok(bytes) + Ok(bytes_out) } } @@ -126,16 +127,19 @@ impl AsyncArrayPartialDecoderTraits for AsyncBitroundPartialDecoder<'_> { &self, array_subsets: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { - let mut bytes = self + ) -> Result>, CodecError> { + let bytes = self .input_handle .partial_decode_opt(array_subsets, options) .await?; - for bytes in &mut bytes { + let mut bytes_out = Vec::with_capacity(bytes.len()); + for bytes in bytes { + let mut bytes = bytes.into_fixed()?; round_bytes(bytes.to_mut(), &self.data_type, self.keepbits)?; + bytes_out.push(bytes.into()); } - Ok(bytes) + Ok(bytes_out) } } diff --git a/src/array/codec/array_to_array/transpose.rs b/src/array/codec/array_to_array/transpose.rs index 89dee8ce..33706274 100644 --- a/src/array/codec/array_to_array/transpose.rs +++ b/src/array/codec/array_to_array/transpose.rs @@ -14,7 +14,11 @@ pub use crate::metadata::v3::codec::transpose::{ pub use transpose_codec::TransposeCodec; use crate::{ - array::codec::{Codec, CodecPlugin}, + array::{ + array_bytes::RawBytesOffsets, + codec::{Codec, CodecPlugin}, + ArrayBytes, RawBytes, + }, metadata::v3::{codec::transpose, MetadataV3}, plugin::{PluginCreateError, PluginMetadataInvalidError}, }; @@ -90,17 +94,41 @@ fn permute(v: &[T], order: &TransposeOrder) -> Vec { vec } +fn transpose_vlen<'a>( + bytes: &RawBytes, + offsets: &RawBytesOffsets, + shape: &[usize], + order: Vec, +) -> ArrayBytes<'a> { + debug_assert_eq!(shape.len(), order.len()); + + // Get the transposed element indices + let ndarray_indices = + ndarray::ArrayD::from_shape_vec(shape, (0..shape.iter().product()).collect()).unwrap(); + let ndarray_indices_transposed = ndarray_indices.permuted_axes(order); + + // Collect the new bytes/offsets + let mut bytes_new = Vec::with_capacity(bytes.len()); + let mut offsets_new = Vec::with_capacity(offsets.len()); + for idx in &ndarray_indices_transposed { + offsets_new.push(bytes_new.len()); + let curr = offsets[*idx]; + let next = offsets[idx + 1]; + bytes_new.extend_from_slice(&bytes[curr..next]); + } + offsets_new.push(bytes_new.len()); + + ArrayBytes::new_vlen(bytes_new, offsets_new) +} + #[cfg(test)] mod tests { - use std::{borrow::Cow, num::NonZeroU64}; + use std::num::NonZeroU64; use crate::{ array::{ - codec::{ - ArrayCodecTraits, ArrayToArrayCodecTraits, ArrayToBytesCodecTraits, BytesCodec, - CodecOptions, - }, - ChunkRepresentation, DataType, FillValue, + codec::{ArrayToArrayCodecTraits, ArrayToBytesCodecTraits, BytesCodec, CodecOptions}, + ArrayBytes, ChunkRepresentation, DataType, FillValue, }, array_subset::ArraySubset, }; @@ -118,26 +146,25 @@ mod tests { fill_value, ) .unwrap(); - let bytes: Vec = (0..chunk_representation.size()).map(|s| s as u8).collect(); + let size = chunk_representation.num_elements_usize() + * chunk_representation.data_type().fixed_size().unwrap(); + let bytes: Vec = (0..size).map(|s| s as u8).collect(); + let bytes: ArrayBytes = bytes.into(); let configuration: TransposeCodecConfiguration = serde_json::from_str(json).unwrap(); let codec = TransposeCodec::new_with_configuration(&configuration).unwrap(); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) .unwrap(); let decoded = codec - .decode( - Cow::Borrowed(&encoded), - &chunk_representation, - &CodecOptions::default(), - ) + .decode(encoded, &chunk_representation, &CodecOptions::default()) .unwrap(); - assert_eq!(bytes, decoded.to_vec()); + assert_eq!(bytes, decoded); // let array = ndarray::ArrayViewD::from_shape(array_representation.shape(), &bytes).unwrap(); // let array_representation_transpose = @@ -179,20 +206,17 @@ mod tests { ) .unwrap(); let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); let encoded = codec - .encode( - Cow::Borrowed(&bytes), - &chunk_representation, - &CodecOptions::default(), - ) + .encode(bytes, &chunk_representation, &CodecOptions::default()) .unwrap(); let decoded_regions = [ ArraySubset::new_with_ranges(&[0..4, 0..4]), ArraySubset::new_with_ranges(&[1..3, 1..4]), ArraySubset::new_with_ranges(&[2..4, 0..2]), ]; - let input_handle = Box::new(std::io::Cursor::new(encoded)); + let input_handle = Box::new(std::io::Cursor::new(encoded.into_fixed().unwrap())); let bytes_codec = BytesCodec::default(); let input_handle = bytes_codec .partial_decoder( @@ -213,7 +237,9 @@ mod tests { .unwrap(); let decoded_partial_chunk = decoded_partial_chunk .into_iter() - .map(|bytes| crate::array::convert_from_bytes_slice::(&bytes)) + .map(|bytes| { + crate::array::convert_from_bytes_slice::(&bytes.into_fixed().unwrap()) + }) .collect::>(); let answer: &[Vec] = &[ vec![ @@ -239,10 +265,11 @@ mod tests { ) .unwrap(); let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -252,7 +279,7 @@ mod tests { ArraySubset::new_with_ranges(&[1..3, 1..4]), ArraySubset::new_with_ranges(&[2..4, 0..2]), ]; - let input_handle = Box::new(std::io::Cursor::new(encoded)); + let input_handle = Box::new(std::io::Cursor::new(encoded.into_fixed().unwrap())); let bytes_codec = BytesCodec::default(); let input_handle = bytes_codec .async_partial_decoder( @@ -276,7 +303,11 @@ mod tests { .unwrap(); let decoded_partial_chunk = decoded_partial_chunk .into_iter() - .map(|bytes| crate::array::convert_from_bytes_slice::(&bytes)) + .map(|bytes| { + crate::array::transmute_from_bytes_vec::( + bytes.into_fixed().unwrap().into_owned(), + ) + }) .collect::>(); let answer: &[Vec] = &[ vec![ diff --git a/src/array/codec/array_to_array/transpose/transpose_codec.rs b/src/array/codec/array_to_array/transpose/transpose_codec.rs index 69aca822..81b40308 100644 --- a/src/array/codec/array_to_array/transpose/transpose_codec.rs +++ b/src/array/codec/array_to_array/transpose/transpose_codec.rs @@ -1,14 +1,12 @@ -use std::borrow::Cow; - use crate::{ array::{ codec::{ - options::CodecOptions, ArrayCodecTraits, ArrayPartialDecoderTraits, + options::CodecOptions, ArrayBytes, ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToArrayCodecTraits, CodecError, CodecTraits, RecommendedConcurrency, }, ArrayMetadataOptions, ChunkRepresentation, }, - metadata::{v3::codec::transpose::TransposeCodecConfigurationV1, v3::MetadataV3}, + metadata::v3::{codec::transpose::TransposeCodecConfigurationV1, MetadataV3}, plugin::PluginCreateError, }; @@ -65,6 +63,90 @@ impl CodecTraits for TransposeCodec { #[cfg_attr(feature = "async", async_trait::async_trait)] impl ArrayToArrayCodecTraits for TransposeCodec { + fn encode<'a>( + &self, + bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + bytes.validate( + decoded_representation.num_elements(), + decoded_representation.data_type().size(), + )?; + + match bytes { + ArrayBytes::Variable(bytes, offsets) => { + let order_encode = self.order.0.clone(); + let shape = decoded_representation + .shape() + .iter() + .map(|s| usize::try_from(s.get()).unwrap()) + .collect::>(); + Ok(super::transpose_vlen( + &bytes, + &offsets, + &shape, + order_encode, + )) + } + ArrayBytes::Fixed(bytes) => { + let order_encode = + calculate_order_encode(&self.order, decoded_representation.shape().len()); + let data_type_size = decoded_representation.data_type().fixed_size().unwrap(); + let bytes = transpose_array( + &order_encode, + &decoded_representation.shape_u64(), + data_type_size, + &bytes, + ) + .map_err(|_| CodecError::Other("transpose_array invalid arguments?".to_string()))?; + Ok(ArrayBytes::from(bytes)) + } + } + } + + fn decode<'a>( + &self, + bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + bytes.validate( + decoded_representation.num_elements(), + decoded_representation.data_type().size(), + )?; + + match bytes { + ArrayBytes::Variable(bytes, offsets) => { + let mut order_decode = vec![0; decoded_representation.shape().len()]; + for (i, val) in self.order.0.iter().enumerate() { + order_decode[*val] = i; + } + let shape = decoded_representation + .shape() + .iter() + .map(|s| usize::try_from(s.get()).unwrap()) + .collect::>(); + Ok(super::transpose_vlen( + &bytes, + &offsets, + &shape, + order_decode, + )) + } + ArrayBytes::Fixed(bytes) => { + let order_decode = + calculate_order_decode(&self.order, decoded_representation.shape().len()); + let transposed_shape = permute(&decoded_representation.shape_u64(), &self.order); + let data_type_size = decoded_representation.data_type().fixed_size().unwrap(); + let bytes = + transpose_array(&order_decode, &transposed_shape, data_type_size, &bytes) + .map_err(|_| CodecError::Other("transpose_array error".to_string()))?; + Ok(ArrayBytes::from(bytes)) + } + } + } + fn partial_decoder<'a>( &'a self, input_handle: Box, @@ -119,60 +201,4 @@ impl ArrayCodecTraits for TransposeCodec { // TODO: This could be increased, need to implement `transpose_array` without ndarray Ok(RecommendedConcurrency::new_maximum(1)) } - - fn encode<'a>( - &self, - decoded_value: Cow<'a, [u8]>, - decoded_representation: &ChunkRepresentation, - _options: &CodecOptions, - ) -> Result, CodecError> { - if decoded_value.len() as u64 != decoded_representation.size() { - return Err(CodecError::UnexpectedChunkDecodedSize( - decoded_value.len(), - decoded_representation.size(), - )); - } - - if self.order.0.iter().copied().eq(0..self.order.0.len()) { - // Fast path for identity transform - Ok(decoded_value) - } else { - let len = decoded_value.len(); - let order_encode = - calculate_order_encode(&self.order, decoded_representation.shape().len()); - transpose_array( - &order_encode, - &decoded_representation.shape_u64(), - decoded_representation.element_size(), - &decoded_value, - ) - .map_err(|_| CodecError::UnexpectedChunkDecodedSize(len, decoded_representation.size())) - .map(Cow::Owned) - } - } - - fn decode<'a>( - &self, - encoded_value: Cow<'a, [u8]>, - decoded_representation: &ChunkRepresentation, - _options: &CodecOptions, - ) -> Result, CodecError> { - if self.order.0.iter().copied().eq(0..self.order.0.len()) { - // Fast path for identity transform - Ok(encoded_value) - } else { - let order_decode = - calculate_order_decode(&self.order, decoded_representation.shape().len()); - let transposed_shape = permute(&decoded_representation.shape_u64(), &self.order); - let len = encoded_value.len(); - transpose_array( - &order_decode, - &transposed_shape, - decoded_representation.element_size(), - &encoded_value, - ) - .map_err(|_| CodecError::UnexpectedChunkDecodedSize(len, decoded_representation.size())) - .map(Cow::Owned) - } - } } diff --git a/src/array/codec/array_to_array/transpose/transpose_partial_decoder.rs b/src/array/codec/array_to_array/transpose/transpose_partial_decoder.rs index 60874482..e7b0ba16 100644 --- a/src/array/codec/array_to_array/transpose/transpose_partial_decoder.rs +++ b/src/array/codec/array_to_array/transpose/transpose_partial_decoder.rs @@ -1,8 +1,6 @@ -use std::borrow::Cow; - use super::{calculate_order_decode, permute, transpose_array, TransposeOrder}; use crate::array::{ - codec::{ArrayPartialDecoderTraits, ArraySubset, CodecError, CodecOptions}, + codec::{ArrayBytes, ArrayPartialDecoderTraits, ArraySubset, CodecError, CodecOptions}, ChunkRepresentation, DataType, }; @@ -31,6 +29,77 @@ impl<'a> TransposePartialDecoder<'a> { } } +fn validate_regions( + decoded_regions: &[ArraySubset], + dimensionality: usize, +) -> Result<(), CodecError> { + for array_subset in decoded_regions { + if array_subset.dimensionality() != dimensionality { + return Err(CodecError::InvalidArraySubsetDimensionalityError( + array_subset.clone(), + dimensionality, + )); + } + } + Ok(()) +} + +fn get_decoded_regions_transposed( + order: &TransposeOrder, + decoded_regions: &[ArraySubset], +) -> Vec { + let mut decoded_regions_transposed = Vec::with_capacity(decoded_regions.len()); + for decoded_region in decoded_regions { + let start = permute(decoded_region.start(), order); + let size = permute(decoded_region.shape(), order); + let decoded_region_transpose = + unsafe { ArraySubset::new_with_start_shape_unchecked(start, size) }; + decoded_regions_transposed.push(decoded_region_transpose); + } + decoded_regions_transposed +} + +/// Reverse the transpose on each subset +fn do_transpose<'a>( + encoded_value: Vec>, + decoded_regions: &[ArraySubset], + order: &TransposeOrder, + decoded_representation: &ChunkRepresentation, +) -> Result>, CodecError> { + let order_decode = calculate_order_decode(order, decoded_representation.shape().len()); + let data_type_size = decoded_representation.data_type().size(); + std::iter::zip(decoded_regions, encoded_value) + .map(|(subset, bytes)| { + bytes.validate(subset.num_elements(), data_type_size)?; + match bytes { + ArrayBytes::Variable(bytes, offsets) => { + let mut order_decode = vec![0; decoded_representation.shape().len()]; + for (i, val) in order.0.iter().enumerate() { + order_decode[*val] = i; + } + Ok(super::transpose_vlen( + &bytes, + &offsets, + &subset.shape_usize(), + order_decode, + )) + } + ArrayBytes::Fixed(bytes) => { + let data_type_size = decoded_representation.data_type().fixed_size().unwrap(); + let bytes = transpose_array( + &order_decode, + &permute(subset.shape(), order), + data_type_size, + &bytes, + ) + .map_err(|_| CodecError::Other("transpose_array error".to_string()))?; + Ok(ArrayBytes::from(bytes)) + } + } + }) + .collect::, CodecError>>() +} + impl ArrayPartialDecoderTraits for TransposePartialDecoder<'_> { fn data_type(&self) -> &DataType { self.decoded_representation.data_type() @@ -40,57 +109,22 @@ impl ArrayPartialDecoderTraits for TransposePartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { - for array_subset in decoded_regions { - if array_subset.dimensionality() != self.decoded_representation.dimensionality() { - return Err(CodecError::InvalidArraySubsetDimensionalityError( - array_subset.clone(), - self.decoded_representation.dimensionality(), - )); - } - } - - // Get transposed array subsets - let mut decoded_regions_transposed = Vec::with_capacity(decoded_regions.len()); - for decoded_region in decoded_regions { - let start = permute(decoded_region.start(), &self.order); - let size = permute(decoded_region.shape(), &self.order); - let decoded_region_transpose = - unsafe { ArraySubset::new_with_start_shape_unchecked(start, size) }; - decoded_regions_transposed.push(decoded_region_transpose); - } + ) -> Result>, CodecError> { + validate_regions( + decoded_regions, + self.decoded_representation.dimensionality(), + )?; + let decoded_regions_transposed = + get_decoded_regions_transposed(&self.order, decoded_regions); let encoded_value = self .input_handle .partial_decode_opt(&decoded_regions_transposed, options)?; - - if self.order.0.iter().copied().eq(0..self.order.0.len()) { - // Fast path for identity transform - Ok(encoded_value) - } else { - // Reverse the transpose on each subset - let order_decode = - calculate_order_decode(&self.order, self.decoded_representation.shape().len()); - let decoded_value = std::iter::zip(decoded_regions, encoded_value) - .map(|(subset, bytes)| { - let len = bytes.len(); - transpose_array( - &order_decode, - &permute(subset.shape(), &self.order), - self.decoded_representation.element_size(), - &bytes, - ) - .map_err(|_| { - CodecError::UnexpectedChunkDecodedSize( - len, - subset.num_elements() - * self.decoded_representation.element_size() as u64, - ) - }) - .map(Cow::Owned) - }) - .collect::, _>>()?; - Ok(decoded_value) - } + do_transpose( + encoded_value, + decoded_regions, + &self.order, + &self.decoded_representation, + ) } } @@ -129,57 +163,22 @@ impl AsyncArrayPartialDecoderTraits for AsyncTransposePartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { - for array_subset in decoded_regions { - if array_subset.dimensionality() != self.decoded_representation.dimensionality() { - return Err(CodecError::InvalidArraySubsetDimensionalityError( - array_subset.clone(), - self.decoded_representation.dimensionality(), - )); - } - } - - // Get transposed array subsets - let mut decoded_regions_transposed = Vec::with_capacity(decoded_regions.len()); - for decoded_region in decoded_regions { - let start = permute(decoded_region.start(), &self.order); - let size = permute(decoded_region.shape(), &self.order); - let decoded_region_transpose = - unsafe { ArraySubset::new_with_start_shape_unchecked(start, size) }; - decoded_regions_transposed.push(decoded_region_transpose); - } + ) -> Result>, CodecError> { + validate_regions( + decoded_regions, + self.decoded_representation.dimensionality(), + )?; + let decoded_regions_transposed = + get_decoded_regions_transposed(&self.order, decoded_regions); let encoded_value = self .input_handle .partial_decode_opt(&decoded_regions_transposed, options) .await?; - - if self.order.0.iter().copied().eq(0..self.order.0.len()) { - // Fast path for identity transform - Ok(encoded_value) - } else { - // Reverse the transpose on each subset - let order_decode = - calculate_order_decode(&self.order, self.decoded_representation.shape().len()); - let decoded_value = std::iter::zip(decoded_regions, encoded_value) - .map(|(subset, bytes)| { - let len = bytes.len(); - transpose_array( - &order_decode, - &permute(subset.shape(), &self.order), - self.decoded_representation.element_size(), - &bytes, - ) - .map(Cow::Owned) - .map_err(|_| { - CodecError::UnexpectedChunkDecodedSize( - len, - subset.num_elements() - * self.decoded_representation.element_size() as u64, - ) - }) - }) - .collect::, _>>()?; - Ok(decoded_value) - } + do_transpose( + encoded_value, + decoded_regions, + &self.order, + &self.decoded_representation, + ) } } diff --git a/src/array/codec/array_to_bytes.rs b/src/array/codec/array_to_bytes.rs index 361df695..1d1b75f3 100644 --- a/src/array/codec/array_to_bytes.rs +++ b/src/array/codec/array_to_bytes.rs @@ -2,6 +2,8 @@ pub mod bytes; pub mod codec_chain; +pub mod vlen; +pub mod vlen_v2; #[cfg(feature = "pcodec")] pub mod pcodec; diff --git a/src/array/codec/array_to_bytes/bytes.rs b/src/array/codec/array_to_bytes/bytes.rs index 09562fba..cd465a17 100644 --- a/src/array/codec/array_to_bytes/bytes.rs +++ b/src/array/codec/array_to_bytes/bytes.rs @@ -66,17 +66,19 @@ pub fn reverse_endianness(v: &mut [u8], data_type: &DataType) { }; v.chunks_exact_mut(8).for_each(swap); } + // Variable-sized data types are not supported and are rejected outside of this function + DataType::String | DataType::Binary => unreachable!(), } } #[cfg(test)] mod tests { - use std::{borrow::Cow, num::NonZeroU64}; + use std::num::NonZeroU64; use crate::{ array::{ - codec::{ArrayCodecTraits, ArrayToBytesCodecTraits, CodecOptions, CodecTraits}, - ChunkRepresentation, ChunkShape, Endianness, FillValue, + codec::{ArrayToBytesCodecTraits, CodecOptions, CodecTraits}, + ArrayBytes, ChunkRepresentation, ChunkShape, FillValue, }, array_subset::ArraySubset, }; @@ -126,19 +128,21 @@ mod tests { let chunk_shape = vec![NonZeroU64::new(10).unwrap(), NonZeroU64::new(10).unwrap()]; let chunk_representation = ChunkRepresentation::new(chunk_shape, data_type, fill_value).unwrap(); - let bytes: Vec = (0..chunk_representation.size()).map(|s| s as u8).collect(); + let size = chunk_representation.num_elements_usize() + * chunk_representation.data_type().fixed_size().unwrap(); + let bytes: ArrayBytes = (0..size).map(|s| s as u8).collect::>().into(); let codec = BytesCodec::new(endianness); let encoded = codec.encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), )?; let decoded = codec .decode(encoded, &chunk_representation, &CodecOptions::default()) .unwrap(); - assert_eq!(bytes, decoded.to_vec()); + assert_eq!(bytes, decoded); Ok(()) } @@ -259,13 +263,13 @@ mod tests { ChunkRepresentation::new(chunk_shape.to_vec(), DataType::UInt8, FillValue::from(0u8)) .unwrap(); let elements: Vec = (0..chunk_representation.num_elements() as u8).collect(); - let bytes = elements; + let bytes: ArrayBytes = elements.into(); let codec = BytesCodec::new(None); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -285,7 +289,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) @@ -303,13 +307,13 @@ mod tests { ChunkRepresentation::new(chunk_shape.to_vec(), DataType::UInt8, FillValue::from(0u8)) .unwrap(); let elements: Vec = (0..chunk_representation.num_elements() as u8).collect(); - let bytes = elements; + let bytes: ArrayBytes = elements.into(); let codec = BytesCodec::new(None); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -331,7 +335,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) diff --git a/src/array/codec/array_to_bytes/bytes/bytes_codec.rs b/src/array/codec/array_to_bytes/bytes/bytes_codec.rs index eddd147c..936be8a2 100644 --- a/src/array/codec/array_to_bytes/bytes/bytes_codec.rs +++ b/src/array/codec/array_to_bytes/bytes/bytes_codec.rs @@ -1,7 +1,5 @@ // Note: No validation that this codec is created *without* a specified endianness for multi-byte data types. -use std::borrow::Cow; - use crate::{ array::{ codec::{ @@ -9,7 +7,8 @@ use crate::{ BytesPartialDecoderTraits, CodecError, CodecOptions, CodecTraits, RecommendedConcurrency, }, - ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, + ArrayBytes, ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, DataTypeSize, + RawBytes, }, metadata::v3::MetadataV3, }; @@ -19,7 +18,7 @@ use crate::array::codec::{AsyncArrayPartialDecoderTraits, AsyncBytesPartialDecod use super::{ bytes_partial_decoder, reverse_endianness, BytesCodecConfiguration, BytesCodecConfigurationV1, - Endianness, IDENTIFIER, NATIVE_ENDIAN, + Endianness, NATIVE_ENDIAN, }; /// A `bytes` codec implementation. @@ -64,20 +63,30 @@ impl BytesCodec { fn do_encode_or_decode<'a>( &self, - mut value: Cow<'a, [u8]>, + mut value: RawBytes<'a>, decoded_representation: &ChunkRepresentation, - ) -> Result, CodecError> { - if value.len() as u64 != decoded_representation.size() { - return Err(CodecError::UnexpectedChunkDecodedSize( - value.len(), - decoded_representation.size(), - )); - } else if decoded_representation.element_size() > 1 && self.endian.is_none() { - return Err(CodecError::Other(format!( - "tried to encode an array with element size {} with endianness None", - decoded_representation.size() - ))); - } + ) -> Result, CodecError> { + match decoded_representation.data_type().size() { + DataTypeSize::Variable => { + return Err(CodecError::UnsupportedDataType( + decoded_representation.data_type().clone(), + super::IDENTIFIER.to_string(), + )) + } + DataTypeSize::Fixed(data_type_size) => { + let array_size = decoded_representation.num_elements() * data_type_size as u64; + if value.len() as u64 != array_size { + return Err(CodecError::UnexpectedChunkDecodedSize( + value.len(), + array_size, + )); + } else if data_type_size > 1 && self.endian.is_none() { + return Err(CodecError::Other(format!( + "tried to encode an array with element size {data_type_size} with endianness None" + ))); + } + } + }; if let Some(endian) = &self.endian { if !endian.is_native() { @@ -93,7 +102,10 @@ impl CodecTraits for BytesCodec { let configuration = BytesCodecConfigurationV1 { endian: self.endian, }; - Some(MetadataV3::new_with_serializable_configuration(IDENTIFIER, &configuration).unwrap()) + Some( + MetadataV3::new_with_serializable_configuration(super::IDENTIFIER, &configuration) + .unwrap(), + ) } fn partial_decoder_should_cache_input(&self) -> bool { @@ -124,28 +136,35 @@ impl ArrayCodecTraits for BytesCodec { // } Ok(RecommendedConcurrency::new_maximum(1)) } +} +#[cfg_attr(feature = "async", async_trait::async_trait)] +impl ArrayToBytesCodecTraits for BytesCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + bytes: ArrayBytes<'a>, decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { - self.do_encode_or_decode(decoded_value, decoded_representation) + ) -> Result, CodecError> { + bytes.validate( + decoded_representation.num_elements(), + decoded_representation.data_type().size(), + )?; + let bytes = bytes.into_fixed()?; + self.do_encode_or_decode(bytes, decoded_representation) } fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + bytes: RawBytes<'a>, decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { - self.do_encode_or_decode(encoded_value, decoded_representation) + ) -> Result, CodecError> { + Ok(ArrayBytes::from( + self.do_encode_or_decode(bytes, decoded_representation)?, + )) } -} -#[cfg_attr(feature = "async", async_trait::async_trait)] -impl ArrayToBytesCodecTraits for BytesCodec { fn partial_decoder<'a>( &self, input_handle: Box, @@ -179,8 +198,16 @@ impl ArrayToBytesCodecTraits for BytesCodec { &self, decoded_representation: &ChunkRepresentation, ) -> Result { - Ok(BytesRepresentation::FixedSize( - decoded_representation.num_elements() * decoded_representation.element_size() as u64, - )) + match decoded_representation.data_type().size() { + DataTypeSize::Variable => { + return Err(CodecError::UnsupportedDataType( + decoded_representation.data_type().clone(), + super::IDENTIFIER.to_string(), + )) + } + DataTypeSize::Fixed(data_type_size) => Ok(BytesRepresentation::FixedSize( + decoded_representation.num_elements() * data_type_size as u64, + )), + } } } diff --git a/src/array/codec/array_to_bytes/bytes/bytes_partial_decoder.rs b/src/array/codec/array_to_bytes/bytes/bytes_partial_decoder.rs index 75f08fb5..799cbc11 100644 --- a/src/array/codec/array_to_bytes/bytes/bytes_partial_decoder.rs +++ b/src/array/codec/array_to_bytes/bytes/bytes_partial_decoder.rs @@ -6,7 +6,7 @@ use crate::{ ArrayPartialDecoderTraits, ArraySubset, BytesPartialDecoderTraits, CodecError, CodecOptions, }, - ChunkRepresentation, DataType, + ArrayBytes, ChunkRepresentation, DataType, DataTypeSize, }, array_subset::IncompatibleArraySubsetAndShapeError, }; @@ -47,47 +47,57 @@ impl ArrayPartialDecoderTraits for BytesPartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { let mut bytes = Vec::with_capacity(decoded_regions.len()); let chunk_shape = self.decoded_representation.shape_u64(); for array_subset in decoded_regions { - // Get byte ranges - let byte_ranges = array_subset - .byte_ranges(&chunk_shape, self.decoded_representation.element_size()) - .map_err(|_| { - IncompatibleArraySubsetAndShapeError::from(( - array_subset.clone(), - self.decoded_representation.shape_u64(), + match self.decoded_representation.data_type().size() { + DataTypeSize::Variable => { + return Err(CodecError::UnsupportedDataType( + self.data_type().clone(), + super::IDENTIFIER.to_string(), )) - })?; - - // Decode - let decoded = self - .input_handle - .partial_decode_concat(&byte_ranges, options)? - .map_or_else( - || { - Cow::Owned( - self.decoded_representation - .fill_value() - .as_ne_bytes() - .repeat(array_subset.num_elements_usize()), - ) - }, - |mut decoded| { - if let Some(endian) = &self.endian { - if !endian.is_native() { - reverse_endianness( - decoded.to_mut(), - self.decoded_representation.data_type(), - ); - } - } - decoded - }, - ); - - bytes.push(decoded); + } + DataTypeSize::Fixed(data_type_size) => { + // Get byte ranges + let byte_ranges = array_subset + .byte_ranges(&chunk_shape, data_type_size) + .map_err(|_| { + IncompatibleArraySubsetAndShapeError::from(( + array_subset.clone(), + self.decoded_representation.shape_u64(), + )) + })?; + + // Decode + let decoded = self + .input_handle + .partial_decode_concat(&byte_ranges, options)? + .map_or_else( + || { + Cow::Owned( + self.decoded_representation + .fill_value() + .as_ne_bytes() + .repeat(array_subset.num_elements_usize()), + ) + }, + |mut decoded| { + if let Some(endian) = &self.endian { + if !endian.is_native() { + reverse_endianness( + decoded.to_mut(), + self.decoded_representation.data_type(), + ); + } + } + decoded + }, + ); + + bytes.push(ArrayBytes::from(decoded)); + } + } } Ok(bytes) } @@ -128,7 +138,7 @@ impl AsyncArrayPartialDecoderTraits for AsyncBytesPartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { for array_subset in decoded_regions { if array_subset.dimensionality() != self.decoded_representation.dimensionality() { return Err(CodecError::InvalidArraySubsetDimensionalityError( @@ -149,14 +159,22 @@ impl AsyncArrayPartialDecoderTraits for AsyncBytesPartialDecoder<'_> { } // Get byte ranges - let byte_ranges = array_subset - .byte_ranges(&chunk_shape, self.decoded_representation.element_size()) - .map_err(|_| { - IncompatibleArraySubsetAndShapeError::from(( - array_subset.clone(), - self.decoded_representation.shape_u64(), + let byte_ranges = match self.decoded_representation.element_size() { + DataTypeSize::Variable => { + return Err(CodecError::UnsupportedDataType( + self.data_type().clone(), + super::IDENTIFIER.to_string(), )) - })?; + } + DataTypeSize::Fixed(data_type_size) => array_subset + .byte_ranges(&chunk_shape, data_type_size) + .map_err(|_| { + IncompatibleArraySubsetAndShapeError::from(( + array_subset.clone(), + self.decoded_representation.shape_u64(), + )) + })?, + }; // Decode let decoded = self @@ -185,7 +203,7 @@ impl AsyncArrayPartialDecoderTraits for AsyncBytesPartialDecoder<'_> { }, ); - bytes.push(decoded); + bytes.push(ArrayBytes::from(decoded)); } Ok(bytes) } diff --git a/src/array/codec/array_to_bytes/codec_chain.rs b/src/array/codec/array_to_bytes/codec_chain.rs index 36c6dae4..fb88ba44 100644 --- a/src/array/codec/array_to_bytes/codec_chain.rs +++ b/src/array/codec/array_to_bytes/codec_chain.rs @@ -1,7 +1,5 @@ //! An array to bytes codec formed by joining an array to array sequence, array to bytes, and bytes to bytes sequence of codecs. -use std::borrow::Cow; - use crate::{ array::{ codec::{ @@ -11,7 +9,8 @@ use crate::{ CodecTraits, }, concurrency::RecommendedConcurrency, - ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, ChunkShape, + ArrayBytes, ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, ChunkShape, + RawBytes, }, metadata::v3::MetadataV3, plugin::PluginCreateError, @@ -225,6 +224,81 @@ impl CodecTraits for CodecChain { #[cfg_attr(feature = "async", async_trait::async_trait)] impl ArrayToBytesCodecTraits for CodecChain { + fn encode<'a>( + &self, + mut bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError> { + bytes.validate( + decoded_representation.num_elements(), + decoded_representation.data_type().size(), + )?; + + let mut decoded_representation = decoded_representation.clone(); + + // array->array + for codec in &self.array_to_array { + bytes = codec.encode(bytes, &decoded_representation, options)?; + decoded_representation = codec.compute_encoded_size(&decoded_representation)?; + } + + // array->bytes + let mut bytes = self + .array_to_bytes + .encode(bytes, &decoded_representation, options)?; + let mut decoded_representation = self + .array_to_bytes + .compute_encoded_size(&decoded_representation)?; + + // bytes->bytes + for codec in &self.bytes_to_bytes { + bytes = codec.encode(bytes, options)?; + decoded_representation = codec.compute_encoded_size(&decoded_representation); + } + + Ok(bytes) + } + + fn decode<'a>( + &self, + mut bytes: RawBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError> { + let array_representations = + self.get_array_representations(decoded_representation.clone())?; + let bytes_representations = + self.get_bytes_representations(array_representations.last().unwrap())?; + + // bytes->bytes + for (codec, bytes_representation) in std::iter::zip( + self.bytes_to_bytes.iter().rev(), + bytes_representations.iter().rev().skip(1), + ) { + bytes = codec.decode(bytes, bytes_representation, options)?; + } + + // bytes->array + let mut bytes = + self.array_to_bytes + .decode(bytes, array_representations.last().unwrap(), options)?; + + // array->array + for (codec, array_representation) in std::iter::zip( + self.array_to_array.iter().rev(), + array_representations.iter().rev().skip(1), + ) { + bytes = codec.decode(bytes, array_representation, options)?; + } + + bytes.validate( + decoded_representation.num_elements(), + decoded_representation.data_type().size(), + )?; + Ok(bytes) + } + fn partial_decoder<'a>( &'a self, mut input_handle: Box, @@ -427,90 +501,6 @@ impl ArrayCodecTraits for CodecChain { Ok(recommended_concurrency) } - - fn encode<'a>( - &self, - decoded_value: Cow<'a, [u8]>, - decoded_representation: &ChunkRepresentation, - options: &CodecOptions, - ) -> Result, CodecError> { - if decoded_value.len() as u64 != decoded_representation.size() { - return Err(CodecError::UnexpectedChunkDecodedSize( - decoded_value.len(), - decoded_representation.size(), - )); - } - - let mut decoded_representation = decoded_representation.clone(); - - let mut value = decoded_value; - // array->array - for codec in &self.array_to_array { - value = codec.encode(value, &decoded_representation, options)?; - decoded_representation = codec.compute_encoded_size(&decoded_representation)?; - } - - // array->bytes - value = self - .array_to_bytes - .encode(value, &decoded_representation, options)?; - let mut decoded_representation = self - .array_to_bytes - .compute_encoded_size(&decoded_representation)?; - - // bytes->bytes - for codec in &self.bytes_to_bytes { - value = codec.encode(value, options)?; - decoded_representation = codec.compute_encoded_size(&decoded_representation); - } - - Ok(value) - } - - fn decode<'a>( - &self, - mut encoded_value: Cow<'a, [u8]>, - decoded_representation: &ChunkRepresentation, - options: &CodecOptions, - ) -> Result, CodecError> { - let array_representations = - self.get_array_representations(decoded_representation.clone())?; - let bytes_representations = - self.get_bytes_representations(array_representations.last().unwrap())?; - - // bytes->bytes - for (codec, bytes_representation) in std::iter::zip( - self.bytes_to_bytes.iter().rev(), - bytes_representations.iter().rev().skip(1), - ) { - encoded_value = codec.decode(encoded_value, bytes_representation, options)?; - } - - // bytes->array - encoded_value = self.array_to_bytes.decode( - encoded_value, - array_representations.last().unwrap(), - options, - )?; - - // array->array - for (codec, array_representation) in std::iter::zip( - self.array_to_array.iter().rev(), - array_representations.iter().rev().skip(1), - ) { - encoded_value = codec.decode(encoded_value, array_representation, options)?; - } - - if encoded_value.len() as u64 != decoded_representation.size() { - return Err(CodecError::UnexpectedChunkDecodedSize( - encoded_value.len(), - decoded_representation.size(), - )); - } - - Ok(encoded_value) - } - fn partial_decode_granularity( &self, decoded_representation: &ChunkRepresentation, @@ -612,7 +602,7 @@ mod tests { decoded_regions: &[ArraySubset], decoded_partial_chunk_true: Vec, ) { - let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = crate::array::transmute_to_bytes_vec(elements).into(); let codec_configurations: Vec = vec![ #[cfg(feature = "transpose")] @@ -637,7 +627,7 @@ mod tests { let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -650,9 +640,9 @@ mod tests { ) .unwrap(); if not_just_bytes { - assert_ne!(encoded, decoded); + assert_ne!(encoded, decoded.clone().into_fixed().unwrap()); } - assert_eq!(bytes, decoded.to_vec()); + assert_eq!(bytes, decoded); // let encoded = codec // .par_encode(bytes.clone(), &chunk_representation) @@ -679,7 +669,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) diff --git a/src/array/codec/array_to_bytes/pcodec.rs b/src/array/codec/array_to_bytes/pcodec.rs index 9c9d71eb..cfe03b86 100644 --- a/src/array/codec/array_to_bytes/pcodec.rs +++ b/src/array/codec/array_to_bytes/pcodec.rs @@ -47,12 +47,13 @@ pub(crate) fn create_codec_pcodec(metadata: &MetadataV3) -> Result = (0..chunk_representation.size()).map(|s| s as u8).collect(); + let size = chunk_representation.num_elements_usize() + * chunk_representation.data_type().fixed_size().unwrap(); + let bytes: Vec = (0..size).map(|s| s as u8).collect(); + let bytes: ArrayBytes = bytes.into(); let max_encoded_size = codec.compute_encoded_size(&chunk_representation)?; let encoded = codec.encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), )?; @@ -93,7 +97,7 @@ mod tests { let decoded = codec .decode(encoded, &chunk_representation, &CodecOptions::default()) .unwrap(); - assert_eq!(bytes, decoded.to_vec()); + assert_eq!(bytes, decoded); Ok(()) } @@ -228,12 +232,13 @@ mod tests { .unwrap(); let elements: Vec = (0..chunk_representation.num_elements() as u32).collect(); let bytes = transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); let codec = PcodecCodec::new_with_configuration(&serde_json::from_str(JSON_VALID).unwrap()); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -253,7 +258,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().into_owned()) .flatten() .collect::>() .chunks(std::mem::size_of::()) @@ -275,12 +280,13 @@ mod tests { .unwrap(); let elements: Vec = (0..chunk_representation.num_elements() as u32).collect(); let bytes = transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); let codec = PcodecCodec::new_with_configuration(&serde_json::from_str(JSON_VALID).unwrap()); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -302,7 +308,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().into_owned()) .flatten() .collect::>() .chunks(std::mem::size_of::()) diff --git a/src/array/codec/array_to_bytes/pcodec/pcodec_codec.rs b/src/array/codec/array_to_bytes/pcodec/pcodec_codec.rs index 5d9be9f6..b3382d85 100644 --- a/src/array/codec/array_to_bytes/pcodec/pcodec_codec.rs +++ b/src/array/codec/array_to_bytes/pcodec/pcodec_codec.rs @@ -5,8 +5,8 @@ use pco::{standalone::guarantee::file_size, ChunkConfig, ModeSpec, PagingSpec}; use crate::{ array::{ codec::{ - ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, - BytesPartialDecoderTraits, CodecError, CodecOptions, CodecTraits, + ArrayBytes, ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, + BytesPartialDecoderTraits, CodecError, CodecOptions, CodecTraits, RawBytes, RecommendedConcurrency, }, convert_from_bytes_slice, transmute_to_bytes_vec, ArrayMetadataOptions, @@ -108,18 +108,22 @@ impl ArrayCodecTraits for PcodecCodec { // pcodec does not support parallel decode Ok(RecommendedConcurrency::new_maximum(1)) } +} +#[cfg_attr(feature = "async", async_trait::async_trait)] +impl ArrayToBytesCodecTraits for PcodecCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + bytes: ArrayBytes<'a>, decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let data_type = decoded_representation.data_type(); + let bytes = bytes.into_fixed()?; macro_rules! pcodec_encode { ( $t:ty ) => { pco::standalone::simple_compress( - &convert_from_bytes_slice::<$t>(&decoded_value), + &convert_from_bytes_slice::<$t>(&bytes), &self.chunk_config, ) .map(Cow::Owned) @@ -164,20 +168,20 @@ impl ArrayCodecTraits for PcodecCodec { fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + bytes: RawBytes<'a>, decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let data_type = decoded_representation.data_type(); macro_rules! pcodec_decode { ( $t:ty ) => { - pco::standalone::simple_decompress(&encoded_value) + pco::standalone::simple_decompress(&bytes) .map(|bytes| Cow::Owned(transmute_to_bytes_vec::<$t>(bytes))) .map_err(|err| CodecError::Other(err.to_string())) }; } - match data_type { + let bytes = match data_type { DataType::UInt16 => { pcodec_decode!(u16) } @@ -209,12 +213,10 @@ impl ArrayCodecTraits for PcodecCodec { data_type.clone(), IDENTIFIER.to_string(), )), - } + }?; + Ok(ArrayBytes::from(bytes)) } -} -#[cfg_attr(feature = "async", async_trait::async_trait)] -impl ArrayToBytesCodecTraits for PcodecCodec { fn partial_decoder<'a>( &self, input_handle: Box, diff --git a/src/array/codec/array_to_bytes/pcodec/pcodec_partial_decoder.rs b/src/array/codec/array_to_bytes/pcodec/pcodec_partial_decoder.rs index 22a91a1e..a51fee5a 100644 --- a/src/array/codec/array_to_bytes/pcodec/pcodec_partial_decoder.rs +++ b/src/array/codec/array_to_bytes/pcodec/pcodec_partial_decoder.rs @@ -1,14 +1,9 @@ -use std::borrow::Cow; - -use crate::{ - array::{ - codec::{ - ArrayPartialDecoderTraits, ArraySubset, BytesPartialDecoderTraits, CodecError, - CodecOptions, - }, - ChunkRepresentation, DataType, +use crate::array::{ + codec::{ + ArrayBytes, ArrayPartialDecoderTraits, ArraySubset, BytesPartialDecoderTraits, CodecError, + CodecOptions, RawBytes, }, - array_subset::IncompatibleArraySubsetAndShapeError, + ChunkRepresentation, DataType, }; #[cfg(feature = "async")] @@ -34,10 +29,10 @@ impl<'a> PcodecPartialDecoder<'a> { } fn do_partial_decode<'a>( - decoded: Option>, + decoded: Option>, decoded_regions: &[ArraySubset], decoded_representation: &ChunkRepresentation, -) -> Result>, CodecError> { +) -> Result>, CodecError> { let mut decoded_bytes = Vec::with_capacity(decoded_regions.len()); let chunk_shape = decoded_representation.shape_u64(); match decoded { @@ -47,7 +42,7 @@ fn do_partial_decode<'a>( .fill_value() .as_ne_bytes() .repeat(array_subset.num_elements_usize()); - decoded_bytes.push(Cow::Owned(bytes_subset)); + decoded_bytes.push(ArrayBytes::from(bytes_subset)); } } Some(decoded_value) => { @@ -56,20 +51,16 @@ fn do_partial_decode<'a>( let decoded_chunk = pco::standalone::simple_decompress(&decoded_value) .map(|bytes| crate::array::transmute_to_bytes_vec::<$t>(bytes)) .map_err(|err| CodecError::Other(err.to_string()))?; + let decoded_chunk: ArrayBytes = decoded_chunk.into(); for array_subset in decoded_regions { - let bytes_subset = array_subset - .extract_bytes( - decoded_chunk.as_slice(), + let bytes_subset = decoded_chunk + .extract_array_subset( + array_subset, &chunk_shape, - decoded_representation.element_size(), - ) - .map_err(|_| { - IncompatibleArraySubsetAndShapeError::from(( - array_subset.clone(), - decoded_representation.shape_u64(), - )) - })?; - decoded_bytes.push(Cow::Owned(bytes_subset)); + decoded_representation.data_type(), + )? + .into_owned(); + decoded_bytes.push(bytes_subset); } }; } @@ -115,7 +106,7 @@ impl ArrayPartialDecoderTraits for PcodecPartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { let decoded = self.input_handle.decode(options)?; do_partial_decode(decoded, decoded_regions, &self.decoded_representation) } @@ -153,7 +144,7 @@ impl AsyncArrayPartialDecoderTraits for AsyncPCodecPartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { for array_subset in decoded_regions { if array_subset.dimensionality() != self.decoded_representation.dimensionality() { return Err(CodecError::InvalidArraySubsetDimensionalityError( diff --git a/src/array/codec/array_to_bytes/sharding.rs b/src/array/codec/array_to_bytes/sharding.rs index 28fde5ef..da416d5c 100644 --- a/src/array/codec/array_to_bytes/sharding.rs +++ b/src/array/codec/array_to_bytes/sharding.rs @@ -105,6 +105,7 @@ fn decode_shard_index( index_array_representation, options, )?; + let decoded_shard_index = decoded_shard_index.into_fixed()?; Ok(decoded_shard_index .chunks_exact(core::mem::size_of::()) .map(|v| u64::from_ne_bytes(v.try_into().unwrap() /* safe */)) @@ -114,9 +115,12 @@ fn decode_shard_index( #[cfg(test)] mod tests { use crate::{ - array::codec::{ - bytes_to_bytes::test_unbounded::TestUnboundedCodec, ArrayCodecTraits, - BytesToBytesCodecTraits, CodecOptionsBuilder, + array::{ + codec::{ + bytes_to_bytes::test_unbounded::TestUnboundedCodec, BytesToBytesCodecTraits, + CodecOptionsBuilder, + }, + ArrayBytes, }, array_subset::ArraySubset, config::global_config, @@ -199,6 +203,7 @@ mod tests { (0..chunk_representation.num_elements() as u16).collect() }; let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); if unbounded { bytes_to_bytes_codecs.push(Box::new(TestUnboundedCodec::new())) @@ -213,13 +218,13 @@ mod tests { .build(); let encoded = codec - .encode(Cow::Borrowed(&bytes), &chunk_representation, options) + .encode(bytes.clone(), &chunk_representation, options) .unwrap(); let decoded = codec .decode(encoded.clone(), &chunk_representation, options) .unwrap(); - assert_ne!(encoded, decoded); - assert_eq!(bytes, decoded.to_vec()); + assert_eq!(bytes, decoded); + assert_ne!(encoded, decoded.into_fixed().unwrap()); } #[test] @@ -293,6 +298,7 @@ mod tests { (0..chunk_representation.num_elements() as u16).collect() }; let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); if unbounded { bytes_to_bytes_codecs.push(Box::new(TestUnboundedCodec::new())) @@ -307,13 +313,13 @@ mod tests { .build(); let encoded = codec - .encode(Cow::Borrowed(&bytes), &chunk_representation, options) + .encode(bytes.clone(), &chunk_representation, options) .unwrap(); let decoded = codec .decode(encoded.clone(), &chunk_representation, options) .unwrap(); - assert_ne!(encoded, decoded); - assert_eq!(bytes, decoded.to_vec()); + assert_eq!(bytes, decoded); + assert_ne!(encoded, decoded.into_fixed().unwrap()); } #[cfg(feature = "async")] @@ -361,7 +367,7 @@ mod tests { vec![4, 8] }; - let bytes = elements; + let bytes: ArrayBytes = elements.into(); let bytes_to_bytes_codecs: Vec> = if unbounded { vec![Box::new(TestUnboundedCodec::new())] @@ -378,7 +384,7 @@ mod tests { .build(); let encoded = codec - .encode(Cow::Borrowed(&bytes), &chunk_representation, options) + .encode(bytes.clone(), &chunk_representation, options) .unwrap(); let decoded_regions = [ArraySubset::new_with_ranges(&[1..3, 0..1])]; let input_handle = Box::new(std::io::Cursor::new(encoded)); @@ -391,7 +397,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) @@ -442,8 +448,7 @@ mod tests { } else { vec![4, 8] }; - - let bytes = elements; + let bytes: ArrayBytes = elements.into(); let bytes_to_bytes_codecs: Vec> = if unbounded { vec![Box::new(TestUnboundedCodec::new())] @@ -460,7 +465,7 @@ mod tests { .build(); let encoded = codec - .encode(Cow::Borrowed(&bytes), &chunk_representation, options) + .encode(bytes.clone(), &chunk_representation, options) .unwrap(); let decoded_regions = [ArraySubset::new_with_ranges(&[1..3, 0..1])]; let input_handle = Box::new(std::io::Cursor::new(encoded)); @@ -475,7 +480,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) @@ -511,8 +516,6 @@ mod tests { #[cfg(feature = "crc32c")] #[test] fn codec_sharding_partial_decode2() { - use crate::array::codec::ArrayCodecTraits; - let chunk_shape: ChunkShape = vec![2, 4, 4].try_into().unwrap(); let chunk_representation = ChunkRepresentation::new( chunk_shape.to_vec(), @@ -522,17 +525,14 @@ mod tests { .unwrap(); let elements: Vec = (0..chunk_representation.num_elements() as u16).collect(); let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); let codec_configuration: ShardingCodecConfiguration = serde_json::from_str(JSON_VALID2).unwrap(); let codec = ShardingCodec::new_with_configuration(&codec_configuration).unwrap(); let encoded = codec - .encode( - Cow::Borrowed(&bytes), - &chunk_representation, - &CodecOptions::default(), - ) + .encode(bytes, &chunk_representation, &CodecOptions::default()) .unwrap(); let decoded_regions = [ArraySubset::new_with_ranges(&[1..2, 0..2, 0..3])]; let input_handle = Box::new(std::io::Cursor::new(encoded)); @@ -549,7 +549,7 @@ mod tests { println!("decoded_partial_chunk {decoded_partial_chunk:?}"); let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) @@ -567,18 +567,14 @@ mod tests { ChunkRepresentation::new(chunk_shape.to_vec(), DataType::UInt8, FillValue::from(0u8)) .unwrap(); let elements: Vec = (0..chunk_representation.num_elements() as u8).collect(); - let bytes = elements; + let bytes: ArrayBytes = elements.into(); let codec_configuration: ShardingCodecConfiguration = serde_json::from_str(JSON_VALID3).unwrap(); let codec = ShardingCodec::new_with_configuration(&codec_configuration).unwrap(); let encoded = codec - .encode( - Cow::Borrowed(&bytes), - &chunk_representation, - &CodecOptions::default(), - ) + .encode(bytes, &chunk_representation, &CodecOptions::default()) .unwrap(); let decoded_regions = [ArraySubset::new_with_ranges(&[1..3, 0..1])]; let input_handle = Box::new(std::io::Cursor::new(encoded)); @@ -595,7 +591,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) diff --git a/src/array/codec/array_to_bytes/sharding/sharding_codec.rs b/src/array/codec/array_to_bytes/sharding/sharding_codec.rs index ed71e36d..134b6709 100644 --- a/src/array/codec/array_to_bytes/sharding/sharding_codec.rs +++ b/src/array/codec/array_to_bytes/sharding/sharding_codec.rs @@ -2,6 +2,7 @@ use std::{borrow::Cow, num::NonZeroU64, sync::atomic::AtomicUsize}; use crate::{ array::{ + array_bytes::{merge_chunks_vlen, update_bytes_flen}, chunk_shape_to_array_shape, codec::{ ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, @@ -11,7 +12,8 @@ use crate::{ concurrency::calc_concurrency_outer_inner, transmute_to_bytes_vec, unravel_index, unsafe_cell_slice::UnsafeCellSlice, - ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, ChunkShape, FillValue, + ArrayBytes, ArrayMetadataOptions, ArraySize, BytesRepresentation, ChunkRepresentation, + ChunkShape, DataTypeSize, FillValue, RawBytes, }, array_subset::ArraySubset, metadata::v3::MetadataV3, @@ -127,18 +129,23 @@ impl ArrayCodecTraits for ShardingCodec { Ok(RecommendedConcurrency::new_maximum(num_elements.into())) } + fn partial_decode_granularity( + &self, + _decoded_representation: &ChunkRepresentation, + ) -> ChunkShape { + self.chunk_shape.clone() + } +} + +#[cfg_attr(feature = "async", async_trait::async_trait)] +impl ArrayToBytesCodecTraits for ShardingCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + bytes: ArrayBytes<'a>, shard_rep: &ChunkRepresentation, options: &CodecOptions, - ) -> Result, CodecError> { - if decoded_value.len() as u64 != shard_rep.size() { - return Err(CodecError::UnexpectedChunkDecodedSize( - decoded_value.len(), - shard_rep.size(), - )); - } + ) -> Result, CodecError> { + bytes.validate(shard_rep.num_elements(), shard_rep.data_type().size())?; // Get chunk bytes representation, and choose implementation based on whether the size is unbounded or not let chunk_rep = unsafe { @@ -149,34 +156,26 @@ impl ArrayCodecTraits for ShardingCodec { ) }; let chunk_bytes_representation = self.inner_codecs.compute_encoded_size(&chunk_rep)?; - Ok(Cow::Owned(match chunk_bytes_representation { + + let bytes = match chunk_bytes_representation { BytesRepresentation::BoundedSize(size) | BytesRepresentation::FixedSize(size) => { - self.encode_bounded(&decoded_value, shard_rep, &chunk_rep, size, options) + self.encode_bounded(&bytes, shard_rep, &chunk_rep, size, options) } BytesRepresentation::UnboundedSize => { - self.encode_unbounded(&decoded_value, shard_rep, &chunk_rep, options) + self.encode_unbounded(&bytes, shard_rep, &chunk_rep, options) } - }?)) + }?; + Ok(RawBytes::from(bytes)) } #[allow(clippy::too_many_lines)] fn decode<'a>( &self, - encoded_shard: Cow<'a, [u8]>, + encoded_shard: RawBytes<'a>, shard_representation: &ChunkRepresentation, options: &CodecOptions, - ) -> Result, CodecError> { - // Allocate an array for the output - let len = shard_representation.size_usize(); - let mut decoded_shard = Vec::::with_capacity(len); - + ) -> Result, CodecError> { let shard_shape = shard_representation.shape_u64(); - let chunks_per_shard = - calculate_chunks_per_shard(shard_representation.shape(), self.chunk_shape.as_slice())?; - let shard_index = - self.decode_index(&encoded_shard, chunks_per_shard.as_slice(), options)?; - - // Decode chunks let chunk_representation = unsafe { ChunkRepresentation::new_unchecked( self.chunk_shape.as_slice().to_vec(), @@ -184,19 +183,20 @@ impl ArrayCodecTraits for ShardingCodec { shard_representation.fill_value().clone(), ) }; + let chunks_per_shard = + calculate_chunks_per_shard(shard_representation.shape(), chunk_representation.shape())?; + let num_chunks = chunks_per_shard + .as_slice() + .iter() + .map(|i| usize::try_from(i.get()).unwrap()) + .product::(); + + let shard_index = + self.decode_index(&encoded_shard, chunks_per_shard.as_slice(), options)?; let any_empty = shard_index .par_iter() .any(|offset_or_size| *offset_or_size == u64::MAX); - let contiguous_fill_value = if any_empty { - Some(get_contiguous_fill_value( - shard_representation.fill_value(), - &self.chunk_shape, - &shard_shape, - )) - } else { - None - }; // Calc self/internal concurrent limits let (shard_concurrent_limit, concurrency_limit_inner_chunks) = calc_concurrency_outer_inner( @@ -211,42 +211,21 @@ impl ArrayCodecTraits for ShardingCodec { .concurrent_target(concurrency_limit_inner_chunks) .build(); - let chunks_per_shard = - calculate_chunks_per_shard(shard_representation.shape(), chunk_representation.shape())?; - let num_chunks = chunks_per_shard - .as_slice() - .iter() - .map(|i| usize::try_from(i.get()).unwrap()) - .product::(); - let element_size = chunk_representation.element_size() as u64; - - { - let output = UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut decoded_shard); - rayon_iter_concurrent_limit::iter_concurrent_limit!( - shard_concurrent_limit, - (0..num_chunks), - try_for_each, - |chunk_index: usize| { + match shard_representation.data_type().size() { + DataTypeSize::Variable => { + let decode_inner_chunk = |chunk_index: usize| { let chunk_subset = self.chunk_index_to_subset(chunk_index as u64, chunks_per_shard.as_slice()); - let output = unsafe { output.get() }; // Read the offset/size let offset = shard_index[chunk_index * 2]; let size = shard_index[chunk_index * 2 + 1]; - if offset == u64::MAX && size == u64::MAX { - if let Some(fv) = &contiguous_fill_value { - let contiguous_iterator = unsafe { - chunk_subset.contiguous_linearised_indices_unchecked(&shard_shape) - }; - for (index, elements) in &contiguous_iterator { - debug_assert_eq!(fv.len() as u64, elements * element_size); - let shard_offset = usize::try_from(index * element_size).unwrap(); - output[shard_offset..shard_offset + fv.len()].copy_from_slice(fv); - } - } else { - unreachable!(); - } + let chunk_bytes = if offset == u64::MAX && size == u64::MAX { + let array_size = ArraySize::new( + chunk_representation.data_type().size(), + chunk_representation.num_elements(), + ); + ArrayBytes::new_fill_value(array_size, chunk_representation.fill_value()) } else if usize::try_from(offset + size).unwrap() > encoded_shard.len() { return Err(CodecError::Other( "The shard index references out-of-bounds bytes. The chunk may be corrupted." @@ -256,46 +235,112 @@ impl ArrayCodecTraits for ShardingCodec { let offset: usize = offset.try_into().unwrap(); let size: usize = size.try_into().unwrap(); let encoded_chunk = &encoded_shard[offset..offset + size]; - let decoded_chunk = self.inner_codecs.decode( + self.inner_codecs.decode( Cow::Borrowed(encoded_chunk), &chunk_representation, &options, - )?; - let contiguous_iterator = unsafe { - chunk_subset.contiguous_linearised_indices_unchecked(&shard_shape) + )? + }; + Ok((chunk_bytes, chunk_subset)) + }; + + // Decode the inner chunks + let chunk_bytes_and_subsets = rayon_iter_concurrent_limit::iter_concurrent_limit!( + shard_concurrent_limit, + (0..num_chunks), + map, + decode_inner_chunk + ) + .collect::, _>>()?; + + // Convert into an array + merge_chunks_vlen(chunk_bytes_and_subsets, &shard_representation.shape_u64()) + } + DataTypeSize::Fixed(data_type_size) => { + // Allocate an array for the output + let mut decoded_shard = Vec::::with_capacity( + shard_representation.num_elements_usize() * data_type_size, + ); + + let contiguous_fill_value = if any_empty { + Some(get_contiguous_fill_value( + shard_representation.fill_value(), + &self.chunk_shape, + &shard_shape, + )) + } else { + None + }; + + { + let output = + UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut decoded_shard); + let decode_chunk = |chunk_index: usize| { + let chunk_subset = self + .chunk_index_to_subset(chunk_index as u64, chunks_per_shard.as_slice()); + let output = unsafe { output.get() }; + + // Read the offset/size + let offset = shard_index[chunk_index * 2]; + let size = shard_index[chunk_index * 2 + 1]; + if offset == u64::MAX && size == u64::MAX { + if let Some(fv) = &contiguous_fill_value { + let contiguous_iterator = unsafe { + chunk_subset + .contiguous_linearised_indices_unchecked(&shard_shape) + }; + for (index, elements) in &contiguous_iterator { + debug_assert_eq!( + fv.len() as u64, + elements * data_type_size as u64 + ); + let shard_offset = + usize::try_from(index * data_type_size as u64).unwrap(); + output[shard_offset..shard_offset + fv.len()] + .copy_from_slice(fv); + } + } else { + unreachable!(); + } + } else if usize::try_from(offset + size).unwrap() > encoded_shard.len() { + return Err(CodecError::Other( + "The shard index references out-of-bounds bytes. The chunk may be corrupted." + .to_string(), + )); + } else { + let offset: usize = offset.try_into().unwrap(); + let size: usize = size.try_into().unwrap(); + let encoded_chunk = &encoded_shard[offset..offset + size]; + let decoded_chunk = self.inner_codecs.decode( + Cow::Borrowed(encoded_chunk), + &chunk_representation, + &options, + )?; + update_bytes_flen( + output, + &shard_representation.shape_u64(), + &decoded_chunk.into_fixed()?, + &chunk_subset, + data_type_size, + ); }; - let length = usize::try_from( - contiguous_iterator.contiguous_elements() * element_size, - ) - .unwrap(); - let mut data_idx = 0; - for (index, _) in &contiguous_iterator { - let shard_offset = usize::try_from(index * element_size).unwrap(); - output[shard_offset..shard_offset + length] - .copy_from_slice(&decoded_chunk[data_idx..data_idx + length]); - data_idx += length; - } + + Ok::<_, CodecError>(()) }; - Ok::<_, CodecError>(()) + rayon_iter_concurrent_limit::iter_concurrent_limit!( + shard_concurrent_limit, + (0..num_chunks), + try_for_each, + decode_chunk + )?; } - )?; + unsafe { decoded_shard.set_len(decoded_shard.capacity()) }; + Ok(ArrayBytes::from(decoded_shard)) + } } - - unsafe { decoded_shard.set_len(len) }; - Ok(Cow::Owned(decoded_shard)) } - fn partial_decode_granularity( - &self, - _decoded_representation: &ChunkRepresentation, - ) -> ChunkShape { - self.chunk_shape.clone() - } -} - -#[cfg_attr(feature = "async", async_trait::async_trait)] -impl ArrayToBytesCodecTraits for ShardingCodec { fn partial_decoder<'a>( &'a self, input_handle: Box, @@ -407,13 +452,16 @@ impl ShardingCodec { #[allow(clippy::too_many_lines)] fn encode_bounded( &self, - decoded_value: &[u8], + decoded_value: &ArrayBytes, shard_representation: &ChunkRepresentation, chunk_representation: &ChunkRepresentation, chunk_size_bounded: u64, options: &CodecOptions, ) -> Result, CodecError> { - debug_assert_eq!(decoded_value.len() as u64, shard_representation.size()); // already validated in par_encode + decoded_value.validate( + shard_representation.num_elements(), + shard_representation.data_type().size(), + )?; // Calculate maximum possible shard size let chunks_per_shard = @@ -453,7 +501,6 @@ impl ShardingCodec { .into_builder() .concurrent_target(concurrency_limit_inner_chunks) .build(); - // println!("{shard_concurrent_limit} {concurrency_limit_inner_chunks:?}"); // FIXME: log debug? // Encode the shards and update the shard index { @@ -472,19 +519,15 @@ impl ShardingCodec { |chunk_index: usize| { let chunk_subset = self.chunk_index_to_subset(chunk_index as u64, chunks_per_shard.as_slice()); - let bytes = unsafe { - chunk_subset.extract_bytes_unchecked( - decoded_value, - &shard_shape, - shard_representation.element_size(), - ) - }; - if !chunk_representation.fill_value().equals_all(&bytes) { - let chunk_encoded = self.inner_codecs.encode( - bytes.into(), - chunk_representation, - &options, - )?; + let bytes = decoded_value.extract_array_subset( + &chunk_subset, + &shard_shape, + chunk_representation.data_type(), + )?; + if !bytes.is_fill_value(chunk_representation.fill_value()) { + let chunk_encoded = + self.inner_codecs + .encode(bytes, chunk_representation, &options)?; let chunk_offset = encoded_shard_offset .fetch_add(chunk_encoded.len(), std::sync::atomic::Ordering::Relaxed); @@ -520,8 +563,9 @@ impl ShardingCodec { }; // Encode and write array index + let shard_index_bytes: RawBytes = transmute_to_bytes_vec(shard_index).into(); let encoded_array_index = self.index_codecs.encode( - Cow::Owned(transmute_to_bytes_vec(shard_index)), + shard_index_bytes.into(), &index_decoded_representation, &options, )?; @@ -549,12 +593,15 @@ impl ShardingCodec { #[allow(clippy::too_many_lines)] fn encode_unbounded( &self, - decoded_value: &[u8], + decoded_value: &ArrayBytes, shard_representation: &ChunkRepresentation, chunk_representation: &ChunkRepresentation, options: &CodecOptions, ) -> Result, CodecError> { - debug_assert_eq!(decoded_value.len() as u64, shard_representation.size()); // already validated in par_encode + decoded_value.validate( + shard_representation.num_elements(), + shard_representation.data_type().size(), + )?; let chunks_per_shard = calculate_chunks_per_shard(shard_representation.shape(), chunk_representation.shape())?; @@ -584,26 +631,28 @@ impl ShardingCodec { .into_builder() .concurrent_target(concurrency_limit_inner_chunks) .build(); - // println!("{shard_concurrent_limit} {concurrency_limit_inner_chunks:?}"); // FIXME: log debug? let encode_chunk = |chunk_index| { let chunk_subset = self.chunk_index_to_subset(chunk_index as u64, chunks_per_shard.as_slice()); - let bytes = unsafe { - chunk_subset.extract_bytes_unchecked( - decoded_value, - &shard_shape, - shard_representation.element_size(), - ) + + let bytes = decoded_value.extract_array_subset( + &chunk_subset, + &shard_shape, + chunk_representation.data_type(), + ); + let bytes = match bytes { + Ok(bytes) => bytes, + Err(err) => return Some(Err(err)), }; - if chunk_representation.fill_value().equals_all(&bytes) { + + let is_fill_value = bytes.is_fill_value(chunk_representation.fill_value()); + if is_fill_value { None } else { - let encoded_chunk = self.inner_codecs.encode( - Cow::Owned(bytes), - chunk_representation, - &options_inner, - ); + let encoded_chunk = + self.inner_codecs + .encode(bytes, chunk_representation, &options_inner); match encoded_chunk { Ok(encoded_chunk) => Some(Ok((chunk_index, encoded_chunk.to_vec()))), Err(err) => Some(Err(err)), @@ -662,7 +711,7 @@ impl ShardingCodec { // Write shard index let encoded_array_index = self.index_codecs.encode( - Cow::Owned(transmute_to_bytes_vec(shard_index)), + ArrayBytes::from(transmute_to_bytes_vec(shard_index)), &index_decoded_representation, options, )?; diff --git a/src/array/codec/array_to_bytes/sharding/sharding_partial_decoder.rs b/src/array/codec/array_to_bytes/sharding/sharding_partial_decoder.rs index a55e724d..0b84c263 100644 --- a/src/array/codec/array_to_bytes/sharding/sharding_partial_decoder.rs +++ b/src/array/codec/array_to_bytes/sharding/sharding_partial_decoder.rs @@ -1,9 +1,10 @@ -use std::{borrow::Cow, num::NonZeroU64}; +use std::num::NonZeroU64; use rayon::prelude::*; use crate::{ array::{ + array_bytes::{merge_chunks_vlen, update_bytes_flen}, chunk_grid::RegularChunkGrid, chunk_shape_to_array_shape, codec::{ @@ -14,7 +15,7 @@ use crate::{ concurrency::{calc_concurrency_outer_inner, RecommendedConcurrency}, ravel_indices, unsafe_cell_slice::UnsafeCellSlice, - ChunkRepresentation, ChunkShape, DataType, + ArrayBytes, ArraySize, ChunkRepresentation, ChunkShape, DataType, DataTypeSize, }, byte_range::ByteRange, }; @@ -128,7 +129,7 @@ impl ArrayPartialDecoderTraits for ShardingPartialDecoder<'_> { &self, array_subsets: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { for array_subset in array_subsets { if array_subset.dimensionality() != self.decoded_representation.dimensionality() { return Err(CodecError::InvalidArraySubsetDimensionalityError( @@ -142,7 +143,7 @@ impl ArrayPartialDecoderTraits for ShardingPartialDecoder<'_> { return Ok(array_subsets .iter() .map(|decoded_region| { - Cow::Owned( + ArrayBytes::from( self.decoded_representation .fill_value() .as_ne_bytes() @@ -167,9 +168,6 @@ impl ArrayPartialDecoderTraits for ShardingPartialDecoder<'_> { let chunks_per_shard = chunk_shape_to_array_shape(chunks_per_shard.as_slice()); let num_chunks = usize::try_from(chunks_per_shard.iter().product::()).unwrap(); - let element_size = self.decoded_representation.element_size(); - let fill_value = chunk_representation.fill_value().as_ne_bytes(); - // Calculate inner chunk/codec concurrency let (inner_chunk_concurrent_limit, concurrency_limit_codec) = calc_concurrency_outer_inner( options.concurrent_target(), @@ -188,79 +186,165 @@ impl ArrayPartialDecoderTraits for ShardingPartialDecoder<'_> { let mut out = Vec::with_capacity(array_subsets.len()); for array_subset in array_subsets { - let array_subset_size = array_subset.num_elements_usize() * element_size; - let mut out_array_subset = vec![0; array_subset_size]; - let out_array_subset_slice = UnsafeCellSlice::new(out_array_subset.as_mut_slice()); - let chunks = unsafe { array_subset.chunks_unchecked(chunk_representation.shape()) }; - rayon_iter_concurrent_limit::iter_concurrent_limit!( - inner_chunk_concurrent_limit, - chunks, - try_for_each, - |(chunk_indices, chunk_subset): (Vec, _)| { - let out_array_subset_slice = unsafe { out_array_subset_slice.get() }; - - let shard_index_idx: usize = - usize::try_from(ravel_indices(&chunk_indices, &chunks_per_shard) * 2) - .unwrap(); - let offset = shard_index[shard_index_idx]; - let size = shard_index[shard_index_idx + 1]; - - // Get the subset of bytes from the chunk which intersect the array - let overlap = unsafe { array_subset.overlap_unchecked(&chunk_subset) }; - let array_subset_in_chunk_subset = - unsafe { overlap.relative_to_unchecked(chunk_subset.start()) }; - - let decoded_bytes = if offset == u64::MAX && size == u64::MAX { - // The chunk is just the fill value - fill_value.repeat(array_subset_in_chunk_subset.num_elements_usize()) - } else { - // Partially decode the inner chunk - let partial_decoder = self.inner_codecs.partial_decoder( - Box::new(ByteIntervalPartialDecoder::new( - &*self.input_handle, - offset, - size, - )), - &chunk_representation, - &options, - ) - .map_err(|err| if let CodecError::InvalidByteRangeError(_) = err { - CodecError::Other( - "The shard index references out-of-bounds bytes. The chunk may be corrupted." - .to_string(), + + match self.decoded_representation.element_size() { + DataTypeSize::Variable => { + let decode_inner_chunk_subset = |(chunk_indices, chunk_subset): ( + Vec, + _, + )| { + let shard_index_idx: usize = + usize::try_from(ravel_indices(&chunk_indices, &chunks_per_shard) * 2) + .unwrap(); + let offset = shard_index[shard_index_idx]; + let size = shard_index[shard_index_idx + 1]; + + // Get the subset of bytes from the chunk which intersect the array + let chunk_subset_overlap = + unsafe { array_subset.overlap_unchecked(&chunk_subset) }; + + let chunk_subset_bytes = if offset == u64::MAX && size == u64::MAX { + let array_size = ArraySize::new( + chunk_representation.data_type().size(), + chunk_subset_overlap.num_elements(), + ); + ArrayBytes::new_fill_value( + array_size, + chunk_representation.fill_value(), ) } else { - err - })?; - let decoded_bytes = partial_decoder - .partial_decode_opt(&[array_subset_in_chunk_subset], &options)? - .remove(0); - decoded_bytes.to_vec() + // Partially decode the inner chunk + let partial_decoder = self.inner_codecs.partial_decoder( + Box::new(ByteIntervalPartialDecoder::new( + &*self.input_handle, + offset, + size, + )), + &chunk_representation, + &options, + ) + .map_err(|err| if let CodecError::InvalidByteRangeError(_) = err { + CodecError::Other( + "The shard index references out-of-bounds bytes. The chunk may be corrupted." + .to_string(), + ) + } else { + err + })?; + partial_decoder + .partial_decode_opt( + &[chunk_subset_overlap + .relative_to(chunk_subset.start()) + .unwrap()], + &options, + )? + .remove(0) + .into_owned() + }; + Ok::<_, CodecError>(( + chunk_subset_bytes, + chunk_subset_overlap + .relative_to(array_subset.start()) + .unwrap(), + )) }; - // Copy decoded bytes to the output - let chunk_subset_in_array_subset = - unsafe { overlap.relative_to_unchecked(array_subset.start()) }; - let mut decoded_offset = 0; - let contiguous_iterator = unsafe { - chunk_subset_in_array_subset - .contiguous_linearised_indices_unchecked(array_subset.shape()) - }; - let length = contiguous_iterator.contiguous_elements_usize() * element_size; - for (array_subset_element_index, _num_elements) in &contiguous_iterator { - let output_offset = - usize::try_from(array_subset_element_index).unwrap() * element_size; - out_array_subset_slice[output_offset..output_offset + length] - .copy_from_slice( - &decoded_bytes[decoded_offset..decoded_offset + length], + // Decode the inner chunk subsets + let chunk_bytes_and_subsets = + rayon_iter_concurrent_limit::iter_concurrent_limit!( + inner_chunk_concurrent_limit, + chunks, + map, + decode_inner_chunk_subset + ) + .collect::, _>>()?; + + // Convert into an array + let out_array_subset = + merge_chunks_vlen(chunk_bytes_and_subsets, array_subset.shape())?; + out.push(out_array_subset); + } + DataTypeSize::Fixed(data_type_size) => { + let array_subset_size = array_subset.num_elements_usize() * data_type_size; + let mut out_array_subset = vec![0; array_subset_size]; + let out_array_subset_slice = + UnsafeCellSlice::new(out_array_subset.as_mut_slice()); + + let decode_inner_chunk_subset_into_slice = |(chunk_indices, chunk_subset): ( + Vec, + _, + )| { + let shard_index_idx: usize = + usize::try_from(ravel_indices(&chunk_indices, &chunks_per_shard) * 2) + .unwrap(); + let offset = shard_index[shard_index_idx]; + let size = shard_index[shard_index_idx + 1]; + + // Get the subset of bytes from the chunk which intersect the array + let chunk_subset_overlap = + unsafe { array_subset.overlap_unchecked(&chunk_subset) }; + + let decoded_bytes = if offset == u64::MAX && size == u64::MAX { + let array_size = ArraySize::new( + chunk_representation.data_type().size(), + chunk_subset_overlap.num_elements(), ); - decoded_offset += length; - } - Ok::<_, CodecError>(()) + ArrayBytes::new_fill_value( + array_size, + chunk_representation.fill_value(), + ) + } else { + // Partially decode the inner chunk + let partial_decoder = self.inner_codecs.partial_decoder( + Box::new(ByteIntervalPartialDecoder::new( + &*self.input_handle, + offset, + size, + )), + &chunk_representation, + &options, + ) + .map_err(|err| if let CodecError::InvalidByteRangeError(_) = err { + CodecError::Other( + "The shard index references out-of-bounds bytes. The chunk may be corrupted." + .to_string(), + ) + } else { + err + })?; + partial_decoder + .partial_decode_opt( + &[chunk_subset_overlap + .relative_to(chunk_subset.start()) + .unwrap()], + &options, + )? + .remove(0) + .into_owned() + }; + let decoded_bytes = decoded_bytes.into_fixed()?; + update_bytes_flen( + unsafe { out_array_subset_slice.get() }, + array_subset.shape(), + &decoded_bytes, + &chunk_subset_overlap + .relative_to(array_subset.start()) + .unwrap(), + data_type_size, + ); + Ok::<_, CodecError>(()) + }; + + rayon_iter_concurrent_limit::iter_concurrent_limit!( + inner_chunk_concurrent_limit, + chunks, + try_for_each, + decode_inner_chunk_subset_into_slice + )?; + out.push(ArrayBytes::from(out_array_subset)); } - )?; - out.push(Cow::Owned(out_array_subset)); + } } Ok(out) } @@ -370,7 +454,7 @@ impl AsyncArrayPartialDecoderTraits for AsyncShardingPartialDecoder<'_> { &self, array_subsets: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { for array_subset in array_subsets { if array_subset.dimensionality() != self.decoded_representation.dimensionality() { return Err(CodecError::InvalidArraySubsetDimensionalityError( @@ -384,7 +468,7 @@ impl AsyncArrayPartialDecoderTraits for AsyncShardingPartialDecoder<'_> { return Ok(array_subsets .iter() .map(|decoded_region| { - Cow::Owned( + ArrayBytes::from( self.decoded_representation .fill_value() .as_ne_bytes() @@ -400,180 +484,246 @@ impl AsyncArrayPartialDecoderTraits for AsyncShardingPartialDecoder<'_> { )?; let chunks_per_shard = chunk_shape_to_array_shape(chunks_per_shard.as_slice()); - let element_size = self.decoded_representation.element_size(); + let chunk_representation = unsafe { + ChunkRepresentation::new_unchecked( + self.chunk_grid.chunk_shape().to_vec(), + self.decoded_representation.data_type().clone(), + self.decoded_representation.fill_value().clone(), + ) + }; + let mut out = Vec::with_capacity(array_subsets.len()); - // FIXME: Could go parallel here + // TODO: Could go parallel here? for array_subset in array_subsets { - // shard (subset) - let shard_size = array_subset.num_elements_usize() * element_size; - let mut shard = Vec::with_capacity(shard_size); - let shard_slice = UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut shard); - - // Find filled / non filled chunks - let chunk_info = - unsafe { array_subset.chunks_unchecked(self.chunk_grid.chunk_shape()) } - .into_iter() - .map(|(chunk_indices, chunk_subset)| { - let chunk_index = ravel_indices(&chunk_indices, &chunks_per_shard); - let chunk_index = usize::try_from(chunk_index).unwrap(); - - // Read the offset/size - let offset = shard_index[chunk_index * 2]; - let size = shard_index[chunk_index * 2 + 1]; - if offset == u64::MAX && size == u64::MAX { - (chunk_subset, None) - } else { - let offset: usize = offset.try_into().unwrap(); - let size: usize = size.try_into().unwrap(); - (chunk_subset, Some((offset, size))) - } - }) - .collect::>(); - - // Decode unfilled chunks - let results = futures::future::join_all( - chunk_info - .iter() - .filter_map(|(chunk_subset, offset_size)| { - offset_size - .as_ref() - .map(|offset_size| (chunk_subset, offset_size)) - }) - .map(|(chunk_subset, (offset, size))| async move { - let chunk_representation = unsafe { - ChunkRepresentation::new_unchecked( - self.chunk_grid.chunk_shape().to_vec(), - self.decoded_representation.data_type().clone(), - self.decoded_representation.fill_value().clone(), - ) - }; - let partial_decoder = self - .inner_codecs - .async_partial_decoder( - Box::new(AsyncByteIntervalPartialDecoder::new( - &*self.input_handle, - u64::try_from(*offset).unwrap(), - u64::try_from(*size).unwrap(), - )), - &chunk_representation, - options, // FIXME: Adjust options for partial decoding - ) - .await - .map_err(|err| if let CodecError::InvalidByteRangeError(_) = err { - CodecError::Other( - "The shard index references out-of-bounds bytes. The chunk may be corrupted." - .to_string(), + match self.decoded_representation.element_size() { + DataTypeSize::Variable => { + let chunks = + unsafe { array_subset.chunks_unchecked(chunk_representation.shape()) }; + + let decode_inner_chunk_subset = |(chunk_indices, chunk_subset): ( + Vec, + _, + )| { + let shard_index_idx: usize = + usize::try_from(ravel_indices(&chunk_indices, &chunks_per_shard) * 2) + .unwrap(); + let chunk_representation = chunk_representation.clone(); + async move { + let offset = shard_index[shard_index_idx]; + let size = shard_index[shard_index_idx + 1]; + + // Get the subset of bytes from the chunk which intersect the array + let chunk_subset_overlap = + unsafe { array_subset.overlap_unchecked(&chunk_subset) }; + + let chunk_subset_bytes = if offset == u64::MAX && size == u64::MAX { + let array_size = ArraySize::new( + self.data_type().size(), + chunk_subset_overlap.num_elements(), + ); + ArrayBytes::new_fill_value( + array_size, + chunk_representation.fill_value(), ) } else { - err - })?; - let overlap = unsafe { array_subset.overlap_unchecked(chunk_subset) }; - let array_subset_in_chunk_subset = - unsafe { overlap.relative_to_unchecked(chunk_subset.start()) }; - // Partial decoding is actually really slow with the blosc codec! Assume sharded chunks are small, and just decode the whole thing and extract bytes - // TODO: Investigate further - // let decoded_chunk = partial_decoder - // .partial_decode(&[array_subset_in_chunk_subset]) - // .await? - // .remove(0); - let decoded_chunk = partial_decoder - .partial_decode_opt( - &[ArraySubset::new_with_shape(chunk_subset.shape().to_vec())], - options, - ) // FIXME: Adjust options for partial decoding - .await? - .remove(0); - let decoded_chunk = array_subset_in_chunk_subset - .extract_bytes(&decoded_chunk, chunk_subset.shape(), element_size) - .unwrap(); - let chunk_subset_in_array_subset = - unsafe { overlap.relative_to_unchecked(array_subset.start()) }; - Ok::<_, CodecError>((chunk_subset_in_array_subset, decoded_chunk)) - }), - ) - .await; - // FIXME: Concurrency limit for futures - - if !results.is_empty() { - rayon_iter_concurrent_limit::iter_concurrent_limit!( - options.concurrent_target(), - results, - try_for_each, - |subset_and_decoded_chunk| { - let (chunk_subset_in_array_subset, decoded_chunk): (ArraySubset, Vec) = - subset_and_decoded_chunk?; - let mut data_idx = 0; - let element_size = element_size as u64; - let shard_slice = unsafe { shard_slice.get() }; - let contiguous_iterator = unsafe { - chunk_subset_in_array_subset - .contiguous_linearised_indices_unchecked(array_subset.shape()) - }; - let length = usize::try_from( - contiguous_iterator.contiguous_elements() * element_size, - ) - .unwrap(); - for (index, _num_elements) in &contiguous_iterator { - let shard_offset = usize::try_from(index * element_size).unwrap(); - shard_slice[shard_offset..shard_offset + length] - .copy_from_slice(&decoded_chunk[data_idx..data_idx + length]); - data_idx += length; + // Partially decode the inner chunk + let partial_decoder = self.inner_codecs.async_partial_decoder( + Box::new(AsyncByteIntervalPartialDecoder::new( + &*self.input_handle, + offset, + size, + )), + &chunk_representation, + options, + ).await + .map_err(|err| if let CodecError::InvalidByteRangeError(_) = err { + CodecError::Other( + "The shard index references out-of-bounds bytes. The chunk may be corrupted." + .to_string(), + ) + } else { + err + })?; + partial_decoder + .partial_decode_opt( + &[chunk_subset_overlap + .relative_to(chunk_subset.start()) + .unwrap()], + options, + ) + .await? + .remove(0) + .into_owned() + }; + Ok::<_, CodecError>(( + chunk_subset_bytes, + chunk_subset_overlap + .relative_to(array_subset.start()) + .unwrap(), + )) } - Ok::<_, CodecError>(()) - } - )?; - } + }; - // Write filled chunks - let filled_chunks = chunk_info - .iter() - .filter_map(|(chunk_subset, offset_size)| { - if offset_size.is_none() { - Some(chunk_subset) - } else { - None - } - }) - .collect::>(); - if !filled_chunks.is_empty() { - let chunk_array_ss = ArraySubset::new_with_shape(self.chunk_grid.chunk_shape_u64()); - let filled_chunk = self - .decoded_representation - .fill_value() - .as_ne_bytes() - .repeat(chunk_array_ss.num_elements_usize()); - - // Write filled chunks - rayon_iter_concurrent_limit::iter_concurrent_limit!( - options.concurrent_target(), - filled_chunks, - for_each, - |chunk_subset: &ArraySubset| { - let overlap = unsafe { array_subset.overlap_unchecked(chunk_subset) }; - let chunk_subset_in_array_subset = - unsafe { overlap.relative_to_unchecked(array_subset.start()) }; - let mut data_idx = 0; - let element_size = self.decoded_representation.element_size() as u64; - let shard_slice = unsafe { shard_slice.get() }; - let contiguous_iterator = unsafe { - chunk_subset_in_array_subset - .contiguous_linearised_indices_unchecked(array_subset.shape()) - }; - let length = usize::try_from( - contiguous_iterator.contiguous_elements() * element_size, + // Decode the inner chunk subsets + let futures = chunks.iter().map(decode_inner_chunk_subset); + let chunk_bytes_and_subsets = futures::future::try_join_all(futures).await?; + + // Convert into an array + let out_array_subset = + merge_chunks_vlen(chunk_bytes_and_subsets, array_subset.shape())?; + out.push(out_array_subset); + } + DataTypeSize::Fixed(data_type_size) => { + // Find filled / non filled chunks + let chunk_info = + unsafe { array_subset.chunks_unchecked(self.chunk_grid.chunk_shape()) } + .into_iter() + .map(|(chunk_indices, chunk_subset)| { + let chunk_index = ravel_indices(&chunk_indices, &chunks_per_shard); + let chunk_index = usize::try_from(chunk_index).unwrap(); + + // Read the offset/size + let offset = shard_index[chunk_index * 2]; + let size = shard_index[chunk_index * 2 + 1]; + if offset == u64::MAX && size == u64::MAX { + (chunk_subset, None) + } else { + let offset: usize = offset.try_into().unwrap(); + let size: usize = size.try_into().unwrap(); + (chunk_subset, Some((offset, size))) + } + }) + .collect::>(); + + let shard_size = array_subset.num_elements_usize() * data_type_size; + let mut shard = Vec::with_capacity(shard_size); + let shard_slice = UnsafeCellSlice::new_from_vec_with_spare_capacity(&mut shard); + + // Decode unfilled chunks + let results = futures::future::join_all( + chunk_info + .iter() + .filter_map(|(chunk_subset, offset_size)| { + offset_size + .as_ref() + .map(|offset_size| (chunk_subset, offset_size)) + }) + .map(|(chunk_subset, (offset, size))| { + let chunk_representation = chunk_representation.clone(); + async move { + let partial_decoder = self + .inner_codecs + .async_partial_decoder( + Box::new(AsyncByteIntervalPartialDecoder::new( + &*self.input_handle, + u64::try_from(*offset).unwrap(), + u64::try_from(*size).unwrap(), + )), + &chunk_representation, + options, // TODO: Adjust options for partial decoding? + ) + .await + .map_err(|err| if let CodecError::InvalidByteRangeError(_) = err { + CodecError::Other( + "The shard index references out-of-bounds bytes. The chunk may be corrupted." + .to_string(), + ) + } else { + err + })?; + let chunk_subset_overlap = unsafe { array_subset.overlap_unchecked(chunk_subset) }; + // Partial decoding is actually really slow with the blosc codec! Assume sharded chunks are small, and just decode the whole thing and extract bytes + // TODO: Investigate further + // let decoded_chunk = partial_decoder + // .partial_decode(&[chunk_subset_overlap.relative_to(chunk_subset.start())?]) + // .await? + // .remove(0); + let decoded_chunk = partial_decoder + .partial_decode_opt( + &[ArraySubset::new_with_shape(chunk_subset.shape().to_vec())], + options, + ) // TODO: Adjust options for partial decoding + .await? + .remove(0).into_owned(); + let decoded_chunk = decoded_chunk + .extract_array_subset( + &chunk_subset_overlap.relative_to(chunk_subset.start()).unwrap(), + chunk_subset.shape(), + self.decoded_representation.data_type() + )? + .into_fixed()? + .into_owned(); + Ok::<_, CodecError>((decoded_chunk, chunk_subset_overlap)) + }}), ) - .unwrap(); - for (index, _num_elements) in &contiguous_iterator { - let shard_offset = usize::try_from(index * element_size).unwrap(); - shard_slice[shard_offset..shard_offset + length] - .copy_from_slice(&filled_chunk[data_idx..data_idx + length]); - data_idx += length; - } + .await; + // FIXME: Concurrency limit for futures + + if !results.is_empty() { + rayon_iter_concurrent_limit::iter_concurrent_limit!( + options.concurrent_target(), + results, + try_for_each, + |subset_and_decoded_chunk| { + let (chunk_subset_bytes, chunk_subset_overlap): ( + Vec, + ArraySubset, + ) = subset_and_decoded_chunk?; + update_bytes_flen( + unsafe { shard_slice.get() }, + array_subset.shape(), + &chunk_subset_bytes.into(), + &chunk_subset_overlap + .relative_to(array_subset.start()) + .unwrap(), + data_type_size, + ); + Ok::<_, CodecError>(()) + } + )?; } - ); - }; - unsafe { shard.set_len(shard_size) }; - out.push(Cow::Owned(shard)); + + // Write filled chunks + let filled_chunks = chunk_info + .iter() + .filter_map(|(chunk_subset, offset_size)| { + if offset_size.is_none() { + Some(chunk_subset) + } else { + None + } + }) + .collect::>(); + if !filled_chunks.is_empty() { + // Write filled chunks + rayon_iter_concurrent_limit::iter_concurrent_limit!( + options.concurrent_target(), + filled_chunks, + for_each, + |chunk_subset: &ArraySubset| { + let chunk_subset_overlap = + unsafe { array_subset.overlap_unchecked(chunk_subset) }; + let filled_chunk = self + .decoded_representation + .fill_value() + .as_ne_bytes() + .repeat(chunk_subset_overlap.num_elements_usize()); + update_bytes_flen( + unsafe { shard_slice.get() }, + array_subset.shape(), + &filled_chunk.into(), + &chunk_subset_overlap + .relative_to(array_subset.start()) + .unwrap(), + data_type_size, + ); + } + ); + }; + unsafe { shard.set_len(shard_size) }; + out.push(ArrayBytes::from(shard)); + } + } } Ok(out) } diff --git a/src/array/codec/array_to_bytes/vlen.rs b/src/array/codec/array_to_bytes/vlen.rs new file mode 100644 index 00000000..07213411 --- /dev/null +++ b/src/array/codec/array_to_bytes/vlen.rs @@ -0,0 +1,198 @@ +//! The `vlen` array to bytes codec. + +mod vlen_codec; +mod vlen_partial_decoder; + +use std::{mem::size_of, num::NonZeroU64}; + +use itertools::Itertools; +pub use vlen::IDENTIFIER; + +pub use crate::metadata::v3::codec::vlen::{VlenCodecConfiguration, VlenCodecConfigurationV1}; +use crate::{ + array::{ + codec::{ArrayToBytesCodecTraits, CodecError, CodecOptions}, + convert_from_bytes_slice, ChunkRepresentation, CodecChain, DataType, Endianness, FillValue, + RawBytes, NATIVE_ENDIAN, + }, + metadata::v3::codec::vlen, +}; + +pub use vlen_codec::VlenCodec; + +use crate::{ + array::codec::{Codec, CodecPlugin}, + metadata::MetadataV3, + plugin::{PluginCreateError, PluginMetadataInvalidError}, +}; + +use super::bytes::reverse_endianness; + +// Register the codec. +inventory::submit! { + CodecPlugin::new(IDENTIFIER, is_name_vlen, create_codec_vlen) +} + +fn is_name_vlen(name: &str) -> bool { + name.eq(IDENTIFIER) +} + +pub(crate) fn create_codec_vlen(metadata: &MetadataV3) -> Result { + let configuration: VlenCodecConfiguration = metadata + .to_configuration() + .map_err(|_| PluginMetadataInvalidError::new(IDENTIFIER, "codec", metadata.clone()))?; + let codec = Box::new(VlenCodec::new_with_configuration(&configuration)?); + Ok(Codec::ArrayToBytes(codec)) +} + +fn get_vlen_bytes_and_offsets( + index_chunk_representation: &ChunkRepresentation, + bytes: &RawBytes, + index_codecs: &CodecChain, + data_codecs: &CodecChain, + options: &CodecOptions, +) -> Result<(Vec, Vec), CodecError> { + // Get the index length and data start + if bytes.len() < size_of::() { + return Err(CodecError::UnexpectedChunkDecodedSize( + bytes.len(), + size_of::() as u64, + )); + } + let index_len = u64::from_le_bytes(bytes[0..size_of::()].try_into().unwrap()); + let index_len = usize::try_from(index_len) + .map_err(|_| CodecError::Other("index length exceeds usize::MAX".to_string()))?; + let data_start = size_of::() + index_len; + let data_compressed_len = bytes.len() - data_start; + + // Decode the index + let index = &bytes[size_of::()..data_start]; + let mut index_bytes = index_codecs + .decode(index.into(), index_chunk_representation, options)? + .into_fixed()?; + if NATIVE_ENDIAN == Endianness::Big { + reverse_endianness(index_bytes.to_mut(), &DataType::UInt64); + } + let index = match index_chunk_representation.data_type() { + // DataType::UInt8 => { + // let index = convert_from_bytes_slice::(&index_bytes); + // offsets_u8_to_usize(index) + // } + // DataType::UInt16 => { + // let index = convert_from_bytes_slice::(&index_bytes); + // offsets_u16_to_usize(index) + // } + DataType::UInt32 => { + let index = convert_from_bytes_slice::(&index_bytes); + offsets_u32_to_usize(index) + } + DataType::UInt64 => { + let index = convert_from_bytes_slice::(&index_bytes); + offsets_u64_to_usize(index) + } + _ => unreachable!("other data types are not part of VlenIndexDataType"), + }; + + // Get the data length + let Some(&data_len_expected) = index.last() else { + return Err(CodecError::Other( + "Index is empty? It should have at least one element".to_string(), + )); + }; + + // Decode the data + let data = &bytes[data_start..data_start + data_compressed_len]; + let data = if let Ok(data_len_expected) = NonZeroU64::try_from(data_len_expected as u64) { + data_codecs.decode( + data.into(), + &unsafe { + // SAFETY: data type and fill value are compatible + ChunkRepresentation::new_unchecked( + vec![data_len_expected], + DataType::UInt8, + FillValue::from(0u8), + ) + }, + options, + )? + } else { + vec![].into() + } + .into_fixed()? + .into_owned(); + let data_len = data.len(); + + // Check the data length is as expected + if data_len != data_len_expected { + return Err(CodecError::Other(format!( + "Expected data length {data_len_expected} does not match data length {data_len}" + ))); + } + + // Validate the offsets + for (curr, next) in index.iter().tuple_windows() { + if next < curr || *next > data_len { + return Err(CodecError::Other( + "Invalid bytes offsets in vlen Offset64 encoded chunk".to_string(), + )); + } + } + + Ok((data, index)) +} + +// /// Convert u8 offsets to usize +// /// +// /// # Panics if the offsets exceed [`usize::MAX`]. +// fn offsets_u8_to_usize(offsets: Vec) -> Vec { +// if size_of::() == size_of::() { +// bytemuck::allocation::cast_vec(offsets) +// } else { +// offsets +// .into_iter() +// .map(|offset| usize::from(offset)) +// .collect() +// } +// } + +// /// Convert u16 offsets to usize +// /// +// /// # Panics if the offsets exceed [`usize::MAX`]. +// fn offsets_u16_to_usize(offsets: Vec) -> Vec { +// if size_of::() == size_of::() { +// bytemuck::allocation::cast_vec(offsets) +// } else { +// offsets +// .into_iter() +// .map(|offset| usize::from(offset)) +// .collect() +// } +// } + +/// Convert u32 offsets to usize +/// +/// # Panics if the offsets exceed [`usize::MAX`]. +fn offsets_u32_to_usize(offsets: Vec) -> Vec { + if size_of::() == size_of::() { + bytemuck::allocation::cast_vec(offsets) + } else { + offsets + .into_iter() + .map(|offset| usize::try_from(offset).unwrap()) + .collect() + } +} + +/// Convert u64 offsets to usize +/// +/// # Panics if the offsets exceed [`usize::MAX`]. +fn offsets_u64_to_usize(offsets: Vec) -> Vec { + if size_of::() == size_of::() { + bytemuck::allocation::cast_vec(offsets) + } else { + offsets + .into_iter() + .map(|offset| usize::try_from(offset).unwrap()) + .collect() + } +} diff --git a/src/array/codec/array_to_bytes/vlen/vlen_codec.rs b/src/array/codec/array_to_bytes/vlen/vlen_codec.rs new file mode 100644 index 00000000..9284715d --- /dev/null +++ b/src/array/codec/array_to_bytes/vlen/vlen_codec.rs @@ -0,0 +1,309 @@ +use std::{mem::size_of, num::NonZeroU64}; + +use crate::{ + array::{ + codec::{ + ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, BytesCodec, + BytesPartialDecoderTraits, CodecError, CodecOptions, CodecTraits, + RecommendedConcurrency, + }, + transmute_to_bytes_vec, ArrayBytes, ArrayMetadataOptions, BytesRepresentation, + ChunkRepresentation, CodecChain, DataType, DataTypeSize, Endianness, FillValue, RawBytes, + }, + metadata::v3::{codec::vlen::VlenIndexDataType, MetadataV3}, + plugin::PluginCreateError, +}; + +#[cfg(feature = "async")] +use crate::array::codec::{AsyncArrayPartialDecoderTraits, AsyncBytesPartialDecoderTraits}; + +use super::{vlen_partial_decoder, VlenCodecConfiguration, VlenCodecConfigurationV1}; + +/// A `bytes` codec implementation. +#[derive(Debug, Clone)] +pub struct VlenCodec { + index_codecs: CodecChain, + data_codecs: CodecChain, + index_data_type: VlenIndexDataType, +} + +impl Default for VlenCodec { + fn default() -> Self { + let index_codecs = CodecChain::new( + vec![], + Box::new(BytesCodec::new(Some(Endianness::Little))), + vec![], + ); + let data_codecs = CodecChain::new(vec![], Box::new(BytesCodec::new(None)), vec![]); + Self { + index_codecs, + data_codecs, + index_data_type: VlenIndexDataType::UInt64, + } + } +} + +impl VlenCodec { + /// Create a new `vlen` codec. + #[must_use] + pub fn new( + index_codecs: CodecChain, + data_codecs: CodecChain, + index_data_type: VlenIndexDataType, + ) -> Self { + Self { + index_codecs, + data_codecs, + index_data_type, + } + } + + /// Create a new `vlen` codec from configuration. + /// + /// # Errors + /// Returns a [`PluginCreateError`] if the codecs cannot be constructed from the codec metadata. + pub fn new_with_configuration( + configuration: &VlenCodecConfiguration, + ) -> Result { + let VlenCodecConfiguration::V1(configuration) = configuration; + let index_codecs = CodecChain::from_metadata(&configuration.index_codecs)?; + let data_codecs = CodecChain::from_metadata(&configuration.data_codecs)?; + Ok(Self::new( + index_codecs, + data_codecs, + configuration.index_data_type, + )) + } +} + +impl CodecTraits for VlenCodec { + fn create_metadata_opt(&self, _options: &ArrayMetadataOptions) -> Option { + let configuration = VlenCodecConfigurationV1 { + index_codecs: self.index_codecs.create_metadatas(), + data_codecs: self.data_codecs.create_metadatas(), + index_data_type: self.index_data_type, + }; + Some( + MetadataV3::new_with_serializable_configuration(super::IDENTIFIER, &configuration) + .unwrap(), + ) + } + + fn partial_decoder_should_cache_input(&self) -> bool { + false + } + + fn partial_decoder_decodes_all(&self) -> bool { + true // TODO: Vlen could do partial decoding, but needs coalescing etc + } +} + +impl ArrayCodecTraits for VlenCodec { + fn recommended_concurrency( + &self, + _decoded_representation: &ChunkRepresentation, + ) -> Result { + Ok(RecommendedConcurrency::new_maximum(1)) + } +} + +#[cfg_attr(feature = "async", async_trait::async_trait)] +impl ArrayToBytesCodecTraits for VlenCodec { + fn encode<'a>( + &self, + bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError> { + bytes.validate( + decoded_representation.num_elements(), + decoded_representation.data_type().size(), + )?; + let (data, offsets) = bytes.into_variable()?; + assert_eq!( + offsets.len(), + decoded_representation.num_elements_usize() + 1 + ); + + // Encode offsets + let num_offsets = + NonZeroU64::try_from(decoded_representation.num_elements_usize() as u64 + 1).unwrap(); + let offsets = match self.index_data_type { + // VlenIndexDataType::UInt8 => { + // let offsets = offsets + // .iter() + // .map(|offset| u8::try_from(*offset)) + // .collect::, _>>() + // .map_err(|_| { + // CodecError::Other( + // "index offsets are too large for a uint8 index_data_type".to_string(), + // ) + // })?; + // let offsets = transmute_to_bytes_vec(offsets); + // let index_chunk_rep = ChunkRepresentation::new( + // vec![num_offsets], + // DataType::UInt8, + // FillValue::from(0u8), + // ) + // .unwrap(); + // self.index_codecs + // .encode(offsets.into(), &index_chunk_rep, options)? + // } + // VlenIndexDataType::UInt16 => { + // let offsets = offsets + // .iter() + // .map(|offset| u16::try_from(*offset)) + // .collect::, _>>() + // .map_err(|_| { + // CodecError::Other( + // "index offsets are too large for a uint16 index_data_type".to_string(), + // ) + // })?; + // let offsets = transmute_to_bytes_vec(offsets); + // let index_chunk_rep = ChunkRepresentation::new( + // vec![num_offsets], + // DataType::UInt16, + // FillValue::from(0u16), + // ) + // .unwrap(); + // self.index_codecs + // .encode(offsets.into(), &index_chunk_rep, options)? + // } + VlenIndexDataType::UInt32 => { + let offsets = offsets + .iter() + .map(|offset| u32::try_from(*offset)) + .collect::, _>>() + .map_err(|_| { + CodecError::Other( + "index offsets are too large for a uint32 index_data_type".to_string(), + ) + })?; + let offsets = transmute_to_bytes_vec(offsets); + let index_chunk_rep = ChunkRepresentation::new( + vec![num_offsets], + DataType::UInt32, + FillValue::from(0u32), + ) + .unwrap(); + self.index_codecs + .encode(offsets.into(), &index_chunk_rep, options)? + } + VlenIndexDataType::UInt64 => { + let offsets = offsets + .iter() + .map(|offset| u64::try_from(*offset).unwrap()) + .collect::>(); + let offsets = transmute_to_bytes_vec(offsets); + let index_chunk_rep = ChunkRepresentation::new( + vec![num_offsets], + DataType::UInt64, + FillValue::from(0u64), + ) + .unwrap(); + self.index_codecs + .encode(offsets.into(), &index_chunk_rep, options)? + } + }; + + // Encode data + let data = if let Ok(data_len) = NonZeroU64::try_from(data.len() as u64) { + self.data_codecs.encode( + data.into(), + &ChunkRepresentation::new(vec![data_len], DataType::UInt8, FillValue::from(0u8)) + .unwrap(), + options, + )? + } else { + vec![].into() + }; + + // Pack encoded offsets length, encoded offsets, and encoded data + let mut bytes = Vec::with_capacity(size_of::() + offsets.len() + data.len()); + bytes.extend_from_slice(&u64::try_from(offsets.len()).unwrap().to_le_bytes()); // offsets length as u64 little endian + bytes.extend_from_slice(&offsets); + bytes.extend_from_slice(&data); + Ok(bytes.into()) + } + + fn decode<'a>( + &self, + bytes: RawBytes<'a>, + decoded_representation: &ChunkRepresentation, + options: &CodecOptions, + ) -> Result, CodecError> { + let num_elements = decoded_representation.num_elements_usize(); + let index_shape = vec![NonZeroU64::try_from(num_elements as u64 + 1).unwrap()]; + let index_chunk_rep = match self.index_data_type { + // VlenIndexDataType::UInt8 => { + // ChunkRepresentation::new(index_shape, DataType::UInt8, FillValue::from(0u8)) + // } + // VlenIndexDataType::UInt16 => { + // ChunkRepresentation::new(index_shape, DataType::UInt16, FillValue::from(0u16)) + // } + VlenIndexDataType::UInt32 => { + ChunkRepresentation::new(index_shape, DataType::UInt32, FillValue::from(0u32)) + } + VlenIndexDataType::UInt64 => { + ChunkRepresentation::new(index_shape, DataType::UInt64, FillValue::from(0u64)) + } + } + .unwrap(); + let (data, index) = super::get_vlen_bytes_and_offsets( + &index_chunk_rep, + &bytes, + &self.index_codecs, + &self.data_codecs, + options, + )?; + Ok(ArrayBytes::new_vlen(data, index)) + } + + fn partial_decoder<'a>( + &'a self, + input_handle: Box, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + Ok(Box::new(vlen_partial_decoder::VlenPartialDecoder::new( + input_handle, + decoded_representation.clone(), + &self.index_codecs, + &self.data_codecs, + self.index_data_type, + ))) + } + + #[cfg(feature = "async")] + async fn async_partial_decoder<'a>( + &'a self, + input_handle: Box, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + Ok(Box::new( + vlen_partial_decoder::AsyncVlenPartialDecoder::new( + input_handle, + decoded_representation.clone(), + &self.index_codecs, + &self.data_codecs, + self.index_data_type, + ), + )) + } + + fn compute_encoded_size( + &self, + decoded_representation: &ChunkRepresentation, + ) -> Result { + match decoded_representation.data_type().size() { + DataTypeSize::Variable => Ok(BytesRepresentation::UnboundedSize), + DataTypeSize::Fixed(_) => { + return Err(CodecError::UnsupportedDataType( + decoded_representation.data_type().clone(), + super::IDENTIFIER.to_string(), + )) + } + } + } +} diff --git a/src/array/codec/array_to_bytes/vlen/vlen_partial_decoder.rs b/src/array/codec/array_to_bytes/vlen/vlen_partial_decoder.rs new file mode 100644 index 00000000..f004a208 --- /dev/null +++ b/src/array/codec/array_to_bytes/vlen/vlen_partial_decoder.rs @@ -0,0 +1,178 @@ +// TODO: Support actual partial decoding, coalescing required + +use std::num::NonZeroU64; + +use crate::{ + array::{ + array_bytes::extract_decoded_regions_vlen, + codec::{ + ArrayPartialDecoderTraits, ArraySubset, BytesPartialDecoderTraits, CodecError, + CodecOptions, + }, + ArrayBytes, ArraySize, ChunkRepresentation, CodecChain, DataType, FillValue, RawBytes, + }, + metadata::v3::codec::vlen::VlenIndexDataType, +}; + +#[cfg(feature = "async")] +use crate::array::codec::{AsyncArrayPartialDecoderTraits, AsyncBytesPartialDecoderTraits}; + +/// Partial decoder for the `bytes` codec. +pub struct VlenPartialDecoder<'a> { + input_handle: Box, + decoded_representation: ChunkRepresentation, + index_codecs: &'a CodecChain, + data_codecs: &'a CodecChain, + index_data_type: VlenIndexDataType, +} + +impl<'a> VlenPartialDecoder<'a> { + /// Create a new partial decoder for the `bytes` codec. + pub fn new( + input_handle: Box, + decoded_representation: ChunkRepresentation, + index_codecs: &'a CodecChain, + data_codecs: &'a CodecChain, + index_data_type: VlenIndexDataType, + ) -> Self { + Self { + input_handle, + decoded_representation, + index_codecs, + data_codecs, + index_data_type, + } + } +} + +#[allow(clippy::too_many_arguments)] +fn decode_vlen_bytes<'a>( + index_codecs: &CodecChain, + data_codecs: &CodecChain, + index_data_type: VlenIndexDataType, + bytes: Option, + decoded_regions: &[ArraySubset], + fill_value: &FillValue, + shape: &[u64], + options: &CodecOptions, +) -> Result>, CodecError> { + if let Some(bytes) = bytes { + let num_elements = usize::try_from(shape.iter().product::()).unwrap(); + let index_shape = vec![unsafe { NonZeroU64::new_unchecked(1 + num_elements as u64) }]; + let index_chunk_representation = match index_data_type { + // VlenIndexDataType::UInt8 => { + // ChunkRepresentation::new(index_shape, DataType::UInt8, FillValue::from(0u8)) + // } + // VlenIndexDataType::UInt16 => { + // ChunkRepresentation::new(index_shape, DataType::UInt16, FillValue::from(0u16)) + // } + VlenIndexDataType::UInt32 => { + ChunkRepresentation::new(index_shape, DataType::UInt32, FillValue::from(0u32)) + } + VlenIndexDataType::UInt64 => { + ChunkRepresentation::new(index_shape, DataType::UInt64, FillValue::from(0u64)) + } + } + .expect("all data types/fill values are compatible"); + let (data, index) = super::get_vlen_bytes_and_offsets( + &index_chunk_representation, + &bytes, + index_codecs, + data_codecs, + options, + )?; + extract_decoded_regions_vlen(&data, &index, decoded_regions, shape) + } else { + // Chunk is empty, all decoded regions are empty + let mut output = Vec::with_capacity(decoded_regions.len()); + for decoded_region in decoded_regions { + let array_size = ArraySize::Variable { + num_elements: decoded_region.num_elements(), + }; + output.push(ArrayBytes::new_fill_value(array_size, fill_value)); + } + Ok(output) + } +} + +impl ArrayPartialDecoderTraits for VlenPartialDecoder<'_> { + fn data_type(&self) -> &DataType { + self.decoded_representation.data_type() + } + + fn partial_decode_opt( + &self, + decoded_regions: &[ArraySubset], + options: &CodecOptions, + ) -> Result>, CodecError> { + // Get all of the input bytes (cached due to CodecTraits::partial_decoder_decodes_all() == true) + let bytes = self.input_handle.decode(options)?; + decode_vlen_bytes( + self.index_codecs, + self.data_codecs, + self.index_data_type, + bytes, + decoded_regions, + self.decoded_representation.fill_value(), + &self.decoded_representation.shape_u64(), + options, + ) + } +} + +#[cfg(feature = "async")] +/// Asynchronous partial decoder for the `bytes` codec. +pub struct AsyncVlenPartialDecoder<'a> { + input_handle: Box, + decoded_representation: ChunkRepresentation, + index_codecs: &'a CodecChain, + data_codecs: &'a CodecChain, + index_data_type: VlenIndexDataType, +} + +#[cfg(feature = "async")] +impl<'a> AsyncVlenPartialDecoder<'a> { + /// Create a new partial decoder for the `bytes` codec. + pub fn new( + input_handle: Box, + decoded_representation: ChunkRepresentation, + index_codecs: &'a CodecChain, + data_codecs: &'a CodecChain, + index_data_type: VlenIndexDataType, + ) -> Self { + Self { + input_handle, + decoded_representation, + index_codecs, + data_codecs, + index_data_type, + } + } +} + +#[cfg(feature = "async")] +#[async_trait::async_trait] +impl AsyncArrayPartialDecoderTraits for AsyncVlenPartialDecoder<'_> { + fn data_type(&self) -> &DataType { + self.decoded_representation.data_type() + } + + async fn partial_decode_opt( + &self, + decoded_regions: &[ArraySubset], + options: &CodecOptions, + ) -> Result>, CodecError> { + // Get all of the input bytes (cached due to CodecTraits::partial_decoder_decodes_all() == true) + let bytes = self.input_handle.decode(options).await?; + decode_vlen_bytes( + self.index_codecs, + self.data_codecs, + self.index_data_type, + bytes, + decoded_regions, + self.decoded_representation.fill_value(), + &self.decoded_representation.shape_u64(), + options, + ) + } +} diff --git a/src/array/codec/array_to_bytes/vlen_v2.rs b/src/array/codec/array_to_bytes/vlen_v2.rs new file mode 100644 index 00000000..d4d2a2c5 --- /dev/null +++ b/src/array/codec/array_to_bytes/vlen_v2.rs @@ -0,0 +1,81 @@ +//! The `vlen_v2` array to bytes codec. + +mod vlen_v2_codec; +mod vlen_v2_partial_decoder; + +use std::mem::size_of; + +pub use vlen_v2::IDENTIFIER; + +pub use crate::metadata::v3::codec::vlen_v2::{ + VlenV2CodecConfiguration, VlenV2CodecConfigurationV1, +}; +use crate::{ + array::{codec::CodecError, RawBytes}, + metadata::v3::codec::vlen_v2, +}; + +pub use vlen_v2_codec::VlenV2Codec; + +use crate::{ + array::codec::{Codec, CodecPlugin}, + metadata::MetadataV3, + plugin::{PluginCreateError, PluginMetadataInvalidError}, +}; + +// Register the codec. +inventory::submit! { + CodecPlugin::new(IDENTIFIER, is_name_vlen_v2, create_codec_vlen_v2) +} + +fn is_name_vlen_v2(name: &str) -> bool { + name.eq(IDENTIFIER) +} + +pub(crate) fn create_codec_vlen_v2(metadata: &MetadataV3) -> Result { + let configuration: VlenV2CodecConfiguration = metadata + .to_configuration() + .map_err(|_| PluginMetadataInvalidError::new(IDENTIFIER, "codec", metadata.clone()))?; + let codec = Box::new(VlenV2Codec::new_with_configuration(&configuration)); + Ok(Codec::ArrayToBytes(codec)) +} + +fn get_interleaved_bytes_and_offsets( + num_elements: usize, + bytes: &RawBytes, +) -> Result<(Vec, Vec), CodecError> { + // Validate the bytes is long enough to contain header and element lengths + let header_length = size_of::() * (1 + num_elements); + if bytes.len() < header_length { + return Err(CodecError::UnexpectedChunkDecodedSize( + bytes.len(), + header_length as u64, + )); + } + + // Validate the number of elements from the header + let header_num_elements = u32::from_le_bytes((&bytes[0..size_of::()]).try_into().unwrap()); + if u32::try_from(num_elements).unwrap() != header_num_elements { + return Err(CodecError::Other(format!( + "Expected header with {num_elements} elements, got {header_num_elements}" + ))); + } + + let bytes_len = bytes.len() - header_length; + let mut bytes_out = Vec::with_capacity(bytes_len); + let mut offsets_out = Vec::with_capacity(num_elements + 1); + let mut offset = size_of::(); + for _element in 0..num_elements { + let length = + u32::from_le_bytes(bytes[offset..offset + size_of::()].try_into().unwrap()); + offset += size_of::(); + offsets_out.push(bytes_out.len()); + if length != 0 { + bytes_out.extend_from_slice(&bytes[offset..offset + length as usize]); + offset += length as usize; + } + } + offsets_out.push(bytes_out.len()); + + Ok((bytes_out, offsets_out)) +} diff --git a/src/array/codec/array_to_bytes/vlen_v2/vlen_v2_codec.rs b/src/array/codec/array_to_bytes/vlen_v2/vlen_v2_codec.rs new file mode 100644 index 00000000..76dba610 --- /dev/null +++ b/src/array/codec/array_to_bytes/vlen_v2/vlen_v2_codec.rs @@ -0,0 +1,157 @@ +use std::mem::size_of; + +use itertools::Itertools; + +use crate::{ + array::{ + codec::{ + ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, + BytesPartialDecoderTraits, CodecError, CodecOptions, CodecTraits, + RecommendedConcurrency, + }, + ArrayBytes, ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, DataTypeSize, + RawBytes, + }, + metadata::v3::MetadataV3, +}; + +#[cfg(feature = "async")] +use crate::array::codec::{AsyncArrayPartialDecoderTraits, AsyncBytesPartialDecoderTraits}; + +use super::{VlenV2CodecConfiguration, VlenV2CodecConfigurationV1}; + +/// The `vlen_v2` codec implementation. +#[derive(Debug, Clone, Default)] +pub struct VlenV2Codec {} + +impl VlenV2Codec { + /// Create a new `vlen` codec. + #[must_use] + pub fn new() -> Self { + Self {} + } + + /// Create a new `vlen` codec from configuration. + #[must_use] + pub fn new_with_configuration(_configuration: &VlenV2CodecConfiguration) -> Self { + // let VlenV2CodecConfiguration::V1(configuration) = configuration; + Self {} + } +} + +impl CodecTraits for VlenV2Codec { + fn create_metadata_opt(&self, _options: &ArrayMetadataOptions) -> Option { + let configuration = VlenV2CodecConfigurationV1 {}; + Some( + MetadataV3::new_with_serializable_configuration(super::IDENTIFIER, &configuration) + .unwrap(), + ) + } + + fn partial_decoder_should_cache_input(&self) -> bool { + false + } + + fn partial_decoder_decodes_all(&self) -> bool { + true // TODO: Vlen could do partial decoding, but needs coalescing etc + } +} + +impl ArrayCodecTraits for VlenV2Codec { + fn recommended_concurrency( + &self, + _decoded_representation: &ChunkRepresentation, + ) -> Result { + Ok(RecommendedConcurrency::new_maximum(1)) + } +} + +#[cfg_attr(feature = "async", async_trait::async_trait)] +impl ArrayToBytesCodecTraits for VlenV2Codec { + fn encode<'a>( + &self, + bytes: ArrayBytes<'a>, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + bytes.validate( + decoded_representation.num_elements(), + decoded_representation.data_type().size(), + )?; + let (bytes, offsets) = bytes.into_variable()?; + + let num_elements = decoded_representation.num_elements(); + debug_assert_eq!(1 + num_elements, offsets.len() as u64); + + let mut data: Vec = Vec::with_capacity(offsets.len() * size_of::() + bytes.len()); + // Number of elements + let num_elements = u32::try_from(num_elements).map_err(|_| { + CodecError::Other("num_elements exceeds u32::MAX in vlen codec".to_string()) + })?; + data.extend_from_slice(num_elements.to_le_bytes().as_slice()); + // Interleaved length (u32, little endian) and element bytes + for (&curr, &next) in offsets.iter().tuple_windows() { + let element_bytes = &bytes[curr..next]; + let element_bytes_len = u32::try_from(element_bytes.len()).unwrap(); + data.extend_from_slice(&element_bytes_len.to_le_bytes()); + data.extend_from_slice(element_bytes); + } + + Ok(data.into()) + } + + fn decode<'a>( + &self, + bytes: RawBytes<'a>, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + let num_elements = decoded_representation.num_elements_usize(); + let (bytes, offsets) = super::get_interleaved_bytes_and_offsets(num_elements, &bytes)?; + Ok(ArrayBytes::new_vlen(bytes, offsets)) + } + + fn partial_decoder<'a>( + &self, + input_handle: Box, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + Ok(Box::new( + super::vlen_v2_partial_decoder::VlenV2PartialDecoder::new( + input_handle, + decoded_representation.clone(), + ), + )) + } + + #[cfg(feature = "async")] + async fn async_partial_decoder<'a>( + &'a self, + input_handle: Box, + decoded_representation: &ChunkRepresentation, + _options: &CodecOptions, + ) -> Result, CodecError> { + Ok(Box::new( + super::vlen_v2_partial_decoder::AsyncVlenV2PartialDecoder::new( + input_handle, + decoded_representation.clone(), + ), + )) + } + + fn compute_encoded_size( + &self, + decoded_representation: &ChunkRepresentation, + ) -> Result { + match decoded_representation.data_type().size() { + DataTypeSize::Variable => Ok(BytesRepresentation::UnboundedSize), + DataTypeSize::Fixed(_) => { + return Err(CodecError::UnsupportedDataType( + decoded_representation.data_type().clone(), + super::IDENTIFIER.to_string(), + )) + } + } + } +} diff --git a/src/array/codec/array_to_bytes/vlen_v2/vlen_v2_partial_decoder.rs b/src/array/codec/array_to_bytes/vlen_v2/vlen_v2_partial_decoder.rs new file mode 100644 index 00000000..00b27bca --- /dev/null +++ b/src/array/codec/array_to_bytes/vlen_v2/vlen_v2_partial_decoder.rs @@ -0,0 +1,120 @@ +// TODO: Support actual partial decoding, coalescing required + +use crate::array::{ + array_bytes::extract_decoded_regions_vlen, + codec::{ + ArrayPartialDecoderTraits, ArraySubset, BytesPartialDecoderTraits, CodecError, CodecOptions, + }, + ArrayBytes, ArraySize, ChunkRepresentation, DataType, DataTypeSize, FillValue, RawBytes, +}; + +#[cfg(feature = "async")] +use crate::array::codec::{AsyncArrayPartialDecoderTraits, AsyncBytesPartialDecoderTraits}; + +/// Partial decoder for the `bytes` codec. +pub struct VlenV2PartialDecoder<'a> { + input_handle: Box, + decoded_representation: ChunkRepresentation, +} + +impl<'a> VlenV2PartialDecoder<'a> { + /// Create a new partial decoder for the `bytes` codec. + pub fn new( + input_handle: Box, + decoded_representation: ChunkRepresentation, + ) -> Self { + Self { + input_handle, + decoded_representation, + } + } +} + +fn decode_vlen_bytes<'a>( + bytes: Option, + decoded_regions: &[ArraySubset], + data_type_size: DataTypeSize, + fill_value: &FillValue, + shape: &[u64], +) -> Result>, CodecError> { + if let Some(bytes) = bytes { + let num_elements = usize::try_from(shape.iter().product::()).unwrap(); + let (bytes, offsets) = super::get_interleaved_bytes_and_offsets(num_elements, &bytes)?; + extract_decoded_regions_vlen(&bytes, &offsets, decoded_regions, shape) + } else { + // Chunk is empty, all decoded regions are empty + let mut output = Vec::with_capacity(decoded_regions.len()); + for decoded_region in decoded_regions { + let array_size = ArraySize::new(data_type_size, decoded_region.num_elements()); + output.push(ArrayBytes::new_fill_value(array_size, fill_value)); + } + Ok(output) + } +} + +impl ArrayPartialDecoderTraits for VlenV2PartialDecoder<'_> { + fn data_type(&self) -> &DataType { + self.decoded_representation.data_type() + } + + fn partial_decode_opt( + &self, + decoded_regions: &[ArraySubset], + options: &CodecOptions, + ) -> Result>, CodecError> { + // Get all of the input bytes (cached due to CodecTraits::partial_decoder_decodes_all() == true) + let bytes = self.input_handle.decode(options)?; + decode_vlen_bytes( + bytes, + decoded_regions, + self.decoded_representation.data_type().size(), + self.decoded_representation.fill_value(), + &self.decoded_representation.shape_u64(), + ) + } +} + +#[cfg(feature = "async")] +/// Asynchronous partial decoder for the `bytes` codec. +pub struct AsyncVlenV2PartialDecoder<'a> { + input_handle: Box, + decoded_representation: ChunkRepresentation, +} + +#[cfg(feature = "async")] +impl<'a> AsyncVlenV2PartialDecoder<'a> { + /// Create a new partial decoder for the `bytes` codec. + pub fn new( + input_handle: Box, + decoded_representation: ChunkRepresentation, + ) -> Self { + Self { + input_handle, + decoded_representation, + } + } +} + +#[cfg(feature = "async")] +#[async_trait::async_trait] +impl AsyncArrayPartialDecoderTraits for AsyncVlenV2PartialDecoder<'_> { + fn data_type(&self) -> &DataType { + self.decoded_representation.data_type() + } + + async fn partial_decode_opt( + &self, + decoded_regions: &[ArraySubset], + options: &CodecOptions, + ) -> Result>, CodecError> { + // Get all of the input bytes (cached due to CodecTraits::partial_decoder_decodes_all() == true) + let bytes = self.input_handle.decode(options).await?; + decode_vlen_bytes( + bytes, + decoded_regions, + self.decoded_representation.data_type().size(), + self.decoded_representation.fill_value(), + &self.decoded_representation.shape_u64(), + ) + } +} diff --git a/src/array/codec/array_to_bytes/zfp.rs b/src/array/codec/array_to_bytes/zfp.rs index 7c461c89..8a72adf1 100644 --- a/src/array/codec/array_to_bytes/zfp.rs +++ b/src/array/codec/array_to_bytes/zfp.rs @@ -271,10 +271,14 @@ fn zfp_decode( #[cfg(test)] mod tests { use num::traits::AsPrimitive; - use std::{borrow::Cow, num::NonZeroU64}; + use std::num::NonZeroU64; use crate::{ - array::codec::{ArrayCodecTraits, ArrayToBytesCodecTraits, CodecOptions}, + array::{ + codec::{ArrayToBytesCodecTraits, CodecOptions}, + element::ElementOwned, + ArrayBytes, + }, array_subset::ArraySubset, }; @@ -304,21 +308,23 @@ mod tests { ] } - fn codec_zfp_round_trip( + fn codec_zfp_round_trip< + T: core::fmt::Debug + std::cmp::PartialEq + ElementOwned + Copy + 'static, + >( chunk_representation: &ChunkRepresentation, configuration: &str, ) where i32: num::traits::AsPrimitive, { let elements: Vec = (0..27).map(|i: i32| i.as_()).collect(); - let bytes = crate::array::transmute_to_bytes_vec(elements.clone()); + let bytes = T::into_array_bytes(chunk_representation.data_type(), &elements).unwrap(); let configuration: ZfpCodecConfiguration = serde_json::from_str(configuration).unwrap(); let codec = ZfpCodec::new_with_configuration(&configuration); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -329,9 +335,10 @@ mod tests { &chunk_representation, &CodecOptions::default(), ) - .unwrap(); - - let decoded_elements = crate::array::convert_from_bytes_slice::(&decoded); + .unwrap() + .into_owned(); + let decoded_elements = + T::from_array_bytes(chunk_representation.data_type(), decoded).unwrap(); assert_eq!(elements, decoded_elements); } @@ -493,13 +500,14 @@ mod tests { ChunkRepresentation::new(chunk_shape, DataType::Float32, 0.0f32.into()).unwrap(); let elements: Vec = (0..27).map(|i| i as f32).collect(); let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); let configuration: ZfpCodecConfiguration = serde_json::from_str(JSON_REVERSIBLE).unwrap(); let codec = ZfpCodec::new_with_configuration(&configuration); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -523,7 +531,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) @@ -548,6 +556,7 @@ mod tests { ChunkRepresentation::new(chunk_shape, DataType::Float32, 0.0f32.into()).unwrap(); let elements: Vec = (0..27).map(|i| i as f32).collect(); let bytes = crate::array::transmute_to_bytes_vec(elements); + let bytes: ArrayBytes = bytes.into(); let configuration: ZfpCodecConfiguration = serde_json::from_str(JSON_REVERSIBLE).unwrap(); let codec = ZfpCodec::new_with_configuration(&configuration); @@ -555,7 +564,7 @@ mod tests { let max_encoded_size = codec.compute_encoded_size(&chunk_representation).unwrap(); let encoded = codec .encode( - Cow::Borrowed(&bytes), + bytes.clone(), &chunk_representation, &CodecOptions::default(), ) @@ -582,7 +591,7 @@ mod tests { let decoded_partial_chunk: Vec = decoded_partial_chunk .into_iter() - .map(|v| v.to_vec()) + .map(|bytes| bytes.into_fixed().unwrap().to_vec()) .flatten() .collect::>() .chunks(std::mem::size_of::()) diff --git a/src/array/codec/array_to_bytes/zfp/zfp_codec.rs b/src/array/codec/array_to_bytes/zfp/zfp_codec.rs index 3ea792fd..f98d7c81 100644 --- a/src/array/codec/array_to_bytes/zfp/zfp_codec.rs +++ b/src/array/codec/array_to_bytes/zfp/zfp_codec.rs @@ -11,8 +11,8 @@ use zfp_sys::{ use crate::{ array::{ codec::{ - ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, - BytesPartialDecoderTraits, CodecError, CodecOptions, CodecTraits, + ArrayBytes, ArrayCodecTraits, ArrayPartialDecoderTraits, ArrayToBytesCodecTraits, + BytesPartialDecoderTraits, CodecError, CodecOptions, CodecTraits, RawBytes, RecommendedConcurrency, }, ArrayMetadataOptions, BytesRepresentation, ChunkRepresentation, DataType, @@ -129,18 +129,21 @@ impl ArrayCodecTraits for ZfpCodec { // TODO: zfp supports multi thread, when is it optimal to kick in? Ok(RecommendedConcurrency::new_maximum(1)) } +} +#[cfg_attr(feature = "async", async_trait::async_trait)] +impl ArrayToBytesCodecTraits for ZfpCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + bytes: ArrayBytes<'a>, decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { - let mut decoded_value_promoted = - promote_before_zfp_encoding(&decoded_value, decoded_representation)?; - let zfp_type = decoded_value_promoted.zfp_type(); + ) -> Result, CodecError> { + let bytes = bytes.into_fixed()?; + let mut bytes_promoted = promote_before_zfp_encoding(&bytes, decoded_representation)?; + let zfp_type = bytes_promoted.zfp_type(); let Some(field) = ZfpField::new( - &mut decoded_value_promoted, + &mut bytes_promoted, &decoded_representation .shape() .iter() @@ -185,22 +188,19 @@ impl ArrayCodecTraits for ZfpCodec { fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + bytes: RawBytes<'a>, decoded_representation: &ChunkRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { zfp_decode( &self.mode, - &mut encoded_value.to_vec(), // FIXME: Does zfp **really** need the encoded value as mutable? + &mut bytes.to_vec(), // FIXME: Does zfp **really** need the encoded value as mutable? decoded_representation, false, // FIXME ) - .map(Cow::Owned) + .map(ArrayBytes::from) } -} -#[cfg_attr(feature = "async", async_trait::async_trait)] -impl ArrayToBytesCodecTraits for ZfpCodec { fn partial_decoder<'a>( &'a self, input_handle: Box, diff --git a/src/array/codec/array_to_bytes/zfp/zfp_partial_decoder.rs b/src/array/codec/array_to_bytes/zfp/zfp_partial_decoder.rs index ac5179ac..7f7103f7 100644 --- a/src/array/codec/array_to_bytes/zfp/zfp_partial_decoder.rs +++ b/src/array/codec/array_to_bytes/zfp/zfp_partial_decoder.rs @@ -1,8 +1,9 @@ -use std::borrow::Cow; - use crate::{ array::{ - codec::{ArrayPartialDecoderTraits, BytesPartialDecoderTraits, CodecError, CodecOptions}, + codec::{ + ArrayBytes, ArrayPartialDecoderTraits, BytesPartialDecoderTraits, CodecError, + CodecOptions, + }, ChunkRepresentation, DataType, }, array_subset::ArraySubset, @@ -51,7 +52,10 @@ impl ArrayPartialDecoderTraits for ZfpPartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { + let data_type_size = self.data_type().fixed_size().ok_or_else(|| { + CodecError::UnsupportedDataType(self.data_type().clone(), super::IDENTIFIER.to_string()) + })?; for array_subset in decoded_regions { if array_subset.dimensionality() != self.decoded_representation.dimensionality() { return Err(CodecError::InvalidArraySubsetDimensionalityError( @@ -73,13 +77,9 @@ impl ArrayPartialDecoderTraits for ZfpPartialDecoder<'_> { false, // FIXME )?; for array_subset in decoded_regions { - let byte_ranges = unsafe { - array_subset.byte_ranges_unchecked( - &chunk_shape, - self.decoded_representation.element_size(), - ) - }; - out.push(Cow::Owned(extract_byte_ranges_concat( + let byte_ranges = + unsafe { array_subset.byte_ranges_unchecked(&chunk_shape, data_type_size) }; + out.push(ArrayBytes::from(extract_byte_ranges_concat( &decoded_value, &byte_ranges, )?)); @@ -87,7 +87,7 @@ impl ArrayPartialDecoderTraits for ZfpPartialDecoder<'_> { } None => { for decoded_region in decoded_regions { - out.push(Cow::Owned( + out.push(ArrayBytes::from( self.decoded_representation .fill_value() .as_ne_bytes() @@ -141,7 +141,10 @@ impl AsyncArrayPartialDecoderTraits for AsyncZfpPartialDecoder<'_> { &self, decoded_regions: &[ArraySubset], options: &CodecOptions, - ) -> Result>, CodecError> { + ) -> Result>, CodecError> { + let data_type_size = self.data_type().fixed_size().ok_or_else(|| { + CodecError::UnsupportedDataType(self.data_type().clone(), super::IDENTIFIER.to_string()) + })?; for array_subset in decoded_regions { if array_subset.dimensionality() != self.decoded_representation.dimensionality() { return Err(CodecError::InvalidArraySubsetDimensionalityError( @@ -163,13 +166,9 @@ impl AsyncArrayPartialDecoderTraits for AsyncZfpPartialDecoder<'_> { false, // FIXME )?; for array_subset in decoded_regions { - let byte_ranges = unsafe { - array_subset.byte_ranges_unchecked( - &chunk_shape, - self.decoded_representation.element_size(), - ) - }; - out.push(Cow::Owned(extract_byte_ranges_concat( + let byte_ranges = + unsafe { array_subset.byte_ranges_unchecked(&chunk_shape, data_type_size) }; + out.push(ArrayBytes::from(extract_byte_ranges_concat( &decoded_value, &byte_ranges, )?)); @@ -177,7 +176,7 @@ impl AsyncArrayPartialDecoderTraits for AsyncZfpPartialDecoder<'_> { } None => { for decoded_region in decoded_regions { - out.push(Cow::Owned( + out.push(ArrayBytes::from( self.decoded_representation .fill_value() .as_ne_bytes() diff --git a/src/array/codec/byte_interval_partial_decoder.rs b/src/array/codec/byte_interval_partial_decoder.rs index e0e95eca..33fcffa7 100644 --- a/src/array/codec/byte_interval_partial_decoder.rs +++ b/src/array/codec/byte_interval_partial_decoder.rs @@ -1,6 +1,7 @@ -use std::borrow::Cow; - -use crate::byte_range::{ByteLength, ByteOffset, ByteRange}; +use crate::{ + array::RawBytes, + byte_range::{ByteLength, ByteOffset, ByteRange}, +}; use super::{BytesPartialDecoderTraits, CodecError, CodecOptions}; @@ -36,7 +37,7 @@ impl<'a> BytesPartialDecoderTraits for ByteIntervalPartialDecoder<'a> { &self, byte_ranges: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let byte_ranges: Vec = byte_ranges .iter() .map(|byte_range| match byte_range { @@ -92,7 +93,7 @@ impl<'a> AsyncBytesPartialDecoderTraits for AsyncByteIntervalPartialDecoder<'a> &self, byte_ranges: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let byte_ranges: Vec = byte_ranges .iter() .map(|byte_range| match byte_range { diff --git a/src/array/codec/bytes_partial_decoder_cache.rs b/src/array/codec/bytes_partial_decoder_cache.rs index de42f45a..634866ea 100644 --- a/src/array/codec/bytes_partial_decoder_cache.rs +++ b/src/array/codec/bytes_partial_decoder_cache.rs @@ -2,7 +2,10 @@ use std::{borrow::Cow, marker::PhantomData}; -use crate::byte_range::{extract_byte_ranges, ByteRange}; +use crate::{ + array::RawBytes, + byte_range::{extract_byte_ranges, ByteRange}, +}; use super::{BytesPartialDecoderTraits, CodecError, CodecOptions}; @@ -58,7 +61,7 @@ impl BytesPartialDecoderTraits for BytesPartialDecoderCache<'_> { &self, decoded_regions: &[ByteRange], _options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { Ok(match &self.cache { Some(bytes) => Some( extract_byte_ranges(bytes, decoded_regions) @@ -79,7 +82,7 @@ impl AsyncBytesPartialDecoderTraits for BytesPartialDecoderCache<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { BytesPartialDecoderTraits::partial_decode(self, decoded_regions, options) } } diff --git a/src/array/codec/bytes_to_bytes/blosc.rs b/src/array/codec/bytes_to_bytes/blosc.rs index ef8287b2..16bdc8b7 100644 --- a/src/array/codec/bytes_to_bytes/blosc.rs +++ b/src/array/codec/bytes_to_bytes/blosc.rs @@ -336,7 +336,9 @@ mod tests { let array_representation = ArrayRepresentation::new(vec![2, 2, 2], DataType::UInt16, FillValue::from(0u16)) .unwrap(); - let bytes_representation = BytesRepresentation::FixedSize(array_representation.size()); + let data_type_size = array_representation.data_type().fixed_size().unwrap(); + let array_size = array_representation.num_elements_usize() * data_type_size; + let bytes_representation = BytesRepresentation::FixedSize(array_size as u64); let elements: Vec = (0..array_representation.num_elements() as u16).collect(); let bytes = crate::array::transmute_to_bytes_vec(elements); @@ -349,10 +351,7 @@ mod tests { .encode(Cow::Borrowed(&bytes), &CodecOptions::default()) .unwrap(); let decoded_regions: Vec = ArraySubset::new_with_ranges(&[0..2, 1..2, 0..1]) - .byte_ranges( - array_representation.shape(), - array_representation.element_size(), - ) + .byte_ranges(array_representation.shape(), data_type_size) .unwrap(); let input_handle = Box::new(std::io::Cursor::new(encoded)); let partial_decoder = codec @@ -384,7 +383,9 @@ mod tests { let array_representation = ArrayRepresentation::new(vec![2, 2, 2], DataType::UInt16, FillValue::from(0u16)) .unwrap(); - let bytes_representation = BytesRepresentation::FixedSize(array_representation.size()); + let data_type_size = array_representation.data_type().fixed_size().unwrap(); + let array_size = array_representation.num_elements_usize() * data_type_size; + let bytes_representation = BytesRepresentation::FixedSize(array_size as u64); let elements: Vec = (0..array_representation.num_elements() as u16).collect(); let bytes = crate::array::transmute_to_bytes_vec(elements); @@ -397,10 +398,7 @@ mod tests { .encode(Cow::Borrowed(&bytes), &CodecOptions::default()) .unwrap(); let decoded_regions: Vec = ArraySubset::new_with_ranges(&[0..2, 1..2, 0..1]) - .byte_ranges( - array_representation.shape(), - array_representation.element_size(), - ) + .byte_ranges(array_representation.shape(), data_type_size) .unwrap(); let input_handle = Box::new(std::io::Cursor::new(encoded)); let partial_decoder = codec diff --git a/src/array/codec/bytes_to_bytes/blosc/blosc_codec.rs b/src/array/codec/bytes_to_bytes/blosc/blosc_codec.rs index f868d30f..c2a79046 100644 --- a/src/array/codec/bytes_to_bytes/blosc/blosc_codec.rs +++ b/src/array/codec/bytes_to_bytes/blosc/blosc_codec.rs @@ -8,7 +8,7 @@ use crate::{ BytesPartialDecoderTraits, BytesToBytesCodecTraits, CodecError, CodecOptions, CodecTraits, RecommendedConcurrency, }, - ArrayMetadataOptions, BytesRepresentation, + ArrayMetadataOptions, BytesRepresentation, RawBytes, }, metadata::v3::MetadataV3, plugin::PluginCreateError, @@ -136,7 +136,6 @@ impl CodecTraits for BloscCodec { cname: self.cname, clevel: self.clevel, shuffle: self.shuffle_mode.unwrap_or_else(|| { - // FIXME: If type size is not known... it must be if self.typesize.unwrap_or_default() > 0 { BloscShuffleMode::BitShuffle } else { @@ -170,9 +169,9 @@ impl BytesToBytesCodecTraits for BloscCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + decoded_value: RawBytes<'a>, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { // let n_threads = std::cmp::min( // options.concurrent_limit(), // std::thread::available_parallelism().unwrap(), @@ -184,10 +183,10 @@ impl BytesToBytesCodecTraits for BloscCodec { fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + encoded_value: RawBytes<'a>, _decoded_representation: &BytesRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { // let n_threads = std::cmp::min( // options.concurrent_limit(), // std::thread::available_parallelism().unwrap(), diff --git a/src/array/codec/bytes_to_bytes/blosc/blosc_partial_decoder.rs b/src/array/codec/bytes_to_bytes/blosc/blosc_partial_decoder.rs index aa9fd701..c4779b99 100644 --- a/src/array/codec/bytes_to_bytes/blosc/blosc_partial_decoder.rs +++ b/src/array/codec/bytes_to_bytes/blosc/blosc_partial_decoder.rs @@ -1,8 +1,12 @@ use std::borrow::Cow; use crate::{ - array::codec::{ - bytes_to_bytes::blosc::blosc_nbytes, BytesPartialDecoderTraits, CodecError, CodecOptions, + array::{ + codec::{ + bytes_to_bytes::blosc::blosc_nbytes, BytesPartialDecoderTraits, CodecError, + CodecOptions, + }, + RawBytes, }, byte_range::ByteRange, }; @@ -28,7 +32,7 @@ impl BytesPartialDecoderTraits for BloscPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options)?; let Some(encoded_value) = encoded_value else { return Ok(None); @@ -38,7 +42,6 @@ impl BytesPartialDecoderTraits for BloscPartialDecoder<'_> { let nbytes = blosc_nbytes(&encoded_value); let typesize = blosc_typesize(&encoded_value); if let (Some(nbytes), Some(typesize)) = (nbytes, typesize) { - // FIXME: This needs coalescing to be efficient, for now CodecTraits::partial_decoder_decodes_all is set to true let mut decoded_byte_ranges = Vec::with_capacity(decoded_regions.len()); for byte_range in decoded_regions { let start = usize::try_from(byte_range.start(nbytes as u64)).unwrap(); @@ -81,7 +84,7 @@ impl AsyncBytesPartialDecoderTraits for AsyncBloscPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options).await?; let Some(encoded_value) = encoded_value else { return Ok(None); diff --git a/src/array/codec/bytes_to_bytes/bz2.rs b/src/array/codec/bytes_to_bytes/bz2.rs index 87717eca..09a49182 100644 --- a/src/array/codec/bytes_to_bytes/bz2.rs +++ b/src/array/codec/bytes_to_bytes/bz2.rs @@ -100,7 +100,9 @@ mod tests { let array_representation = ArrayRepresentation::new(vec![2, 2, 2], DataType::UInt16, FillValue::from(0u16)) .unwrap(); - let bytes_representation = BytesRepresentation::FixedSize(array_representation.size()); + let data_type_size = array_representation.data_type().fixed_size().unwrap(); + let array_size = array_representation.num_elements_usize() * data_type_size; + let bytes_representation = BytesRepresentation::FixedSize(array_size as u64); let elements: Vec = (0..array_representation.num_elements() as u16).collect(); let bytes = crate::array::transmute_to_bytes_vec(elements); @@ -112,10 +114,7 @@ mod tests { .encode(Cow::Borrowed(&bytes), &CodecOptions::default()) .unwrap(); let decoded_regions: Vec = ArraySubset::new_with_ranges(&[0..2, 1..2, 0..1]) - .byte_ranges( - array_representation.shape(), - array_representation.element_size(), - ) + .byte_ranges(array_representation.shape(), data_type_size) .unwrap(); let input_handle = Box::new(std::io::Cursor::new(encoded)); let partial_decoder = codec @@ -147,7 +146,9 @@ mod tests { let array_representation = ArrayRepresentation::new(vec![2, 2, 2], DataType::UInt16, FillValue::from(0u16)) .unwrap(); - let bytes_representation = BytesRepresentation::FixedSize(array_representation.size()); + let data_type_size = array_representation.data_type().fixed_size().unwrap(); + let array_size = array_representation.num_elements_usize() * data_type_size; + let bytes_representation = BytesRepresentation::FixedSize(array_size as u64); let elements: Vec = (0..array_representation.num_elements() as u16).collect(); let bytes = crate::array::transmute_to_bytes_vec(elements); @@ -159,10 +160,7 @@ mod tests { .encode(Cow::Borrowed(&bytes), &CodecOptions::default()) .unwrap(); let decoded_regions: Vec = ArraySubset::new_with_ranges(&[0..2, 1..2, 0..1]) - .byte_ranges( - array_representation.shape(), - array_representation.element_size(), - ) + .byte_ranges(array_representation.shape(), data_type_size) .unwrap(); let input_handle = Box::new(std::io::Cursor::new(encoded)); let partial_decoder = codec diff --git a/src/array/codec/bytes_to_bytes/bz2/bz2_codec.rs b/src/array/codec/bytes_to_bytes/bz2/bz2_codec.rs index 6bba2f1b..e55a81e2 100644 --- a/src/array/codec/bytes_to_bytes/bz2/bz2_codec.rs +++ b/src/array/codec/bytes_to_bytes/bz2/bz2_codec.rs @@ -9,7 +9,7 @@ use crate::{ BytesPartialDecoderTraits, BytesToBytesCodecTraits, CodecError, CodecOptions, CodecTraits, RecommendedConcurrency, }, - ArrayMetadataOptions, BytesRepresentation, + ArrayMetadataOptions, BytesRepresentation, RawBytes, }, metadata::v3::MetadataV3, }; @@ -74,9 +74,9 @@ impl BytesToBytesCodecTraits for Bz2Codec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + decoded_value: RawBytes<'a>, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let mut encoder = bzip2::read::BzEncoder::new(Cursor::new(decoded_value), self.compression); let mut out: Vec = Vec::new(); encoder.read_to_end(&mut out)?; @@ -85,10 +85,10 @@ impl BytesToBytesCodecTraits for Bz2Codec { fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + encoded_value: RawBytes<'a>, _decoded_representation: &BytesRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let mut decoder = bzip2::read::BzDecoder::new(Cursor::new(encoded_value)); let mut out: Vec = Vec::new(); decoder.read_to_end(&mut out)?; diff --git a/src/array/codec/bytes_to_bytes/bz2/bz2_partial_decoder.rs b/src/array/codec/bytes_to_bytes/bz2/bz2_partial_decoder.rs index c3d7bf89..d0582923 100644 --- a/src/array/codec/bytes_to_bytes/bz2/bz2_partial_decoder.rs +++ b/src/array/codec/bytes_to_bytes/bz2/bz2_partial_decoder.rs @@ -3,7 +3,10 @@ use std::{borrow::Cow, io::Read}; use bytes::Buf; use crate::{ - array::codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + array::{ + codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + RawBytes, + }, byte_range::{extract_byte_ranges, ByteRange}, }; @@ -26,7 +29,7 @@ impl BytesPartialDecoderTraits for Bz2PartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options)?; let Some(encoded_value) = encoded_value else { return Ok(None); @@ -66,7 +69,7 @@ impl AsyncBytesPartialDecoderTraits for AsyncBz2PartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options).await?; let Some(encoded_value) = encoded_value else { return Ok(None); diff --git a/src/array/codec/bytes_to_bytes/crc32c/crc32c_codec.rs b/src/array/codec/bytes_to_bytes/crc32c/crc32c_codec.rs index 0e93b295..0cf0cfbe 100644 --- a/src/array/codec/bytes_to_bytes/crc32c/crc32c_codec.rs +++ b/src/array/codec/bytes_to_bytes/crc32c/crc32c_codec.rs @@ -6,7 +6,7 @@ use crate::{ BytesPartialDecoderTraits, BytesToBytesCodecTraits, CodecError, CodecOptions, CodecTraits, RecommendedConcurrency, }, - ArrayMetadataOptions, BytesRepresentation, + ArrayMetadataOptions, BytesRepresentation, RawBytes, }, metadata::v3::MetadataV3, }; @@ -63,9 +63,9 @@ impl BytesToBytesCodecTraits for Crc32cCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + decoded_value: RawBytes<'a>, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let checksum = crc32c::crc32c(&decoded_value).to_le_bytes(); let mut encoded_value: Vec = Vec::with_capacity(decoded_value.len() + checksum.len()); encoded_value.extend_from_slice(&decoded_value); @@ -75,10 +75,10 @@ impl BytesToBytesCodecTraits for Crc32cCodec { fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + encoded_value: RawBytes<'a>, _decoded_representation: &BytesRepresentation, options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { if encoded_value.len() >= CHECKSUM_SIZE { if options.validate_checksums() { let decoded_value = &encoded_value[..encoded_value.len() - CHECKSUM_SIZE]; diff --git a/src/array/codec/bytes_to_bytes/crc32c/crc32c_partial_decoder.rs b/src/array/codec/bytes_to_bytes/crc32c/crc32c_partial_decoder.rs index f8769c0b..4d034849 100644 --- a/src/array/codec/bytes_to_bytes/crc32c/crc32c_partial_decoder.rs +++ b/src/array/codec/bytes_to_bytes/crc32c/crc32c_partial_decoder.rs @@ -1,7 +1,10 @@ use std::borrow::Cow; use crate::{ - array::codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + array::{ + codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + RawBytes, + }, byte_range::ByteRange, }; @@ -27,7 +30,7 @@ impl BytesPartialDecoderTraits for Crc32cPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let bytes = self.input_handle.partial_decode(decoded_regions, options)?; let Some(bytes) = bytes else { return Ok(None); @@ -80,7 +83,7 @@ impl AsyncBytesPartialDecoderTraits for AsyncCrc32cPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let bytes = self .input_handle .partial_decode(decoded_regions, options) diff --git a/src/array/codec/bytes_to_bytes/gzip/gzip_codec.rs b/src/array/codec/bytes_to_bytes/gzip/gzip_codec.rs index a635315f..af024c25 100644 --- a/src/array/codec/bytes_to_bytes/gzip/gzip_codec.rs +++ b/src/array/codec/bytes_to_bytes/gzip/gzip_codec.rs @@ -11,7 +11,7 @@ use crate::{ BytesPartialDecoderTraits, BytesToBytesCodecTraits, CodecError, CodecOptions, CodecTraits, RecommendedConcurrency, }, - ArrayMetadataOptions, BytesRepresentation, + ArrayMetadataOptions, BytesRepresentation, RawBytes, }, metadata::v3::MetadataV3, }; @@ -78,9 +78,9 @@ impl BytesToBytesCodecTraits for GzipCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + decoded_value: RawBytes<'a>, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let mut encoder = GzEncoder::new( Cursor::new(decoded_value), flate2::Compression::new(self.compression_level.as_u32()), @@ -92,10 +92,10 @@ impl BytesToBytesCodecTraits for GzipCodec { fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + encoded_value: RawBytes<'a>, _decoded_representation: &BytesRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let mut decoder = GzDecoder::new(Cursor::new(encoded_value)); let mut out: Vec = Vec::new(); decoder.read_to_end(&mut out)?; diff --git a/src/array/codec/bytes_to_bytes/gzip/gzip_partial_decoder.rs b/src/array/codec/bytes_to_bytes/gzip/gzip_partial_decoder.rs index dd86a86b..8ecff296 100644 --- a/src/array/codec/bytes_to_bytes/gzip/gzip_partial_decoder.rs +++ b/src/array/codec/bytes_to_bytes/gzip/gzip_partial_decoder.rs @@ -6,7 +6,10 @@ use std::{ use flate2::bufread::GzDecoder; use crate::{ - array::codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + array::{ + codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + RawBytes, + }, byte_range::{extract_byte_ranges, ByteRange}, }; @@ -30,7 +33,7 @@ impl BytesPartialDecoderTraits for GzipPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options)?; let Some(encoded_value) = encoded_value else { return Ok(None); @@ -71,7 +74,7 @@ impl AsyncBytesPartialDecoderTraits for AsyncGzipPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options).await?; let Some(encoded_value) = encoded_value else { return Ok(None); diff --git a/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_codec.rs b/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_codec.rs index c7723865..7730b8f6 100644 --- a/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_codec.rs +++ b/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_codec.rs @@ -1,12 +1,10 @@ -use std::borrow::Cow; - use crate::{ array::{ codec::{ BytesPartialDecoderTraits, BytesToBytesCodecTraits, CodecError, CodecOptions, CodecTraits, RecommendedConcurrency, }, - ArrayMetadataOptions, BytesRepresentation, + ArrayMetadataOptions, BytesRepresentation, RawBytes, }, metadata::v3::MetadataV3, }; @@ -56,18 +54,18 @@ impl BytesToBytesCodecTraits for TestUnboundedCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + decoded_value: RawBytes<'a>, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { Ok(decoded_value) } fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + encoded_value: RawBytes<'a>, _decoded_representation: &BytesRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { Ok(encoded_value) } diff --git a/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_partial_decoder.rs b/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_partial_decoder.rs index e999809b..9838b28e 100644 --- a/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_partial_decoder.rs +++ b/src/array/codec/bytes_to_bytes/test_unbounded/test_unbounded_partial_decoder.rs @@ -1,7 +1,10 @@ use std::borrow::Cow; use crate::{ - array::codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + array::{ + codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + RawBytes, + }, byte_range::{extract_byte_ranges, ByteRange}, }; @@ -25,7 +28,7 @@ impl BytesPartialDecoderTraits for TestUnboundedPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options)?; let Some(encoded_value) = encoded_value else { return Ok(None); @@ -62,7 +65,7 @@ impl AsyncBytesPartialDecoderTraits for AsyncTestUnboundedPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options).await?; let Some(encoded_value) = encoded_value else { return Ok(None); diff --git a/src/array/codec/bytes_to_bytes/zstd/zstd_codec.rs b/src/array/codec/bytes_to_bytes/zstd/zstd_codec.rs index 29268056..187be17a 100644 --- a/src/array/codec/bytes_to_bytes/zstd/zstd_codec.rs +++ b/src/array/codec/bytes_to_bytes/zstd/zstd_codec.rs @@ -8,7 +8,7 @@ use crate::{ BytesPartialDecoderTraits, BytesToBytesCodecTraits, CodecError, CodecOptions, CodecTraits, RecommendedConcurrency, }, - ArrayMetadataOptions, BytesRepresentation, + ArrayMetadataOptions, BytesRepresentation, RawBytes, }, metadata::v3::MetadataV3, }; @@ -76,9 +76,9 @@ impl BytesToBytesCodecTraits for ZstdCodec { fn encode<'a>( &self, - decoded_value: Cow<'a, [u8]>, + decoded_value: RawBytes<'a>, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { let mut result = Vec::::new(); let mut encoder = zstd::Encoder::new(&mut result, self.compression)?; encoder.include_checksum(self.checksum)?; @@ -93,10 +93,10 @@ impl BytesToBytesCodecTraits for ZstdCodec { fn decode<'a>( &self, - encoded_value: Cow<'a, [u8]>, + encoded_value: RawBytes<'a>, _decoded_representation: &BytesRepresentation, _options: &CodecOptions, - ) -> Result, CodecError> { + ) -> Result, CodecError> { zstd::decode_all(std::io::Cursor::new(&encoded_value)) .map_err(CodecError::IOError) .map(Cow::Owned) diff --git a/src/array/codec/bytes_to_bytes/zstd/zstd_partial_decoder.rs b/src/array/codec/bytes_to_bytes/zstd/zstd_partial_decoder.rs index 432a6ab0..5a357b39 100644 --- a/src/array/codec/bytes_to_bytes/zstd/zstd_partial_decoder.rs +++ b/src/array/codec/bytes_to_bytes/zstd/zstd_partial_decoder.rs @@ -3,7 +3,10 @@ use std::borrow::Cow; use bytes::Buf; use crate::{ - array::codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + array::{ + codec::{BytesPartialDecoderTraits, CodecError, CodecOptions}, + RawBytes, + }, byte_range::{extract_byte_ranges, ByteRange}, }; @@ -27,7 +30,7 @@ impl BytesPartialDecoderTraits for ZstdPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options)?; let Some(encoded_value) = encoded_value else { return Ok(None); @@ -66,7 +69,7 @@ impl AsyncBytesPartialDecoderTraits for AsyncZstdPartialDecoder<'_> { &self, decoded_regions: &[ByteRange], options: &CodecOptions, - ) -> Result>>, CodecError> { + ) -> Result>>, CodecError> { let encoded_value = self.input_handle.decode(options).await?; let Some(encoded_value) = encoded_value else { return Ok(None); diff --git a/src/array/data_type.rs b/src/array/data_type.rs index 5b622f7f..1f745d22 100644 --- a/src/array/data_type.rs +++ b/src/array/data_type.rs @@ -22,6 +22,7 @@ use super::FillValue; /// A data type. #[derive(Clone, Debug)] #[non_exhaustive] +#[rustfmt::skip] pub enum DataType { /// `bool` Boolean. Bool, @@ -55,9 +56,13 @@ pub enum DataType { Complex128, /// `r*` raw bits, variable size given by *, limited to be a multiple of 8. RawBits(usize), // the stored usize is the size in bytes + /// A UTF-8 encoded string. + String, + /// Variable-sized binary data. + Binary, - // /// An extension data type. - // Extension(Box), + // /// An extension data type. + // Extension(Box), } /// An unsupported data type error. @@ -102,6 +107,17 @@ impl IncompatibleFillValueError { } } +/// The size of a data type. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum DataTypeSize { + /// Fixed size (in bytes). + Fixed(usize), + /// Variable sized. + /// + /// + Variable, +} + /// Extension data type traits. pub trait DataTypeExtension: dyn_clone::DynClone + core::fmt::Debug + Send + Sync { /// Returns the identifier. @@ -110,8 +126,8 @@ pub trait DataTypeExtension: dyn_clone::DynClone + core::fmt::Debug + Send + Syn /// Returns the name. fn name(&self) -> String; - /// Returns the size in bytes. - fn size(&self) -> usize; + /// Returns the data type size in bytes. + fn size(&self) -> DataTypeSize; /// Returns the data type metadata. fn metadata(&self) -> MetadataV3; @@ -154,6 +170,8 @@ impl DataType { Self::Complex64 => "complex64", Self::Complex128 => "complex128", Self::RawBits(_usize) => "r*", + Self::String => "string", + Self::Binary => "binary", // Self::Extension(extension) => extension.identifier(), } } @@ -178,20 +196,30 @@ impl DataType { // } } - /// Returns the size in bytes. + /// Returns the [`DataTypeSize`]. #[must_use] - pub const fn size(&self) -> usize { + pub const fn size(&self) -> DataTypeSize { match self { - Self::Bool | Self::Int8 | Self::UInt8 => 1, - Self::Int16 | Self::UInt16 | Self::Float16 | Self::BFloat16 => 2, - Self::Int32 | Self::UInt32 | Self::Float32 => 4, - Self::Int64 | Self::UInt64 | Self::Float64 | Self::Complex64 => 8, - Self::Complex128 => 16, - Self::RawBits(size) => *size, + Self::Bool | Self::Int8 | Self::UInt8 => DataTypeSize::Fixed(1), + Self::Int16 | Self::UInt16 | Self::Float16 | Self::BFloat16 => DataTypeSize::Fixed(2), + Self::Int32 | Self::UInt32 | Self::Float32 => DataTypeSize::Fixed(4), + Self::Int64 | Self::UInt64 | Self::Float64 | Self::Complex64 => DataTypeSize::Fixed(8), + Self::Complex128 => DataTypeSize::Fixed(16), + Self::RawBits(size) => DataTypeSize::Fixed(*size), + Self::String | Self::Binary => DataTypeSize::Variable, // Self::Extension(extension) => extension.size(), } } + /// Returns the size in bytes of a fixed-size data type, otherwise returns [`None`]. + #[must_use] + pub const fn fixed_size(&self) -> Option { + match self.size() { + DataTypeSize::Fixed(size) => Some(size), + DataTypeSize::Variable => None, + } + } + /// Create a data type from metadata. /// /// # Errors @@ -216,6 +244,8 @@ impl DataType { "bfloat16" => return Ok(Self::BFloat16), "complex64" => return Ok(Self::Complex64), "complex128" => return Ok(Self::Complex128), + "string" => return Ok(Self::String), + "binary" => return Ok(Self::Binary), _ => {} }; @@ -280,11 +310,26 @@ impl DataType { return Ok(FillValue::new(bytes.clone())); } } - Err(IncompatibleFillValueMetadataError( - self.name(), - fill_value.clone(), - )) - } // Self::Extension(extension) => extension.fill_value_from_metadata(fill_value), + Err(err()) + } + Self::Binary => { + if let FillValueMetadata::ByteArray(bytes) = fill_value { + Ok(FillValue::new(bytes.clone())) + } else { + Err(err()) + } + } + // Self::Extension(extension) => extension.fill_value_from_metadata(fill_value), + Self::String => match fill_value { + FillValueMetadata::String(string) => Ok(FillValue::new(string.as_bytes().to_vec())), + FillValueMetadata::Float(float) => match float { + FillValueFloat::HexString(hex_string) => Ok(String::from(hex_string).into()), + FillValueFloat::NonFinite(non_finite) => Ok(String::from(non_finite).into()), + FillValueFloat::Float(_) => Err(err()), + }, + FillValueMetadata::ByteArray(bytes) => Ok(FillValue::new(bytes.clone())), + _ => Err(err()), + }, } } @@ -346,7 +391,12 @@ impl DataType { Self::RawBits(size) => { debug_assert_eq!(fill_value.as_ne_bytes().len(), *size); FillValueMetadata::ByteArray(fill_value.as_ne_bytes().to_vec()) - } // DataType::Extension(extension) => extension.metadata_fill_value(fill_value), + } + // DataType::Extension(extension) => extension.metadata_fill_value(fill_value), + Self::String => FillValueMetadata::String( + String::from_utf8(fill_value.as_ne_bytes().to_vec()).unwrap(), + ), + Self::Binary => FillValueMetadata::ByteArray(fill_value.as_ne_bytes().to_vec()), } } } @@ -869,7 +919,7 @@ mod tests { assert_eq!(json, serde_json::to_string(&data_type.metadata()).unwrap()); assert_eq!(data_type.identifier(), "r*"); assert_eq!(data_type.name().as_str(), "r8"); - assert_eq!(data_type.size(), 1); + assert_eq!(data_type.size(), DataTypeSize::Fixed(1)); let metadata = serde_json::from_str::("[7]").unwrap(); let fill_value = data_type.fill_value_from_metadata(&metadata).unwrap(); @@ -885,7 +935,7 @@ mod tests { assert_eq!(json, serde_json::to_string(&data_type.metadata()).unwrap()); assert_eq!(data_type.identifier(), "r*"); assert_eq!(data_type.name().as_str(), "r16"); - assert_eq!(data_type.size(), 2); + assert_eq!(data_type.size(), DataTypeSize::Fixed(2)); let metadata = serde_json::from_str::("[0, 255]").unwrap(); let fill_value = data_type.fill_value_from_metadata(&metadata).unwrap(); @@ -949,7 +999,7 @@ mod tests { let json = r#""r16""#; let metadata = serde_json::from_str::(json).unwrap(); let data_type: DataType = DataType::from_metadata(&metadata).unwrap(); - assert_eq!(data_type.size(), 2); + assert_eq!(data_type.size(), DataTypeSize::Fixed(2)); } #[test] @@ -960,7 +1010,7 @@ mod tests { }"#; let metadata = serde_json::from_str::(json).unwrap(); let data_type: DataType = DataType::from_metadata(&metadata).unwrap(); - assert_eq!(data_type.size(), 2); + assert_eq!(data_type.size(), DataTypeSize::Fixed(2)); } #[test] @@ -1140,4 +1190,38 @@ mod tests { .fill_value_from_metadata(&metadata) .is_err()); } + + #[test] + fn data_type_string() { + let json = r#""string""#; + let metadata: MetadataV3 = serde_json::from_str(json).unwrap(); + let data_type = DataType::from_metadata(&metadata).unwrap(); + assert_eq!(json, serde_json::to_string(&data_type.metadata()).unwrap()); + assert_eq!(data_type.identifier(), "string"); + assert_eq!(data_type.name().as_str(), "string"); + assert_eq!(data_type.size(), DataTypeSize::Variable); + + let metadata = serde_json::from_str::(r#""hello world""#).unwrap(); + let fill_value = data_type.fill_value_from_metadata(&metadata).unwrap(); + assert_eq!(fill_value.as_ne_bytes(), "hello world".as_bytes(),); + assert_eq!(metadata, data_type.metadata_fill_value(&fill_value)); + + let metadata = serde_json::from_str::( + r#"[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]"#, + ) + .unwrap(); + let fill_value = data_type.fill_value_from_metadata(&metadata).unwrap(); + assert_eq!(fill_value.as_ne_bytes(), "hello world".as_bytes(),); + assert_ne!(metadata, data_type.metadata_fill_value(&fill_value)); // metadata is byte array rep, that is okay + + let metadata = serde_json::from_str::(r#""Infinity""#).unwrap(); + let fill_value = data_type.fill_value_from_metadata(&metadata).unwrap(); + assert_eq!(fill_value.as_ne_bytes(), "Infinity".as_bytes(),); + assert_ne!(metadata, data_type.metadata_fill_value(&fill_value)); // metadata is float rep, that is okay + + let metadata = serde_json::from_str::(r#""0x7fc00000""#).unwrap(); + let fill_value = data_type.fill_value_from_metadata(&metadata).unwrap(); + assert_eq!(fill_value.as_ne_bytes(), "0x7fc00000".as_bytes(),); + assert_ne!(metadata, data_type.metadata_fill_value(&fill_value)); // metadata is float rep, that is okay + } } diff --git a/src/array/element.rs b/src/array/element.rs new file mode 100644 index 00000000..b4bec745 --- /dev/null +++ b/src/array/element.rs @@ -0,0 +1,267 @@ +use std::mem::ManuallyDrop; + +use itertools::Itertools; +use ArrayError::IncompatibleElementType as IET; + +use super::{convert_from_bytes_slice, transmute_to_bytes, ArrayBytes, ArrayError, DataType}; + +/// A trait representing an array element type. +pub trait Element: Sized + Clone { + /// Validate the data type. + /// + /// # Errors + /// Returns an [`ArrayError`] if the data type is incompatible with [`Element`]. + fn validate_data_type(data_type: &DataType) -> Result<(), ArrayError>; + + /// Convert a slice of elements into [`ArrayBytes`]. + /// + /// # Errors + /// Returns an [`ArrayError`] if the data type is incompatible with [`Element`]. + fn into_array_bytes<'a>( + data_type: &DataType, + elements: &'a [Self], + ) -> Result, ArrayError>; +} + +/// A trait representing an owned array element type. +pub trait ElementOwned: Element { + /// Convert bytes into a [`Vec`]. + /// + /// # Errors + /// Returns an [`ArrayError`] if the data type is incompatible with [`Element`]. + fn from_array_bytes( + data_type: &DataType, + bytes: ArrayBytes<'_>, + ) -> Result, ArrayError>; +} + +/// A marker trait for a fixed length element. +pub trait ElementFixedLength {} + +impl ElementFixedLength for bool {} +impl ElementFixedLength for u8 {} +impl ElementFixedLength for u16 {} +impl ElementFixedLength for u32 {} +impl ElementFixedLength for u64 {} +impl ElementFixedLength for i8 {} +impl ElementFixedLength for i16 {} +impl ElementFixedLength for i32 {} +impl ElementFixedLength for i64 {} +impl ElementFixedLength for half::f16 {} +impl ElementFixedLength for half::bf16 {} +impl ElementFixedLength for f32 {} +impl ElementFixedLength for f64 {} +impl ElementFixedLength for num::complex::Complex32 {} +impl ElementFixedLength for num::complex::Complex64 {} +impl ElementFixedLength for [u8; N] {} + +impl Element for bool { + fn validate_data_type(data_type: &DataType) -> Result<(), ArrayError> { + (data_type == &DataType::Bool).then_some(()).ok_or(IET) + } + + fn into_array_bytes<'a>( + data_type: &DataType, + elements: &'a [Self], + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + Ok(transmute_to_bytes(elements).into()) + } +} + +impl ElementOwned for bool { + fn from_array_bytes( + data_type: &DataType, + bytes: ArrayBytes<'_>, + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + let bytes = bytes.into_fixed()?; + let elements_u8 = convert_from_bytes_slice::(&bytes); + if elements_u8.iter().all(|&u| u <= 1) { + let length: usize = elements_u8.len(); + let capacity: usize = elements_u8.capacity(); + let mut manual_drop_vec = ManuallyDrop::new(elements_u8); + let vec_ptr: *mut u8 = manual_drop_vec.as_mut_ptr(); + let ptr: *mut Self = vec_ptr.cast::(); + Ok(unsafe { Vec::from_raw_parts(ptr, length, capacity) }) + } else { + Err(ArrayError::InvalidElementValue) + } + } +} + +macro_rules! impl_element_pod { + ($raw_type:ty, $data_type:expr) => { + impl Element for $raw_type { + fn validate_data_type(data_type: &DataType) -> Result<(), ArrayError> { + (data_type == &$data_type).then_some(()).ok_or(IET) + } + + fn into_array_bytes<'a>( + data_type: &DataType, + elements: &'a [Self], + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + Ok(transmute_to_bytes(elements).into()) + } + } + + impl ElementOwned for $raw_type { + fn from_array_bytes( + data_type: &DataType, + bytes: ArrayBytes<'_>, + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + let bytes = bytes.into_fixed()?; + Ok(convert_from_bytes_slice::(&bytes)) + } + } + }; +} + +impl_element_pod!(i8, DataType::Int8); +impl_element_pod!(i16, DataType::Int16); +impl_element_pod!(i32, DataType::Int32); +impl_element_pod!(i64, DataType::Int64); +impl_element_pod!(u8, DataType::UInt8); +impl_element_pod!(u16, DataType::UInt16); +impl_element_pod!(u32, DataType::UInt32); +impl_element_pod!(u64, DataType::UInt64); +impl_element_pod!(half::f16, DataType::Float16); +impl_element_pod!(f32, DataType::Float32); +impl_element_pod!(f64, DataType::Float64); +impl_element_pod!(half::bf16, DataType::BFloat16); +impl_element_pod!(num::complex::Complex32, DataType::Complex64); +impl_element_pod!(num::complex::Complex64, DataType::Complex128); + +impl Element for [u8; N] { + fn validate_data_type(data_type: &DataType) -> Result<(), ArrayError> { + if let DataType::RawBits(n) = data_type { + (*n == N).then_some(()).ok_or(IET) + } else { + Err(IET) + } + } + + fn into_array_bytes<'a>( + data_type: &DataType, + elements: &'a [Self], + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + Ok(transmute_to_bytes(elements).into()) + } +} + +impl ElementOwned for [u8; N] { + fn from_array_bytes( + data_type: &DataType, + bytes: ArrayBytes<'_>, + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + let bytes = bytes.into_fixed()?; + Ok(convert_from_bytes_slice::(&bytes)) + } +} + +macro_rules! impl_element_string { + ($raw_type:ty) => { + impl Element for $raw_type { + fn validate_data_type(data_type: &DataType) -> Result<(), ArrayError> { + (data_type == &DataType::String).then_some(()).ok_or(IET) + } + + fn into_array_bytes<'a>( + data_type: &DataType, + elements: &'a [Self], + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + + // Calculate offsets + let mut len: usize = 0; + let mut offsets = Vec::with_capacity(elements.len()); + for element in elements { + offsets.push(len); + len = len.checked_add(element.len()).unwrap(); + } + offsets.push(len); + + // Concatenate bytes + let mut bytes = Vec::with_capacity(usize::try_from(len).unwrap()); + for element in elements { + bytes.extend_from_slice(element.as_bytes()); + } + Ok(ArrayBytes::new_vlen(bytes, offsets)) + } + } + }; +} + +impl_element_string!(&str); +impl_element_string!(String); + +impl ElementOwned for String { + fn from_array_bytes( + data_type: &DataType, + bytes: ArrayBytes<'_>, + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + let (bytes, offsets) = bytes.into_variable()?; + let mut elements = Vec::with_capacity(offsets.len()); + for (curr, next) in offsets.iter().tuple_windows() { + elements.push( + String::from_utf8(bytes[*curr..*next].to_vec()) + .map_err(|_| ArrayError::InvalidElementValue)?, + ); + } + Ok(elements) + } +} + +macro_rules! impl_element_binary { + ($raw_type:ty) => { + impl Element for $raw_type { + fn validate_data_type(data_type: &DataType) -> Result<(), ArrayError> { + (data_type == &DataType::Binary).then_some(()).ok_or(IET) + } + + fn into_array_bytes<'a>( + data_type: &DataType, + elements: &'a [Self], + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + + // Calculate offsets + let mut len: usize = 0; + let mut offsets = Vec::with_capacity(elements.len()); + for element in elements { + offsets.push(len); + len = len.checked_add(element.len()).unwrap(); + } + offsets.push(len); + + // Concatenate bytes + let bytes = elements.concat(); + + Ok(ArrayBytes::new_vlen(bytes, offsets)) + } + } + }; +} + +impl_element_binary!(&[u8]); +impl_element_binary!(Vec); + +impl ElementOwned for Vec { + fn from_array_bytes( + data_type: &DataType, + bytes: ArrayBytes<'_>, + ) -> Result, ArrayError> { + Self::validate_data_type(data_type)?; + let (bytes, offsets) = bytes.into_variable()?; + let mut elements = Vec::with_capacity(offsets.len()); + for (curr, next) in offsets.iter().tuple_windows() { + elements.push(bytes[*curr..*next].to_vec()); + } + Ok(elements) + } +} diff --git a/src/array/fill_value.rs b/src/array/fill_value.rs index 6d60ec3e..4de19490 100644 --- a/src/array/fill_value.rs +++ b/src/array/fill_value.rs @@ -2,6 +2,8 @@ //! //! See . +use num::Integer; + /// The fill value of the Zarr array. /// /// Provides an element value to use for uninitialised portions of the Zarr array. @@ -20,6 +22,18 @@ impl From<&[u8]> for FillValue { } } +impl From<[u8; N]> for FillValue { + fn from(value: [u8; N]) -> Self { + Self(value.to_vec()) + } +} + +impl From<&[u8; N]> for FillValue { + fn from(value: &[u8; N]) -> Self { + Self(value.to_vec()) + } +} + impl From> for FillValue { fn from(value: Vec) -> Self { Self(value) @@ -122,6 +136,18 @@ impl From for FillValue { } } +impl From for FillValue { + fn from(value: String) -> Self { + Self(value.into_bytes()) + } +} + +impl From<&str> for FillValue { + fn from(value: &str) -> Self { + Self(value.as_bytes().to_vec()) + } +} + impl FillValue { /// Create a new fill value composed of `bytes`. #[must_use] @@ -145,7 +171,13 @@ impl FillValue { #[allow(clippy::missing_panics_doc)] #[must_use] pub fn equals_all(&self, bytes: &[u8]) -> bool { + // Special cases for variable length data + if !bytes.len().is_multiple_of(&self.0.len()) || bytes.len() < self.0.len() { + return false; + } + match self.0.len() { + 0 => bytes.is_empty(), 1 => { let fill_value = self.0[0]; let fill_value_128 = u128::from_ne_bytes([self.0[0]; 16]); diff --git a/src/array_subset.rs b/src/array_subset.rs index e743c13b..3abc3352 100644 --- a/src/array_subset.rs +++ b/src/array_subset.rs @@ -6,8 +6,7 @@ //! [`iterators`] includes various types of [`ArraySubset`] iterators. //! //! This module also provides convenience functions for: -//! - computing the byte ranges of array subsets within an array, and -//! - extracting the bytes within subsets of an array. +//! - computing the byte ranges of array subsets within an array with a fixed element size. pub mod iterators; @@ -24,7 +23,6 @@ use thiserror::Error; use crate::{ array::{ArrayIndices, ArrayShape}, byte_range::ByteRange, - vec_spare_capacity_to_mut_slice, }; /// An array subset. @@ -39,25 +37,6 @@ pub struct ArraySubset { shape: ArrayShape, } -/// An array extract bytes error. -#[derive(Debug, Error)] -#[error("array subset {_0} is incompatible with array of shape {_1:?} and element size {_2}")] -pub struct ArrayExtractBytesError(ArraySubset, ArrayShape, usize); - -/// An array store bytes error. -#[derive(Debug, Error)] -pub enum ArrayStoreBytesError { - /// Incompatible array subset and array shape. - #[error(transparent)] - InvalidArrayShape(#[from] IncompatibleArraySubsetAndShapeError), - /// Invalid subset bytes. - #[error("expected subset bytes to have length {_1}, got {_0}")] - InvalidSubsetBytes(usize, usize), - /// Invalid array bytes. - #[error("expected array bytes to have length {_1}, got {_0}")] - InvalidArrayBytes(usize, usize), -} - impl ArraySubset { /// Create a new empty array subset. #[must_use] @@ -287,6 +266,12 @@ impl ArraySubset { usize::try_from(self.num_elements()).unwrap() } + /// Returns [`true`] if the array subset contains `indices`. + #[must_use] + pub fn contains(&self, indices: &[u64]) -> bool { + izip!(indices, &self.start, &self.shape).all(|(&i, &o, &s)| i >= o && i < o + s) + } + /// Return the byte ranges of an array subset in an array with `array_shape` and `element_size`. /// /// # Errors @@ -327,81 +312,11 @@ impl ArraySubset { byte_ranges } - /// Return the bytes in this array subset from an array with shape `array_shape` and `element_size`. - /// - /// # Errors - /// - /// Returns [`ArrayExtractBytesError`] if the length of `array_shape` does not match the array subset dimensionality or the array subset is outside of the bounds of `array_shape`. - /// - /// # Panics - /// - /// Panics if attempting to access a byte index beyond [`usize::MAX`]. - pub fn extract_bytes( - &self, - bytes: &[u8], - array_shape: &[u64], - element_size: usize, - ) -> Result, ArrayExtractBytesError> { - let element_size_u64 = element_size as u64; - if bytes.len() as u64 == array_shape.iter().product::() * element_size_u64 - && array_shape.len() == self.dimensionality() - && self - .end_exc() - .iter() - .zip(array_shape) - .all(|(end, shape)| end <= shape) - { - Ok(unsafe { self.extract_bytes_unchecked(bytes, array_shape, element_size) }) - } else { - Err(ArrayExtractBytesError( - self.clone(), - array_shape.to_vec(), - element_size, - )) - } - } - - /// Return the bytes in this array subset from an array with shape `array_shape` and `element_size`. - /// - /// # Safety - /// The length of `array_shape` must match the array subset dimensionality and the array subset must be within the bounds of `array_shape`. - /// - /// # Panics - /// Panics if attempting to reference a byte beyond `usize::MAX`. - #[must_use] - pub unsafe fn extract_bytes_unchecked( - &self, - bytes: &[u8], - array_shape: &[u64], - element_size: usize, - ) -> Vec { - debug_assert_eq!( - bytes.len() as u64, - array_shape.iter().product::() * element_size as u64 - ); - let num_bytes = self.num_elements_usize() * element_size; - let mut bytes_subset: Vec = Vec::with_capacity(num_bytes); - let bytes_subset_slice = vec_spare_capacity_to_mut_slice(&mut bytes_subset); - let mut subset_offset = 0; - let contiguous_indices = self.contiguous_linearised_indices_unchecked(array_shape); - let byte_length = contiguous_indices.contiguous_elements_usize() * element_size; - for (array_index, _contiguous_elements) in &contiguous_indices { - let byte_offset = usize::try_from(array_index).unwrap() * element_size; - debug_assert!(byte_offset + byte_length <= bytes.len()); - debug_assert!(subset_offset + byte_length <= num_bytes); - bytes_subset_slice[subset_offset..subset_offset + byte_length] - .copy_from_slice(&bytes[byte_offset..byte_offset + byte_length]); - subset_offset += byte_length; - } - unsafe { bytes_subset.set_len(num_bytes) }; - bytes_subset - } - /// Return the elements in this array subset from an array with shape `array_shape`. /// /// # Errors /// - /// Returns [`ArrayExtractBytesError`] if the length of `array_shape` does not match the array subset dimensionality or the array subset is outside of the bounds of `array_shape`. + /// Returns [`IncompatibleArraySubsetAndShapeError`] if the length of `array_shape` does not match the array subset dimensionality or the array subset is outside of the bounds of `array_shape`. /// /// # Panics /// Panics if attempting to access a byte index beyond [`usize::MAX`]. @@ -460,90 +375,6 @@ impl ArraySubset { bytes_subset } - /// Store `bytes_subset` corresponding to the bytes of an array (`array_bytes`) with shape `array_shape` and `element_size`. - /// - /// # Errors - /// - /// Returns [`ArrayStoreBytesError`] if: - /// - the length of `array_shape` does not match the array subset dimensionality or the array subset is outside of the bounds of `array_shape`. - /// - the length of `bytes_array` is not compatible with the `array_shape` and `element size`, or - /// - the length of `bytes_subset` is not compatible with the shape of this subset and `element_size`. - /// - /// # Panics - /// - /// Panics if attempting to reference a byte beyond `usize::MAX`. - pub fn store_bytes( - &self, - bytes_subset: &[u8], - bytes_array: &mut [u8], - array_shape: &[u64], - element_size: usize, - ) -> Result<(), ArrayStoreBytesError> { - let element_size_u64 = element_size as u64; - let expected_subset_size = self.num_elements() * element_size_u64; - let expected_array_size = array_shape.iter().product::() * element_size_u64; - if bytes_subset.len() as u64 != expected_subset_size { - Err(ArrayStoreBytesError::InvalidSubsetBytes( - bytes_subset.len(), - usize::try_from(expected_subset_size).unwrap(), - )) - } else if bytes_array.len() as u64 != expected_array_size { - Err(ArrayStoreBytesError::InvalidSubsetBytes( - bytes_array.len(), - usize::try_from(expected_array_size).unwrap(), - )) - } else { - let mut offset = 0; - let contiguous_indices = self.contiguous_linearised_indices(array_shape)?; - let byte_length = contiguous_indices.contiguous_elements_usize() * element_size; - for (array_index, _contiguous_elements) in &contiguous_indices { - let byte_index = usize::try_from(array_index).unwrap() * element_size; - debug_assert!(byte_index + byte_length <= bytes_array.len()); - debug_assert!(offset + byte_length <= bytes_subset.len()); - bytes_array[byte_index..byte_index + byte_length] - .copy_from_slice(&bytes_subset[offset..offset + byte_length]); - offset += byte_length; - } - Ok(()) - } - } - - /// Store `bytes_subset` corresponding to the bytes of an array (`array_bytes`) with shape `array_shape` and `element_size`. - /// - /// # Safety - /// - /// The length of `array_shape` must match the array subset dimensionality and the array subset must be within the bounds of `array_shape`. - /// The length of `bytes_array` must match the product of the `array_shape` components and `element_size`. - /// The length of `bytes_subset` must match the product of the array subset shape components and `element_size`. - /// - /// # Panics - /// - /// Panics if attempting to reference a byte beyond `usize::MAX`. - pub unsafe fn store_bytes_unchecked( - &self, - bytes_subset: &[u8], - bytes_array: &mut [u8], - array_shape: &[u64], - element_size: usize, - ) { - debug_assert_eq!(bytes_subset.len(), self.num_elements_usize() * element_size); - debug_assert_eq!( - bytes_array.len() as u64, - array_shape.iter().product::() * element_size as u64 - ); - let mut offset = 0; - let contiguous_indices = self.contiguous_linearised_indices_unchecked(array_shape); - let byte_length = contiguous_indices.contiguous_elements_usize() * element_size; - for (array_index, _contiguous_elements) in &contiguous_indices { - let byte_index = usize::try_from(array_index).unwrap() * element_size; - debug_assert!(byte_index + byte_length <= bytes_array.len()); - debug_assert!(offset + byte_length <= bytes_subset.len()); - bytes_array[byte_index..byte_index + byte_length] - .copy_from_slice(&bytes_subset[offset..offset + byte_length]); - offset += byte_length; - } - } - /// Returns an iterator over the indices of elements within the subset. #[must_use] pub fn indices(&self) -> Indices { @@ -812,28 +643,6 @@ mod tests { #[test] fn array_subset_bytes() { let array_subset = ArraySubset::new_with_ranges(&[1..3, 1..3]); - let mut bytes_array = vec![0; 4 * 4]; - array_subset - .store_bytes(&[1, 2, 3, 4], &mut bytes_array, &[4, 4], 1) - .unwrap(); - - assert!(array_subset - .store_bytes(&[1, 2, 3], &mut bytes_array, &[4, 4], 1) - .is_err()); - - assert!(array_subset - .store_bytes(&[1, 2, 3, 4], &mut bytes_array, &[2, 2], 1) - .is_err()); - - assert_eq!( - bytes_array, - vec![0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 0] - ); - unsafe { array_subset.store_bytes_unchecked(&[5, 6, 7, 8], &mut bytes_array, &[4, 4], 1) }; - assert_eq!( - bytes_array, - vec![0, 0, 0, 0, 0, 5, 6, 0, 0, 7, 8, 0, 0, 0, 0, 0] - ); assert!(array_subset.byte_ranges(&[1, 1], 1).is_err()); @@ -852,36 +661,5 @@ mod tests { ByteRange::FromStart(9, Some(2)) ] ); - - assert!(array_subset - .extract_bytes(&bytes_array, &[1, 1], 1) - .is_err()); - - assert_eq!( - array_subset - .extract_bytes(&bytes_array, &[4, 4], 1) - .unwrap(), - vec![5, 6, 7, 8] - ); - - assert_eq!( - unsafe { array_subset.extract_bytes_unchecked(&bytes_array, &[4, 4], 1) }, - vec![5, 6, 7, 8] - ); - - assert!(array_subset - .extract_elements(&bytes_array, &[1, 1]) - .is_err()); - - assert_eq!( - array_subset - .extract_elements(&bytes_array, &[4, 4]) - .unwrap(), - vec![5, 6, 7, 8] - ); - assert_eq!( - unsafe { array_subset.extract_elements_unchecked(&bytes_array, &[4, 4]) }, - vec![5, 6, 7, 8] - ); } } diff --git a/src/metadata/array.rs b/src/metadata/array.rs index f968e785..57d29652 100644 --- a/src/metadata/array.rs +++ b/src/metadata/array.rs @@ -2,15 +2,18 @@ //! //! See . -use super::v2::{ - array::{ - array_metadata_fill_value_v2_to_v3, data_type_metadata_v2_to_endianness, - data_type_metadata_v2_to_v3_data_type, ArrayMetadataV2, ArrayMetadataV2DataType, - ArrayMetadataV2Order, DataTypeMetadataV2InvalidEndiannessError, FillValueMetadataV2, +pub use super::v3::ArrayMetadataV3; +use super::{ + v2::{ + array::{ + array_metadata_fill_value_v2_to_v3, data_type_metadata_v2_to_endianness, + data_type_metadata_v2_to_v3_data_type, ArrayMetadataV2, ArrayMetadataV2DataType, + ArrayMetadataV2Order, DataTypeMetadataV2InvalidEndiannessError, FillValueMetadataV2, + }, + codec::blosc::{codec_blosc_v2_numcodecs_to_v3, BloscCodecConfigurationNumcodecs}, }, - codec::blosc::{codec_blosc_v2_numcodecs_to_v3, BloscCodecConfigurationNumcodecs}, + v3::codec::vlen_v2::VlenV2CodecConfigurationV1, }; -pub use super::v3::ArrayMetadataV3; use thiserror::Error; use derive_more::{Display, From}; @@ -138,22 +141,36 @@ pub fn array_metadata_v2_to_v3( codecs.push(transpose_metadata); } - // Filters (array to array codecs) + // Filters (array to array or array to bytes codecs) + let mut is_vlen = false; if let Some(filters) = &array_metadata_v2.filters { for filter in filters { - codecs.push(MetadataV3::new_with_configuration( - filter.id(), - filter.configuration().clone(), - )); + match filter.id() { + "vlen-utf8" | "vlen-bytes" | "vlen-array" => { + is_vlen = true; + let vlen_v2_metadata = MetadataV3::new_with_serializable_configuration( + super::v3::codec::vlen_v2::IDENTIFIER, + &VlenV2CodecConfigurationV1 {}, + )?; + codecs.push(vlen_v2_metadata); + } + _ => { + codecs.push(MetadataV3::new_with_configuration( + filter.id(), + filter.configuration().clone(), + )); + } + } } } - // Array-to-bytes codec - let bytes_metadata = MetadataV3::new_with_serializable_configuration( - super::v3::codec::bytes::IDENTIFIER, - &BytesCodecConfigurationV1 { endian: endianness }, - )?; - codecs.push(bytes_metadata); + if !is_vlen { + let bytes_metadata = MetadataV3::new_with_serializable_configuration( + super::v3::codec::bytes::IDENTIFIER, + &BytesCodecConfigurationV1 { endian: endianness }, + )?; + codecs.push(bytes_metadata); + } // Compressor (bytes to bytes codec) if let Some(compressor) = &array_metadata_v2.compressor { diff --git a/src/metadata/v2/array.rs b/src/metadata/v2/array.rs index 1e6426d2..c1872b51 100644 --- a/src/metadata/v2/array.rs +++ b/src/metadata/v2/array.rs @@ -159,7 +159,12 @@ pub fn data_type_metadata_v2_to_v3_data_type( "f8" => Ok(DataType::Float64), "c8" => Ok(DataType::Complex64), "c16" => Ok(DataType::Complex128), - // TODO "|V" + "|O" => Ok(DataType::String), // LEGACY: This is not part of the spec. The dtype for a PyObject, which is what zarr-python 2 uses for string arrays. + // TODO "|mX" timedelta + // TODO "|MX" datetime + // TODO "|SX" string (fixed length sequence of char) + // TODO "|UX" string (fixed length sequence of Py_UNICODE) + // TODO "|VX" other (void * – each item is a fixed-size chunk of memory) _ => Err(DataTypeMetadataV2UnsupportedDataTypeError( data_type.clone(), )), diff --git a/src/metadata/v2/codec/blosc.rs b/src/metadata/v2/codec/blosc.rs index 2d9b6b85..4fd14f8c 100644 --- a/src/metadata/v2/codec/blosc.rs +++ b/src/metadata/v2/codec/blosc.rs @@ -46,22 +46,42 @@ pub fn codec_blosc_v2_numcodecs_to_v3( blosc: &BloscCodecConfigurationNumcodecs, data_type: &DataType, ) -> BloscCodecConfiguration { + let (shuffle, typesize) = match (&blosc.shuffle, data_type.fixed_size()) { + (BloscShuffleModeNumCodecs::NoShuffle, _) => (BloscShuffleMode::NoShuffle, None), + // Fixed + (BloscShuffleModeNumCodecs::Shuffle, Some(data_type_size)) => { + (BloscShuffleMode::Shuffle, Some(data_type_size)) + } + (BloscShuffleModeNumCodecs::BitShuffle, Some(data_type_size)) => { + (BloscShuffleMode::BitShuffle, Some(data_type_size)) + } + (BloscShuffleModeNumCodecs::AutoShuffle, Some(data_type_size)) => { + if data_type_size == 1 { + (BloscShuffleMode::BitShuffle, Some(data_type_size)) + } else { + (BloscShuffleMode::Shuffle, Some(data_type_size)) + } + } + // Variable + ( + BloscShuffleModeNumCodecs::Shuffle + | BloscShuffleModeNumCodecs::BitShuffle + | BloscShuffleModeNumCodecs::AutoShuffle, + None, + ) => { + // FIXME: Check blosc auto behaviour with variable sized data type + // Currently defaulting to "bitshuffle" + // What do other implementations do for a variable sized data type? + // May need to make this function fallible + (BloscShuffleMode::NoShuffle, None) + } + }; + BloscCodecConfiguration::V1(BloscCodecConfigurationV1 { cname: blosc.cname, clevel: blosc.clevel, - shuffle: match blosc.shuffle { - BloscShuffleModeNumCodecs::NoShuffle => BloscShuffleMode::NoShuffle, - BloscShuffleModeNumCodecs::Shuffle => BloscShuffleMode::Shuffle, - BloscShuffleModeNumCodecs::BitShuffle => BloscShuffleMode::BitShuffle, - BloscShuffleModeNumCodecs::AutoShuffle => { - if data_type.size() == 1 { - BloscShuffleMode::BitShuffle - } else { - BloscShuffleMode::Shuffle - } - } - }, - typesize: Some(data_type.size()), + shuffle, + typesize, blocksize: blosc.blocksize, }) } diff --git a/src/metadata/v3.rs b/src/metadata/v3.rs index 396957b7..4924a09b 100644 --- a/src/metadata/v3.rs +++ b/src/metadata/v3.rs @@ -27,6 +27,10 @@ pub mod codec { pub mod sharding; /// `transpose` codec metadata. pub mod transpose; + /// `vlen` codec metadata. + pub mod vlen; + /// `vlen_v2` codec metadata. + pub mod vlen_v2; #[cfg(feature = "zfp")] /// `zfp` codec metadata. pub mod zfp; diff --git a/src/metadata/v3/codec/vlen.rs b/src/metadata/v3/codec/vlen.rs new file mode 100644 index 00000000..4244f1db --- /dev/null +++ b/src/metadata/v3/codec/vlen.rs @@ -0,0 +1,84 @@ +use derive_more::{Display, From}; +use serde::{Deserialize, Serialize}; + +use crate::metadata::MetadataV3; + +/// The identifier for the `vlen` codec. +pub const IDENTIFIER: &str = "https://codec.zarrs.dev/array_to_bytes/vlen"; + +/// A wrapper to handle various versions of `vlen` codec configuration parameters. +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display, From)] +#[serde(untagged)] +pub enum VlenCodecConfiguration { + /// Version 1.0. + V1(VlenCodecConfigurationV1), +} + +/// Configuration parameters for the `vlen` codec (version 1.0). +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display)] +#[serde(deny_unknown_fields)] +#[display(fmt = "{}", "serde_json::to_string(self).unwrap_or_default()")] +pub struct VlenCodecConfigurationV1 { + /// Encoding for the variable length data indices (offsets). + pub index_codecs: Vec, + /// Encoding for the variable length data. + pub data_codecs: Vec, + /// The indices data type. + pub index_data_type: VlenIndexDataType, +} + +/// Data types for variable length chunk data indices. +#[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Debug, Display)] +#[serde(rename_all = "lowercase")] +pub enum VlenIndexDataType { + // /// `uint8` Integer in `[0, 2^8-1]`. + // UInt8, + // /// `uint16` Integer in `[0, 2^16-1]`. + // UInt16, + /// `uint32` Integer in `[0, 2^32-1]`. + UInt32, + /// `uint64` Integer in `[0, 2^64-1]`. + UInt64, +} + +impl VlenCodecConfigurationV1 { + /// Create a new `vlen` codec configuration. + #[must_use] + pub fn new( + index_codecs: Vec, + data_codecs: Vec, + index_data_type: VlenIndexDataType, + ) -> Self { + Self { + index_codecs, + data_codecs, + index_data_type, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn codec_vlen_simple() { + serde_json::from_str::( + r#"{ + "data_codecs": [{"name": "bytes"}], + "index_codecs": [{"name": "bytes","configuration": { "endian": "little" }}], + "index_data_type": "uint32" + }"#, + ) + .unwrap(); + } + + #[test] + fn codec_vlen_compressed() { + serde_json::from_str::(r#"{ + "data_codecs": [{"name": "bytes"},{"name": "blosc","configuration": {"cname": "zstd", "clevel":5,"shuffle": "bitshuffle", "typesize":1,"blocksize":0}}], + "index_codecs": [{"name": "bytes","configuration": { "endian": "little" }},{"name": "blosc","configuration":{"cname": "zstd", "clevel":5,"shuffle": "shuffle", "typesize":4,"blocksize":0}}], + "index_data_type": "uint32" + }"#).unwrap(); + } +} diff --git a/src/metadata/v3/codec/vlen_v2.rs b/src/metadata/v3/codec/vlen_v2.rs new file mode 100644 index 00000000..373a6cf8 --- /dev/null +++ b/src/metadata/v3/codec/vlen_v2.rs @@ -0,0 +1,37 @@ +use derive_more::{Display, From}; +use serde::{Deserialize, Serialize}; + +/// The identifier for the `vlen_v2` codec. +pub const IDENTIFIER: &str = "https://codec.zarrs.dev/array_to_bytes/vlen_v2"; + +/// A wrapper to handle various versions of `vlen_v2` codec configuration parameters. +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display, From)] +#[serde(untagged)] +pub enum VlenV2CodecConfiguration { + /// Version 1.0. + V1(VlenV2CodecConfigurationV1), +} + +/// Configuration parameters for the `vlen_v2` codec (version 1.0). +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug, Display, Default)] +#[serde(deny_unknown_fields)] +#[display(fmt = "{}", "serde_json::to_string(self).unwrap_or_default()")] +pub struct VlenV2CodecConfigurationV1 {} + +impl VlenV2CodecConfigurationV1 { + /// Create a new `vlen_v2` codec configuration. + #[must_use] + pub const fn new() -> Self { + Self {} + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn codec_vlen_v2() { + serde_json::from_str::(r#"{}"#).unwrap(); + } +} diff --git a/src/metadata/v3/fill_value.rs b/src/metadata/v3/fill_value.rs index 44dee963..7d5b7957 100644 --- a/src/metadata/v3/fill_value.rs +++ b/src/metadata/v3/fill_value.rs @@ -26,12 +26,16 @@ pub enum FillValueMetadata { Int(i64), /// A float. Float(FillValueFloat), - /// A raw data type. + /// An array of integers. Suitable for raw (`r`) and `binary` data types. #[display(fmt = "{_0:?}")] ByteArray(Vec), /// A complex number. #[display(fmt = "{{re:{_0}, im:{_1}}}")] Complex(FillValueFloat, FillValueFloat), + /// A string. + String(String), + /// An unsupported fill value. + Unsupported(serde_json::Value), } impl TryFrom<&str> for FillValueMetadata { @@ -103,6 +107,12 @@ impl HexString { } } +impl From<&HexString> for String { + fn from(value: &HexString) -> Self { + bytes_to_hex_string(value.as_be_bytes()) + } +} + impl core::fmt::Display for HexString { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{:?}", self.0) @@ -162,6 +172,17 @@ pub enum FillValueFloatStringNonFinite { NaN, } +impl From<&FillValueFloatStringNonFinite> for String { + fn from(value: &FillValueFloatStringNonFinite) -> Self { + match value { + FillValueFloatStringNonFinite::PosInfinity => "Infinity", + FillValueFloatStringNonFinite::NegInfinity => "-Infinity", + FillValueFloatStringNonFinite::NaN => "NaN", + } + .to_string() + } +} + impl FillValueMetadata { /// Convert the fill value to a [`bool`]. #[must_use] @@ -546,4 +567,58 @@ mod tests { _ => unreachable!(), } } + + // Null is not currently supported, so recognise it as unknown fill value metadata + #[test] + fn fill_value_metadata_null() { + let json = r#"null"#; + let metadata: FillValueMetadata = json.try_into().unwrap(); + assert_eq!(json, serde_json::to_string(&metadata).unwrap()); + match metadata { + FillValueMetadata::Unsupported(fill_value) => { + assert!(fill_value.is_null()) + } + _ => unreachable!(), + } + } + + // A negative single byte, so recognise it as unknown fill value metadata + #[test] + fn fill_value_metadata_neg_array1() { + let json = r#"[-5]"#; + let metadata: FillValueMetadata = json.try_into().unwrap(); + assert_eq!(json, serde_json::to_string(&metadata).unwrap()); + match metadata { + FillValueMetadata::Unsupported(fill_value) => { + assert!(fill_value.is_array()) + } + _ => unreachable!(), + } + } + + // Two negative -> complex + #[test] + fn fill_value_metadata_neg_array2() { + let json = r#"[-5, -5]"#; + let metadata: FillValueMetadata = json.try_into().unwrap(); + assert_ne!(json, serde_json::to_string(&metadata).unwrap()); // [-5.0, -5.0] + match metadata { + FillValueMetadata::Complex(_re, _im) => {} + _ => unreachable!(), + } + } + + // Single array element > u8::MAX is currently unknown + #[test] + fn fill_value_metadata_large_array() { + let json = r#"[256]"#; + let metadata: FillValueMetadata = json.try_into().unwrap(); + assert_eq!(json, serde_json::to_string(&metadata).unwrap()); + match metadata { + FillValueMetadata::Unsupported(fill_value) => { + assert!(fill_value.is_array()) + } + _ => unreachable!(), + } + } } diff --git a/src/storage/storage_async.rs b/src/storage/storage_async.rs index f014ca05..66ff26a2 100644 --- a/src/storage/storage_async.rs +++ b/src/storage/storage_async.rs @@ -204,7 +204,9 @@ pub async fn async_store_set_partial_values = Vec::new(); - // FIXME: Asynchronously get metadata of all prefixes + // TODO: Asynchronously get metadata of all prefixes for prefix in &prefixes { let key = meta_key(&prefix.try_into()?); let child_metadata = match storage.get(&key).await? { diff --git a/src/storage/storage_sync.rs b/src/storage/storage_sync.rs index 19c48a88..93569244 100644 --- a/src/storage/storage_sync.rs +++ b/src/storage/storage_sync.rs @@ -186,7 +186,9 @@ pub fn store_set_partial_values( vec.resize_with(end_max, Default::default); vec } else { - bytes.to_vec() + let mut bytes = bytes.to_vec(); + bytes.truncate(end_max); + bytes }; // Update the store key diff --git a/src/storage/store/store_async/opendal.rs b/src/storage/store/store_async/opendal.rs index b0d6a1b3..abb4e010 100644 --- a/src/storage/store/store_async/opendal.rs +++ b/src/storage/store/store_async/opendal.rs @@ -63,7 +63,7 @@ impl AsyncReadableStorageTraits for AsyncOpendalStore { key: &StoreKey, byte_ranges: &[ByteRange], ) -> Result>, StorageError> { - // FIXME: Get OpenDAL to return an error if byte range is OOB instead of panic, then don't need to query size + // TODO: Get OpenDAL to return an error if byte range is OOB instead of panic, then don't need to query size let (size, reader) = futures::join!(self.size_key(key), self.operator.reader(key.as_str())); if let (Some(size), Some(reader)) = (size?, handle_result(reader)?) { let mut byte_ranges_fetch = Vec::with_capacity(byte_ranges.len()); diff --git a/src/storage/store/store_sync/memory_store.rs b/src/storage/store/store_sync/memory_store.rs index ec3061d6..e0833e39 100644 --- a/src/storage/store/store_sync/memory_store.rs +++ b/src/storage/store/store_sync/memory_store.rs @@ -66,6 +66,8 @@ impl MemoryStore { let length = usize::try_from(offset + value.len() as u64).unwrap(); if data.len() < length { data.resize(length, 0); + } else { + data.truncate(length); } let offset = usize::try_from(offset).unwrap(); data[offset..offset + value.len()].copy_from_slice(value); diff --git a/src/storage/store/store_sync/opendal.rs b/src/storage/store/store_sync/opendal.rs index 46392e5d..de2d66d0 100644 --- a/src/storage/store/store_sync/opendal.rs +++ b/src/storage/store/store_sync/opendal.rs @@ -58,7 +58,7 @@ impl ReadableStorageTraits for OpendalStore { key: &StoreKey, byte_ranges: &[ByteRange], ) -> Result>, StorageError> { - // FIXME: Get OpenDAL to return an error if byte range is OOB instead of panic + // TODO: Get OpenDAL to return an error if byte range is OOB instead of panic let size = self.size_key(key)?; if let Some(size) = size { let reader = self.operator.reader(key.as_str())?; diff --git a/tests/array_async.rs b/tests/array_async.rs index 777108f2..3129755d 100644 --- a/tests/array_async.rs +++ b/tests/array_async.rs @@ -1,10 +1,13 @@ #![cfg(all(feature = "async", feature = "ndarray", feature = "object_store"))] -use zarrs::array::{ArrayBuilder, DataType, FillValue}; +use zarrs::array::codec::array_to_bytes::vlen::VlenCodec; +use zarrs::array::codec::TransposeCodec; +use zarrs::array::{Array, ArrayBuilder, DataType, FillValue}; use zarrs::array_subset::ArraySubset; use object_store::memory::InMemory; +use zarrs::metadata::v3::codec::transpose::TransposeOrder; use zarrs::storage::store::AsyncObjectStore; #[rustfmt::skip] @@ -48,15 +51,15 @@ async fn array_async_read(shard: bool) -> Result<(), Box> array.async_store_array_subset(&ArraySubset::new_with_ranges(&[1..3, 0..2]), &[5, 6, 9, 10]).await?; assert!(array.async_retrieve_chunk(&[0, 0, 0]).await.is_err()); - assert_eq!(array.async_retrieve_chunk(&[0, 0]).await?, [1, 2, 5, 6]); - assert_eq!(array.async_retrieve_chunk(&[0, 1]).await?, [3, 4, 7, 8]); - assert_eq!(array.async_retrieve_chunk(&[1, 0]).await?, [9, 10, 0, 0]); - assert_eq!(array.async_retrieve_chunk(&[1, 1]).await?, [0, 0, 0, 0]); + assert_eq!(array.async_retrieve_chunk(&[0, 0]).await?, vec![1, 2, 5, 6].into()); + assert_eq!(array.async_retrieve_chunk(&[0, 1]).await?, vec![3, 4, 7, 8].into()); + assert_eq!(array.async_retrieve_chunk(&[1, 0]).await?, vec![9, 10, 0, 0].into()); + assert_eq!(array.async_retrieve_chunk(&[1, 1]).await?, vec![0, 0, 0, 0].into()); assert!(array.async_retrieve_chunk_if_exists(&[0, 0, 0]).await.is_err()); - assert_eq!(array.async_retrieve_chunk_if_exists(&[0, 0]).await?, Some(vec![1, 2, 5, 6])); - assert_eq!(array.async_retrieve_chunk_if_exists(&[0, 1]).await?, Some(vec![3, 4, 7, 8])); - assert_eq!(array.async_retrieve_chunk_if_exists(&[1, 0]).await?, Some(vec![9, 10, 0, 0])); + assert_eq!(array.async_retrieve_chunk_if_exists(&[0, 0]).await?, Some(vec![1, 2, 5, 6].into())); + assert_eq!(array.async_retrieve_chunk_if_exists(&[0, 1]).await?, Some(vec![3, 4, 7, 8].into())); + assert_eq!(array.async_retrieve_chunk_if_exists(&[1, 0]).await?, Some(vec![9, 10, 0, 0].into())); assert_eq!(array.async_retrieve_chunk_if_exists(&[1, 1]).await?, None); assert!(array.async_retrieve_chunk_ndarray::(&[0, 0]).await.is_err()); @@ -72,9 +75,9 @@ async fn array_async_read(shard: bool) -> Result<(), Box> assert!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..2])).await.is_err()); assert!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..3, 0..3])).await.is_err()); - assert_eq!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 0..2])).await?, [1, 2, 5, 6]); - assert_eq!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..1, 0..2])).await?, [1, 2]); - assert_eq!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 1..2])).await?, [2, 6]); + assert_eq!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 0..2])).await?, vec![1, 2, 5, 6].into()); + assert_eq!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..1, 0..2])).await?, vec![1, 2].into()); + assert_eq!(array.async_retrieve_chunk_subset(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 1..2])).await?, vec![2, 6].into()); assert!(array.async_retrieve_chunk_subset_ndarray::(&[0, 0], &ArraySubset::new_with_ranges(&[0..3, 0..3])).await.is_err()); assert!(array.async_retrieve_chunk_subset_ndarray::(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 0..2])).await.is_err()); @@ -83,11 +86,11 @@ async fn array_async_read(shard: bool) -> Result<(), Box> assert_eq!(array.async_retrieve_chunk_subset_ndarray::(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 1..2])).await?, ndarray::array![[2], [6]].into_dyn()); assert!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2])).await.is_err()); - assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..0, 0..0])).await?, Vec::::new()); - assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 0..1])).await?, [1, 2, 5, 6]); - assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 0..2])).await?, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0]); - assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 1..2])).await?, [3, 4, 7, 8, 0, 0, 0, 0]); - assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 1..3])).await?, [3, 4, 0, 0, 7, 8, 0, 0]); + assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..0, 0..0])).await?, vec![].into()); + assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 0..1])).await?, vec![1, 2, 5, 6].into()); + assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 0..2])).await?, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0].into()); + assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 1..2])).await?, vec![3, 4, 7, 8, 0, 0, 0, 0].into()); + assert_eq!(array.async_retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 1..3])).await?, vec![3, 4, 0, 0, 7, 8, 0, 0].into()); assert!(array.async_retrieve_chunks_ndarray::(&ArraySubset::new_with_ranges(&[0..2])).await.is_err()); assert!(array.async_retrieve_chunks_ndarray::(&ArraySubset::new_with_ranges(&[0..2, 0..2])).await.is_err()); @@ -96,13 +99,12 @@ async fn array_async_read(shard: bool) -> Result<(), Box> assert_eq!(array.async_retrieve_chunks_ndarray::(&ArraySubset::new_with_ranges(&[0..1, 1..3])).await?, ndarray::array![[3, 4, 0, 0], [7, 8, 0, 0]].into_dyn()); assert!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..4])).await.is_err()); - assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..0, 0..0])).await?, Vec::::new()); - assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..0, 0..0])).await?, [] as [u8; 0]); - assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..2, 0..2])).await?, [1, 2, 5, 6]); - assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..4, 0..4])).await?, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0]); - assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[1..3, 1..3])).await?, [6, 7, 10 ,0]); - assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[5..7, 5..6])).await?, [0, 0]); // OOB -> fill value - assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..5, 0..5])).await?, [1, 2, 3, 4, 0, 5, 6, 7, 8, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // OOB -> fill value + assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..0, 0..0])).await?, vec![].into()); + assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..2, 0..2])).await?, vec![1, 2, 5, 6].into()); + assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..4, 0..4])).await?, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0].into()); + assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[1..3, 1..3])).await?, vec![6, 7, 10 ,0].into()); + assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[5..7, 5..6])).await?, vec![0, 0].into()); // OOB -> fill value + assert_eq!(array.async_retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..5, 0..5])).await?, vec![1, 2, 3, 4, 0, 5, 6, 7, 8, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].into()); // OOB -> fill value assert!(array.async_retrieve_array_subset_ndarray::(&ArraySubset::new_with_ranges(&[0..4])).await.is_err()); assert!(array.async_retrieve_array_subset_ndarray::(&ArraySubset::new_with_ranges(&[0..4, 0..4])).await.is_err()); @@ -114,9 +116,9 @@ async fn array_async_read(shard: bool) -> Result<(), Box> assert!(array.async_partial_decoder(&[0]).await.is_err()); assert!(array.async_partial_decoder(&[0, 0]).await?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1])]).await.is_err()); - assert_eq!(array.async_partial_decoder(&[0, 0]).await?.partial_decode(&[]).await?, Vec::>::new()); - assert_eq!(array.async_partial_decoder(&[5, 0]).await?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2])]).await?, [vec![0, 0]]); // OOB -> fill value - assert_eq!(array.async_partial_decoder(&[0, 0]).await?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2]), ArraySubset::new_with_ranges(&[0..2, 1..2])]).await?, [vec![1, 2], vec![2, 6]]); + assert_eq!(array.async_partial_decoder(&[0, 0]).await?.partial_decode(&[]).await?, []); + assert_eq!(array.async_partial_decoder(&[5, 0]).await?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2])]).await?, [vec![0, 0].into()]); // OOB -> fill value + assert_eq!(array.async_partial_decoder(&[0, 0]).await?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2]), ArraySubset::new_with_ranges(&[0..2, 1..2])]).await?, [vec![1, 2].into(), vec![2, 6].into()]); Ok(()) } @@ -132,3 +134,183 @@ async fn array_async_read_uncompressed() -> Result<(), Box Result<(), Box> { array_async_read(true).await } + +async fn array_str_impl( + array: Array>, +) -> Result<(), Box> { + // Store a single chunk + array + .async_store_chunk_elements(&[0, 0], &["a", "bb", "ccc", "dddd"]) + .await?; + assert_eq!( + array + .async_retrieve_chunk_elements::(&[0, 0]) + .await?, + &["a", "bb", "ccc", "dddd"] + ); + + // Write array subset with full chunks + array + .async_store_array_subset_elements( + &ArraySubset::new_with_ranges(&[2..4, 0..4]), + &[ + "1", "22", "333", "4444", "55555", "666666", "7777777", "88888888", + ], + ) + .await?; + assert_eq!( + array + .async_retrieve_chunk_elements::(&[1, 0]) + .await?, + &["1", "22", "55555", "666666"] + ); + assert_eq!( + array + .async_retrieve_chunk_elements::(&[1, 1]) + .await?, + &["333", "4444", "7777777", "88888888"] + ); + + // Write array subset with partial chunks + array + .async_store_array_subset_elements( + &ArraySubset::new_with_ranges(&[1..3, 1..3]), + &["S1", "S22", "S333", "S4444"], + ) + .await?; + assert_eq!( + array + .async_retrieve_chunk_elements::(&[0, 0]) + .await?, + &["a", "bb", "ccc", "S1"] + ); + assert_eq!( + array + .async_retrieve_chunk_elements::(&[0, 1]) + .await?, + &["", "", "S22", ""] + ); + assert_eq!( + array + .async_retrieve_chunk_elements::(&[1, 0]) + .await?, + &["1", "S333", "55555", "666666"] + ); + assert_eq!( + array + .async_retrieve_chunk_elements::(&[1, 1]) + .await?, + &["S4444", "4444", "7777777", "88888888"] + ); + + // Write multiple chunks + array + .async_store_chunks_elements( + &ArraySubset::new_with_ranges(&[0..1, 0..2]), + &["a", "bb", "ccc", "dddd", "C0", "C11", "C222", "C3333"], + ) + .await?; + assert_eq!( + array + .async_retrieve_chunk_elements::(&[0, 0]) + .await?, + &["a", "bb", "C0", "C11"] + ); + assert_eq!( + array + .async_retrieve_chunk_elements::(&[0, 1]) + .await?, + &["ccc", "dddd", "C222", "C3333"] + ); + assert_eq!( + array + .async_retrieve_chunks_elements::(&ArraySubset::new_with_ranges(&[0..1, 0..2])) + .await?, + &["a", "bb", "ccc", "dddd", "C0", "C11", "C222", "C3333"] + ); + + // Full chunk requests + assert_eq!( + array + .async_retrieve_array_subset_elements::(&ArraySubset::new_with_ranges(&[ + 0..4, + 0..4 + ])) + .await?, + &[ + "a", "bb", "ccc", "dddd", "C0", "C11", "C222", "C3333", // + "1", "S333", "S4444", "4444", "55555", "666666", "7777777", "88888888" // + ] + ); + + // Partial chunk requests + assert_eq!( + array + .async_retrieve_array_subset_elements::(&ArraySubset::new_with_ranges(&[ + 1..3, + 1..3 + ])) + .await?, + &["C11", "C222", "S333", "S4444"] + ); + + // Incompatible chunks / bytes + assert!(array + .async_store_chunks_elements(&ArraySubset::new_with_ranges(&[0..0, 0..2]), &["a", "bb"]) + .await + .is_err()); + assert!(array + .async_store_chunks_elements(&ArraySubset::new_with_ranges(&[0..1, 0..2]), &["a", "bb"]) + .await + .is_err()); + + Ok(()) +} + +#[tokio::test] +async fn array_str_async_simple() -> Result<(), Box> { + let store = std::sync::Arc::new(AsyncObjectStore::new(InMemory::new())); + let array_path = "/array"; + let mut builder = ArrayBuilder::new( + vec![4, 4], // array shape + DataType::String, + vec![2, 2].try_into().unwrap(), // regular chunk shape + FillValue::from(""), + ); + builder.bytes_to_bytes_codecs(vec![ + #[cfg(feature = "gzip")] + Box::new(zarrs::array::codec::GzipCodec::new(5)?), + ]); + + let array = builder.build(store, array_path).unwrap(); + array_str_impl(array).await +} + +#[tokio::test] +async fn array_str_async_sharded_transpose() -> Result<(), Box> { + let store = std::sync::Arc::new(AsyncObjectStore::new(InMemory::new())); + let array_path = "/array"; + let mut builder = ArrayBuilder::new( + vec![4, 4], // array shape + DataType::String, + vec![2, 2].try_into().unwrap(), // regular chunk shape + FillValue::from(""), + ); + builder.array_to_array_codecs(vec![Box::new(TransposeCodec::new( + TransposeOrder::new(&[1, 0]).unwrap(), + ))]); + builder.array_to_bytes_codec(Box::new( + zarrs::array::codec::array_to_bytes::sharding::ShardingCodecBuilder::new( + vec![2, 1].try_into().unwrap(), + ) + .array_to_bytes_codec(Box::::default()) + .build(), + )); + builder.bytes_to_bytes_codecs(vec![ + #[cfg(feature = "gzip")] + Box::new(zarrs::array::codec::GzipCodec::new(5)?), + ]); + + let array = builder.build(store, array_path).unwrap(); + array_str_impl(array).await +} diff --git a/tests/array_sync.rs b/tests/array_sync.rs index 5ddcd859..b1263afc 100644 --- a/tests/array_sync.rs +++ b/tests/array_sync.rs @@ -22,15 +22,15 @@ fn array_sync_read(array: Array) -> Result<(), Box(&[0, 0]).is_err()); @@ -46,9 +46,9 @@ fn array_sync_read(array: Array) -> Result<(), Box(&[0, 0], &ArraySubset::new_with_ranges(&[0..3, 0..3])).is_err()); assert!(array.retrieve_chunk_subset_ndarray::(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 0..2])).is_err()); @@ -57,11 +57,11 @@ fn array_sync_read(array: Array) -> Result<(), Box(&[0, 0], &ArraySubset::new_with_ranges(&[0..2, 1..2]))?, ndarray::array![[2], [6]].into_dyn()); assert!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2])).is_err()); - assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..0, 0..0]))?, Vec::::new()); - assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 0..1]))?, [1, 2, 5, 6]); - assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 0..2]))?, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0]); - assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 1..2]))?, [3, 4, 7, 8, 0, 0, 0, 0]); - assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 1..3]))?, [3, 4, 0, 0, 7, 8, 0, 0]); + assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..0, 0..0]))?, vec![].into()); + assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 0..1]))?, vec![1, 2, 5, 6].into()); + assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 0..2]))?, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0].into()); + assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..2, 1..2]))?, vec![3, 4, 7, 8, 0, 0, 0, 0].into()); + assert_eq!(array.retrieve_chunks(&ArraySubset::new_with_ranges(&[0..1, 1..3]))?, vec![3, 4, 0, 0, 7, 8, 0, 0].into()); assert!(array.retrieve_chunks_ndarray::(&ArraySubset::new_with_ranges(&[0..2])).is_err()); assert!(array.retrieve_chunks_ndarray::(&ArraySubset::new_with_ranges(&[0..2, 0..2])).is_err()); @@ -70,13 +70,12 @@ fn array_sync_read(array: Array) -> Result<(), Box(&ArraySubset::new_with_ranges(&[0..1, 1..3]))?, ndarray::array![[3, 4, 0, 0], [7, 8, 0, 0]].into_dyn()); assert!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..4])).is_err()); - assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..0, 0..0]))?, Vec::::new()); - assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..0, 0..0]))?, [] as [u8; 0]); - assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..2, 0..2]))?, [1, 2, 5, 6]); - assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..4, 0..4]))?, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0]); - assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[1..3, 1..3]))?, [6, 7, 10 ,0]); - assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[5..7, 5..6]))?, [0, 0]); // OOB -> fill value - assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..5, 0..5]))?, [1, 2, 3, 4, 0, 5, 6, 7, 8, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // OOB -> fill value + assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..0, 0..0]))?, vec![].into()); + assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..2, 0..2]))?, vec![1, 2, 5, 6].into()); + assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..4, 0..4]))?, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0].into()); + assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[1..3, 1..3]))?, vec![6, 7, 10 ,0].into()); + assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[5..7, 5..6]))?, vec![0, 0].into()); // OOB -> fill value + assert_eq!(array.retrieve_array_subset(&ArraySubset::new_with_ranges(&[0..5, 0..5]))?, vec![1, 2, 3, 4, 0, 5, 6, 7, 8, 0, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].into()); // OOB -> fill value assert!(array.retrieve_array_subset_ndarray::(&ArraySubset::new_with_ranges(&[0..4])).is_err()); assert!(array.retrieve_array_subset_ndarray::(&ArraySubset::new_with_ranges(&[0..4, 0..4])).is_err()); @@ -88,9 +87,9 @@ fn array_sync_read(array: Array) -> Result<(), Box>::new()); - assert_eq!(array.partial_decoder(&[5, 0])?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2])])?, [vec![0, 0]]); // OOB -> fill value - assert_eq!(array.partial_decoder(&[0, 0])?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2]), ArraySubset::new_with_ranges(&[0..2, 1..2])])?, [vec![1, 2], vec![2, 6]]); + assert_eq!(array.partial_decoder(&[0, 0])?.partial_decode(&[])?, []); + assert_eq!(array.partial_decoder(&[5, 0])?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2])])?, [vec![0, 0].into()]); // OOB -> fill value + assert_eq!(array.partial_decoder(&[0, 0])?.partial_decode(&[ArraySubset::new_with_ranges(&[0..1, 0..2]), ArraySubset::new_with_ranges(&[0..2, 1..2])])?, [vec![1, 2].into(), vec![2, 6].into()]); Ok(()) } @@ -122,6 +121,7 @@ fn array_sync_read_uncompressed() -> Result<(), Box> { array_sync_read(array) } +#[cfg(feature = "sharding")] #[test] #[cfg_attr(miri, ignore)] fn array_sync_read_shard_compress() -> Result<(), Box> { @@ -133,7 +133,6 @@ fn array_sync_read_shard_compress() -> Result<(), Box> { vec![2, 2].try_into().unwrap(), // regular chunk shape FillValue::from(0u8), ); - #[cfg(feature = "sharding")] builder.array_to_bytes_codec(Box::new( zarrs::array::codec::array_to_bytes::sharding::ShardingCodecBuilder::new( vec![1, 1].try_into().unwrap(), @@ -159,3 +158,216 @@ fn array_sync_read_shard_compress() -> Result<(), Box> { array_sync_read(array) } + +fn array_str_impl(array: Array) -> Result<(), Box> { + // Store a single chunk + array.store_chunk_elements(&[0, 0], &["a", "bb", "ccc", "dddd"])?; + assert_eq!( + array.retrieve_chunk_elements::(&[0, 0])?, + &["a", "bb", "ccc", "dddd"] + ); + + // Write array subset with full chunks + array.store_array_subset_elements( + &ArraySubset::new_with_ranges(&[2..4, 0..4]), + &[ + "1", "22", "333", "4444", "55555", "666666", "7777777", "88888888", + ], + )?; + assert_eq!( + array.retrieve_chunk_elements::(&[1, 0])?, + &["1", "22", "55555", "666666"] + ); + assert_eq!( + array.retrieve_chunk_elements::(&[1, 1])?, + &["333", "4444", "7777777", "88888888"] + ); + + // Write array subset with partial chunks + array.store_array_subset_elements( + &ArraySubset::new_with_ranges(&[1..3, 1..3]), + &["S1", "S22", "S333", "S4444"], + )?; + assert_eq!( + array.retrieve_chunk_elements::(&[0, 0])?, + &["a", "bb", "ccc", "S1"] + ); + assert_eq!( + array.retrieve_chunk_elements::(&[0, 1])?, + &["", "", "S22", ""] + ); + assert_eq!( + array.retrieve_chunk_elements::(&[1, 0])?, + &["1", "S333", "55555", "666666"] + ); + assert_eq!( + array.retrieve_chunk_elements::(&[1, 1])?, + &["S4444", "4444", "7777777", "88888888"] + ); + + // Write multiple chunks + array.store_chunks_elements( + &ArraySubset::new_with_ranges(&[0..1, 0..2]), + &["a", "bb", "ccc", "dddd", "C0", "C11", "C222", "C3333"], + )?; + assert_eq!( + array.retrieve_chunk_elements::(&[0, 0])?, + &["a", "bb", "C0", "C11"] + ); + assert_eq!( + array.retrieve_chunk_elements::(&[0, 1])?, + &["ccc", "dddd", "C222", "C3333"] + ); + assert_eq!( + array.retrieve_chunks_elements::(&ArraySubset::new_with_ranges(&[0..1, 0..2]))?, + &["a", "bb", "ccc", "dddd", "C0", "C11", "C222", "C3333"] + ); + + // Full chunk requests + assert_eq!( + array.retrieve_array_subset_elements::(&ArraySubset::new_with_ranges(&[ + 0..4, + 0..4 + ]))?, + &[ + "a", "bb", "ccc", "dddd", "C0", "C11", "C222", "C3333", // + "1", "S333", "S4444", "4444", "55555", "666666", "7777777", "88888888" // + ] + ); + + // Partial chunk requests + assert_eq!( + array.retrieve_array_subset_elements::(&ArraySubset::new_with_ranges(&[ + 1..3, + 1..3 + ]))?, + &["C11", "C222", "S333", "S4444"] + ); + + // Incompatible chunks / bytes + assert!(array + .store_chunks_elements(&ArraySubset::new_with_ranges(&[0..0, 0..2]), &["a", "bb"]) + .is_err()); + assert!(array + .store_chunks_elements(&ArraySubset::new_with_ranges(&[0..1, 0..2]), &["a", "bb"]) + .is_err()); + + Ok(()) +} + +#[test] +fn array_str_sync_simple() -> Result<(), Box> { + let store = std::sync::Arc::new(MemoryStore::default()); + let array_path = "/array"; + let mut builder = ArrayBuilder::new( + vec![4, 4], // array shape + DataType::String, + vec![2, 2].try_into().unwrap(), // regular chunk shape + FillValue::from(""), + ); + builder.bytes_to_bytes_codecs(vec![ + #[cfg(feature = "gzip")] + Box::new(zarrs::array::codec::GzipCodec::new(5)?), + ]); + + let array = builder.build(store, array_path).unwrap(); + + array_str_impl(array) +} + +#[cfg(feature = "sharding")] +#[test] +fn array_str_sync_sharded_transpose() -> Result<(), Box> { + use zarrs::{ + array::codec::{array_to_bytes::vlen::VlenCodec, TransposeCodec}, + metadata::v3::codec::transpose::TransposeOrder, + }; + + let store = std::sync::Arc::new(MemoryStore::default()); + let array_path = "/array"; + let mut builder = ArrayBuilder::new( + vec![4, 4], // array shape + DataType::String, + vec![2, 2].try_into().unwrap(), // regular chunk shape + FillValue::from(""), + ); + builder.array_to_array_codecs(vec![Box::new(TransposeCodec::new( + TransposeOrder::new(&[1, 0]).unwrap(), + ))]); + builder.array_to_bytes_codec(Box::new( + zarrs::array::codec::array_to_bytes::sharding::ShardingCodecBuilder::new( + vec![2, 1].try_into().unwrap(), + ) + .array_to_bytes_codec(Box::::default()) + .build(), + )); + builder.bytes_to_bytes_codecs(vec![ + #[cfg(feature = "gzip")] + Box::new(zarrs::array::codec::GzipCodec::new(5)?), + ]); + + let array = builder.build(store, array_path).unwrap(); + + array_str_impl(array) +} + +#[rustfmt::skip] +#[test] +fn array_binary() -> Result<(), Box> { + let store = std::sync::Arc::new(MemoryStore::default()); + let array_path = "/array"; + let mut builder = ArrayBuilder::new( + vec![4, 4], // array shape + DataType::Binary, + vec![2, 2].try_into().unwrap(), // regular chunk shape + FillValue::from([]), + ); + builder.bytes_to_bytes_codecs(vec![ + #[cfg(feature = "gzip")] + Box::new(zarrs::array::codec::GzipCodec::new(5)?), + ]); + + let array = builder.build(store, array_path).unwrap(); + + array.store_array_subset_elements::<&[u8]>( + &ArraySubset::new_with_ranges(&[1..3, 1..3]), + &[&[0], &[0, 1], &[0, 1, 2], &[0, 1, 2, 3]], + )?; + assert_eq!( + array.retrieve_chunk_elements::>(&[0, 0])?, + vec![ + vec![], vec![], + vec![], vec![0] + ], + ); + assert_eq!( + array.retrieve_chunk_elements::>(&[0, 1])?, + vec![ + vec![], vec![], + vec![0, 1], vec![] + ], + ); + assert_eq!( + array.retrieve_chunk_elements::>(&[1, 0])?, + vec![ + vec![], vec![0, 1, 2], + vec![], vec![] + ], + ); + assert_eq!( + array.retrieve_chunk_elements::>(&[1, 1])?, + vec![ + vec![0, 1, 2, 3], vec![], + vec![], vec![] + ], + ); + assert_eq!( + array.retrieve_array_subset_elements::>(&ArraySubset::new_with_ranges(&[1..3, 0..4]))?, + vec![ + vec![], vec![0], vec![0, 1], vec![], + vec![], vec![0, 1, 2], vec![0, 1, 2, 3], vec![], + ], + ); + + Ok(()) +} diff --git a/tests/cities.rs b/tests/cities.rs new file mode 100644 index 00000000..08a544e0 --- /dev/null +++ b/tests/cities.rs @@ -0,0 +1,131 @@ +use std::{ + error::Error, + fs::File, + io::{BufRead, BufReader}, +}; + +use zarrs::{ + array::{ + codec::{ + array_to_bytes::{ + sharding::ShardingCodecBuilder, vlen::VlenCodec, vlen_v2::VlenV2Codec, + }, + ArrayToBytesCodecTraits, ZstdCodec, + }, + ArrayBuilder, ArrayMetadataOptions, DataType, FillValue, + }, + array_subset::ArraySubset, + metadata::v3::codec::vlen::VlenCodecConfiguration, + storage::{ + store::{FilesystemStore, MemoryStore}, + ReadableWritableListableStorage, + }, +}; + +fn read_cities() -> std::io::Result> { + let reader = BufReader::new(File::open("tests/data/cities.csv")?); + let mut cities = Vec::with_capacity(47868); + for line in reader.lines() { + cities.push(line?); + } + Ok(cities) +} + +fn cities_impl( + cities: &[String], + compression_level: Option, + chunk_size: u64, + shard_size: Option, + vlen_codec: Box, + write_to_file: bool, +) -> Result> { + let store: ReadableWritableListableStorage = if write_to_file { + std::sync::Arc::new(FilesystemStore::new("tests/data/v3/cities.zarr")?) + } else { + std::sync::Arc::new(MemoryStore::default()) + }; + store.erase_prefix(&"".try_into().unwrap())?; + + let mut builder = ArrayBuilder::new( + vec![cities.len() as u64], // array shape + DataType::String, + vec![chunk_size].try_into()?, // regular chunk shape + FillValue::from(""), + ); + if let Some(shard_size) = shard_size { + builder.array_to_bytes_codec(Box::new( + ShardingCodecBuilder::new( + vec![shard_size].try_into()?, // inner chunk chape + ) + .array_to_bytes_codec(vlen_codec) + .build(), + )); + } else { + builder.array_to_bytes_codec(vlen_codec); + } + if let Some(compression_level) = compression_level { + builder.bytes_to_bytes_codecs(vec![ + #[cfg(feature = "zstd")] + Box::new(ZstdCodec::new(compression_level, false)), + ]); + } + + let array = builder.build(store.clone(), "/")?; + array.store_metadata_opt(&ArrayMetadataOptions::default().set_include_zarrs_metadata(false))?; + + let subset_all = ArraySubset::new_with_shape(array.shape().to_vec()); + array.store_array_subset_elements(&subset_all, &cities)?; + let cities_out = array.retrieve_array_subset_elements::(&subset_all)?; + assert_eq!(cities, cities_out); + + let last_block = array.retrieve_chunk(&[(cities.len() as u64).div_ceil(chunk_size)])?; + let (_bytes, offsets) = last_block.into_variable()?; + assert_eq!(offsets.len() as u64, chunk_size + 1); + + Ok(store.size_prefix(&"c/".try_into().unwrap())?) // only chunks +} + +#[rustfmt::skip] +#[test] +fn cities() -> Result<(), Box> { + let cities = read_cities()?; + assert_eq!(cities.len(), 47868); + assert_eq!(cities[0], "Tokyo"); + assert_eq!(cities[47862], "Sariwŏn-si"); + assert_eq!(cities[47867], "Charlotte Amalie"); + + let vlen_v2 = Box::new(VlenV2Codec::default()); + + // let vlen = Box::new(VlenCodec::default()); + let vlen_configuration: VlenCodecConfiguration = serde_json::from_str(r#"{ + "data_codecs": [{"name": "bytes"}], + "index_codecs": [{"name": "bytes","configuration": { "endian": "little" }}], + "index_data_type": "uint32" + }"#)?; + let vlen = Box::new(VlenCodec::new_with_configuration(&vlen_configuration)?); + + let vlen_compressed_configuration: VlenCodecConfiguration = serde_json::from_str(r#"{ + "data_codecs": [{"name": "bytes"},{"name": "blosc","configuration": {"cname": "zstd", "clevel":5,"shuffle": "bitshuffle", "typesize":1,"blocksize":0}}], + "index_codecs": [{"name": "bytes","configuration": { "endian": "little" }},{"name": "blosc","configuration":{"cname": "zstd", "clevel":5,"shuffle": "shuffle", "typesize":4,"blocksize":0}}], + "index_data_type": "uint32" + }"#)?; + let vlen_compressed = Box::new(VlenCodec::new_with_configuration(&vlen_compressed_configuration)?); + + print!("| encoding | compression | size |\n"); + print!("| ---------------- | ----------- | ------ |\n"); + print!("| vlen_v2 | | {} |\n", cities_impl(&cities, None, 1000, None, vlen_v2.clone(), true)?); + print!("| vlen_v2 | zstd 5 | {} |\n", cities_impl(&cities, Some(5), 1000, None, vlen_v2.clone(), false)?); + print!("| vlen | | {} |\n", cities_impl(&cities, None, 1000, None, vlen.clone(), false)?); + print!("| vlen | zstd 5 | {} |\n", cities_impl(&cities, None, 1000, None, vlen_compressed.clone(), false)?); + println!(); + // panic!(); + + // | encoding | compression | size | + // | ---------------- | ----------- | ------ | + // | vlen_v2 | | 642196 | + // | vlen_v2 | zstd 5 | 362626 | + // | vlen | | 642580 | + // | vlen | zstd 5 | 346950 | + + Ok(()) +} diff --git a/tests/data/cities.csv b/tests/data/cities.csv new file mode 100644 index 00000000..cfc78d01 --- /dev/null +++ b/tests/data/cities.csv @@ -0,0 +1,47868 @@ +Tokyo +Jakarta +Delhi +Guangzhou +Mumbai +Manila +Shanghai +São Paulo +Seoul +Mexico City +Cairo +New York +Dhaka +Beijing +Kolkāta +Bangkok +Shenzhen +Moscow +Buenos Aires +Lagos +Istanbul +Karachi +Bangalore +Ho Chi Minh City +Ōsaka +Chengdu +Tehran +Kinshasa +Rio de Janeiro +Chennai +Xi’an +Lahore +Chongqing +Los Angeles +Baoding +London +Paris +Linyi +Dongguan +Hyderābād +Tianjin +Lima +Wuhan +Nanyang +Hangzhou +Foshan +Nagoya +Tongshan +Luanda +Zhoukou +Ganzhou +Kuala Lumpur +Heze +Quanzhou +Johannesburg +Chicago +Nanjing +Jining +Hanoi +Pune +Fuyang +Ahmedabad +Bogotá +Shenyang +Dar es Salaam +Khartoum +Shangqiu +Hong Kong +Cangzhou +Riyadh +Santiago +Xingtai +Zhumadian +Chattogram +Surabaya +Zhanjiang +Bijie +Yancheng +Hengyang +Zunyi +Shaoyang +Sūrat +Shangrao +Xinyang +Madrid +Baghdad +Maoming +Jieyang +Miami +Singapore +Houston +Liaocheng +Huanggang +Dalian +Dallas +Qingdao +Yulin +Douala +Qujing +Nangandao +Philadelphia +Pudong +Toronto +Zhengzhou +Dezhou +Nanchong +Jinan +Giza +Nairobi +Guadalajara +Ankara +Tai’an +Langfang +Dazhou +Saint Petersburg +Monterrey +Belo Horizonte +Suzhou +Yongzhou +Changde +Xiangyang +Rangoon +Atlanta +Washington +Zhaotong +Zhangzhou +Melbourne +Yichun +Bozhou +Suqian +Abidjan +Ji’an +Guilin +Pingdingshan +Berlin +Alexandria +Mianyang +Sydney +Huanglongsi +Barcelona +Yuncheng +Cape Town +Changsha +Jeddah +Weinan +Chenzhou +Jiangmen +Jiujiang +Xinpu +Yibin +Huaihua +Yangzhou +Taizhou +Kunming +Yiyang +Changchun +Lu’an +Jiangguanchi +Meizhou +Ürümqi +Suzhou +Boston +İzmir +Guigang +Shantou +Kabul +Xiaoganzhan +Bamako +Luzhou +Hefei +Hengshui +Fortaleza +Anqing +Liuzhou +Zhangjiakou +Zhaoqing +Shijiazhuang +Ningbo +Qiqihar +Phoenix +Fuzhou +Chifeng +Xiaoxita +Amman +Chuzhou +Linfen +Qingyuan +Xianyang +Loudi +Binzhou +Zhuzhou +Taiyuan +Nanning +Harbin +Abuja +Yokohama +Suihua +Zaozhuang +Detroit +Xiamen +Neijiang +Montréal +Fuzhou +Baicheng +Wuhu +Yulinshi +Medan +Wenzhou +Changzhou +Puyang +Jiaozuo +Nanchang +Seattle +Ibadan +Casablanca +Kumasi +Deyang +Busan +Hohhot +Hechi +Algiers +Tangshan +Shiyan +Lucknow +Mashhad +San Francisco +Boankra +Dubai +Anshan +Baojishi +Qinzhou +Guiyang +Bengbu +Bazhou +Suining +Wuxi +Kotla Qasim Khan +Hanzhong +Putian +Zhenjiang +Guang’an +Faisalabad +Changzhi +Tongren +Leshan +Santa Cruz de la Sierra +Qinhuangdao +Jaipur +Xinzhou +Lanzhou +Wuzhou +Athens +San Diego +Addis Ababa +Taichung +Huainan +Guatemala City +Kuwait City +Budapest +Qincheng +Rizhao +Quezon City +Sanaa +Tashkent +Kyiv +Meishan +Incheon +Birmingham +Ningde +Zhongshan +Weihai +Bursa +Minneapolis +Mbuji-Mayi +Haikou +Tongliao +Chaoyang +La Paz +Pyongyang +Tampa +Shaoguan +Heyuan +Brasília +Omdurman +Malang +Stuttgart +Daqing +Rome +Brooklyn +Kaohsiung +Xiangtan +Longyan +Baotou +Handan +Jinzhou +Kanpur +Denver +Nanping +Gāzipura +Shanwei +Chaozhou +Guayaquil +Weifang +Huai’an +Zibo +Ankang +Mogadishu +Munich +Gulou +Taipei +Bekasi +Damascus +Sanming +Yangjiang +Jiamusi +Luohe +Medellín +Dingxi +Shaoxing +Yantai +Huizhou +Lishui +Xuanzhou +Khowrhesht +Mirzāpur +Zigong +Hamburg +Guangyuan +Cali +Huangshi +Xining +Lusaka +Ouagadougou +Yaoundé +Zhuhai +Huludao +Baoshan +Mecca +Vancouver +Lianshan +Beirut +Salvador +Bucharest +Longba +Nāgpur +Queens +Jilin +Tieling +Accra +Yunfu +Bekasi Kota +Daegu +Ghāziābād +Luoyang +Brisbane +Anshun +Riverside +Yingkou +Colombo +Yanjiang +Baku +Antananarivo +Mudanjiang +Fukuoka +Yan’an +Jincheng +Nantong +Lincang +Yuxi +Las Vegas +Caracas +Tangerang +Laibin +Konya +Supaul +Vienna +Eşfahān +Baltimore +Shengli +Dandong +Qinbaling +Gaoping +Awka +Taizhou +Ma’anshan +Harare +Perth +St. Louis +Phnom Penh +Depok +Stockholm +Puning +Huaibei +Kowloon +Córdoba +Haiphong +Zamboanga City +Chongzuo +Rawalpindi +Portland +Kano +Yushan +Havana +Hezhou +Pingliang +Vadodara +Manaus +Qingyang +San Antonio +Rājkot +Shangzhou +Vishākhapatnam +Sanmenxia +Baicheng +Gujranwala +Aleppo +Tijuana +Bamenda +Minsk +Indore +Karaj +Kananga +Peshawar +Sapporo +Sacramento +Tilburg +Pingxiang +Ecatepec +Almaty +Austin +Yinchuan +Santos +Blantyre +Thāne +Orlando +Tainan +Xiping +Multan +Santa Cruz +Port Harcourt +Jixi +Fushun +Warsaw +Beihai +Fuxin +Wuwei +Siping +San Juan +Mersin +Bhopāl +Mosul +Lubumbashi +Davao +Curitiba +San Jose +Shuyangzha +Adana +Quito +Pittsburgh +Brazzaville +Hyderabad City +Diyarbakır +Indianapolis +Pimpri-Chinchwad +Masqaţ +Montevideo +Shuozhou +Manhattan +Cincinnati +Kansas City +Patna +Tegucigalpa +Kampala +Cleveland +Sanzhou +Changshu +Heihe +Conakry +Ximeicun +Caloocan City +Masvingo +Zhongli +Novosibirsk +Bilāspur +Semarang +Jingdezhen +Ludhiāna +Liaoyang +Chengtangcun +Rājshāhi +Balandougou +Jiangyin +Valencia +Āgra +León de los Aldama +Puebla +Columbus +Yopougon +Hebi +Shīrāz +Madurai +Huzhou +Tabrīz +Jamshedpur +Maracaibo +Sofia +San José +Prayagraj +Palembang +Kawasaki +Kōbe +Jiaxing +Kigali +Zhangjiajie +Baiyin +Guiping +Lianjiang +Jianguang +Yucheng +Xushan +Panama City +Nneyi-Umuleri +Leizhou +Gwangju +Katako-Kombe +Recife +Nāsik +Valencia +Onitsha +Abu Dhabi +Zapopan +Daejeon +Bronx +Yekaterinburg +Huazhou +Jinhua +Kyōto +Amsterdam +Pizhou +Kismaayo +Yangshe +Virginia Beach +Dakar +Goiânia +Charlotte +Rui’an +Muscat +Kharkiv +Wenling +Gaozhou +Farīdābād +Medina +Khulna +Ulaanbaatar +Fuqing +Kayseri +Tel Aviv-Yafo +Wuzhong +Pingdu +Sangereng +Yangquan +Samsun +Yutan +Copenhagen +Helsinki +Prague +Milan +Auckland +Santiago +Chizhou +Makassar +Liangshi +Porto Alegre +Huangshan +Barranquilla +Al Başrah +Benxi +Saitama +Guarulhos +Juárez +Mandalay +Xintai +Wusong +Calgary +Meerut +Yushu +Belém +Kuaidamao +Huazhou +Baishan +Adelaide +Haicheng +Milwaukee +Providence +Jacksonville +Yicheng +Cacuaco +Porto +Rosario +Canagatan +Soweto +Bagam +Jabalpur +Rucheng +Huaiyin +Dublin +Kazan +Dayan +Shaoyang +Balıkesir +Comayagüela +Laiwu +Sharjah +Jingling +Kalyān +Nizhniy Novgorod +Yongcheng +Sumedang +Cần Thơ +Brussels +Suwon +Yiwu +Beidao +Vasai-Virar +Xiangshui +Dadukou +Campinas +Lingcheng +Shuangyashan +Mombasa +Najafgarh +Xinyu +Qom +Hargeysa +Baidoa +Zhangye +Vārānasi +Hiroshima +Chiang Mai +Belgrade +Maiduguri +Chelyabinsk +Batam Centre +Rongcheng +Mbandaka +Doha +Ahvāz +Shymkent +Tripoli +Srīnagar +Nashville +Liaoyuan +Aurangābād +Cilacap +Salt Lake City +Omsk +Pikine +Samara +Guankou +Bandar Lampung +Raleigh +Lianyuan +Rongcheng +Dhanbād +Nay Pyi Taw +Aba +Kaiyuan +Zhuji +Yingtan +Edmonton +Leiyang +Ulsan +Yichun +Benin City +Bujumbura +Guyuan +Xiantao +Rostov +Maputo +Bukavu +Amritsar +Shagamu +Yingchuan +Alīgarh +Santo Domingo +Bogor +Bishkek +Tbilisi +Guwāhāti +Ufa +Fès +Mwanza +Biên Hòa +Mexicali +Sevilla +Ikare +Dongtai +Dingzhou +Xibeijie +Tamale +Yuyao +Hanchuan +Gongzhuling +N’Djamena +Ubungo +Cologne +Krasnoyarsk +Zhufeng +Ezhou +Astana +Nezahualcóyotl +Nouakchott +Hāora +Tongjin +Xiashi +Yerevan +Rānchi +Richmond +Ciudad Nezahualcóyotl +Gwalior +Ottawa +Zhongwei +Oslo +Goyang +Sendai +Mizhou +Xishan +Barquisimeto +Hegang +Chandīgarh +Voronezh +Managua +Haldwāni +Vijayavāda +Perm +Fangchenggang +Jiancheng +Cazenga +Kisangani +Shouguang +Memphis +São Luís +Jodhpur +Matola +Ogbomoso +Sanya +Rangapukur +Ashgabat +Wutong +Linhai +Denizli +Niamey +Shubrā al Khaymah +Wafangdian +Zhongxiang +Monrovia +San Cristóbal +Islamabad +Xinyi +Thủ Đức +Morelia +Odesa +Raipur +Changwon +Arequipa +Volgograd +Zaoyang +Xingyi +Shuizhai +Kota +Quetta +Quảng Hà +Domaa-Ahenkro +Bareilly +Oklahoma City +Bordeaux +Xingcheng +Taixing +Xinhualu +Lilongwe +Port-au-Prince +Yingcheng +Al Mijlad +Luocheng +Pekanbaru +Natal +Chiba +Kirkuk +Hartford +Huilong +Wuchuan +Dnipro +Nārāyanganj +Gqeberha +Málaga +Marrakech +Cebu City +Louisville +Asmara +Coimbatore +Maceió +Nada +Taishan +Teresina +Solāpur +Freetown +Santo Domingo Este +Krasnodar +Vientiane +Tangier +Anqiu +Kermānshāh +Feicheng +Kibanseke Première +Seberang Jaya +Buffalo +Hubli +El Alto +Çankaya +Hwasu-dong +Setagaya +Keçiören +Jerusalem +Khartoum North +Meishan +Mushin +Trujillo +Kitakyūshū +Aguascalientes +New Orleans +Fort Worth +Taihe +Riga +Xin’an +Taihecun +Kashgar +Sŏngnam +Trichinopoly +Cartagena +Qingzhou +Naples +Santiago del Estero +Naucalpan de Juárez +Daye +Hengzhou +Padang +Bridgeport +Owerri +Zhuanghe +Bobo-Dioulasso +Ad Dammām +Quzhou +Donetsk +Ashmūn +Bunia +Jiaozhou +Campo Grande +Wuchang +São Gonçalo +Bucaramanga +Mérida +Yangchun +Osmangazi +Esenyurt +Morādābād +Bangui +Abeokuta +Cancún +Antipolo +Dengtalu +Taguig City +Tabūk +Zhoushan +Tucson +As Sulaymānīyah +Chihuahua +Klang +Tiruppūr +Gurgaon +Ar Ramādī +Hai’an +Laiyang +Barinas +Jalandhar +Marseille +Kaifeng Chengguanzhen +Eskişehir +Gaomi +Lhasa +Ipoh +El Paso +Saltillo +Dushanbe +Ikeja +El Dorado +Cochabamba +Portsmouth +Tyumen +Southampton +Hermosillo +Wuxi +Leping +Cheongju +Shache +Sale +Hailun +Macheng +Akure +Ilorin +Erbil +Kathmandu +Saratov +Iguaçu +Zijinglu +Turin +Yuci +Dehui +Pietermaritzburg +Durban +Bhubaneshwar +Denpasar +Tongchuan +João Pessoa +Samarinda +Chengxiang +Rongjiawan +Weichanglu +Sakai +Renqiu +Omaha +Xindi +Wu’an +Qingping +Gaoyou +São Bernardo do Campo +Yiyang +Hejian +Puxi +Bhayandar +Androtsy +Culiacán +Cúcuta +Danyang +Dongyang +Kraków +Pasig City +Thessaloníki +Querétaro +Palermo +Xigazê +Qamdo +McAllen +Libreville +Seyhan +San Pedro Sula +Niigata +Hempstead +Leeds +Hamamatsu +Pointe-Noire +Xiangxiang +Birmingham +Chaohucun +Bucheon +Lubango +Homs +Bilbao +Zouping +Frankfurt +San Luis Potosí +Dali +Fuyang +Khŭjand +Korla +Albuquerque +Hamhŭng +Erzurum +Zagreb +Al ‘Ayn +Songzi +Patiāla +Laixi +Zhongba +Bahawalpur +Qingnian +Kaduna +Winnipeg +Trabzon +Guangshui +Baardheere +Shīshgarh +Nerima +Sizhan +Ciudad Guayana +Natal +Lichuan +Licheng +Santo André +Ōta-ku +Gaalkacyo +Thiruvananthapuram +Osasco +Nampula +Pretoria +Kyaukse +Chengguan +Nehe +Cabinda +Kumamoto +Kermān +Zunhua +Orūmīyeh +Wugang +Bağcılar +Quebec City +Shuangqiao +Umraniye +Yanggok +Tshikapa +Tulsa +Osogbo +Comodoro Rivadavia +Nottingham +Hamilton +Langzhong +Cagayan de Oro +Qian’an +Fresno +An Najaf +Cencheng +Sorocaba +Guli +Sagamihara +Pīshbar +Okayama +Anlu +Concepción +Mississauga +Changsha +Songyang +Lviv +Shihezi +Vilnius +Marka +Enugu +Valenzuela +Yatou +Uberlândia +Xichang +Zaporizhzhia +Bhiwandi +George Town +Bristol +Charleston +Sahāranpur +Dashiqiao +Yenimahalle +Warangal +Nampo +Dasmariñas +Jaboatão +Chisinau +Shiliguri +Boosaaso +Port Moresby +Latakia +Rochester +Ribeirão Prêto +Edogawa +São José dos Campos +General Santos +Ḩamāh +Qianxi +Bauchi +Pendik +Salem +Shishi +Sinnūris +Cocody +Miluo Chengguanzhen +Lokoja +Guadalupe +Gaizhou +Karbalā’ +Borvāyeh-ye Al Bū ‘Azīz +City of Parañaque +Leling +Mamak +Jianshe +Tolyatti +Shizuoka +Jingcheng +Agege +Mar del Plata +Zaragoza +Adachi +Xinmin +Rasht +Shanhu +Zhongshu +Cotonou +Tasikmalaya +Kochi +Soledad +Dhūlia +Acapulco de Juárez +Gorakhpur +Bahār +Kumul +Wrocław +Murcia +Pinghu +Guankou +Łódź +Guntūr +Bhāngar +Dayton +Ch’ŏngjin +Qionghu +Zhaodong +Puyang Chengguanzhen +Bulawayo +Huambo +Aracaju +Bacoor +Wenchang +Rotterdam +Tlaquepaque +Villavicencio +Shulan +Makhachkala +Banjarmasin +Narela +Catia La Mar +Al Hufūf +Jalingo +Sargodha +Karaikandi +Bouaké +Lingbao Chengguanzhen +Brampton +Abomey-Calavi +Durango +Cape Coral +Tondo +Dayrūţ +Tlalnepantla +Ansan +Xiping +Huế +Sanhe +San Jose del Monte +Ch’ŏnan +Cuiabá +Jieshou +Ērer Sātā +Selçuklu +Suohe +Guixi +Izhevsk +Honchō +Wuxue +Jaboatão dos Guararapes +Yıldırım +Bhāvnagar +Jinghong +Tengyue +Mission Viejo +Ruiming +Qufu +Sha Tin +Petaling Jaya +Colorado Springs +Noida +Xinshi +Baton Rouge +Manama +Las Palmas +Chak Forty-one +Jin’e +Benghazi +Chuxiong +Barnaul +Palermo +Makati City +Düsseldorf +Allentown +Xinxing +Ţūkh +Glasgow +Namangan +Bazal’tove +Al Qaţīf +Bhilai +Ulyanovsk +Mangalore +Kaihua +Irkutsk +Meilan +Bazhou +Ogden +Turpan +Jos +Al Manşūrah +Contagem +Jambi +Ḩalwān +Provo +Tân An +Port-Bouët +Pontianak +Meihekou +Jurong +Bihtā +Yuhuan +Joinvile +Feira de Santana +Khabarovsk +Leipzig +Xinji +Knoxville +Ta‘izz +Etimesgut +Changping +Tallinn +Chimalhuacán +Kandahār +Serang +Zhangshu +Grand Rapids +Yukarıkaraman +Gothenburg +Kuantan +Gold Coast +Kawaguchi +Las Piñas City +Cuttack +San Miguel de Tucumán +Ar Rayyān +Salīmpur +Malanje +Columbia +Kryvyi Rih +Djibouti +Zhuozhou +Tianchang +Tunis +Yaroslavl +Bacolod +Garoua +Bafoussam +Haifa +Raurkela +Tumkūr +Balikpapan +Somolu +Vladivostok +Al Ḩillah +Melikgazi +Kagoshima +Sihui +Dortmund +Irapuato +Al Maḩallah al Kubrá +Sialkot City +Luocheng +Albany +Pereira +Gaza +Uvira +Reynosa +Zāhedān +Cimahi +Mbale +Wenlan +Shangzhi +Essen +Itabashi +Shah Alam +Botou +Suginami-ku +Tenkāsi +Kingston +Al Mafraq +Aţ Ţā’if +Port Sudan +Tuxtla +Dehra Dūn +Xiulin +Fu’an +Mymensingh +Hachiōji +Iloilo +Puente Alto +Tomsk +Rabat +Sincan +Bakersfield +Kottayam +Luofeng +Shibīn al Qanāţir +Nakuru +Lingyuan +Tonalá +Bremen +Abū Ḩummuş +Irbid +Macau +Surrey +Ciudad Bolívar +Durgāpur +Shenzhou +New Haven +Orenburg +Kuiju +Zhenzhou +Āsansol +Bokaro Steel City +Dresden +Bello +Kolhāpur +Wencheng +Lanxi +Dangyang +Nava Raipur +Kemerovo +Genoa +Herāt +Londrina +Cuautitlán Izcalli +Uyo +Hamadān +Luanzhou +Chiclayo +Surakarta +Novokuznetsk +Ajmer +Kimhae +Nānded +Wuhai +Palma +Rustenburg +Amrāvati +Des Moines +Lisbon +Yanji +Huanghua +Al Ḩudaydah +Anyang +The Hague +Andijon +Manchester +Nellore +Poznań +Samarkand +Xingcheng +Wancheng +Kaiyuan +Hannover +Sungai Petani +Valledupar +Fengcheng +Muntinlupa City +Ghulja +Ixtapaluca +Fuding +Heroica Matamoros +Akron +Mbeya +An Nāşirīyah +Xiangyang +Ibagué +Al Ḩillah +Juiz de Fora +City of Calamba +El Geneina +Santa Cruz +Ryazan +Chang’an +Florianópolis +Nilüfer +Antwerp +Kassala +Aksu +Salta +Dispur +Palm Bay +Naberezhnyye Chelny +Gulbarga +Nansana +Mingguang +Concord +Beira +Yazd +Ardabīl +Touba +Bīkaner +Gaobeidian +Ndola +Himeji +Ailan Mubage +Bandar ‘Abbās +Skopje +Santa Teresa del Tuy +Port Said +Astrakhan +Kōtō-ku +Ciudad Apodaca +Montería +Nuremberg +Kitchener +Yucheng +Nāgercoil +Agartala +Soacha +Buca +Lyon +Maipú +Arāk +Serra +Tultitlán de Mariano Escobedo +Meknès +Bắc Ninh +Anda +Longzhou +Al Fayyūm +Utsunomiya +Sheffield +Mixco +Suez +Heshan +Penza +Loni +Jiaji +Santa Marta +Ujjain +Beining +Abū Ţisht +Maturín +Liverpool +Macapá +Benguela +Yicheng +Al Fashn +Al ‘Amārah +Carrefour +Campos +Cadaado +Encheng +Bhīlwāra +Bibā +Wichita +Leicester +Newcastle +Hải Dương +Aden +Jhānsi +Matsuyama +Ulhāsnagar +Nagqu +Kitwe +Vellore +Toulouse +Pohang +Mesa +Lipetsk +Duisburg +Jammu +Ile-Ife +Homyel’ +Kirov +Mazatlán +Meicheng +El Fasher +Farāh +Belas +Talatona +Nenjiang +Sukkur +Hsinchu +Harrisburg +Kaliningrad +Hongjiang +Qaraghandy +Lapu-Lapu City +Matsudo +Johor Bahru +Purnea +Imus +Niterói +Beipiao +Dengtacun +Zhijiang +Suoluntun +Staten Island +Chengjiao +Lembok +Likasi +Oujda-Angad +Duyun +Toledo +Pindi Bhattian +Nyala +Bissau +Ichikawa +Kota Bharu +Yuanping +Higashi-ōsaka +Larkana +‘Ajmān +Vinh +Ciudad López Mateos +Cheboksary +Yueqing +Belgaum +Caerdydd +Edinburgh +Brookhaven +Nishinomiya-hama +Karamay +Worcester +Kawachichō +Shahe +Gdańsk +Sevastopol +Garoowe +Gaoping +Villa Nueva +Dunhua +Lianran +Akhmīm +Şanlıurfa +Az Zarqā’ +Mālegaon +São José do Rio Prêto +Valletta +Kolwezi +Jāmnagar +Sylhet +Ananindeua +East London +Berbera +Jiannan +Chiniot +Asunción +Ōita +Nangong +Bārdoli +Eldoret +Bratislava +Kurashiki +Al Jubayl +Worthing +Gaya +Shekhupura +Piura +Vila Velha +Ar Ruşayfah +Jiaojiangcun +Laohekou +San Juan +Mykolaiv +Beian +Fujin +Küçükçekmece +Mazār-e Sharīf +Xiaoyi +Balashikha +Qingzhen +Tula +Ba‘qūbah +Katlehong +Jiangshan +Buraydah +Surab +Kupang +Ambattūr +Nakhon Ratchasima +Tân Uyên +Constantine +Longjiang +Caxias do Sul +Angeles City +Kuqa +Kanazawa +Long Beach +Port St. Lucie +Manado Light +Kartal +Cranbourne +Jalgaon +Porto Velho +Chhatarpur +Fukuyama +Little Rock +Juba +Lanús +Amagasaki +Kikwit +Pyeongtaek +Reno +Kurnool +Spokane +Marikina City +Jian’ou +Huadian +Melaka +Manado +Manizales +Bornova +Minzhu +Demiryol +Erköklü +Kota Kinabalu +Katsushika-ku +Madison +Santiago de Cuba +Udaipur +Kursk +Mogi das Cruzes +Stavropol +General Trias +Sirājganj +Boise +Bonita Springs +Mariupol +Eslāmshahr +Piraeus +Barcelona +Tanbei +Zürich +Pingquan +Ado-Ekiti +Baisha +Batman +Yongji +Esenler +Rodriguez +Ensenada +Danjiangkou +Chauddagram +Kahramanmaraş +San Nicolás de los Garza +Taoyuan District +Ndjili +Mathura +Pasay City +Ning’an +Halifax +Fujisawa +Ulan-Ude +Denton +Laval +Jinchang +Oakland +Springfield +Guangming +Augusta +Kâğıthane +Sunch’ŏn +Sāngli +Avcılar +Jeju +Zhuangyuan +Davangere +Machida +Sanghar +Al Marāghah +Bandung +Kissimmee +Calicut +Kenitra +Windhoek +Huili Chengguanzhen +Sidi Bouzid +Bārāmati +Ţanţā +Ismailia +Cusco +Veracruz +Sokoto +Winston-Salem +Kashiwa +Al Bājūr +Xunyang +Malatya +Yan’an Beilu +Mothīhāri +Aomori +Akola +Mandaluyong City +Aves +Sihŭng +Burco +Tver +Xalapa +Buenaventura +London +Piracicaba +Yogyakarta +Toyota +Daloa +Agadir +Elazığ +Uijeongbu +Hpa-An +Rahimyar Khan +Ugep +Hailin +Mishan +Sarajevo +Seremban +Zhengjiatun +Lecheng +Campina Grande +Xicheng +Pencheng +Kowloon City +Tirana +Kushtia +El Obeid +Mauá +Magnitogorsk +Da’an +Luhansk +Xingren +Takamatsu +Arusha +Fenyang +Ajdābiyā +Callao +Awsīm +Shinagawa-ku +Paju +Santa Rosa +Bettiah +Jhang City +Altındağ +Talā +Stockton +Ţalkhā +Boa Vista +Banjul +Jayapura +Toyama +Sanandaj +Khon Kaen +Fangting +Linghai +Shorāpur +Koumassi +Betim +Sochi +Tinnevelly +Pasto +Syracuse +Bellary +Bhāgalpur +Kisumu +Zhangjiakou Shi Xuanhua Qu +Maringá +Kocasinan +Mataram +Shashemenē +Zaria +Kumi +Wanyuan +Biñan +Chattanooga +Jiexiu +Bağlar +Padiāla +Đà Lạt +Sham Shui Po +Santa Fe +Delhi Cantonment +Cumaná +Barura +Yüreğir +Nagasaki +Mardan +Hat Yai +Salt Lake City +Qazvīn +Etāwa +Lancaster +Sonīpat +Jundiaí +Ivanovo +Greenville +Toyonaka +Bogra +Öskemen +Gifu +Maungdaw +Jiangjiafan +Durham +Bryansk +Dera Ghazi Khan +Anápolis +Pensacola +Miyazaki +Quilon +Mulangodi +Munro Turuttu +Hirakata +Sandakan +Szczecin +Brno +Surgut +Hejin +Fayetteville +Betsiboka +Thiès +Arlington +Al Jahrā’ +Kaunas +Thanh Hóa +Diadema +Lobito +Saurimo +Yola +Zhugang +Tāngāil +Nha Trang +Khayelitsha +Ad Dīwānīyah +Nnewi +Hancheng +San-Pédro +Gujrat +Yokosuka +Tieli +Asyūţ +Gwoza +Sampaloc +Saki +Bologna +Aqtöbe +Cilegon +Uvinza +Aurora +Carapicuíba +Ḩafr al Bāţin +Zanjān +Petrolina +Bairia +Oyo +Taytay +Kisenzi +Bhātpāra +Kūkatpalli +Manisa +Sirūr +Tarlac City +Okazaki +Lianzhou +Ceel Baraf +Yidu +Lingxi +Ilesa +Kākināda +Savar +Nuevo Laredo +Bawshar +Christchurch +Gusau +Zêtang +Palu +Canberra +Minamisuita +Tétouan +Malabon +Neiva +Novi Sad +Huancayo +Celaya +Ichinomiya +Caruaru +Sintra +Hatay +Iquitos +Pānihāti +Cainta +Helixi +Mamou +Manukau City +Itaquaquecetuba +Cantonment +Rohtak +Gaziantep +Māler Kotla +Bhawana +Khorramābād +Lipa City +Butuan +Dikirnis +Stoke-on-Trent +Takasaki +Malakwal +Toyohashi +Chitungwiza +Gebze +Cibinong +Lengshuijiang +Panshi +Az Zubayr +Oxnard +Vinnytsia +Indio +Bharatpur +Petare +Nagano +Huichang +Keelung +Bauru +La Florida +Nicolás Romero +Jinshan +Baguio City +Scranton +Bochum +Sivas +Kolga +Korba +Qardho +Rio Branco +Tecámac +Alanya +Mandaue City +Victorville +Kocaeli +Warri +Victoria +Wŏnsan +Iligan +Anguo +K’ebrī Dehar +Coventry +Kayapınar +Trenton +Cuenca +Blumenau +Nanqiao +Florence +Buurhakaba +Bengkulu +Malmö +Wudalianchi +Shuanghe +Pétion-Ville +Utrecht +Sīkar +Umuahia +Vitsyebsk +Palmira +Wuppertal +Hrodna +Ash Shuhadā’ +Karūr +Ponta Grossa +Sasarām +Taraz +Cubal +Luena +Karnāl +Yong’an +Konak +Minatitlán +Linxia Chengguanzhen +Brahmapur +Chānda +Caucaia +Cuito +Cabuyao +Hongzhai +Gedaref +San Fernando +Kawagoe +Modesto +Nizhniy Tagil +Pokhara +Villahermosa +Van +Mahilyow +Wakayama +Osh +Kita-ku +Gimpo +Corrientes +Franca +Thari Mir Wah +Nara +Vladimir +Yakeshi +Nam Định +Sinŭiju +Oruro +Cabimas +Arkhangelsk +Batangas +Ibb +Ahmadnagar +Sarai Alamgir +Semey +Holguín +Tungi +Yingmen +Sawrān +Chita +Olinda +Praia Grande +Dāsarhalli +Huntsville +Shinjuku +Alicante +Cariacica +Varna +Honolulu +Antofagasta +Ambon +Nice +Cascavel +Pamukkale +Canoas +Takatsuki +António Enes +Greensboro +Anaheim +Plovdiv +Central Coast +Karşıyaka +Shāhjānpur +Gwagwalada +Alamādi +Āvadi +Tanch’ŏn +Khānāpur +Wad Medani +Kūstī +Belfast +Hosūr +Cuddapah +Nakano +Ōtsu +Maseru +Makiivka +Pavlodar +Chon Buri +Naga City +Sarıyer +Brest +Meram +Gómez Palacio +Paulista +Rājahmundry +Koshigaya +Vũng Tàu +Jeonju +Alwar +Tokorozawa +Sumqayıt +Vitória da Conquista +Simferopol +Buôn Ma Thuột +Serekunda +Islip +Cuernavaca +Markham +Bielefeld +Uberaba +Jitpur +Bydgoszcz +Tangdong +Chinju +Corpus Christi +Fort Wayne +Reading +Randburg +Matadi +Bonn +Iwaki +Oshawa +Shah Latif Town +Sambalpur +Fort Collins +Jackson +Yingzhong +Santo Domingo de los Colorados +Uruapan +Lublin +Licheng +Tampere +Belgorod +Muzaffarpur +Viña del Mar +Tepic +Khipro +Hangu +Asan +Chak Jhumra +Myrtle Beach +Soledad de Graciano Sánchez +Şalālah +Santarém +Yanbu +Maebashi +Kaluga +Dumai +Beylikdüzü +Gəncə +Asahikawa +Kendari +Wŏnju +Birkat as Sab‘ +Lafia +Dahūk +Finglas +Kāmārhāti +Thái Nguyên +Bamiantong +Nicosia +São Vicente +Ribeirão das Neves +Guédiawaye +Ciudad Obregón +São José dos Pinhais +Campīernagar +Phatthaya +Fayetteville +Debrecen +Mirpur Mathelo +Sultanbeyli +Bijāpur +Cabanatuan City +Tharād +Antioch +Si Racha +Salamanca +Ratnāgiri +Ulanhot +Koriyama +Yunzhong +Roodepoort +Volzhskiy +Pucallpa +San Pedro +Pelotas +Kōchi +Rāmpur +Kuching +Cotabato +Cimanggis +Gonaïves +Nazrēt +Kikuyu +Córdoba +Kluang +Mekele +Binxian +Nantes +Vaughan +Kaiyuan +Vitória +Shimoga +Lansing +Uíge +Hotan +Camagüey +Taourirt +San Salvador de Jujuy +Kāshīpur +Thủ Dầu Một +Al Kūt +Lexington +Sukabumi +Münster +Menongue +Mobile +Godē +Okene +Jūnāgadh +Smolensk +Guasavito +Asan +Nukus +Kaech’ŏn +Tehuacán +Coatzacoalcos +Muhanga +Youngstown +Zalantun +Saransk +Katsina +Puerto Plata +Henderson +Gwangmyeongni +Geita +Cherepovets +Taubaté +An Nhơn +Fontibón +Hāpur +Kot Radha Kishan +Barueri +San Salvador +Savannah +Naha +Bari +Xiaoli +Trichūr +Mannheim +Bor +Cà Mau +Saint-Denis +San Miguelito +Muar +Kasur +Usme +Barddhamān +Poughkeepsie +Kingston upon Hull +Binangonan +Temara +Attiecoubé +Jiayuguan +Pasir Gudang +Vologda +Gorgān +Tanza +Yakutsk +Panvel +Santa Ana +Guarujá +Nizāmābād +Quy Nhơn +Ḩā’il +Datang +Longquan +Mitchells Plain +Gwangju +Yokkaichi +Chalco +Shahrīār +Shahr-e Qods +Kurgan +Ciudad del Este +Ann Arbor +St. Paul +Karlsruhe +Safi +Ciudad Benito Juárez +Karawang +Sariwŏn +Suzano +Newark +Nghi Sơn +Parbhani +Puerto Princesa +Hisar +Vladikavkaz +Windsor +Kasugai +Ciudad Santa Catarina +Puerto La Cruz +Fatehpur +Ciudad Victoria +Playa del Carmen +Yeşilyurt +Yonghetun +Irvine +Kāshān +Minna +Sumbawanga +Orël +Akita +Kurume +Az Zaqāzīq +Podolsk +Palmas +Montpellier +Vila Nova de Gaia +Bahía Blanca +Al Waqf +San Bernardo +San Juan del Río +Armenia +Augsburg +Qianzhou +Popayán +Al Qunfudhah +Yakou +Newcastle +Oulgaret +Āwasa +Ingrāj Bāzār +Oaxaca +Binjai +Barr Eliâs +Khairpur Tamewah +Sucre +Al ‘Ajamī +Al Maţarīyah +Bada Barabīl +Ash Shāmīyah +Oyster Bay +Ar Raqqah +Chakwal +Ōakashichō +Afyonkarahisar +Dod Ballāpur +Camaçari +Ciudad General Escobedo +Catania +Jember +Al Mubarraz +Pekalongan +Los Mochis +Toshima +Pachuca +Yangsan +Valladolid +Tampico +Bihār +Espoo +Malabo +Pilar +Valparaíso +Cirebon +Tagum +Santa Rosa +Darbhanga +Comilla +Battalgazi +Sorong +Shubrākhīt +Floridablanca +Silang +Eloy Alfaro +Pondokaren +Sikandarābād +Kafr Şaqr +Vila Teixeira da Silva +Pānīpat +Rangpur +Białystok +Canton +Asheville +Flint +Vigo +Coacalco +Āīzawl +Bāli +Bradford +Mabalacat +Dexing +Winter Haven +Graz +Palni +Resistencia +Groznyy +Chimbote +Strasbourg +Bergen +Gatineau +Surajgarha +Tegal +Anchorage +Batna +Aarhus +Morioka +Lincoln +Hulin +Hong’an +Karīmnagar +Santa Maria +Tambov +Dewās +Güngören +Magway +Farg‘ona +Concord +Hugli +Chunchura +Sétif +Sonpur +Meguro +Machala +San Lorenzo +Jersey City +Ichalkaranji +Punto Fijo +Várzea Grande +Tirupati +Pathein +Chernihiv +Sincelejo +Cluj-Napoca +Springfield +Sekondi +Tacna +Tin Shui Wai +Juazeiro do Norte +Al Qurnah +Korhogo +Bhatinda +Katowice +Jālna +Foz do Iguaçu +Bolton +San Pablo +Huixquilucan +Plano +Qillīn +Croix-des-Bouquets +San Juan Sacatepéquez +Ljubljana +Fukushima +Bago +Delmas +Fuquan +Ibaraki +Shreveport +Ostrava +Poltava +Wiesbaden +Satna +Sannai +Huozhou +Temuco +Ica +Tongchuanshi +Jining +Chuncheon +Sakarya +İnegöl +Kaura Namoda +Davenport +Malārd +Lubbock +Lakeland +Sterlitamak +Bukhara +Santa Ana +Sumbe +Mingaora +Çorlu +Kherson +Lucena +Petrópolis +Mamuju +Mau +Nizhnevartovsk +Long Xuyên +Petrozavodsk +Gyeongsan +Bārāsat +South Bend +Pematangsiantar +Maastricht +Việt Trì +Sunderland +Kostroma +Gagnoa +Xingsha +Dire Dawa +Lashkar Gāh +Itagüí +Juliaca +Chula Vista +Posadas +Farrukhābād +Chandler +Kunsan +Yeosu +Qarshi +Saugor +Khmelnytskyi +Nassau +Ratlām +Crato +Yeosu +Shaowu +Pasarkemis +Cotia +Taboão da Serra +San Mateo +Novorossiysk +Tsu +Rockford +Imperatriz +Los Alcarrizos +Soubré +Reading +Székesfehérvár +Majene +Sumida +Chopda +Gabela +Dayr az Zawr +Iaşi +Santa Maria +Sartā +Eugene +Iksan +Mỹ Tho +Nguru +Arnavutköy +Derby +Mito +Kunp’o +Gombe +Bijiao +Cherkasy +Bayat +Handwāra +Kunduz +Drug +Wilmington +Mönchengladbach +Gijón +Brāhmanbāria +Santa Clarita +Thái Bình +Ichihara +Tarija +Shibīn al Kawm +Plymouth +Aswān +Bimo +Murmansk +Gilbert +Maradi +Xiangkhoang +Anantapur +Adıyaman +Kütahya +Yoshkar-Ola +Marabá +Salem +Saskatoon +Sumaré +Killeen +Nagaoka +Djelfa +Sumy +Khwazakhela +Chernivtsi +Suncheon +Kibaha +Nalchik +Sfax +Gent +Gravataí +Antsirabe +Feni +Engels +Imphāl +Taunggyi +Nogales +Ed Daein +Dezfūl +Mossoró +Round Lake Beach +Potosí +Osmaniye +Columbus +Itajaí +North Las Vegas +Tāluqān +Constanţa +Luque +Yao +Jalālābād +Nawabshah +Talisay +Gelsenkirchen +Jagdalpur +Tchibota +Kafr ad Dawwār +Quilmes +Wollongong +Zhytomyr +Volta Redonda +Fukui +Arrah +Malolos +Heroica Nogales +Bariadi +Hong +Oumé +Fuchū +Minato +Boksburg +Olongapo +Quảng Ngãi +Al Ḩamzah +Kennewick +Qo‘qon +Kotri +St. Petersburg +Mişrātah +Aydın +Singa +Manta +Tallahassee +Kakogawachō-honmachi +Isparta +Siverek +Ndulo +Antalya +Huayin +Hiratsuka +Rāniyah +Annaba +Governador Valadares +Khimki +Ondo +Etāwah +Siddhirganj +Horlivka +Indaiatuba +Bloemfontein +Ấp Đa Lợi +Türkmenabat +Malkājgiri +Vitoria-Gasteiz +Germiston +Nonthaburi +Verona +Tuzla +Westminster +Laredo +Kuala Terengganu +San Pedro Carchá +Moçâmedes +Irving +Turmero +Tokushima +São Carlos +Longueuil +Marilao +Tuni +Ash Shaţrah +Sab‘ al Būr +Fort-de-France +Mawlamyine +Peoria +Godomè +Rāpar +Samāstipur +Aksaray +Shinozaki +Parnamirim +Kızıltepe +Jhenida +Turku +Bharatpur +Aachen +Begusarai +Kediri +Kanggye +Chiayi +Çekme +Hakodate +Tacloban +Jūnāgarh +Braunschweig +İskenderun +Pécs +Sōka +Nedumana +Higüey +Los Teques +Montgomery +Jinshi +Wolverhampton +Pointe-à-Pitre +Al Fallūjah +Timişoara +Bata +Rạch Giá +Companiganj +Venice +Taganrog +Bābol +São José +La Paz +Al Bayḑā’ +Natogyi +Kurmuk +Râs el-Barr +Kalār +Bojnūrd +Türkistan +New Delhi +Las Condes +Goma +Rishon LeẔiyyon +Komsomol’sk-na-Amure +Campeche +Manzhouli +Tiruvottiyūr +Palangkaraya +Chesapeake +Burnaby +Rāmnagar +Limeira +Carmen +Gāndhīdhām +Banikoara +Chemnitz +Salūmbar +Kyŏngju +Mérida +Glendale +Sibu +Qā’em Shahr +Paraná +Büyükçekmece +Kiel +Sahiwal +A Coruña +Navotas +Santa Clara +Mehrabpur +Yamagata +York +Khomeynī Shahr +Beykoz +Tsukuba-kenkyūgakuen-toshi +Oruro +Macaé +Győr +Al ‘Āshir min Ramaḑān +Mahajanga +Mount Lavinia +Northampton +Krishnarājpur +Hafizabad +Nelamangala +Beichengqu +Abertawe +Syktyvkar +Rivne +Gdynia +Nashua +Barnsley +Taiping +Rondonópolis +São José de Ribamar +Puducherry +Merlo +Portoviejo +Damanhūr +Garland +Kabinda +Jessore +Kesbewa +Tripoli +Fuji +Eindhoven +Sabzevār +Dourados +Bahir Dar +Yoshiichō-shimobaru +Myitkyina +Rāmgundam +Pālanpur +Tuy Hòa +Sasebo +Sapele +Birāṭnagar +Pandharpur +Qyzylorda +St. Catharines +Chigasaki +Araraquara +Kahama +Halle +Americana +Zhangping +Man +Sete Lagoas +Bānchpār +Haeju +Soyapango +Masaurhi Buzurg +Baruta +Düzce +Marília +Katihār +Scottsdale +Tarapoto +Atushi +Abī al Khaşīb +Jacareí +Anju +Bunkyō-ku +Byatarayanpur +Ahor +Diaobingshancun +Magdeburg +Yato +Matsumoto +Szeged +Chimoio +Kasulu +Elche +Tarsus +Ivano-Frankivsk +Chōfugaoka +González Catán +Nyíregyháza +Wuyishan +Shenmu +Tuticorin +As Sīb +Gangānagar +Braşov +Lafayette +Āmol +Stavanger +Sandnes +Nizhnekamsk +Monclova +Chishui +Djougou +Norfolk +Mirpur Khas +Lille +P’yŏngsŏng-si +P’yŏng-dong +Centurion +North Hempstead +Tinkhang +Rewa +Pākdasht +Kajang +Petaẖ Tiqwa +Abhā +Freiburg im Breisgau +Al Minyā +Iseyin +Central District +Gaborone +Arlington +Juazeiro +Zinder +Bole +Shakhty +Ganda +Uluberiya +Bulandshahr +Banda Aceh +Najafābād +Shibuya-ku +Bayamo +Limassol +Borūjerd +Ibb +García +Arapiraca +Longquan +Miri +Maracanaú +Oral +Craiova +Formosa +Appleton +Chauhanpatti +Bo +Mambéré +Damboa +Groningen +Ipswich +Teluk Intan +San Cristóbal +Cannanore +Rāichūr +Okara +Saga +Saidpur +Lin’an +Colombo +Machilīpatnam +Beni +Nazipur +Purwokerto +Bratsk +Biyalā +Madan +Rancagua +Phú Yên +Neuquén +Divinópolis +Qarchak +Ormoc +Fresnillo +Dzerzhinsk +Granada +Sơn Tây +Singkawang +Zégoua +Kulai +Barishal +Pāli +Songadh +Noginsk +Gadda Madiral +Orsk +Ordu +Košice +Kasukabe +Miriālgūda +Aguadilla +Envigado +Haridwār +Rock Hill +Fremont +Vizianagaram +Cobán +Khénifra +Guantánamo +Krefeld +Şabyā +Fargo +Rāisinghnagar +Uşak +Pāthardi +Magé +Gulfport +Neya +Mel Pālaiyam +Novo Hamburgo +Ipatinga +Sāqultah +Choloma +Kropyvnytskyi +Khatīma +Daşoguz +Khanewal +Petlād +Kamianske +Bremerton +Ageoshimo +Changhua +Regina +Badalona +Dianbu +Kolpino +Rio Verde +Meycauayan +Presidente Prudente +Green Bay +Varāmīn +Padangsidempuan +Uacu Cungo +Enterprise +Hunchun +Tarrasa +Ternopil +Kimberley +Nadiād +Toamasina +Rennes +Mutare +Cikupa +Ratodero +Chuādānga +Carlos Manuel de Céspedes +Blagoveshchensk +Nong’an +Ōta +Itaboraí +Puerto Vallarta +Capiatá +Viamão +Takarazuka +Chapecó +Banfield +Toluca +Atsugichō +Paramaribo +Cox’s Bāzār +Bandar-e Būshehr +Itapevi +Staryy Oskol +Probolinggo +Hialeah +Tanjore +Ji’an Shi +Angarsk +Hachinohe +Ijebu-Ode +Velikiy Novgorod +Barra do Dande +Mezitli +Sandton +Beji +Cork +Dili +Owo +Swindon +Myeik +Cabo Frio +Kichha +Longjiang +Katri +Korolëv +Sarıçam +Guéckédou +Neyshābūr +Sousse +Tabora +Sóc Trăng +Dagarua +Deltona +Tchaourou +Rufisque +San Bernardino +Duekoué +Gainesville +Sambhal +San Felipe +Sāveh +Mainz +Santa Luzia +Chí Linh +La Vega +Singrauliya +El Jadid +Kremenchuk +Ashdod +Prizren +Spring Valley +Thatta +Yenişehir +Al Khubar +Osisioma +Tacoma +Tuluá +Zanzibar +Kafue +Konibodom +Petrel +Messina +Pangkalpinang +Roanoke +Bitung +Santo Tomas +San Miguel +Sabadell +Lübeck +Cartagena +Naihāti +Arakawa +Galaţi +Babylon +Laâyoune +Butembo +Oviedo +Tapachula +Porbandar +São Leopoldo +Apapa +Netanya +Qostanay +Alor Setar +Wayaobu +Zielona Góra +Batu +Gujiao +José C. Paz +Yamunānagar +Banjarbaru +Valencia +Ayacucho +Wellington +Peñalolén +Dongxing +Lutsk +La Ceiba +Ar Ruseris +Hortolândia +Pallāvaram +Marg‘ilon +Jiutepec +Brownsville +Tân An +Golmud +San Rafael +Sidi Aïssa +Khargone +As Samāwah +Maţraḩ +Comalcalco +Cúa +Almere +Vantaa +Mokpo +La Victoria +Warnes +Cascais +Çiğli +Marcory +Chilas +Sikasso +Osan +Oakville +Secunderābād +Sa Đéc +Turbat +El Tigre +Bhuj +Sodo +Isesaki +Jerez de la Frontera +College Station +Norwich +Częstochowa +Monghyr +Luton +Chāpra +Sidi Bel Abbès +Zhubei +Tumaco +Trondheim +Mallawī +Kure +Kuje +Bhadrāvati +Taitō +‘Aqrah +Cao Lãnh +Guadalupe +Mytishchi +Xigujing +Irákleio +Criciúma +Panchkula +Mirpur Bhtoro +Burhānpur +Olympia +Oberhausen +Burgas +Sobral +Clarksville +Trece Martires City +Gangneung +Pagadian +Quilicura +Kirātot +Linz +Arroyo Naranjo +Bukit Mertajam +Dongning +Richmond +Rostock +Kāpra +Pskov +Yonkers +Burutu +Móstoles +Moreno Valley +Thousand Oaks +Legazpi City +Portland +Fontana +Panabo +Puerto Cabello +Ich’ŏn +Beersheba +Bila Tserkva +Santo Agostinho +Oulu +Luziânia +Ciputat +Guarenas +Mohammedia +Babruysk +Taisheng +Sunyani +Lubuklinggau +Ashaiman +Ambāla +Zamora +Chungju +Kasangati +Kharagpur +Farshūţ +Monywa +Nishitōkyō +Robertsonpet +Lyubertsy +Dindigul +Toledo +Milton Keynes +Marawi City +Morogoro +Rānīwāra Kalān +Solihull +Parakou +Damietta +Shimla +Padova +Banjar +Cidade de Nacala +Passo Fundo +Dinājpur +Hospet +Islington +Talca +Hickory +Amarillo +Ifakara +Pamplona +Northcote +Māldah +San Carlos City +Jiutai +Phan Thiết +Puqi +Khān Yūnis +Ongole +Córdoba +Brahmanpara +Biskra +Bingerville +Betigeri +Sioux Falls +Mpanda +Ternate +Kassel +Sakākā +Sejong +Quetzaltenango +Coquimbo +Tekirdağ +Luzhang +Kodumur +Kukawa +Geneva +Huntington +Ellore +Evansville +Kinh Môn +Bīrjand +Santa Ana +Barrancabermeja +La Guaira +Loja +Mandi Burewala +Lauro de Freitas +Mazabuka +Deoghar +Tanjungpinang +Phủ Từ Sơn +Huntington +Chhindwāra +Iringa +Lingampalli +Waterbury +Mokameh +Luxor +Arica +Las Tunas +Qal‘at Bīshah +Frisco +Hà Tĩnh +Richmond Hill +Timayy al Imdīd +Al Khums +Charleroi +Lorain +Matsue +Tarakan +Loures +Pingzhen +Radom +Petropavl +Rio Claro +Maroua +Cajamarca +Qinā +Mai’Adua +Hebron +Puri +Şidfā +Soio +Menemen +Kalamazoo +Haldia +Jacobabad +Khandwa +Aberdeen +Biysk +Huacho +Almería +Yachiyo +Nandyāl +Pulimaddi +Georgetown +Morena +Galveston +Nasīm Shahr +Cosenza +Guacara +Kabankalan +Nagareyama +Araçatuba +Vĩnh Long +Lạng Sơn +Az Zāwīyah +Isanlu +Río Cuarto +Lochau +Karjat +At Tājī +Spartanburg +Lahad Datu +Drabar +Madiun +Santa Tecla +Santa Barbara +Pristina +Uripa +Khowy +Gbadolite +Huangyan +Laqţah +Amroha +Lunga-Lunga +Trieste +Sunrise Manor +Toruń +Martapura +Rānī +Kankan +Chakradharpur +Helong +Segamat +Bhiwāni +Bhind +Huntington Beach +Hobart +Tocuyito +Baure +Higashi-Hiroshima +Maricá +Grand Prairie +Ciudad Madero +Itami +Zākhū +Kodaira +Rajin +Alcalá de Henares +Parma +Overland Park +Huánuco +Kusŏng +Brescia +Zipaquirá +Khammam +Kouribga +McKinney +Madhyamgram +Sinop +Kajo Kaji +Viranşehir +Ghāndīnagar +Rzeszów +Prato +Waco +Acarigua +Myawadi +Mwene-Ditu +Karaköprü +Parachinar +Koronadal +La Serena +Maharagama +San Pedro de Macorís +Liège +Hagerstown +Suzuka +Baharampur +Tchitato +Malema +N’Zérékoré +Mbarara +Morbi +Yuzhno-Sakhalinsk +Cuautla +Anseong +Glendale +Guanajuato +Tébessa +Kamirenjaku +Holon +San Fernando +Pingtung +Peterborough +Tanauan +Nampa +Sūhāj +Pāndhurnā +Bené Beraq +Sosnowiec +Būkān +Muş +Fatehpur +Kumagaya +La Plata +Banī Suwayf +Lae +Quelimane +Hyesan +Béni Mellal +Jalapa +Guanare +Kaesŏng +Nossa Senhora do Socorro +Castanhal +Croydon +Ārba Minch’ +Rio Grande +Gorontalo +Florencia +Fianarantsoa +Tsing Yi Town +Yamaguchi +Iwo +Rāe Bareli +Godoy Cruz +Peoria +Ciudad del Carmen +Bago +Damān +Valera +Ouargla +Cedar Rapids +Manzanillo +Malaybalay +Armavir +Vancouver +Isidro Casanova +Chibia +Leganés +Hino +Orai +Shahr-e Kord +Rybinsk +Jhelum +Mahbūbnagar +Prokopyevsk +Pābna +Cap-Haïtien +Nova Friburgo +Saddiqabad +Balakovo +Ngaoundéré +Hagen +Chŏngju +Paradise +Poza Rica de Hidalgo +Murtazābād +Rājendranagar +Las Heras +Odawara +Abū Ghurayb +Anjōmachi +Araure +Donostia +Fuenlabrada +Pinar del Río +Kenema +Digos +El Progreso +Al Ḩasakah +San Francisco de Macorís +Taranto +Prabumulih +Kishiwada +Iquique +Desē +Gharyān +Kecskemét +Numazu +Ratanpur +Bournemouth +Bhusāval +Tottori +Alvorada +Jōetsu +Chaedŏk +Guatire +Chilpancingo +San Diego +Kōfu +Ucu Seles +Calbayog City +Kırıkkale +Burlington +Kielce +Ocala +Itabuna +Kairouan +Klerksdorp +Pasuruan +Bahraigh +Ed Damazin +Suva +Basildon +Getafe +Cachoeiro de Itapemirim +Potsdam +St. John's +Erie +Umreth +Dunhuang +Semnān +Narsingdi +Newport News +Temirtaū +Banja Luka +Ittikara +Yei +Mahesāna +Frederick +Kuchlagh +Murfreesboro +Ferraz de Vasconcelos +Bolu +‘Unayzah +Pak Kret +Seixal +Al Qāmishlī +Padalarang +Modena +Breda +Toyokawa +Vĩnh Châu +Siguiri +Cuango +Rāiganj +San Cristóbal +Fernando de la Mora +Trảng Bàng +Aqtaū +Santa Bárbara d’Oeste +Batāla +Niš +Oradea +Tumpat +Malumfashi +Isiro +Pinrang +Fort Lauderdale +Jaraguá do Sul +Sirsa +Morsi +Donghua +Odense +Nouméa +Dinapore +Sorsogon +Guarapuava +Tambaram +Bethelsdorp +Saarbrücken +Kāraikkudi +Shrīrāmpur +Abakan +Braga +Epe +Aurora +Kelowna +Plzeň +Fardīs +Himatnagar +Kindia +Tachikawa +Tempe +Thanhlyin +Turbo +La Rioja +Guna +Hamm +Nawāda +Cuauhtémoc +Ploieşti +Inisa +Berazategui +Ikot Ekpene +Funtua +Obuase +Toulon +Jaunpur +Mbanza Kongo +Edirne +Longjing +Geelong +Lhokseumawe +Mahād +Madanapalle +Danbury +Palopo +Petarukan +Guri +Singosari +Quảng Yên +Tongjiang +Longjin +Santander de Quilichao +Wadlakonda +Bhachāu +Shivpuri +Caluquembe +Hosa’ina +Tanjungbalai +Buḍhānilkanṭha +Uji +Mongu +Norilsk +Divo +Calabar +Reims +Dosquebradas +Roxas City +Masan +Purwakarta +Sātāra +El Khroub +Tiaret +Cuautitlán +Spring Hill +Njeru +Torbalı +Ilhéus +Al ‘Arīsh +Langsa +Gastonia +Phillaur +Quevedo +Tebingtinggi +Kandi +Nijmegen +Unnāo +Dundo +Meiktila +Salinas +Sītāpur +La Pintana +Ambato +Almada +Riobamba +Kalamboli +Ciudad Valles +Fredericksburg +Maidstone +San Luis Río Colorado +Letpandan +Hamilton +Al Juwayyidah +Cianjur +Ontario +Ar Raḩmānīyah +Wārāseonī +Castellón de la Plana +León +Mauli +Harnaut +Bejaïa +Elk Grove +Biu +Arafat +Rantau Prapat +Krasnogorsk +Catumbela +Shibirghān +El Bosque +Gainesville +Santa María Texmelucan +Matosinhos +Navadwīp +Salatiga +Marāgheh +Kotdwāra +Amadora +Durrës +Chicoloapan +Khapalu +Bodrum +Yangmei +Pīlibhīt +Sīrjān +Narashino +Cary +Curug +Rancho Cucamonga +Kangqiao +Timon +Burgos +Dagupan City +Ludwigshafen +Bắc Giang +Alleppey +Ada +Habaswein +Gliwice +Piedras Negras +Linjiang +Carúpano +Bida +Sakura +Townsville +Oceanside +Cuddalore +Pátra +Basel +Tlemcen +Lubao +Mexico +Gondal +Shāhīn Shahr +Syzran +Deo +Albacete +Fenglu +Keningau +Akhisar +Podgorica +Sherbrooke +Kamakurayama +Hạ Long +Oldenburg +Silchar +Chīrāla +Gadag +Santander +Saint-Étienne +Mang La +Hitachi +Jabālyā +Polomolok +Ongata Rongai +Sacaba +General Mariano Alvarez +Mülheim +Lagos de Moreno +Tiruvannāmalai +Kindu +Kaolack +Bīdar +Baranavichy +San Miguel +Bade +Talhar +Jalālābād +Izumo +Rafaḩ +Bir el Djir +Ait Melloul +Oeiras +Alcorcón +Cazanga +Garden Grove +Kempton Park +Volgodonsk +Lancaster +Al Kūfah +Araguaína +Metro +Nawsari +Surigao +Erciş +Reggio di Calabria +Makurdi +Bảo Lộc +Kohat +Petite Rivière de l’Artibonite +Ussuriysk +Hemet +Pembroke Pines +Ibirité +Hinthada +Nqutu +Escuintla +Fusagasugá +Malāyer +Olsztyn +Tomakomai +Aplahoué +Valsād +Thingangyun +As Suwayq +Métouia +Concepcion +San Luis +Barra Mansa +Cape Coast +Magwe +Panama City +Urayasu +Puerto Montt +Reggio Emilia +Vallejo +Al Marj +Saḩāb +Caluquembe +Medinīpur +Sŏsan +Talas +Minbya +Chūō-ku +Santa Rita +Manchester +Batumi +Bielsko-Biała +Chetumal +Kamensk-Ural’skiy +Nishio +Medford +Damoh +Kalalé +Kroonstad +Toliara +Bayamón +Calabozo +Baliuag +Harīpur +Mahābād +Neyveli +Bordj Bou Arreridj +Mauldin +Karaman +Moratuwa +Francisco Morato +Hŭich’ŏn +Ilford +Kasama +Gondomar +Novocherkassk +Malanville +Bāramūla +Pôrto Seguro +Jamālpur +Ríohacha +Santa Cruz +Catape +Hirosaki +Villa Canales +Malkāpur +Katha +Oyama +Basuo +Jīnd +Angra dos Reis +Phan Rang-Tháp Chàm +Osnabrück +Itapecerica da Serra +Mogok +Fethiye +Itu +Al Qurayyāt +Jutiapa +Palmdale +Zlatoust +Norwich +Chandannagar +Muskegon +Çerkezköy +Linhares +Tiantoujiao +Sampit +Uppsala +Villanueva +Ādoni +Alasandigutta +Tuguegarao +Siirt +Kuytun +Leesburg +Offa +Ipiales +Le Havre +Sudbury +Ratnapura +Niiza +Takaoka +Leverkusen +Kushiro +Iwata +Obihiro +São Caetano do Sul +Sawangan +Béchar +K’ebrī Beyah +Körfez +Singida +Warrington +Udipi +Saqqez +Fyzābād +Kökshetaū +Ebo +Manavgat +Fukang +Idlib +Sawāi Mādhopur +Lajes +Tenāli +Cienfuegos +Petropavlovsk-Kamchatskiy +High Point +Bocoio +Abengourou +Tuscaloosa +Conjeeveram +Hadano +Chillán +Abū Ḩulayfah +Madhubani +Arnhem +Quibala +Proddatūr +Baubau +San Martin Texmelucan de Labastida +Tunja +Teresópolis +San Marcos +Poços de Caldas +Sultānpur Mazra +Visalia +Wāpi +Blida +Sidon +Wau +Tokat +Garissa +Pocheon +Skikda +Muridke +Muzaffargarh +Kebili +San Fernando +Turgutlu +Jizzax +Ungaran +Kyaunggon +Huddersfield +Ube +Bandar-e Māhshahr +Nazilli +Simao +Anaco +Marysville +Gölcük +Haarlem +Boma +Tuxtepec +Sullana +San Andrés Tuxtla +Heidelberg +Darmstadt +Parnaíba +Mukono +Hala +Godhra +Rafsanjān +Sariaya +Multai +Perugia +Nador +Guadalajara +Tema +Zemun +Ndalatando +Salihli +Daule +Rājapālaiyam +Zhanlicun +Pangzawl +Bontang +Jinggang +Ash Shīḩānīyah +Papantla de Olarte +San Miguel del Padrón +Tulancingo +Tacheng +Tân Phú +Naic +Liancheng +General Roca +Zaranj +Al Ghardaqah +Kidapawan +Chittoor +Bragança Paulista +Solingen +Merced +Pindamonhangaba +Hayward +Split +Lafayette +Ziarat +Girón +Miyakonojō +Đồng Hới +Trà Vinh +Khanpur +Ferkessédougou +Southend +Ciudad Acuña +José María Ezeiza +Khōst +Koudougou +Saint-Marc +Ninh Bình +Bingöl +Dhamār +Sivakāsi +Huaycan +San Nicolás de los Arroyos +Osorno +Milagro +Ceyhan +Moga +Ede +Ekibastuz +Barreiras +Enschede +Springfield +Newport +Chirchiq +Dijon +Jijiga +Patos de Minas +Budaun +Ramat Gan +Uttarpāra +Catamarca +La Laguna +Daltonganj +Quipungo +Jequié +Benoni +Macuspana +Zhengding +Aral +Cadiz +Elektrostal +Matsuzaka +Klaipėda +Ōgaki +Corona +Zabrze +Bharūch +Ilagan +Abaetetuba +Guimarães +Ibarra +Paterson +Gojra +Banhā +Mahlaing +Alexandria +Calama +San Miguel +’s-Hertogenbosch +Grenoble +Amersfoort +Erzincan +Regensburg +George +Herne +Bima +Mandi Bahauddin +Châu Đốc +Severodvinsk +Angers +Itapetininga +Xiaping +Caxias +Villeurbanne +Nāblus +Nan Zhuang +Zaanstad +Guaymas +Enfield +Kamina +Molo +Macon +Saharsa +Chaoshan +Kétou +Rio das Ostras +Adzopé +Portmore +Binghamton +Qalyūb +Danao +Marbella +Ghorāhī +Lakewood +Bạc Liêu +Capas +Cẩm Phả +Almetyevsk +Al Miqdādīyah +Vidisha +Pathānkot +Nowgong +Ravenna +Ar Ramthā +Borāzjān +Tigaraksa +Kisi +Esmeraldas +Kansas City +Horad Barysaw +Souk Ahras +Daiwanishi +Chlef +Pandi +Camarajibe +Odessa +El Eulma +Salzburg +Thānesar +Danzao +Camacupa +Kishangarh +Ŭiwang +Hanam +Paderborn +Zango +Brăila +Barrie +Sunnyvale +Saint-Louis +Edremit +Rudarpur +Kitenkela +Tindwāra +Bandırma +Nalgonda +Jinghai +Hitachi-Naka +Lucapa +Neuss +Noda +Santana de Parnaíba +Ambikāpur +Madīnat as Sādis min Uktūbar +Dibrugarh +Singaraja +Moanda +Seogwipo +Palo Negro +New Bedford +Verāval +Mogi Guaçu +Hoeryŏng +Abbotsford +Kırşehir +Tochigi +Betūl Bazār +Andong +Bālurghāt +Bytom +San Jose +Jorhāt +Poblacion +Ixtlahuaca +Salavat +Kariya +Nevşehir +Krishnanagar +Dutse +Newcastle +Ueda +Livorno +Tete +Vĩnh Yên +Bārākpur +Hollywood +Sinpo +Pouso Alegre +Ciudad Choluteca +Hòa Thành +Alagoinhas +Mudon +Amatitlán +Gulu +Gwangyang +South Lyon +Imabari +Kawashiri +Oxford +Bordj el Kiffan +Gò Công +Erdemli +Gonbad-e Kāvūs +Al Manāqil +Shāntipur +Dīla +Hindupur +Araucária +Ipswich +Matanzas +Beāwar +Long Khánh +Bhālswa Jahangirpur +Aş Şuwayḩirah as Sāḩil +Tauranga +Miass +Erode +Escondido +Lake Charles +Dahuaishu +Minglanilla +Manzanillo +Chichicastenango +Đức Phổ +San Jose +Copiapó +Tafeng +Mahmutlu +Büyük Çakırman +Buğdaylı +Eminabad +Kragujevac +Pasadena +Bellevue +Logroño +Delicias +Talcahuano +Piedecuesta +Toledo +Higashimurayama +Ipokia +Jaranwala +Nāngloi Jāt +Joliet +Kukichūō +Badajoz +Champaign +Fengyicun +Shāhrūd +Mzuzu +Valle de Santiago +Đồng Xoài +Valdivia +Gölbaşı +Naogaon +Kashikishi +El Minié +Borj Hammoud +Auchi +Chauk Azam +Yilan +Sievierodonetsk +Urganch +Ocumare del Tuy +Willemstad +Bávaro +Soro +Pénjamo +Santa Rita +Mariveles +Pomona +Saumlaki +Villa de Álvarez +Lévis +Fairfield +Asaba +Kerch +Concordia +Mesquite +Lashio +Elkhart +Bohicon +Harrow +Rimini +Port Louis +Ağrı +Naperville +Maīmanah +Musashino +Kastamonu +St. George +Sagay +Roseville +‘Ajlūn +Marvdasht +Melitopol +Potchefstroom +Coquitlam +Nek’emtē +Xianshuigu +Nūzvīd +Abbottabad +Santiago +Lárisa +Ramapo +Coro +Sayama +Taza +Jean-Rabel +Al ‘Aqabah +Dundee +Sitārganj +Dongguazhen +Topeka +Al Ḩawīyah +Cagliari +Nîmes +Lüleburgaz +Consolacion +Maridi +Quilpué +Rafael Castillo +Zhangaözen +Nchelenge +Szombathely +Kutaisi +Komaki +Kiambu +Siem Reap +Orekhovo-Borisovo Yuzhnoye +Hājīpur +Pesquería +Kopeysk +Mati +Aix-en-Provence +Malakal +Chingola +Milas +La Lisa +Burlington +Kafr ash Shaykh +Tipitapa +Clermont-Ferrand +Hưng Yên +Tama +Dongsheng +Hābra +Yonago +Kramatorsk +Pageralam +Kalemie +Colima +Dawei +Maquela do Zombo +Wamba +Warner Robins +Cairns +Xinjing +Cam Ranh +Bīr +Florencio Varela +Odintsovo +Keren +Dar‘ā +West Bromwich +Derince +Gandajika +Colina +Dadu +Pleiku +Amreli +Taungdwingyi +Nārnaul +Jyväskylä +Chitaldrug +Pyatigorsk +Calapan +Calapan +Franco da Rocha +Mostaganem +Paço do Lumiar +Etah +Baní +Surprise +Gloucester +Qūchān +Vila Junqueiro +Torrance +Ereğli +Foggia +Iruma +Abohar +Thanatpin +Miskolc +Bhāndāria +Teixeira de Freitas +Villa de Cura +Facatativá +Arad +Fujita +Le Mans +Kisaran +Khairpur Mir’s +Bukoba +Kaithal +Arayat +Poole +Comayagua +Yima +Moshi +Saguenay +Urdaneta +Boca del Rio +Odivelas +Xintang +Barranca +Balasore +Guelph +Zhaxi +Mehtar Lām +Al Mukallā +Kolomna +Dar Naim +Cinere +Pinetown +Salamanca +Asaka +Ramu +Mallapalli +Santa Maria +Kakamigahara +Aalborg +Koiridih +Ciego de Ávila +Bandundu +Disūq +Calabayan +Coimbra +Ghaznī +Zhaoxiang +Ruse +Touggourt +Shillong +Athens +Houma +Cizre +Malasiqui +Lleida +Sannār +Los Ángeles +Rewāri +Paghmān +Birkenhead +Jinjiang +Tinipuka +Cartago +Ashikaga +Stara Zagora +Telford +Nakhodka +Columbia +Huelva +Garanhuns +Hazāribāgh +Moundou +Trindade +Nizip +Nawābganj +Toda +Fullerton +Lichinga +Settat +Bafra +Bhīmavaram +Negombo +Olathe +Okinawa +Namacunde +Boca Chica +Altay +Bahawalnagar +Misato +Olmaliq +Moriguchi +Preston +Thornton +York +Mandsaur +Jahrom +Bondoukou +Lausanne +Bocaue +Khuzdar +Tepatitlán de Morelos +Pemba +Elbistan +Bilbays +Berezniki +Piteşti +Gweru +Khasavyurt +Tân Châu +Numan +Kamālshahr +Rize +Subang +Villupuram +Ingolstadt +Las Maravillas +Greeley +Tabaco +Fukayachō +Beaumont +Nsele +Las Cruces +Porac +Mejicanos +Krugersdorp +Middlesbrough +Shizhaobi +Paranaguá +Sāmarrā’ +Iguala de la Independencia +Ozamiz City +Harchandpur +Yaritagua +Midland +Kumbakonam +Metairie +Torbat-e Ḩeydarīyeh +Xiangcheng +Batu Pahat +Nāḩiyat Ghammās +Peristéri +Darwin +Reykjavík +Atbara +Kanasín +Giá Rai +Payatas +Debre Birhan +La Romana +Aul +Brest +Masaya +Malambo +Rubtsovsk +Momostenango +Pakpattan +Botucatu +Jicheon +Tanay +Blackpool +Carolina +Trois-Rivières +Balneário de Camboriú +Maykop +Balkanabat +Dos Hermanas +Apeldoorn +Pantanal +West Valley City +Ishizaki +Çarşamba +Kuwana +Orange +Warren +Gemena +Sancti Spíritus +Whitby +Cambridge +Kolār +Grand Junction +Médéa +Teluknaga +Tarragona +Koga +Dipolog +Dabou +Tsuchiura +Tyler +Jacmel +Chicacole +Montero +Koutiala +Shūnan +Candelaria +Silivri +Mthatha +Gaziemir +Brusque +Tours +Iğdır +Kovrov +Gunungsitoli +Negage +Pasadena +Teófilo Otoni +La Trinidad +Bānkura +Mandya +Palhoça +Norrköping +Jolo +Kusatsu +Cunduacán +Dehri +Hampton +Sinfra +Myebon +Atibaia +Quillacollo +Medina Estates +Stockport +Kanata +Rangkasbitung +Porto Amboim +Minō +Durgauti +Curicó +Vila Franca de Xira +Igboho +Gingoog +Phủ Lý +Marīvān +Huehuetenango +Barrechid +San Justo +Shizuishan +Mainpuri +Nasugbu +Bloomington +Quimbele +Varginha +Port-Gentil +Carcar +Qabr as Sitt +Chech’ŏn +Campo Largo +San José del Cabo +Cachoeirinha +Termiz +Zinacantepec +Batang +Bacău +Norzagaray +Yaizu +Talaivāsal +Kisarazu +Ağcabədi +Birgañj +Dīsa +Tobruk +Elizabeth +Ebina +Floridablanca +Gitega +Rionegro +Stamford +Nkongsamba +Yuma +Raigarh +Yalova +Maia +Ituzaingó +Tây Ninh +Kigoma +Kent +Miramar +Andīmeshk +Tizi Ouzou +Agboville +Siwān +Maldonado +Ipetumodu +Shahreẕā +Zābol +Inazawa +Caraguatatuba +Pyay +Silopi +Djakotomé +El Oued +Mörön +Bern +Coeur d'Alene +Ashqelon +Minoo +Mabacun +Laghouat +Salto +Sibiu +Brighton +Zafarwal +Londuimbali +Cametá +Vitória de Santo Antão +Dumaguete City +Navoiy +Marianao +Sale +Luuq +Ba Đồn +Gubeng +Daraga +Veszprém +Lakewood +Famalicão +Debre Mark’os +Tiraspol +Coral Springs +Ruda Śląska +Rybnik +Idfū +Tokha +Sterling Heights +Kalol +San Andres +Marituba +Amiens +Yunxian Chengguanzhen +Ferfer +Renca +Ségou +Jaú +Tando Allahyar +Thandwe +Hagonoy +Hassan +Batu Gajah +Matagalpa +Lalitpur +Conchalí +Santa Cruz do Sul +Long Bình +Pitalito +Bibémi +Naga +Porto-Novo +Uppsala +Yuba City +Khorramshahr +Tarime +Crato +Male +Parla +Milton +M’Sila +Srīpur +Kipushi +Gondiā +Zhangmu Touwei +Schaarbeek +Luxembourg +Reẖovot +San Carlos +São Mateus +Dalūpura +Mogaung +Ödemiş +Kingston +San Luis +Centro Habana +Zagnanado +Isahaya +Yakima +Adonara +Talavera +Rustavi +Carrollton +San Juan +Āwarē +Naryāi ka Puri +Blitar +Racine +Karabük +Palwal +Ōme +Chicomba +Johnson City +Annecy +Papeete +Cubatão +Conselheiro Lafaiete +Ji-Paraná +Al Khmissat +Billings +Jijel +Fürth +Buea +Apopa +Itapipoca +Spanish Town +Lam Tin +Pālghāt +Atyraū +Araras +Maijdi +Kuşadası +Vlorë +Quibdó +Marand +Bassila +Thaton +Zama +Chittandikavundanūr +Iowa City +Nanqiaotou +Shuangcheng +Surat Thani +Narita +Lào Cai +Trinidad +Innsbruck +Kozan +Angono +Silay +Ānand +Jīroft +City of Isabela +Nantou +Los Guayos +Inezgane +Arcahaie +Botād +Abiko +Tabarre +Udon Thani +Baiyashi +Lincoln +Mojokerto +Dover +Onomichi +Lucheng +Apucarana +Jamundí +Ergani +Relizane +Polokwane +Aaley +Cili +Battambang +Taldyqorghan +Huejutla de Reyes +Bongaigaon +Bellingham +Mukeriān +Zwolle +Girardot +Vespasiano +Limoges +Charleston +Ponnagyun +Sukrah +Araruama +Çayırova +Hanumāngarh +Jetpur +Arcot +Kokubunji +Amherst +Kānchrāpāra +Parepare +Ciénaga +Sabará +Chinguar +Ferrara +Antsiranana +Tottenham +Mansa +Jamaame +Petapa +Mataró +Cholula de Rivadabia +Idanre +Bamban +Harar +Sarhari +Guadalajara de Buga +Dörtyol +Ulm +Bragança +Mubi +Guagua +Lynchburg +Songnim +Bat Yam +Kislovodsk +Ōsaki +Santo Tomas +Västerås +Puno +Hoshangābād +Táriba +Fengcheng +Saïda +Rosario +Heilbronn +Chās +Apatzingan de la Constitucion +Tuaran +Rudnyy +Nefteyugansk +Khanna +Ahmadpur East +Wazirabad +Santa Clara +Avrankou +Vihari +Guasdualito +Mosquera +Dongsheng +Garut +Votorantim +Buôn Hồ +Abaji +Salmās +Domodedovo +Pforzheim +Edremit +Würzburg +Jāzān +Norman +Santa Lucía Cotzumalguapa +Guimba +Greenville +Simi Valley +Latina +Zhaozhou +Dessalines +San Ignacio +Ciudad Sandino +Allada +Iwakuni +Nagda +Bam +Opole +Kayes +Koforidua +Seto +Ōmiyachō +Missérété +Koganei +Salerno +Torrejón de Ardoz +Saidpur +Nāḩiyat Khān Banī Sa‘d +Angren +Pakokku +Leiria +Sertãozinho +Hardoī +Ñemby +Neftekamsk +Kamëz +Bataysk +Santa Cruz +Ünye +Fuyuan +Duitama +Gurabo al Medio +Ajax +Barcarena Nova +Catabola +Novocheboksarsk +Ksar El Kebir +Örebro +My Drarga +Fort Smith +Suhum +Jandira +Abilene +San Juan +Valinhos +Altamira +Guntakal +Mary +Iizuka +Pithampur +Karatepe +Wolfsburg +Serpukhov +Rosetta +Arecibo +Giresun +Kombolcha +San Fernando +Shchelkovo +Payakumbuh +Pātan +Bonao +Barbacena +Cam Ranh +Zoetermeer +Basīrhat +Resende +Nzega +Villa Alemana +Gashua +Polatlı +Lewisville +Larache +Kristiansand +Az Zulfī +Jilib +Cerro +Hālīsahar +Magelang +Jagādhri +Tychy +Salto +Juticalpa +Novomoskovsk +Jizhou +Leuwiliang +Koidu +Guarapari +Pinsk +Sunām +Ouahigouya +Rishra +Grand-Bassam +Jhārsugra +Leeuwarden +Pearland +Bến Tre +Lehigh Acres +Glazoué +Panevėžys +Chinautla +New Mirpur +Serik +Chía +Kenosha +Noksan +Bajos de Haina +Magalang +Exeter +Bimbo +Pāli +Leiden +Kadirli +Fugu +Savannakhet +Khrustalnyi +Kaspiysk +Magangué +Cambridge +Kirishima +Cai Lậy +Maicao +Pobé +Derbent +Giugliano in Campania +Pervouralsk +Algeciras +Paleng +Santa Cruz +Akçaabat +Djidja +Dūmā +Longtian +Seaside +Punta Arenas +Itaituba +Burlington +Três Lagoas +Nāndgaon +Orizaba +Bento Gonçalves +Honmachi +Baraki +Arvada +Alwāl +Gapan +Kaya +Ed Damer +Munch’ŏn +Gexianzhuang +Kilifi +Zacatecas +Romford +Dimāpur +Patnos +Shiyan +Pati +Kâhta +Yuanlin +Bayawan +Machiques +Hoima +San Pedro Garza García +Bayan Lepas +Ciudad Hidalgo +Behbahān +Itatiba +Cagua +Barretos +Ise +Puerto Cortés +Maina +Indramayu +Cherkessk +Tam Kỳ +Uruma +Sarangāpuram +Mufulira +Waldorf +Ereğli +Independence +Ciudad Ojeda +Bhadrakh +León +Gyumri +Dharmavaram +Rochester +Colchester +Monza +Sivaganga +Chinandega +Hội An +Logan +Farīdpur +Springs +Dorūd +Kashiwara +Kuopio +Ondjiva +Alberton +Temperley +Harlingen +Waterloo +Dordrecht +Kamalia +Berkeley +Tsuruoka +Lianhe +Ar Rass +Hòa Bình +Doğubayazıt +Port-de-Paix +Upington +Wuling +Samandağ +Chơn Thành +Puruliya +Mīt Ghamr +Tabuk +Kırıkhan +Sassari +Ghazīpur +Ch’ungmu +Apartadó +Tumen +Thành Phố Uông Bí +Jīma +Genhe +Navojoa +Porlamar +Anderlecht +Metz +Winterveld +Renala Khurd +Chilapa de Álvarez +Coatepeque +Bagaha +Gudiyāttam +Mahuva +Catchiungo +Fier +Clovis +Kotamobagu +Gurdāspur +Kỳ Anh +Kot Addu +Round Rock +Barcelos +Pueblo +Ramos Mejía +High Wycombe +Gemlik +Temple +Söke +Khurda +Delgado +Poblacion +Kandy +Ban Bang Pu Mai +Gateshead +Guelma +Unwana +Ar Rustāq +San Carlos +Baraka +Ghardaïa +Nokha +Jandrapeta +Hengken +Đông Hòa +Gorzów Wielkopolski +Terrebonne +Lalo +Pelabuhanratu +Yelahanka +Meridian +Malindi +Almirante Tamandaré +Ebetsu +Boulogne-Billancourt +Moncton +Yüksekova +Palma Soriano +An +Jiangna +Perpignan +Pleven +Fulgāzi +Bergamo +Shuixi +Sanxi +Naz̧arābād +Candaba +Parow +Tizayuca +Moḩammad Shahr +Silifke +Port Dickson +Besançon +Debre Tabor +Arapongas +Guaratinguetá +Slough +Aw Dheegle +Ţūz Khūrmātū +Birigui +Totonicapán +Göttingen +Huaraz +Daitōchō +Darjeeling +Piraquara +Bet Shemesh +Bismil +Vihiga +Pescara +Miramar +Sopur +Nowshera +Duluth +Bandar-e Anzalī +Bruges +Yongqing +Calumpit +Bwana Mkubwa +Butwāl +Senador Canedo +The Woodlands +Chikmagalūr +Matamoros +Kadoma +Guelmim +Orekhovo-Zuyevo +Yangliuqing +Xuqiaocun +Soasio +Kampong Cham +Dinalupihan +Malita +Niğde +Gudivāda +Bama +Lahti +Bottrop +Quyang +Ilobu +Ligao +Boulder +Richardson +Trento +Nouadhibou +Dongsheng +Blackburn +Cambridge +Phagwāra +Bagé +Nazran +Aizuwakamatsu +Lodhran +Tahoua +Matsubara +Araguari +Gogounou +Agadez +Pudukkottai +Saanich +Nobeoka +Charallave +Uribia +West Palm Beach +Luanshya +Banyuwangi +Reutlingen +Handa +Kabwe +La Asunción +Salmān Bāk +Catacamas +Tangjin +Midsayap +Port Arthur +Heroica Guaymas +Munūf +East Los Angeles +Uruguaiana +Banfora +Harshin +Adilābād +Redding +Apalit +Yulu +Umuarama +Alcobendas +Cassongue +Clearwater +Fāqūs +Dąbrowa Górnicza +Monroe +Kapaklı +Baripāda +Soreang +Kōnosu +Samal +Datu Odin Sinsuat +Utica +Manpo +Nevinnomyssk +Tatuí +St. Cloud +Mandeville +Chimaltenango +Orléans +La Granja +Erlangen +Yavatmāl +Titāgarh +Ikoma +Lira +Honchō +Barnāla +Cheltenham +Forlì +Chittaurgarh +West Jordan +Xai-Xai +Gabès +Tecomán +Boké +Coronel +Narasaraopet +Siracusa +Himamaylan +Ocaña +Ballarat +Ādīgrat +Dharān +Smithtown +Fatsa +Temixco +Bongao +Ramenskoye +Aïn Beïda +Dimitrovgrad +Karatsu +Nagahama +Târgu-Mureş +Sogamoso +San Tung Chung Hang +Kyzyl +Beppu +Adjaouèrè +Ra’s al Khaymah +Valle de La Pascua +Urasoe +São Gonçalo do Amarante +Sri Jayewardenepura Kotte +Catanduva +Várzea Paulista +North Charleston +San Ildefonso +Linköping +Formosa +Tarogong +Richmond +Nasushiobara +Nusaybin +Pedro Juan Caballero +Ribeirão Pires +Sandvika +Westminster +Bremerhaven +Uzhhorod +Saginaw +Kōenchō +Kovilpatti +Ar Rumaythah +Kasese +Bijnor +Chelmsford +Los Baños +Puerto Madryn +Koblenz +El Pueblito +Kailua +Sliven +Elbląg +Igarassu +Guanabacoa +Aihua +Mendoza +Al Muḑaybī +Obninsk +Swabi +Ciudad Guzmán +Tlapacoyan +Bu’aale +Turbaco +Niihama +Al Manşūrah +Brandon +Amasya +Ponce +Rawajaya +Rawasari +Sano +Dam Dam +Las Delicias +Carlsbad +Lowell +Qiaotou +Hatsukaichi +Bijeljina +Maghnia +Płock +Shacheng +Sach’on +Thimphu +Ariana +Iriga City +Borås +Simões Filho +Plaridel +Catalão +Jaramānā +Kaikkudi +Codó +Yŏju +Broken Arrow +Ambovombe +Sakété +Elgin +Alphen aan den Rijn +Lugazi +Machakos +Rouen +San Juan +Bintulu +Petržalka +Matéri +Kakegawa +Saint-Denis +Oktyabr’skiy +Zhijiang +Kuningan +Helsingborg +Quilengues +Tawau +Poá +Sakiet ed Daier +Īrānshahr +Ifanhim +Euriápolis +Ndali +Gresham +Pul-e Khumrī +Fujimino +Comitán +League City +Mungo +Guiguinto +Midyat +Itabira +Sa-ch’on +Bukittinggi +Sātkhira +Novyy Urengoy +Manolo Fortich +Sloviansk +Akçakale +Hikone +Mangaldan +Hōfu +Mostar +Tōkai +Yessentuki +Downey +Sokodé +Libmanan +Hosan +San Carlos de Bariloche +Paulo Afonso +Tecpán Guatemala +Kazo +Jönköping +Bergisch Gladbach +Tayabas +Remscheid +Carora +Lomas de Zamora +Balāngīr +Shegaon +Macul +Ōshū +Nkayi +Higashiōmi +Otaru +Ciudad de la Costa +Badin +Kisii +Santa Lucía +Goth Tando Sumro +Waterloo +Shkodër +Madrid +Kaposvár +Mahāsamund +Trier +Rājpura +Hezuo +La Libertad +Pochuta +Dassa-Zoumé +Akishima +Bāgalkot +Osmānābād +Estelí +Paarl +Kouandé +Kaliānpur +Shujālpur +Sāhibganj +Passos +Subic +Murrieta +Jaén +Fujimi +Leominster +Longview +Baybay +Jacksonville +Ichinoseki +Cádiz +Pompano Beach +Colatina +Bou Saada +Bou Saâda +Bend +Alkmaar +Recklinghausen +Mawanella +Daet +Nova Lima +Araxá +Laoag +Miami Gardens +Chilón +Chiquimula +Sabara Bangou +Costa Mesa +Baleraja +Montreuil +Villa Mercedes +Sioux City +Ghotki +Jawhar +Santamesa +Kasempa +Champdani +São Lourenço da Mata +Ḩaraḑ +Jena +Gafsa +Ariquemes +Kasuga +Kamyshin +Nsukka +Kintampo +Nandurbar +Purwa Utar +Tuzla +Kaiyun +Namur +Khushab +Everett +Puerto Barrios +Fasā +Rosario +Gilroy +Kiffa +Al Aḩad al Masāriḩah +As Salamīyah +Sorriso +Franceville +San Antonio Enchisi +Quíbor +Socopó +Ahuachapán +Manzini +Masindi +Muktsar +Martínez de la Torre +San Buenaventura +Changbang +Empangeni +Ferozepore +Bāneh +Itele +Rochdale +Jeonghae +Shirayamamachi +Temecula +Tubarão +Sugar Land +Ōmuta +Chico +Msaken +Tinaquillo +Bridgetown +Wythenshawe +Mancherāl +Qal‘at Sukkar +Pisco +Retalhuleu +Bernal +Sutton Coldfield +Vicenza +Doncaster +Winterthur +Dali +Rotherham +Dera Ismail Khan +Esteban Echeverría +Quezon +Aguachica +Naujan +Glan +Bayugan +Eau Claire +Brovary +Gualeguaychú +Delft +Walthamstow +Drammen +Medenine +Nkpor +Kamagaya +Tacurong +Malacatán +Taoyang +Béja +Yŏngju +Labo +Sandachō +Berkane +Sầm Sơn +White Rock +Marugame +Tangjia +Sehore +Murom +Soma +Handeni +Balombo +Talisay +Taitung +Bangaon +Dolgoprudnyy +Thunder Bay +Pulilan +Maxixe +Kasserine +Bagu Na Mohra +Maţrūḩ +Baia Mare +Shihuajie +Tondabayashichō +Bà Rịa +El Monte +Witbank +Khopoli +Ferizaj +Xishancun +Mascara +Khenchela +Taungoo +Móng Cái +Idaho Falls +Melipilla +Komatsu +Islāmābād +Yāsūj +Khardah +Cawayan +Reus +Mopti +Delta +Dearborn +Toowoomba +Mungeli +Bloomington +Alto Hospicio +Habikino +Novoshakhtinsk +Maramag +Yevpatoriia +Caen +Nantang +West Covina +Tādpatri +Birnin Kebbi +Acharnés +Yilong +Sarh +Sparks +Mudanya +An Nuhūd +Žilina +Zhukovskiy +Itumbiara +Rijeka +Douliu +Seversk +South Fulton +Baía Farta +Mazhang +Castelar +Villa Krause +Balsas +Lingayen +Centennial +Labé +Gharbara +Chaman +Sultānpur +Joyabaj +Umm Qaşr +Kogon Shahri +Kawit +Kotmale +Mineshita +Shikohābād +Morales +Liberec +Santana +Shinyanga +Basingstoke +Jalpāiguri +Manokwari +Shāmli +Argenteuil +Sandy Springs +Wa +Cambé +Bhilai Karanja +Chongshan +Ilebo +La Gi +Ejido +Emmen +Edison +Reutov +Banté +Luján +Bagong Silangan +Noyabrsk +Yopal +Erdenet +Inglewood +Suriāpet +Kalmunai +Tajimi +Chābahār +Artëm +Tenggarong +Maipú +Hillsboro +Columbia +Crawley +Açailandia +Roquetas de Mar +As Safīrah +Wardha +La Banda +Catbalogan +Htison +Rānībennur +Burbank +Longjiang +Terni +Mulhouse +Nakhon Si Thammarat +Berdiansk +Toufen +Kŭlob +Kemalpaşa +Ad Dakhla +Tiaong +Tarnów +Carmona +Dagenham +El Limón +Barnoi +Bolzano +Raba +Mingəçevir +Sītāmarhi +Lokossa +Nanaimo +Sơn La +São Pedro da Aldeia +Contramaestre +Khanty-Mansiysk +Bình Hòa +Atebubu +Koszalin +Idkū +Granada +Lo Barnechea +Davie +Kishanganj +Sông Cầu +Temoaya +Kiryū +Jataí +El Cajon +Erechim +Tikrīt +Hindaun +Azare +Semāri +Jurupa Valley +Lerma +Tarīm +Nova Serrana +Japeri +Paragominas +Gangāwati +Bình Long +Pushkino +Maluñgun +Allen +Šabac +Charsadda +Alchevsk +Robāţ Karīm +Auburn +Renton +Nautanwa +Mazyr +Xiva +Moers +Achinsk +Ash Shaykh ‘Uthmān +Lagarto +Jamālpur +Kongolo +Mityana +Bulan +Yozgat +Texcoco +Nikopol +Alaşehir +Holland +Sultan Kudarat +Maranguape +Ndjamba +Makrāna +Al Fāw +Jincheng +Planaltina +Sheopur +Kandhkot +Pergamino +Tagbilaran City +Los Minas +Parral +Lavras +Coronel Fabriciano +Brockton +Włocławek +Brantford +Tenancingo +Presidente Franco +Tuyên Quang +Olanchito +Sergiyev Posad +Salzgitter +Masbate +Gödöllő +Ballia +Wałbrzych +Barika +Rio Rancho +Yelets +Girona +Suruç +Šiauliai +Nancy +Ourense +Aquin +Techiman +Chorzów +Tam Điệp +Balanga +San Mateo +Gillingham +Kanoya +Ikeda +Arzamas +Muriaé +Halifax +Tādepallegūdem +Natitingou +Chatham +Ourinhos +Sindangan +Chicoutimi +Bānsbāria +Tula de Allende +Lida +Toride +Salford +Rialto +Ilopango +Masaka +Spokane Valley +Saijō +Charlottesville +Kilinochchi +Bacabal +Menifee +Orsha +Daly City +Uitenhage +Biak +Wigan +Roncaglia +Itacoatiara +Berdsk +Elista +Yunfu +Musoma +Breves +Buzău +Mubende +Francistown +Lower Hutt +Woodbridge +Tanga +Ubá +Hounslow +Bumba +Būndi +Bergama +Chikushino +Patos +Itanhaém +Aracruz +San Rafael +Inzai +Iguatu +Camboriú +Miryang +Tanjungpandan +Santo Antônio de Jesus +Bendigo +Bouskoura +Paniqui +Amarāvati +Parang +Negapatam +Sangju +Santa Rosa +Buxar +Wembley +Caieiras +Telde +Kurichchi +Hinche +Hōyachō +Guihulñgan +Saint Helens +Gürsu +Jirjā +Noginsk +Kheda +Siegen +Tezpur +Wichita Falls +Riverview +Piacenza +Messaad +Sundarnagar +Houzhuang +Gütersloh +Mayarí +Seoni +Ngong +Ban Mangkon +Mustafakemalpaşa +Kāshmar +Bahrain +Aurangābād +Joünié +Ituiutaba +Mositai +Matehuala +Rishīkesh +Simanggang +Yishi +Isehara +Novokuybyshevsk +Shibuya +Şabrātah +Lahān +Aflou +Al Fqih Ben Çalah +Fugangcun +Al Jumayl +Dhangaḍhi̇̄ +Tavşanlı +Norwalk +Worcester +Shūshtar +Tota +Tando Muhammad Khan +Hildesheim +Kapūrthala +Boryeong +Al Ḩajar al Aswad +Olomouc +Zonguldak +Lee's Summit +Dhamtari +Rāneswar +Chishtian +Longmont +‘Ibrī +Vacaville +Nantou +Ōnojō +Brājarājnagar +Eastbourne +Sūjāngarh +Highlands Ranch +Ciudad Río Bravo +Bhadreswar +Pavlohrad +Clarington +Hengnan +Assis +Klagenfurt +Chilakalūrupet +San Luis de la Paz +Hanau +Hikkaduwa +Sungai Penuh +Kingsport +Chaguanas +Jingping +Novara +Kousséri +Aïn Oussera +Deventer +San Vicente de Baracaldo +Kaiserslautern +KwaDukuza +San Tan Valley +Ngã Bảy +Hồng Ngự +Jeypore +Zomba +Daoukro +Santa Cruz +Itaperuna +Oran +Mporokoso +Quincy +Edinburg +Kāranja +Aboisso +Salavan +Xırdalan +Saint-Jérôme +Red Deer +Sakado +Bỉm Sơn +Kefar Sava +Chanwari +Xinhua +Sungailiat +Sittwe +Zheleznogorsk +Concepción del Uruguay +Leer +Cavite City +Playas de Rosarito +Lynn +Ahar +Yên Bái +Weifen +Sur +Port Blair +Nāḩiyat al Iskandarīyah +Kalyani +Masjed Soleymān +Calasiao +Datia +Kamianets-Podilskyi +Itauguá +Torbat-e Jām +Diourbel +Madhavaram +Kawachinagano +Libertad +Shahrisabz +Gangtok +Vaciamadrid +Boconó +San Felipe del Progreso +Chust +Lamitan +Talipao +San Angelo +Sabanalarga +Zelënodol’sk +Pyinmana +Zahlé +Bāmyān +Mbanza-Ngungu +Banzhuangcun +Ra’s Ghārib +Gwelej +Babīlē +Dzolokpuita +Suramāla +Navalyal +Barod +Vāsco Da Gāma +Khambhāliya +Abbigeri +Kundli +Ad Dujayl +Mumias +Luckeesarai +Songea +Pouytenga +Sololá +Mabai +Debre Zeyit +Dunedin +Hesperia +Nabire +Sundsvall +Kadaiyanallūr +Sayaxché +Ciamis +Putatan +Xiongzhou +Urgut Shahri +Fengning +Bowling Green +Shahdadpur +Federal Way +Talara +Menglang +Kani +Cottbus +Tinsukia +Santa Cruz del Quiché +Hualien +Carmel +Bismarck +Campo Mourão +Alaminos +Xiegang +Tellicherry +Jinotega +Itārsi +Izumisano +Thika +Bislig +Abhar +Viseu +Malate +Ginowan +Wakefield +Sakata +Khamīs Mushayţ +Pili +Pickering +Hasilpur +Trincomalee +Riberalta +Morón +Fishers +Kohīma +Sisophon +Tourcoing +Vereeniging +Mīāneh +Heshan +Paoy Paet +Weldiya +Nyeri +Roubaix +Lafayette +Tobolsk +Burzaco +Espejo +Kontagora +Senahú +Khambhāt +Santiago de Compostela +Ixmiquilpan +Caldas Novas +Schwerin +Salihorsk +Reyhanlı +Itoshima +Zárate +Oton +Manacapuru +Sopron +Koytendag +Abreu e Lima +Lorca +Chipata +Lethbridge +Vista +Chikusei +Ancona +Saku +Silvassa +Santa Cruz do Capibaribe +Babahoyo +Lugo +M’lang +Leme +Las Rozas de Madrid +Río Grande +Boca Raton +Moortebeek +Chitose +Bălţi +Smederevo +Rāmnagar +Trelew +Sarapul +Kamloops +Montego Bay +Catarman +Valença +Saint-Jean-sur-Richelieu +Marmaris +Udine +Janakpur +Serov +Nanxicun +St. Augustine +Paulínia +Kambar +Al Jammālīyah +Itaúna +Ipojuca +Quilenda +Gambēla +Kallithéa +Deoni Buzurg +Radès +Mariano Roque Alonso +Hammamet +Aşağıçinik +Beaverton +Votkinsk +Goodyear +San Cugat del Vallés +Tartu +Tsuyama +Isulan +Kallūru +Kōnan +Lajeado +Adjarra +Dongducheon +Portsmouth +Attock Khurd +Nanterre +Fanyang +Yacuiba +Vị Thanh +Pernik +Andria +Pará de Minas +Orem +Worcester +Modi‘in Makkabbim Re‘ut +Ukhta +Munakata +Maribor +Harnai +Didim +Colón +Gävle +Tumbes +Es Senia +Bodināyakkanūr +Quvasoy +Paletwa +Caotun +Tamazunchale +Arauca +Tela +Paraíso +Do Gonbadān +Sumber +Kāzerūn +Francisco Beltrão +Sangolquí +Iida +Votuporanga +Tiddim +Buin +Bab Ezzouar +Oldham +Zhudong +Sunrise +Ōmura +Half Way Tree +Pejë +Wujiaqu +Harihar +České Budějovice +Tomohon +Parintins +Navapolatsk +Osijek +Greece +Corumbá +Arezzo +Cáceres +Vitry-sur-Seine +Doudian +Lysychansk +Escalante +Portsmouth +Itabaiana +Leninsk-Kuznetskiy +Chārīkār +Arden-Arcade +Harran +Lawrence +Muzaffarabad +Bachhraon +Toms River +Hammersmith +Amalner +Balayan +Sardārshahr +Kalisz +Witten +Longkeng +Longquan +Vanderbijlpark +Vilhena +Río Gallegos +Weiyuan +Caseros +Cesena +Tataouine +Dhuliān +Hadera +Arifwala +Sandy +São Cristóvão +Rayleigh +Paramagudi +Zerakpur +Slidell +Tandwa +Shirē +Kamisu +Çubuk +Burdur +Candelaria +Mezhdurechensk +Aliağa +Pesaro +Erbaa +Tiruchengodu +Hương Thủy +Mons +Pedagādi +Oued Zem +Boli +Nagīna +Bogo +Saint-Michel de l’Atalaye +Chākdaha +Shimada +Closepet +Jiantang +Dovzhansk +Birecik +Emmiganūr +Yalamakūru +Balamban +Siguatepeque +Labuan +Naxçıvan +Rawānduz +Yumbo +Vāniyambādi +Al Jīzah +Buckeye +Rubio +Tiruttani +Mianwali +Dongping +Meizichong +Nāḩiyat al Karmah +Moca +Rincón de Romos +Ocotlán +Sibolga +Esslingen +Cereté +Hemel Hempstead +Livonia +San Ramón +San Martín Jilotepeque +Williamsburg +Bouna +Legnica +Kangan +Suffolk +Los Patios +Compton +Lecce +Bath +Behshahr +Lopez +Lingwala +La Crosse +Bhadohi +Kanuma +Gjakovë +Edmond +San Joaquín +Gerona +Carson +Allinagaram +Gatchina +Bayan Hot +Niagara Falls +Villa Luzuriaga +Marmagao +San Marcos +Pingyuanjie +Greenburgh +Shibata +Ludwigsburg +Gießen +Ashiya +Yishui +Yi Xian +Tracy +Paracatu +Herẕliyya +Monkayo +Ponta Porã +Hayes +Rio Largo +San Fernando +Azumino +Prescott Valley +Dhār +Qormi +San José del Rincón Centro +Middletown +Valongo +Alvand +Lingtang +Đông Hà +Menderes +Chiantla +Simeulu +Ziftá +Cape Breton +Al Fujayrah +Sanjō +Mikhaylovsk +Fall River +Gera +Jaén +Mairiporã +Lawang +San Germán +Hradec Králové +Daanbantayan +Sarov +Michurinsk +Monastir +Wangjia +Yashio +Jinbi +Akşehir +Yotsukaidō +Düren +Chilliwack +Santa Cruz Xoxocotlán +Lemery +Indanan +Santa Fe +Râmnicu Vâlcea +Fenggang +Tual +Plantation +Galle +Mayagüez +Itajubá +Kwekwe +Glazov +Darlington +New Braunfels +Sidi Slimane +Créteil +La Marsa +Ubatuba +Ciudad General Belgrano +Rafaela +Wukari +Guaíba +Barra do Piraí +Palimbang +Nisshin +Hanamaki Onsen +Tübingen +Boundiali +La Reina +Magadan +Roswell +Wimbledon +San Sebastián de los Reyes +Tatvan +Kadugli +Akot +Tamanrasset +Helmond +Inagi +Solikamsk +Mtwara +Rongwo +Sablayan +Azua +Naju +Mogi Mirim +Flensburg +Iserlohn +São João da Boa Vista +Oss +Conroe +Barletta +Bedford +South Gate +Errachidia +Tatakan +Sepatan +Kitakami +Serra Talhada +Contai +Santa Barbara +Ōbu +Teziutlan +Santa Monica +Pardubice +Coatepec +La Spezia +São Roque +Voskresensk +Kirkland +Hoover +Kot Kapūra +Ústí nad Labem +Netrakona +Hove +Cruzeiro do Sul +Satsumasendai +Shabqadar +Pato Branco +O'Fallon +Hamilton +Higashi-Matsuyama +Tultepec +Kakamega +Raub +Ţurayf +Southport +Mijas +Ouidah +Goalundo Ghāt +Sinendé +Linquan +Phú Thọ +Maracay +Çaycuma +Niono +Grahamstown +Myingyan +Alafaya +Brossard +Satu Mare +Pīrānshahr +Yao +Samālūţ +Kārwār +Mīzan Teferī +Arzew +Salaman +Māndvi +San Francisco Solano +Tucuruí +Kalamariá +Jauharabad +Kendu Bay +Hilversum +Rāyachoti +Avaré +Pāloncha +Manhuaçu +Caçapava +Xiancun +Palm Coast +Alessandria +Ambohimangakely +Hastings +Norwalk +Agua Prieta +Lawton +Chino +Lachhmangarh Sīkar +Maple Ridge +Miaoli +Mount Pleasant +Velikiye Luki +Tonacatepeque +Grudziądz +Guercif +Solwezi +Cisauk +Caimbambo +Oudtshoorn +Bauan +Pantukan +Pongotan +Rāmagiri Udayagiri +Cambambe +Gwadar +Mengdingjie +Manteca +Funza +Zhezqazghan +Çanakkale +Katiola +Westminster +Biga +Eslāmābād-e Gharb +Chililabombwe +Vanadzor +Fundación +Ponnāni +Sahagún +Arsuz +Jāmtāra +Florence +Joplin +Pinamalayan +Avignon +Orpington +Valjevo +Julu +Pazardzhik +Vezirköprü +Mandurah +Watford +Poitiers +São João del Rei +Yoshiwara +Puerto Padre +Caucasia +Germantown +Peñaflor +Imizuchō +Nasatta +Abomey +Pollāchi +Gjilan +Hendek +Gujar Khan +Jalalpur Jattan +Wajir +Victorias +Marudi +Kāvali +Aubervilliers +Botoşani +Darnah +Möng Tun +Richard-Toll +Afmadow +Barwaaqo +Ma‘arrat an Nu‘mān +Luau +Necochea +Tangjia +Al Badrashayn +Léogâne +El Ejido +Mihara +Compostela +Presidencia Roque Sáenz Peña +Kiselëvsk +Bayt Lāhyā +Patrocínio +El Puerto de Santa María +Itapeva +San Leandro +Olavarría +Dobrich +Stevenage +San José Pinula +Sankeshwar +Kōka +Glyfáda +Serdar +Saquarema +Cantaura +Los Cerrillos +Conda +Cáceres +Cheektowaga +Ţarţūs +Town 'n' Country +Clifton +Waukegan +Kadiri +Tonghae +Zhunan +Ipil +Prijedor +Oulad Teïma +Níkaia +Mestre +Caracase +Surallah +Ciudad de Atlixco +Pistoia +Akyazı +Torrevieja +Pamekasan +Ségbana +Maladzyechna +Bloomington +Léré +Avondale +Maumere +Phusro +Polangui +Banga +Humpata +Kalibo +San Francisco +Atascocita +Kūhdasht +Jalal-Abad +Kairāna +Jaworzno +Kamensk-Shakhtinskiy +Saundatti +Kansk +Shwebo +Hinigaran +Calabanga +As Salţ +Passi +Colombes +Murcia +Bogo +Aalst +Lucca +Missoula +Hemei +Pisa +Wangqing +Viana do Castelo +Danlí +Chiclana de la Frontera +Fort Myers +Montelíbano +Ben Guerir +Toviklin +Chosica +Paingkyon +Villa María +Rāsipuram +Leping +Najībābād +Podujevë +San Luis +Barra do Corda +Bayramaly +Kimje +Bhakkar +Berisso +Bertoua +Newton +La Grita +Solana +Aïn M’Lila +Nirmal +Nirāla +Ootacamund +Echague +Aroroy +Mobara +Ben Arous +Prosperidad +Alabel +Ban Laem Chabang +Grimsby +Lobnya +Villingen-Schwenningen +Jangipur +Jaffna +Janzūr +Leshou +Lawrence +Muncie +Sangrūr +Damaturu +Qiantangcun +Hartlepool +Al Wakrah +Sassandra +Sakai +Newmarket +Jilotepec +Makilala +Wislane +Maiquetía +Mettupālaiyam +Wakiso +Bromley +Jumri Tilaiyā +Rapid City +Guanambi +Jagüey Grande +Baggao +San Juan de los Morros +Aruppukkottai +Farīdkot +Calauan +Ceylanpınar +Ama +Słupsk +Madgaon +Baras +Gitarama +Ende +Koidu-Bulma +Palangotu Adwār +Sakiet ez Zit +Western Bicutan +Chester +Consolación del Sur +Cipolletti +Kpalimé +Changting +Maasin +San Fabian +Şatrovka +Ratingen +Midrand +Denan +Santa Catarina Pinula +Calaca +Caratinga +Jamūī +Middelburg +Camiling +Nahualá +Limpio +Shuangshuicun +Torrente +Chongoroi +Chimbas +Bhola +Bi’r al ‘Abd +Lorena +Dipalpur +Zwickau +Troy +Fulham +Houndé +Livermore +Citrus Heights +Ad Diwem +Norton +Bama +Wulan +Hawthorne +Heyunkeng +Mardin +Kumārapālaiyam +Heerlen +Mechelen +Cacoal +Takasagochō-takasemachi +Binmaley +Lünen +Tangxing +Campana +Paredes +Fukuroi +Widekum +Winchester +Taohuajiang +Longonjo +Dunkerque +Gubkin +Les Cayes +Hānsi +Salinas Victoria +Kattagan +Tiflet +Springdale +Cárdenas +Shahdol +Yoro +Hamakita +Unaí +Clarkstown +Nuneaton +Anakāpalle +Gravatá +Nabua +Tucupita +Novotroitsk +Tuncheng +Whittier +Deerfield Beach +Nīmbāhera +Nakhon Sawan +Yaofeng +Nachchāndupatti +Hassi Bahbah +Loznica +Kalpitiya +Karanganyar +Navegantes +Yabēlo +Santa Rosa Jauregui +Dingcheng +Guasave +Gotenba +Odienné +Ciudad de Melilla +Bangkalan +Bantayan +San Antonio +Decatur +Batticaloa +Seoni Mālwa +Buzuluk +Ibshawāy +Settsu +Silvan +Sārni +Aulnay-sous-Bois +San Ramon +Repentigny +Shchëkino +Bugulma +Toledo +Khowrāsgān +Kitanagoya +Vineland +Shaoshanzhan +Potiskum +Sharūrah +Kameoka +Keffi +Qaraçuxur +Iga +Chiguayante +Cabiao +Konstanz +Kouvola +Vólos +Guinobatan +Kharian +Mission +Bāsoda +Longhua +Taishan Houcun +San Pedro Sacatepéquez +Ducheng +Ādwa +Sekimachi +Maratturai +Auburn +Fuengirola +Redenção +Karakol +Lake Forest +El Bayadh +Mukacheve +Fusui +Xuddur +Karād +Pariaman +Chinnachauku +Batarasa +Lugang +Junín +Shumen +Colonie +Warder +Caldas +Vélez-Málaga +Pori +Mitrovicë +Jinhe +Garulia +Tagaytay +Apaseo el Grande +General Rodríguez +Chiquinquirá +Krishnagiri +Arona +Upper Darby +Dapitan +Takayama +Grand Bourg +Newport Beach +Harda Khās +Gurupi +Maga +Araripina +Monte Chingolo +Jastrzębie-Zdrój +Puerto Maldonado +Mhow +Derry +Santa Inês +Ealing +Walvisbaai +Bahlā’ +Taxila +Hövsan +Luvungi +Korgas +Melbourne +Atakpamé +Woolwich +Longchuan +Brooklyn Park +Karacabey +Baabda +Larnaca +Prešov +Bryan +Sayhāt +Westland +Ílion +Peterborough +Ciudad Mante +Konotop +Pandacan +Chirundu +Túxpam de Rodríguez Cano +Ijuí +Napa +Mohammadia +Catanzaro +Sumenep +Tshilenge +Worms +Pinheiro +Treviso +Mādabā +Khemis Miliana +Yokotemachi +Dhorāji +Rafḩā +Honiara +Ushiku +Tire +Vīrappanchathiram +Baytown +Komae +Santana do Livramento +Sabanalarga +Dmitrov +New Kru Town +Carpina +Kaizuka +Nabunturan +Marl +Suceava +Bais +Villa Altagracia +Science City of Muñoz +Athurugiriya +Higashiyamato +Ayase +Bilwi +Cicero +Chigorodó +Quixadá +Concepción Tutuapa +Wakō +Al Hindīyah +Luancheng +Dārayyā +Sambava +Kitakōriyamachō +Heṭauḍā +Ath Thawrah +Lāharpur +Diphu +Bolinao +Arujá +El Milia +Channapatna +San Baudilio de Llobregat +Chita +Anderson +Keşan +Kineshma +Ermelo +Zheleznogorsk +Xishancun +Acayucan +Lucas do Rio Verde +Dolisie +Bhawānipatna +Pilkhua +Samadiāla +Ho +Haskovo +Yeysk +Franklin +Matão +Barahona +Tiruppattūr +Hamma Bouziane +Versailles +Moriyama +Farmington Hills +Nizwá +Buena Park +Foumban +Talavera de la Reina +Lafey +Galway +Albany +Aylesbury +Atambua +Nazareth +Taytay +Phúc Yên +Reşiţa +La Piedad +Gokulgarh +São Bento do Sul +Serrinha +Maco +Lqoliaa +Pine Hills +Ashford +Sirsilla +Como +State College +Boukoumbé +Habiganj +Lakshmīpur +La Trinidad +Picos +Siaton +Redwood City +Minden +Kampong Trach +San Antonio +Moju +Ciudad de Ceuta +Lelystad +La Lima +San Fernando +Wutiancun +Mingxing +Mazatenango +Mānsa +Mabinay +Busto Arsizio +Nantingcun +David +Al Ḩayy +Louga +Ufeyn +Ji’an +Wadala Sandhuan +Warwick +Jackson +Bayeux +Stockton-on-Tees +Nakatsu +Brindisi +Cranston +Shīrvān +Tanjay +Chingleput +Jacobina +Mian Channun +Manfalūţ +Rivadavia +Rivadavia +Cruzeiro +Chelghoum el Aïd +Bhalwal +Largo +Calatrava +Pontevedra +Wuyi +Chulucanas +El Estor +Edmonton +Velbert +Cukai +Miami Beach +Chaykovskiy +Sabaneta +Oleksandriia +Owariasahi +Shikokuchūō +Alhambra +Kuznetsk +Deurne +Ōmihachiman +Johns Creek +Puerto Iguazú +Nueva Concepción +Macaíba +Uman +Saint Albans +Mountain View +Quixeramobim +Bekobod +Tacaná +Harlow +Carmen +Burnley +Ust’-Ilimsk +Salisbury +Jepara +Redditch +Saunda +Morgantown +Kongjiazhuangcun +Norderstedt +Ashoknagar +Silver Spring +Ubay +Yurga +Bhaktapur +Banco Filipino International Village +Layton +Bilecik +Yıldız +Gürgenpınarı +Uzungöz +Lucerne +Siasi +Concórdia +Watampone +Springfield +Kātoya +An Khê +Paranavaí +Muroran +Timóteo +Apizaco +Hukou +São Sebastião +Courbevoic +Purmerend +Dar el Beïda +Imam Qasim +Lakewood +Kentaū +Remedios de Escalada +Xicotepec de Juárez +Anapa +Fiumicino +Afşin +Shuibian +Kadi +Valdemoro +Chapadinha +Xiedian +Matalam +Kimitsu +Grosseto +Buhi +Athi River +Nowy Sącz +Florence +San José de las Lajas +Pacatuba +Lambunao +Bulacan +Novouralsk +Mannārgudi +Port of Spain +Orhangazi +Hengkou +Itá +Folsom +Kapalong +Salina Cruz +Panzos +Tecate +Balrāmpur +Baalbek +Hengelo +Kashiwazaki +Tallaght +Khamānon Kalān +La Louvière +Launceston +Madera +Dera Allahyar +Gonder +Campo Limpo +Gaoliying Ercun +New Rochelle +Rafaḩ +Ahenkro +Yonezawa +Orihuela +Shiji +Gobernador Gálvez +San Francisco +Malapatan +Balçova +Barili +Wujindian +Meybod +Yanggao +Bargarh +Curvelo +San Cristóbal Verapaz +Comitancillo +Seropédica +Parma +Terre Haute +San Ramón +Bulanık +Samā’il +Dahegām +Torre del Greco +Randfontein +Batley +Somerville +Ādīgala +Azov +Nagaoka +Calandala +Panjgur +Butterworth +Tala +Antehiroka +Oum el Bouaghi +Cabadbaran +Béziers +Tagoloan +Kāmāreddipet +Zuwārah +Bafut +Tākestān +Arni +Echizen +Maravatío de Ocampo +Lívingston +Aquiraz +Kumbo +Bolpur +Peruvancha +Sint-Niklaas +Flagstaff +Taroudannt +Namsan +Gumlā +Simdega +San Andrés Cholula +Qŭnghirot +Cachoeira do Sul +Boynton Beach +Gamagōri +Manmād +Goiana +Rubí +Nabatîyé +Masallātah +Andahuaylas +Kathri +Jamshoro +Khewra +Zarzis +Puerto Ayacucho +San Carlos del Zulia +Koktokay +Piro +Tall ‘Afar +Homestead +Scunthorpe +Polatsk +Newark +Mīt Salsīl +Bamberg +Plymouth +Turhal +Ben Gardane +Sefrou +Kırklareli +Pátzcuaro +San Jose +Drobeta-Turnu Severin +Sokcho +Paco +Kottagūdem +Idah +Marsala +Poblacion +Anniston +Piatra Neamţ +Ciudad Lerdo +Dessau-Rosslau +Tissamaharama +Akiruno +Texarkana +Patikul +Ezpeleta +Banī Mazār +Mahdia +Vila do Conde +Krasnyi Luch +Cianorte +Tustin +Belo Jardim +Neumünster +Xai +Viana +Eséka +Döşemealtı +Robles +San Martín +Torres Vedras +Langarūd +Pharr +Senhor do Bonfim +Afgooye +Klin +Dudley +San Isidro +Port Huron +Iwamizawa +Yenakiieve +Mangatarem +Ban Talat Rangsit +Sorgun +Caçador +Turlock +Owendo +Schiedam +Yalta +Ban Nong Prue +Drummondville +Natori-shi +Kawartha Lakes +Lisala +Évosmos +Juventino Rosas +Ciudad Lázaro Cárdenas +Jaen +Dobni Para +Hannō +Carmen +Rancho Cordova +Gokāk +Ceará-Mirim +The Villages +Tīkamgarh +Ikom +Milpitas +Ozërsk +Būmahen +Ubon Ratchathani +Bahārestān +Arāria +Cuamba +Huaral +Madīnat as Sādāt +Pèrèrè +Alfenas +Sougueur +Nakatsugawa +New Westminster +Tiko +Sesto San Giovanni +Perris +Bistriţa +Manresa +Daugavpils +Upland +Subulussalam +Tambacounda +Dome +Nakhon Pathom +Toboali +Tierralta +Maizuru +Bury +Alton +Eastleigh +Elbasan +Pagbilao +Villa Celina +Ra’s al Khafjī +Pleasanton +Alīgūdarz +Zaandam +Mooka +Arlit +Skarżysko-Kamienna +Dabakala +Curepipe +Dongchuan +Hengbei +Kuvango +Brixton +La Rochelle +Taher +Gyōda +Sahuayo de Morelos +Aveiro +Bauang +Dinga +Iperu +Varese +Kendall +Arkonam +Delmenhorst +Jonesboro +Bandar Emām +Bellflower +Três Rios +Kashiba +Barreiro +Battle Creek +Denov +Pototan +Qorveh +Queluz +Limay +Bamban +Manbij +Pingyi +Southall +Huolu +San Pedro Pinula +Chino Hills +Péhonko +Viersen +Cheyenne +Argao +Rueil-Malmaison +Al Khānkah +Tanashichō +Chitembo +Chitemo +Ilioúpoli +Macabebe +Kropotkin +Lebanon +Carmichael +South Jordan +Kuacjok +Gandía +Faranah +Mandiraja Kulon +Baracoa +Kizugawa +Godāwari̇̄ +Balqash +Colón +Essaouira +Tanuku +Narra +Koch Bihār +Chengbin +Pakxé +Honjō +Toyomamachi-teraike +Fray Bartolomé de Las Casas +Rheine +Hoofddorp +Davis +Marburg +Villa Victoria +Elizabethtown +Linkou +Birkhadem +Kuniyamuttūr +Kortrijk +Kambam +Bir el Ater +Champigny-sur-Marne +Brikama +Ukunda +Huebampo +Hasselt +Bebedouro +Aksu +Nitra +Phuket +Lipjan +Bodhan +Schaumburg +Alameda +Santa Rosa +Zhongcheng +Santa Catalina +Grand-Lahou +Stellenbosch +Hermosa +Fnidq +Mengla +Usol’ye-Sibirskoye +Katano +Hammond +Tsubame +Tirkākara +Vorkuta +Quatre Bornes +Jelenia Góra +Puli +Caxito +Pasco +Latacunga +Bracknell +Ban Tha Khlong +Cozumel +Paisley +Gelendzhik +Pattoki +Harunabad +Roosendaal +Aş Şuwayrah +Bustos +Evanston +Kabacan +Fukuchiyama +Shūsh +Lehi +Alexandria +Chalándri +Keratsíni +Umingan +Pau +Tecamachalco +Guildford +Zhlobin +Talakag +Nikkō +Nabari +Balagtas +Toyooka +Balkh +Estepona +North Port +Bongabong +Nagua +Berbérati +Santo Ângelo +Ébolowa +Valença +Mao +Lüneburg +Baj Baj +Veliko Tarnovo +Arlington Heights +Chatham +Surt +Shostka +Balashov +El Viejo +Usta Muhammad +Camarillo +Pyapon +Wyoming +Dorsten +Prince George +Mafra +E’erguna +Nipāni +Vinhedo +Tacámbaro de Codallos +Ait Ali +Flower Mound +Ivanteyevka +Aira +Caledon +Bethlehem +Cotuí +Alcalá de Guadaira +Tianguá +Daxincun +Dschang +İdil +Virac +Hattiesburg +Trinidad +Loveland +Abéché +Fāzilka +Khemis el Khechna +Funing +Armant +Al Musayyib +Shinkai +Ibiúna +Paysandú +Pittsburg +Kafr az Zayyāt +Crateús +Ninh Hòa +Siedlce +Sasolburg +Melton +Cedar Park +Palencia +Pozzuoli +Shājāpur +So-Awa +Troisdorf +Tuban +Palmerston North +Padre Hurtado +Anzhero-Sudzhensk +Palo +Keshod +Infanta +East Ham +Kadoma +Daisen +Nahāvand +Bender +Wenatchee +Weston-super-Mare +Montepuez +Esteio +Southfield +Kahror Pakka +Lins +Wilhelmshaven +Fancheng +Molina de Segura +San Ramón de la Nueva Orán +Chintāmani +Ryūgasaki +Manaoag +Rochester Hills +Hammond +Banská Bystrica +Merouana +Yanam +Tailai +Toba Tek Singh +Villa Elisa +Valdosta +Houmt Souk +Rulin +Châteauguay +Gladbeck +Catacaos +Kengtung +Ovalle +Solok +Sankt Gallen +Espinal +Benalmádena +Pilar +Surendranagar +Stakhanov +Sentani +Malappuram +Kargilik +Mérignac +Cadereyta Jiménez +Laiyuan +Xaignabouli +Lod +Sidi Qacem +Maghāghah +Arta +Santa Rosa +Sapiranga +Owensboro +Umeå +San Pedro +Arjona +Apple Valley +Jocotán +Aïn Temouchent +Woodbury +Garhi +Cataguases +Avilés +Joensuu +Jablah +Ramla +Três Corações +Landshut +Saint-Maur-des-Fossés +Tindivanam +Carlisle +Srīvilliputtūr +Kiyose +Xinglong +Bhadarwāh +Rānāghāt +Shadrinsk +Cheria +South Shields +Kai +Bonāb +Villa Carlos Paz +Ciudad Real +Ardakān +Cửa Lô +Acacías +Frontera +Itapira +Tissemsilt +Pawtucket +Lagoa Santa +Dongguan +Dhrāngadhra +Kunitachi +Dayr al Balaḩ +Pinamungahan +Antibes +East Kilbride +Teyateyaneng +Aracati +Detmold +Newcastle under Lyme +Mawatagama +Burton upon Trent +Libon +Chernogorsk +Belleville +Telêmaco Borba +St. Joseph +Gangammapeta +Puqiancun +Dubna +Iju +Wisil +Al Muḩarraq +Khejroli +Tirumangalam +Pardigūda +Warabi +Bugallon +Tocumen +Cherry Hill +Panggezhuang +Jaorā +Doral +Gönen +Fouchana +Amakusa +Tura +Ambājogāi +Palencia +Juchitán de Zaragoza +Dabra +Ubud +Sasagawa +Darhan +Darhan +Pozorrubio +Toffo +Tiznit +Esperanza +Tanguiéta +Tosu +Moulay Abdallah +Cotorro +Drohobych +Dalaguete +Piraçununga +Ouro Prêto +Dover +Cinisello Balsamo +Missouri City +Dayong +Bayreuth +Īṭahari̇̄ +Péda-Houéyogbé +Katori +Kandori +Shancheng +Bozüyük +San Antonio de Los Altos +Assab +Gbawe +Skellefteå +Balingasag +Saratoga Springs +Arnsberg +Wandiwāsh +Ouaké +Rāmhormoz +Pocatello +Bongouanou +San Juan Opico +Miki +Oshkosh +Uspantán +Silao +Brick +New Britain +Çınar +Zlín +Izumiōtsu +Canindé +Mankono +Le Kram +Aprilia +Okegawa +Meshgīn Shahr +Al Qā’im +Airdrie +Blagoevgrad +Castle Rock +Chalchuapa +Gūdūr +Yelabuga +Casoria +Pedro Brand +Gravesend +Ra‘ananna +Brookes Point +Tatebayashi +Lauderhill +Kyōtanabe +Kahan +Tatsunochō-tominaga +Majalengka +Broomfield +Sarnia +Dale City +Mineral’nyye Vody +Vlaardingen +Tamworth +Samundri +Dumangas +Alicia +Dĩ An +Yurihonjō +Aïn Oulmene +Cunhinga +Ajaccio +Hāveri +Castrop-Rauxel +Türkoğlu +Beyşehir +Yegoryevsk +Bolingbrook +Redmond +Caguas +El Kef +Gouda +Mansfield +Tefé +Tarn Tāran +Nandi Hills +Birobidzhan +Hoorn +Mangalagiri +João Monlevade +Brandenburg +Linares +Ellicott City +Vriddhāchalam +Harrogate +Copacabana +Cao Bằng +Târgu Jiu +Sheboygan +Xindian +Kallakkurichchi +Irecê +Kasama +El Hamma +Kumluca +Paterna +Bandar-e Genāveh +Tupi +Mansfield +Novoaltaysk +Lala +Kāsipālaiyam +Glens Falls +Troitsk +Asti +Inuyama +Pančevo +Jose Abad Santos +Bagan Si Api-api +Daytona Beach +Reconquista +Quillota +Cannes +Crewe +Lodi +Redlands +Tan-Tan +Fada Ngourma +Ōtawara +Pacajus +Shakargarh +Harrisonburg +Ragusa +Ciudadela +Bula +Pattukkottai +Almelo +Gobindgarh +Nabeul +Edéa +Brakpan +Néa Smýrni +Usulután +Shibukawa +Luján de Cuyo +Moa +Berdychiv +Dothan +Baghlān +Chaigoubu +Santa Rosa de Cabal +Santa Isabel do Pará +Türkmenbaşy +Naqadeh +Çatalca +San Vicente del Caguán +Jinja +Russas +La Dorada +Mackay +Padre Las Casas +Kostiantynivka +Khomeyn +Cleveland +Jōyō +Vsevolozhsk +Tocoa +Jackson +Mount Vernon +Jingzhou +Caserta +Chapayevsk +Paine +San Martín +Catanauan +Spijkenisse +Södertälje +Centreville +Hương Trà +Amparo +Yafran +Lappeenranta +Carles +Cascavel +Sanwal +Rio do Sul +Yukuhashi +Sremska Mitrovica +Gaspar +Mysłowice +Majadahonda +Zhuolu +Lanxi +San Dionisio +Belovo +Esmeraldas +Weligama +Nepālgañj +Siruguppa +Tangalla +Bacacay +Hekinan +Ede +Sipalay +Aschaffenburg +Dazaifu +Samborondón +Longkoucun +Alegrete +Keshan +Candeias +Altoona +Sangāreddi +Benidorm +Zogbodomé +Maroúsi +Wood Buffalo +Dambulla +Goya +Oroquieta +Virudunagar +Abancay +Penafiel +San Fernando +Palín +Turbaná +Yoshikawa +Santo Antônio do Descoberto +El Banco +Warora +Casa Nova +Tibati +Kirovo-Chepetsk +Saint-Nazaire +Sault Ste. Marie +Camalig +Najrān +Belo Tsiribihina +Myaydo +Al Līth +Bella Vista +Bailongqiaocun +Colón +Chaklāsi +Nilanga +Long Mỹ +Borongan +San Andrés +Wenping +Gumaca +Stara Pazova +Bocholt +Araranguá +Esbjerg +Merzifon +Goianira +Chiryū +Čačak +Quilāndi +Carpi +Lüdenscheid +Mun’gyŏng +Ishioka +Jabuticabal +Calauag +Castro +Cajamar +Framingham +Camden +São Sebastião do Paraíso +Bouaflé +Patzún +Georgetown +Vyborg +Kabarore +Sambrial +Piła +Dondo +Shrewsbury +Mānikganj +Baldwin Park +Florida +Rocklin +Porterville +Ágios Dimítrios +Kayes +Calarcá +Tarīn Kōṯ +Bakıxanov +Kawm Umbū +Mandlā +Tamarac +Palmeira dos Índios +Ostend +Saymayl +Indaial +La Estrella +Sonsonate +Pililla +Santo Tirso +Gosport +Parang +Bartın +Dias d’Ávila +Lomas del Mirador +Nanfengcun +Salamá +Biankouma +Lisburn +Rāyadrug +Mamoudzou +Glen Burnie +Halmstad +Le Bardo +Binalbagan +Shahrixon +Bilāra +Villa Tunari +Huanchaco +Campo Formoso +Goa +Drancy +Rāyagada +Blacksburg +Talibon +Las Piedras +Ganthier +Verkhnyaya Pyshma +Jinsha +Parappanangādi +Konongo +Wausau +Sumter +Gela +Placetas +Janesville +Melong +Fernandópolis +Musashimurayama +Brunswick +Morong +San Francisco del Rincón +Gibara +Ratangarh +Tāndūr +Bakhmut +Terme +Mārkāpur +Bunbury +Sihanoukville +Mauban +Tejupilco +Alabang +Goianésia +Dublin +Warzat +Montecristi +Ayvalık +Nadi +Wilmington +Zográfos +An Nu‘mānīyah +Izalco +Malaut +Lowestoft +Waukesha +Samraong +Kopargo +Phitsanulok +Kodungallūr +Corozal +Neyyāttinkara +Kumanovo +Dondo +Fairbanks +Ejura +Zinjibār +Sesvete +Érd +Zadar +Fatehābād +Bāpatla +Kalamasseri +Tumauini +Izmail +Ostrów Wielkopolski +Lakeville +St. Charles +Şirvan +Al Qurayyā +Gardēz +Cremona +Pavia +Rugby +Badvel +Loulé +Redondo Beach +Yinying +Chiang Rai +Karasu +Poblacion +Shujaabad +Stafford +Vālpārai +Yambol +Esperanza +Djemmal +Chingford +Cabudare +Sankaranayinār Kovil +Xangongo +Uxbridge +Zenica +Chekhov +Bundaberg +Sūratgarh +Spring Hill +Tamana +Kaukhāli +Sig +Bayonne +Coari +Grand Forks +Baiquan +Mindelo +Togoch’alē +Noblesville +Torremolinos +Būr Fu’ād +Capanema +Pavia +Noisy-le-Grand +Yawata-shimizui +Linares +Aliaga +Orani +Dandeli +Santa María La Pila +Minxiong +Huwei +Bopa +Brumado +Havířov +Hujra Shah Muqim +Şa‘dah +Ban Houayxay +Nāndūra Buzurg +Dimbokro +Rizal +Tinambac +Pazarcık +Guaynabo +Celle +San Antonio +Sagunto +El Paso de Robles +Kabirwala +Thaba Nchu +North Richland Hills +Maple Grove +Eniwa +Guzhou +Gaura +Mineiros +Pan’an +Tsurugashima +Grajaú +Cahama +Waingapu +Kempten +Passaic +Blaine +Lubin +Luodong +Thakhèk +Castries +Nansang +Al ‘Āmirāt +Talamba +Badhan +Điện Biên Phủ +Phú Quốc +Longtangwan +Zhanggu +‘Izbat al Burj +Bijaynagar +Satyamangalam +Madhipura +Kodoli +Az Zubaydīyah +Lake Elsinore +Mansfield +Raha Tiga +Raha +San Antonio +Nikki +Fulda +Avaniyāpuram +Rogers +Entebbe +Imerintsiatosika +Eskilstuna +Aigáleo +Rohri +Sagaing +Casas Adobes +Qingquan +Saint John +Farroupilha +Moquegua +Yueshanwan +Altamura +Sherman +Vushtrri +Encarnación +Konin +Novomoskovsk +Kwamhlanga +Ratnanagar +Villa del Rosario +Amstelveen +Garzón +San Miguel de Allende +Walnut Creek +Sanlúcar de Barrameda +San Juan de los Lagos +Los Reyes de Salgado +Basavakalyān +Farīdpur +Kiyosu +Conway +Ziguinchor +Minami-Alps +Uwajima +Roxas +Rioverde +Rittō +Eastvale +Saint-Louis du Nord +Inowrocław +Somasso +L’Aquila +Tournai +Bawku +Samch’ŏk +Rhondda +Union City +Biguaçu +Michigan City +Thohoyandou +Poptún +Sōja +Tripunittura +Toyoake +Al Qūşīyah +Alenquer +Victoria +Aqsū +Chisec +Kirdāsah +Poinciana +Nowrangapur +Welland +Kars +Bitola +Planeta Rica +Don Carlos +Bafia +Cawayan +Tulare +Anan +Limonade +Limbé +Shangchuankou +Barra do Garças +Ongjang +Cuímba +Torbeck +Fedosiia +Rongcheng +Gary +Ad Darb +Imola +Necoclí +Mansehra +Renk +Mila +Mocuba +Dharmasāgaram +Granby +Gaithersburg +San Pascual +Peruíbe +Kireka +Kamsar +Ko Samui +Moriya +Tanabe +Mocuba +Mococa +Piotrków Trybunalski +Varisshiyakuni +Korba +Huishi +La Paz +Yitiaoshan +Bagumbayan +Liuhe +Pālghar +La Chorrera +Buenavista +Lippstadt +East Orange +San José del Guaviare +Queenstown +Yunnanyi +Aparri +Assen +Ixtaczoquitlán +Aalen +Wesley Chapel +Ponta Delgada +Purísima de Bustos +Arcoverde +Jacona de Plancarte +Pakribarawān +Al Aḩmadī +Suwałki +Say’ūn +West Des Moines +Yuriria +Mineral de la Reforma +Indang +Sabae +Alamada +Isnā +Venâncio Aires +Požarevac +Kāyankulam +Velsen-Zuid +Dalton +Dubuque +Jarabacoa +Parādīp Garh +Quartu Sant’Elena +Issy-les-Moulineaux +Valle Hermoso +Bouira +San Leonardo +Ilkal +Zapotlanejo +Doboj +Víctor Larco Herrera +Igbanke +Nihtaur +Schenectady +Mamungan +Cabo San Lucas +Southampton +Kladno +Castelldefels +Ankeny +Sanza Pombo +Tangub +Anjangaon +Maricopa +Şəki +Bardi̇̄bās +Cergy +Puerto San José +Ash Shiḩr +Oriximiná +Adrar +Eagan +Tuymazy +Matara +Lodja +St. Albert +Otukpo +Franklin +Swedru +Nghĩa Lộ +Tynemouth +Sipocot +Tuburan +Villanueva y Geltrú +Hanford +Miagao +Xá Muteba +Bristol +Cuyapo +Mbaké +Yorba Linda +Weston +Watsonville +Hämeenlinna +Levallois-Perret +Minusinsk +Fort McMurray +Lindong +Renukūt +Nābha +Ixtlahuacán de los Membrillos +Putrajaya +Al Buraymī +San Pedro Ayampuc +La Barca +Yanghe +Palo Alto +Castillejos +Antalaha +Kstovo +Ōdate +Siuri +Bodītī +Januária +South Hill +Chengjiao Chengguanzhen +Conceição do Coité +Formiga +Ksar el Boukhari +Kamuli +Rājsamand +Longshan +Bishnupur +Cannock +Dinslaken +Kashiwara +Pesqueira +Colmar +Tepotzotlán +Bayombong +Sant’Eufemia Lamezia +Apac +Shashijie +Pongnam +İslahiye +Shawnee +Modāsa +Santa Barbara +Banepā +Youssoufia +Vaasa +Santa Catarina Otzolotepec +Heroica Caborca +Molepolole +Walsall +Manaure +Kovel +Abnūb +Zigon +Gauravaram +Bergen op Zoom +San Marcos +Areguá +Ayolas +Herford +Sausar +Yuquan +Taman Senai +Omīdīyeh +Huajing +Dhenkānāl +Zihuatanejo +Chicacao +Fuefuki +Urun-Islāmpur +Rolândia +Calais +Stargard Szczeciński +Gopālganj +Itapema +Ankazoabokely +Capelle aan den IJssel +Tomé-Açu +Great Falls +Cuilco +Tôlan̈aro +Lala Musa +Rüsselsheim +Haverhill +Āsela +Sousa +Union City +Séguéla +Shiojiri +Kerpen +Palatine +Longview +Corvallis +Bay +Tabatinga +Wanggezhuang +Washington +Lushar +Rockville +Néa Ionía +Zrenjanin +Szolnok +Old Bridge +Dolores Hidalgo Cuna de la Independencia Nacional +Liepāja +Sa’ada +Skokie +Pikit +Dhārāpuram +Guruvāyūr +Kashima +Cedeño +Jagoniguda +Mīrpeta +Nizhyn +Lupon +Phalodi +Embu-Guaçu +Târgovişte +Middletown +Nueva Guinea +Acilia +Veenendaal +Mount Vernon +Kati +Güines +Beypore +Casper +El Seibo +Grays +Bongabon +Kissidougou +Cosmópolis +Janaúba +Āksum +Çumra +Janiuay +Calimera +Godalming +Pessac +San Mateo Atenco +Botolan +Siddipet +Bulancak +Ilidža +Ames +Rosales +Hihyā +Hīt +Kraljevo +Bolgatanga +Chiyoda-ku +Viladecáns +Karlskrona +Karimama +La Carlota +San Mateo +Focşani +Delray Beach +Nālūt +Katwijk +Sammamish +Walton upon Thames +Ramos Arizpe +Aflao +Karakax +Novi Pazar +Cabedelo +Koratla +Saiki +Weiyuan +Damba +Georgiyevsk +Yachimata +Zacapa +Cuscatancingo +Guangping +Vénissieux +Urla +Lynwood +Hasanpur +Opol +Dundalk +Bethesda +Hashima +Slavyansk-na-Kubani +Växjö +Huquan +Zanhuang +Morristown +Reghaïa +Kampung Tengah +Bengkalis +Virginia +Juana Díaz +Sahaswān +Ocoyoacac +Belogorsk +Arāmbāgh +Kazanlak +Pidugurālla +Massa +Vidnoye +Cazin +Lençóis Paulista +Tsuruga +Ilo +Oberá +Genk +Goz-Beida +Chibok +Ban Suan +Oas +Kankakee +Dangbo +Moita +Agoo +Fajardo +Torreón +El Carmen de Bolívar +Madirovalo +Taman Johor Jaya +Puliyankudi +Stupino +Neuwied +Lantapan +Asenovgrad +Viterbo +Anamur +Lahat +Itapetinga +Alpharetta +Wilde +Tatabánya +Novi +Martínez +Kavála +Karlstad +Coron +Roxas +Zacatecoluca +Finchley +Thornton Heath +Gloucester +Sangamner +Chegutu +Kenner +Kiamba +Fukutsu +Wamena +San Remigio +Gohna +Pulivendla +Bay City +Sakrand +Santo Tomé +Smila +Ina +Collado-Villalba +Victoria +Surubim +Menzel Temime +Lutayan +Tulcea +Arima +Weimar +Angat +Qiryat Gat +Kirtipur +Istaravshan +Rio Negro +South San Francisco +Barreirinhas +Qarqan +Bom Jesus da Lapa +Apex +Parkersburg +Xarardheere +San Francisco El Alto +El Prat de Llobregat +San Antonio Suchitepéquez +Kānhangād +Xiantangcun +Al Minshāh +Beloretsk +Los Amates +Xieqiaocun +Jaisalmer +São Tomé +Singaparna +Malden +Kurabūr +Aïn Defla +Gniezno +Piripiri +Castro Valley +Narok +Rechytsa +Ishimbay +São Félix do Xingu +Ārān Bīdgol +Bāqershahr +Giddarbāha +Täby +Purulhá +Develi +Villa Curuguaty +Tamlūk +Hadjout +Jamjamāl +Sinnar +Vaijāpur +Jocotitlán +Solano +Kungur +Quezon +Pruszków +Bozeman +Birnin Konni +Tigbauan +Ouricuri +Torquay +Jagraon +Alīpur Duār +Pateros +Dhūri +Xibang +Ḩalabjah +Kitamoto +Guider +Zarechnyy +Dormagen +Ishim +San Jose +Villach +Buynaksk +Estância +Itaberaba +Rāth +Villasis +Zeist +Mecheria +Brentwood +Farnborough +Jiquílpan de Juárez +Popondetta +Saidu Sharif +Bāzār-e Yakāwlang +Patuakhāli +Sindelfingen +Matamey +Embu +Caripito +Sumbawa Besar +Bucak +Maasin +Keitumkawn +Autlán de Navarro +Busia +Ioánnina +La Ceja +Kolonnawa +Coyula +Chiquimulilla +Gukovo +Don Torcuato +Nagcarlan +Palaió Fáliro +Ladysmith +Tomigusuku +Clichy +Igarapé-Miri +Bordj Menaïel +Gwacheon +Sabinas +Acaraú +Ostrowiec Świętokrzyski +Soloma +Plauen +As Suwaydā’ +Chipindo +Waltham +Faīẕābād +Sangzishi +Seydişehir +Oued Rhiou +Kensington +Siemianowice Śląskie +Meulaboh +Marinilla +Gerli +Santo Domingo Tehuantepec +Binga +Fredericton +Boston +Grevenbroich +Lechang +Faro +Pirané +Narapalli +Fujioka +Ţūlkarm +Pflugerville +Isabela +Hilongos +Arrecife +Pālitāna +Roeselare +Valence +Rivera +Rahat +Itamaraju +North Little Rock +Al Qurayn +Dharmapuri +Apaseo el Alto +Brentwood +Sokhumi +Idappādi +Hiriyūr +Porto Nacional +Paignton +Potenza +Rosenheim +Chunian +Malvar +Santiago Tianguistenco +Martil +Waterlooville +Sirsi +Sibulan +Póvoa de Varzim +Ash Shaykh Zuwayd +Chervonohrad +Saravia +Seraing +Głogów +Atimonan +Laguna Niguel +Ambarawa +Misantla +Kodād +San Clemente +Alba Iulia +Sangmélima +Ciénaga de Oro +Bertioga +Vacaria +Qinggang +Ghardimaou +Seinäjoki +Tādepalle +Grande Prairie +Welkom +Qal‘ah-ye Now +San Felipe +Yanagawa +Niksar +Pomezia +Siuna +Asbest +Burnsville +Teresa +Randers +Armūr +Simav +Ivry-sur-Seine +Horad Zhodzina +Guiseley +Neubrandenburg +Sodegaura +Tiquisate +Tuao +Bankra +Nawalgarh +Spring +Tupã +Port Charlotte +Camocim +Ferrol +Bognor Regis +Tohāna +Nieuwegein +Most +Penedo +Santa Cruz +Inhambane +Songkhla +Sibalom +Trnava +Kangbao +La Línea de la Concepción +Khagaul +Tenri +Daljā +Ponferrada +Magong +Zarand +Odendaalsrus +Guamúchil +Chakpi Karong +Sundapālaiyam +Fraijanes +Bourges +Jatani +Chokwé +Kurihara +Zvornik +Nawá +Chincha Alta +Jose Pañganiban +Chik Ballāpur +Guiglo +Quimper +Donskoy +Athni +Eden Prairie +Dédougou +Fredrikstad +Paphos +Capão da Canoa +Hornchurch +Assi Bou Nif +Maidenhead +Greenwood +Yangqingcun +Benevides +Lower Merion +At Tall +Midoun +Millcreek +Yattir +Asahi +Slatina +Bhairāhawā +Badr Ḩunayn +Khulayş +Korydallós +Pokrovsk +Rundu +Tajumulco +Akurana +Mitcham +Medicine Hat +Pervomaisk +Feltham +Itō +Dhuburi +Fujiidera +Mirassol +Bellevue +Vittoria +Prilep +Stourbridge +Coon Rapids +Rowlett +Mercedes +Galgamuwa +Ban Lam Sam Kaeo +Abū Qurqāş +Kitale +Cajazeiras +Ouled Djellal +Antony +Banda del Río Salí +Gorno-Altaysk +Volsk +San Marcos +Anuradhapura +Svyetlahorsk +Tartagal +Lugano +Gadwāl +Tetovo +Horsens +Rockhampton +Hamilton +Lakewood +Qurayyāt +Florence-Graham +Teoloyucan +Sīdī Barānī +Granollers +Novaya Balakhna +Nankana Sahib +Visnagar +Puerto Asís +Nago +Commerce City +San Fernando +Vaslui +Pāmūru +Çaldıran +Kasongo +Kaga +Rochester +Batatais +Bossier City +Miyoshi +Pabianice +Halton Hills +Beledweyne +Dewsbury +Taylor +Klintsy +Friedrichshafen +Sheikhpura +Narlıdere +Marina di Carrara +Irún +Māhdāsht +La Habra +Yurimaguas +Campo Bom +Balboa Heights +Sirsi +Wāshīm +Calinog +Mut +Port Orange +Palmela +Rossosh +Moncada +Balad +Itupeva +Gampaha +Woking +Troyes +Nānpāra +Tân Phước Khánh +Castellammare di Stabia +La Seyne-sur-Mer +Bansalan +Champasak +Bāri +Pavlovskiy Posad +Lingshou +Qoryooley +Gusang +Brookline +Revda +Moore +Koro +Council Bluffs +Tandag +Boadilla del Monte +Icó +Carmen de Viboral +Kapatagan +Bensalem +Anse à Galets +Leninogorsk +Sittingbourne +Leander +Acton +Dearborn Heights +Herten +Nagakute +Kilis +Mobārakeh +Portel +Aïn Harrouda +Rovaniemi +Wenxicun +Bergheim +Berekum +Rānipet +Ambilobe +Wundanyi +Reston +Kolding +Schwäbisch Gmünd +Kesamudram +Villa Domínico +Ras Tanura +Puerto Peñasco +Bainet +Riosucio +Shangtangcun +Boryspil +Tuapse +Caràzinho +Kolda +Nagari +Cristalina +Zelenogorsk +Napier +Sherkot +Tighenif +Santarém +Asaka +Camaquã +Panchari Bazar +Bannu +Cyuve +Boituva +Rāghogarh +Chidambaram +Twickenham +Agía Paraskeví +Analavory +Figueira da Foz +Aurora +Narwāna +Vigevano +North Bergen +Tríkala +Cabaret +Aurora +Montebello +Okha +Zaraza +Nova Odessa +Meshkīn Dasht +Naro-Fominsk +San Francisco +Viedma +Sihushan +Bhabhua +Kōshizuka +Manicaragua +Rouiba +Tendō +Borj el Qoblé +Pontiac +Arua +Nanjangūd +Camotán +Mongaguá +Encinitas +Tagajō +Yongbei +Menzel Bourguiba +Montauban +Rayong +Cambanugoy +Sätbayev +Zengqiao +Siddhapur +Plato +Polevskoy +Mitoyo +Derik +Żory +Kotlas +São Miguel dos Campos +Leszno +Runcorn +Nakhyaungcharīpāra +Queen Creek +Nkawkaw +Camabatela +Borisoglebsk +Hita +Lysva +Saraburi +Medford +Springfield +Morada Nova +Naj‘ Ḩammādī +Jhārgrām +Afragola +Santo Amaro +Yangiyŭl +Bezerros +Sungo +Penápolis +Kapchagay +Shiroi +Offenburg +Xiluodu +Cortazar +Praia +Kolea +San Juan Chamelco +San Antonio del Táchira +Plymouth +Karonga +Wrecsam +Sayyid Şādiq +Valle de Bravo +Hendersonville +Palm Harbor +Hato Mayor +Extremoz +Pico Rivera +Cayenne +May Pen +Santa Ana +Výronas +Asker +Ostuncalco +Ilobasco +Itogon +Port Coquitlam +Korosten +Baao +La Democracia +Uzunköprü +Hasuda +Widnes +Taal +Djibo +Euclides da Cunha +Xinmin +Rāmanāthapuram +Kozluk +Candon +Sawahlunto +Gia Nghĩa +Marietta +Hatogaya-honchō +Tunasan +Wellington +Garbsen +Wesel +Budënnovsk +Vejle +Tarnowskie Góry +Trikonavattam +Santa Catarina Ixtahuacán +Sanford +Kolomyia +Sibay +Yala +Salgueiro +Halvad +Mateare +Wels +Barbalha +Woodland +Tauá +Margate +Abuyog +Caldwell +Coyhaique +Maués +Huntersville +Bocaranga +Ar Rastan +Caicó +Udamalpet +Cabatuan +Mirabel +Santo Domingo +Ellesmere Port +Santa Rosa de Copán +Barberena +Velika Gorica +Hashimoto +Idiofa +Bristol +Olbia +Neu-Ulm +Nordre Fåle +La Plata +Ogōshi +Bangor +Iranduba +Nekā +Tulunan +Hürth +Adjohon +Wanparti +Jupiter +Tafo +Aisai +Tsushima +Itoman +Soroti +Unna +San Rafael +La Mesa +Nambuangongo +Los Polvorines +Richland +Jinoba-an +Łomża +Tamba +Chāmrājnagar +Fort Portal +Pantin +Burhaniye +Meihuacun +Yamatotakada +Bethal +Orion +Artemisa +Sarandí +Kresek +El Wak +Villamaría +Shihe +Puerto Limón +Calulo +Galapa +Cubulco +Mbabane +Oyem +Kyustendil +Huatusco +Castilla +Laoang +Oda +Ibitinga +Kukarmunda +Kokawa +Trang +Viareggio +Revere +Trujillo +Yongyang +Meriden +Tigaon +Matanao +Atotonilco el Alto +Taunton +Dumraon +Piscataway +Fryazino +Itapecuru Mirim +Ełk +Monterey Park +Gardena +Slutsk +Vratsa +Euless +Cruz das Almas +Altınözü +Bor +Panruti +Lalmanirhat +Ambanja +Ciudad Arce +Velampālaiyam +Laeken +Gubat +Wallasey +Yisuhe +Rosario +Irvington +Belladère +Mizusawa +Clay +Tirukkoyilūr +San Mateo Ixtatán +Parkent +Paracale +Yame +Qoorlugud +Belebey +Rāzampeta +Kangān +Chistopol +Kumertau +Labinsk +Nedumangād +Berrouaghia +Zamość +Pasaje +San Mariano +Nioro +Ābyek +Samut Sakhon +Mbalmayo +Des Plaines +Jinxing +Malay +Souq Sebt Oulad Nemma +Towada +Pirojpur +Manhiça +Horqueta +Floriano +São Borja +Monte Alegre +Sarāvān +Tyre +Faruka +Buqda Caqable +Oodweyne +Güigüe +Hurlingham +Kribi +Suifenhe +Consuelito +Baba Hassen +Meskiana +Afula +Nahariyya +Gunupur +Mehnājpur +Bayjī +Banane +Kakuma +Kratie +Barneveld +Hamburg +Obando +San Marcos +Çivril +Bābolsar +Union +Thatri +Urus-Martan +Rubizhne +Registro +Chandralapādu +Legnano +Loughborough +San Vicente del Raspeig +Ponnūru +West Allis +Carrara +Aïn Touta +Arankhola +Sigaboy +Kathua +Chambéry +Ilog +North Miami +Özalp +St. Cloud +The Hammocks +Escada +Aranjuez +Blainville +North Lakhimpur +Fano +Andradina +Langenfeld +Skhirate +Dongcun +Euskirchen +Ragay +Khartsyzk +Cupertino +Užice +Lakhdaria +Taylorsville +Vinukonda +Alexandroúpoli +Suharekë +Huehuetoca +Viçosa do Ceará +Gohadi +Kananya +Greifswald +Khagaria +Hardenberg +Matera +Petaluma +Bougouni +Karamürsel +Huajiang +Sanyō-Onoda +Aguacatán +Sennan +Guerra +Date +Pāchora +Ouezzane +Medellin +Maimbung +Lianzhuangcun +Coroatá +Limoeiro do Norte +Chełm +Tiptūr +Altamira +Kokomo +Gopichettipālaiyam +Givatayim +Santee +Alcoy +Itānagar +Esfarāyen +Xo‘jayli Shahri +Hakkari +Mérida +Wangzhuang +Stonecrest +Taunton +Rzhev +White Plains +Montenegro +Yara +Shimotsuke +Druzhkivka +Shirakawa +Tomaszów Mazowiecki +Los Andes +Ouinhri +Morón +Hua Hin +Stralsund +Esperanza +Koga +Aş Şaff +Galátsi +Kesennuma +Garín +Ruhengeri +Aleksandrov +Jōsō +Niort +Alfonso +Zhoujiajing +Gaibandha +União dos Palmares +Hyūga +Dhone +Irosin +Neuilly-sur-Seine +Sérres +Zamora +Irati +Gannan +San Francisco +Trollhättan +Rājgarh +Kateríni +San Simon +Chalkída +Mansalay +Dāmghān +Chichibu +Umm al Qaywayn +Antigua Guatemala +Panna +Palm Beach Gardens +Barking +Chivacoa +Göppingen +Constanza +Saint-Louis du Sud +Yevlax +Mossel Bay +El Palomar +Tahara +Upi +Metapán +Florida +Jiguaní +Petroúpoli +Huauchinango +Kattaqo’rg’on Shahri +Anzio +Motril +Nirgua +Chapel Hill +Santa María Chiquimula +Cruz Alta +Cerro de Pasco +Xikeng +Lac-Brome +Andoharanofotsy +Gattaran +Carvajal +Parobé +Sidi ech Chahmi +Zahirābād +Scheveningen +Roxas +Wani +Binnāguri +Ban Rangsit +Canlaon +Kalamáta +Beccar +Jackson +Manouba +Upleta +El Salvador +Narasapur +Xánthi +Chikuma +Hoboken +Kruševac +Pedro Leopoldo +Parker +Jaguariúna +Blue Springs +Calatagan +Baganga +Faenza +Viseu +Izberbash +Jovellanos +Shoreline +Dosso +Baguinéda +Koja +St. Clair Shores +Kasungu +Sonabedha +Pasrur +Wuyang +Raharpur +Edgware +Xinfeng +Alta Floresta +Lytkarino +Kaş +Mpondwe +Tenkodogo +Horizon West +Ōsakasayama +Frutal +Pipariā +San Luis +Caltanissetta +Gllogovc +Una +Balancán +Ibaan +Kélibia +Sardhana +São Gabriel +Hastināpur +Crotone +Ma’erkang +San Pedro +Tianningcun +Liannong +Liantangcun +Sarcelles +Benevento +Qaskeleng +Trairi +Przemyśl +Margate +Heerhugowaard +San Fernando +Littlehampton +Sandīla +Orland Park +Pebane +Zengcun +Nyagan +Acerra +Ogōri +Limerick +Punta Alta +Palompon +Abington +Tiruvālūr +Sucun +Murakami +Nanjian +Capenda Camulemba +Ishikari +Antsalova +Lambayeque +Doetinchem +Le Blanc-Mesnil +Pursat +Carson City +Rass el Djebel +Mouscron +Frankfurt (Oder) +Sillod +Ruislip +Mielec +Călăraşi +Savona +Naval +Barotac Nuevo +Temascalcingo +Samaná +Chivilcoy +Tikhvin +Halesowen +Kitahiroshima +Midwest City +Mulbāgal +North Vancouver +Rouissat +Bakwa-Kalonji +Dapaong +Maisons-Alfort +Felgueiras +Streatham +Royal Oak +Timargara +Ambahikily +Chibuto +Meleuz +Masantol +Tczew +Pradera +Chornomorsk +Santa Isabel +Kawthoung +Hunsūr +Pānskura +Nanjakkād +Bowie +Kan’onjichō +New Corella +Zempoala +Hameln +Kolondiéba +Allanmyo +Cogan +Aleksin +Berëzovskiy +Prokhladnyy +Oued Lill +Nausori +Glew +Lorient +Rāmpur Hat +Mikhaylovka +Dumanjog +Asingan +Sidi Yahya Zaer +Suileng +Marano di Napoli +Orito +Xiezhou +Royal Tunbridge Wells +Tikhoretsk +Živinice +Villejuif +Ávila +El Attaf +Hervey Bay +Kettering +Bellevue +Khandāla +Lonāvale +St. Peters +Kosai +General Pico +Oak Lawn +Mogoditshane +Grand-Popo +Pavlovo +Salsk +Stalowa Wola +Gengzhuangqiaocun +Towson +Jerez de García Salinas +Yanguancun +New Plymouth +Camajuaní +Taquara +Bilimora +Kothāpet +Coconut Creek +Maduraivayal +Tōgane +Sīra +Monte Plata +Lucan +Diriamba +Milagros +Choshi +Santa Maria +Decatur +Krasnotur’insk +Palāsa +Tokoname +Ejmiatsin +Lenexa +Wiwilí +Guarabira +Bartlett +Humaitá +Santiago Tuxtla +Cosquín +Tanauan +Chintalapalli +Meerbusch +Lohārdagā +Buluan +Sinop +Cuvelai +Ponte Nova +Richards Bay +Acará +South Whittier +Foumbot +Antsinanantsena +Huaniu +Qianwu +Nacaome +Bebington +Molfetta +Tieshansi +Eldorado +Mali +Roermond +Weymouth +Coruripe +Lake Havasu City +Mācherla +Boac +Gümüşhane +Bīmgal +Nova Esperança +Içara +Kandukūr +Tres Arroyos +Saint-Hyacinthe +Keonjhargarh +Krymsk +Riosucio +Villa Hayes +Aldershot +Bilhorod-Dnistrovskyi +Cupang +Alangalang +Samannūd +Belize City +Bulungu +Uson +Boufarik +Ping’an +Kollegāl +Cosamaloapan +Sarapiquí +Moknine +Bel Air South +Unjha +Benslimane +Uki +Nonoichi +Moramanga +Fréjus +Borūjen +Devrek +Maun +Fountainebleau +Wylie +Mafeteng +Bail-Hongal +Jasaan +Shuya +Dehdasht +Semara +Alvarado +Baden-Baden +Lunglei +Neryungri +Minokamo +Ipele +Bura +Zushi +Talagante +Rîbniţa +Nasīrabād +Cerignola +Ródos +Madison +Cuemba +Tezonapa +Ushuaia +Ban Bang Kaeo +Cachoeiras de Macacu +Machang +Huaixiangcun +San Luis +Kędzierzyn-Koźle +Puerto Boyacá +Azzaba +Hagonoy +Mora +Xam Nua +Limbang +Dina +Gūdalur +Ipirá +Caacupé +Miragoâne +Sāmalkot +Karīmganj +Brookhaven +Acambay +Santa Rosa +Pinagkaisahan +Bobbili +Irpin +Bebandem +Chinhoyi +Highland +Fussa +Fountain Valley +Bowmanville +Düziçi +Kālna +Sattenapalle +Tulcán +Al Hoceïma +Lagonoy +Basey +Beauvais +Kudamatsu +Pau d’Alho +Hod HaSharon +Pirapora +Barabai +Muğla +Vrindāvan +Chini +Iskitim +Acámbaro +Diglipur +Khāsh +Beni Enzar +Den Helder +Forest +Macclesfield +Pangantocan +Görlitz +Wellingborough +Tāybād +Mafra +Berwyn +Ar Riqqah +San Pedro Sacatepéquez +Lingen +Ramon +Ixtahuacán +Limoeiro +Porto Feliz +Naugaon Sādāt +Colomba +Sendhwa +Athiémé +El Cerrito +Bartolomé Masó +Stolberg +Moyobamba +Bianyang +Tiwi +Severn +Talegaon Dābhāde +Tama +Rafael Calzada +Wote +Hassa +Rolim de Moura +Mocoa +Boudouaou +Narbonne +Villarrica +Binalonan +Longxing +Sankt Augustin +Sucat +Albany +National City +Placer +Paços de Ferreira +Rosh Ha‘Ayin +Korkuteli +Lian +Narammala +Libungan +Amarante +Magsaysay +Lacey +Bihać +Pèlèngana +Esquipulas +Kūt-e ‘Abdollāh +Klimovsk +Poonamallee +Sarikei +M’diq +Shali +Kettering +Gangārāmpur +Rahovec +Oosterhout +Hohoe +Mount Prospect +Arcadia +Dongola +Mota +Mukōchō +Khlong Luang +Tilakpur +Moncalieri +Castelo Branco +Mizuho +Diffun +Cuizhuangzi +Waiblingen +Tiruvallūr +Mandapeta +San Andrés Villa Seca +Tirur +Mendi +Takizawa +Kimilili +Uman +Eschweiler +Bonga +Pithorāgarh +Kengri +Huaquillas +Myaungmya +Intibucá +Bluefields +Oke-Mesi +Langtang +Ropar +Parsippany-Troy Hills +Abū Za‘bal +Chiapa de Corzo +Lower Bicutan +General Tinio +Takaishi +Acul du Nord +Ajodhya +DeSoto +Poblacion +Smyrna +Bungoma +Longmen +Khān Shaykhūn +Changling +Belampalli +Kharar +Viramgām +Zarrīn Shahr +Sidi Bennour +Hilden +Bradenton +Braintree +Bambang +Biswān +Tsévié +Union +Rengo +Gulariyā +Cuneo +Umm Ruwaba +Kannamangalam +Royal Leamington Spa +Lesosibirsk +Azul +Atchampeta +Oulad Yaïch +New Brunswick +Apatity +Nōgata +Asadābād +Tursunzoda +Paombong +Będzin +Zile +Dzerzhinskiy +Nawucun +Siliancun +Hashtgerd +Kāndi +Nueva Loja +Meaux +Portimão +Hoogeveen +Nyenga +Guliston +Yongqing +Apple Valley +Iba +Mulanay +Kuala Kapuas +Tinley Park +Finote Selam +Hà Giang +Trapani +Urbiztondo +Saravena +Nuevo Casas Grandes +Buthidaung +Wellington +Raxaul +Pulheim +Kidderminster +Shendi +Sankt Pölten +Opava +Agrigento +Chystiakove +San Agustín Acasaguastlán +Sarasota +Barwāni +Porto Alexandre +Barrow in Furness +Batac +Villarrica +Videira +Qiryat Ata +Hacienda Heights +Chicopee +Nansan +Tonekābon +Zalaegerszeg +Biała Podlaska +Xinqing +Monte Mor +Tatalon +Ovar +Sacapulas +Asturias +Toki +Erumaippatti +Khorramdarreh +Langenhagen +Thérmi +Yamasá +Taliwang +West Haven +Mercedes +Winneba +Harpanahalli +Buta +Midalt +Herriman +Umm el Faḥm +Meyerton +Periya Semūr +Moreno +Três Pontas +Wangguanzhuang Sicun +Nordhorn +Madhupur +Foligno +Perth Amboy +Rijswijk +Porirua +Pombal +Chālil +Pinto +Verviers +Colmenar Viejo +Challakere +Casa Grande +Wuhuang +Tigard +Biel/Bienne +Kronjo +Puthiyangādi +Lazarevac +Nāmakkal +Vranje +Ibiporã +Santa Cruz +Hyères +Stryi +Linares +Māngrol +Shijōnawate +Békéscsaba +Novohrad-Volynskyi +Manapla +Chonthrhu +Bhīmunipatnam +Zgierz +Olímpia +Eqbālīyeh +Rangewala +Bobigny +Apopka +Ucuma +Lampang +Fālākāta +União da Vitória +Chino +Canoinhas +Touba +Agbangnizoun +Bilis Qooqaani +Elenga +Polūr +Bhongīr +Tāsgaon +Bad Homburg +Narutochō-mitsuishi +Dompu +Songjiangcun +Catu +Şırnak +La Roche-sur-Yon +Granadilla de Abona +Trani +Oxchuc +Tequisquiapan +Corby +Nāndod +Tivoli +Southaven +Imarichō-kō +Acıpayam +Luquembo +Canterbury +Zhushan +Pithāpuram +Queensburgh +Yenişehir +Jelgava +Minamiuonuma +Bad Salzuflen +Khurai +Świdnica +Ŏjŏk-tong +Tacuarembó +Punganūru +Trenčín +Hidaka +Piedade +Barranqueras +Santa Cruz +Chaiwu +Sarpsborg +Belén de Escobar +Schweinfurt +Phuthaditjhaba +Saruhanlı +Carigara +Sara +Hattingen +Chone +Mikkeli +Pila +Chota +Gabrovo +Annaka +Ghātāl +Terneuzen +Palmares +Santa Elena +Giurgiu +Sāgar +Huntington Park +Mūndka +Diamond Bar +Gus’-Khrustal’nyy +Jinchang +Masinloc +Volzhsk +Bentonville +Pontevedra +Trento +Jalapa +Clamart +Buderim +Ortaca +Douar Ain Chkef +Kampen +Ensenada +Antanifotsy +Nihonmatsu +Kouri +Yucaipa +Capitão Poço +Mbulungu +Tapas +Vannes +Pallíni +Caojia +Konan +San Isidro +Dikwella South +Medianeira +Plainfield +Javānrūd +Azrou +Shidong +Shidongcun +Sakurai +Islāmpur +Umm Qurūn +Ruma +Bełchatów +Morsott +Sidhi +Rāhuri +Chelles +Sado +Hanyū +Zarafshon Shahri +Manhattan +San Manuel +Kızılpınar +Paraćin +Aspen Hill +Rocky Mount +Cornillon +Valle del Guamuez +Bristol +Ankadinondry-Sakay +Christchurch +Rotorua +Peabody +Don Bosco +Frýdek-Místek +Wetzlar +Hashtpar +Kāsaragod +Komotiní +West Sacramento +Frenda +Bir Ali Ben Khalifa +Wayne +Huesca +Ixhuatlán de Madero +Cajicá +Louang Namtha +Puttūr +Mariano Acosta +Jalor +Tarma +San Jacinto +Chèddra +Samāna +Kunnamkulam +Kentwood +Palmaner +Xihu +Jālākāti +Deolāli +Lozova +São Gonçalo do Amarante +Prachuap Khiri Khan +Ribeira do Pombal +Juanjuí +Tagkawayan +Ghōriyān +Jihong +Kennedy Town +Titay +Puerto Libertador +Minalabac +Neustadt +Umred +Şabbāshahr +Bandar-e Torkaman +Hamura +Chenab Nagar +Sohna +Colton +Chilibre +Cholet +Vigan +Manicoré +San Bartolomé +Chaniá +An Nimāş +Passau +Manfredonia +Cabagan +Bacaadweyn +Narva +Bījār +Iganga +Impasugong +Pārvatipuram +Millcreek +Oak Park +Mansāla +Ullāl +Magpet +Juigalpa +Kitaotao +Louangphabang +Dholka +Ottappālam +Westchester +Smyrna +São Francisco do Sul +Zongo +A Yun Pa +Cangola +Funato +Gazipaşa +Upata +Svobodnyy +Wheaton +Hadali +Mora +Manjeri +Alcobaça +Kongoussi +Évry +Krasnokamsk +Al Majāridah +Ashta +Sakon Nakhon +Gisenyi +Lower Paxton +Cambundi Catembo +Évora +Encarnación de Díaz +Beaumont +Ilindu Kothi +Bisceglie +Aloha +Kāliyāganj +Jaggayyapeta +Minnetonka +Cuenca +Brits +Morondava +Liski +Modica +Marechal Cândido Rondon +Ilgın +Épinay-sur-Seine +Travnik +Extrema +Howell +Hongshandian +Ajuy +Pasacao +Marco de Canavezes +Popeşti-Leordeni +Goālpāra +Sibonga +Dilovası +Santa Lucía +Zhigulevsk +Pryluky +Mutsu +Kleve +Liberia +Yaguajay +Shāhpur +Guiuan +Tutóia +Pinellas Park +Ahlen +Granja +Tōkamachi +Keighley +Kannapolis +Gorkhā +Chaozhou +Itabirito +Montesilvano +Tame +Inhumas +Paramount +Dongshan +Amalāpuram +Tokmok +Açu +Dangila +Yangmei +Bakhtiyārpur +Vyksa +Legionowo +Arsikere +San Vicente +La Gomera +Saint-Ouen +Qingan +Estancia +Kabale +Hamilton +Dongsheng +Bitonto +Barbosa +Patancheruvu +Capivari +Pinotepa +Barobo +Rondon do Pará +Vikārābād +Molave +Bāruipur +Beberibe +Deva +Hereford +Dandarah +Dunfermline +Lucban +Zaragoza +Texas City +San Manuel +Sagua la Grande +Itapagé +Puttūr +Novato +Targovishte +Edina +Naka +Mahmutlar +Elda +Piekary Śląskie +Safranbolu +Aurora +At Tawāhī +Salo +San Estanislao +Izumi +Manglaur +Beloeil +Saint-Quentin +Phra Nakhon Si Ayutthaya +Simojovel de Allende +Kadiolo +Bagheria +Hyosha +Normal +Tilhar +Gudermes +Bondy +Xincheng +Buenavista +São Miguel do Guamá +Xinguara +Sultānganj +Congonhas +Tiruvalla +Kandıra +Mandi Dabwāli +Maha Sarakham +Tamiami +‘Alīābād-e Katūl +Clorinda +Grand Island +Xingcheng +Siena +Methuen Town +Frechen +Gallarate +Hrazdan +Timbaúba +San Remo +Elyria +Wheaton +Lorica +Usa +Harrismith +São Francisco +Malkara +Ksar Chellala +Bayonne +Pigcawayan +Ouenza +Jette +Lagoa da Prata +Karak +Madīnat Ḩamad +Woerden +Venkatagiri +Hamtic +Kelaa Kebira +Paracambi +Corbeil-Essonnes +Wolfenbüttel +Bozova +Kobryn +North Bay +Kendale Lakes +Pôrto Ferreira +Quezaltepeque +San José Villa de Allende +Bloomfield +Tramandaí +Kahnūj +Yaozhuangcun +Minami-Sōma +San Joaquin +Zhangjiazhuang +Zhangjiazhuangcun +Bani +Sihor +Tizimín +Brentwood +Imbituba +Roskilde +Cagnes-sur-Mer +Nerkunram +Jihlava +Başkale +Marana +Sertolovo +Guernica +Bad Kreuznach +Neibu +Velletri +Cihanbeyli +President Roxas +Burauen +Tlacotepec +Vyazma +An Nabk +Panjakent +Qabqa +Bamei +Thongwa +Pacora +Badūria +Dauis +El Rama +Claveria +Bârlad +Sironj +Ban Om Noi +San Miguel Ixtahuacán +West New York +Padangpanjang +Ibbenbüren +Tønsberg +Altrincham +Coronel Oviedo +Jangaon +Miyakojima +Charlottetown +Marechal Deodoro +Ibajay +Daudnagar +Paraíso do Tocantins +Jiyyammavalasa +Zalău +Acajutla +Antratsyt +Mandamāri +Lakhminia +Sison +Aïn Sefra +Twin Falls +Krasnokamensk +Marondera +Akbou +Campo Belo +Santo Estêvão +Delmiro Gouveia +Taquaritinga +Tekkeköy +Enerhodar +Lancaster +Óbidos +Cangandala +Lautoka +Pula +Taxco de Alarcón +San Pablo +São José do Rio Pardo +Korāput +Mudhol +Avellino +Pola de Siero +Naguilian +Victoria +Horishni Plavni +Florissant +Ålesund +Uriangato +Bato +El Tumbador +Vaulx-en-Velin +Bhajani +Phaltan +Shiraoka +Buíque +Glendora +Belorechensk +Acatzingo +Diu +Lengquancun +Portici +Ampanihy +Todupulai +Bitlis +Ālbū Kamāl +Chajul +Pontes e Lacerda +Thomazeau +Tangkak +Caetité +Yendi +Gummersbach +Ambohibary +Ad Dabbah +Tejen +Dungu +Takeo +Shiogama +Huamantla +Ibiza +San Onofre +Khattan +Leon +Cathedral City +Vaisampākkal +Kumarankari +Al Kharj +Ntoum +Piaseczno +Eilat +Muban Saeng Bua Thong +Timashevsk +Santa Eulalia +Mengmeng +Aliso Viejo +Vernon +Liaquatpur +Rumia +San Gil +Wangjiazhai +El Bagre +Tomiya +Alytus +Padre Garcia +Villareal +Vila Real +Arwal +Sevran +Choma +Kardzhali +Melo +Mollet +Fontenay-sous-Bois +M.Ə. Rəsulzadə +Palenque +Covilhã +Placentia +São Gabriel da Cachoeira +Crosby +Palmas +Sherpur +Burla +Hoffman Estates +Gādarwāra +Caleta Olivia +Baranoa +Caldas da Rainha +Caramoan +Gradiška +Pordenone +Utrera +Belle-Anse +Isfara +Guapimirim +Tamboril +Qalqīlyah +Kālpi +Aguadulce +Girardota +Civitavecchia +Baião +Santa Ignacia +Shahr-e Bābak +Alaminos +Solnechnogorsk +Xanxerê +Mulongo +Huazangsi +Tijucas +Irinjālakuda +Menggala +Kokstad +Tachilek +Zeralda +Teramo +Tirupparangunram +Maubin +Tulsīpur +İncirliova +Bandō +Zangāreddigūdem +Burien +Barri +Baham +Abdul Hakim +Ravensburg +Râs el Oued +Sombor +Bantacan +Böblingen +Dunwoody +Ensenada Berisso +Viana +Sūsangerd +Mangochi +Willenhall +Peine +Cerca la Source +El Kelaa des Srarhna +Bootle +Stratford +Speyer +Torrelavega +Uzlovaya +Morrinhos +Nentón +Koumantou +Gopālganj +Boukadir +Folkestone +’Aïn Merane +Tadmur +Brandon +Rastatt +Samut Prakan +Kalawana +Sapé +Lənkəran +Rincón de la Victoria +Kyzyl-Kyya +Palm Desert +Puerto Francisco de Orellana +Cutervo +Peranāmpattu +Troy +Guarne +Tamalous +Racibórz +Rongat +Wāliṅ +Dartford +Dabhoi +Montijo +Sartrouville +Severomorsk +Herning +Salekhard +Bargny +Bhavāni +Puthuppariyāram +Mascouche +Collierville +Sidlaghatta +Jūrmala +Korçë +Levittown +Leopoldina +Martin +Tsukubamirai +Fuchū +Barra +Brejo Santo +Marpalli +Bowringpet +Knysna +Sar-e Pul +Ocampo +San Narciso +Aurangābād +Hodal +Snezhinsk +Fatwa +Rosemead +Rosso +Kot Mumin +Shimencun +Weymouth +Segovia +Kalbā +Iormughanlo +Umán +Country Club +Tucurú +Massy +Enid +Horsham +Cumbernauld +Pardwāl +Djamaa +Cuyahoga Falls +Guaxupé +Tobias Barreto +Esher +Metpalli +Kalamansig +Mishawaka +Columbus +Andover +Kirishi +Juruti +Babīlā +Silkeborg +Repalle +Huaiyang +Skenderaj +Mabini +Kyōtango +Miyako +Pontal +Campos do Jordão +Teplice +Summerville +Vigia +Livingston +Nicoya +Banī Walīd +Cheremkhovo +Çermik +Levittown +Tŭrtkŭl +Geyve +Kuchaiburi +Vyāra +Whangarei +Zabīd +Sibsāgar +Irondequoit +Mahmudābād +Elmshorn +Grapevine +Goshogawara +Jarash +Zumpango +Marigot +Covina +Rio Tinto +Ranchuelo +Quirinópolis +Beruniy +Bikramganj +Agrínio +Göksun +Mweka +Chinchiná +Estância Velha +Sunāmganj +Milford city +Neath +Chinnamanūr +Draper +Fafe +Cataingan +Kotka +El Jem +Skien +Lakewood +Haskah Mēnah +Jaru +Metema +Sakaidechō +Catalina Foothills +Arao +Ānaiyūr +Kosamba +La Calera +Clacton-on-Sea +Cava de’ Tirreni +Emden +Northwich +Jaspur +Nichinan +Acireale +Susono +Delano +Gloria +El Nido +Maḩmūd-e Rāqī +Forbesganj +San Ignacio +Tebourba +Hunedoara +Naviraí +Bas Limbé +Tūyserkān +Laksar +Youfangcun +Cabreúva +El Talar de Pacheco +Bar Bigha +Tūndla +Arles +Boa Viagem +Bangued +Aringay +Haverford +Tanjombato +Ampitatafika +Plaisance +Wao +Myrnohrad +Chbar Mon +Ma‘ān +Amulung +Vargem Grande Paulista +Cojutepeque +Chinú +Bāghpat +Floreşti +Peñablanca +Rho +Donsol +Beveren +Rowley Regis +Artur Nogueira +Bhawānīpur Rājdhām +Houten +Yūki +Goslar +Ghŭlakandoz +Gombong +Nes Ẕiyyona +Nakagawa +Palpalá +Hamada +Karviná +Moskovskiy +Adeje +Gopālpur +Borovichi +Willich +Cardona +Qinhe +Bang Bua Thong +Scarborough +Lincoln +Ercolano +Sour el Ghozlane +Déressia +Roslavl +Itararé +Bhadrāchalam +Francisco I. Madero +Sfântu-Gheorghe +Tubod +Biaora +Sojat +Yerba Buena +Wolossébougou +Yasu +Miyoshi +Hassan Abdal +Murray +Mazara del Vallo +Leith +Pamplona +Heidenheim +Mooresville +Eger +Weert +Sakubva +Qabb Eliâs +El Ghâzîyé +Aarsâl +Ikot Okoro +Sechura +Chak Thirty-six North Branch +Rukan +Buni +Chak Sixty-one Gugera Branch +Al Wajh +Abū Ḩamad +Godinlabe +Ceel Dheere +Tukuyu +Kyaliwajjala +Āqchah +Krems an der Donau +Bandar Seri Begawan +Kahemba +Gutao +Xiayang +Dongxishan +Xiazhai +Jieshangya +Saoula +’Aïn el Turk +Semera +Bogoso +Tammampatti +Sujānpur +Shiv +Bhattu Kolān +Downers Grove +Louveira +Florin +Al Khārjah +Sihorā +Chatrā +Rovigo +Parāsia +Satte +Chake Chake +Middelburg +Cypress +Chahār Dangeh +Simraungaḍh +Porvoo +Ejeda +Muktāgācha +Janīn +Shankou +Al Ma‘allā’ +Bigadiç +Erftstadt +Lörrach +Stouffville +Hilsa +Poprad +Cuxhaven +Tepeapulco +Neyrīz +Pananaw +Xankəndi +Boaco +Nohar +Gediz +Gronau +Ain El Aouda +Östersund +Ostrołęka +Cerquilho Velho +Hannan +El Meghaïer +Concepción +Novovolynsk +Jeffersonville +Karapınar +Bhainsa +North Bethesda +Çine +Itupiranga +Pontevedra +Selibe Phikwe +Perintalmanna +Padrauna +Bignay +Albi +Gualán +Azusa +Yeovil +Coral Gables +Ridder +Wagga Wagga +Canguçu +Nanao +Zyryanovsk +Laval +Perambalūr +Chesterfield +Irákleio +Noshiromachi +Coelho Neto +Shawinigan +Aversa +Rosario +Kandangan +Pirot +Cimitarra +Sosúa +McLean +San Juan del Cesar +Huancavelica +Saint-Herblain +Kizhake Chālakudi +Mojo +Leonberg +Dumarao +Sesimbra +Mpigi +Sulleru +St. Louis Park +Araklı +East Honolulu +San Pedro +Rheda-Wiedenbrück +Gao +Shakhtarsk +Bad Oeynhausen +Peddāpuram +Novovyatsk +Payyoli +Tomisato +María la Baja +East Brunswick +Santa Lucía del Camino +Kameyama +Monte Alto +Bedford +Mājalgaon +Noveleta +Catemaco +São Bento do Una +Villaguay +Singen +Battipaglia +Gennevilliers +Özgön +Pen-y-Bont ar Ogwr +Nowshahr +Prudentópolis +Suzaka +Prattipādu +Scandicci +Kiblawan +Karlovac +Ksar Hellal +Santiago +Arifiye +Mulukukú +Freising +Sebeta +Mozhga +Wandan +San Severo +Bagumbayan +Haripur +Mbouda +Goba +Kapadvanj +Mailiao +Edenvale +Odiongan +Euclid +Bergkamen +Asakura +Higashiura +Kizlyar +Joliette +Buguruslan +Zargar +Agustín Codazzi +Tuodian +Lawrence +Tennala +Fangcun +Baicheng +Cintalapa de Figueroa +Carmen +Midori +Ceres +Samaniego +Yong’an +Straubing +Qalāt +Kaédi +University +Notsé +Rāmnagar +Biloxi +Tunuyán +Luleå +San Marcos +Slonim +Saray +Suresnes +Luwero +Guozhen +Hikari +Kefamenanu +Malabang +Sungurlu +Yamaga +El Dorado Hills +Nahuizalco +Pio Duran +Naugachhia +Ardea +Lesnoy +Frankenthal +Karlovy Vary +Vinzons +La Libertad +Port-Vila +Bornheim +Ōamishirasato +Misterbianco +Cerritos +Nizāmpur +Farajok +Sông Đốc +Jaggisettigūdem +Dulag +Rye +Changyŏn +Valladolid +Suwa +Burleson +Libona +Eltham +Fouka +Portage +Rimouski +Al Mayādīn +Barnstable +Courtenay +Alcala +Upplands Väsby +‘Akko +Kangar +Dublin +Panay +Dumingag +Nomimachi +Jiménez +Couva +Hampstead +Godda +Telerghma +Takeochō-takeo +Empoli +Tājūrā’ +Bādurpalle +Washington +Santo Domingo Suchitepéquez +Saint-Priest +Vertientes +Waalwijk +Shimotsuchō-kominami +Aïn Fakroun +Cacongo +Vincennes +Chikugo +Jales +Nikaweratiya +Bastia +Ocotal +Sanare +El‘ad +Sesto Fiorentino +Tunglangan +Tucano +Poway +Lal-lo +Cedar Hill +Harderwijk +Verrettes +Boucan Carré +Dongzhang +Takahama +Everett +Mladenovac +Koduvalli +Garmsār +Guntakal Junction +Gooty +Mantova +Brejo da Madre de Deus +Roman +Stillwater +Barendrecht +Colcapirhua +Amora +Caraballeda +Zaječar +Bantvāl +Barotac Viejo +Angol +Soest +Leiktho +Batajnica +Titusville +Namtu +Yenangyaung +Martigues +São Joaquim da Barra +Omitama +Masagua +Orangetown +Cwmbran +Inabanga +Suzukawa +Nyaungu +Sutton in Ashfield +Siocon +Kīlvishāram +Begoro +Liujiaxia +Niagara Falls +Khairābād +’Aïn Azel +Kyle +Jasdan +Etterbeek +Upperu +Kawkareik +Leesburg +Pedreira +Chieti +Mangalapādi +Kurganinsk +Wakema +Dollard-des-Ormeaux +Asadābād +West Orange +Babaeski +Kozlu +Minalin +Welwyn Garden City +Damāvand +Erlin +Waterford +Stade +Collegno +Beni Yakhlef +Kalima +San Pedro Mixtepec +Alsdorf +Alajuela +Grasse +IJmuiden +Mandeville +Upper Buchanan +Tuba +Levakant +Asunción Mita +Vite +Kara-Balta +Nong Khai +Beypazarı +Jiashizhuangcun +Westfield +Mahayag +Ishigaki +Berastagi +Chhāgalnāiya +Titao +Little Elm +Morden +Dongshan +Çan +Duyên Hải +Santa Rita +Homnābād +Joshīmath +Sanmu +Qulicun +Dachau +Smethwick +Hāgere Hiywet +Shuishang +Florida +Playas +Middletown +Gumia +Alta Gracia +Finike +Kirkcaldy +Shelekhov +Faya +Bokāro +North Highlands +Ami +Durham +Dornbirn +Bacolor +Balimbing +Tuckahoe +Wake Forest +Scafati +Minot +Araci +Roswell +Nettuno +Colonia del Sol +Bocaiúva +Aquidauana +Kanye +Kashira +Monroe +Hennef +Tunduru +Liutuancun +Santangpai +Nāngal Township +Ena +Monopoli +Yongping +Cuetzalan +Ash Shaykh Badr +Kasuya +Iwakura +Okhtyrka +Basoko +Sadāseopet +New Washington +Hoskote +Barras +Clondalkin +Carepa +Bhamo +Wauwatosa +Bothell +Birendranagar +Glenview +Vila Verde +Tibigan +Figueras +Dyero +Chong Nonsi +Rockwall +Báguanos +Golpāyegān +Jalandhar Cantonment +Cornwall +La Reja +Hørsholm +Pativilca +Jiquilisco +Monte Santo +Luwuk +Donetsk +Wilson +Victoriaville +Oranienburg +Bhatkal +Higashine +Güroymak +Águeda +Ad Darwa +Al Madrah Samā’il +Tremembé +Dūngarpur +Mamburao +Diamantina +Rancho Santa Margarita +Chandrāwāda +Kamidani +Zawiercie +Monte Carmelo +Ocosingo +Vale de Cavalos +Montrouge +Amahai +Ambatondrazaka +Pabellón de Arteaga +La Mirada +Georgina +São Benedito +Tonami +Antelope +Hilo +San Lorenzo +Invercargill +Longchamps +Gracias +Landau +Ono +Yumbe +Chetouane +Al Aaroui +Gavá +Hitachi-ota +Dumka +‘Āmūdā +Yecun +Kokkola +Catriel +Helsingør +Chioggia +Sogod +Pampán +Vich +Mairena del Aljarafe +Lamía +San Luis Obispo +Puerto Lempira +Bunawan +Rengam +Gaocheng +Okaya +Buena Vista Tomatlán +Aznā +Egg Harbor +Changanācheri +Dalaman +Poso +Roseville +Newark +Dülmen +Campi Bisenzio +Umarkhed +Serowe +Liuhu +Inđija +Perth +Zutphen +Atarra +La Vega +Altos +Osório +Chaparral +Malinao +Nanto +Lousada +Villa Constitución +Chenalhó +Penco +Voluntari +Vryheid +Sanski Most +Barnet +Sayanogorsk +Wejherowo +Jobabo +General Martín Miguel de Güemes +Sumisip +Qasbat Tadla +Aubagne +Kifisiá +Saint-Malo +Azhikkōd +Azhikkal +Kingisepp +Rio de Mouro +Arsenyev +Loum +Mentor +Talghar +Ocoee +Évreux +São José de Mipibu +San Andrés de Sotavento +Mataquescuintla +Gosen +Snizhne +Cunén +Oued Sly +Ayapel +Vikramasingapuram +Perinton +Waspán +Melle +Jiāganj +Livny +Manappārai +Kasumbalesa +As Sa‘dīyah +Rowland Heights +Zhongtanying +Evesham +Kikugawa +Douz +Otradnyy +Děčín +La Courneuve +Fort Pierce +Albuera +Rivoli +Yabrūd +Urrao +Sidrolândia +Capão Bonito +Cumanayagua +Paderno Dugnano +Ayungon +Pilar +Brea +Cantel +Şowme‘eh Sarā +Mattanūr +Campobasso +Qingyuan +Zarzal +Oro Valley +Chaïdári +Dracena +Hagaribommanahalli +Hà Tiên +Pallipālaiyam +Calimaya +Corato +East Providence +Saranambana +Dahutang +Al Balyanā +Banisilan +Haeryong +Casalnuovo di Napoli +Liulin +Viti +Santo Domingo +Jitaicun +Cuilapa +San Benedetto del Tronto +Nandikotkūr +Herzogenrath +Chomutov +Tomioka +Esplugas de Llobregat +Selu +Stretford +Vyshniy Volochëk +Soest +Maţāy +Mēla Gūdalūr +Martina Franca +Valencia +Boujad +Campo Maior +Borgne +Kabasalan +Neunkirchen +Poções +Lecco +Banbury +Beckenham +Noboribetsu +Blois +Pearl City +João Pinheiro +Lørenskog +Nanzhuangzhen +Greenford +Lohja +Santiago +Isabel +Ayr +Teotihuacan +San Jacinto de Buena Fe +Santa Ana Chiautempan +Al Quşayr +Araioses +Kotelniki +Wokingham +Hyvinkää +Rovenky +Salina +Lukavac +Jesús Menéndez +Sanuki +La Jagua de Ibirico +South Brunswick +Taebaek +Stepnogorsk +Guaramirim +Cologno Monzese +Woodstock +Punalūr +Kampli +Bizerte +Yashan +Ramat HaSharon +La Caleta +Kuilsrivier +Norala +Nellikkuppam +Daxiang +Ridderkerk +Hioki +Dongnanyanfa +Padra +Fujiyoshida +Schwerte +Hof +Muara Teweh +Yalvaç +Wangtan +Libertador General San Martín +Puerto Villarroel +Suluova +Brive-la-Gaillarde +Zarinsk +Bruchsal +Langford Station +Beavercreek +Obra +Faratsiho +Ḩajjah +Nakai +Quinte West +Montevista +Schagen +Lucaya +Aland +Dori +Tuy +Winter Garden +Puñal +Ḩadīthah +Potomac +Lower Tungawan +Świętochłowice +Gryazi +Vuyyūru +Cordon +Kadinamkulam +Corroios +Mānvi +Jendouba +Farmington +San Francisco de los Romo +Jeomchon +Henrietta +Santa Cruz do Rio Pardo +Nelson +Skierniewice +Kita +Rodgau +Albstadt +Río Tercero +Pakenham +Alcira +Sardasht +La Independencia +Quva +Charleville-Mézières +São Bento +Manacor +Lissone +Attleboro +Starogard Gdański +Nilambūr +Shimenzhai +Kilmarnock +Marino +Meudon +Cuihua +Bhālki +Halle-Neustadt +Pagalungan +Bindura +Ban Plai Bua Phatthana +Starachowice +Vidin +Kurayoshi +Farim +Cobija +Zhongzhai +Douera +Anandpur +Capannori +Kouré +Takashima +Nichelino +Pilar +San Lorenzo +Talisay +Narvacan +Aranđelovac +Santana do Ipanema +Carcassonne +Berëzovskiy +Izunokuni +Shimeo +Huntsville +Lawas +Chitré +Tingo María +Megion +Filderstadt +Labutta +Puerto Tejada +Strongsville +Zhob +Seabra +Tlalmanalco +Choisy-le-Roi +União +Manono +Casimiro de Abreu +Eagle Mountain +Noisy-le-Sec +Borča +Sumpango +Kasaoka +Bridgewater +Jammalamadugu +Acaxochitlán +Beringen +Garhwa +Santurce-Antiguo +San Felíu de Llobregat +Prescott +Sikandra Rao +Cavaillon +Eusébio +Nova Venécia +Bothaville +Bünde +Livry-Gargan +Tombôco +Nawāshahr +Trenque Lauquen +Gotha +Rānāvāv +Mairinque +Bihāt +Gahini +Mindat +Bājil +Huilongcun +Camp Perrin +Amboasary +Isiolo +Ḩarastā +Ban Bang Mae Nang +Kikuchi +Dingle +San Rafael +Jaguaquara +Markala +Santiago +Coonoor +Wodzisław Śląski +Thoubāl +Tamagawa +Paraguaçu Paulista +Freeport City +Olive Branch +Ourém +Haymana +Lupao +Donggang +Hokota +Lumba-a-Bayabao +Fastiv +Arlington +Joal-Fadiout +Koupéla +Campo Novo do Parecis +Chepén +Fellbach +Arendal +Stavroúpoli +Dharmaragar +Middletown +Juína +Parys +Goose Creek +Memmingen +Tallbīsah +Sicklerville +Chajarí +Igarapé +Pākaur +Settimo Torinese +Shima +Cheshunt +Jablonec nad Nisou +Shertallai +Havant +Aribinda +Hexiwu +Dodoma +Phan Rí Cửa +Anshan +Kaufbeuren +Nawai +Lubny +Salvador +Altamonte Springs +Badrashni +Haltom City +Ouled Moussa +Borgerhout +Gollalagunta +Hackensack +Dongsu +Tantangan +Dialakorodji +St. Thomas +Maluso +Rājgarh +Muradiye +La Goulette +Changchong +Yambio +Santa María Huatulco +Farrukhnagar +Dendermonde +Puttalam +Hokuto +Shangpa +Rosny-sous-Bois +Elmhurst +Mislata +Torzhok +Ogimachi +Porangatu +Jones +Chattamangalam +Denia +Remedios +Tangdukou +Tindouf +El Valle del Espíritu Santo +Qianjiang Shequ +Urbandale +Kitakata +Caiguantun +Nueva Gerona +Baiji +Ascoli Piceno +Kirkby +Mauriti +Los Banos +Río Cauto +Guacharachi +Talagutong +Kumta +Busaar +Littleton +Cuautepec de Hinojosa +Ortega +Sangarébougou +Veldhoven +Canela +Voi +Kanash +Warud +Ashburn +Salisbury +Kariya +Gaya +Lalian +Bāfq +Surčin +Lábrea +Kerkrade +Birāk +Carnot +Ganapathivattam +East Lansing +Olhão +San Pelayo +Fuxing +West Seneca +Mbulu +Palayan City +Jipijapa +Gobārdānga +Barra Velha +Bountiful +Erith +San Antonio Abad +Nazarovo +San Isidro +Ciudad de Huajuapam de León +Keller +Svitlovodsk +Karmiel +Vallenar +Morgan Hill +Gaoua +Rieti +Saint-Eustache +Weinheim +Puławy +Neustadt am Rübenberge +Hinckley +Ruzayevka +Tayug +Misséni +Radā‘ +Talence +Kelo +Jaraguá +Webster +Chimteppa +Gračanica +Sierra Vista +Cornélio Procópio +Vercelli +Manchester +Ashton +Gaoua +Drachten +Araquari +Medemblik +Paterno +Inongo +Banī ‘Ubayd +Presidente Dutra +Belfort +Garango +Hassi Messaoud +Sayreville +Basud +Surbiton +Numata +Puertollano +Marau +Massigui +Montemorelos +Castleford +Chalungalpādam +Aguilar +Bingmei +Aksay +Nova Kakhovka +Concepción +Inuma +Krosno +Arantāngi +Nāyudupet +Maracaju +Caeté +Alfortville +Haugesund +Bắc Kạn +Sundargarh +Abqaiq +Chalon-sur-Saône +Odenton +Prievidza +Biləcəri +Heusden +Slavonski Brod +Shchūchīnsk +Lapa +Cleveland Heights +Pakxan +Batroûn +Shaḩḩāt +Parma +Kutum +Nimule +Jedeïda +Baba I +Mladá Boleslav +Rabinal +Mahālingpur +Bhāyala +Nalegaon +Muddebihāl +Kedgaon +Sachīn +Ālamūru +Qarabulaq +Dīg +Hekou +Tank +Næstved +Barnagar +Brianka +Marhanets +Tres Valles +Angadanan +Timbó +Acopiara +Maria Aurora +Gallatin +Āstāneh-ye Ashrafīyeh +Plainfield +Nadym +Yatağan +Palm Springs +Mount Laurel +Seregno +Lancaster +Pederneiras +Catford +Tarnobrzeg +Port Loko +Borlänge +Razgrad +Charkhi Dādri +Āz̄arshahr +Buguias +Sagua de Tánamo +Shangshan +Shazhou +Dois Vizinhos +Volkhov +Guledagudda +Al ‘Azīzīyah +Tateyama +Bolívar +Riverton +West Lafayette +Parigi +Rāmeswaram +Santiago Atitlán +Meoqui +Xinji +Port Macquarie +Brentwood +Lehrte +Colotenango +Nasipit +‘Ayn al ‘Arab +Barru +Mochudi +Santa Bárbara +Merksem +Falkensee +Brühl +Santana do Paraíso +Manjuyod +São Lourenço +Balcarce +Jidd Ḩafş +Pemangkat +Sakura +Zwijndrecht +Chichigalpa +Liuquancun +Xique-Xique +Kimry +Cutler Bay +Cascina +Itaberaí +Worksop +Salon-de-Provence +San Pedro Perulapán +Melūr +Terracina +Lake Ridge +Whitney +Dhupgāri +Kafr al Baţţīkh +Sapanca +Sète +Pahrump +Lodi +Flores +Yaopu +Tangjiacun +Soliman +Mount Pleasant +Katipunan +Zamalkā +Bhārella +Kharan +Zouerate +Pyu +Dowlaiswaram +North Lauderdale +Concepcion +Portugalete +Dolores +Conceição do Araguaia +Xiluo +Jacaltenango +Kitgum +Fairfield +Sainthia +Gogrial +Mamanguape +Grabouw +Upper Bicutan +Wentzville +Istres +Augusto Correa +Tori-Bossito +Alcamo +Guisa +Jangamguda +Arboletes +Cayambe +Salem +Mawlaik +Mantes-la-Jolie +Piendamó +Garça +San Vicente +Fond du Lac +Seferhisar +Otwock +Gori +Nsawam +Culasi +Jalacingo +Petatlán +Shekhupur +Masuda +Tsiroanomandidy +Wiener Neustadt +Rohnert Park +Ellenabad +Banaybanay +San Pascual +Mankato +Moorhead +Radomsko +Morley +Karvārakundu +São Sebastião do Passé +Rāpūr +Abū al Maţāmīr +Siyāna +Abovyan +Angul +Bacnotan +Rājaldesar +Robē +Elmadağ +Tongoma +Yaoquan +Santo Antônio da Platina +Sandefjord +Bulalacao +Dalli Rājhara +Houbu +Svishtov +Nandigāma +Vlissingen +Beigangwa +San Jacinto +San Juan y Martínez +Eqlīd +Kołobrzeg +Iwanuma +Kaimana +São Miguel d’Oeste +Pagsanjan +Changtoushang +The Colony +Jisr ash Shughūr +Nanjō +Deinze +General Mamerto Natividad +Çayeli +Barwāh +Chauk +Alaplı +Pinneberg +Labangan +Bom Conselho +Dráma +Sonqor +Medak +Kaarst +Talipparamba +Huatan +Manakara +İznik +Jora +Pattani +Burke +Loon +Saint-Brieuc +Ananipalle +Erkelenz +Majurwa +Freeport +Cateel +Miliana +Tiberias +Maitum +Regla +El Centro +Dikili +Germencik +Al ‘Ayyāţ +Kuybyshev +Rio Grande da Serra +Las Matas de Farfán +Raisen +Albufeira +Harsīn +Turnhout +Shakopee +Central Signal Village +Wilkes-Barre +Mandaon +West Vancouver +Hagi +Daijiazhuang +Tōgō +Tlajomulco de Zúñiga +Roghun +Yartsevo +Zevenaar +Lompoc +Hicksville +Talatamaty +Noordwijk +Jānakammapeta +Georgetown +Oakland Park +Lombard +Otofuke +Concord +Sihora +Dębica +San Vicente de Tagua Tagua +Guinayangan +Al Midhnab +Nocera Inferiore +Murshidābād +Senigallia +Vilvoorde +Boyabat +Korogwe +Ahmadpur +Tinajdad +Limache +Seohāra +Yuchengcun +La Paz +Mucaba +San Jose +Coatbridge +Tarbes +New Tecumseth +Casale +Labason +Yuanli +Bakamune +Goshikichō-aihara-minamidani +Livramento de Nossa Senhora +Comendador +Alès +Wānkāner +Loreto +Wismar +Châlons-en-Champagne +Zongolica +Etten-Leur +Erkrath +Addanki +Berkeley +Hinatuan +Wallsend +Merthyr Tudful +Yirga ‘Alem +Nidadavole +Ciudad Constitución +Beni Saf +Xinjun +Baler +Bellinzona +Varaždin +Anekal +Āzādshahr +Jaro +Rasskazovo +Bietigheim-Bissingen +Sugito +Salto de Pirapora +Himi +Lubuk Sikaping +Shyorongi +Ząbki +Chusovoy +Badian +Thun +Murzuq +Kottangara +Pittsfield +Venray +Kalilangan +North Brunswick +Takāb +Cameron Highlands +Bushenyi +Maştağa +Bagneux +Porsa +Bodupāl +Krasnodon +Tanghin-Dassouri +Alhaurín de la Torre +Puteaux +Rāmachandrapuram +Greenacres +Chembra +Gifhorn +Jinku +Shinshiro +Nijkerk +San Isidro +Santa Elena +Raduzhnyy +Roseller Lim +Villeta +Birsk +Caluire-et-Cuire +Kumatori +Uruará +Cové +Guambog +Prostějov +’Aïn Arnat +Zhexiang +Presidente Epitácio +Shōranūr +Ksar +Rheden +Oakley +Panambi +Kiraz +Jerada +Cimerak +Of +Ponte de Lima +Çeşme +Borken +Bahía Honda +Linden +Heinsberg +Tarauacá +Campbell +Moises Padilla +Paoskoto +Al Kiswah +Hokuto +Danville +Pedro Celestino Negrete +Toboso +Kikuyō +Kilosa +Frosinone +Loreto +Victoria +Bolvadin +Anse Rouge +Puerto del Rosario +Actopan +De Bilt +Nilothi +Dounan +Trelleborg +Yutiancun +Isla +Jambusar +Xihuachi +Sawākin +Innisfil +Turda +Kozáni +Shināş +Hueyapan de Ocampo +El Cuá +General Pacheco +Kōttōppādam +Douar Bni Malek +El Asintal +Villa de Zaachila +Zhongbu +Lota +San Clemente +Andes +North Miami Beach +Vaudreuil-Dorion +Alenquer +Clermont +Silistra +Vargem Grande +San Sebastián Huehuetenango +Aleksinac +Konārak +Paso de los Libres +Ocozocoautla de Espinosa +Maḩallāt +Kula +Khawr Fakkān +San Bruno +Ambāsamudram +Véroia +Laurel +Yeola +Nagaizumi +Channelview +Vahdat +Shanshan +South Upi +Trujillo Alto +Kapan +Nagykanizsa +Aguazul +Darcheh +Berchem +Dock Sur +Vergína +Şān al Ḩajar al Qiblīyah +Sonaguera +Bāniyās +Zhangliangcun +Chicamán +Cumaribo +Maïssade +Khutubi +Ormond Beach +Rantepao +Kāyalpattanam +Kobayashi +Inabe +Dún Dealgan +Vargem Grande do Sul +Sidcup +Macenta +Eṭ Ṭaiyiba +Bakau +Nettetal +Taketoyo +Huber Heights +Rudauli +Dhāka +Lubao +Tešanj +Dunakeszi +Makinohara +Kamen +Alcantarilla +Bron +Yatomi +Barhiya +Woonsocket +Kattivākkam +Kingston upon Thames +Jesús María +Gualeguay +Hillsborough +Santa Cruz +Garbahaarrey +Saoner +Rezé +Yepocapa +Valenciennes +Abucay +Periyakulam +Cuchi +Lai Châu +Middleton +Aurich +Châteauroux +Jatibonico +Heist-op-den-Berg +Santo Antônio +San Cristóbal Totonicapán +Nandongcun +Nandazhang +Buffalo Grove +Badulla +Akdağmadeni +Char Fasson +Zhangcun +Bairāgnia +Sevanagala +Pirthīpur +Bradford West Gwillimbury +Tepalcatepec +Villaba +Shimabara +Mahbūbābād +Santo Tomas +Garges-lès-Gonesse +Fleet +Kalaiyā +Longtoushan Jiezi +Lucena +Puerto Colombia +King’s Lynn +Salaberry-de-Valleyfield +Chefchaouene +Laguna +La Mata +West Babylon +Ban Pet +Nueva Valencia +Al Badārī +Limbdi +Catonsville +Barreiros +Atenco +Mrirt +Itarema +Altadena +Bukama +Naranjo +Ciechanów +Edmonds +Lokeren +Gravina in Puglia +Linton Hall +Thol +Spanish Fork +Hammam Sousse +Newnan +Sarıkamış +Taniyama-chūō +Musina +Orlândia +Meru +Jincheng +Laatzen +Castres +Proper Bansud +Nakano +Quinhámel +Vineyard +Evere +Mengdong +Cabo Bojador +Kafr al Kurdī +Barpeta +Jefferson City +Webuye +Miranda +Kharik +Sidi Mohamed Lahmar +Mondoro +El Affroun +Sukheke Mandi +Manassas +Tecoanapa +Biella +Woodbridge +Zharkent +Puyallup +San Francisco Menéndez +Fianga +Arras +Šibenik +Awaji +Sālār +Nyunzu +Hwange +Simão Dias +Shuilou +Vera Cruz +Machalí +Mata de São João +Panitan +José de Freitas +Thomassique +Jājpur +Sokoura +Tamu +Uruaçu +Allūru +Schertz +Guarda +Amberg +Maroantsetra +Balabac +El Charco +Kōta +Loufan +Kadalur +Coppell +Itapa-Ekiti +Danville +Mariel +North Fort Myers +San Giorgio a Cremano +Jambughoda +Columbia +Dupnitsa +Bairuo +Shebekino +Osinniki +La Orotava +Moline +Seevetal +Kārsiyāng +Dilbeek +Tucuran +Singhanakhon +Sanarate +Carranglan +San Rafael del Sur +Santa Cruz +Beverly +Eisenach +Si Sa Ket +Midland +Xidiancun +Bassano del Grappa +Bang Kruai +Bhatpalli +Santa Rita +Alghero +Balykchy +Melun +Kotabumi +São Mateus do Sul +Thān +Acatlán de Pérez Figueroa +Laungowāl +Akaiwa +Shenjiatun +Annandale +Yaguate +Qā’en +Ben Zakkay +Rouyn-Noranda +Tomé +Iten +Xonobod +Pallisa +Homburg +Kasai +Llanera +Futtsu +Coachella +Coronel Suárez +Alerce +Polanco +Dreieich +Maniwa +Kutno +Hoddesdon +Myanaung +Marki +Akbarpur +President Quirino +Woodlawn +Viborg +Palladam +Uozu +Ansbach +Hilvan +Liloy +Fareham +Meadow Woods +Kārmegh +Aritao +Smederevska Palanka +Machang +Sarakhs +Coram +Qapshaghay +Jocotepec +Thionville +Amontada +Mozdok +Belleville +Nysa +Morarano Chrome +Safonovo +Peachtree Corners +Claveria +Liantang +Ängelholm +Anakaputtur +Diyadin +Cortlandt +Dildārnagar +Cáceres +Jinotepe +Pardés H̱anna Karkur +Kālol +Monchegorsk +Hollister +Villa Bisonó +Sbiba +Bensheim +Esperanza +Pratāpgarh +Bokhtar +Coyuca de Catalán +Puerto Real +Paraíba do Sul +Guaratuba +Quesada +Imperia +Soran +Sarāb +Guaraciaba do Norte +Zhovti Vody +Siegburg +Tineghir +Madridejos +Mampong +San José de Bocay +Miercurea-Ciuc +Holly Springs +Wangyuanqiao +Korenovsk +Nāthdwāra +Dronten +Pā̃chkhāl +Ti̇̄npiple +Santa Rosa del Sur +Štip +Myedu +Songhuajiangcun +Qiryat Moẕqin +Lingquan +Muttayyāpuram +Vawkavysk +Greenock +Matnog +São Lourenço do Sul +Nāikankudi +Mercedes +Puerto Galera +Zhujiacun +Yangcunzai +Yagoua +Nuevo San Carlos +Kolchugino +Hódmezővásárhely +Tactic +Delaware +Hố Nai +Santa María Atzompa +Tiel +Ōizumi +Kirchheim unter Teck +Tororo +Minamishimabara +Amadeo +Qiryat Ono +Schwäbisch Hall +Kibawe +Ban Wat Lak Hok +Larantuka +Barauli +Dunaújváros +Beverwijk +Macaúbas +Montenegro +Kalmar +Marialva +Quezon +Coburg +Yinggen +Tadjenanet +El Aïoun +Urmston +Coyotepec +San Miguel +Miura +Palmares +Rancho Palos Verdes +Diamond Harbour +Waxahachie +Jardinópolis +Satka +Civitanova Marche +Tādif +Köniz +Uden +Sūrampatti +Velasco Ibarra +Kasibu +Paiçandu +Krasnoznamensk +Beitbridge +Dacun +Nārāyanpet +Tôrres +El Consejo +Naga +Boucherville +Santa Bárbara +Fenoarivo Atsinanana +Saidpur Dabra +Shādegān +Dandéresso +Bodø +Álimos +Campechuela +Otavalo +Tavas +Varash +Oued Fodda +Billerica +Tolosa +Kampong Chhnang +Salinas +Ust’-Kut +Wunstorf +Hempfield +Boumerdes +Pueblo Nuevo +Gonzaga +Litian Gezhuang +Blanes +Bayt al Faqīh +Mableton +Jáltipan de Morelos +Přerov +Fitchburg +Gay +Kenge +Daram +Ambohitrimanjaka +Yuzawa +Oqtosh Shahri +Shefar‘am +Le Cannet +Berubāri +Ayagöz +Bullhead City +Su-ngai Kolok +Rājgīr +Socorro +Santa Cruz de Los Taques +Shetou +Sipe Sipe +San Pedro Necta +Dubrovnik +Santa Helena +Lloret de Mar +Indi +Amuntai +Rajaori +Slobozia +Lindi +Anda +Águas Belas +Patulul +Yarumal +Copán +Strezhevoy +Tagudin +San Donà di Piave +Nalhāti +Ruteng +Ventanas +Sānand +Puntarenas +Bourg-en-Bresse +Mission +Puerto Gaitán +Barra dos Coqueiros +Poti +Shimotsuma +Königswinter +Zugdidi +Kodīnar +Sagauli +Golāghāt +Pīleru +Verkhnyaya Salda +Sutton +Marlboro +Karabulak +Sinanpaşa +Llavallol +Desio +Nola +Eberswalde +Memāri +Banī Suhaylā +Tabogon +Teaneck +Svay Rieng +Grove City +Arcos +Lusambo +Mondragon +Yakacık +Maplewood +Kendrāparha +Villa Ángela +Nürtingen +Caerphilly +Marion +Nebbi +Marlborough +Tortuguitas +San +Myski +Naini Tal +Erzin +Santa Cruz +Maulavi Bāzār +Bambari +Germering +Kitaibaraki +Sena Madureira +Tuchín +Narathiwat +Brookfield +Obita +Nordhausen +Tezoyuca +Rāmganj Mandi +El Tocuyo +Santo Antônio de Pádua +Nurdağı +Currais Novos +Mahalapye +Meïganga +Arauquita +Hückelhoven +San Lorenzo +Alcala +Tabarka +Caloundra +Alcalde Díaz +Bridgwater +Leigh +Jayamkondacholapuram +Cherupulasshēri +Mikołów +Guácimo +Hatfield +Wijchen +Panchimalco +Mersa +Niquero +Chaves +Fredericia +Rozzano +French Valley +Santa Eulalia del Río +Schwabach +Schweizer-Reineke +Maayon +Lasam +Hoboken +Mangaratiba +Bacong +Constitución +Shelton +Túquerres +Nossa Senhora da Glória +Trikarpūr North +Shutayil +Agar +San Jose de Urquico +Tanxia +Zákynthos +Antequera +Claypole +Pine Bluff +Peddapalli +Igualada +Kearny +Villa Alsina +Sevilla +Anglet +Geel +Bilāsipāra +Timmins +Halfeti +Guaduas +Toritama +Temryuk +Matiguás +Spassk-Dal’niy +Paliā Kalān +José Mármol +Hālol +Ganta +Kallār +Hallandale Beach +Mambajao +Germantown +Huizen +La Libertad +Angoulême +Ardeşen +Sevilla de Niefang +Rivas +Ambositra +Newbury +Merano +Bujanovac +Komoro +Ishaka +Sumoto +Tagbina +Amami +Pozi +Arraiján +Milton +Tampakan +Unzen +Ciudad Darío +Bazar-Korgon +Ciudad Vieja +Pyt’-Yakh +Upper Hutt +Gatunda +Sarandë +Dongyangshi +Shengaocun +Dongluocun +Segovia +Chambas +Welling +Woburn +Beigang +Hongfengcun +Wujie +Monterotondo +Patti +Esperantina +Marikina Heights +Lancaster +Paranaíba +Drogheda +Bagua Grande +Nanbei +Dowlatābād +Maddela +Lijiaxiang +Reynoldsburg +Yingzhou Linchang +Covington +Salinópolis +Azemmour +Famagusta +Buxtehude +Ciudad Piar +Dhamdāha +Boulogne-sur-Mer +Muaná +Velika Plana +Delījān +Jalalpur Bhattian +Pugachev +Friendswood +Talukkara +Meftah +Penn Hills +Betun +Apóstoles +Weslaco +Malilipot +Patzicía +Santo Tomas +Land O' Lakes +Essex +Tālcher +Soe +Wattrelos +Cuito Cuanavale +Bartlett +Promissão +Anyuan +Qādiān +Fourou +Mobo +Pāmban +Abadan +Buchholz in der Nordheide +Neumarkt +Ahlat +Saint-Germain-en-Laye +Kitob +Westfield +Temsia +Vallehermoso +Swords +Vavveru +Elmalı +Gonābād +Sidi Moussa +Baichigan +Lobo +Sassuolo +Kingswood +Pie de Pató +Buddh Gaya +Shanhe +Katō +Kirkkonummi +Khowrmūj +Annapolis +Villafranca del Panadés +Arys +Ipiaú +Dunstable +DeKalb +Vasto +Mambusao +Maragondon +Cedar Falls +Pirmasens +Itabaianinha +Qeshm +Tomar +Sukuta +Kadūr +Sint-Truiden +Mundakkal +Sherghāti +Nanuque +Veles +Bury Saint Edmunds +Zoumi +Avezzano +Artigas +Ladispoli +Pechora +Barra de São Francisco +Dayr Mawās +Manalapan +Santa Rita do Sapucaí +Nabas +Akyurt +Evren +Yangtangxu +Yatangcun +Lancaster +Njombe +Douar Laouamra +Şəmkir +Pôrto de Moz +Lemgo +Pilāni +Remanso +Siay +Bayındır +Nowgong +Santa Maria da Boa Vista +Metlili Chaamba +Brighton +Bayburt +Ölgiy +Bosconia +Jānjgīr +Uray +Romblon +Andradas +Padre Las Casas +Katsuren-haebaru +Lordegān +San Juan +Villenave-d’Ornon +Gap +Macerata +Cumbal +Guariba +Sovetsk +Freiberg +Erramvāripālem +Corigliano Calabro +Mińsk Mazowiecki +Crystal Lake +Dacun +Halberstadt +Lake Oswego +Severna Park +Pilate +Sosnovoborsk +Krishnarājāsāgara +Rizal +Leinfelden-Echterdingen +Villanueva +Lakeshore +Ramsgate +Findlay +Mārākkara +Huaura +Aracataca +Channarāyapatna +Montélimar +Leyte +Compiègne +Saratoga Springs +Alexandria +New Berlin +Pālampur +Agano +Chebarkul +Hofheim +Reguiba +Zainsk +Almenara +Jhābua +Stains +Vellakkovil +Culver City +Bouar +Beyneū +Curuçá +Balaoan +La Unión +Rubengera +Sabalgarh +Sensuntepeque +Molina +Komono +Kualaserba +Indian Trail +Bañga +Romny +Magburaka +Hellevoetsluis +Payabon +Talas +Colinas +Ampana +Murtajāpur +Kamen’-na-Obi +Peringalam +Autazes +Ōzu +Duncanville +Valley Stream +Yajalón +Belaya Kalitva +Kardítsa +Löhne +Pinamar +Tosya +Ahaus +Afogados da Ingazeira +Majibacoa +Hıdırbey +Fonds Verrettes +Clinton +Camargo +Merta +Uttarkāshi +Boa Esperança +Świnoujście +Schorndorf +Kabuga +Leramatang +Itoigawa +Secunda +El Golea +Havza +Völklingen +Maihar +Begamganj +Gagny +Pedra Branca +Jambe +Santa Quitéria +Salinas +Tiruchendūr +Mokolo +Sejenane +La Rinconada +Myrhorod +The Acreage +Colomiers +Malalag +Balud +Podilsk +Tutayev +Torre Annunziata +Dohazāri +Taysan +Taicheng +Gourcy +Kīlakkarai +Kālimpong +Cihuatlán +Gramado +Romeoville +Oroqen Zizhiqi +Dingras +Heroica Ciudad de Tlaxiaco +Socorro +Phulwāria +Sisak +Luebo +Amursk +Järvenpää +Chiredzi +Soria +Longtang +Raxruhá +Kakrāla +Bragadiru +Santo Domingo +Zagora +Menghan +Hurst +Altagracia de Orituco +Kunigal +Mailapur +Varkkallai +Soavinandriana +Curitibanos +Montana +Mayyanād +Panaji +Poissy +Sieradz +Inverness +Armação dos Búzios +Oraiókastro +Zacualpa +Post Falls +Ihnāsyā al Madīnah +Jbaïl +Matsoandakana +Bukit Gambir +Bandhi +Safdarabad +Jalalabad +Choa Saidan Shah +Ranipur +Lidköping +Kambia +Uchqŭrghon Shahri +Madīnat ‘Īsá +Bamessing +Alashankou +Strood +L’Asile +Chikodi +Rājgarh +Sindgi +Wādegaon +Sardulgarh +Samālkha +Junnar +Salaiya +Tāzah Khūrmātū +Nicastro +Valladolid +Hutchinson +Kasumigaura +Cabatuan +Yalutorovsk +Lishaocun +Herstal +Szigetszentmiklós +Fushë Kosovë +Visoko +Kyaukme +Zimapan +Yian +Santa Cruz del Sur +Jayrūd +Sarāqib +Vyshneve +Xaçmaz +Qiryat Bialik +Brčko +Zhongbai +Chelsea +Santiago Nonualco +Barcellona-Pozzo di Gotto +Ngozi +Acevedo +Waipahu +Lynnwood +Yecapixtla +Sagae +Winslow +Kīsh +Koumra +Northampton +Zvolen +Rāmdurg +Plaridel +Panglao +Braine-l’Alleud +Tago +Matías Romero +Baco +Pinhal +Maintal +Kópavogur +Rauma +Rovereto +Lincoln Park +Huamachuco +Ostfildern +Pamplona +Oshnavīyeh +Villamontes +Sebdou +Amudālavalasa +Fort Lee +’Aïn el Melh +Santo Niño +Cape Girardeau +Atmakūr +Yomitan +Kırkağaç +Palauig +Montclair +Hobbs +Toukountouna +San Nicolas +Carini +Magsaysay +Benenitra +Hangu +Aizawa +Apsheronsk +Massawa +Tivaouane +Maarssen +Draguignan +Shirone +Surin +Novozybkov +Alimodian +Albano Laziale +Kurobeshin +Cantù +Veruela +Pomigliano d’Arco +Caraga +Burjasot +Tianzhong +Ettlingen +Buldon +Masaki +Temascal +Oshakati +Talacogon +Srebrenik +Ţabas +Tulun +Kovvūr +Líbano +Fonseca +Carol Stream +Plant City +Xisa +Douai +Todos Santos Cuchumatán +Wageningen +Nakama +Poblacion +Ninove +Yomra +Capelinha +Aventura +Despatch +Bāsudebpur +Charbagh +Pärnu +Tafí Viejo +Vendrell +Şamaxı +Huanghuajie +La Troncal +Isfisor +Villa del Carbón +Skövde +Manay +Chachoengsao +Villa de San Diego de Ubaté +Jordan +Lebanon +Freital +Djidian Kéniéba +Salcedo +Ihosy +Streamwood +Oviedo +Jiaozishan +Tucumã +Fondi +Kalingalan Caluang +Ḑubā +Écija +Mount Juliet +Farīmān +São Gonçalo dos Campos +Nova Viçosa +Virreyes +Media +Ossining +La Tebaida +Itápolis +Lilio +Pachrūkha +Brant +Siniloan +Alicia +Doğanşehir +San José de Ocoa +Sogod +San Giuliano Milanese +Quincy +Marratxi +Asamankese +Kalu Khan +Lālganj +Islāmpur +Qiryat Yam +Plasencia +Presidente Venceslau +Parral +Whanganui +Xonqa +Issaquah +Sanjiang +Parkland +Guajará-Mirim +Olintepeque +Khāchrod +Żyrardów +Abinsk +Bādepalli +Sijua +Park Ridge +Bagnolet +Morshansk +Kaffrine +Clarin +Marcq-en-Baroeul +Spruce Grove +Placilla de Peñuelas +Seram +Gradačac +Pamplona +Vādāsinor +Abrantes +Amambaí +Naranjal +Damulog +Jacarèzinho +Puerto Berrío +Cocorote +Cesano Maderno +Sadiola +Cacuso +Tangpingcun +Moanda +Marovoay +Istog +Neu Isenburg +Nueva Santa Rosa +Niederkassel +Jogbani +Galkot +Chojnice +Cottage Grove +Guaíra +Takikawa +Bell Gardens +Oliveira +Matinhos +Rio Negrinho +Tarazá +Solan +Hailākāndi +Al Qā‘idah +Magra +Apan +Tamba-Sasayama +Erattukulakkada +Köyceğiz +Nawābganj +Yuzhnoukrainsk +Langen +Yelizovo +Ospino +Ayirāpuram +San Gabriel +Playa Vicente +Warren +Heemskerk +Kampot +Axochiapan +Androka +Guemar +Baikonur +Visconde do Rio Branco +Cacocum +Masamba +Marcos Paz +Mibu +Bayanan +Security-Widefield +Iesi +Manggar +Mettmann +Grants Pass +Ilmenau +Cakung +Keizer +Idangansālai +Çiftlikköy +Ait Ourir +Stendal +Agoncillo +Chittaranjan +Halle +Sual +Penfield +Moatize +Roy +Nueva Rosita +Susurluk +Pirna +Huanren +Narón +Partāpnagar +San Dionisio +Sidi Bibi +Weißenfels +Lluchmayor +Revelganj +Torre-Pacheco +Marinha Grande +Sébékoro +Camaná +Mitsuke +Kaseda-shirakame +Amla +Rtishchevo +Toumodi +Ambatomainty +Al Mālikīyah +Trofa +Ramallah +Bettendorf +Kachkanar +Cleethorpes +Nuevitas +Betamcherla +Ciudad Melchor Múzquiz +Ancud +Sidi Khaled +Gornji Milanovac +Várzea Alegre +Nongzhangjie +Tromsø +Pala Oua +San Fernando de Henares +Sayansk +Sciacca +La Chaux-de-Fonds +Gabaldon +Nabarūh +Goes +Mafamude +São Fidélis +São Raimundo Nonato +Dibaya-Lubwe +Nallūr +Galeana +Königs Wusterhausen +Yangfang +Brumadinho +Staoueli +Penumūr +Westerville +Caluya +Wālājāpet +Huangyoutang +Garalo +Changchunpu +Juan Rodríguez Clara +San Nicolas +San Raimundo +Tuvāgudi +Empalme +Draa el Mizan +Cabugao +Higashimatsushima +Xiwanzi +Royal Palm Beach +Dwārka +Haverstraw +Birmitrapur +Apache Junction +Pehowa +Inashiki +Taşköprü +Saryaghash +Akçakoca +Tshela +Hitachiomiya +São Mateus do Maranhão +Navarre +Ngororero +Aïn Tedeles +Wheeling +Ohrid +Lake Stevens +Skelmersdale +Santa Helena de Goiás +Nūrpur +Rexburg +Pervomaisk +Ermezinde +Ōmagari +Dubbo +Nyköping +Mehidpur +Tipton +Lambaréné +Campina Grande do Sul +Ban Bang Khu Lat +Eccles +Braintree +Gujō +Fasano +Urbana +Aborlan +Shrewsbury +Valencia +Penalva +Los Palacios +Yoshinogawa +Villepinte +Ouro Branco +Rosenberg +Tinnanūr +Dzhankoi +Barbacoas +Cajibío +Los Palacios y Villafranca +Pinner +Monreale +Taibao +Great Yarmouth +Paracuru +Yako +Real +Sakuragawa +Kwai Chung +Vetapālem +Jamindan +Kamp-Lintfort +Margosatubig +Tonbridge +Tianchang +Zacatelco +West Fargo +Pereslavl’-Zalesskiy +Paravūrkambolam +Tuusula +Považská Bystrica +Ilkeston +Shibata +Mariinsk +Voghera +Armavir +Metlaoui +San José de Las Matas +Ábrego +San Fernando +La Presa +Dabola +Kampung Baharu Nilai +Menomonee Falls +Vengat +Santa Maria da Vitória +Arucas +Vestavia Hills +Calexico +Würselen +Ciampino +Valrico +Aketi +Køge +Schio +Leyland +Ibusuki +Champerico +Leribe +Papenburg +La Vergne +Ban Na Pa +Sungandiancun +Vangaindrano +Strängnäs +Achaguas +Khalkhāl +Aziylal +Glenrothes +Alingsås +Santa Clara del Cobre +Bərdə +Klinë +Rājula +Atlantic City +Konakovo +San Andres +Caibarién +Nishiwaki +Rosário +Sarikishty +Al Ghizlānīyah +La Unión +San Felipe Orizatlán +Ingeniero Pablo Nogués +Emîr Abdelkader +Maasin +Saint-Martin-d’Hères +Coto Brus +Clovis +Mahādeopur +Chartres +Szczecinek +Minas +Saronno +Olutanga +Novodvinsk +Lanyi +Genç +Buug +Chorley +Chacabuco +Peachtree City +Phenix City +Sibaté +Melmadai +Buchireddipālem +Shijiazhuangnan +Hammam-Lif +Qiaotouyi +Darāw +Krasnoufimsk +DeLand +Herne Bay +Vredenburg +Kaka +Usinsk +Fribourg +Miyoshidai +Nindirí +Bougara +Misawa +Mtsensk +Atamyrat +Waregem +Ripollet +Kurchatov +Xiaguanying +Marcianise +Steyr +Patnongon +Alekseyevka +Mechanicsville +Itaitinga +Novo Horizonte +Wilrijk +Nigel +Bayan +Şarkışla +Samal +Chuangjian +Khairtal +Mmabatho +Iturama +Krasnyy Sulin +Azzano +Stanton +Maule +Laur +Tāki +Am-Timan +Siyang +Maibara +Antsohihy +Xiushui +Ibara +Barrancas +Zavolzhye +Matale +Brasschaat +Bat Khela +Città di Castello +Dicle +Menglie +Pitangueiras +Holyoke +Greven +Winter Springs +Américo Brasiliense +Bishops Stortford +Xico +Mechelen-aan-de-Maas +Baksan +Wesseling +Borbon +Joué-lés-Tours +Naushahro Firoz +Porur +Pallipram +Oeiras +Tayasan +Zacualtipán +Kehl +Fereydūn Kenār +Karuvambram +Matozinhos +Choybalsan +Bautzen +Owasso +Bradford +Prattville +Cananea +East Point +Trujillo +Campbell River +Navgilem +Vavuniya +Quba +Entre Rios +Orange +San Germán +Shankarpur Khawās +Shengang +Veghel +Sabang +Clifton Park +Savelugu +Thakraha +San Mateo +Mapandan +Prokuplje +Mantingan +Pacifica +Bol’shoy Kamen’ +Bangar +Dubrājpur +Hot Springs +Shambhunāth +Gūdārah +Aristóbulo del Valle +Zhongdong Shequ +Rūdsar +Abū Qīr +Gurais +San Pédro Jocopilas +Bagabag +Dengtangcun +Sidi Yahia El Gharb +Sama +Tlapa de Comonfort +Mucuri +Olot +Yamen +Adelanto +Backnang +Princeton +San Juan Cancuc +Qaratog +Northglenn +Goribidnūr +Kéniéran +Ali Sabieh +Tupelo +Hajīn +Biougra +La Quinta +Ureña +Sampués +San Adrián de Besós +Annemasse +Raalte +Srīnagar +Puri +Rusape +Shakhtīnsk +Pedro II +Bitterfeld +Dhanera +Guayacanes +Obala +Andkhōy +Świdnik +Giyon +Luuk +Celje +Gampola +Ameca +Namlea +Elmont +Tlalixcoyan +Cerveteri +Dibulla +Mission Bend +Tumba +Gaspar Hernández +Pen +Bangkinang +Montclair +Izobil’nyy +Mateus Leme +Güira de Melena +La Puente +Santaluz +Carpentersville +Koboko +Al Bayḑā’ +Al Qaryatayn +Emirdağ +Santa Pola +Pentecoste +Oleiros +Cheltenham +Cheyyār +Pathanāmthitta +Mahanoro +Kaštel Stari +Teijlingen +Nové Zámky +Tudela +Belleville +Ohangaron +Patía +Sillanwali +San Antonio de Padua +Charaut +San Sebastián de Mariquita +Kwidzyn +Arnold +Santo Domingo +Afuá +Marantao +Rāni +Long Eaton +Prince Albert +Güzelbahçe +Calpulalpan +Jalapa +Karuhatan +Manali +Sun City +Mixquiahuala de Juarez +Mamun +Haedo +Coondapoor +Hanumānnagar +Portage +Mombaça +Gomoh +São Francisco do Conde +Yuzhnouralsk +Matina +San Marcelino +Aklera +Umi +Uchaly +Apia +Hilton Head Island +Jacundá +Melchor Ocampo +Yolöten +Mizunami +Falāvarjān +Rāwatbhāta +Satānā +Tōkai +Custódia +Basavana Bāgevādi +Massapê +Galloway +Vasylkiv +Fürstenfeldbruck +Villagarcía de Arosa +Basista +Sanchahe +Les Abricots +Riviera Beach +Venlo +Tietê +Coalville +Huzūrābād +Monrovia +Yanqi +Kolongo-Bozo +Benjamin Constant +Attingal +Hatta +Malbork +Foothill Farms +Bom Jardim +Jeremoabo +Rome +Uryupinsk +Taounate +Warendorf +Stirling +Su’ao +Rio Brilhante +Malavalli +South Valley +Salto del Guairá +Lampa +New Albany +Sirinhaém +Lewiston +Akhtubinsk +Bolesławiec +Rio Branco do Sul +Kranj +Bamendjou +Villaflores +Dubno +Mira +Paraty +Neuilly-sur-Marne +Winchester +Kahrīzak +Gabú +Greenfield +Franconville +Bletchley +Dalnegorsk +Tuxpan +Perote +Atalaia +Georgetown +Tosno +Phônsavan +El Bordo +Allahabad +Pokrov +Baocheng +Turiaçu +Ma‘arratmişrīn +Itaqui +Teboulba +Don Benito +Tambulig +Bonito +Goryachiy Klyuch +Leighton Buzzard +Paracho de Verduzco +San Carlos +Souma +Tuttlingen +Evans +San Andres +Pleasant Grove +Oras +San Antonio +Lovech +Malgobek +Donji Kakanj +Amargosa +Cansanção +Porteirinha +Santa Rosa de Osos +Samobor +Sārangpur +Sandūr +Yugorsk +Kanigiri +Kérou +Oregon City +Magallanes +Gorinchem +Airdrie +Ambatofinandrahana +Trou du Nord +Shiji +Agudos +Mabuhay +Selçuk +Jaito +Argun +Savigny-sur-Orge +Phulbāni +Progreso +Bayur +Tozeur +Conchagua +Grimbergen +Bečej +Villa González +Eboli +Mullaittivu +Blyth +Fengguangcun +Beckum +Besni +Sitangkai +Luna +Ataq +Bartlesville +Santa Cruz +Al Hāshimīyah +Sanankoroba +Lahār +Falun +Dajiecun +São Manuel +Pilibangan +Tibú +Mariano Escobedo +Göygöl +Port Talbot +Rock Island +Landgraaf +Česká Lípa +Lydenburg +Gajendragarh +Jāle +Yamoussoukro +Paravūr Tekkumbhāgam +Bouznika +Jelilyüzi +Mankayan +Mölndal +Andilamena +Katsuragi +Melgar +Kaman +Hanover Park +Alapayevsk +Vettūr +Comapa +Salvatierra +Rukungiri +Leavenworth +Mangai +Moerdijk +Chunār +Wangsicun +Tunzi +Laindon +Kizilyurt +Rezh +Ratia +Kadiyam +Ciudad Manuel Doblado +Minami-Bōsō +Formia +Silves +Bantay +Bahādurganj +Imbatug +Maşyāf +Obburdon +Qulsary +Adjumani +Qo‘ng‘irot Shahri +Binəqədi +Languyan +Boryslav +Martinez +Amarante do Maranhão +Sittard +Long Lama +Kalutara +Redcar +Jagdīspur +Siribala +Chorkŭh +Prijepolje +Porsgrunn +Cloppenburg +Sitalkuchi +Tokār +Kalinkavichy +Llanelli +Pujali +Kālihāti +Lesozavodsk +Kampene +Coesfeld +Beslan +Thonon-les-Bains +Mol +Holstebro +Lagkadás +Greer +Suhl +Bentota +Mandoto +Manazary +Beeston +Dargot +Dāchepalle +Kyshtym +Granadero Baigorria +Tucker +La Ciotat +Villeta +Pennsauken +Baishi Airikecun +Santiago Sacatepéquez +Dom Pedrito +Stara Gora +Nakodar +Bucha +Richmond West +Nanshuicun +Tabligbo +Shaxi +Oświęcim +Lūnāvāda +Ban Doi Suthep +Aourir +Şuhut +Shengli +Port-Margot +Monatélé +Muskogee +Campos Novos +Guilderland +Moalboal +Dālkola +Bindki +Colón +Santa Ana +Kānkuria +Chaiyaphum +Netishyn +Chimboy Shahri +Basilisa +San Enrique +Segrate +Vavur +Pingxiangcheng +Small Heath +Grugliasco +Penticton +Dagua +Moncada +Claremont +Manucan +Siyabuswa +Musiri +Anosiala +Águilas +Kearns +East Meadow +Pāthri +Fāraskūr +Échirolles +San Miguel Chicaj +Nowa Sól +Zuojiawu +Pylaía +Sagnay +Kesavapuram +Maddaloni +Mahē +Missão Velha +Wildomar +Brighton +Caimito +Erding +Richfield +Marijampolė +Magsaysay +Ipueiras +Agogo +Elixku +Qalādizay +Uster +Salima +Camberley +Kanie +La Macarena +Sayula +Châtillon +Tuensang +Mulavana +Coatepeque +Kona +Manoli +Dargaz +Köneürgench +Lakshmeshwar +Sōma +Taxisco +Västervik +San José +Houghton le Spring +Zīra +Wangtuan +Tsubata +Kāramadai +Torres Novas +Mandaguari +Esik +Yasugichō +Or Yehuda +Enrile +Michalovce +Kambove +Yovon +Xinpo +Anserma +Robertsganj +Esquel +Beni Khiar +Estero +Ikongo +Thāna Bhawan +Irbit +Pande +Risalpur Cantonment +Sītākund +Sorel-Tracy +Lierre +Ulan Hua +Beloit +Kulp +Hojāi +José Bonifácio +Matan +Rosário do Sul +Lajedo +Belalcázar +Esch-sur-Alzette +Whitley Bay +Aurora +Las Navas +Demirci +Kannan +Makan +Kidangazhi +Sinsheim +Rossano +Mek’ī +Cantanhede +Denton +Natick +Schaffhausen +Jaral del Progreso +São João da Barra +Ebebiyín +‘Afrīn +Tunduma +Dabutou +Nemmara +Chippenham +Baishan +Punārakh +Barra do Choça +Oakton +Patāmundai +Bulicun +Benāpol +Songo +Horasan +Central Islip +Bindé +Şile +Haomen +Franklin +Neiba +Kodaikānal +Dashtobod +Mamfe +Chelora +Upper Arlington +Knurów +Berat +Cambrils +Nueve de Julio +Zhetisay +Ichchāpuram +West Bridgford +Kaniama +Bossangoa +Guápiles +Lecherías +Sonsón +Arawa +Mazıdağı +Zinzana +Tocancipá +Copperas Cove +Rende +Pūrna +Liwonde +Estahbān +Byumba +Anse d’Hainault +Andover +Holubivske +Simbahan +Porta Westfalica +Banaz +Monaco +Namakgale +Maur +Emsdetten +Cegléd +San Pablo +Ratchaburi +Sandanski +Yahyalı +Fuchūchō +Borehamwood +Barra Bonita +Tomatlán +Bjelovar +Tooele +Danihe +Wołomin +Tomelloso +Jarosław +San Juan Cotzal +Mpessoba +Kajaani +Winsen +Dinas +Nargund +Cabanglasan +Oak Creek +Cumberland +Santiago Juxtlahuaca +Kurtalan +Spoleto +Aketao +Parappur +Coatepec Harinas +Yandian +Melito di Napoli +Teruel +Kotma +Prey Veng +Tuntum +San Miguel Acatán +Beiya +Siayan +Cuenca +Mühlhausen +Yorktown +Modugno +Capalonga +Randallstown +Athis-Mons +Isla de Maipo +Yejituo +Merrillville +Palapye +Canaman +Bollate +Six-Fours-les-Plages +Cuyotenango +Göyçay +San Bernardo del Viento +Gasan +Voerde +Mieres +Onteniente +Taastrup +Ouled Beni Messous +La Vallée de Jacmel +Aparecida +Madingou +Chelmsford +Dagami +Kalāleh +Nyaungdon +San Luis +Temple City +Zacatepec +Cisterna di Latina +Boende +Ban Mueang Na Tai +Rapu-Rapu +Carrollwood +Nellāya +Barira +Petit-Trou de Nippes +Pingshang +Ewing +Pestel +Sareh Mowndeh +Bālarāmpuram +Amancio +Mingjian +Kishmat Dhanbāri +Dīnhāta +Dighwāra +Komatsushimachō +Garhākota +Meppen +Guáimaro +Lunsar +Creil +Hilliard +Girau do Ponciano +Châtelet +Al Jabāyish +Frankston +Apodi +Gutalac +Dunedin +Castricum +Kamenicë +Berriozábal +Sunbury +El Plan +East Kelowna +Kanada +Moorpark +Sokol +Roseville +Maspalomas +Piuí +Pioltello +Limburg +Sibuco +Hillerød +Tamamura +Matanog +Claveria +Masasi +Vempalle +Wai +Virú +Bombardopolis +Mālpura +Saparua +Pihānī +Guayaramerín +Bel-Air +Żary +Shirdi +Ingelheim +San Carlos Sija +Vohipeno +Ampasina-Maningory +Mugumu +Bugiri +Farafenni +Nīm ka Thāna +Taloda +Egypt Lake-Leto +La Libertad +Rāmsar +Naduvattam +Chekkal +Krong Kep +Farmers Branch +Tlokweng +Arroyomolinos +Boyarka +Minas +Pandan +Sarıgöl +Seika +Saint-Raphaël +Uto +Tarikere +Oued Athmenia +Anloga +Hellendoorn +Rumonge +Kamenka +Marion +Conflans-Sainte-Honorine +Az̧ Z̧āhirīyah +Ambohibary +San Lorenzo de Guayubín +Yangshuwa +Lauderdale Lakes +Villefranche-sur-Saône +Mokokchūng +Chillum +Majhaul +Kakhovka +Malmesbury +Daiyue +San Antonio +Hyde +Chernyakhovsk +Dinangorou +Partūr +Chieri +Görükle +Meyzieu +Santa Cruz Verapaz +Lyudinovo +Hendon +Caivano +Dumbéa +Vyazniki +Jalārpet +Dar Chabanne +Maragogipe +Tirkadavūr +Oleśnica +Beja +Orangevale +Falkirk +Huzūrnagar +Sun Prairie +Sainte-Geneviève-des-Bois +Ampelókipoi +Karak +Munro +Jagna +Agualva +Pantnagar +Cedar City +Protvino +Zaïo +Igarapé-Açu +Kāttipparutti +Taozhou +Tambolaka +Fermo +Andújar +Varberg +La Porte +Smarhon +Commack +Caltagirone +Azogues +Crailsheim +Prestea +Riverhead +Bad Vilbel +Kalakkādu +Vavatenina +Burriana +Tam Hiệp +Svetlograd +Aliança +Kharagpur +Nawan Shahr +Pak Chong +Leamington +Guane +Haguenau +Kumo +Camiri +Norristown +Calumet City +South Miami Heights +Vršac +Ẕefat +Numancia +Santa Ana +Addison +Iporá +Macomia +Collo +Usuki +Shiggaon +Mahna +Kinel +Sōsa +Inver Grove Heights +Graaff-Reinet +Hole Narsipur +Santiago de Tolú +Câmara de Lobos +Miyajima +Gürpınar +Leer +Guacarí +Frolovo +Coventry +El Mirage +Goiatuba +Chītāpur +Richmond +Miranda de Ebro +Port Shepstone +Awa +Al ‘Aqīq +Aguelmous +Setouchi +Zhentang +Walkden +Chortoq +Medina +Medchal +Midvale +Kendall West +Casiguran +Kenton +Kula +Cha-am +San Andrés Itzapa +Hoogvliet +Narsampet +Shangzhuangcun +Isumi +Uravakonda +Savanūr +Yerköy +Bariri +Lima +Niamina +Freehold +Pishin +Sanok +Sykiés +Rafiganj +Aravankara +Mahabo +Pambujan +Vitrolles +Yangambi +Sirohi +Belluno +Gahanna +Lökbatan +Savonlinna +Olney +Rifu +Miahuatlán de Porfirio Díaz +Guamá Abajo +Torrington +Şaḩneh +Udhampur +Gigante +Sungaiselam +Kaneohe +Villeneuve-Saint-Georges +Coevorden +North Ridgeville +Umarga +Ringsaker +Hamīrpur +La Concordia +Simiganj +Cartagena del Chairá +Woodley +Cutral-Có +San Juan +Yayladağı +Midlothian +Ténès +Accrington +Pola +Ōfunato +Lugoj +Bôca do Acre +Tamuín +Tallkalakh +Sandino +Salisbury +Savalou +Spišská Nová Ves +Ulliyil +Socorro +Fuquay-Varina +Feijó +Tomobe +Lage +Santuario +Pinerolo +Matanzas +Casalecchio di Reno +Oakville +Boyarka +Dayr Ḩāfir +Kundian +Zorgo +Bou Noura +Angra do Heroísmo +Aïne Draham +Pampatar +Buhriz +Bautista +Ratnapur +Morong +Baohezhuangcun +Hamidiye +Guskhara +Millerovo +Samokov +Pilar +Morohongō +Unnan +Yongjing +Rio Real +Akçadağ +West Hollywood +Pilão Arcado +Dama +Ürgüp +La Palma +Westmont +Bragança +Fruit Cove +Timbuktu +Kilimli +Tonalá +Benton +Yarumal +Saint-Benoît +Conceição de Jacuípe +Villa Adelina +Barra do Bugres +Tahuna +Brunswick +Yasynuvata +Villa Ballester +Newton +Juban +Bedēsa +Kerava +Mörfelden-Walldorf +Ciudad de Allende +Cieza +El Hajeb +Chakapara +Quimbaya +Wildwood +Sūrandai +Goch +Aizumi +Diabali +Bridlington +Czechowice-Dziedzice +Tangancícuaro de Arista +Pansol +Douglasville +Chandanais +Voznesensk +Gandara +San Javier +Evergem +Jieshang +Azuqueca de Henares +Allacapan +Yecla +Cento +Zvishavane +Mirnyy +Roi Et +Usilampatti +Baturité +Sankt Ingbert +Kamata +Bria +Winchester +Tilingzhai +Buenos Aires +San Luis +Springville +Bou Salem +Datteln +San Luis +Zaventem +Praya +Watertown Town +Abra de Ilog +Izkī +Bom Jesus do Itabapoana +Perunād +Deggendorf +Woodstock +Yefremov +Billingham +Aktuluk +Hammam Bou Hadjar +Barsinghausen +Soteapan +Mahasolo +Sulop +Giddalūr +Mananara Avaratra +Lingig +Jaguariaíva +Pāppinisshēri +Fair Oaks +Tāzhakara +Manhattan Beach +Trinidad +Ikalamavony +Pandaul +Adamantina +Bibhutpur +Qazax +Steinfurt +Rāwatsār +San Juan Capistrano +Puerto López +Effia-Kuma +Pulppatta +Cassino +Chrzanów +Lebowakgomo +Al Ḩişn +Plainfield +Kherrata +Confresa +Saint-Chamond +Salinas +Balasan +Vinces +Umarkot +Casilda +Yellandu +Suong +Río Grande +Ouro Preto d’Oeste +Phatthalung +Ieper +Bethlehem +Chur +Tebesbest +Guimbal +San Luis de Sincé +San Pedro de Ycuamandiyú +Unión de Reyes +Munai +Charqueadas +Palotina +Māranchēri +Blagoveshchensk +Kōṯah-ye ‘As̲h̲rō +Maīdān Shahr +Wokha +Prado +Mannar +Awbārī +Firavahana +Fotadrevo +Ibrā’ +Chakdarra +Negotin +Luga +Ḑulay‘ Rashīd +Shaqrā’ +Şalkhad +Tall Salḩab +Bagamoyo +Magu +Caucagua +Guanta +Maojiatang +Cangxi +Dikhil +Winsford +Bāpaura +Chiplūn +Harra +Mel Nāriyappanūr +Dulhanganj +Al Ḩamdānīyah +Shū +Brugherio +Owings Mills +Pimenta Bueno +Talanga +Dimitrovgrad +Meridian +Oranjestad +Maglaj +Ōzu +Ngaoundal +Mlimba +Francavilla Fontana +Padre Bernardo +Cookeville +Niquelândia +Shenjiabang +Camoapa +Ez Zahra +Kaizu +Chipinge +Payao +Northbrook +Karumattampatti +Aţ Ţurrah +Fair Lawn +Tenosique +Foça +Balingen +Ypané +Tarkwa +Kahoku +També +Ilhabela +Eşme +Jiaoxi +Lingsugūr +Dietzenbach +Shīyāli +Iyo +Dundee +Campoalegre +Nyamata +Khodābandeh +Tamura +Slavuta +Ekpé +Posse +Santa Cruz +Armenia +Ikot Abasi +Santa Cruz del Norte +Juara +Madukkarai +Piskent +Châtenay-Malabry +Seiyo +Monroe +Aznakayevo +Palaiseau +Jagodina +Ouled Fares +Victoria +Ville Bonheur +Richmond +Mendez-Nuñez +Alandatte +Ewell +Vadigenhalli +Aguaí +University City +Cernusco sul Naviglio +São José do Belmonte +Kempen +Hīrākud +Munnarkōd +Mannārakkāt +Galapagar +Parkland +Arsin +Villajoyosa +Dragash +Naryn +Āllagadda +Oswego +Yarīm +Oildale +Santa Fé do Sul +Sansanné-Mango +Limbiate +Alatyr +Hammam Dalaa +Khajamahalpur +Uddevalla +Auxerre +Graham +Vernier +Morecambe +Mason +Roanne +São Luís Gonzaga +Montgomery Village +Castelo +Seelze +Wermelskirchen +Yhú +Zhitiqara +Long Beach +Hinesville +Safidon +Shangcaiyuan +Çorum +Leganes +Golden Glades +Del Rio +Kolattupuzha +Saarlouis +Zhujiezhen +Třebíč +Bagre +Ayutuxtepeque +Sion +Goshen +Gladstone +Simpang Renggam +University Place +Randolph +Zelenokumsk +Osimo +Azazga +Dhāmnod +Farafangana +Bugasong +Tienen +Korkino +Naranjito +Augusta +Rio Pardo +Mānāmadurai +Slagelse +Abashiri +Tortosa +Butte +East Gwillimbury +Sarpol-e Z̄ahāb +Marutharōd +Andapa +Anse-à-Veau +Medgidia +Misungwi +Sidi Lakhdar +Dabouziya +Mugnano di Napoli +Falls +Phokeng +Dueñas +Tynaarlo +Espiye +Grantham +Zhangziying +Huntington Station +Qaşr al Qarabūllī +Abulug +Inca +Swadlincote +Yangquan +San Juan Despí +Mildura +Banda +Yeonil +Bugojno +Cativá +Bonifacio +Ofunato +Paithan +Kalaa Srira +Dāpoli +Sabaneta +Wedel +Cañete +Zweibrücken +Viernheim +Kulittalai +Gisborne +Pasni +Koryazhma +Bayog +Bāft +Mogpog +Santa Maria +Skhira +Ahrensburg +Pleasant Hill +Côte-Saint-Luc +Ankola +Aïn Taya +Lębork +Manitowoc +Barugo +Sadda +Akouda +Fairborn +Brzeg +Ballesteros +Ocuilan de Arteaga +Shangzhen +Bodocó +Santa Fe +Curuzú Cuatiá +Gerāsh +Nola +Formigine +Aloguinsan +San Dimas +Smolyan +Nishihara +Schoten +Mazarrón +Stow +Motosu +Banes +Madakalavāripalli +Canicattì +Mâcon +Hatibanda +Bela Vista de Goiás +Sambir +Zaidpur +Sochaczew +Kalasin +Fort Liberté +Exmouth +McMinnville +Ye +Mnasra +Gotō +North Shields +Centenario +Kuji +College Park +Merauke +Itaporanga d’Ajuda +Paxtaobod +Riccione Marina +Năvodari +Vichuga +Meppel +Toretsk +Santa Ana Nextlalpan +Biwong +Corsico +Cherchell +Durazno +Kiryas Joel +Yihezhuang +Houlong +São Joaquim de Bicas +Lakewood Ranch +Kita Chauhāttar +Pueblo West +Betafo +Garibaldi +Merseburg +Heunghae +Phra Phutthabat +Same +Tandubas +Degāna +La Blanca +Třinec +Wavre +Bathurst +Tábor +Swakopmund +Isingiro +Merritt Island +Derry +Geldern +Quilevo +Araçuaí +Conegliano +Nandaime +Licata +São Pedro +Shinjō +Almeirim +Kalarūch +Pinukpuk +Buchanan +Lewiston +Nova Cruz +Lautaro +Fusō +Aiyappan Kōvil +São Desidério +Hitchin +Vedāranniyam +Pomerode +Zhangzhengqiao +Esposende +Lixingcun +Timberwood Park +New Panamao +Simunul +La Huacana +Sibutu +Sahuarita +Nāz̧erābād +Baraidih +Dakota Ridge +Colinas do Tocantins +Atami +Mosonmagyaróvár +General Nakar +Lexington +Santa Maria +Isfana +Gulkevichi +Prairieville +Le Perreux-Sur-Marne +São Sebastião +Pangururan +Úbeda +Badiadka +Shāhīn Dezh +Şereflikoçhisar +Karoi +Toumoukro +Eastchester +Tōon +Valuyki +Redmond +Šid +Korschenbroich +Curaçá +Orangeville +Cariari +Ābīy Ādī +Tiruvūr +Datang +Ágioi Anárgyroi +Lufkin +Bor +Talayan +Tepeji del Río de Ocampo +Tobelo +Znojmo +Villena +Kokrajhar +Risod +Dimona +Caldono +Kornwestheim +Schiltigheim +Laoac East +Takhemaret +Almora +Boğazlıyan +Brejo +San Agustín +Shisō +Spalding +Balarāmpur +Uonuma +Cravinhos +Gyapekurom +Guindulman +Fungurume +Pingtang +Pikesville +Diakon +Qingyang +Argyroúpoli +Radebeul +Leduc +Rainham +Eastpointe +Beaufort West +San Manuel +Çınarcık +Honaz +Portão +Titlāgarh +Cantilan +Wāris Alīganj +Gbarnga +Deer Park +Cooper City +San Remigio +Podgórze +La Unión +Lommel +Pagani +Vác +Sint-Pieters-Leeuw +Palapag +São Domingos do Maranhão +Puqiancun +Westlake +Woodridge +Zeghanghane +Hemer +Jalajala +Jāmkhed +Spanaway +Rūdarpur +San Juan Nepomuceno +Minamishiro +Majagual +Biberach +Dīvāndarreh +Oneşti +Quinchía +Gibraltar +Ankazomiriotra +Maromandia +Mahasoabe +Lushoto +Zhegaozhen +Tamra +Valparaiso +Letchworth +American Fork +Kallidaikurichi +Shariff Aguak +Menen +San Quintin +Les Mureaux +Vassouras +Angri +Peyziwat +Milaor +Kignan +Sharypovo +Cieszyn +Sibagat +Acatlán de Osorio +Stuhr +Korsakov +Lochem +Almendralejo +Kakata +North Providence +Lanciano +Annigeri +Uelzen +San José Poaquil +Uttaradit +San Juan Evangelista +Bassin Bleu +Pulgaon +Sındırgı +City of Orange +Starokostiantyniv +Nizhneudinsk +Oued el Alleug +Impfondo +Zhuqi +Windsor +Curralinho +Initao +Mulavūr +Adrano +Lupi Viejo +Réo +Navan +Guying +Timbío +Gadsden +Zhaitangcun +Toda Bhīm +Byādgi +Itiúba +Lianga +Tabango +Desamparados +Sneek +Palmeira +Imzouren +São Luís de Montes Belos +Selmane +Baclaran +Chaodongcun +Nuoro +Beni Tamou +Oeiras do Pará +Bozdoğan +Dao +Walla Walla +Camiri +New City +Bell Ville +Golungo Alto +Jasło +San Martín Sacatepéquez +Strumica +Harima +Waikabubak +IJsselstein +Parras de la Fuente +Tobias Fornier +Buxin +Lichfield +San Antonio de los Baños +Río Verde Arriba +Kearney +Inhambupe +Kadungapuram +Somoto +Naguilian +Xinzhancun +Crema +Leawood +Beni Slimane +Baldwin +Ghazaouet +Braço do Norte +Martinez +Bangaon +Vechta +Puerto Rico +Narsīpatnam +Bogorodsk +Zhmerynka +Mount Lebanon +Catmon +Várzea da Palma +Tekes +Mankoeng +Zacatlán +Kadingilan +Crown Point +El Ksar +Ojiya +Jaguaribe +Chilecito +Kovin +Capoocan +Kaippakanchēri +Carmel +Āzezo +Karaağaç +Léo +Trappes +Midsalip +Fallbrook +Grodzisk Mazowiecki +Vemalwāda +Xiaotangzhuang +Antiguo Cuscatlán +Irvine +Landi Kotal +Roldanillo +Somma Vesuviana +Palmerston +Tlanchinol +Kasba +Sukhoy Log +Datu Paglas +Kohtla-Järve +Mella +Moose Jaw +Batobato +Upper Merion +Penha +Villa Riva +San Antero +Bārhadashi̇̄ +Oulad Zemam +San Roque +Ōno +Florida +Lianmuqin Kancun +Englewood +East Lake +Aranda de Duero +Macuro +Kōryō +Chascomús +‘Ajab Shīr +Binche +Morro do Chapéu +Batouri +Koh Kong +Atiquizaya +Rheinfelden (Baden) +Masiu +Sapa Sapa +Côtes de Fer +Elmina +Sicuani +Dāganbhuiya +Iriba +Qadsayyā +Maassluis +Pitanga +Goldsboro +Áno Liósia +Aleshtar +Mercedes +Bagh +Chāvakkād +Ixtapan de la Sal +Belen +Aweil +Port Moody +Cabarroguis +Acornhoek +Ayorou +Columbio +Manganam +Saint Helier +Chumphon +Arteijo +Sidi Okba +San Vicente +Comé +Ribeirão +Gorizia +Ken Caryl +Leticia +Niangoloko +Canton +Bacarra +Schwedt (Oder) +Warminster +Manlius +Corinto +Chempalli +Pointe-Claire +Wickford +Batan +Fraiburgo +Hlukhiv +Neuchâtel +Cishan +Nogent-sur-Marne +West Little River +Olkusz +Dhekiajuli +Coxim +Badr +Houilles +Chimbarongo +Bad Nauheim +Mangalam +Poço Redondo +Çukurçayır +Sabanagrande +Santa Ana +Monteiro +Vettam +Paidha +Madhubani +Angamāli +Getafe +Orodara +Darsi +Castro +Sirīpur +Alabaster +Mỹ Hòa +Orillia +Kaçanik +Shōbara +Ban Pak Phun +Butajīra +Date +Geraardsbergen +Paso de Ovejas +Kong +Riachão do Jacuípe +Namhkam +Asakuchi +Madikeri +Bell +Banate +Aldaya +Tulum +Gölbaşı +Kondapalle +Landskrona +Iperó +Tayshet +Kennesaw +South Riding +Tavda +Loughton +Bafang +Montluçon +Glossop +Vintar +Dursunbey +An’gang +Shirakawa-tsuda +Shiroishi +Ronda +Puyo +Batcha +Menlo Park +Nokia +Taishi +Al Mindak +Baltiysk +Amparafaravola +Bāmaur +Ziniaré +Dupax Del Norte +Estreito +Churi +Kidamangalam +Mohnyin +João Câmara +Beidou +Kolín +Shanawān +Buenaventura Lakes +Gojō +Bethel Park +Nowy Targ +Hisuā +Oława +Didouche Mourad +Romainville +Muconda +Petersburg +Radnor +Cottonwood Heights +Perşembe +Mažeikiai +Xincheng +Zamānia +Barguna +Capim Grosso +Stratford +Kampong Speu +Kavundappādi +Pivijay +Castro-Urdiales +Ceres +Shatura +Bragado +Foster City +Ālamat’ā +Ross +Geiro +Guarambaré +Kyrenia +Kartārpur +Obukhiv +Borne +Epe +Andırın +Huyton +Uniondale +Khvāf +Lower Makefield +Statesboro +Furmanov +Katiéna +Pandami +Eirunepé +Puerto Cumarebo +Partizansk +Cranberry +Jülich +Gillette +Totana +Chuhuiv +Shamsābād +Baja +Dipaculao +Palmeira das Missões +Abingdon +Shikārpūr +Salina +Pánuco +Kusapín +Minamikyūshū +Umaria +Brooklyn Center +Trowbridge +Ben Ahmed +Mukdahan +Bugembe +Kaarina +Knokke-Heist +Aosta +Los Gatos +Shima +Glendale Heights +Tekkebhāgam +El Arrouch +Chanderi +Calape +Bungoōno +Temascalapa +Mushie +Tynda +Kamaishi +Victoria Falls +Timimoun +Borba +Kareli +Castelfranco Emilia +Tutin +Ban Ang Sila +Kingman +Taiobeiras +Chester +‘Aïn el Hadjel +Didy +San Luis +Kadınhanı +Wakabadai +Harker Heights +Touros +Puebloviejo +Las Mercedes +Dana Point +Luboń +Jishi +Shingū +Hāngal +Sarıkaya +Marignane +Xinbu +Livingstone +Ambodimanga II +Vohitromby +Zumbo +Forbe Oroya +Lomé +Gumdag +Gyzylgaya +Osvaldo Cruz +Luxitun +Villafranca di Verona +Hinda +Turkauliyā +Boxtel +Hampden +Forchheim +Pôrto União +Taguasco +São Paulo de Olivença +Spring Valley +Sopot +Shalingzicun +Asse +Elesvaram +Bembe +Dellys +Örnsköldsvik +Chernushka +Ventspils +Itamarandiba +Djenné +Rencun +Dara +Dehlorān +Musikoṭ-Khalaṅgā +Carapeguá +Biritiba-Mirim +Castelfranco Veneto +Saint-Georges +Dumalinao +Yamanashi +Massango +Aravan +Romans-sur-Isère +Baraguá +Saintard +Fatehpur Sīkri +Escuque +Fort Erie +Moninnpébougou +Patrātu +Sānchor +Pantelimon +Aksay +Lampertheim +Oued Zenati +Kifrī +Clarence +Tawsalun +Níjar +Lohagaon +Sō +Nikšić +Araban +Watari +Villanueva +San Felipe +Sanana +Nevers +Kollo +Carache +Kakira +Tunceli +Gostivar +Umarkot +Urbano Santos +Sertânia +Pilar +Ārumuganeri +Igrejinha +Tecuci +Baraawe +Syracuse +Teutônia +Ticul +Sighetu Marmaţiei +Slobodskoy +Buco Zau +Parambil +Tit Mellil +Shaliuhe +Franklin +St. Charles +Bela Cruz +Rubino +Delbrück +Ubajara +Bocas de Satinga +Udaipur +Sayram +Xinyuan +Chand Chaur +Fair Oaks +Achim +Val-d’Or +Mankada +Yuzhne +Puerto Escondido +Balzar +Příbram +Barouéli +Ylöjärvi +Kallūr +Sayula de Alemán +LaSalle +Ivaiporã +Rodas +Warwick +Geraldton +Trëkhgornyy +Sherwood +Kaysville +Ansongo +Vadavalli +Nurlat +Jaguarari +Yufu +Debagrām +La Mesa +Falmouth +Silvia +Cota +Arbaoua +Nānjikkottai +São João Batista +Xiaodian +Vilakkudi +Dobryanka +Zhanjia +Des Moines +Iława +Oğuzeli +Itaíba +Herrenberg +City Bell +Fürstenwalde +Jamikunta +Putla Villa de Guerrero +Tārānagar +Goleta +Cibolo +Andover +El Difícil +Lawrence +Belhi +Frederico Westphalen +Lens +San Lazzaro di Savena +Aïn el Bya +Istra +Ōsawa +Ostrogozhsk +Mayantoc +Arris +Kraśnik +Motherwell +Mashiki +Matalom +Diplahan +Businga +Shamsābād +Inzá +Erraguntla +Balindong +Rochester +Payshamba Shahri +Şarköy +Vyatskiye Polyany +Esplanada +Shimanto +Aïn Bessem +Mateur +Saint-Médard-en-Jalles +Chēmanchēri +Badoc +Helena +Hani +Kulebaki +I-n-Salah +Salt +Caçapava do Sul +Dolores +Slantsy +Lobougoula +Minamisatsuma +Elk Grove Village +Spring Valley +Mānwat +Agen +Amés +Shiyeli +Pombal +Baiyan +Garfield +Yinchengpu +Réthymno +Nueva Italia de Ruiz +Ourilândia do Norte +Sotouboua +Fucheng +Correntina +Staryy Beyneu +Ferry Pass +Virei +Chemmaruthi +Savage +Turaiyūr +Deurne +Nouna +Abbiategrasso +Omaezaki +Lower Macungie +Dioungani +Vrilíssia +Bussum +Beverly Hills +Nedroma +Plottier +Desert Hot Springs +Ketti +Kameda-honchō +Pierrefitte-sur-Seine +Dumfries +Oisterwijk +Pires do Rio +Chamtha +Clearfield +Dartmouth +Brighouse +Massantola +Kiranomena +Ingenio +Yankou +Redcliff +Guararapes +Kävlinge +Pattanapuram +Ire +Geesthacht +Lumbang +La Virginia +Sāsthānkotta +Narsinghgarh +San Pedro de Urabá +Kalyandrug +Wigston Magna +Lugo +Bilzen +Ōharu +Namerikawa +Chancay +Sant’Antimo +Nagarote +El Abiodh Sidi Cheikh +Madīnat al Ḩabbānīyah +Tattamangalam +Sibiti +Cachoeira Paulista +Dracut +Naumburg +Curanilahue +Venaria Reale +Komárno +Épinal +Messaména +Concón +Chiché +Peñaranda +Niéna +Wheat Ridge +Bernburg +Zarqān +Zaojiao +Itzehoe +Jimalalud +Bambadinca +Boro +Guanhães +North Olmsted +Ţafas +São Bento +Termoli +Kangasala +Jacqueville +La Calera +Laranjeiras do Sul +Yōkaichiba +Sébaco +Paraipaba +Şāfītā +Mallig +Kindi +Casale Monferrato +Buloqboshi +Cochrane +Igbaras +Piombino +Georgsmarienhütte +Kristianstad +Windsor +Estrêla +Didcot +Nagato +Primorsko-Akhtarsk +Bramsche +Massillon +Gandu +Ibaté +Xangda +Catubig +Matões +Maragogi +Homa Bay +Yorii +Papendrecht +Weatherford +Alubijid +Pasadena +Koungou +Catende +Rokhaty +Sint-Amandsberg +Erāmala +Miguel Alves +Buguey +Nacogdoches +Kāngayam +Utraula +Salug +Shilou +Douar Oulad Hssine +Pojuca +Pervari +Ptolemaḯda +Kōnan +Maputsoe +Termas de Río Hondo +Balimbing +Caramoran +Ribeira Grande +Huixtla +Mizuho +Juneau +Campo Alegre +O'Fallon +Ōdachō-ōda +Rumbek +Waiyuanshan +Zapala +Aguilares +Guaíra +Ouro Fino +Kukshi +Mangūr +Mutki +Serdobsk +Quitilipi +Sami +Kovūr +Antsohimbondrona +Rādhanpur +Pekin +Tamparan +Dhahran +Uglich +Remedios +Florence +Ciudad Sabinas Hidalgo +Radolfzell am Bodensee +São Miguel Arcanjo +Earley +Canyon Lake +Rome +Rahachow +Munnar +Fontana +Chachapoyas +Brasília de Minas +Wernigerode +Malangas +Bauko +Akivīdu +Bizen +Bezons +San Donato Milanese +Aiken +Sakaiminato +Tirebolu +Marrero +Bandarawela +Andriba +Bekoratsaka +Vohilava +Itampolo +Ambano +Ghuenke +Yaguarón +Santo Tomás +Cabaiguán +Makhdumpur +Milot +Aalsmeer +North Cowichan +Września +Youwangjie +Kanzakimachi-kanzaki +Arzano +Levice +Pullman +Franklin Square +Purāini +Mascalucia +Massafra +Tholikuzhi +Needham +Deptford +Cheb +Sitges +La Concepción +Mangalia +Warwick +Sergio Osmeña Sr +Nísia Floresta +Landecy +Ganderkesee +San Carlos Alzatate +Nerópolis +Long Branch +Bexleyheath +South Kingstown +Quintero +Bougaa +Santo Antônio do Tauá +Araguatins +Xaxim +Palamel +Purattūr +Polillo +Southport +Yenice +Nilka +San Pablo +Santa Maria Capua Vetere +Erdek +Cañuelas +Claveria +Cacolo +Avellaneda +Paso del Macho +Bayaguana +Centereach +Turicato +Maryville +Aix-les-Bains +Kampong Thom +Jyväskylän Maalaiskunta +Alengād +Paipa +Dzierżoniów +Oudenaarde +Bửu Long +Bahharet Oulad Ayyad +São Gabriel +Palmeiras de Goiás +Guachavés +Maur Kalān +Cleburne +El Oro de Hidalgo +Domingos Martins +Willingboro +Exu +Camaiore +Atwater +Sidi Ali +Oer-Erkenschwick +Remchi +Pampanito +Sherpur +Namegata +Jhanjhārpur +São Gotardo +Ortaköy +Alamnagar +Palmira +Santa Rita +Newburgh +Velikiy Ustyug +San Lucas Tolimán +Plettenberg Bay +Masi-Manimba +Teykovo +Tongxiao +Stadskanaal +Bagasra +Gurupá +San Pedro de Ribas +Hassi Khelifa +Gallipoli +Kottaikuppam +North Huntingdon +Ferreñafe +Montigny-le-Bretonneux +Salamína +Pantabangan +Tubao +Velliyōd +Komagane +Bocana de Paiwas +Singia +General José de San Martín +Descalvado +Carlsbad +Yıldızeli +Tekkēkara Kizhakku +’Aïn Abid +Duluth +La Maná +Tredyffrin +Farrokh Shahr +Sadābād +Amatenango de la Frontera +Al ‘Aydābī +Laramie +Donggou +La Uruca +Maebara +Kochugaon +Staffanstorp +Bostaniçi +Tuljāpur +Kavār +Santa Catarina Mita +Sitionuevo +El Palmar +Bangor +Oldenzaal +Jaguaruana +Dania Beach +Lālgola +Rushden +Baradères +Sigma +Amecameca de Juárez +Zhaoyu +Garner +Jāsim +West Bend +Bagrāmī +Itapicuru +Kumba +Masur +Vught +Jiming +Naugatuck +Shimizuchō +Barros Blancos +Nautan Dube +Rumuruti +Calubian +Capela +Siquirres +Nueva Imperial +Balyqshy +Morro Agudo +Zentsujichó +Kiryandongo +Tecozautla +Ecclesfield +Kuroishi +Jesús María +Jalpatagua +Jerez +Chum Phae +Favara +Media Luna +Chorbog +Masatepe +Mundelein +Pruszcz Gdański +Žepče +Lloydminster +Nanyuki +Merida +Manises +Wisbech +Fangyuan +Darwen +Holladay +Lidingö +Shenwan +Cururupu +Katagami +Sosnogorsk +Pehuajó +Lawndale +Cueto +Al Khawr +Thazhamel +Hayama +Lake Magdalene +Rāhatgarh +Ayabe +Oak Ridge +I‘zāz +Mae Sot +Milford Mill +İvrindi +Puerto Wilches +Shikārpur +Prosper +Kurivikod +Novovoronezh +Buzovna +Encrucijada +Prestwich +Mechraa Bel Ksiri +Bünyan +Charthāwal +Knjaževac +Epsom +Marks +Oceanside +Dialoubé +Colombia +Qārā +Samdhin +Dej +Sejiyŏn +Kostopil +Mandaguaçu +Bangassou +Airmadidi +Parambu +Savé +Chambly +Kalisizo +Nagdha Simla +Jam +Trebinje +Forquilhinha +Nauāgarhi +Cambrai +Deori Khās +Neuruppin +Renkum +Carballo +Nieuw-Vennep +Lemery +Pindaré-Mirim +Çay +Wevelgem +Āreka +Norak +Kunnatnād +Neira +Kolachel +Cornelius +Sanha +Shentang +L’Haÿ-les-Roses +Shawnee +Halden +Yawatahama-shi +Vellanād +Ílhavo +Draa Ben Khedda +Buyan +Navalcarnero +Courcelles +Plaisir +Myōkō +New Bern +Kudymkar +Colíder +Bolobo +Quţūr +Sri Mādhopur +Bagac +Opelika +Humenné +Ithaca +Hoyerswerda +Villaricca +Dasol +Nicholasville +Point Pedro +Cicero +Guamo +Maralal +Lumding +Cândido Mota +Norwood +Waddinxveen +Dimataling +Mamaroneck +Wenxian Chengguanzhen +Odorheiu Secuiesc +Kléla +Diemen +Hitoyoshi +Monjas +Kandalaksha +Rio das Pedras +Gongguan +Pontoise +Redan +Tanmen +Sherpur Khurd +Araçoiaba da Serra +Ibanda +Altenburg +Netivot +İmişli +Magsingal +Yahşihan +Bel Air North +Río Bravo +Zaqatala +Eyvān +Maḩallat Damanah +Mograne +Shimotoba +Yby Yaú +Port Chester +Burgdorf +Ennery +Châtellerault +Aguada de Pasajeros +Ivisan +Ibaraki +Bandeirantes +President Roxas +Cuauhtémoc +Vadakakarai +Tiquipaya +Boghni +Ōiso +Petrovac na Mlavi +Hendrik-Ido-Ambacht +Inkhil +Siliana +Parnarama +Rillieux-la-Pape +Nāspur +Carangola +La Verne +Unchagao +Esperança +Barrinha +Changuinola +Salgótarján +Valkenswaard +Rosmalen +Kosonsoy +Poconé +Itaperuçu +Bittou +Alba +Bramhapuri +Pontypridd +Duanshan +Shepparton +Kreuztal +Lobos +Rutherglen +Sakaraha +LaGrange +Dar Ould Zidouh +Laguna Hills +Varto +Paracelis +Saint Neots +Siraway +Khānah Sūr +Buenavista +Rusera +Middle River +Rheinberg +Asilah +Ciudad del Plata +Podili +Yaita +Tongeren +Gata +Ambatomiady +Bogoroditsk +Beidaying +Sovetskiy +Orcutt +Shrīgonda +Los Altos +Fomento +Ngudu +Kalliyasshēri +West Falls Church +Rosa Zarate +North Royalton +Tequila +Socorro +Espinosa +Yingyangcun +Lushnjë +Bembèrèkè +Tancítaro +Chitral +Danghara +Khorugh +Sakhnīn +Gevelsberg +Thiais +Sabana Grande de Boyá +Montebelluna +Centre Wellington +Vibo Valentia +Sasaguri +Livingston +Bedworth +Tewksbury +Huangxicun +Tanguá +San Juan Ixcoy +Nantan +Barreirinha +Sterling +Cambita Garabitos +Manaratsandry +Vienne +Vigneux-sur-Seine +Malaikkal +Lagos +Pompeu +Werl +Viry-Châtillon +Petroşani +Hopkinsville +Tairan Camp +Tummapāla +Mushābani +Chantal +Espinho +Karera +Dover +Springfield +Konséguéla +Malakanagiri +Rodolfo Sánchez Taboada +São José do Egito +Vohitrandriana +Andranovory +Wobulenzi +Dashao +San Vicente +Alamogordo +Burlingame +Iguape +Diffa +Zima +Itapemirim +Arraial do Cabo +Santa Vitória do Palmar +Bethany +Gīmbī +Babati +Lucera +Yaese +Lakeside +Dolo Odo +La Paz +Dyurtyuli +Irituia +Arcos de la Frontera +Mocímboa da Praia +Tawaramoto +Ballwin +Tarakeswar +Minas de Matahambre +Rostov +Wanghong Yidui +Bādāmi +Husainābād +Saint-Laurent-du-Var +Ridley +Chagne +Dedza +Alcázar de San Juan +SeaTac +Chichester +Săcele +Mława +Sabirabad +Deal +Jérémie +West Warwick +Itatiaia +Cícero Dantas +Canavieiras +West Odessa +Pichanal +Flores da Cunha +Okagaki +North Chicago +Coria del Río +Kaminokawa +Bairi Chak +Champotón +Pontefract +Dreux +Voorhees +São Luís do Quitunde +Leh +Pattanakkād +Ózd +Culleredo +San Antonio Ilotenango +Sholinghur +Dharampur +Juanacatlán +Bicester +Mānāvadar +Puerto de la Cruz +Palaiya Āyakkudi +North Andover +Careiro da Várzea +Lohmar +Vinkovci +Kalgoorlie +Cholargós +Westfield +Capulhuac +Sarayköy +Nartkala +Zionsville +Beverley +Al Ḩusaynīyah +Chinnālapatti +Walsrode +Pattittara +Arlon +Friedberg +Kórinthos +Lohāgāra +Bègles +Taunusstein +Vitória do Mearim +Ungheni +Nālchiti +Ganassi +Lavras da Mangabeira +Qo‘rg‘ontepa +Jonuta +Careiro +Escuinapa +Nardò +Santa Paula +Río Blanco +Southlake +Barão de Cocais +Busia +Saratoga +Weil am Rhein +Carpentras +Mahemdāvād +Alegre +Paşcani +Andingcun +Tsuruno +San Narciso +Guaranda +Gadarpur +Ban Sai Ma Tai +Písek +Ulliyeri +Ferizli +Tekkali +Chak Five Hundred Seventy-five +Udaypur Gaḍhi̇̄ +Einbeck +San Sebastián +Novoyavorovskoye +San Isidro +Pedana +Mattathūr +Além Paraíba +Agblangandan +Juatuba +Aglipay +Northport +Riacho de Santana +Sekiyado +Dois Irmãos +Tekeli +Pandua +Nova Russas +Bābura +Goussainville +Treviglio +San Ramón +Ciudad Melchor de Mencos +Czeladź +Tepetlaoxtoc +Cruz del Eje +Bannūr +Mont-de-Marsan +Partinico +Moche +Campo Alegre de Lourdes +Balatan +Villiers-sur-Marne +Presidente Figueiredo +Gobernador Virasora +Laḩij +Catolé do Rocha +Chūō +Osterholz-Scharmbeck +Gamu +Newark +Toribío +Chengam +Tabuleiro do Norte +Bad Hersfeld +Ennepetal +San Giuliano Terme +Nazaré da Mata +Juquitiba +Luís Correia +Yunoshima +Niles +Burgess Hill +Eagle +Calafell +Gurnee +Santana do Acaraú +Police +Victoria +Mataas Na Kahoy +Miami Lakes +Jarinu +Carapó +Kaelé +São José da Tapera +Keles +Capim +Taozhuangcun +Diéma +Cachan +Banamba +Uzynaghash +Grottaglie +Talakkād +Devarshola +Birtouta +Aïn Kercha +Buey Arriba +Hafnarfjörður +Sarno +Illescas +Bay Shore +Wallkill +Leusden +Xingang +Zug +Haan +Sokuluk +Osmancık +Olopa +Suzak +Founougo +Liptovský Mikuláš +Hayrabolu +Anilao +Gariadhar +Parkville +Ouatagouna +Aungban +Savigny-le-Temple +Westville +Fārsān +Sankaramangalam +Nāgāwaram +Thung Song +Krabi +Giannitsá +Stratford-upon-Avon +Masho Khel +Hellín +Maināguri +San Carlos +G’ijduvon Shahri +Pamukova +Pittsford +Pau dos Ferros +Gubbio +North Tonawanda +Torrijos +Karuvakulam +Mukumbura +Neuburg +Santa Bárbara +Lawrenceville +Yanai +Afonso Cláudio +Motema +Ar Ruḩaybah +Princeton +Ono +New Smyrna Beach +Trípoli +Erie +Beşiri +Tchindjendje +Ash Shinān +Uran +Maguing +Bandar-e Lengeh +Mandera +Tskhinvali +Magdalena de Kino +Camamu +Pontal do Paraná +Rotterdam +Quillabamba +Bālā Kōh +Carlos Barbosa +Myszków +Menton +Kailahun +Valdepeñas +Friedberg +Karjan +Okotoks +Motomiya +Blagodarnyy +Banlung +Mūvattupula +Austintown +Salyan +Manāwar +Avola +Schönebeck +Samrong +Amagá +Sanford +Ust’-Dzheguta +Oristano +Eldersburg +Kūttānallūr +Dhāri +Salem +Mānsa +Newark upon Trent +Nanyō +Temascaltepec de González +Żywiec +Villemomble +Alma +Rehli +Hirakawachō +Huatabampo +Fengrenxu +Trindade +Graneros +Abū Şuwayr +Shāhpura +Sallimedu +Xinpo +Seguin +Kessel-Lo +Pothuhera +Kurunegala +Al ’Attawia +Télimélé +Ségala Mba +Northolt +San Salvador El Seco +Chimichagua +Dolores +To‘raqo‘rg‘on +Kondopoga +Koni +Liberty +Bella Vista +Cabrobó +Malakoff +Wishaw +Bai Chay +Chimākurti +Andernach +Ometepec +Benguema +San Gregorio de Nigua +Bardejov +Candelaria +Jima Abajo +Majidpur +Drexel Heights +Asprópyrgos +Gaggenau +Jinka +Pantao-Ragat +Zhedao +Kasimov +Las Nieves +Harpenden +Falou +Huanta +Salou +Chabet el Ameur +Tāramangalam +Anse-à-Foleur +Best +Wik’ro +Highland Park +Lewe +Uithoorn +Anjad +Qarataū +Milford +Berriane +Daheba +Whitstable +Tsuru +Crevillente +Calintaan +Mozhaysk +Gorodets +Waterloo +Ndora +Djendel +Gorna Oryahovitsa +Kaipram +Middletown +Kibiti +Kokhma +Bankass +Cláudio +Yverdon-les-Bains +Bowling Green +Periyanāyakkanpālaiyam +Ypacaraí +Liévin +Egra +Inami +Joaçaba +Anse à Pitre +Floresta +Ostuni +Quezaltepeque +Piagapo +Taşova +Kanniparamba +San Giuseppe Vesuviano +Candijay +Marogong +Mussoorie +Pulupandan +Planadas +San Miguel +Mucari +Gukeng +Miramar +Saktī +Dumalag +Rury +Elūr +Balete +Postmasburg +Rahīmpur +Mīnūdasht +Rosignano Marittimo +Oltu +Bretten +Muratlı +Kondarangi Kīranūr +Iguig +Wuyuan +Szekszárd +Monte Patria +Nethirimangalam +Mārgrām +Merzig +Sainte-Julie +Milazzo +Nanchital de Lázaro Cárdenas del Río +Villa Regina +Sakhipur +Zemoura +Degeh Bur +Meschede +Kericho +Granger +Cahul +Dauin +Comiso +Congleton +Kulat +Mahugaon +Jamālpur +Monterey +Santa Maria +Ārda +Balungao +Qahderījān +Chmistâr +El Fanar +Bent Jbaïl +Zghartā +Andranomanelatra +Tsitondroina +Ambinanitelo +Ambalavao +Majuro +Bourèm Guindou +Du Yar +Kuah +Dulmial +Malak Abad +Malème Hodar +Sali +Uar Esgudud +Ikoto +Kafr Nubl +Änew +Mpwapwa +Kayunga +Pop +Kanyobagonga +Gongyefu +Liaojiayuan +Les Palmes +Mundāhal Khurd +Hasanparti +Rānpur +Pātri +Salāya +Edasshēri +Mundi +Padappakara +Sāgwāra +Tirwa +Kaluvāya +Masabdisa +Māgadi +Bāghmāri +Sarpavaram +Dhandhuka +‘Aynkāwah +Jalawlā’ +Mutsamudu +Kotovsk +Saundhonwāli +Salay +Pārakadavu +Eshtehārd +Dala +Soledade +Sombrio +Koratgi +Schwandorf +Askøy +Kamisato +Winter Park +Anchieta +East Niles +Chamblee +Navāpur +Riga +Kaminoyama +Zgorzelec +Birūr +Aarschot +Kottūru +Vero Beach South +San Andrés del Rabanedo +Holbæk +Garopaba +Saint-Constant +Radcliffe +Southgate +Agno +Verbania +Gérakas +Dalin +Pind Dadan Khan +Manduria +La Garenne-Colombes +Marhaura +Banning +Ragan Sur +Santa Rita +Mohyliv-Podilskyi +Imbituva +Galesburg +Subotica +Rietberg +Carshalton +Slavgorod +Vyshhorod +Vestal +Triprangōttūr +General Alvear +Dandenong +Mahón +Plympton +Pānakkudi +Serra Negra +Metamórfosi +Algonquin +Conguaco +Aral +Pinhão +San Roque +Mandalī +Mabole +Campo Magro +Padada +Balabagan +Wellesley +Tacuba +El Idrissia +Villa Dolores +Al Madad +Be’er Ya‘aqov +San Andrés Xecul +Xiaba +Quiapo +El Kseur +Waslala +Ozhūr +Kabalo +Gloucester +Fitchburg +Alacuás +Ris-Orangis +San Luis +Motala +Nutley +Kodayattūr +Petite Rivière de Nippes +Nanga Eboko +Oosterend +Shibancun +Dzyarzhynsk +Shetang +Tiruvēgapra +Fleming Island +Thuận Tiến +Krishnarājpet +Kınık +Bad Zwischenahn +Hakha +Bontoc +Talwāra +Fresno +Kaita +Hengchun +Antsampandrano +East Windsor +Puente-Genil +Madavur +Hengshuicun +Ranai +Dahana +Râmnicu Sărat +Puthupalli +Santa Cruz +Raytown +Bulwell +Durango +Mount Hagen +Bois-Colombes +Mananasy-Tsitakondaza +Charneca +Ancón +Nattam +San Lorenzo +Atascadero +Morrisville +Artëmovskiy +Benito Soliven +Bāzeh Kalāgh +Chahchaheh +Bozmargī +Kalāteh-ye Mīr Āb +Santiago do Cacém +Perico +Rendsburg +Reghin +Sardrūd +Dedovsk +Phú Mỹ +Clichy-sous-Bois +Atbasar +Mbanga +Yong’ancun +Tabio +Décines-Charpieu +Devarkonda +Fridley +Heesch +Igarapava +Saint-Cloud +East Fishkill +Tena +Summerlin South +Karahrūd +Makato +Savanette +Dagestanskiye Ogni +Bayramiç +Bergen +Buenavista +Kloof +Nu‘ayjah +Orchard Park +Kitaakita +Asha +Parsuram +Paragould +Sursand +San Jacinto +Vinaroz +Buriti +Hosdurga +Uychi +Manjo +Nepānagar +Werve +La Rinconada +Pasuquin +Newtownards +Rota +Hazleton +Vlasotince +Alushta +Canguaretama +Zaragoza +Stung Treng +Piraju +Yingshouyingzi +Rahway +Pedras de Fogo +Warrnambool +Trutnov +Toksun +Bonou +Synelnykove +West Rembo +Chatou +Waltrop +Oelde +Monfalcone +Lathrop +Petrich +Cruz +Villa Donato Guerra +Bregenz +Jāmai +Pati do Alferes +Placer +Alquízar +Xinmin +Matthews +Chikuzen +Kalpatta +Mannārgudi +Ağdaş +Idar +Veliyangōd +Villa Gesell +Kendal +San Agustín Chahal +Dayr Abū Sa‘īd +Mangdongshan +Kollengode +Gotse Delchev +South Ubian +Rārōtt +Barbosa +Laurel +Point Fortin +Mashan +Bourgoin-Jallieu +Hajdúböszörmény +Tokmak +Schererville +Hobart +Xalatlaco +Lākheri +Inagawa +Zamboanguita +Limoeiro do Ajuru +Burton +Pedro Betancourt +Eastern Goleta Valley +Antsahalava +Güstrow +Chiknāyakanhalli +Landsberg +Maranga +Johnston +Purificación +Vandœuvre-lès-Nancy +Cambuí +Sumilao +Behror +Olocuilta +Temse +Unterschleißheim +Bra +East Palo Alto +Vallentuna +Central +Périgueux +Nan’ao +Sevenoaks +Demnat +N’Gaous +Dongyuya +Sint-Michielsgestel +Duanzhuang +Hutto +Fountain +Mīnād +Garfield Heights +Ja‘ār +Oak Park +Greenville +Augustów +Lalla Mimouna +Kumalarang +Flandes +Escárcega +Melrose +Northfleet +Arari +Manticao +Sankaridrug +Yangshuling +Fritissa +Nejapa +Brecht +Buenos Aires +Dembī Dolo +Zaltbommel +Charenton-le-Pont +West Windsor +Northeim +Tournefeuille +McCandless +Pirakkād +Juchitepec +Garchitorena +Ibrāhīmpatnam +Mūdbidri +Bujaru +Ātmakūr +Pueblo Nuevo Viñas +Vadakku Valliyūr +Uthal +Krimpen aan den IJssel +Tizi Gheniff +Perafita +Guyancourt +Cramlington +Texarkana +Funchal +Kyegegwa +Golden Gate +Figuil +Espigão D’Oeste +Budaörs +Pontedera +Lavezares +Bagong Pag-Asa +Kostomuksha +Lāmerd +Brownsburg +Likino-Dulevo +L’Arbaa Naït Irathen +Bluffton +Marar +Santiago de Baney +Bāglung +Crofton +Kavajë +Carney +Suisun City +Didiéni +Prainha +Póvoa de Santa Iria +Pilachikare +Ra’s al ‘Ayn +Glória do Goitá +Anderson +Casma +Pattikonda +Nalakadoddi +Castelvetrano +Madang +Jacksonville +Asipovichy +Aralam +Pignon +Glenville +Tönisvorst +Shikharpur +Mioveni +Catarroja +Guotang +Pitou +Yōrō +Kirkwood +Ski +Vaihingen an der Enz +Linden +Swarzędz +Benhao +Emmen +Sun City Center +Arfoud +Carmona +San Rafael +Shuangtian +Magna +Namaacha +Chalatenango +Khunti +Novaya Usman’ +Licab +Riihimäki +Shibushi +Oakleaf Plantation +Oslob +Rasrā +Gates +Garaimāri +Perry Hall +Quivicán +Paratinga +Cachoeira +Divnogorsk +Winnenden +East Lake-Orient Park +Bromsgrove +Kōshū +Udaipur +Fandriana +Drexel Hill +Le Plessis-Robinson +Saalfeld +Actopan +Capitán Bermúdez +Maddagiri +Orchards +Fundão +Tōmi +Cottica +Changzhi +Dougabougou +Cañada de Gómez +Beldānga +Esmeralda +Bulung’ur Shahri +Poás +Ob +Redondela +Zapotiltic +Santa Cruz Cabrália +Poona-Piagapo +La Source +Arniquet +Kamphaeng Phet +Aipe +Irará +Draveil +San Fernando +Oktyabr’sk +Ath +Washington +Blankenfelde +Shaker Heights +Horki +Nieuwkoop +Anadia +Hinunangan +Rāghopur +Yehud +Queensbury +Yomou +Nelson +McDonough +Bühl +Ulundi +Pallijkarani +Mahendragarh +Nakrekal +Takanezawa +São Miguel do Iguaçu +Mégara +Burbank +Culemborg +Sopó +San Cristóbal +Moñitos +Primero de Enero +Ozumba +Sānkrāil +Springe +Kelkheim (Taunus) +Englewood +Bogdanovich +Viacha +Xiaobazi +Desenzano del Garda +Colgong +Agde +Rapallo +Chili +Şūrān +Hisor +Budaka +Sherobod +Cambuslang +Danville +La Oliva +Pālpā +Madīnat Zāyid +Casselberry +Mehlville +Sonāmukhi +Kālappatti +Baixo Guandu +Zhongwangzhuang +Sexmoan +Riesa +Shumerlya +Teapa +Marigliano +Maubeuge +Whitehall +Boxmeer +Pont-y-pŵl +Kitui +Paripiranga +Vattalkundu +Chortkiv +Catandica +Stoughton +Shiqiao +Uttamapālaiyam +Lugus +Mirandópolis +Sendjas +Santo Domingo +Gagarin +Deodrug +Johi +Somotillo +Tocache Nuevo +Vallikunnam +Kudat +Togitsu +Winterswijk +Matouying +San Marcos +Benavente +Reforma +San Javier +Hendījān +Ouled Haddaj +Carmo do Paranaíba +Meißen +Pirri +Ipubi +Vandiyūr +Ponmana +Dapa +Úrsulo Galván +Abasolo +Senhora da Hora +Ahmer el ’Aïn +Ofaqim +Sortöbe +Timizart +Gūdalūr +Câmpina +Humansdorp +Ermont +Pervomaiskyi +Ystad +Cervia +La Dorada +Tameslouht +Cruces +Plachēri +Germī +Sotteville-lès-Rouen +Langley +Ammi Moussa +Lake in the Hills +Laplace +Kailāras +Ḩawţat Sudayr +Hajira +Limoeiro de Anadia +Orange +Bochnia +Tondela +Russellville +Hakmana +Ampatuan +Barabinsk +Humberto de Campos +Sibanicú +Široki Brijeg +Hanawa +Santo Niño +Pucón +Greenville +Haines City +Fabriano +Stafford +Siquijor +Ban Phai +Jimenez +La Calera +Tabuelan +Kuttuparamba +Candelária +Ariyalūr +Dalfsen +Nāhan +Bielawa +Três Marias +Coromandel +Petrovsk +Tazmalt +Rösrath +Borzya +Karippira +Lādwa +Arrentela +Gidri +Easton +Grimsby +Ponot +Munsan +Lacey +Ruskin +Mount Olive +Mondlo +Carinhanha +Balakliia +Welk’īt’ē +Santa Cruz das Palmeiras +Pokhrām +Stockbridge +Emmendingen +Baleno +Mathba +Thabazimbi +Bou Arfa +Izegem +Rehoboth +Kūdligi +Vīrapāndi +Villiers-le-Bel +Śrem +Duzhuang +Ibaiti +Las Rosas +Caetés +Caicedonia +Takahashi +Babatngon +Hirado +Tiruvambadi +San Lucas Sacatepéquez +Narsimlāpet +Curridabat +Kamalāpuram +Saikaichō-kobagō +Garupá +Lepe +Roseaux +Yoshida +Bugarama +Kiskunfélegyháza +Asago +Tarawa +Pingdeng +Bom Jesus +Jeffersontown +Ponmala +Pápa +Landhaura +Metu +Fresnes +Acatenango +Manatí +Hanwell +Premiá de Mar +Stanford le Hope +Zighout Youcef +Umrat +Martorell +Misilmeri +West Springfield +Pilón +Kozhinjampāra +Bella Vista +Novyi Rozdil +Zhonghechang +Kikinda +Carauari +Nongstoin +Rāikot +Sidi Smai’il +Bixby +Schwelm +Independence +Harrison +Tanglou +Tantoucun +Taza +Maki +Lansing +Chahe +Höxter +Andoharanomaitso +Muritiba +Soissons +Krotoszyn +Ballymena +Tibiao +Karakoçan +Paraparaumu +Mabini +Pakwach +Katima Mulilo +Yerres +Leonding +Ferdows +Candelaria +Pilar +Bang Phongphang +Murlīganj +Nauhata +Souk et Tnine Jorf el Mellah +Benicarló +Esztergom +Jamestown +Navolato +Old Harbour +Santiago +Doña Remedios Trinidad +Geislingen an der Steige +Taungup +Nowy Dwór Mazowiecki +Esparza +San Salvador +Mehdya +Pitoa +Oyabe +Pattāmbi +Sarny +Nueva Concepción +Mondragone +Gevaş +Saito +Kombissiri +Fenoarivobe +Pawāyan +Manga +Ciudad Sahagun +Kartaly +Neduvannūr +Edayikunnam +Agawam +İhsaniye +Mirzāpur +Tudela +Jujutla +Bom Jesus +Xizhou +San Carlos +Tracuateua +Laoaoba +Mampikony +Yangiyer +Akkattettar +Bethlehem +Iúna +Rancharia +Simri Bakhriārpur +Sottaiyampālaiyam +Shangluhu +Koprivnica +Zhongtai +Statesville +Moribabougou +Manampizha +Munnalam +Jaciara +Mechernich +Saugus +Frome +Blackrock +Sabra +Mouzaïa +El Copey +Plaine du Nord +Santo Niño +Baradero +Brodnica +Reinbek +Rūdehen +Basay +Bridgewater +Isnos +Aleysk +Hattersheim +Azángaro +Verden +Bamba +Nivelles +Madison Heights +Amaliáda +Ḩarīr +Monroeville +Enterprise +Saint-Étienne-du-Rouvray +Bāgha Purāna +Losal +Dubăsari +Ambatolampy +Bin-Houyé +Longaví +Rajpur +Heerenveen +Pārdi +Cajati +Szentendre +Matsubushi +Samut Songkhram +Izu +Mendefera +Frattamaggiore +San Lorenzo de Esmeraldas +Sue +Pāvugada +Gusev +Ilave +Condega +Nenmem +Elanjivaliseri +Venezuela +Puerto Leguízamo +Zhailuo +Frankfort +Tsushima +Piracuruca +Wood Green +Milton +Oulad Hammou +Conceição da Barra +Selargius +Mpika +Coyaima +Siraha +Douar Oulad Aj-jabri +Tha Yang +Goio-Erê +Kumru +Castel Volturno +Ouled Ben Abd el Kader +Bonito Oriental +Spring +South Laurel +Forest Hills +Ludwigsfelde +Baishaling +Bushey +Saint Bernard +Almus +Cártama +Harūr +Raseborg +Ar Ruţbah +Short Pump +Byaroza +Jaramijó +Allen Park +Valencia +Aberdeen +San Manuel +Ogawa +Yaldā +Bānswāda +Mitú +Conceição das Alagoas +Datu Piang +Qianxucun +Toli +Ciro Redondo +Rāmanayyapeta +Mahārājpur +Voúla +New Iberia +Sidi Lakhdar +Kamateró +Dieppe +Pongoz +Nkhotakota +Aioi +Ban Bang Khu Wat +Villanueva +Guararema +Prata +Passira +General San Martín +Baunatal +Mannanchōri +Clarksburg +Princes Town +Toucheng +Kpandu +Kočani +Arivonimamo +Brāhmana Periya Agrahāram +Henstedt-Ulzburg +Puvali +Tarāna +Kizhakkōtt +Puttankulam +Magog +Boisbriand +Taiwa +Sāho +Mollendo +Higashikagawa +Srungavarapukota +Glen Ellyn +Karanjiā +Oltinko‘l +Aïn Taoujdat +Temerin +Truskavets +Monsey +Supe +Bermejo +Saint-Sébastien-sur-Loire +Ruy Barbosa +Huanghuajing +Guamal +Bakhor +Tablat +Libacao +Herentals +Rio Pardo de Minas +Kolambugan +Adrogue +Safājā +Shakīso +Juangriego +Geilenkirchen +Maravilha +Qiman al ‘Arūs +Vícar +Northampton +Lagdo +Aného +Ans +Köşk +Giżycko +Bardaskan +Altınova +Kevelaer +Königsbrunn +Cuitzeo del Porvenir +Temescal Valley +Hājipur +Edappalli +Bergenfield +Caucete +Antur +Eonyang +Diangouté Kamara +Cocal +Sirsāganj +Walnut +Santo Antônio do Içá +Vakfıkebir +Poggibonsi +Kotagiri +Zacoalco de Torres +Metepec +Bejucal +Grimma +Heywood +Əmircan +Whitehorse +Wappinger +Heshancun +Reda +Kroměříž +Ljubuški +Ayun +Babar +Carmagnola +Ouésso +Pokhvistnevo +Agui +Dobropillia +Shāhpura +Arqalyq +Çiftlik +Lier +Chatan +Eagle Pass +Henderson +Itabela +Guma +Camas +Dar Bel Hamri +Warin Chamrap +Nalayh +Villaviciosa de Odón +Nirasaki +Khrestivka +Gaotan +Saldanha +Obama +Carrickfergus +Tetela de Ocampo +Sønderborg +Chennamangalam +Glen Cove +Pinyahan +Alotenango +Arnstadt +Cabricán +Čapljina +Bearsden +Bhambia Bhai +Udomlya +La Paz Centro +Cabangan +Ridgecrest +Sāngola +Sheohar +San Vicente dels Horts +Neptune +Dieppe +Massamá +Tsinjoarivo +Conchal +Golo-Djigbé +Bom Jardim +Seseña +Kakiri +Tara +Maryland Heights +Kirov +Hazar +Kuli +Nallıhan +Gyula +Xochistlahuaca +Nakhal +Mima +Qujingpu +Sueca +San Vicente de Chucurí +Casa Branca +Pô +Khulm +Guaimaca +Wegberg +Honchō +Dajabón +Djugu +Kalwākurti +East Hampton +Reddish +Converse +Rhennouch +Lincoln +Devanhalli +Gingee +Leichlingen +Villazón +Khust +Åkersberga +Oakdale +Vallauris +Kefar Yona +Bayang +Nunspeet +Navahrudak +Mainit +Vanves +Mchinji +Anajás +Lomme +Twentynine Palms +Douentza +Tainai +Dübendorf +Geldrop +Qornet Chahouâne +Sahavato +Imito +Sandrandahy +Ambohijanahary +Masanwa +Bo‘ka +Qianshanhong Nongchang +Jiaoxiling +Sāila +Limeil-Brévannes +Kārākurisshi +Billericay +Cuartero +Langedijk +Isser +Almazora +Lubok Antu +Montfermeil +San Felipe Jalapa de Díaz +Pacho +Belpasso +Zeitz +Yangyuhe +Orlová +Shaler +San Andrés Sajcabajá +Kasangulu +Kushtagi +Gragnano +Shalqar +San Martín de los Andes +Kanavāikuli +Punceres +Āron +Lake Jackson +Dhabauli +Labasa +Goriar +Hamar +Canosa di Puglia +Vilāngudi +Noé +Douglas +Tsinjoarivo +Aloran +Garden City +Nochistlán de Mejía +Bitam +Ennis +Malmal +Iguaba Grande +Sfizef +Newry +Danvers +Mocímboa +Dahmani +Łuków +Bouka +Ash Shajarah +El Sauce +Reina Mercedes Viejo +Reina Mercedes +Bordj el Bahri +Ambohitompoina +Larreynaga +Majayjay +Caridad +Gülnar +Maple Valley +Gyöngyös +Hiji +Harelbeke +Cecina +Dingalan +Melgaço +Talusan +Orvault +Mytilíni +Chichaoua +San Isidro +Zanandore +Ampasimanolotra +Mahaplag +Quiroga +Daphne +Villa Luvianos +Topki +Sirakorola +Chalhuanca +Umargām +Guaçuí +Sabaneta +Kakuda +Zolotonosha +Hamtramck +Bārughutu +Griesheim +Uchturpan +Muchun +Sestao +Sachse +Traipu +Wāsi +Mizumaki +Darlaston +Belmont +Nibria +Magdalena +Motozintla +Vleuten +Lohne +Rockledge +Māttūl +Tualatin +Wilmette +Vadnagar +Aci Catena +Tlalpujahua de Rayón +Williston +Chato +Ramsey +Desnogorsk +Viñales +Soledad de Doblado +Bongor +Bernards +Ivanjica +Tenares +Ashington +Chaska +Mongo +Fūman +Ramotswa +Charkhāri +Paivalike +Williamsport +Pirapòzinho +Immokalee +Monção +Qibray +Itapissuma +Ōuda-yamaguchi +Khātegaon +As Sarw +Gabasumdo +Havran +Hidrolândia +Sundern +Lapuyan +Ocean +Batken +Tahla +Palmar de Varela +Lebrija +João Alfredo +Itacaré +Tudiyalūr +Parabiago +Mogliano Veneto +Dodge City +San Giovanni in Persiceto +Axim +North Kingstown +Koewarasan +Borşa +Kashima +Santa Bárbara +George Town +San Miniato +Shuiding +Bellaa +Wajimazakimachi +Teltow +Spinea +Santa Rosa de Lima +Alatri +San Pedro del Pinatar +Poruvakara +Porto Belo +Troyan +Le Chesnay +Tabira +Aparecida do Taboado +Amarpur +San Pablo +Brunssum +Argelia +Ban Chang +Kitsuki +Clinton +New Windsor +Atlautla +Tuku +Malargüe +Lagoa Vermelha +Phuntsholing +Tangutūru +Huntley +Niuchangqiao +Zongdi +Mukher +San Juan Guichicovi +Di Linh +Parsa +Hikawa +Mount Pleasant +Leon Postigo +Longtan +Pachor +Pādiyanallūr +Yahaba +Bhimbar +Yemanzhelinsk +Theniet el Had +Quijingue +Shatiancun +Shilan +Sucy-en-Brie +Mont-Dore +Maracás +Baesweiler +Zarechnyy +Lagoa Sêca +Tysons +Veendam +Reisterstown +Pilar do Sul +Contla +Prior Lake +Vila do Conde +Assisi +Soignies +Ambodibonara +New London +Cabrero +Madison +Svendborg +Ouled Fayet +Waddān +Swatara +Laojiezi +Hulst +Câmpulung +Taougrite +Andenne +Ouled Slama Tahta +Narat +Wengtiancun +Wangtang +Karlskoga +Atharan Hazari +Jauja +Mulchén +Homewood +Mazenod +Conner +Pombos +Fortuna Foothills +Wetter (Ruhr) +Kantai +Sorochinsk +Kobuleti +Heemstede +Novo Oriente +Rardhu +Citong +Rāyamangalam +Hacıqabul +Ninomiya +Patjirwa +Teno +Marion +Jarrow +Niimi +Abarkūh +Millville +Witney +Takahagi +Apaxco de Ocampo +Pitogo +Daulatkhān +Marshalltown +Marolambo +Sūlūru +Sitakili +Timaru +Nuwara Eliya +Verkhniy Ufaley +İpsala +Triunfo +Sint-Joost-ten-Node +Tazoult-Lambese +Fichē +McHenry +Shingū +Nāsriganj +Supía +Bourem +Oiapoque +Bandipura +Lemon Grove +Kholmsk +Oulad Yaïch +Tongyangdao +Duayaw-Nkwanta +Piraí +Konnūr +Ukiha +Aleksandrovskoye +San Carlos +Águas Santas +Schloß Holte-Stukenbrock +Feteşti +Purral +Ciudad Bolívar +Los Reyes de Juárez +Toqsu +Villa El Carmen +Arar +Vandikarai +Maloyaroslavets +Algemesí +Mandirituba +Malekān +Sürmene +Crestview +Mu’tah +Mililani Town +Cyangugu +Jardim +Wangen im Allgäu +Heilbron +Ružomberok +Guastatoya +Overath +Caracal +Sébikhotane +Butzbach +Oppegård +Villareal +Shotley Bridge +Sādri +Ayyagarpet +Ibipetuba +Nalbāri +Itaí +Ashford +Penukonda +Leiderdorp +Staraya Russa +Itako +Tuxpan +Macau +Chicago Heights +Ciudad Tecún Umán +Kedu +Balussheri +Chillán Viejo +K’olīto +Panauti +Paouignan +Korgan +Strausberg +Jalpan +Varandarapilli +Kent +Green +King +Blerick +Ikaruga +Parksville +Aytos +Drimmelen +Alvin +Shtime +Palanas +Bihpur +Balch Springs +Castaños +Macalelon +Neenah +Cuerámaro +Pallippurattusēri +Chiavari +Navrongo +Zarraga +Almuñécar +Savur +Deer Park +Nokha +Piešťany +Gurlan +Xovos +Ilchester +Santo Antônio do Monte +Porto Calvo +Bhānder +Behara +Corrente +Ramon Magsaysay +Ehingen an der Donau +Santo Amaro da Imperatriz +Mason City +Sipacapa +Mirnyy +Haliyāl +Bady Bassitt +Citrus Park +Zalingei +Grigny +Pearl +Choba +Novi Ligure +Akitakata +Hamminkeln +Álvares Machado +Talisay +New Lenox +Kushva +Tepehuacán de Guerrero +Gubkinskiy +Debiāpur +Hayang +Kahului +Fremont +Morón de la Frontera +Holbrook +Redenção +Longton +Bourzanga +Calimete +Ezhipram +Garden City +Castelli +Oak Forest +Mocajuba +Ewa Gentry +West Islip +Kimbe +Sihecun +Boralday +Merrimack +Kobyłka +El Abadia +Taraka +Paiporta +Les Anglais +Tauramena +Kernersville +Kupiansk +Conception Bay South +West Linn +Melton Mowbray +Bo’ao +Nguti +Buri Ram +San Juan de Urabá +Dargeçit +Zhongshan +Keswick +Leimen +Hohen Neuendorf +Lindenhurst +Jonava +Pijnacker +Thomasville +Digboi +Piçarras +Dame-Marie +Čakovec +Parimpūdi +Lambersart +Aalten +San Agustín Tlaxiaca +Illkirch-Graffenstaden +Asheboro +Rappang +Novi Grad +Sikonge +Nemuro +Jeffrey’s Bay +Awara +Brétigny-sur-Orge +Haiyang +Rheinbach +Lishanpu +Pershotravensk +Mirano +Ambohijanaka +Pereyaslav-Khmel’nyts’kyy +Afzalpur +Fort Saskatchewan +Tall Rif‘at +Sol’-Iletsk +Long Thành +Liugoucun +Batgram +Quakers Hill +Ichikikushikino +Villagrán +Muchamiel +Vittorio Veneto +Lochearn +Zomin Shaharchasi +El Alia +Minaçu +Irimbiliyam +Ágios Nikólaos +Pedernales +Kuzhittura +Nova Olinda do Norte +Nayoro +Ksebia +Klosterneuburg +Toguéré-Koumbé +Harbiye +Badiangan +Pasinler +Wakefield +Libenge +Guanxi +Nazaré +Wiesloch +San Isidro +Haverhill +Benicia +Rāver +Loutété +Quezon +İmamoğlu +Springettsbury +Märsta +Sens +Leisure City +Plum +Santa Eugenia +Nizao +Thetford +Amatepec +Catamayo +Granite City +Taverny +Malebennūr +Mādhura +Wooster +Ermelo +Āmangal +Bāgepalli +Ticuantepe +Alexânia +Pueblo Bello +Chiriguaná +Marcos Juárez +Pāyakarāopeta +Vohipaho +Tsaravary +Miandrarivo +Mandabe +Andranomavo +Antsiatsiaka +Alakamisy Itenina +Arandu +Jaglot +Haqqulobod +Aragua de Barcelona +Arrecifes +Barbacha +Paracuellos de Jarama +Catió +Woolwich +Estarreja +Kriens +Belmont +Tarragona +Rapperswil-Jona +Oullins +Ourika Wawrmas +Ambinanisakana +Soanierana Ivongo +Anajatuba +Limbe +Aldridge +Basi +Aripuanã +Kapellen +Kadappuram +San Sebastián de Yalí +Ar Rudayyif +Novo Cruzeiro +Gladstone +Nava +Ternivka +Uyuni +Seaford +Lemoore +Bouguirat +Potrerillos +Wassenaar +Zuitou +Heppenheim +Fidenza +São Bernardo +Pfaffenhofen +Werkendam +Tupanatinga +Albania +Farnworth +Moon +Ureshinomachi-shimojuku +Dietikon +Şafāshahr +Nainijor +Tambo +Łowicz +Znamensk +Pemberton +Celendín +Nelliyalam +Qā’emīyeh +Khmilnyk +Margherita +Maner +Pınarbaşı +San Andrés de la Barca +Kulasekharapuram +Atitalaquia +Kaluđerica +Karasuk +San Antonio del Monte +Wahga +Mayskiy +Lobatse +Wheeling +Acapetahua +Bridgeton +Baraúna +Al Qiţena +Albignasego +Pāppākurichchi +Pāmidi +Douglas +Idigny +Miracema +Kadambanād +Alhaurín el Grande +Lukula +Kararān +Sarayönü +Bakhchysarai +San Luis Jilotepeque +Kızılcahamam +Arerāj +Union City +Paducah +Madattukkulam +Kālikāvu +Miki +Feidh el Botma +Gursarāi +Pūnch +Scicli +Chíos +Shoreview +Nsanje +Xima +Bozyazı +Clayton +Canindé de São Francisco +Majagua +Vādippatti +Bankāpur +Shencottah +Villeparisis +Alitagtag +Temple Terrace +Santa Margarita +Rambouillet +Ives Estates +Labrador +Vilyeyka +Wesselsbron +Cangas +Ban Phonla Krang +Khānābād +Bamessi +Magilampupuram +Fortul +Tūvūr +Bolton +Srīnivāspur +Garbagnate Milanese +Trikkunnapuzha +Paracuaro +Margate +Mirassol d’Oeste +Jumilla +Líšeň +Cenon +Solânea +Tamayo +Santa María de Jesús +Sannois +‘Abasān al Kabīrah +Qarah Ẕīā’ od Dīn +Thātha +West Melbourne +Bétera +Tlaxcoapan +Mahina +Gadhada +Bidur +Vernon Hills +Tamorot +Meppāyyūr +Magarao +Malitbog +Goianinha +Cormeilles-en-Parisis +Upper Dublin +Semiluki +Hennigsdorf +Ḩukūmatī Baghrān +Soron +Santa María Ixhuatán +Mégrine +Alattūr +Miacatlán +Saguiaran +Bhuban +Morales +Los Córdobas +Circasia +Kiruna +Ronse +Wanlaweyn +Sapian +Qahā +Māmidālapādu +Palm Springs +Lamego +Pirenópolis +Miyanaga +Piracaia +Shelek +Shangxiao +Wellington +Pitangui +Quarrata +Heiligenhaus +Turrialba +Nediyanad +Ipu +San Juan +Auburn +Ambodiangezoka +Itamaracá +Al Quţayfah +Sacramento +Birine +Bad Neuenahr-Ahrweiler +Nannamukku +Paianía +Talāja +Bien Unido +Segezha +Samayac +Highbury +Kuppādi +Mizque +Bugho +Dalsingh Sarai +South Portland +Kirovsk +Horn Lake +Las Flores +Frías +San Pablo +Ajka +Chettipālaiyam +Manjacaze +Betong +San Felipe +Sun City West +Sibi +Silao +Rājgarh +Buldan +Manihāri +Cuajinicuilapa +Maçka +Edwardsville +Carrollton +Lauri +Plainview +Propriá +Moulay Bousselham +Dar Chioukh +Baytūnyā +Aschersleben +Jaguarão +Chuanliaocun +Newton Mearns +Pantar +Wieliczka +Ibimirim +San Benito Abad +Sidi Akkacha +Voinjama +Ghatāro Chaturbhuj +Okuta +Nova Esperança +South Pasadena +Ratau +Iheddadene +Paramus +Susquehanna +Macrohon +Lauaan +Miguel Pereira +Porto da Folha +Sofiyivs’ka Borshchahivka +Bussy-Saint-Georges +Jarocin +Casiguran +Gioia del Colle +Superior +Iesolo +Tarui +Plainview +La Teste-de-Buch +Shāhganj +Molíns de Rey +Sanger +San Alberto +Lanquín +Manāsa +Horsham +Agía Varvára +Dasūya +Perumbalam +Nyāmti +Severouralsk +Cabot +Zeboudja +Mint Hill +Mantena +Sainte-Thérèse +Étampes +Deogarh +Ituporanga +Kantābānji +Nacimiento +Aleksandrovac +Krasnoarmeysk +Eureka +Novoaleksandrovsk +Dois Córregos +La Unión +Hennaya +Bubong +Ahmadābād +Giarre +Qingshan +Brawley +Clarence-Rockland +Uchinada +Shirley +Charata +Neckarsulm +Karumāndi Chellipālaiyam +Troy +Elmira +Sebeş +Al Karnak +Capão do Leão +Xincun +Timbiras +Upper Macungie +Cheadle Hulme +Sokoura +Madalum +Marapanim +Achern +Kayapa +Langdu +Blagnac +Apam +Quilalí +Água Preta +El Monte +Gördes +Kaisarianí +Mabini +Randolph +Wete +Wall +Pérez +Lido di Iesolo +Kamyshlov +Makubetsu +Apollo Beach +Maski +Oktyabrsk +Tāmarakulam +Nakhon Phanom +Caboolture +Santa Josefa +Pānchla +Tortona +Tecolutla +Peniche +Mandi +Māvelikara +Sélibaby +Lauf +Mauganj +Groß-Gerau +Newton Aycliffe +Beohāri +Madruga +Nādbai +Dinokana +Zemmouri +La Prairie +Gorlice +Miramas +Del Gallego +Blenheim +Owatonna +Estoril +Binə +Mühlacker +Dīnānagar +Cajuru +Jinju +Vīrakeralam +Ouled Mimoun +Rangia +Kirovsk +Camas +Balboa +East Grinstead +Elakādu +Ashton in Makerfield +Rēzekne +Dalnerechensk +San Jose +Zottegem +Bombo +Dongen +Gundlupēt +Lagindingan +East Chicago +Jaltenco +Vicência +Reoti +Panchānandapur +Pandag +Batavia +İncesu +Yuanyangzhen +Poldokhtar +Wyszków +Tougan +Sapouy +Ilha Solteira +Vogošća +Bāgh-e Malek +Pensilvania +Lichtenburg +Ondokuzmayıs +Duptiair +Elói Mendes +Kirzhach +Cheranallūr +Parit Buntar +Bergerac +Tehuipango +Weiterstadt +Navabad +San Pablo +Caririaçu +Clydebank +Windsor +Ulaangom +Ubaidullāhganj +Werota +Siquinalá +Wasco +Walpole +South Salt Lake +Ibotirama +Bingen am Rhein +Nordenham +Cotoca +Koelwār +Khā̃dbāri̇̄ +La Ceiba +Batalha +Nuevo Arraiján +Aru +Bozkır +East Hempfield +Baden +Az Zabadānī +Făgăraş +Narasannapeta +Rasiāri +Sabaa Aiyoun +Beramanja +Saint-Bruno-de-Montarville +Kaboïla +Wright +Yapacani +Aş Şanamayn +Ōra +Teustepe +Pooler +Laranjal Paulista +Semīrom +Zhaicun +Bayanhongor +Carbonia +Karpinsk +Midland +Infanta +Mirganj +Mel Bhuvanagiri +Paz de Ariporo +Bourdoud +Lamut +Kūdlu +San Giovanni Rotondo +Zirndorf +Poro +Colonia del Sacramento +Buesaco +Lainate +Ganjing +Tekkalakote +Chivasso +Rancho Grande +Willebroek +Kalfou +Woodburn +Muñiz +Ksour Essaf +Gedera +Tālīkota +Saumur +Kiskunhalas +Wilmslow +Polysayevo +Labytnangi +Aït Faska +Sogrāha +Cañas +Eṭ Ṭīra +Iradan +Vadakkanandal +Buddayyakota +Kottakota +Guruzāla +Lunel +Marimba +Athens +Liushuquan +Kętrzyn +Rosario de la Frontera +Flémalle-Haute +Puerto Varas +Budhlāda +Montemor-o-Velho +Shuanghe +Sant’Anastasia +Burlington +Tavira +Sanchez-Mira +Suphan Buri +Lice +Selm +Manito +Jirwa +Mankāchar +Iskandar +Baykan +Forest Grove +Beuningen +Mortsel +Imperial Beach +Austin +San Ignacio +Mesagne +Frankfort +Dum Duma +Suār +Gūdūru +Rīngas +Kaous +Oum Hadjer +Cifuentes +Perevalsk +Ouled Rahmoun +Dongfeng +Bijbiāra +Pacasmayo +Çankırı +Wum +Santiago Papasquiaro +Lockport +Bāruni +Vadakku Viravanallur +Montichiari +Gourma Rharous +Tuxpan +Huaquechula +Itapuranga +Skopin +Terlizzi +Kuyucak +Tōno +Desamparados +Anosipatrana +Novopavlovsk +Campos Gerais +Terrytown +Misserghin +Camanducaia +Mzimba +Sierra Bullones +Tianyingcun +Elangunnapuzha +Medina +Phulera +Requínoa +Erice +Terdāl +Tholen +Konobougou +Woodstock +Winona +Élancourt +Dengjiazhuang +Halemba +Tralee +Northdale +Kathu +Key West +Chellalat el Adhaouara +Dancagan +Mahates +Franklin +Thetford Mines +Odemira +Tianwei +Alagoa Grande +La Máquina +Bad Honnef am Rhein +El Hadjar +Casillas +Keystone +Jászberény +Mahitsy +Emmeloord +Dardoq +Gamboma +Burntwood +Zavodoukovsk +Chuimatan +Buenavista +Ridgewood +Hercules +Burgos +Hénin-Beaumont +San Juan Atitán +Renigunta +Bangzha +Lübbecke +Barra da Estiva +Hovd +Skardu +Bajina Bašta +Fort Mill +Cave Spring +Idhnā +Sāndi +Vertou +Bresso +Ambatomborona +Malaimbandy +Mahambo +Ambatofotsy +Tsarazaza +Poytug‘ +Brasiléia +Majiadiancun +Harsewinkel +Sinait +Lakshmīcharīpāra +Gahmar +Gaoya +De Witt +Rosemount +Rich +Dehgolān +Wilsonville +Upper Moreland +Mangaldai +Gonglang +Fairland +Londonderry +Bom Jesus dos Perdões +Montreux +Dharmapuram +Puerto Píritu +Istmina +Tiruppattūr +Queimadas +Curtea de Argeş +Le Grand-Quevilly +Rāmpur +Tekman +Lodi +Santa Lucia +Binidayan +Bobon +Gonesse +Gölköy +Palm City +Giussano +Ōtake +Giyani +Chintalapūdi +Kimovsk +Pando +Big Spring +Gressier +Mathibestad +Socorro +Dolores +Columbine +São Joaquim +Fleetwood +Boscoreale +Santa Ana +Bournville +Masrakh +Elk River +San Sebastián Coatán +Putignano +Gembloux +Mannachchanellūr +Maevatanana +Santa Perpetua de Moguda +Krishnāpuram +Cavaillon +Dano +Jaynagar-Majilpur +Cesenatico +Grandview +Azacualpa +Hjørring +Tubize +La Garde +Grevená +Haoping +Puerto Escondido +Lučenec +Mimoso do Sul +San Martín +El Jícaro +Formosa do Rio Preto +Gilarchāt +Demre +Jodhpur +Teniente Primero Manuel Irala Fernández +Chevella +Bessemer +El Quetzal +Kibeho +Noicattaro +Galatina +Dhrol +Ōmachi +Norfolk +Xishan +Vimercate +Colleyville +Vesala +Jharka +Marmara Ereğlisi +Unterhaching +Boureït +Jenks +Fonte Boa +El Cerrito +Chanhassen +San Juan +Ciempozuelos +Santa Isabel do Rio Negro +Perunkalattu +Ban Pa Sak +Montgomery +Kotal +Port Alfred +Amnat Charoen +Alaçam +Calpe +Gokarn +Ciudad Altamirano +Triggiano +Cəlilabad +Lindau +Dondon +Canarana I +Artvin +Yuanchang +El Progreso +Suitland +Inkster +Vitez +Nagai +Gradignan +Assèmini +Schleswig +Andasibe +San Vicente de Cañete +Polasara +Shenley Brook End +Fort Washington +Kārkala +Lanaken +Kulmbach +Korkut +Aurillac +Vignola +Vayakkalattu +Maracanã +Consett +Rāman +Marysville +Marco +Kadamalaikkundu +Koko +Alboraya +Lādkhed +Nechí +Kunisakimachi-tsurugawa +Le Ray +Vichy +Maintirano +Mungaoli +Chhota Udepur +Tubay +Rockville Centre +Santo Cristo +Florence +Marshfield +Pura +Helmstedt +Karavaram +Conversano +Koba +Arapoti +Wągrowiec +Bishunpur Sundar +Seondha +Natividad +Novelda +Pāveh +Zakopane +Cherukolattur +Biarritz +Talisayan +Chinna Salem +Santa Maria +Firmat +Břevnov +Vorkādi +Halfmoon +Koper +Coffs Harbour +San Antonio del Sur +Horb am Neckar +Ginan +Tecax +Villanueva de la Serena +Béma +Hasköy +Yinajia +Felipe Carrillo Puerto +Kireyevsk +Lapão +Arida +Lourinhã +Tabina +Néa Filadélfeia +Mpophomeni +Bandar-e Deylam +Palm River-Clair Mel +Ban Piang Luang +Rinteln +Lincoln +Kłodzko +New Milton +Tarangnan +Santeramo in Colle +Oxford +Lower Providence +Nanpingcun +Venice +Jardín América +Zhutailing +Mogtédo +Haisyn +Carahue +Champs-Sur-Marne +Coulsdon +Nova Prata +Diébougou +Safīpur +Nāgod +Scandiano +Huejotzingo +Ellwangen +Netāpur Tānda +Pereira Barreto +Fenoarivo +Malanguan +Lamzoudia +Kurchaloy +Fort Beaufort +Santa Lucia La Reforma +Tosa +Batabanó +Friedrichsdorf +Ligang +Villanueva +Tōin +Pace +Sagara +Imatra +Siqbā +Kanchanaburi +Oulad Said +Voorschoten +Doba +Ḩaql +Yolombó +Foughala +São Sebastião da Boa Vista +Altavas +West Chicago +Phulpur +Nanminda +Palma +Keşlə +Otradnoye +Geretsried +Francavilla al Mare +Trussville +Alegria +Busuanga +Tumwater +Moscow +Igaci +Utena +Kāko +Farnham +Valdagno +Migdal Ha‘Emeq +Porto Sant’Elpidio +Inajá +Sliedrecht +Warrington +Velenje +El Tarf +Genet +Mount Gambier +Tarkeshwar +Sirumugai +Missour +Chainpura +Sankt Wendel +Armentières +Staunton +Şarkîkaraağaç +Bilston +Balabanovo +Montbéliard +Nagar +Haiwei +Pszczyna +São João Nepomuceno +Bandiagara +Kami +Raghunāthpur +Oliva +Vijāpur +Jericoacoara +Alençon +Idstein +Wellington +Aracoiaba +Derby +Abay +Stevens Point +Okemos +Ipameri +Onda +Niramaruthūr +Solano +Cliffside Park +Poranki +Shāhedshahr +Karayazı +Oltiariq +Witham +Licey al Medio +Rockaway +Miranda +Tipo-Tipo +Tougué +Vaterstetten +Falconara Marittima +Verl +Salor +Mar de Ajó +Saintes +Ayuquitan +Rottweil +Enna +Brilon +Lopez Jaena +Manyoni +Nettappākkam +Roseto degli Abruzzi +Al ‘Awwāmīyah +Borçka +Xenia +Kocaali +Ciying +Mimasaka +Fujikawaguchiko +Santa Helena +Oldbury +Menaceur +Treinta y Tres +Wetteren +Bungku +Bačka Palanka +Fort Hood +Sobradinho +Astorga +Mimata +Mannadipattu +Kalispell +Salaga +Orosháza +South Bradenton +Mahwah +Tupaciguara +Veenoord +Thatcham +Mercer Island +Exeter +Vistahermosa +Biłgoraj +Āgaro +Bathnāha +Bishop Auckland +Kouhu +Silver Springs Shores +Yany Kapu +Unisan +San Pedro Masahuat +Inta +São José do Norte +West Whittier-Los Nietos +Sangerhausen +Moscháto +Pauri +Tumbao +Anagé +Três Passos +San José +Losino-Petrovskiy +Brunoy +Rocha +Limonar +Kīranūr +Omigawa +Ain Aicha +Nyanza +Szentes +Caloto +Reading +Longbridge +Vnukovo +Leandro N. Alem +Bloxwich +Peekskill +Nagtipunan +Rouached +Craíbas +Vsetín +Chengannūr +Pérama +Belvidere +Zawyat ech Cheïkh +Öhringen +Miyaki +Lamu +Hudson +Demba +Maplewood +Jilikŭl +Showţ +Newberg +Coração de Jesus +Turek +Luzilândia +Tomares +Holt +Eaubonne +De Pere +Zhongcun +Salem +Villeneuve-la-Garenne +Diego Martin +Cherbourg +Roth +Arriaga +Nonāhi +Legnago +Yanaul +Upminster +Louis Trichardt +Ozëry +Ottumwa +San Miguel +Thal +Yanyan +Tarpon Springs +Lennestadt +Galt +Vierzon +Hazelwood +Santo Tomás +Ibirapitanga +San Giovanni Lupatoto +Karunāgapalli +Busselton +Norco +Rakovski +Salamanca +Pinal de Amoles +Yamagata +Timurni +Vynohradiv +Jevargi +Wiehl +Requena +Salzkotten +Lafayette +Harbel +Ulongué +Obertshausen +Mill Creek East +Farkhor +Giv‘at Shemu’él +Lengir +Oupeye +Kovancılar +Suşehri +Ula +Arzignano +Caledonia +Belén de Umbría +San Juan de Alicante +Mednogorsk +Denizciler +La Unión +Bābra +Forney +Camillus +Budai +Sebastian +Tanabi +Kirkby in Ashfield +Kingsville +Seriate +Merkānam +Lüdinghausen +Wādi +Mariano Comense +Chocontá +Weingarten +Bouknadel +Dyatkovo +Kawlin +Albergaria-a-Velha +Elkridge +Acatlán +Topoľčany +Reedley +Cândido Sales +Delitzsch +Chardonnières +Talugtug +Camalaniugan +Fengruncun +Chiromo +Barstow +Ganshoren +Almonte +Ilaiyānkudi +Mudgal +Atlatlahucan +Pfungstadt +Bacoli +Miahuatlán +Allen +Tipasa +Mananjary +Petershagen +Wumayingcun +Sandoná +Sastamala +Avon Lake +Apiaí +Workington +Guéné +Allendale +Uruçuí +Maaseik +Brodósqui +Somoniyon +Saranga +Morozovsk +Taquari +Albany +Adra +Şaydnāyā +Uttaramerūr +Kingswinford +Kola +Villarrobledo +Lātehār +Göle +Chekfa +Sarrat +Erlun +Piranhas +Pāonta Sāhib +Tirorā +Norden +University Park +Fish Hawk +Melrose Park +Banhatti +Walker +Espelkamp +Malyn +El Calafate +Jutaí +Overijse +Aridagawa +Barberton +Raahe +Monreal +El Ghiate +Fatimé +Vāsudevanallūr +Carteret +Álamo +Debila +Bagno a Ripoli +Moses Lake +Bardsīr +Dedham +Rhyl +Gulām +Sovetskaya Gavan’ +Kasrāwad +Ditzingen +Wewak +Panāgar +Brandon +Aimorés +Atkarsk +Candelaria +Campos Sales +Otuzco +Pallappatti +North Tustin +Santa María Tonameca +Sāhibpur Kamāl +Sohwal +Rānia +Conway +Edgewood +Dickinson +Atuntaqui +Torrelodones +Mombin Crochu +Saiha +Novi Travnik +Nāmrup +Corsicana +Āshkhāneh +Malaṅgawā +Mequon +Kadavūr +Baliqchi +Pagudpud +Hastings +Iglesias +Sahjanwa +Rajākheri +Kongsberg +Santo Tomás +Newport +Vicuña +Burē +Ninohe +Ibiapina +Yapqan +Jāfarābād +Safsaf +Correggio +Soccorro +Muskego +Beersel +Duiven +Oegstgeest +Šumperk +Shrīrangapattana +El Karimia +Muret +Armilla +Bombinhas +Romulus +Steenbergen +Seal Beach +Huşi +Waukee +Kochubeyevskoye +Lanling +Nabīnagar +Sohāgpur +Charentsavan +Camaligan +Wolfsberg +San Felipe +Whitehaven +Slavutych +Datça +Barwa Sāgar +Droitwich +Pangil +Daventry +Quirino +Coín +Saint-Ouen-l’Aumône +Boussé +Easton +São João dos Patos +Barki Ballia +Nepomuceno +Simria +Yarmouth +Olpe +Trikodi +Valls +Hukeri +Naubatpur +Rāmshīr +Maywood +Pathiyanikunnu +Sonzacate +Attili +Paoay +Hindley +Khed Brahma +Vangviang +Ehden +Ampahana +Fidirana +Mahatalaky +Ankazomborona +Antsirabe Avaratra +Bidur +Catembe +Nijverdal +Santiago de Chuco +Caballococha +Dainyor +Pinhal Novo +Baxdo +Tall Shihāb +Zaouiet Sousse +Kamonkoli +Kibuku +Sho‘rchi +Araira +Higuerote +Drodro +Dbarwa +Moyalē +Portishead +Pitsea +Tegalbuleud +Ayirūrpāra +Pārner +Lālru +Singhāna +Kalamner +Sojītra +Mādha +Chānasma +Vodurivāndlagūdem +Khiria Jhānsi +Lādol +Kali +Data +Malanvādi +Aş Şaqlāwīyah +Shaqlāwah +Ash Shūnah ash Shamālīyah +Moyale +Simaria +Nossa Senhora das Dores +Tateyama +Calahorra +Mohale’s Hoek +Béthune +Sultepec +Ponta de Pedras +Norton Shores +Kabanga +Sidhaulī +Westhoughton +Tsaratanana +Tapa +Paduvari +Mərdəkan +Sandusky +Gajwel +Baindūr +Plettenberg +Visby +La Esperanza +Sugar Hill +Paete +Springfield +Rio Preto da Eva +Bad Oldesloe +Yuzhang +Niscemi +Traralgon +Cuijk +Portalegre +Marneuli +Ixchiguán +Dalupo +Pinillos +Termini Imerese +Zheleznovodsk +Mundargi +Três de Maio +Koumia +Nainpur +Hunucmá +Elefsína +Morton Grove +Dimasalang +Montalbán +Dugda +Broadstairs +Nogi +Pezinok +Sand +Ixhuatlancillo +Üshtöbe +Westchase +Castelnau-le-Lez +Flores Costa Cuca +Minowa +Quisqueya +Westerlo +Sora +Piracanjuba +Loma Linda +Pedro Carbo +Martinópolis +Quispamsis +Schmallenberg +Sahasoa +Meckenheim +Omurtag +Stein +Iki +Denison +Villa Tapia +Kobo +Wasaga Beach +Wujiaying +Karukurti +Watertown +Pavlovsk +Kirovsk +Kālāvad +Wyandotte +Edavanakad +Ishii +Jabonga +Perrysburg +Solsona +Fort Dodge +Ādīs Zemen +Rangāpāra +Kuna +Madūru +Cherukara +Valambur +Anivorano Avaratra +Liangwu +Sprockhövel +Kérkyra +Rāghopur +Ghoti Budrukh +Santa Rita do Passa Quatro +Sirmatpur +Hamme +Gemerek +Banga +Arnold +Turuttikkara +Carolina Forest +Avon +Aso +Ciudad Barrios +Tamboril +Nazareth +Uherské Hradiště +Collingwood +Syke +Bāsopatti +Piat +Madaoua +General Luna +Riverbank +Derry +Poblacion +Thundersley +Kuttampuzha +West Milford +Świecie +Icatu +Zittau +Khalāri +Baarn +Corralillo +Ouaoula +Voorst +Suchitoto +São Lourenço d’Oeste +Gorleston-on-Sea +Shivganj +Bailey's Crossroads +Ardmore +Salanso +Pamplona +Soledad +Tugaya +Douar Olad. Salem +Nar’yan-Mar +Guaraí +Fontenay-aux-Roses +Zanesville +Pepa +Pweto +Dodola +San Benito +Beifan +Galdácano +San Francisco Zapotitlán +Penistone +Kalayaan +Santana +Jamay +Rudolstadt +Tres Isletas +Ban Khamen +Meiningen +Tuburan +Bintuni +Thornaby on Tees +Frederickson +Villanueva +Scotch Plains +Cambre +Kulachi +Medford +Patian +Taquaritinga do Norte +Owando +Cloverleaf +Bāzārak +Junqueiro +Lutz +Hertford +Zumpango del Río +Brasil Novo +Delfzijl +Bystrc +Moron +Dinuba +Castro Alves +João Lisboa +Algeciras +Ma‘bar +Zhenbeibu +Gouna +Podatūrpeta +Victoria +G’allaorol Shahri +Mairwa +Santa Rosa +North Potomac +Oga +Saltpond +Kakonko +Baroy +Bainbridge Island +Tamilisan +Raška +Hınıs +Jacaré +Pānapur +Kajiado +Narutō +Patnāgarh +Monte Cristi +Stutterheim +Narasingapuram +Shitan +Uauá +Chandili +Miguel Calmon +Kaga Bandoro +Pāsighāt +Ternate +Dix Hills +Naduvannur +Eidsvoll +Larvik +Warstein +Greenbelt +Leoben +Burdeos +Newton in Makerfield +Las Cabras +Pālakodu +Oleshky +Boquim +Shamgarh +Merelbeke +Bielsk Podlaski +Al Qubbah +Bayonet Point +El Milagro +Ban Bang Phun +Santa Maria do Pará +Zwevegem +Ridgeland +Rawson +Navalgund +San Borja +Iaçu +Donggangli +Waldshut-Tiengen +Khashuri +Madougou +Pāta Kalidindi +Rathenow +Coral Terrace +Etajima +Fatoma +Rāmdiri +Oulad Tayeb +Télagh +Auburn Hills +Darende +Condado +Carrascal +Gorantla +Rio Tinto +Irugūr +Selma +Paris +Biharamulo +Reserva +Calamar +Aïn Kechera +Ronnenberg +Zion +Sept-Îles +Panglong +Carlos A. Carrillo +Bad Mergentheim +Païta +Takhli +Isernhagen-Süd +El Retorno +Zernograd +Tuzluca +Karataş +Tapejara +Libourne +Břeclav +Mponela +Guabiruba +Vernon +Stjørdal +Kottapeta +Wierden +Valdivia +Cheruvāranam +Alcobaça +Santo Tomas +Ravānsar +Sirkhandi Bhitha +Clinton +Westford +Markkleeberg +Dungra Chhota +Ain Dfali +Liria +Malinao +Watsa +Chebba +Cordeirópolis +Amatán +Centerville +Homer Glen +Aklvidu +Zdolbuniv +Qualiano +Hulbuk +Bereket +Haren +Andhra Thārhi +Nij Khari +Dongxiaozhai +Tirumuruganpūndi +Parambatt Kavu +Ocara +Waldkraiburg +Tulsīpur +Pindwāra +Ấp Khánh Hòa +Dhāmnagar +Mahdīshahr +Kaynarca +Orly +Riverside +Hanerik +Khajurāho +Traun +Oak Ridge +Leland +Neftekumsk +San Agustín Loxicha +Purwā +Juayúa +Baar +Socastee +Gyál +Sahaspur +Farmington +Cartaxo +Oak Harbor +Sahāwar +Nasukarasuyama +Herndon +Wetzikon +Igaraçu do Tietê +Attendorn +Zungeru +Olesa de Montserrat +Vinnamāla +Būndu +Tamahú +Felixstowe +Ponca City +Qabāţīyah +Arad +Channagiri +’Aïn Boucif +Vilankulo +Zhuangwei +Gaz +Balarāmpur +Garcia Hernandez +Yokadouma +Landover +São Sebastião do Caí +Três Coroas +North Augusta +Żagań +King of Prussia +Decatur +Faribault +Mola di Bari +Armiansk +North Laurel +Erandio +Pedra Azul +Oirase +Bay Point +Ramain +Fray Bentos +Minas Novas +Ashwarāopeta +Herzogenaurach +Tirutturaippūndi +Abim +Varel +Garhara +Panmana +Itambé +Stroitel +Siófok +Medford +Rugeley +Ngorkou +Happy Valley +Le Kremlin-Bicêtre +Kings Norton +Santa Ana +Tbeng Meanchey +Alicia +Eysines +Les Irois +Kazincbarcika +Asan +Buzen +Bacolod +Port St. John +Benbrook +Putten +Valente +Preah Vihear +Kenndié +Hirrīyat Raznah +Pýrgos +Duncan +Birkirkara +Hennenman +Puerto Guzmán +Nagarpāra +Ambohimasina +West Memphis +Taquarituba +Ruvo di Puglia +Asino +Nova Xavantina +Paruthūr +Porto de Mós +Le Bouscat +Saidpur +Grombalia +Sagbayan +Kerrville +Horquetas +Canhotinho +Martos +Las Margaritas +Ballenger Creek +Singarāyakonda +Ladera Ranch +Tadjmout +Buturlinovka +Pallapatti +Iringal +Xinxing +Gose +White Bear Lake +Lucena +Portogruaro +Sarykemer +Ipixuna +La Paz +Bijāwar +Qazi Ahmad +Cedros +Velūr +Echemmaia Est +Cantanhede +Bedburg +Alfreton +Oud-Beijerland +Freudenstadt +Qianwangcun +Koloriāng +Pinheiral +Curacaví +Dakṣiṇkāli̇̄ +Barnegat +Ajim +Collinsville +Staßfurt +Canton +Rădăuţi +Raisio +Oulad Barhil +Kiên Lương +Saint-Laurent-du-Maroni +Saky +Baheri +Almansa +Mahārājgani +Volksrust +Zhuchangba +Elmwood Park +Satuba +Nueva Paz +Starkville +South Plainfield +Borre +Carlow +Katrineholm +Westmont +Wekiwa Springs +Ayanavelikulangara Tekku +Middleborough +Palmetto Bay +Senador Pompeu +Noto +Umga +Zhangshanying +São Geraldo do Araguaia +Gazojak +Saint-Nicolas +Lukaya +Tocopilla +Somerset +Hudson +Mahaiza +Mau +San Juan Nepomuceno +Fairfax +Douar ’Ayn Dfali +El Salto +Valparaíso +Belton +El Factor +Mayāng Imphāl +uMhlanga Rocks +Lebedyn +Carutapera +Mekla +Nova Soure +Ganzhu +Vēttakkāranpudūr +North Lynnwood +Qiaomaichuan +Haaksbergen +Freha +Chester-le-Street +Środa Wielkopolska +Pelham +Jan Kempdorp +El Congo +Calw +Los Barrios +Cabrera +Guatuba +Gotvand +Übach-Palenberg +Farnley +Ambalamanasy II +Great Sankey +Kariba +Debaltseve +Rodez +Canarana +Calliaqua +Ponneri +Soure +Donmatías +Buwenge +Uchquduq Shahri +Boulsa +Gelemso +Aioun +Feriana +Yukon +Marín +Nāravārikuppam +Halikner +Kauswagan +Ortigueira +Quatro Barras +Lagonglong +Fossano +Maksi +Mogalturru +Machachi +Novo Mesto +Magenta +San Enrique +Skawina +Helleland +Forquilha +San Fernando +Golborne +Caibiran +Wałcz +Lop Buri +Les Pavillons-sous-Bois +Ukkāyapalle +Kosigi +Jaruco +Angatuba +Ōguchi +Yoqne‘am ‘Illit +Sehnde +Pingtang +Velingrad +Macia +Liushui +Heiloo +Meyrin +Hingham +Baharly +Rioblanco +Itaporã +Bir Jdid +Zaprešić +Simpsonville +Marsella +Isa +Setti Fatma +Korostyshiv +Salvaterra +Eisenhüttenstadt +Mairena del Alcor +Loha +Tiruvattār +Emporia +Anjozorobe +San Agustin +Marple +Vrbas +Sundararaopeta +Alwaye +Fishkill +Paraopeba +Anastácio +Upper Providence +Saginaw +Ţayyibat al Imām +Bontoc +Wandlitz +Plymstock +Bloomingdale +Espera Feliz +Jaisinghpur +As Sulayyil +Ryde +Qiloane +Areia Branca +Cogua +Monte Sião +Lagoa Grande +Mirandola +Deyr +Montevarchi +Vicente López +Santa María Colotepec +Ormskirk +Wadsworth +Goiás +Semënov +Zaragoza +Sangrāmpur +Skoura +Balete +Quezon +Rolling Meadows +Solon +Boo +Mandan +Senboku +Arttuvāttala +Mina +Tangcun +Rita +Siswa +Sūleswaranpatti +Auburn +Tegina +Guapí +Yanbu +Sakai +Bellview +Columbus +Buritis +Sanando +Jasmine Estates +Saint-Lin--Laurentides +Kourou +Independência +Pontinha +Kościan +Atar +Veranópolis +Laon +Yādiki +Kingston +Papillion +Tehri +Soamanandrariny +Ambatotsipihina +Jequitinhonha +Bcharré +Ambohimandroso +Lopary +Antonibe +Antanimieva +Miarinarivo +Tsiatosika +Itigi +Butaleja +Chinobod +Jalolquduq +Sheghnān +Tchibanga +Maheshwar +Payipira +Caazapá +Quellón +Uvarovo +Zolochiv +Sikandarpur +Jardim +Cachoeira do Arari +Cavinti +Pennādam +San Pedro +Sharya +Huilongping +Barnstaple +Burlington +Laranjeiras +Plainsboro +General Emilio Aguinaldo +Rickmansworth +Kamiamakusa +Icod de los Vinos +Dabaga +Kyonpyaw +Embarcación +Shāhpur +Laguna Salada +São Gonçalo do Sapucaí +Bom Jesus +Littleover +San Fernando +Santa Quitéria do Maranhão +Newport +Wil +La Valette-du-Var +Goirle +Neduvattūr +Ambohimahamasina +Urucurituba +Itaporanga +Jüchen +Arbroath +Tsawwassen +Bulusan +São João da Ponte +Belo Oriente +Sighişoara +Mapoteng +Solin +Wijk bij Duurstede +Rodniki +Puyappalli +Jucás +El Zulia +Douar Bou Tlelis +Ibi +Koulikoro +Manlio Fabio Altamirano +Umbaúba +Irauçuba +Usia +Sendamangalam +Hatonuevo +Kraskovo +São João do Paraíso +Buritizeiro +Pompei +San Nicolas +Alfter +Zwedru +Porto Franco +Fălticeni +Tacaratu +Paxtakor Shahri +Brotas +Mejorada del Campo +Columbus +Tantoyuca +Tecoluca +Gungu +Hadžići +Mātābhānga +Mulgund +Cibitoke +Caversham +Freeport +Vänersborg +Seveso +Tata +Nóqui +Macaparana +Iraquara +Burlington +Peringuzha +Karian +Strathroy-Caradoc +Subaykhān +Acton +Buôn Trấp +Koilkuntla +Matriz de Camarajibe +Dunleary +Johnston +Ourikela +Westerstede +Lihe +Magallanes +Herohalli +Mirandela +Oadby +Hopa +Rosemont +Jurh +Carás +Az Zuwāydah +Ksar el Hirane +South Elgin +Webster Groves +Cranford +Chanthaburi +Mulakumūd +Palu +Limbach-Oberfrohna +Cruzeiro do Oeste +Mansfield +Honda +Annūr +Makhmūr +San Miguel Ocotenco +Ciudad Serdán +Diest +Atotonilco el Grande +Pão de Açúcar +Willoughby +Quesada +Kasongo-Lunda +Altea +Popovo +Encruzilhada do Sul +Squamish +Douar Ouled Ayad +Novo Aripuanã +Thorold +Firuzoba +Kalawit +Carandaí +Kuju +Buy +Dongsheng +Frontignan +Hungund +Kumar Khad +Catigbian +Hodonín +Zawyat an Nwaçer +Montgeron +Sulya +Misato +Bithar +Farragut +Thiene +Highland +Grootfontein +Selydove +El Maknassi +Fada +Gaojiayingcun +Ituango +Dākor +Vallabh Vidyanagar +Stepanavan +El Tejar +Agrestina +Tirumala +Villanueva +Hoh Ereg +Vélingara +Dole +Ishiki +Baliguian +Akwatia +Basankusu +Kuvandyk +Manari +Döbeln +Verukulambu +De Aar +Oldebroek +Kidsgrove +Cullera +Candoni +Santa Apolonia +Burgos +Limbuhan +Hachimantai +Starnberg +Elukone +East Retford +Lālgudi +Fountain Hills +Avanigadda +Vizela +Bīrpur +Nocera Superiore +Husum +Huntingdon +Mummidivaram +Stalybridge +Ōji +Munster +Tatarsk +Fria +Pout +Alice Springs +San Giovanni la Punta +Kościerzyna +Waverly +Lebu +Ayancık +Nørresundby +Puduva +Aurora +Dasungezhuang +Devikolam +Karavalūr +Khenichet-sur Ouerrha +Rishton +Korbach +Tangalan +Salqīn +Chinoz +Stanmore +Nesher +Shama +Sezze +Ayt Mohamed +Southold +Miantso +Maldegem +Droylsden +Marple +San Juan Cotzocón +Gelnhausen +Sīlappādi +Patterson +Tirukkalikkunram +Anūpshahr +Shelbyville +Cazones de Herrera +Sanaur +Santo Antônio do Sudoeste +Muscatine +Dalyoni Bolo +Greenfield +Borne +San Lorenzo +Champlin +Lexington +Orleães +Conil de la Frontera +Lubliniec +Bonito +Independencia +Ālangulam +Yellāpur +Roseburg +Perry Barr +Conde +Piraí do Sul +Raritan +Rajpur +Dunaharaszti +Ahualulco de Mercado +Bang Sao Thong +Chandrakona +Bafilo +Tecali +Pitogo +Taupo +Bogotol +Beni Amrane +Berhoum +Gosforth +Mannamturuttu +Satun +Santa Gertrudes +Kenmore +Fresno +Yesagyo +Gueznaia +Kalach-na-Donu +Mountain House +Aşkale +Tapiales +Ōgawara +Kulgam +Shamsābād +Jacksonville Beach +Truro +Kyeintali +Kébila +Oostkamp +Newton Abbot +Ipatovo +Lustenau +Perungudi +Ðakovo +San Martín Totolán +Cerro Azul +Middletown +Kottūru +Amstetten +San Ignacio de Velasco +Tayga +Monsefú +Tamandaré +Toda Rai Singh +Pēravūr +Montgomery +Bauta +Castiglione delle Stiviere +Heverlee +Gollapūdi +Dhing +Unecha +Ma‘alot Tarshīḥā +Codajás +Luninyets +Belsand +Gerede +Bambuí +Salzwedel +Bishopbriggs +Kaltenkirchen +São Miguel +Khelil +Nyūzen +Xiaojiangcun +Xiaping +El Paso +Jaleshwar +Corinto +Yangi Marg‘ilon +Hannoversch Münden +Brookings +Dumaran +Honāvar +General Pánfilo Natera +Amherstburg +Nixa +Funes +Canalete +Ban Phru +Cupira +Aţ Ţafīlah +Watauga +Marshall +Sonneberg +Loon op Zand +Kaniv +Mujuí dos Campos +Muang Sing +Quaraí +Arukutti +Miyoshi +Davlekanovo +Suonan +Nāyanakulam +Lisle +Ringsted +Pakil +Port Laoise +Jocotenango +Cuyo +Padre Burgos +Gardner +Český Těšín +Farmington +Griffin +Mosbach +Matinha +Dillenburg +Oued el Djemaa +Koili Simra +Yugawara +Lensk +Carmo do Cajuru +Bloemendaal +Chanaur +Gauripur +Francisco Sá +Oulad Hassoune +Hajdúszoboszló +Khārupatia +Maple Heights +Maharlika Village +Monte Caseros +Krychaw +Les Lilas +Kyenjojo +Bonoufla +Ḑank +Tapaktuan +Muggiò +Sanga +Brody +Sinj +Beni Rached +Madangir +Kėdainiai +Minamikarasuyama +Chrudim +Copiague +L’Assomption +Rāmpura +Gjirokastër +Nasu +Bni Frassen +Elburg +Pilar de la Horadada +Kilindoni +Badnāwar +Raul Soares +Pissila +Maychew +Sattahip +Kailāshahar +Vega Baja +Pesochin +San Buenaventura +Zheleznogorsk-Ilimskiy +Srvanampatti +Santa Rosa de Viterbo +Teguise +Veinticinco de Mayo +Senftenberg +Al ‘Azīzīyah +Bình Hòa +Havlíčkŭv Brod +Van Buren +Burhar +Gālīkesh +Ban Thoet Thai +Svilajnac +Kafr Shukr +Clinton +Makouda +Meda +Sluis +Maywood +Bedford +Teorama +Ponda +Almeirim +Albenga +West Springfield +Akkuş +Giulianova +Vanimēl +Gamay +Bultfontein +Severobaykalsk +Netphen +Caniço +Rock Springs +Barbasa +Beni Khalled +Quảng Trị +Pottstown +Sredneuralsk +Dighwa +Sakleshpur +Montecchio Maggiore +Piteå +Takehara +Sāndwa +Çağlayancerit +Pindoretama +Leutkirch im Allgäu +Avellaneda +Tazhava +Madappalli +Sokolo +Maigo +Westerly +Piravanthūr +Saint-Ghislain +Mandāwa +Antanimasaka +Coronel Vivida +Cide +Čadca +Dongshi +Berehove +Zemst +Doctor Mora +Warburg +Collipulli +Ambohimiadana +Horgen +Minja +Sai Mai +Dalmine +Pelitli +Capinzal +Quedlinburg +Jieshang +Ron +Calbiga +Ikeda +North Platte +Bazhajiemicun +Phôngsali +Moskva +Tecumseh +Santo Tomé +Tugatog +Tobatí +Ardahan +Lormont +Bordj Ghdir +Niskayuna +Añatuya +Goumori +Aldeias Altas +La Cruz de Río Grande +Poxoréo +Carambeí +San Rafael Abajo +Whitefield +Kedavūr +Achkhoy-Martan +Piastów +Alhama de Murcia +San José +Rathfarnham +Monteros +Gersthofen +Teodoro Sampaio +Mūlampilli +Camp Springs +Telica +Abaeté +Linda +Cajidiocan +Tekāri +Martha Lake +La Higuerita +La Huerta +Maibog +Alliston +Tsaratanana +Ulukışla +Píritu +Cockeysville +Ozuluama de Mascareñas +Santo Antônio de Posse +Motul +Mine +Phetchaburi +Xunjiansi +Vaikam +Mantua +Cottage Lake +Raymore +Selim +Kūn Puhāl +Pickerington +Calamba +Loanda +Nuku‘alofa +Samrāla +Sasovo +Mizdah +Culion +Kedia +Sheybān +Nakashunbetsu +Cambará +Kolpashevo +Fergus +Kelīshād va Sūdarjān +Pātakākāni +Amarapura +Sevan +Manambūr +Touboro +Wertheim +Montgomery +Wareham +Tranquebar +Wilmington +Kazhukambalam +Capoterra +Itabaiana +Bassar +Rastede +‘Ālī Shahr +Nova Petrópolis +Vilaseca de Solcina +Vukovar +Ponmundam +Kannamangalam Tekku +Union Hill-Novelty Hill +Eastmont +Carmen +Karben +Tototlán +Colón +Pajapita +Kouoro +Gitega +Tūkrah +Ashland +Conceição do Mato Dentro +Bad Soden am Taunus +Vreden +Apatin +Minamata +Puenteareas +Zarautz +Sonepur +Colón +Ribas do Rio Pardo +Ban Bang Rin +Abreus +Białogard +Ravulapalem +New Brighton +Edgewater +Belton +Planalto +Easley +Shuilin +Bananeiras +Douar Imoukkane +Puerto Concordia +Soledad Atzompa +Elgin +Neihuzhai +Trotwood +Litoměřice +Lalganj +São Mamede de Infesta +Manage +Mahthi +Tamiahua +Oakdale +Caba +West Goshen +Ottaviano +Yásica Arriba +Rafael Delgado +Liberty Triangle +Los Arabos +Ōno +Sansanding +Singhāra Buzurg +Fânzeres +Chantilly +Calabasas +Vuliyattara +Cartersville +Sonāri +Engandiyūr +Eustis +Roxbury +Tupiza +Qiryat Mal’akhi +Hombori +Überlingen +Oxkutzkab +Morris +Yunak +Rochefort +Sederot +Mujiayu +Gusinoozërsk +Khirkiyān +Rucphen +Sīwah +Maisons-Laffitte +Fokino +Vilāchcheri +Qiryat Shemona +Tnine Lgharbia +Apolda +Vigonza +Bear +Saint-Dizier +Chester +Pallikondai +Yakınca +Roissy-en-Brie +Orbassano +Cataño +Asafābād +Couëron +Weilheim +Dom Pedro +Nagykőrös +Lunbei +Warragul +Achí +Bloomington +Koussané +Velugodu +Penwortham +Youwarou +Devonport +Hopewell +Dunajská Streda +Auch +Thiotte +Buyende +Upper Allen +Bad Kissingen +Koiri Bigha +Fernley +Mangidy +Copertino +Monte Alegre +Bataguaçu +Anjarkandi +Oliveira do Bairro +San Andrés de Giles +Nova Milanese +Lanester +Frontera +Shiling +Tembagapura +Lysander +Tubungan +Curumaní +Kulattuppālaiyam +Ladner +Nový Jičín +Glassboro +Bad Salzungen +Loos +Khairā Tolā +Ban Bang Krang +Hudson +Taylors +Harborne +Ka-Bungeni +Carletonville +Majdel Aanjar +Ambohitrarivo +Mahela +Farahalana +Analamisampy +Ambohitoaka +Miantsoarivo +Ankaramy +Marovato +Ankilizato +Andalatanosy +Kungsbacka +Xingang +Gyêgu +Zhaoling +Rawtenstall +Dindori +Candiac +Krasnouralsk +Valencia +Despotovac +Wichian Buri +Krasnoarmeysk +Stoneham +Panelas +Wallenhorst +Niamtougou +Manlin +Nagold +Ivoti +Mobetsu +Lisse +Radcliff +Lengerich +Vandiperiyār +Watertown +Lagoa +Yaguachi Nuevo +Tighedouine +Malinalco +Labuleng +Essa +Brent +Latauna +Woodlawn +Sandviken +Manuel B. Gonnet +Minbu +Encantado +Frederikshavn +Searcy +Nikaho +Paradise +Moguer +Dabeiba +Crystal +Las Breñas +Scherpenheuvel +Elektrogorsk +Nocatee +Kamabougou +Manghit +Christiansburg +Friesoythe +Kitzingen +Muttupet +Mékhé +Hollola +Abu +Laguna Beach +Molodohvardiisk +Znamianka +Nijlen +Clifton +Huaibaijie +Loves Park +Blue Island +Swinton +Peters +Manosque +Famaillá +Prairie Village +Bathgate +Itaocara +Biancavilla +Pul-e ‘Alam +Kilkís +Dáfni +Market Harborough +Nyakrom +Wulongpu +Edewecht +Dialakoroba +Dokuchaievsk +Keene +Zduńska Wola +Bhirāha +Isilkul +Shurugwi +Kotido +Vadakarai Kīl Pidāgai +Ayos +El Palmar +Colorado +Senden +Dorohoi +Lermontov +Fontaine +Trebišov +Losser +Vellalūr +Pointe à Raquettes +Ogre +La Democracia +Garoua Boulaï +Zeewolde +Ramos +Kalat +Luruaco +Marcinelle +Rivera +Mahādebnagar +Ekeren +Neusäß +Garden City +Pietrasanta +Viga +Baile Átha Luain +Guadalupe +Bhadās +Genzano di Roma +Vale de Cambra +Laupheim +Araçariguama +Nazca +Allen +Waltham Abbey +Malacatancito +Patacamaya +Oteiza +Olivet +General Luna +Azové +Vagos +Hadyach +Sarandi +Ventimiglia +Blangmangat +Krnov +Arcos de Valdevez +Roselle +Villanueva de la Cañada +Dammarie-lè-Lys +Gainsborough +Machesney Park +Guanajay +Nayāgaon +Tadmaït +Chitarpur +Naolinco de Victoria +Ecoporanga +Selvazzano Dentro +Qaţanā +Xinsi +Ahwa +Erdington +Katy +Millbrae +Nogoyá +Ondangwa +Pawni +Torre del Mar +Ataco +Bressanone +Gaoshu +Hialeah Gardens +Kagadi +Balen +Tadotsu +Siqueira Campos +Yanshanbu +Barbate de Franco +Camilo Ponce Enríquez +Cheriāl +Zunheboto +Winchester +Tomarza +Pulimāthu +Corcoran +Beek en Donk +Fangliao +Beshariq +Haywards Heath +Nāḩiyat al Kifl +Pitogo +Kapfenberg +Brambleton +Pedra +Frascati +Cinco Saltos +Pecan Grove +Aybastı +Achhnera +Lumbatan +Bormujos +Gormi +Velsk +Cartago +Sun Valley +Butig +Kungälv +San José Ojetenam +Amoucha +Pariyāpuram +Kavallemmāvu +Kodarmā +Kaler +Onondaga +Baravāt +Saint-Lambert +Kumano +Duncan +Herdecke +Linstead +Kanchika +Nasrullāhganj +Morrinhos +Villa Park +Vernāg +San Felíu de Guixols +San Miguel de Papasquiaro +Ivato +Quartier Militaire +Ojinaga +Gobō +Vayanūr +Melíssia +Ashtown +Keta +Seva +Cartagena +Junction City +Kalachinsk +Boura +Kulkent +Chunakara Vadakku +Curchorem +Ayagawa +Rāvar +Arroyito +Kerūr +Garmdarreh +Alnif +Idak +Rosita +Asaita +Watertown +Byala Slatina +Madira +Volendam +Sidi Lmokhtar +Zeya +Amalfi +Kittanapalli +Murādpur +Hazel Dell +Vélizy-Villacoublay +Ambriz +Feira Grande +Nakūr +Buenavista +Bulle +Anthem +The Crossings +Candler-McAfee +Kluczbork +Kapolei +Allison Park +Jarqo‘rg‘on +Saint-Louis +Athens +Litvínov +North Plainfield +Goldasht +Inhapim +Burg +Dalān +Shaomi +Candelaria de La Frontera +Patharia +Beixingzhuang +Andoany +Mallasamudram +Tequixquiac +Tassin-la-Demi-Lune +Lucala +Moirāng +Dip +Oytal +Laguna de Duero +Kitajima +Mullingar +Khaw Zar Chaung Wa +Dover +Moncagua +Llaillay +Cudahy +Nanyangcun +East San Gabriel +Lefkáda +Bagulā +Tashtagol +Wednesfield +La Trinidad +Prieto Diaz +Stadthagen +Pullappalli +Okahandja +Røyken +Zedelgem +Olindina +Areia +Beşikdüzü +Valašské Meziříčí +Chincholi +Fucecchio +Manimala +Morombe +Olteniţa +Manzanares +Barakī Barak +Büdingen +Sèvres +Andorra la Vella +Tocantinópolis +Santa Fe de Antioquia +Timmāpur +Fairhope +Montigny-lès-Cormeilles +Lajas +Savanna-la-Mar +Hirpardangal +Manki +Abbeville +Fleurus +Farsley +Parabcan +Bouzeghaia +Bonney Lake +Warrenton +Yahualica de González Gallo +Valmiera +Furukawa +Dawmat al Jandal +Sardinata +Strakonice +Şirvan +Camacan +Cholavandān +Senador José Porfírio +Oshwe +Boriziny +Los Llanos +El Amria +Talayolaparambu +Bronnitsy +Uenohara +Isperih +Haar +Summit +Souk Tlet El Gharb +Bélabo +Rāman Mandi +East Peoria +Pokhuria +Letterkenny +Sinjār +Florida Ridge +Tlacolula de Matamoros +Mentana +Vengattūr +Kenilworth +Horizon City +Lempäälä +Potters Bar +Kafr Baţnā +Medjez el Bab +Melila +Metzingen +Bobleshwar +Greenwood +Zaragoza +Meiwa +Huautla +Katangi +Gölhisar +Sarangani +Sabana de Torres +Jogipet +Melchor Romero +Hulikal +Deuil-la-Barre +Kotelnich +Mutatá +Cherry Hill +Nadvirna +Corinth +Bafatá +Ouani +Kafr Sa‘d +Roselle +Vilcún +Zabrat +Klatovy +Coração de Maria +Challans +Coralville +San Antonio La Paz +Willowbrook +San Pablo Jocopilas +Lazi +La Madeleine +Ivatsevichy +Nkowakowa +Sucre +Chavasshēri +Foleshill +Mount Pearl Park +Staraya Kupavna +Lincoln +Piddig +Yuli +Chatayamangalam +San Juan de Aznalfarache +Emiliano Zapata +Mouila +Khadyzhensk +Kondāzhi +Karnobat +Caculé +Baclayon +Ladyzhyn +Buriti Bravo +Puente Nacional +Gan Yavne +Pullanpallikonam +Naawan +Torcy +Esparraguera +Mihama +Vernon +Biddeford +Aymangala +Bloomingdale +Moyo +Albertville +Pirajuí +Donaueschingen +Naciria +Ottobrunn +Rancho San Diego +Finnkolo +Sarea Khās +Junnārdev +Bristol +Goulburn +Sibut +Formby +Fenyuan +Sipilou +Maying +Kasamatsuchō +Jebba +Betsizaraina +La Porte +Pudsey +Rixensart +Kiboga +Zhengtun +Zurbāţīyah +Gujan-Mestras +Macas +Bermo +Quissamã +Barreira +Freire +Szczytno +Taishituncun +Sevlievo +Gonghe +Hartbeespoort +Káto Polemídia +Mechta Ouled Oulha +Lindsay +Ibatiba +Perundurai +Montville +Arouca +Central Falls +Rumphi +Ivrea +Bad Rappenau +Saint-Lazare +Arbi’a Tighadwiyn +Diriomo +Gif-sur-Yvette +Sek’ot’a +Sabunçu +Cedro +Waynesboro +Loei +Gurmatkāl +Mendeleyevsk +Carouge +Lyndhurst +Gīlān-e Gharb +Kadiria +Sāmbhar +El Tortuguero +Guérou +Taulahā +Natagaima +Bhawānīgarh +Ceccano +Acworth +Owen Sound +Zvenigorod +Lyman +Scarborough +Frauenfeld +Chinameca +Daxin +DeBary +Panniyannūr +El Doncello +Prāntij +Yuli +Gornji Vakuf +Evesham +Guía de Isora +Bundibugyo +Qorako‘l Shahri +Lochristi +Piúma +Phichit +Montilla +March +Roşiori de Vede +Požega +Magallanes +Brockville +Tiverton +Braine-le-Comte +Laja +Nikolskoye +Cayo Mambí +Sanso +Digor +Pale +Ruston +Brushy Creek +Bartoszyce +Valença do Piauí +Monte Aprazível +Cisnădie +Had Sahary +Oyonnax +Zhucaoying +Maracena +Shoeburyness +Versmold +Chankou +Yokoshibahikari +Lordelo do Ouro +Acatlán +Palaw +Ugong +Palmer +Tiruttangal +Senekane +Hillside +Telšiai +Edegem +Aljaraque +Montereau-faut-Yonne +Mountain Brook +Nagla +Ankireddikuntapālem +Bhatpurī +Chausa +Marina +Singampunari +Itsukaichi +El Hermel +Karaçoban +Athiringal +Tervuren +El Colegio +Kihei +Silvânia +Souahlia +Alangāyam +Bahçe +Litherland +Takahata +Koziatyn +Kheïredine +Combs-la-Ville +West Carson +Bignona +Picasent +Huangzhai +Yeadon +Silver Firs +Ibiá +Yahualica +Kundgol +São Filipe +Sokolov +Hérouville-Saint-Clair +Eppingen +Ingabu +Metekora +Radevormwald +Murayama +Shārūnah +Świebodzice +Saint John’s +Dasnāpur +Poggiomarino +Acomb +Abū Şīr Banā +Khorabar +Bahía de Caráquez +Ortona +Topola +Tiruverumbūr +Ilsede +Zirāpur +Sunny Isles Beach +Samtredia +Tirat Karmel +West Deptford +Hillegom +Rioja +Guazacapán +Soroca +Repelón +Medeiros Neto +Simaria +Adalhāt +Yavuzeli +Chalmette +’s-Gravenzande +Surdulica +Sandomierz +McNair +Kondalāmpatti +Phularwan +Pattiyūrgrāmam +Las Torres de Cotillas +Haderslev +Gubbi +Shabestar +Granite Bay +Gümüşhacıköy +Kilkenny +Bakhri +Maribojoc +Santo Antônio +Yabu +Nova Zagora +Sulmona +Guabo +Qarazhal +Flores +Goleniów +Mbaïki +Jiangdi +Chestermere +Les Pennes-Mirabeau +Salvaterra de Magos +Batad +Vellithiruthi +Paraguarí +Takelsa +Ghriss +Sarapāka +Aleksandrów Łódzki +Sant’Arcangelo di Romagna +Ensley +Bavly +Vayalār +Katkol +Bhānvad +Golden Valley +West Rancho Dominguez +Ban Pa Tueng +World Golf Village +Salcedo +Guryevsk +Pīrmed +Waldkirch +Reigate +Lower +Phetchabun +Pingtan +Kingsville +Bourkika +Ramona +Fantino +Bellavista +Sahil +Tabursuq +Talwandi Sābo +Heide +Livadeiá +Salémata +Krolevets +Qapqal +Cunha +Santa Fe +Arroyito +Namayumba +Caojiachuan +Doutou +La Cruz +Madhupur +San Agustin +Essex +Palmital +Evans +Hallim +Clarksville +Smithfield +Árgos +Perāvūrani +Huejúcar +Pailitas +Penarth +Howli +Montclair +Ocatlán +Muelle de los Bueyes +Husnābād +Hoogezand +São José do Rio Preto +Vilnohirsk +Taixi +Timbiquí +Horley +Newquay +Camborne +West Puente Valley +Kālchīni +Estcourt +Eschborn +Karlsfeld +Moncada +Yorosso +Qifţ +Palestrina +Hastings +Schwetzingen +Nevyansk +Imbert +Parsāgarhi +Ḩamīdīyeh +Kommunar +Gardelegen +Ādampur +Chhanera +Itaiópolis +Oxford +Madamba +Lorton +Rimavská Sobota +Polýgyros +Kalýves Polygýrou +Northwood +Honmachi +San Martín +Ceres +Aswāpuram +Khandela +Karaisalı +Tiquisio +Dongta +Mondovì +East Ridge +Carbondale +Ruwa +Jizhuang +Semikarakorsk +Sapulpa +Banbishancun +Woensdrecht +Jāwad +Naregal +Dubnica nad Váhom +Elsdorf +Corail +Silvania +Oxford +Dioumanzana +Anini-y +Taveta +Comacchio +Meixedo +Ostrów Mazowiecka +Tola +Greystones +Uliastay +Paese +Priego de Córdoba +Chillicothe +Épernay +Jugiāl +Ghāt +Manakambahiny +Ambodimotso Atsimo +Ampasimanjeva +Iarintsena +Andranovorivato +Bemanonga +Vohimasina +Andilanatoby +Alakamisy-Ambohimaha +Ambalaroka +Jafaro +Ankiabe-Salohy +Antsakabary +Uch Sharif +Lebane +Huskvarna +Kigumba +Hacı Zeynalabdin +Aoshang +Atherton +Clevedon +Bukkarāyasamudram +Machagai +Unchahra +Göd +Kotovo +Zundert +Drās +Gavimané +Sanford +Taminango +Bilthoven +Al Bāḩah +Pitrufquén +Néma +Vilyuchinsk +Pinhalzinho +Khosrowshahr +Ampanotokana +Vereshchagino +Iracemápolis +San Rafael del Yuma +Djinet +Robbah +Arroio do Meio +Kuppam +Koekelberg +Vertentes +Koksijde +San Jose +Dudelange +Villa de Leyva +Darien +Sêrro +Valinda +Glauchau +Chākia +Pochāram +Diamantino +Mundamāla +New Hartford +Rāmantali +Ḩārim +Ấp Phú Mỹ +Robertson +Svetlyy +Tornio +Nakagusuku +Samba Cango +Mazagão +Chambersburg +Sandbach +Chalchihuitán +Axapusco +Ituberá +Nerja +Makó +Gōtsuchō +St. Andrews +Aichach +Al Fuḩayş +Krathum Baen +Pascagoula +Pak Tin Pa +Shiroishi +Bungotakada +Membakut +São Miguel do Araguaia +Sayada +Kāchhāri +Darreh Shahr +Árta +Béguédo +São Francisco de Paula +Lom +Muzambinho +Vanthli +Kueneng +Póvoa de Lanhoso +Pio XII +Caranavi +Alfafar +Frameries +North Salt Lake +Casablanca +Almoradí +Shinhidaka +Montmorency +Maghalleen +Karlovo +Hillsborough +Middleton +New Castle +Sonthofen +Sainte-Foy-lès-Lyon +Nogales +Montigny-lès-Metz +Renfrew +Komló +Flörsheim +Gigaquit +Binnish +Tongzhou +Kafr Qāsim +Port Hueneme +Rajauli +Massapequa +Mata Grande +Lihuzhuang +Mbandjok +Māngrol +Ōtsuki +Koçarlı +Los Palmitos +Muhlenberg +Machico +Mount Pleasant +Kepsut +Mangalvedha +Yoshioka +Santa Teresa +Danwān +Puttige +Belper +Soyāgaon +Columbia Heights +Hayesville +Horad Smalyavichy +Kizhakkemanād +Ginosa +Sheldon +Mehnatobod +De Meern +Ginebra +Azambuja +Ouardenine +Ma’mūnīyeh +Pallippuram +Amtali +Orobó +Soltau +Pueblo Juárez +Amposta +Muzhakkunnu +Parsippany +Klamath Falls +Kreuzlingen +Płońsk +Looc +Manor +Falmouth +Palmas de Monte Alto +Poço Verde +Siilinjärvi +Santa Lucía Utatlán +Yate +Morinda +Polkowice +Charo +Aḑ Ḑabyah +Aḑ Ḑāli‘ +Avon +Le Petit-Quevilly +Jaynagar +Magdalena +Puruk Cahu +Tūnēri +Had Oulad Issa +Ambatomanoina +Hassi Maameche +Langley Park +Silverdale +Sidi Amrane +Surpur +Bhānpura +Gülşehir +Geertruidenberg +El Callao +Chatra Gobraura +Kayanza +Sedalia +Maniche +Mailavaram +Lakeside +Selden +Seia +South Euclid +Zara +Otopeni +Nøtterøy +Penonomé +Bato +Oberwingert +Shendurjana +Cagwait +Sarai Ranjan +Chapa de Mota +Puerto Triunfo +Eislingen +Hockenheim +Bānapur +Zoersel +Guipos +Bad Harzburg +Birmingham +Chimoré +Anamalais +Shanywathit +Sori +Kurikka +Kalleribhāgam +Massarosa +Vāmanapuram +Miguelópolis +Comalapa +Zabré +Mezdra +Yaojiazhuangcun +Yaojiafen +Erval d’Oeste +Idukki +Tixtla de Guerrero +Vendram +Moularès +Wädenswil +Bankoumana +Caransebeş +Pachino +São João da Madeira +Alhandra +Millau +Shelby +Guapiaçu +Port Alberni +Kozakai-chō +Pampierstad +Tidili Masfiywat +Chāgallu +Sombrerete +Springwater +Eyl +Saint-Jean-de-Braye +Biggleswade +Yucca Valley +Chaumont +Millburn +Assaré +Mühldorf +Paramirim +Kavak +Qādirganj +Brunswick +Duarte +Geseke +Bad Krozingen +Kadiapattanam +Can-Avid +Del City +Pāmpur +Al Karak +Sirat +Ocotlán de Morelos +Tigbao +San Luis Talpa +Gallup +Kangal +Kopřivnice +American Canyon +Senda +Zantiébougou +Kami +Ibicaraí +Lindlar +Bailleston +Gros Islet +Nangavaram +Kobilo +Gökçebey +Nefta +Himora +Pāpanāsam +Lohutí +Jaipur Chuhar +Anūppur +Kānke +Sarzana +Lentini +Ayamonte +San Jacinto +Rāja Pākar +Tiruvankod +Ōkuchi-shinohara +Riachão das Neves +Kumla +Howick +Iisalmi +Tlaltenango de Sánchez Román +São Miguel do Guaporé +Mercato San Severino +Herent +Orzesze +Villeneuve-sur-Lot +Pushkar +Yenice +Zărneşti +San Justo +Mashiko +New Hope +Novopokrovka +Sidi Ifni +Fukagawa +Sainte-Suzanne +Scugog +Bela Vista +Jiuru +Nueva Granada +Nerupperichchal +Lakato +Amarpātan +Savigliano +Xinzhai +Paraguaçu +Vicente Noble +Tamgrout +Isla-Cristina +Alliance +San Fernando +G‘azalkent +Ashtarak +Cuilapan de Guerrero +Chapala +Senaki +Seynod +M’Chedallah +Łaziska Górne +Rosario de Lerma +Alcalá la Real +Unity +Bougado +Qal’acha +Spremberg +Ibirubá +Martí +Xanten +MacArthur +Salcajá +Chilca +Mandapam +Pergine Valsugana +Selouane +Tukwila +Elverum +Seligenstadt +Pākāla +San Nicolás +Mandelieu-la-Napoule +Rancheria Payau +Santa Teresita +Arcueil +Uxbridge +Truro +Kalpakathukonam +Stadtallendorf +Fulshear +Rocky River +Beni Douala +Colle di Val d’Elsa +Pancas +Galeras +Mililani Mauka +Cabucgayan +Ashland +Nāranammālpuram +Kontéla +Güimar +Corciano +Stowmarket +Acatic +Naqādah +Thebes +Payson +Nong Bua Lamphu +Lino Lakes +Wexford +Sermādevi +Ladário +Zerbst +Deán Funes +Cardito +San Martín de las Pirámides +Caombo +Goroka +Villagarzón +Eckernförde +Áno Sýros +Chebli +Bastos +Aarau +Alnāvar +Whyalla +Celina +Parelhas +Hazebrouck +Boquira +North Guwāhāti +Muthutala +Tanki Leendert +Alta Floresta D’Oeste +Holiday +Jawor +Nang Rong +San Bernardo +Allauch +Artémida +Günzburg +Harvey +Chesham +Puerto Natales +Rees +Dickinson +Trezzano sul Naviglio +Takaba +Pandan +Aspe +Kodikuthi +Secaucus +Richmond +Mons-en-Baroeul +Ambohitromby +Hojambaz +Gökdepe +Fort St. John +Madakasīra +Juli +Kotli +El Paujíl +Llorente +Ozark +Sihu +Loncoche +Ryazhsk +Beni Mered +Ganapavaram +Laventille +Paramonga +Senador Guiomard +Palatka +Qalansuwa +East Patchogue +Tarko-Sale +Riehen +Tong’anyi +Paravai +Pendurti +Rio Rico +Osterode +Bariārpur +Amizmiz +Waghäusel +Bogandé +Nhamundá +Volnovakha +Ust’-Katav +Partizánske +Thenia +Fleury-les-Aubrais +Saint-Michel-sur-Orge +Jēkabpils +Chandlers Ford +Tambaú +Āndippatti +Eğil +Mārutūru +Icapuí +Zossen +Omutninsk +Panagyurishte +Trinidad +Shāhbāzpur +Wilmot +Hoogstraten +Noāmundi +Merefa +São João do Piauí +Uruçuca +Ghanzi +Puchheim +Four Square Mile +San Bonifacio +Kutná Hora +Tauragė +Lioua +Grand Island +Neuilly-Plaisance +Péfki +Santa Rosa de Lima +Santa Bárbara +Srīvaikuntam +Jandaia do Sul +Alejandro Korn +Ashland +Bayi +Kant +Świedbodzin +Cumaral +Grajewo +Pāmarru +Shirhatti +Naas +Annecy-le-Vieux +Geneva +Inopacan +Khowai +Mohiuddīnnagar +Perdões +Afourar +Los Vilos +Nogent-sur-Oise +Singur +Kirkintilloch +Gummudipūndi +Nedre Eiker +Allende +Masis +Mantes-la-Ville +Teteven +Almaguer +Palma di Montechiaro +Pleasant Prairie +Seymour +Igreja Nova +Senago +Fortín de las Flores +Achères +Bilohorodka +Mukilteo +Ambinanindrano +Fukuyoshi +Westborough +Iguaí +Stange +Bornem +Silva Jardim +Vecsés +Hafshejān +Galūgāh +Zambrów +Tiruppuvanam +Mountlake Terrace +Khotkovo +Mī’ēso +Metahāra +Mundgod +Dax +South Lake Tahoe +Hammanskraal +Darton +Kasumpti +Chernogolovka +Padmanābhapuram +Doaba +Pāmbādi +Lindenwold +Vicksburg +Moorestown +San Antonio de Areco +Somers +Ulus +Antilla +Terrier Rouge +Oum Drou +Mrągowo +Srīperumbūdūr +Sukhodilsk +Youganning +Yegainnyin +Alcudia +Lyskovo +Mīt Namā +Winter Gardens +Sondershausen +Kelkit +Tubbergen +Naryn +Armidale +São João +Aralık +Aiud +Nirmāli +Narippatta +Wang Nam Yen +Makulubita +Artashat +Akonolinga +Casal di Principe +Luna +Kaduturutti +Huy +Kaikalūr +Cacém +Chāgalamarri +Krus na Ligas +South Holland +Sulphur +Sevilimedu +Royton +Dolton +Clemmons +Mansourah +Perry +Kitcharao +Carthage +Gauting +Mabitac +Belovodskoe +Yorkville +Pájara +Wieluń +Linamon +Aguilares +Baldwin +Mossaka +Nowa Ruda +Agropoli +Vialonga +Almasi +Dronfield +Elmwood Park +Oshoba +Iruttarakonam +Rolante +Traunstein +Nāmagiripettai +Sulejówek +West Pensacola +Tapalpa +Asni +Koduvilārpatti +Carrboro +Ntcheu +Monroe +Sanxing +Suwanee +Aguadas +Manuel Tames +Lealman +Bhairi̇̄ +Ossett +Montecristo +Urk +Narkher +Degollado +Tādikombu +Fierenana +Dupax del Sur +São Sepé +Pillaiyārkuppam +Bobonong +Essex +Kosgi +Zonhoven +Concepción Huista +Jiangjiadong +Kontich +Parasi +Matsuura +Rose Hill +Obock +Tabount +Varennes +Lucélia +Chorwād +Rātu +Saint-Mandé +Milwaukie +Caaporã +Rio Maior +Valle Nacional +Qia’erbagecun +Nāgamangala +Borgomanero +Boca da Mata +Rupauli +Šaľa +Vryburg +Floridia +Hyde Park +Shāzand +Belonia +Gardanne +Lāthi +Belas +Manlleu +Varadero +Tiburon +Penzance +Sarāri +Tinja +Guasipati +Clarin +Bologoye +Khromtaū +Varkaus +Wildeshausen +Hallein +Allschwil +Florencia +Morāsar +Maracaçumé +Hancha +Saponé +Irákleia +Kanmaki +Bayou Cane +Loyola Heights +Kannānendal +Quirima +Saurh +Cortona +Kağızman +Forbach +Villeneuve-le-Roi +Aguinaldo +Cartaya +Skegness +Carlos Casares +Schramberg +Raksaha +Adigaratti +Enköping +Shark +Suaza +Vikhorevka +Kokofata +Ādēt +San Juan de Río Coco +Princesa Isabel +Nogales +Foley +Wipperfürth +Irukanni +Hays +Martellago +Tullahoma +Āmodei +Bānki +Conceição de Macabu +Molde +Chocamán +Traunreut +Altepexi +Wülfrath +Germersheim +Tehata +Gorgonzola +El Pinar +Gardner +San Isidro de Lules +Oued el Aneb +Itapaci +Sadao +Tizi-n-Bechar +São Marcos +Seria +Chopinzinho +Xoxocotla +Furano +Harstad +North Bellmore +Paiganapalli +Karachayevsk +Phulpur +Sondrio +Orhei +Injibara +North Ogden +Toguchin +Imi n’Oulaoun +Xinnongcun +Palmeiras +Behat +Caxambu +Paulistana +San Juan de Vilasar +Makakilo +Saint Austell +Laje +Chinchali +San Francisco +Villapinzón +Palafrugell +Jangy-Nookat +Ukmergė +Saka +Saint Paul’s Bay +Joaquín V. González +South Whitehall +Itambacuri +Park Forest +Nubl +Helena +Oro-Medonte +Józefów +Praia da Vitória +Mirador +Caterham +Sysert +Porto Torres +Wade Hampton +São Jerônimo +Groß-Umstadt +Phalia +Zülpich +Patpāra +Ariano Irpino +Stephenville +Klaukkala +San José de Jáchal +Az Zuwaytīnah +Timmarāsanāyakkanūr +Woodlesford +Nördlingen +San Víctor Abajo +Fatehgarh Chūriān +Mānjhi +Tanhaçu +Sāmba +Willmar +Ronda +Stratton Saint Margaret +Alto-Cuilo +Cuilo +Daddi +Mangghystaū +Merrick +Cranendonck +Sremčica +Nurota +Morafeno +Sitampiky +Ambalavato +Tongobory +Tsarasaotra +Ambohipandrano +Andolofotsy +Soanindrariny +Ankililoaka +Tsiamalao +Fiadanana +Antanambao +Sahamadio +Miorimivalana +Ambohimanambola +Ampasimatera +Karianga +Matanga +La Colonia Tovar +Fengjia +Dabaozi +Sancoale +Kudāl +Anah +Mandza +Sidi Lahssen +Lebanon +Tufānganj +Ţorqabeh +Fredonia +San Antonio Sacatepéquez +Vadakkum +Walia +Laranjeira +Cassilândia +Barcelona +Sokal +Capela do Alto +Agan +Itapecerica +Welench’ītī +Daboh +Nizāmpatam +El Retén +Suzzara +Osmaneli +Zele +Fót +Santa Vitória +Baiheqiao +Thuân An +Saint-Cyr-l’École +Bugalagrande +Ankaraobato +Hualqui +Pushchino +Upper St. Clair +Caracaraí +Carmo do Rio Claro +Mont-Royal +Pacatu +Coreaú +Hirekerūr +Quela +Purranque +Hino +Nizhniy Lomov +Mineola +San Cataldo +Vladičin Han +East Moline +East Pennsboro +Green Valley +Öndörhaan +Chaudfontaine +Cuncolim +Piedra Blanca +Torrox +Damua +Punturin +Saint-Genis-Laval +Renens +Nambiyūr +Chợ Phước Hải +Alagoa Nova +Concepción Chiquirichapa +Louisville +Urussanga +Fort Walton Beach +Argenta +Five Corners +San Guillermo +Vili +Leskovac +Aishō +Guará +Jericho +Bni Rzine +Little Egg Harbor +Mössingen +Esperalvillo +Osa +Vakkam +Lučani +La Unión +Pudupattanam +Kamamaung +Senden +Snellville +Herborn +Voiron +Eeklo +Monte Santo de Minas +Pico Truncado +Battle Ground +Beaumont +Texistepec +Liubotyn +Bālugān +Germantown +Brummen +Ludlow +Murphy +Don Bosco +Koāth +Quixeré +Ambohimanga +Normanton +Mulanje +Sint-Katelijne-Waver +Palavūr +Murree +Zaliohouan +Kyaukpyu +Saint-Gratien +Sotomayor +Sánchez +Bordj Bounaama +Bambalang +Mudākkal +Kara-Suu +Aurād +Luisiana +Shōwa +El Gara +Oliveira do Hospital +Sidi Abdelkader +Buinsk +Birkerød +Beni Haoua +Hyattsville +Amdjarass +Wallington +Hindang +Pogradec +Moniquirá +Olenegorsk +Ovejas +Carlisle +Vinany +Kurovskoye +Sanhe +Wettingen +Cercado Abajo +Letlhakane +Musselburgh +Hārohalli +Arnold +Luckenwalde +Debark’ +Yachiyo +Imi-n-Tanout +Paldorak +Wasquehal +Lajinha +Junqueirópolis +Halluin +Norton +Jindřichŭv Hradec +Bruchköbel +Conselheiro Pena +Elektrougli +Gaura +Castrovillari +West St. Paul +Murrysville +Buckingham +Karmana +Covington +São José da Laje +Miches +Meinerzhagen +Bhainsdehi +Sonāgāzi +Bourg-la-Reine +Beroun +Lockport +Stadtlohn +Devirammanahalli +Mariāni +Grayslake +Malaba +Chelak +Ararat +Conceição da Feira +Valkeakoski +Banting +Schortens +Mill Creek +Ambondro +Alta +Derinkuyu +Ibicoara +Morsang-sur-Orge +Peringanād +Cordeiro +Veresegyház +Coolbaugh +Croix +Jicomé +Carcagente +Wittmund +Sestu +Bronkhorstspruit +Leek +Samacá +Algete +Hörstel +Gavarr +Coudekerque-Branche +Barhampur +Springfield +Bulnes +Colfontaine +Ul +Oliveira de Azemeis +Pālkonda +Puduppalli Kunnam +Chaves +Yermal +Luacano +Sivaslı +Illapel +Valljkkod +Ino +Bryant +Banganapalle +Mino +Supaul +Kuknūr +Sivrihisar +Narwar +Bandar-e Gaz +Mathukumnel +Leigh-on-Sea +Castel San Pietro Terme +Sonbarsa +Tittagudi +Anagni +Puzol +Le Creusot +Monsummano +Zhangatas +Hanahan +Iriona +Hexiang +Gannavaram +St. John +Kiseljak +Achampet +Moḩammadābād +Boscombe +Palestina de los Altos +Dugulubgey +Beruri +Arnaud +Oliveira dos Brejinhos +Hanmayingcun +Goodlands +Lebedinovka +Ennis +Tolosa +Elvas +Parma Heights +Enger +Ménaka +Vranov nad Topľou +Werdau +São João Batista +Llandudno +Guaratinga +Nidderau +Kolāras +Mae Sai +Luna +Campestre +Monte Azul +Ati +Olho d’Água das Flores +Chithara +Ozoir-la-Ferrière +Dolyna +Montecatini Terme +São João de Pirabas +Palma del Río +Baroda +San Julián +Lennox +Baie-Comeau +Mäntsälä +Soye +Bussolengo +Pozantı +Failsworth +Recanati +Cornaredo +South Milwaukee +Kremenets +Kirkstall +Marquette +Wuustwezel +Steinhagen +Działdowo +Profesor Salvador Mazza +Bozoum +Waxhaw +Guadalupe +Lomita +Schwanewede +İsmayıllı +Lagoa do Itaenga +Mesquite +Sidi Chiker +Muttatōdi +Givors +Rosamond +Fougères +Ås +Banaue +Los Llanos de Aridane +Melena del Sur +Montgomery +Bohumín +Piazza Armerina +Denain +Vinjamūr +Kladovo +Nerekhta +Riacho das Almas +El Hammadia +San Isidro +Parramos +Miandrivazo +Lubalo +Bagou +Bad Waldsee +Sidi Rahal +Mitry-Mory +Yanagawamachi-saiwaichō +Sour +Sarreguemines +Kāmalāpuram +Pueblo Nuevo +Arroyo Seco +Longjumeau +Bethany +Chachahuantla +Pahuatlán de Valle +Maraú +Bockum +Isernia +Kleppe +Schifferstadt +Hardi +Manhumirim +Pittsburg +Na Klang +Hurricane +Dingolfing +Concarneau +Crowborough +Adrian +Bobrov +Târnăveni +Tân Phong +Al Qays +Botevgrad +Paraíso +Celbridge +Ghafurov +Popasna +Yakkabog‘ +Sunbāţ +Tepexi de Rodríguez +Patuvilāyi +South St. Paul +Somanya +Aldan +Nan +Goris +Manbengtang +Câmpia Turzii +Neufahrn bei Freising +Jatāra +Kawambwa +Gjøvik +Caravelas +Nanuet +Sāvda +Riverview +Kapay +Wachtberg +Mead Valley +Nuenen +Lillehammer +Loja +Kekem +Baza +Chapulhuacán +Buftea +Rosolini +Toktogul +Palo del Colle +Romano di Lombardia +Nikolsk +Hashtrūd +Mbala +Qagan Us +Foya Tangia +Şā al Ḩajar +Arhavi +Pleasantville +Dumbarton +Lugait +‘Adrā +Chintalapalle +Hlohovec +Mödling +Libertyville +Jefferson +Sultanpur +Forest Lake +Honnāli +La Resolana +Fröndenberg +Zestaponi +Shoreham-by-Sea +Chã Grande +Namioka +Vakon +Arsk +Sunchales +Gandujie +Batī +Colleferro +Codlea +Mazinde +Laboulaye +Guadalupe Nuevo +Sultanhisar +Carmen de Patagones +Quemado de Güines +Aomar +Maniyamturuttu +Torhout +Bothell West +Bladel +Lami +Sonkach +Hernani +Hythe +La Paz +Vadamadurai +Madipakkam +Baião +Chennimalai +Bala +Žďár nad Sázavou +Cobourg +Ōhara +Mustang +Northfield +Atoyac de Álvarez +Station des Essais M.V.A. +Tyrnyauz +Eruh +Elko +Coswig +Colonia General Felipe Ángeles +Cauto Cristo +Carquefou +Trecate +Ijevan +Nishigō +Bibai +Bañolas +Kozmodemyansk +Baskil +Horten +Muhammadābād +Pendembu +Tielt +Shimogamo +Cranbrook +Nellimarla +Lubartów +Grottaferrata +Binondo +San Bernardino +Seydi +Sapang Dalaga +Nahorkatiya +Khvānsār +Sceaux +Limerick +Stevenson Ranch +Capanema +Hatvan +Peritoró +Saint-Pol-sur-Mer +Lower Southampton +Posušje +Becerril +La Celle-Saint-Cloud +Hailsham +Bhojpur Kadīm +Uetze +Kurshab +Reçani +Dülken +Nadikūde +Kaltan +Magsaysay +Timaná +Mindouli +Sant Just Desvern +Golden +Omagh +Kizhāttūr +Aïn Cheggag +Kawayan +Otsego +Bourne +Costas de Cão +Caparica +San Martín +Taşlıçay +Mường Lay +Saco +Paraisópolis +Puerto Quito +Maghull +Piqua +Keevallur +’Aïn el Bell +Fara +Sidi Jaber +Imperial +Susaki +Mealhada +Cinfães +Ostrov +Jarājūs +Vyškov +Pak Phanang +Huércal-Overa +Itatira +Baud +Aígio +Chepo +Sandwich +Roshal +Bezhetsk +Koipādi +Yasothon +Lambari +Joinville-le-Pont +Kuala Pembuang +Bouguenais +Jaboticatubas +Dereli +Pariyāram +San Lorenzo +Reggane +’Aïn el Hammam +Iztapa +Hauppauge +Monroe +Follonica +Greiz +Montrose +Donggou +West Hempstead +North Liberty +Zaghouan +Haßloch +Requena +Old Jamestown +Painesville +Newmarket +Sandhurst +Chokkampatti +Beforona +Koło +Longbangcun +La Cañada Flintridge +Naraura +Jaguaruna +Barki Saria +Rāmnagar Farsāhi +Samboan +Porto Real +Reichenbach/Vogtland +Alatsinainy-Bakaro +Kūttampala +Feltre +San Pablo Tacachico +Kanaya +Yangping +Tewkesbury +Okha +Cormano +Rothwell +Karaiyāmpudūr +Frøyland +Høyland +Marblehead +Sidney +Kihihi +Blankenberge +Sartalillo +Altamont +Lannion +Cugnaux +Harpālpur +Bratunac +Neustrelitz +Middle +Yellowknife +Makhtal +Westbrook +Mundra +Tala Yfassene +Huanuni +North Amityville +Kashkar-Kyshtak +Dan Gorayo +Grande-Synthe +La Chapelle-sur-Erdre +Trentola +Santa María Chilchotla +Chevilly-Larue +Dharmkot +Nesoddtangen +Farāshband +Fangasso +Farum +Baihar +Salmon Creek +Xincheng +Santa Rosa +Rawicz +Katākos +Senta +Santa Rita +Khowrzūq +Las Vigas de Ramírez +Chandragiri +Lynbrook +Gryfino +Kyakhta +Selendi +Bellshill +Tobe +East Northport +Duderstadt +Sherwood +San Martin De Porres +São Felipe +Marion Oaks +Oroville +Lalín +Bīrpur +Salgado +Inírida +Cândido Mendes +Shisui +Chorozinho +Shāmgarh +Nyon +Teculután +Simití +Concordia +Sergach +Tenjo +Minturno +Whitpain +Gopavaram +Çilimli +Lingolsheim +Devrukh +Arlington +Ogden +Kokopo +East Hemet +Pulicat +Rumoi +Frankfort +Wodonga +Luperón +Parkāl +Ely +Ervália +Rovira +Bad Schwartau +Vico Equense +Sbeitla +Chodavaram +Hazlet +Danao +Husainpur +Mar’’ina Horka +Mosta +South Burlington +Blieskastel +Jdour +Aguas Zarcas +Touna +Rāipura +Abano Terme +Palisades Park +Ochtrup +Zhangjiazhuang +Samthar +Āsosa +Belūr +Xionglin +Parnamirim +Telgte +Piñan +Edakkunnam +Le Plessis-Trévise +Khilchipur +Lichtenfels +Gyömrő +Bruges +Kortenberg +Ban Tha Pha +Yaraka +Lower Allen +Gostyń +Azacualpa +San Francisco +Sessa Aurunca +Le Mée-sur-Seine +Chāndpur +Entroncamento +Ypsilanti +Rhenen +Pennāgaram +Mělník +Tondi +Stebnyk +Xo‘jaobod +Ağsu +Ağstafa +Mayluu-Suu +Rivalta di Torino +Pontassieve +Pompéia +Boromo +Cournon-d’Auvergne +Uruburetama +South Frontenac +Douar Lamrabih +Puerto Viejo +Reitz +Pikalëvo +Guácima +Voyenno-Antonovka +Skive +Ripley +Cruz Grande +Ban Klang +Blansko +Taïbet +Kotelnikovo +Polonne +Seaham +Talayāzham +Monte Alegre de Minas +Abou el Hassan +Peterlee +Pargi +Schopfheim +Otegen Batyr +Motatán +Shafter +Diondiori +Sivagiri +Nelkattumseval +Akora +Kubinka +Medina +Frontino +Erragondapālem +Río Grande +Aurād Shāhjahāni +Ayaviri +Pantanaw +Sesheke +Bhitarwār +Regente Feijó +Kherālu +Cahors +Midway +La Trinidad +Rosas +Mattigiri +Alblasserdam +Ālampālaiyam +Dorchester +Teonthar +Arbutus +Giengen an der Brenz +Karukachal +Aquidabã +Portland +Kürten +Del Carmen +Toprakkale +Mayfield Heights +Farakka +Morristown +Turmalina +Pujehun +Belmonte +Holzminden +Bela +Leinefelde +Villa Verde +Vettikkavala +Rivière-du-Loup +Huanímaro +Senec +Halewood +Comrat +Plainview +Archena +Pallazzolo sull’Oglio +Barkly West +Nykøbing Falster +Culpeper +Gálvez +Nkoteng +Westminster +Celorico de Basto +Biləsuvar +Lubań +Kulpahār +Montalto Uffugo +Buckhall +Satsuma +Oberkirch +La Crescenta-Montrose +Medina del Campo +Villa Hidalgo +Agoura Hills +Kwinana +Denderleeuw +Piatã +Yabayo +Şiran +Douglas +Lonār +Vīrarājendrapet +Barroso +Mithi +Porto Real do Colégio +Skanderborg +Killingworth +Depālpur +Sidhapa +Naranjos +Ėsanboy +Dhorīmanna +El Ancer +Cabra +Mahaditra +Temacine +Horwich +Mont-Saint-Aignan +Llallagua +Schmalkalden +Banī Murr +Brezno +Schroeder +Rosedale +Ban Wat Sala Daeng +Casa de Oro-Mount Helix +Nguékhokh +Mesra +Durbat +Pita +Kārtikapalli +Guding +Shakhunya +Diguapo +Buxton +Ferentino +Lohur +Meadowbrook +Bülach +Teopisca +Kannod +Alagir +Kafr Lāhā +Makoua +Castillo de Teayo +Mutuípe +São Joaquim do Monte +Tettnang +Bhopatpur +Whitehall +Harvey +Yumbel +Tolú Viejo +Atescatempa +Port Colborne +Beaune +Bubanza +Hakui +La Esmeralda +Takanabe +Albany +Rolla +Atarfe +Cittadella +Howard +Sidi Merouane +Altoona +Kissa +Oderzo +Jiangjiehe +Dumbrăviţa +Tsotsin-Yurt +Krasnohrad +Pertuis +Etzatlán +Calceta +Presidente Getúlio +Kandakkadava +Rio Formoso +Gorāya +Port Angeles +Tupanciretã +Forest Park +Piove di Sacco +El Ksiba +Bispham +Indwe +Kfar Kiddé +El Bâzoûrîyé +Slobozia +Ampasimena +Mandrosohasina +Ambalakirajy +Rantabe +Mandiavato +Ambatosoratra +Antsampandrano +Tsararafa +Analapatsy +Tsarabaria +Soavina Antanety +Bekatra Maromiandra +Haka +Arvayheer +Cárdenas +Kuala Lipis +Opuwo +Bulolo +Gahi Mammar +Alfena +Kébémer +Mikumi +Muheza +Sultonobod +Sangīn +Sitrah +Zemio +Bamukumbit +Bamumkumbit +Sanjianxiang +Hampton +Minster +Shri Mahāvīrji +Tadas +Asarganj +Rankhandi +Bhaluhār +Mandi Bamora +Bareja +Sikka +Mūnak +Pīrbahora +Hudli +Bāzidpur Madhaul +Suroth +Sujnipur +Marjampād +Sohāna +Chimthāna +Mangapet +Ankalgi +Kothanūru +Tuminkatti +Nāranda +Sonāimukh +Baragoi +Ciudad Miguel Alemán +’Aïn Mabed +Comăneşti +Garhshankar +Donauwörth +Vasiana +Chaville +Salsomaggiore Terme +Dillingen +Evaz +Emet +Antrim +Trostyanets’ +Chirilagua +Sanrh Majhgawan +Palāshi +Sidi Taibi +San Marcos +Kumīl +’Ali Ben Sliman +Shōnai +Shirahama +Vazante +Shīrūru +Valderrama +Valiyakumāramangalam +Kadakola +Vianen +L’Isle-sur-la-Sorgue +Matheu +Tibagi +Itsoseng +Alpinópolis +Usman +Bafoulabé +Altagracia +Korntal-Münchingen +Benicasim +Kampong Thum +Petrinja +Ampefy +Waldbröl +Hudson +Bhasāwar +Coruche +Plaisance-du-Touch +Ban Tha Kham +Carira +Chilly-Mazarin +Acquaviva delle Fonti +Butare +Tarhzirt +Náchod +Irlam +Mapai +Mulundo +Venmani +Dharampur +Aït Tamlil +Koskāpur +Doany +San Martín de la Vega +Had Zraqtane +Sand Springs +La Mornaghia +Hiddenhausen +Chatiā +Andāl +Sīāhkal +Merrifield +Affton +Ulcinj +Dhanaula +Palliman +Äänekoski +Burnie +Merad +Bichena +Yuancun +Novate Milanese +Senapparetti +Pukhrāyān +Plattsburgh +Saint-Augustin-de-Desmaures +Bressuire +Piedade +Ban Tha Ton +Sakae +Nottuln +El Arenal +Cachoeirinha +Zāwiyat Razīn +Oregon +Hunters Creek +Akureyri +Biddulph +Saynshand +Vevey +Vila Rica +Nejo +Tolosa +Mokena +Crest Hill +Namegawa +Maple Shade +Loudima Poste +Málaga +Kisai +Nizhnyaya Tura +El Paraíso +Gil +Guiré +Andirá +Kūysinjaq +Brandsen +Peshtera +Hamina +Miamisburg +Senica +Dagohoy +Karlapālem +Gherla +Castilho +Homewood +Canelones +El Castillo de La Concepción +Opfikon +Sacile +Ibirama +Calella +Orašje +Comapa +Quepos +Bara Malehra +Līkak +Boussu +Umrāpur +El Mansouria +Gerlingen +Zimatlán de Álvarez +Kavieng +Tepetlixpa +Cartavio +San Miguel +Humanes de Madrid +Ratanpur +Moosburg +Campamento +Gubakha +Kuusankoski +Jagatpur +Cantagalo +Rechaïga +Gebre Guracha +Volokolamsk +Stroud +Peto +Masterton +Sint-Andries +Rio Verde de Mato Grosso +Ellamanda +Khizrpur +Kolavallúr +Makurazaki +Spennymoor +Huntsville +Broadview Heights +Pradópolis +Dillingen +Jāmbai +Atlapexco +Albertville +Lincolnia +Garforth +Alamo +Dokolo +Lisieux +Sleaford +Anghad +Mannūr +Kochas +Kāmākhyānagar +Torgau +Ban Na San +Hirokawa +Remígio +Universal City +Sainte-Marthe-sur-le-Lac +Agryz +Stoke Gifford +Wilnsdorf +Kannānkurichchi +Itaparica +Rubiataba +Nosy Varika +Çekerek +Puttūr +Nyandoma +Araripe +Holden +Poperinge +Time +Mosopa +Smørumnedre +Sparta +Oulad Embarek +Massy +Vulcan +Malabuyoc +Cheung Chau +Brandýs nad Labem-Stará Boleslav +Zhaodianzi +Palm Valley +Kattanam +Puerto Armuelles +Ghatkesar +Lackawanna +Nogales +Selby +Bishunpur +Ennigerloh +Ryūyō +San Miguel +Oulad Fraj +Xingangli +Simonésia +Lake Zurich +Prudnik +Poshkent +Três Barras +Pattamadai +Calvillo +Os +Wittlich +Lloydminster +Opoczno +Itatinga +Assebroek +Thimiri +Beldaur +Marsberg +Cherakhera +Mengdan +Sarstedt +Yonabaru +Issaba +Kanekallu +Evergreen Park +Crisópolis +Moineşti +Bachi-Yurt +Yosano +Claremore +Viadana +Nittedal +Pećinci +West Whiteland +Cuité +Hongshui +Gröbenzell +Shinjō +Saavedra +Castelo do Piauí +Pichidegua +Río Segundo +Payimattam +Mayen +Echizen +Schenefeld +Jnane Bouih +Alga +Oschersleben +Beltsville +Kinston +Bückeburg +Stamford +Rybnoye +Babanūsah +Lehāra +South El Monte +Suárez +Colotlán +San Salvo +Taketa +Jimaguayú +Dicholi +Harmanli +Mokēri +Buşrá ash Shām +Silla +Kātpādi +Kanniyākumāri +Shelbyville +Calatayud +Mougins +Nambūru +Orós +Whitemarsh +Sinacaban +Maḩmūdābād Nemūneh +Hajnówka +Guantiankan +Udalguri +Korsholm +Pastores +Būdipuram +Westmount +Andaingo Gara +Chiconcuac +Pichor +Buriti dos Lopes +Komárom +Silver Spring +Bruz +Durağan +Yuanhucun +Grafton +Chipiona +Karuizawa +Kondūr +Nové Mesto nad Váhom +Villa Elisa +Luénoufla +Dayr Abū Ḩinnis +Davyhulme +Villabate +Monroe +Ahfir +Nilakkottai +Urumita +Hanumana +Rāwah +Jussara +Várpalota +Haiger +Bir Kasdali +Ampère +Forest Park +Atasū +Otjiwarongo +Yahotyn +Bad Aibling +Arvin +Rāmjībanpur +Cherepanovo +Lerdo de Tejada +Okhmalynka +Punta Gorda +Bad Pyrmont +Mayahaura +El Coco +Ilijaš +Veroli +Niiyama +Brigham City +Bondo +Kutina +San Juan Zitlaltepec +Petrila +Diinsoor +Sādpur +Tapauá +Ischia +Russell +Turnu Măgurele +Holtsville +Xapuri +Lieto +Rhede +Lexington +Yershov +Buritirama +Lastra a Signa +Hidalgotitlán +Visaginas +Venadillo +Schilde +Engelskirchen +Liuliang +Les Coteaux +Bourg-lès-Valence +Bequimão +Jājarm +Punjai Puliyampatti +Caraúbas +Erlanger +Burnham-on-Sea +Ituzaingó +Barañáin +Heinola +Caoayan +Abbots Langley +Santa Teresita +Suchiapa +Amorebieta +Aysha +Atchoupa +Wenden +Doujing +Mirfield +Acıgöl +Gallipoli +Ansermanuevo +Ballyfermot +Vallam +Dudinka +Morwa +Rizal +Mogiyon +Töle Bī +Hermosa Beach +Caraí +Thamaga +Huseni +Pathrajolhania +Tīrthahalli +Guapó +Jhalidā +Artik +Beloyarskiy +Mihona +Mārahra +Liuguang +Herceg Novi +Crespo +Bagaces +Artik +Rajaudha +Eersel +Eupen +Candelaria +Ipanema +Pauini +Hoxut +Ibigawa +Goole +Bedelē +Parsāhi Sirsia +Arese +Fukude +Yusufeli +Alaca +Kalayapuram +Āmta +Telavi +Mahināwān +Tibba +East Massapequa +Akanavāritota +Āsasa +West Mifflin +Castellana Grotte +Garsfontein +Ait Bousarane +Ait Bouziyane +São Vicente Ferrer +Sjöbo +Sangasso +Hushihacun +Terek +Los Álamos +El Arahal +Teminabuan +Oulad Salmane +Katangi +Callosa de Segura +San Juan de Dios +Hoveyzeh +Deneysville +Nīlgiri +Rhar el Melah +Capinota +Orinda +Albolote +Cugir +Eschwege +Santiago +Saray +Borna +Jesús María +Mölln +Müllheim +Jagalūr +Krishnapur +Orvieto +Lodeynoye Pole +Hawthorne +Sondiha +Gogogogo +Qorasuv +Polonuevo +Setlagode +Rāmchandrapur +Teghra English +Angleton +Narsāpur +Cervantes +Clifton +Marihatag +Kempston +Hechingen +Kemi +Ronchin +Lake Forest +Sabaudia +Madisonville +Kos +Salmon Arm +Cardonal +Adel +Tublay +Someren +Santiago Texacuangos +Ban Thap Kwang +Bartow +Gaeta +Lynn Haven +Kemisē +Liversedge +Siruma +Nova Granada +Kārttigappalli +Vence +Kirkland +Ardon +Dorou +Sāmalāpuram +Salangaippālaiyam +Abrīsham +Xihuangcun +Weil der Stadt +Sulzbach-Rosenberg +Zachary +Los Bajos +Frutillar Alto +Sipoo +Sweetwater +Yandrapalle +Dalanzadgad +Pahsara +Kantharalak +Pariquera-Açu +Kushiro +Bad Driburg +Cabildo +Alto Araguaia +Rayevskiy +Arbaoun +Annaberg-Buchholz +Sartell +Barro +Törökszentmiklós +Englewood +Kalghatgi +Shikrapur +Charef +Saint-Lô +Manjathala +Les Côteaux +Casarano +Prunedale +Middelkerke +Heishanzuicun +Seabrook +Abhayāpuri +Kākdwīp +Boone +Giovinazzo +Canto do Buriti +Burghausen +Tajerouine +Kloten +Kitatajima +Gōdo +Saint-Fons +Pastrana +Juquiá +Rifādpur +Mukaiengaru +Saré-Yamou +Buruanga +Paranapanema +Heishuikeng +Arbatache +Balta +Prichard +Nauen +Kuttyādi +Great Linford +Brookfield +Dudu +Jämsä +Napindan +Ban Bueng +Ban Patong +Mahājerān-e Kamar +Oruvadālkotta +Moulins +José Cardel +Tadian +Wassenberg +Allanridge +Pugo +San Roque +Tangbian +Wolfratshausen +Sorada +Weesp +Bieruń +Cajolá +Corner Brook +Dashtigulho +Pułtusk +Presidente Médici +Bholsar +Ban Fang Tuen +Perūru +Tevāram +Saint-Dié-des-Vosges +Kamiichi +Warrensburg +Faversham +Stillwater +New Glasgow +Moaña +Naples +Palera +Panniperumthalai +Mâncio Lima +San Antonio Huista +Assamannur +Pohādi +Tash-Kömür +Pottanikād +Heusenstamm +Dukinfield +Jirkov +Monte Azul Paulista +Virovitica +Dorval +Qandala +Sélestat +Marechal Taumaturgo +Espiritu +Kapangan +Sirvār +Casamassima +Sukumo +Twinsburg +Ganyesa +Sudley +Dolynska +Seminole +Douar Ait Sidi Daoud +Bouanri +Bhojpur Jadīd +Cutlerville +Iiyama +Wanluan +Kirovgrad +Rovato +Beaconsfield +Tsumeb +Pitimbu +Sint-Gillis-Waas +Mapastepec +Marchena +Peterhead +Ashland +Indargarh +Haldensleben +Highland +Hermiston +Maitland +Alzey +El Viso del Alcor +Kudra +Bakal +Ferndale +Cassano d’Adda +Tillabéri +Balintawak +Bābai +Cabusao +Sherrelwood +Henichesk +Valle Vista +Tonantins +Realeza +Águas Formosas +Gilching +Dračevo +Soure +Söğüt +Araçoiaba +Quartier Morin +Kamwenge +Sirnia +Groveland +Holalkere +Diadi +Al Brouj +Ballitoville +Aberdeen +Roosevelt +Garot +Kassama +Monção +Ghosāi +Magitang +Sühbaatar +Pescia +Gázi +Orange +Vigna di Valle +Atok +Springboro +Amboanana +Khonj +Harrison +Eruvatti +Chetichēri +Kabūdarāhang +Tingloy +Malgrat de Mar +Brie-Comte-Robert +Bandar-e Kong +Ecclesall +Ābomsa +Jakobstad +Zola Predosa +Texcaltitlán +Puerto Morelos +Jiabong +Lumphat +Ystrad Mynach +Andrychów +Lebedyan +Rangra +Kale +Jamiltepec +Devgadh Bāriya +Attapu +Aradíppou +Sligo +Lebbeke +Rurrenabaque +La Corredoría +Binka +Khamaria +Gomīshān +Ermita +Schkeuditz +Venceslau Brás +Ranst +Alcoy +Zerong +Bad Tölz +Dumra +Pokaran +Sibila +Vera +Oued el Abtal +Sirpur +Maumelle +West Manchester +Badger +Maghar +Tinton Falls +La Crau +Gioia Tauro +Norton +Krasnogorskiy +La Paz +Schönefeld +Ghogardīha +Rosedale +Deerfield +Jaicós +Sidi Redouane +Naantali +Meise +Koropí +Chiari +Horseheads +Ambatomirahavavy +Essen +Blankenburg +Seesen +Izra +Gülağaç +Raita +Pauktaw +Vila Real de Santo António +Sömmerda +Tiruvādi +Cocos +Cedar Mill +Papanduva +Guaranésia +Durango +Senguio +Pitt Meadows +Biswanath Chariali +Gerze +Reinach +Ad Dir‘īyah +Schwalmtal +Fukusaki +Diamante +Sirālkoppa +Schneverdingen +Pidhorodne +Billinghurst +Kodumba +Diepenbeek +Passagem Franca +Iramala +Pljevlja +Ampanety +Nikolayevsk-na-Amure +Trzebinia +Zaouïa Aït Ishak +Eitorf +Ainan +Vargem Alta +Contenda +La Ligua +Shemonaīkha +Knightdale +Kufstein +Imouzzer Kandar +Chennīrkara +Māvinpalli +Ban Mon Pin +Ashkezar +Shimokizukuri +Central Point +Midlothian +Baden +San Teodoro +Martín Coronado +Morauna +Shāhgarh +La Unión +Sorgues +Cerqueira César +Cacahoatán +Uwchlan +Montemurlo +Gobabis +White Oak +Bieruń Stary +Bella Unión +Shāhpur +Harpur +Lumberton +Liberal +Stord +Nīlambūr +Lebach +Taka +Frimley +Chautāpal +Lumbayanague +Anguillara Sabazia +Haslett +Paillaco +Molesey +Tavares +Niagara-on-the-Lake +Saugerties +Mumbwa +Prestatyn +Butiá +Pindobaçu +Villefontaine +Cherán +Tazishan +Winchester +Menzel Abderhaman +Aizumisato +Douar Toulal +Rizal +Cirencester +Karlshamn +Ban Bueng Phra +Calne +Perumkulam +Mahisi +Cocoa +Simri +Nalua +Dixon +Ixtlahuacán del Río +Scituate +São José de Piranhas +Sant’Antonio Abate +Pruzhany +Bouansa +Cunco +Malanday +Chinna Ganjām +Murugampālaiyam +La Eliana +Sabanitas +Gentilly +Hindoria +Tanbaichichō +Zverevo +Žatec +Monkseaton +Préveza +Pūranpur +Svay Pak +Sylvania +Itaosy +Cumberland +Lejiangxiang +Cimarron Hills +Guaymango +Warwick +Dharmsāla +Bukungu +Kovūr +Proletarsk +Taquarana +Winthrop +Onega +Royan +Tirmitine +Telpaneca +Rahata +Point Pleasant +Cardedeu +Sarauli +Wervik +Monor +Morlanwelz-Mariemont +Cotija de la Paz +Norwood +Dankov +North Valley Stream +West Chester +Caowotan +Ferguson +Dadeldhurā +Santa Ana Jilotzingo +Sahline +Spoltore +Mānjha +Fond des Blancs +Fayetteville +Fate +El Bolsón +Akune +Água Branca +Gautier +Quaregnon +Pfullingen +Mao +Lagoa de Itaenga +Ellensburg +Zwijndrecht +Befandriana Atsimo +Anjahabe +Ambalanirana +Ambatomena +Mitsinjo +Belamoty +Vohimasy +Ampataka +Ifanirea +Tanambe +Ambodinonoka +Miarinavaratra +Ambatosia +Mahazoarivo +Manantenina +Bezaha +Ranomena +Nootdorp +Bajo Boquete +Shovot +Dūrpalli +Vitré +Greenfield +Cafelândia +Vista Hermosa de Negrete +Kouloum +Haukipudas +Sārangpur +Druten +Chapada dos Guimarães +Bīrpur +Heredia +Kosatarosh +Barão do Grajaú +Nārapala +Sukhāsan +Scorzè +Radeberg +Laukaa +Kāveripatnam +Onex +Ait Ben Daoudi +Caconde +Boiro +Siripur +Koliakkod +Weirton +La Nucía +Sarso +Burscheid +Acqui Terme +Varidhanam +Ban Na Yang +Colwood +Konstantynów Łódzki +Chichiriviche +Southbourne +El Rosal +Saint Peter Port +Carei +Sarsāwa +Krommenie +Utebo +Makronia +Ansonia +San Ignacio Cerro Gordo +Chilkūru +Križevci +Fox Crossing +Pitseng +Atacames +Pinole +Kolbermoor +El Malah +San Gabriel +Tak Bai +Guru Har Sahāi +Motomachi +Beni Zouli +Aikaranad +Augusta +Neviges +Casalgrande +Malacky +Lakhnādon +Harrisburg +Ayvacık +Middlesex Centre +Sudbury +Desavilakku +Monserrato +Bad Berleburg +Eiheiji +Vera +Nakasi +Elamāttūr +Zuidhorn +Pirkkala +Āb Pakhsh +Prenzlau +Ismailpur +Kōtekāra +Ranbīrsinghpura +Tadó +Lagoa Formosa +Franklin Farm +Sironko +Beshkent Shahri +Shirin +Fakfak +Mo i Rana +Matteson +Utazu +Horsforth +Somandepalle +Nayāgarh +Bad Reichenhall +Gātāda +Garðabær +Madalag +Ribeira Grande +Amares +Nanjanād +San Carlos Park +Guareí +Ezhamkulam +Sugaon +Kasterlee +Náousa +Formoso do Araguaia +Jaggampeta +Pozzallo +Hūn +Lagawe +Korsimoro +Ấp Khánh Hưng +Signa +Malazgirt +Ajacuba +Massaguet +Kalmthout +Lake Shore +Coronado +Groesbeek +Hemmingen +Altamira +Kabbūr +Vīrapāndi +Vārapatti +Arita +Alsip +San Sebastián de Buenavista +Araç +Kottakota +Duero +Conceição +Mont-Saint-Hilaire +Naaldwijk +Traiskirchen +Kovylkino +Cinco Ranch +Weißenburg +Larne +Malimono +Horizontina +North Myrtle Beach +Anzoátegui +Fihaonana +Guachucal +Kara-Köl +Oirschot +Varzelândia +Santa Fe Springs +Zahana +Dukli +Ben ’Aknoûn +Ronkonkoma +Chełmno +Nakhl-e Taqī +Onalaska +Acri +Tradate +Lakeway +Kalach +Cusano Milanino +Bradfordville +Barcelos +Qitai +Dzüünharaa +Alzenau in Unterfranken +Las Terrenas +Edam +Nunuñgan +Khetia +Somerset East +São José da Coroa Grande +Republic +Camarate +Berkovitsa +Odžak +Carlos Spegazzini +Brownwood +Milton +Villa Nueva +Bad Dürkheim +Sebaste +Ascención de Guarayos +Lancing +Sabalpur +Marktoberdorf +Vélez +Purushottampur +Sheridan +Syosset +Kalabahi +Udumanthala +Huehuetla +Pastos Bons +Sortavala +Shimomura +Abdurahmoni Jomí +Dŭstí +Hazorasp +Diallassagou +Ware +Xinhua +Hala +Starobilsk +East St. Louis +Marshfield +Owego +Bremervörde +Arilje +Ibirataia +Tocaima +Lukovit +Oulmes +Taft +Jwaneng +Wisconsin Rapids +Terra Santa +Itajuípe +Sompeta +Ban Bo Haeo +Heerde +Springfield +Antotohazo +Lgov +Pastavy +Chowchilla +Camrose +Kabala +Kralupy nad Vltavou +Złotów +Marānchi +Presidente Olegário +Villaquilambre +Doñihue +Novyy Oskol +Karia Ba Mohamed +Villa Rica +Ayyāmpettai +Durant +Birnagar +Bergeijk +Retiro +Rutherford +Hopkins +San Juan Ermita +Nanthankulam +Bonneuil-sur-Marne +Kurumbapālaiyam +Hopkinton +Koporo-Kénié-na +Kiliia +Bayshore Gardens +Thomasville +Ngathainggyaung +Palestine +Harihans +Altônia +Wallingford Center +Melmuri +Riom +Los Lagos +San Rafael La Independencia +Adliswil +Schlieren +Sendamaram +Paglat +Rufino +Lansdale +Gunri +Görele +Alfeld +Phoenixville +Ozorków +Country Walk +South San Jose Hills +Tlalnelhuayocan +Ključ +Hem +Snina +Altus +Ottawa +Dhāriwāl +Aroeiras +Salamina +Djidian +Vadakkangara +Choghādak +Peduasi +Aburi +Qo’shko’pir +Abong Mbang +Lupeni +Tyèlè +Tsivory +Balilihan +Çerkeş +Qaryat al Qī‘ān +Valle +Nefas Mewch’a +Perunturuttu +Andéranboukan +Majdanpek +Areia Branca +Surovikino +Middelburg +Ceglie Messapico +Zapote +Creve Coeur +Leicester +Morales +Martinsburg +Round Lake +Kinzau-Vuete +Doura +Blooming Grove +Togba +Afrânio +Bensenville +São Raimundo das Mangabeiras +Mansa Konko +Trinity +Sonhauli +Lakhna +Almel +Rishivandiyam +Lelydorp +Meerssen +Jasidih +Broughty Ferry +Şammā +Seagoville +Kavalerovo +Siyəzən +Maimón +Soalkuchi +Molakālumuru +Centerton +Santa Catarina Juquila +Selwyn +Cambridge +Elumalai +San Julián +St. Michael +Lauālāgaon +Carnaíba +Kangazha +Shimanovsk +Telwa +Adria +Castaic +Aldama +Futog +Szamotuły +Basatpur +Mūkkanūr +Enkhuizen +Ashland +Bonanza +Bergneustadt +Kīlmangalam +Mānikkal +Le Puy-en-Velay +Lede +Mossendjo +Ribeirão Branco +Chākūr +Manakayi +Ubaíra +Urucará +Sanharó +Tarifa +Ballincollig +Londerzeel +Seara +Knik-Fairview +Vanino +Uetersen +Medjedel +Carlos Chagas +Volketswil +Tillsonburg +Eastwood +Fairwood +Tata +Engenheiro Coelho +Maurepas +Bellwood +East Dereham +Onga +Mullach Íde +Stannington +Reriutaba +Concord +Corinto +Ajnāla +Leposaviq +Saylac +Toshloq +São Gabriel +San Miguel +Miyatoko +Timoktene +Los Alcázares +Renningen +Kalugumalai +Jbabra +Antombana +Felanitx +Five Forks +Ploemeur +Preakness +Majhua +Valavanūr +Al Jawf +Lebanon +Anna +Hatfield +Jalakandāpuram +San Mauro Torinese +Colonia +Skara +Windham +Shika +Rhynern +Tamri +Mohana +Liuma +Clive +Liancourt +Narangba +Meylan +Kasongan +Elizabeth City +Nederland +Bougtob +Tomaszów Lubelski +Crimmitschau +Paluan +San Sebastián Salitrillo +Miracema do Tocantins +Ban Mae Hia Nai +Erumakkuzhi +Zhosaly +Kingsland +Pizarro +Tarrafal +Bhadaur +Shenandoah +Ebbw Vale +Garuva +Boom +Mingjiujie +Leteri +Wheatfield +Morros +Zākīyah +Miracatu +Priozërsk +Lessines +Matipó +Kumbhrāj +Mennzel Bou Zelfa +Mellacheruvu +Berea +Shaogang +Glinde +Ban Mae Kha Tai +Ferguson +Sebt Gzoula +Orhaneli +Hochheim am Main +Kothia +Morro da Fumaça +Kulu +Arcata +Colina +Goyty +Baena +San Diego +Stabroek +Santander +Guadix +Newton +Parole +Sokołów Podlaski +Ba +Rohār +Melville +Oxon Hill +Asunción Nochixtlán +Thalwil +Lodhwe +Tsetserleg +Tessenderlo +Guanzhai +Santa Cruz Zenzontepec +Bilar +Iselin +Brook Park +Härnösand +Galhinna +Huércal de Almería +St. Marys +Tādikonda +Madre de Deus +Anicuns +Tatsuno +Pālaiyampatti +Hässleholm +Buikwe +Appley Bridge +Goffstown +Rawmarsh +Ghedi +Kivsharivka +Potirendaba +Bitkine +Rhaude +Vlotho +Karcag +Misato +Alton +Kalynivka +Chubek +San Lorenzo de El Escorial +Busovača +Schwalmstadt +Staines-upon-Thames +Unquillo +Zagarolo +Piñas +Laurel +San Celoni +Sirvel +Fushë-Krujë +Kherāmeh +Ajaigarh +Foxborough +Tinoc +Giszowiec +Boerne +Vellmar +Tirmalgiri +Qaşr-e Shīrīn +Sharon +Bedlington +Sacavém +Hoppegarten +Éragny +Alcântara +Taft +La Marque +Çatak +Castel Maggiore +Kotanchēri +Kunitomi +Nara +Pio IX +Kannapuram +Oskū +Hessisch Oldendorf +Lagoa da Canoa +Od +Kāriyāpatti +Mill Hill +Matelândia +Cognac +Ngolonianasso +Shimokodanaka +Narlıca +Coalcomán de Vázquez Pallares +Haaltert +Kassaro +Jucuapa +Achocalla +Bakhmach +Princeton +Bönen +Hellemmes-Lille +Chouafa +Zhangshicun +Choi Hung +Arroyo Grande +Astrea +Albert Lea +Cullman +Baliangao +Yur’yev-Pol’skiy +Lahnstein +Dumjor +Ponedera +Johnstown +Orestiáda +Dover +Juvisy-sur-Orge +New River +Abdulino +Mukkūdal +Trenton +Loreto +Vechelde +Montrouis +Pomáz +Castelfidardo +Kreminna +Svatove +San Vicente Pacaya +Ocean Springs +Fatick +Kronberg +Devadānappatti +Basse Santa Su +Unhel +Winder +Hardinxveld-Giessendam +Amvrosiivka +Foum el Anser +Belo Campo +Tallmadge +San Blas Atempa +Tilothu +Nīār +Konz +Nordestina +Fairmont +Korsun-Shevchenkivskyi +Quitandinha +Kumārapuram +Santa Marinella +Langen +Srikhanda +North Babylon +Inhapi +Crowley +North Bay Shore +Aragarças +Hārij +Tinajeros +Longjia +Rio Maria +Bhawānīpur +Itapororoca +Hampton +Sanpaicun +Bracciano +East Goshen +Straşeni +Walcourt +Greene +Cesário Lange +Sigmaringen +Franklin Park +Cuautitlán +Clonmel +Qatlūpur +Illertissen +Mumford +Assa +Filomeno Mata +Chennevières-sur-Marne +Agarpur +Nytva +Baependi +Santiago Ixcuintla +São Benedito do Rio Preto +El Tránsito +Olten +Écully +Noci +Chhoti Sādri +Krasyliv +Newburyport +Campo de la Cruz +Stekene +San Rafael Pie de la Cuesta +Cagdianao +Wörth am Rhein +Louviers +Saladas +Ammāpettai +Almondbury +Redland +Nāri Bhadaun +Maryland City +Cortes +Buenavista +Apastepeque +Sendārappatti +Capoeiras +Mineros +Lake Ronkonkoma +Mirante do Paranapanema +Daryābād +Lamrasla +Xintian +West Haven +Picuí +Anandpur +Rizal +Novopavlovka +Cran-Gévrier +Pembroke +Memuro-minami +Sandaré +Shaoyu +Nuuk +Skýdra +Calverton +Karuppur +Tha Bo +Taió +Melzo +San José Tenango +Lora del Río +Carrières-sous-Poissy +Talata-Volonondry +Riachão do Dantas +Pully +Pontalina +Morretes +Gerd Farāmarz Shāhedīyeh +Abrandābād-e Shāhedīyeh +Kitagata +Nossombougou +Nehbandān +Mangualde +Belém de São Francisco +Lenoir +Do’stlik Shahri +Hadleigh +Beloozërskiy +Sint-Genesius-Rode +Ommen +Volochysk +Püttlingen +Bingley +Rutigliano +Aveiro +Taung +Slyudyanka +Szigethalom +Sakouéba +Navraftor +Şenkaya +Panama City Beach +Pinecrest +Parchim +Palos Hills +Fomboni +Santa Fe +Kadaň +Paraibano +Rāmpur +Kristiansund +Mannara +Rosendaël +Phelan +Aït Bouchta +Bni Bouayach +Tárrega +Kasba Maker +Somerset +Concord +Burlington +Paraibuna +Yupiltepeque +Siloe +Bideford +Luz +Ban Mai +Monte Cristo +Regensdorf +Yoichi +Mūlanūr +Shuangluan +South Orange Village +Bagnols-sur-Cèze +Moissy-Cramayel +Staveley +Asakapalle +Mathurāpur +Pisz +Shaw +Amsterdam +Savaştepe +Nārāyankher +Monforte de Lemos +Sivandipuram +Santa Iria da Azóia +Manchester +Carrigaline +Comodoro +Kānp +Ikniwn +Calera de Tango +Łęczna +Centralia +Fulwood +Antanambao +Ocean Acres +Eski-Nookat +Kingstowne +Kottukal +Júlio de Castilhos +Manga +Budrio +Galaat el Andeless +Mahiari +Bad Segeberg +Kurakhove +Baixa Grande +El Astillero +Pieksämäki +Bronte +Pijijiapan +Zielonka +Ţāqah +Banī Ḩasan ash Shurūq +Nazaré Paulista +Farias Brito +Bettioua +Taku +Gameleira +Sipacate +Stillorgan +Tirunāgeswaram +Sāhna +Filadelfia +Sikhio +Blindio +Serrita +Dagana +Amaraji +Kudatini +Budhni +Kishi +Shaying +Końskie +Santiago de María +Bet She’an +North Massapequa +Kiangara +Ranquitte +Griffith +Palamós +San Sebastián Tutla +Udaipura +Pelham +Plymouth +Washington +Bedēsa +Sarvestān +Taufkirchen +‘Anbarābād +Rikuzen-Takata +Oyama +Concord +Solonópole +Dapi +Oconomowoc +Quibaxi +Aldo Bonzi +Mohiuddinnagar +Steubenville +South Fayette +Warminster +Gossau +Sycamore +Vredendal +Logansport +Bhadrapur +Meishan +Tummalapenta +Redhill +Laives +Åsane +Kottapalle +Corbetta +Petawawa +Colonial Heights +Xochiatipan de Castillo +Zinvié +Starodub +Qishe +Guayama +El Achir +Heckmondwike +Bouarouss +Lavāsān +Ingá +Trujillo +Piatykhatky +Čitluk +Keskin +Heusweiler +Minamishibetsuchō +Dobrush +Pinabacdao +Yoshimi +Schofield Barracks +Palanga +Andalucía +Una +Tominian +Gangwuzhen +Portsmouth +Svilengrad +Beerse +San Pedro +Sangre Grande +Canby +Dumri +Jora Khurd +New Castle +Bourbonnais +Menasha +Łomianki +Ouankoro +Louny +Ciriè +Pottanūr +Feyẕābād +Terra Roxa d’Oeste +Barhampur +Ambiula +Raisāri +Coronda +Poulton le Fylde +Rāmpur +Convención +Polohy +Gāndarbal +Fâches-Thumesnil +Mānikpur +McAlester +Caldas de Montbuy +Pahārpur +Shorewood +Campos Belos +Mure +Niles +White Settlement +Bình Minh +Varjota +Fort Carson +Maoussa +Hybla Valley +Pavullo nel Frignano +San Vito dei Normanni +Großenhain +Borgo San Lorenzo +Kikube +Berkhampstead +Cofradía +Belterra +Dolný Kubín +Southeast +Tora +Chapelle +Antonina +General Juan Madariaga +Madalena +Heguri +Cudahy +Calenzano +Barīkot +Ghouazi +Água Azul do Norte +Kopa +East Riverdale +Arājpur +Wandsworth +Mayorga +Bobingen +Kęty +Ricaurte +Manyas +Pedra Preta +São Tiago de Custoias +Oroszlány +Fuente-Álamo de Murcia +Luganville +Ismaning +Tottiyam +Scarsdale +Bīdestān +Kottá Kalidindi +Santa Ana +Sidi Allal Tazi +Tlacoachistlahuaca +Ambāla +Libjo +Myślenice +San Vicente +Bādkulla +Spanish Lake +Middelharnis +Annakunnu +Vilavūr +Buadiposo-Buntong +Nigrán +Chodzież +Taperoá +Timri +Whitestown +Carmelo +Sunbury +Mwanza +Abangaritos +Frankenberg +Bryn Mawr-Skyway +Keszthely +Târgu Neamţ +Cristinápolis +San Pedro +Porto Novo +Schwechat +Destelbergen +Gidi +Valenza +Piossasco +Zuhres +Matigou +Koratagere +Lakshmaneswaram +Tordera +Ulao +Banbalah +Buchen in Odenwald +Tillmans Corner +Fécamp +Itaberá +Jasien +Fundão +Dumont +Campina Verde +Toyono +Marcos +Marsciano +Rwamagana +Nipomo +Soisy-sous-Montmorency +Biro +Ashtabula +Sakri +Terrell +Dbaïyé +Antsampanimahazo +Antanambe +Manampatrana +Alakamisy +Maroteza +Bemahatazana-Belobaka +Vohilengo +Amboahangibe +Mahazoma +Ambongo +Alatsinainy Ialamarina +Analaiva +Maroaloka +Belobaka +Ankofa +Matsakabanja +Ambovombe Afovoany +Tsianisiha +Beantake +Behenjy +Tranoroa +Qal‘ah-ye Zāl +General Deheza +Al Hamalah +Ad Dirāz +Doruma +Yoboki +Mickleover +Gondar +Tankāra +Ghogaon +Mahraurh +Tall Qaşab +Athār +Gorham +Kamienna Góra +Batié +Kolonodale +Serra Preta +Bombon +Tyāgadurgam +Aci Sant’Antonio +Cameron Park +Wantagh +Stony Plain +Neftegorsk +Oak Bay +Hijuelas +San Cristóbal Cucho +Ariccia +Mount Washington +Sevierville +Kosvik +Lagoa do Carro +Bourne +Cuquío +Sivagiri +Hranice +Halstenbek +Sukhsena +Rāmpur Tilak +Rājmahal +Terenure +Avtury +Kharabali +Konaklı +Dīzīcheh +Antenor Navarro +Melegnano +North Grenville +Sapeaçu +Santo Anastácio +Kegalle +Chaita +Souba +Payyannūr +Cohoes +Ptuj +Towamencin +Jadcherla +Torit +Bodegraven +Almeria +Ranzan +Koula +Bucay +Ben Daoud +Erumāpālaiyam +Barvāla +Haren +Blythe +Mūkondapalli +Doylestown +Flora +Loyalist +Stilfontein +Yeddumailāram +Falköping +Bischheim +Miyauchi +Madeley +Jiadong +Agliana +Kuchinda +Quipapá +Tres de Mayo +Manthani +Burke Centre +Cortes +Texistepeque +Ammon +Gitagum +Palmi +Olho d’Água das Cunhãs +Coltauco +Kapsabet +Shirosato +Alice +Unión de San Antonio +Roulia +Deux-Montagnes +Ituaçu +Narni +Pelaya +Pornic +Mabéhiri +Châteauneuf-les-Martigues +Khokha +Natchitoches +Franconia +Wadowice +Glenvar Heights +Manambaro +Saatlı +Nyborg +Kostrzyn nad Odrą +Mebane +Não-Me-Toque +Garches +Nguigmi +Filadélfia +Fátima +Tiffin +Zapotlán del Rey +Sint-Oedenrode +Murambi +Silvāni +Pudunagaram +Anoka +Puquio +Bafanji +Sanghera +Veldurti +Çal +Mount Eliza +Yuanquan +Munguía +Cary +Guapiara +Steiner Ranch +Gibsonton +Carmópolis de Minas +Gaoniang +Santa Cruz Naranjo +Vilāttikulam +Selma +El Bordj +Ramsbottom +Tolentino +Patar +Bay City +Segué +Vordingborg +Sa Kaeo +Pimentel +Chortiátis +Martūru +Pachmīr +Marwa +Farmington +San Kamphaeng +Cenoví +Manilva +Százhalombatta +Loay +Hidrolândia +Ourém +Forst (Lausitz) +Colne +Sangenjo +Carvin +Vissannapeta +Aci Castello +Ambohitralanana +Bekalta +Shirāli +Montanha +Pontarlier +Pôrto Grande +Édessa +Portsmouth +Sing Buri +Sidi Kada +Pataskala +Marabut +Savignano sul Rubicone +Itapiúna +Kristinehamn +Harper +San Bartolo Tutotepec +Ribera +Pelahiivka +Timbedgha +Policoro +Parede +Goshaingaon +Águas de Lindóia +Bredene +Werdohl +Paks +Yakacık +Bhīkhi +Arcore +Villa Corona +Mengjiacun +Las Heras +São Luís Gonzaga do Maranhão +Carate Brianza +Brownsville +Blaj +Freilassing +Alton +Kukmor +Mazapil +Itanhém +Oberasbach +Pariharpur +Muttenz +Steinbach +Salgar +Seyah Cheshmeh +Santa Fe +Gazantarak +Fontaine-l’Évêque +Feilding +Dhānsāria +Sobinka +Herenfa +Bagahi +Hendaye +Vennandūr +San Rafael +Jovellar +Charleston +Salaspils +Delran +Jucurutu +Ponmana +Shichigahama +Santa Elena +Godfrey +Amīnpur +San Rafael del Norte +Portchester +Idylwood +Berlín +Mankara +Mooirivier +Arakkapādi +Cordenons +Anda +Khaşab +Monthey +Dhamaun +Freudenberg +North Canton +Varvarin +Łańcut +Prachin Buri +Fanipal’ +Tall ‘Aran +Visé +Somma Lombardo +Ash Shaykhān +Agua Blanca +Lake Butler +Klaeng +Weilerswist +Willimantic +Cairu +Auerbach +Or ‘Aqiva +Troy +Lunéville +Schrobenhausen +Māḩiş +Cahokia Heights +Ostermundigen +Arco +North Aurora +Floirac +McKeesport +Eslöv +Dergaon +Douar Oulad Mbarek +Kuttālam +Chitipa +Köping +Toba +Saint-Colomban +Dianópolis +Dniprorudne +Reni +Ekazhevo +Manzanares +Kodiyēri +Nīkshahr +Liulin +Laukāha +Sapucaia +Erjie +Bad Münder am Deister +Estancia Pozo Colorado +Susner +Békés +Herzele +Rockland +Cesson-Sévigné +Ban Mae Ngon Khilek +Pirapemas +Domodossola +Hlybokaye +Live Oak +Broken Hill +Dialafara +Zalţan +Ashton +Ngora +Major Isidoro +Kharhiāl +Miramichi +Kiangan +Vettavalam +Vrede +Miaojiaping +Kalyānpur Bamaiya +Kreuzau +Flórina +Diepholz +Maripād +Palanan +Harwich +East Lampeter +Dourbali +Panórama +Bechem +Dugo Selo +Dumri +Mairi +Avion +Webster +Hope Mills +Levin +Torredembarra +South Ockendon +Moreton +Pūlla +Kitahiroshima +Southbridge +Tufanbeyli +Beni Fouda +Whittlesey +Anacortes +Duffel +Brignoles +Minquan +Biliran +El Omaria +Bad Säckingen +Jaguaripe +Vandalūr +Brenham +Yumurtalık +Pinehurst +Tohoué +Pianoro +Golitsyno +Tunapuna +Nidda +Monzón +Fern Down +Balaguer +Tábara Arriba +Fornaka +Pirapora do Bom Jesus +Kappiyara +Fanandrana +Mount Holly +Bexbach +Arsanjān +Camano +San Jose +Valluvandad +Vettikattiri +Stowbtsy +Gretna +Nelidovo +São Miguel do Tapuio +Abaré +Dingjiagouxiang +Damme +Stuart +Jacksonville +Terenos +El Carmen de Chucurí +Cerrillos +Otrokovice +Cariré +Pupri +Mānullahpatti +Siloam Springs +Woodmere +Saint-Maximin-la-Sainte-Baume +Inza +Stegen +Oborniki +Ban Mae Ka Hua Thung +Daimiel +Asarcık +Pinili +La Primavera +Limay +Eastlake +Gostynin +Lobogo +Longjia +Nakło nad Notecią +Karacasu +Yayas de Viajama +Colbún +Benito Juárez +São Francisco de Assis +Vittal +Ambolomadinika +Sokółka +San Jorge +İskilip +Sam Phran +Totoró +Omallūr +Veliko Gradište +Ubaitaba +Zhongguyue +Restrepo +Barrhead +Capua +Chedaopo +Şavşat +Tijucas do Sul +El Dorado +Storrs +Bel Air +Polyarnyy +Lousã +New Philadelphia +Pirayú +Siderno Marina +Raghunāthpur +Bakouma +Abejorral +Amacuzac +San Alejo +Herve +Boqueirão +Sigus +Arauco +Yondó +Raghunāthpur +Neder-Over-Heembeek +Bad Wildungen +Palau +Para +Marcon +Laatatra +Srbac +Manganj +Putte +Zamora +Santos Reyes Nopala +Inkollu +Eldama Ravine +Ajā +Maesteg +Saint Andrews +Chakkuvarakal +San Jorge +Žiar nad Hronom +Muḩradah +Quanzhang +Peruvanthānam +Rāyappanpatti +Zephyrhills +Krishnapuram +Cortland +Compostela +Água Branca +Aït Majdane +Trossingen +Cerca Carvajal +Boissy-Saint-Léger +Catarman +Alcochete +Rožňava +Sagrada Familia +Wayne +Piritiba +Tak +Ban Thum +Sirari +Barhampur +Kambla +Kisoro +Bistāria +Arroio Grande +Khutāha +Lemont +Clemson +Gömeç +Pālaiyam +Mawkanin +Son en Breugel +Penn +Le Pontet +Çameli +Glencoe +Punnayūr +Colchester +Morarano-Gara +Waalre +Lattes +Aliyābād +Takoma Park +Koriāpatti +Swellendam +Yeniseysk +Al ‘Ashārah +Scarborough +Etacheri +Sona +Mitake +Kempele +Vāyalpād +Oak Grove +Esperanza +Shangjing +Shanglingcun +Harinākunda +Duijiang +Kirksville +Esquimalt +Polignano a Mare +Rio Bananal +Bonnyrigg +Turuvekere +Shirva +Norcross +Mistrató +Dabas +Attimarappatti +Garching bei München +Guidan Roumdji +Boljoon +Yeşilhisar +Villorba +Matagob +Manīn +Gunjur +Krasnystaw +Quedgeley +Malacacheta +Ivanovka +Strzelce Opolskie +Rocca di Papa +St. Matthews +Sulaco +Plast +Ebino +Libertad +Elankūr +Moloacán +Tenango de Doria +Piratini +Mendes +Baxt +San Antonio de Ibarra +Eksambe +Goodlettsville +Cafelândia +Buguda +Kudavāsal +Sahel +Puerto Guzmán +Īlām +Puerto Rico +Stockach +Scott +Coalinga +Nümbrecht +Biyahmū +Ciudad Hidalgo +Karukh +Augustinópolis +Zhoujia +Bhucho Mandi +Ambatolahy +Villa Sarmiento +Croatá +Pajapan +Budva +Kushk +Urucuia +Shin-Kamigotō +South Ogden +El Reno +Fairview +Tepatlaxco +Dharampuri +Umirim +Corbélia +Vallières +Anantāvūr +Saluzzo +Pocinhos +South Venice +Phayao +Cafarnaum +Samaná +Talitay +Vladimirci +Cruz do Espírito Santo +Bluffdale +Gainesville +West Columbia +Guanagazapa +Gautampura +Morganton +Karkamb +Faléa +Marche-en-Famenne +Kiyama +Dar Chaifat +Veternik +Chamalières +Sibutao +Māndvi +Puurs +Los Lunas +Laguna Woods +Bon Air +Tasquillo +Krasnokumskoye +Rojales +Suvorov +Woodhouse +Karachev +Albino +Royston +Peçanha +Abdullahnagar +Rio Pomba +Tabernes de Valldigna +Nedugula +Lakhnaur +Rozdilna +Puerto Aysén +Pātan +Brielle +Nova Era +Nīsang +Lubang +Montemor-o-Novo +Sinzig +Reota +Forio +Bramhall +Mehrān +Kahoku +Derhachi +Seoni Chhapāra +Totutla +Remagen +Pescantina +Anosiarivo +Guaranda +Santa Lucía Milpas Altas +Nahāzāri +Cham +Kolokondé +Camocim de São Félix +Zaslawye +Loboc +Osuna +Bahon +Olivehurst +Conyers +Viradouro +Murray +New Castle +San Isidro +Colón +Calayan +Awlouz +Babenhausen +Karahia +Isola Capo Rizzuto +Buckingham +Ummannūr +Namminikara +Jhagarua +Beinasco +Fraserpet +Borda da Mata +Douétiré +Rio Claro +Yutz +Odaipatti +Międzyrzecz +Bolhrad +Jomboy Shahri +Bry-sur-Marne +Mārtahalli +Wahiawa +Bhagabānpur +Kawa +Curti +Ziracuaretiro +Pyskowice +São Domingos do Prata +Abelardo Luz +Wilton +Çat +Banni +Plungė +Mareth +Balma +Central Saanich +Solrød Strand +Villanueva del Pardillo +Mula +Louth +Néa Erythraía +Kurugodu +Santa Maria di Sala +Streetsboro +Woodcrest +Wangaratta +Gunjāpalle +Kelsterbach +Nizhnyaya Salda +Ban Song +Arpaçay +Raychikhinsk +Paoua +Holmdel +Lalībela +Mujikharf +Barhan +Sānwer +Ayacucho +Gescher +Milla’ab +Oued el Kheïr +Betio +Villa Rica +Viljandi +Glassmanor +Ketama +Bad Langensalza +Sestri Levante +Sainte-Catherine +Lumbreras +Kembhāvi +Ibrāhīmpatan +Skadovsk +Hednesford +Santa Elena +Kadogawa +Tonj +Kamudi +Valenzano +Gothini +Shumikha +Yerrapālem +Sedeh Lanjān +Padre Paraíso +Galaz +Mori +Pécel +Riva del Garda +New Amsterdam +Guardamar del Segura +Mau Dhaneshpur +Betroka +Krasnoslobodsk +Johnstown +Mudukulattūr +Matam +Mannō +Tagana-an +Dijiasuoxiang +Aïn Zaouïa +Uryzhar +Muniz Freire +El Kouif +Miharu +Suesca +Pital +Betulia +Schwarzenbek +Villiers +Mohács +Jenison +As Suqaylibīyah +Chadchan +Pohādi +Mecayapan +Otacílio Costa +Fort Thomas +Cajamarca +Schwalbach +Sierpc +Tíogollo +Maranello +Chāripāra +Almolonga +Namayingo +Dombóvár +Kanrangana +Mundo Novo +Ban Pong +Holzwickede +Sāram +Poyo +Chorhat +Krupanj +Guryevsk +Barbastro +Thorne +Fortim +Port Hope +Keota +Jawkatiā +West Lampeter +Horn-Bad Meinberg +Porciúncula +Pont-à-Celles +Kouka +Santo Antônio do Amparo +Talwandi Bhai +Brand +Toledo +Bad Münstereifel +Bethpage +Houghton Regis +Garwolin +Pollensa +Amesbury +Zébala +Osny +Baie de Henne +Lebanon +Thornton +Kukraun +Norrtälje +Mūlki +Arinos +Sengés +Sanary-sur-Mer +Kulasegaram +Moroni +Shongzhy +Hernando +Staphorst +Benavente +Dehti +Ellinikó +Maigh Nuad +Oskarshamn +Tecolotlán +Rattaphum +Rancho Mirage +San Juan Nonualco +Stanford +Baymak +Capistrano +G‘uzor +Kinel’-Cherkassy +Illizi +Venturosa +Heanor +Friern Barnet +Milton +Khānpur +Dharmāpuri +Mariakerke +Baturbāri +Laurel +North Druid Hills +Mettuppālaiyam +Stafford +Gunzenhausen +Marmande +Shelbyville +Oerlinghausen +Nadugadda +Bawgalegyi +Les Clayes-sous-Bois +Hatfield +Amarante +Inverness +Heilbad Heiligenstadt +Kangaba +Ejutla de Crespo +Jaguaretama +Cipó +Pāvumba +Abadiânia +Aurora +Resplendor +Littau +Souaflia +Minakami +Belmopan +Buford +Bendorf +Monselice +Castelfiorentino +Çukurca +Bakeshiyingcun +Martigny +Belākoba +Pisaflores +Bareggio +Clayton +Bailén +Terzigno +Avenel +Durleşti +Carnaubal +Itacarambi +Kretinga +Port-à-Piment +Marktredwitz +L’Isle-d’Abeau +Raiyam +Piera +Chouafaa +Shahritus +Carmo +Akassato +Lérida +Banabuiú +Anori +Digne-les-Bains +Danville +Badantola +Araruna +Glen Parva +Mont-Organisé +Dormentes +Flowing Wells +Sudipen +Bāţūfah +Forssa +Cherakara +Calhoun +North Decatur +Lyepyel +Trstenik +Bad Wörishofen +Bedford +Cacimba de Dentro +Jouy-le-Moutier +Padugupādu +Neerpelt +Al Ḩārah +Nederweert +Alcantara +Shek Tong Tsui +Villa Isabela +Hinsdale +Zandvoort +Guoxing +Castilleja de la Cuesta +Sumé +Conceição do Almeida +Iati +Traiguén +Cluses +Cottingham +Calnali +Bellaire +Pinewood +Massaranduba +Peka +Poção de Pedras +Tizi Rached +Sìnnai +Konstantinovsk +Itirapina +Kayaralam +Tanque Novo +Malta +Swansea +Konstancin-Jeziorna +Cássia +Tejuçuoca +Tlahuelilpan +Joaquim Gomes +Mayuge +Bom Sucesso +Sake +Settiyārpatti +Monsenhor Tabosa +Majītha +Sawankhalok +Ōi +Grumo Nevano +San Felipe +Ayinīkkād +Tricase +Clitheroe +Grenchen +Berezhany +Saguday +Firminy +Pānchgrām +Fairview Park +Kusa +Ipaba +Figline Valdarno +Graham +Frederikssund +Regeneração +Sallanches +Beckley +Peso da Régua +Banovići +Correntes +Giria +Sa‘ādat Shahr +Marsabit +Pouso Redondo +Ejea de los Caballeros +Manassas Park +Wādī Ḩalfā’ +Barrington +Ilaka Atsinanana +Easton +Ban Phe +Wang Tau Hom +South Hadley +Péruwelz +Damous +Kaukauna +San Bernardino +Groves +Kutiyāna +Manaquiri +Shoufeng +Ignacio de la Llave +Nova Pazova +Bülbülə +Yizhu +Tagounite +Dilasag +Gīnīr +Taxtako‘pir +Xintangcun +Pottasshēri +Mosbrough +Santa Magdalena +Braunau am Inn +Kolaccheri +Melfi +Oswego +Estelle +Mata Roma +San Esteban +Tādigadapa +Chandia +Lake St. Louis +Stockelsdorf +Tolūprpatti +Safety Harbor +Laç +Eutin +Elias Fausto +Usmānpur +Denville +El Segundo +Peragamanna +Sarotar +Condeixa-a-Nova +Zvenyhorodka +Gudipallipādu +San Rafael Cedros +Sibinal +Cinnaminson +Púchov +Xiulin +Svalyava +Mannukara +Āyikudi +Challapalle +Serra Dourada +Crixás +Guadarrama +Künzell +Māvalli +Upper Grand Lagoon +Turinsk +Cañon City +Tifton +Souto Soares +Gavrilov-Yam +Chuarrancho +Paulino Neves +Amfilochía +Sidi Yakoub +Tortum +Condeúba +Ramnagar +Saint-Basile-le-Grand +Kafr Zaytā +Itarantim +La Garriga +West Hempfield +Kibungan +Ruhango +Canovellas +Porteiras +Guernica y Luno +Cáqueza +Ilhota +Knemis Dades +Cheraro +Terre Neuve +Massapequa Park +Kelheim +Lons-le-Saunier +Pernamitta +Norwalk +Carlentini +Kitanakagusuku +Grójec +Bristol +Gennep +Ribeirópolis +San Miguelito +Menzelinsk +Santa María +Arıcak +Gachancipá +Addison +Sinsina +Pokrov +Bellingham +Tsararivotra +Albal +Milledgeville +Rubeho +São Simão +Piranga +Xinying +Huntington +Wadgassen +Heysham +Nāyakanhatti +Hinode +Cariús +Kamenz +Port Washington +Karratha +Macatuba +Sītāmau +Springfield +Middletown +Peñamiller +Juazeirinho +Avitanallur +Wixom +Upper Gwynedd +Pendleton +Brasnorte +Saint-Cyr-sur-Loire +Hannibal +Abington +Baaqlîne +Marosangy +Tolongoina +Etrotroka +Ilakatra +Ambila +Marofoty +Ambohitrolomahitsy +Lazarivo +Milanoa +Isoanala +Amboanjo +Befotaka +Tsarahonenana +Antanimora Atsinanana +Ankarongana +Ambondromisotra +Ambohitsimanova +Anosivelo +Manombo Atsimo +Sahamadio +Anosibe-Ifanja +Beahitse +Antsahavaribe +Ambohipihaonana +Mandritsara +Ambolidibe Atsinanana +Sadabe +Dzitbalché +Ghonchí +Yangi Mirishkor +Jāyal +Matauna +Aḑ Ḑulū‘īyah +Santo Antônio do Leverger +Hindarx +Alauli +Saint-Égrève +Peraía +Naula +Santo Tomás de Jánico +Kakraul +Tomas Oppus +Itajobi +Ban Rawai +Ambalavayal +Analanampotsy +Shankar Saraiyā +Kawai +Clayton +Sikandra +Lodwar +Oulad Amrane +Guisborough +Brunico +Bayt Ūmmar +Ulubey +Fortuna +Arai +Retiro +Srīkūrmam +San Juan Lalana +Gainesville +Andranofasika +Zarumilla +L’Ancienne-Lorette +Ibititá +Kōrōth +Aberdeen +Rāmachandrapuran +Ughara +Geddes +Serafina Corêa +Ginsheim-Gustavsburg +Viroflay +Yanggezhuang +Berga +Meltonakkal +Bishunpura +Qal’at Mgouna +Santana do Cariri +Cercola +Bou Hanifia el Hamamat +Dirba +Puerto Caimito +Kombai +Liuchuan +Mers el Kebir +Balmazújváros +Octeville +Perupālem +Acoyapa +Hohenems +Pozoblanco +Dallas +Myrtle Grove +Garagoa +Upper Saucon +Adelphi +Heber +Namysłów +Podporozhye +San José de Chiquitos +Hünfeld +Hampton Bays +Bridgeview +Ashwaubenon +Sarıoğlan +Chavara Grāmam +Boki-Wéré +Wondelgem +Kottapeta +Powder Springs +Tibau do Sul +Liuguoju +Long’e +Morriston +Aubange +Dalain Hob +Tekanpur +Eggenstein-Leopoldshafen +Guadalupe Victoria +Huruta +Baikatpur +Mālancha +Shingūchō-shingū +Carovigno +Stockerau +Governador Celso Ramos +Glace Bay +Cubellas +McKinleyville +Tobré +Galich +Alcantara +Río Bueno +Ginatilan +Kronach +Zinapécuaro +Carlópolis +Māri‘ +Fındıklı +Massé +Iziaslav +Nāranattenvanpatti +Nidgundi +Sidi Daoud +High Blantyre +Pallikapuzha +Douar Lamjaara +Rāmāyampet +Dehāqān +Laconia +Tubaran +Dazhangzicun +Dazhangzi +Dhulkot +Belle Glade +Aklanpa +Navalmoral de la Mata +Fetromby +Bruckmühl +Khed +Santa Teresa +Colonial Park +Ngara +Morteros +São João dos Poleiros +Farmingville +Vatutine +Soumagne +Vīrapāndi +Ettaiyāpuram +Mājra +New Milford +Miqiao +Heidenau +Azaourissè +Chambellan +Laferrière +Zhukovka +Ighram +Bermeo +Benešov +La Quiaca +Sada +Agaram +Boa Vista do Tupim +Annonay +Pleszew +Bédigoazon +Lamas +Ashmyany +Colesberg +Canutama +Thale +Hosakote +Marion +Le Pré-Saint-Gervais +Bambara-Maoundé +Nerang +Japaratuba +Nerviano +Pampa +Mount Vernon +Jāsk +Alfajayucan +Ban Tha Mai I +Moraga +Latifpur +Sāyarpuram +Linnei +Korem +Maltby +Rāmpur Jalālpur +Rubano +Lerum +Sliema +Pulimel +Janakkala +Bitburg +Defiance +São Pedro do Sul +Pran Buri +Finnentrop +Madanpur +Braunstone +Fiorano Modenese +Bostonia +Haslingden +Auburn +Boden +Azeffoun +Meiti +Damascus +North Hykeham +Shāhkot +Bhawānīpur +Hot Springs Village +Aïn Feka +Xixinzhuangzhen +Belaya Glina +Vallegrande +Wittenberge +Lillerød +Acharipallam +Devizes +Tsuiki +Hrubieszów +Trzcianka +Montceau-les-Mines +Saltash +Vechūr +Mattoon +Upper Chichester +Washougal +Haslemere +Achaljāmu +Ratba +Orăştie +Brixham +Yabuki +Salinas de Hidalgo +Gemert +Bhainsoda +Makīnsk +Asten +Dongjiangshui +Saint Ives +Kadikkād +Iglino +Long Beach +Sidi Lamine +Bad Lippspringe +Vazhani +Baronissi +Minamichita +Daireaux +Altıntaş +Kodikulam +Wyckoff +Cerea +Keetmanshoop +Rijen +Busolwe +Druzhba +Maroochydore +Astara +Montornés del Vallés +Beinan +Ambarès-et-Lagrave +Sinūnī +Kaliro +Puliyankunnu +Marib +San Julián +Famy +Sierre +Roxana +Kāmavarapukota +Weehawken +San Roque +Cestas +Tromsdalen +San Francisco +São Paulo do Potengi +Fazakerley +El Rosario +Sudak +Batuco +Kauhava +Truckee +Orta Nova +Pionki +Villeneuve-Loubet +Tsundupalle +Solothurn +Palmetto Estates +Říčany +Windlesham +Vila Bela da Santíssima Trindade +Latsia +Buntok +Sunland Park +Ouaouzgane +Posoltega +Connahs Quay +’Aïn Abessa +Masamagrell +Maşīf Sarsink +Dhobauli +Bāuria +Puerto Carreño +Humacao +Attappampatti +Eğirdir +Havelock +Yağlıdere +Young +El Piñón +Nandigaon +Bovisio Masciago +Djouab +San Miguel de Salcedo +Maardu +Chiva +Swift Current +Campo do Brito +Chestnuthill +Kadod +Nuevo San Juan Parangaricutiro +Shahbā +Königstein im Taunus +Thandla +Kushima +Santa Lucía +Donna +New Port Richey +Chinampa de Gorostiza +Água Clara +Vimodrone +Centerville +Ribat Al Khayr +Bytów +Diksmuide +Arakkal +Yerbas Buenas +Preganziol +Plumstead +Livinjipuram +Bürstadt +Sobrado de Paiva +Leixlip +Boysun +Dēra +Tengampudūr +Bek’ojī +Kings Park +Penzberg +Takhatgarh +Sendurai +Roche-à-Bateau +Hīrna +Katsuura +Ponte de Sôr +Băicoi +Holzkirchen +Bredbury +Chalāla +Konodimini +Kukës +Iluppur +Fuying +Fuyingzicun +Dour +Kodumudi +Glanerbrug +Klippansbruk +Vincennes +Aston +La Vista +Cabeceiras de Basto +Novomichurinsk +Pisticci +Firestone +Richmond Hill +Povorino +Saalfelden am Steinernen Meer +Kattiyeri +Gikongoro +Balighattam +Westchester +Pôrto Acre +Gonegandla +Ban Wang Nok Aen +Verdun +Pazhayannūr +Pochëp +Piriyāpatna +Jilotepec +East Greenbush +Jalpa de Méndez +Saran +Nässjö +Rotselaar +Erumād +Harborcreek +São Vicente Férrer +Hāvi Bhauār +Holly Springs +La Cruz +Zafra +Murraysville +Deoria +Ocho Rios +Néa Mákri +Châteaurenard +Wellington +Ferndale +Phrae +Kundal +Campagna +Murehwa +São Caetano de Odivelas +Zequ +Banstead +Kumage +Riemst +Przasnysz +Podalakūr +Federación +Bassum +Kruibeke +Hueytown +Kakkalapalle +Madrid +Whickham +Beaver Dam +Agourai +Loxstedt +Zveçan +Berber +Grangemouth +Arani +Sidi Ettiji +Bogatynia +Tāwargeri +Araçagi +Ban Na Sai +Calera +Khirhar +Keynsham +Barangka +Itapiranga +Shiraoi +Lake Mary +Ittiva +Xiaolongtan +Salitre +Glenmont +Millbrook +Mullānwāla +Tadaoka-higashi +Seeheim-Jugenheim +Red Wing +Añisoc +Tantéga +Tiahounkossi +San Isidro +Medicina +Epitacio Huerta +Cleckheaton +Pratteln +Micoud +Bull Run +Brod +Douar Tabouda +El Escorial +La Algaba +Valu lui Traian +Itororó +Shpola +Piquet Carneiro +Ad Dīs +Bánovce nad Bebravou +Leopoldshöhe +Wurzen +Bariārpur +Clearlake +Mariestad +Sedan +Bargūr +Poreč +Zirara +Ceadîr-Lunga +Noordwijkerhout +Shek Wai Kok +Khaniādhāna +Ibipeba +Mangueirinha +Marienberg +Reinheim +Lomas de Sargentillo +Getúlio Vargas +Morton +Kaatsheuvel +Macetown +Burbaliq +Dilijan +The Mumbles +Pannaipuram +Tukums +Mauguio +Three Lakes +Rio Linda +Saint-Jean-de-la-Ruelle +San Juan Bautista +Soumpi +Wailuku +Bijni +Xinyuan +Puerto El Triunfo +Buritama +Cidreira +N’Goussa +Country Club Hills +Łask +Īlkhchī +Īlkhechī +La Sierpe +Mohan Eghu +Ippy +San Giovanni Valdarno +Pembroke +Heumen +Barkot +Warrington +Pirque +Eppelborn +Lille +Miyazu +Tongluo +Paragaticherla +Humble +Menomonie +Lakhipur +Bhai Rupa +Plácido de Castro +Mensora +Cabaceiras do Paraguaçu +Ina +Guaymate +Slaný +Seltso +Itaquitinga +Domchānch +Indiaroba +Coaraci +Santa Maria das Barreiras +Ramón Santana +Hønefoss +West Richland +Middelfart +Tichi +Sujina +Regenstauf +Cattolica +Wentang +Raunheim +Kade +Odumase +Tamallalt +Bogucice +Ada +Parali +Mangrauni +Segbwema +Batán +Marly-le-Roi +Vero Beach +Ahmetli +Ledeberg +Liangyi +Ban Cho Ho +Bayat +Rentachintala +Thị Trấn Ngải Giao +Hövelhof +Brackenheim +Madison +Mapiri +Santa María Petapa +San Estanislao +Puerto Pilón +Pedregulho +Gussago +Horodok +Torre Maggiore +Sunagawa +Uchkeken +Caiapônia +Cassano al Ionio +Thompson +Ciudad Guadalupe Victoria +Haji Shah +Berezan +Langrucun +Espartinas +Sant’Elpidio a Mare +Chinde +Al Ghāţ +Qarqīn +Qusar +Cowley +Pilāppulli +Mudakkiraye +East Highland Park +Amba Icharua +Alpignano +Ukiah +Słubice +Fléron +Shintomi +Adelfia +Zapotlán de Juárez +La Paz +Jinjicun +Jinji +Tafresh +Hebburn +Linbian +Ashby de la Zouch +Milanówek +Ham Lake +Chorbogh +Jasper +Grimari +Bobangui +Kalundborg +Rāsivarai Tottam +Reggello +Antanambao Mahatsara +Ervādi +Braniewo +Rājbalhāi +Hillcrest Heights +Warsaw +Sabotsy +Ban Lam Narai +Barbacoas +Enfield Lock +Ōyodo +Fairburn +Escoublac +Mifune +Dighaun +Ujre +Ban Nong Han +Kirchhain +Dahibhāt Mādhopur +Loma Plata +Kilwinning +Chopadandi +Mohanūr +Mannūr +San Casciano in Val di Pesa +Lake Wales +Fillmore +Les Herbiers +Ojus +Wardenburg +Nanbu +Tōhoku +Taylor +Batalha +Anorí +Sakardih +Encruzilhada +Churriana de la Vega +Glenn Heights +Albemarle +Kozelsk +Katosi +Nakanoto +Piancó +Charqueada +Ciney +Cayetano Germosén +Bordj Mokhtar +Edmundston +Cloverly +Hannut +Greenville +Gurh +Lufeng +Rājnagar +Auburndale +Pupiales +Altena +Rawa Mazowiecka +Belén +Bilohirsk +Vedelago +Gasparillo +Neópolis +Bykhaw +Boshrūyeh +Pearl River +San Miguel +Pelhřimov +Kierspe +Aberdeen +Peer +Adjahomé +Batangafo +Burgdorf +Goulmima +Ambohimanambola +Curacautín +Nilaiyūr +Spanish Springs +Franklin +Hilltown +Westbury +Lugu +Cajari +Hanover +Uherský Brod +Petersberg +Kirsanov +Islām Qal‘ah +Portachuelo +Baro +Dyer +Pudu +Poing +Rāikal +Kurtamysh +Mastchoh +Belém +Vienna +Ntungamo +Las Cabezas de San Juan +Pocking +Dentsville +Bosobolo +Toro +Pamiers +Hatti +Mahesh Khunt +Passa Quatro +Kastoriá +Freienbach +Kesath +Faxinal +Gokavaram +Tahlequah +Outat Oulad Al Haj +Poço Fundo +Nova Resende +Hollins +Middletown +Libiąż +Karema +Bou Hadjar +Stone +Khargāpur +Khirpai +Puan +Zhongzai +Radford +Taohongpozhen +Malnate +Divriği +Caridade +Panukulan +Pasaquina +Brakel +Hude +Aki +Moreau +Angara-Débou +Kingsborough +Žitorađa +Kirchlengern +Barra de Santo Antônio +Straelen +Denby Dale +Phirangipuram +Erba +San Juan +Guben +Ubrique +Payson +Sebt Aït Saghiouchen +East Longmeadow +Mercedes +Juchique de Ferrer +Arteche +Bagnacavallo +Fairview Heights +Fujioka +Bangor +Fullerton +Jussara +Usgao +Nunna +Mahālandi +Chettināyakkanpatti +Cosautlán +Jambaló +Sulzbach +Nova Olímpia +North Arlington +Rolleston +Bārnia +Moussoro +Central +Chinácota +Wemmel +Halver +Ban Thung Tam Sao +Gālivedu +Kakching +Großostheim +Arenys de Mar +Hương Canh +Bad Essen +Novoukrainka +Kargil +Grosse Pointe Woods +Vadugappatti +Villa San José +Piru +Çarşıbaşı +La Falda +Ouled Chebel +Crawfordsville +Sahatavy +Muscle Shoals +Erwitte +Baipingshan +Mount Dora +Westport +Sunnyside +Sananduva +Shuzenji +Bree +Yoshinogari +Tiverton +Elsen +Bandar Murcaayo +Guelendeng +Srbobran +Wallisellen +Poplar Bluff +Yuvileine +Xianxi +Changji +Khunti Dhanaili +Northbridge +Bargteheide +Schmelz +Douglas +Moroto +Lyantonde +Leinì +Birstall +Noniyā +Umbertide +Fort Drum +Shuili +Tremedal +Shahriston +Kodala +Novoanninskiy +Merchtem +Hampton +Arachchalūr +Sohtha +Mālhīpur +Bacuri +’Ayn Bni Mathar +Acarape +Barharwa Kalān +Buffalo +Welby +São Francisco do Guaporé +Birsinghpur +Wiefelstede +Dungannon +Colle Salvetti +Yorkton +Zumarraga +Raposos +Kabo +Omalūr +Center Point +Carcarañá +Utinga +Domoni +Kassorola +Nawnghkio +Berriche +Ripon +San Dionisio +Queensbury +Madukkūr +Ivanava +Sabana de La Mar +Nobsa +General Villegas +Martinsicuro +Simaria +Al Laţāminah +San Antonio Oeste +Acahay +Momil +Brus +Yotoco +Taishachō-kizukikita +Jagdispur +Oyten +Wendlingen am Neckar +Kasumi +Antsahanoro +Goundam +Radzionków Nowy +Ispica +Bad Bentheim +Naama +Ambalabe +Llanquihue +Benjamín Aceval +Montalvo +Éghezée +Bikou +Az Zaydīyah +Jalālpur +Glen Allen +Carhué +Santomera +Ransiki +Progreso +Târgu Secuiesc +Manamelkudi +Bālasamudram +Parkway +Cherān +Khirbat Ghazālah +Longchang +Spárti +Stepney +Massakory +Mukhtārpur Salkani +Kota +Fiano Romano +Artesia +Bethlehem +Garou +Tadikalapūdi +San Martino Buon Albergo +Chickasha +Opa-locka +Künzelsau +Restrepo +South Middleton +El Peñol +Giaveno +Oteapan +Orimattila +Palma Campania +Yunshan +Neratovice +Turgutalp +Ōyamazaki +Freiberg am Neckar +Hermitage +Kabugao +Cotorra +Ikast +Hajdúnánás +Vitthalāpuram +Petrovsk-Zabaykal’skiy +Çaykara +Aranyaprathet +Lemay +Jičín +Al Ḩībah +Walnut Park +Basford +Landerneau +eMuziwezinto +Rožnov pod Radhoštěm +Burrillville +Singhwara +Santa Anita +Altinópolis +Stahnsdorf +Porumāmilla +Šilutė +Do‘stobod +Vodil +Handlová +San Pedro de Lloc +Xiangjiaba +Gokarna +Taree +Khutauna +Saraikela +Izamal +Nakhon Nayok +Ansfelden +Brzesko +Stallings +Kozienice +Bandora +Hostomel +Roşu +Mastic Beach +Bīleh Savār +Kanhauli Manohar +Svitavy +Tocantins +Ampahimanga +Alegria +Attūr +Berea +Itāhri +Aruvāpalam +Griffith +Castellaneta +Harenkarspel +Köprüköy +Chotāla +Alsfeld +Riversdale +Aguadulce +Ségoubougou +Ganeshpur +Monte Carmelo +West Norriton +As Sukhnah +Chorfa +Readington +Ocean Pointe +Timezgana +Huarmey +Dyersburg +South Houston +Banora Point +Kotoura +Hibbing +Talsint +River Falls +Bingawan +Four Corners +Parma +Al Qbab +Baharu +Pujilí +Rāmnagar +Schlüchtern +Alcañiz +Guérande +Milford +Caldera +Pielisjärvi +Loimaa +Āgiripalle +Troutdale +Bni Tajjit +Babayurt +Westwood +Al Awjām +Ban Kao +Sikeston +Rygge +Castenaso +Sayville +Venustiano Carranza +Voss +Kittūr +Tyldesley +Caravaggio +Springfield +Sylvan Lake +Mafuné +Carlet +Upala +Santa Cruz Muluá +Zegzel +East Barnet +Port-de-Bouc +Easthampton +Forks +La Grange +Cêrro Azul +Jaypul +Los Muermos +Markranstädt +Quarteira +Noale +Bang Phae +Upton +’Aïn Babouche +Douar Azla +La Grange +Yeni Suraxanı +Buckley +Jakkampālaiyam +Chennūr +Ranong +Ségou +Bumpe +Rustampur +Simcoe +Math Lohiyār +Ustroń +Kāmayakkavundanpatti +Subachoque +Kodinsk +Jacupiranga +Sultānābād +Kujwa +Parrita +Ambarakaraka +Gubin +Balş +Jalālābād +Medjana +Ubatã +Chaona +Cherukunnu +Khusropur +Saraland +Tarqui +El Ach +Diabigué +Masmouda +Frogn +Pilkha +Bakarpur Ogairah +Nonantola +Bovolone +Prinzapolka +Canudos +Kajur +Nowogard +Sūrappalli +Panajachel +Chinggil +Birhana +Michelstadt +Hazro +Nyahanga +Anantapalle +Ripon +Ait Yaazem +Chai Prakan +Johnstone +Wendelstein +Aurāhi +Aquitania +Bellevue +Horodok +Ottūr +Bouchabel +Viškovo +Fatipura +Ottakkadai +Brüggen +South River +Seymour +Banigbé +Şemdinli +Großenkneten +Kollūru +Rāmewādi +Owase +Santiago Tulantepec +Wohlen +Domont +Mecheraa Asfa +Shāhpur +Olecko +Tankal +Federal +Dalachi +Kalanjūr +Eloy +Quiindy +Bhiloda +Hüyük +Middle Smithfield +Léré +Yaojia +Makhu +Czernica +Fartura +Punta Umbría +Vontimitta +Safo +Sultonobod +Tachiarai +Mount Pleasant +Montbrison +Bādshāhpur +Baléyara +Sulechów +Sérarou +Mikkabi +Ukrainka +Strathroy +Ayyampālaiyam +Darién +Marbach am Neckar +Mārupe +North Fayette +Dickson +Gardendale +Ágios Ioánnis Réntis +Bni Quolla +Grovetown +Stone Ridge +Sivapuram +Lady Lake +Bay Village +Telfs +Al Ḩazm +Mayilūr +Scordia +Ranohira +Duxbury +Tourlaville +Agudo +Penugonda +Fort Mohave +Qarabulaq +Vauréal +Hewitt +Sulphur Springs +Eilenburg +Worcester Park +Bou Djeniba +Doğanhisar +Mahavelona +Kāyanna +Samarate +Mountain Home +Ciudad de Huitzuco +Az Zintān +Cajueiro +Preetz +Azalea Park +Zeulenroda +Americus +Lithia Springs +Qazyan +Grandville +Rāhon +Marahōm +Khat Azakane +Kasli +Giruá +Ya‘bad +Locarno +Aue +Myrza-Ake +Bracebridge +Santa Ana +Fort Hunt +Sátiro Dias +Orsay +Rāni Shakarpura +Sapatgrām +Rylsk +Utnūr +Türkeli +Blanquefort +Kumaranallūr +Exeter +Sidi Azzouz +El Rosario +Degtyarsk +Höganäs +Sughrāin +Summerside +Bethulie +Tsiningia +Antindra +Andapafito +Vohilengo +Manompana +Bevonotra +Betanty +Mandrosonoro +Ankazondandy +Androrangavola +Fiadanana +Alarobia +Inanantonana +Ambalatany +Andemaka +Vohiposa +Anjangoveratra +Leanja +Fenoarivo +Fenoarivo +Bekitro +Ambohibe +Tangainony +Antsenavolo +Analila +Mangabe +Baltit +Tullinge +Kafia Kingi +Manafwa +Buwama +Sardoba +Ishtixon Shahri +Mông Dương +Longji +Koulamoutou +Asāra +Dandu Mailāram +Al Mazār ash Shamālī +Wātrāp +Illingen +Rumilly +Chilgazí +Weener +Zemrane +Neriyamangalam +Dêngka +Dianga +Üsharal +Caidat Sidi Boubker El Haj +Youngsville +Canmore +East Finchley +Ambohimalaza +Guioyo +Lewes +Nanāttupārai +San Cesareo +The Dalles +Washington +Tasīl +Füssen +Rāiganj Bāzār +Ḩammām al ‘Alīl +Dublin +Bathurst +Kamyzyak +Chornobaivka +Yaypan +São Lourenço da Serra +St. Simons +Vicente Guerrero +Balneário do Rincão +Saint-Amand-les-Eaux +Jāwalgeri +Kerman +Saint-Leu-la-Forêt +Kizhūr +Kudali +Cruz Machado +Ouamri +Antadinga +Clarksburg +Frankfort +Este +Barysh +Yurihama +Chittayankottai +Neykkārappatti +Mwingi +Erlensee +Finsterwalde +Hayange +Tuineje +Chertsey +Sukth +Valavakāttumūla +Obra +Mohanpur +Amarwāra +Ambohidrapeto +Bahutāl +Landen +Zhytkavichy +Kyabé +Chivolo +Viera West +Ghomrassen +Gentbrugge +L’Oulja +Pātapatnam +Elbeuf +Tagazhi +Ishidoriyachō-eso +Motru +Ras el Oued +Mandiakui +Coos Bay +South Hayling +Fontainebleau +Valeggio sul Mincio +Tarquinia +Marco Island +Talitsa +Süchteln +Despujols +Summerfield +Alotau +Androy +Stará Ľubovňa +Hongsi +Brahmadesam +Bellmore +Alabat +Schwarzenberg +Campanha +Manatanna +Codru +Königslutter am Elm +Gargždai +Aporá +Sertanópolis +Xiaqiaotou +Băileşti +Bikin +Penicuik +Râşnov +Plavsk +Cumaru +Comarapa +Middleburg Heights +Dunaivtsi +Verneuil-sur-Seine +Ban Dung +Karambakkudi +Lakamané +Petite-Synthe +Adwick le Street +Alpine +Quixelô +Saint-Pierre-des-Corps +Vlagtwedde +Paso de Carrasco +Sāyalkudi +Suchindram +Nyasvizh +Hayes +Alexándreia +San Giovanni in Fiore +Kuršumlija +Lewiston +Calbuco +Brooklyn Park +Marmeleiro +Lower Salford +Schaesberg +Fremont +Heggadadevankote +Fairhaven +Haddada +Aladağ +Piaçabuçu +Bastogne +Ostrov +Zunil +Sint-Kruis +Eilendorf +Walldorf +Floral Park +Greater Napanee +Barentu +Cerejeiras +Luzhou +Skvyra +Ivdel +Turffontein +Vijayapuri North +Quezon +Wadern +Gheorgheni +Addlestone +Vellikulangara +Highland Village +Lam Luk Ka +Dighirpār +Sertã +Concorezzo +Benetúser +Mahires +Esquipulas +Davutlar +Brusciano +Kulhudhuffushi +Beek +Drensteinfurt +Kishundāspur +Warren +Katav-Ivanovsk +Udayagiri +Tapejara +Galván +Bar +Sidi Allal el Bahraoui +Alvarães +Villalbilla +Gryfice +Codroipo +Mario Campos +Prospect Heights +Nidiyanga +Vári +Tupi Paulista +Baghlia +Hammam M’Baïls +Demerval Lobão +Seaford +Valabhīpur +Toma +Sahambala +Jamestown +Toul +Dembeni +Gatesville +Lonigo +Tamazouzt +Xiaozhengzhuang +Pawai +Indianola +La Lucila +Bonito +Osowa +Jataúba +Gandevi +Brofodoumé +Chhapra Bahās +Simmerath +Saint-Julien-en-Genevois +Dassari +Borodino +Taromske +Odaiyakulam +Overland +Bruck an der Mur +Vatomandry +Mandialaza +Hadjadj +Kavarna +Feke +Rypin +Le Pecq +Hugo +Międzyrzec Podlaski +Zhutian +Elkton +Dhusar Tikāpatti +Srīmushnam +Seven Oaks +Kodikkulam +Vallirana +Kadamakudi +Harlingen +Ascheberg +Kalininsk +Ban Samo Khae +Port Orchard +Rutland +Tlaltetela +Santa Rosa +Tapiramutá +Pewaukee +Lake Country +Colônia Leopoldina +Taucha +Ropczyce +Grottammare +Tanakpur +Saviano +Opelousas +João Neiva +Kallūr +Kabayan +Mamadysh +Ash Shaddādah +Kumano +Batalha +Serinyol +Niceville +Haftkel +Cadoneghe +Lentate sul Seveso +Altay +Ixhuatlán del Sureste +Adrasmon +Maliana +Cholai +Tarancón +Victor +Whakatane +Diang +Breisach am Rhein +Salonta +Pūluvappatti +Dhāni Sukhan +Centre de Flacq +Antrim +Belaur +Kunithala +Longmeadow +Dhūmnagar +Westbury +Vardannāpet +Fatehpur +Ōarai +Krapkowice +Palagiano +Waterville +Shāhpura +Palagonia +Altopascio +Kāndla Port +Chethakal +Mahudha +Ras El Oued +San Bartolomé Jocotenango +Macedo de Cavaleiros +Yorito +Rahden +Lara +Ouadhia +Aïn Mediouna +Ramada +Kovdor +Miguelturra +Laurentides +Windham +Goubellat +Garrel +Novo Airão +Gonohe +Kannampālaiyam +Al Mu‘abbadah +Pijiño del Carmen +Mansingha +Sulat +Akambādam +Kalanādu +Rūpbās +Dolores +Kasimkota +Uusikaupunki +San Antonio Palopó +Vieux Fort +Patton +Diafarabé +Vendôme +Iporã +Hennebont +Sonāpur +Herisau +Ardestān +Quimavango +General Pinedo +Northallerton +Titel +Thibodaux +Sered’ +Itatim +Susanville +Wildwood +Santa Juliana +Mirangaba +Hanover +Lindås +Trisshilēri +Usuda +Toyoyama +Hille +Correia Pinto +Guasca +Puduppatti +Minamiminowa +Lübbenau/Spreewald +Lymington +Carugate +Live Oak +Orizona +La Montañita +Dūbacherla +Whitewater +Vynnyky +Campina da Lagoa +Baeza +Lynden +Ribnitz-Damgarten +North Strabane +San Jacinto Amilpas +Zulte +Tarūr +Maruim +Langenberg +Eravattūr +Newberry +Bharanikāvu Tekku +Wolf Trap +Coelemu +Mennecy +Sāhar +Steffisburg +Castillo +Morges +Mwinilunga +Pochampalli +Hayden +North Whitehall +Southern Pines +Kimwanyi +Beko +Dieburg +Taima +Hilvarenbeek +Weston +Niepołomice +Ebersbach an der Fils +Newton +Si Satchanalai +Turkaguda +Damdama +Grain Valley +Buçimas +Beernem +Noto +Aabenraa +Xixucun +’Aïn el Arbaa +Todi +Ifanadiana +Azzano Decimo +San Miguel +Zhirnovsk +Beaucaire +Carterton +Nova Brasilândia d’Oeste +Mount Clemens +Binningen +Yakumo +Tīrān +Copparo +Dhanot +Renai +Melonguane +Namala Guimbala +Bayt Saḩam +Hedongcun +Hartford +Bububu +Novouzensk +Ponders End +Ince-in-Makerfield +Tsukumiura +Colorado do Oeste +Gaillac +Wenwu +Valmontone +Bhit Bhagwānpur +Kājha +Dhemāji +Soavina +La Cruz +Mitchell +Mecitözü +Schiffweiler +Marivorahona +Ərkivan +Mindelheim +Shchuchyn +Ochiai +Zaṟah Sharan +Ban Tha Pho +Northborough +Le Vésinet +Mvurwi +Bengonbeyene +Mezőtúr +Bālkonda +Nioro du Rip +Câmpulung Moldovenesc +Ostroh +Chenlu +Baile an Bhiataigh +Donacarney +Yazu +Capilla de Guadalupe +Porthcawl +Leso +Chubbuck +Molinella +Jiaojiazhuang +Toui +Manūjān +Langenau +Rājāpur +Coto de Caza +Nailsea +Manjīl +Bolotnoye +Boudjima +Longwood +Guinguinéo +Dammāj +Palmitos +Leopoldsburg +Langenthal +Loma de Cabrera +Serpa +Puttalam +Mayoyao +Ashikita +Cheramkod +Solapuram +Pallappatti +Sukhothai +Porto San Giorgio +Tōbetsu +Drăgăşani +Boppard +Kara-Kulja +Frecheirinha +Fort Leonard Wood +Tatahuicapan +Rakvere +Oswestry +Jurāwanpur Karāri +Olmué +Dewangarh +Mangqu +Mölnlycke +Narendrapatnam +Kolakalūru +Antarvedi +Anadyr +Sin-le-Noble +Calumpang +Lucé +Chembagarāmanpudūr +Bilpura +Porto Empedocle +Templin +Ermúa +Julita +Shively +Cumru +Ponsacco +Mouiat Ouennsa +Sundarpur +Crusinallo +Dalanping +Epe +Shizukuishi +Mezőkövesd +Bhagta +Bhagwāngola +Galliate +Pozos +Princeton Meadows +Red Hill +Baynāla +Akdepe +Maullín +Najasa +Zevio +Muhammadābād +Sebt Bni Smith +Cosío +Ban Pang Mu +São Pedro do Sul +Kadaiyam +Belo +Kompalle +Rakovník +Chamgardān +Yığılca +Dixon +Southchase +Cochoapa el Grande +Ernagūdem +Juma Shahri +Ipuã +Kasagi +San Miguel Dueñas +Tung Tau Tsuen +Miyota +Vatlūru +Pequannock +Canapi +Swinton +Bad Neustadt +Frei Paulo +Eppelheim +El Chal +Edakkazhiyūr +Puerto Pimentel +Kežmarok +Machang +Jasol +New Haven +West Ham +Einsiedeln +Chittūr +Sāligrāma +Agrate Brianza +Svetogorsk +Santa Cecília +Ponnamarāvati +Qaryat Sulūq +Scottsboro +La Roda +Ayaş +Mỹ Lương +Palhālan +Shimanto +Codogno +Sovetsk +Greenwood Village +Rakhiv +Souagui +Kukkundūr +Sānātikri +Kumaralingam +Bissegem +Bituruna +Tidjikja +Anār +Kyazanga +Wattignies +Nannestad +Wanda +North Reading +Itariri +Barod +Lwengo +Igaporã +Sainte-Luce-sur-Loire +Bredasdorp +Glória +Dastgerd +Los Osos +Rendon +La Palma +Aleg +El Palmar +Hofgeismar +Edineţ +Matlock +Bokoro +Kučevo +Diapaga +Lahoysk +Certaldo +Ebn Ziad +Aldine +Lezhë +Palanisettipatti +Batavia +Sayō +Sirāli +Meghauna +Morteẕá Gerd +Zhuolan +Teodoro Schmidt +Saffron Walden +Rossville +Kifosso +Bŭston +Cherryland +Pipra Latīf +Kanan +Zelenogradsk +Nobres +Pudtol +Patilār +Daigo +Carthage +White Oak +Kurāwar +Banqiao +Asthānwān +Casalpusterlengo +Vemuladīvi +Maurānwān +Montijo +Dejen +Shipley +Linguère +Ain el Hadid +Ternat +Todmorden +Skhour Rehamna +Tizi-n-Tleta +Tiszaújváros +White Center +Overpelt +Funyan Bīra +Maskanah +Verkhnodniprovsk +Pichhor +Lajkovac +Seekonk +Nkouraba +Budakeszi +Isorana +Ambaguio +Moreni +Skalica +Ban Nong Kathao +Fos-sur-Mer +Hiệp Hòa +Traverse City +Mainburg +Sabana Grande de Palenque +Corbera de Llobregat +Sarai Jattān +Amboavory +Sagala +Baiceng +Neustadt in Holstein +Kyzyl-Suu +Ban Duea +Altunhisar +Noisiel +Guipavas +Andover +Udala +Solec Kujawski +Panorama +Greeneville +Yeşilova +Montivilliers +Differdange +Sandhausen +Turhāpatti +Csongrád +Phulaut +Bilgi +Pianezza +Rosário Oeste +Stapleford +Soliera +Kinna +Mitrapur +Weybridge +Chilamattūru +Madera +Ilovaisk +Kestel +Ventaquemada +Taperoá +Santa Cruz de la Palma +Knaresborough +Kambadūru +Bemidji +Romit +Broxburn +Al Hammam +Arumbāvūr +Bois-d’Arcy +Cipanas +Uthai Thani +Jiblah +Ezzhiliga +Anazzou +Estrela de Alagoas +Dilārpur +Concepción +Nedumudi +Northview +Gehrden +Jamālpur +Ala-Buka +Dacheng +Nymburk +Nuth +Tarascon +Manohisoa +Yankton +Saint-Rambert +Odanāvattam +Vipparla +Machelen +Khao Yoi +Efkarpía +Buggānipalle +Bruntál +Dayton +Clark +Hartselle +Tari +Spittal an der Drau +Robbinsville +Tururu +Corinto +Nancagua +Ezine +Blomberg +Sorrento +Kérouané +Dison +Messias +Glasgow +Żabbar +Meco +Berea +Chokkanāthapuram +Potenza Picena +Grimes +Andrakata +Khampat +Siladon +Sodāg +Lāl Khatangā +Khijri +Nova Olinda +Malhada +Patos +Landázuri +Villa del Rosario +Besana in Brianza +Jackson +Tendrara +Jamao al Norte +Seacombe +Aç-çahrij +Magdiwang +Kürdəmir +Ostashkov +Butiama +Fortuna +Ambongamarina +Ban Khek Noi +Jelcz-Laskowice +Samsikāpuram +Bradley +Raspur Patasia +Fraga +Strzegom +Gopālnagar +Ayutla de los Libres +Robinson +San Policarpo +Homosassa Springs +Cruzília +Discovery Bay +Victoria +Putaendo +Silvi Paese +Thoen +Baildon +Kot Bhāi +Mortara +Krasnovishersk +Trélazé +Talaināyar Agrahāram +Lopare +Kocaköy +Urandi +Rājgaḍh +Frattaminore +Genappe +Tanhuato de Guerrero +Mátészalka +Sava +Vişeu de Sus +Eden +Dvůr Králové nad Labem +Anao-aon +San Luis del Palmar +Clinton +Kumaramputtūr +Bambous +Amatitán +Moul El Bergui +Alta +Uvalde +Bunnik +Manor +Castro Daire +Eldorado +Perivale +Semra +Bennington +Bar +Kanegasaki +Gomboussougou +Daisen +Abaza +Chhājli +Winkler +Chaltyr +Isrāin Kalān +Khamir +Evans +Fruitville +Bad Bramstedt +Haddon +Ratekau +Basārh +Jupi +Maddikera +Odenthal +Amānganj +Undi +Villa Paranacito +Bandar-e Khamīr +Inhuma +Wombwell +São João Evangelista +Burbach +Pihra +Maydolong +Atalaia do Norte +Stanley +Bankheri +Llantrisant +Veys +White +Poronaysk +Itajibá +Mottola +Bhānumukkala +Guerouma +Franklin Park +Belchertown +Broxbourne +Dudhgaon +Uiraúna +Andicun +Elandakuttai +Nagasu +Tenafly +Ladson +Harper Woods +Guamaré +Vennesla +Medrissa +Belāri +Shchigry +Erongarícuaro +Norridge +Shāl +Chaparral +Lagoa da Confusão +Yenice +Maryborough +Clausthal-Zellerfeld +Santa Úrsula +Saint-Charles-Borromée +Chilcuautla +Tēkkampatti +Mātar +Mantua +Lyss +Sidi Ghiles +Yaransk +Atyrá +Ulladulla +Cunit +Sippola +Shedbal +Palmer Ranch +Galanta +Kālikāpur +Motiong +Pereiro +Chemini +Boumahra Ahmed +Peddaboddepalle +Sāhpur +Yasnogorsk +Udayendram +Es Sebt +Vincent +Aïn Jemaa +Beldānga +Privolzhsk +Yasnyy +San Rafael Arriba +Wittenheim +Mangawān +Rātan +Dawlish +Shimohata +Rio Grande City +Puréparo de Echaíz +Project Six +Senlis +Nonkon +Ober-Ramstadt +Penacova +Ovruch +Coulommiers +Boksitogorsk +Bouc-Bel-Air +Vail +Civita Castellana +Volpiano +Springdale +Kinross +Castellarano +Dengshangcun +Palmview +Asbury Park +Pichucalco +Libagon +Featherstone +Mexborough +Melissa +Glenn Dale +Tazert +Anosy Avaratra +La Solana +Marui +Kriel +Aramil +Bétérou +Itanhandu +Metković +Wilmington Island +Kanding +Pimpalgaon Rājā +Mulakaledu +Cowansville +Conchas +Upper Southampton +Johnson City +Rochedale +Billapādu +Vieiro +Neston +Sainte-Anne-des-Plaines +Avsallar +Pinhalzinho +Chervonopartyzansk +Támesis +Charām +Bidston +Rive-de-Gier +Vammala +Bunkeflostrand +Capurso +Shangtianba +Musāpur +Saint-Brice-sous-Forêt +Humayingcun +Macomb +Sumidouro +Phillipsburg +Souk Et-Tleta des Oulad Hamdane +Ljungby +Aravakkurichchi +Tirhassaline +La Apartada +Francheville +Château-Thierry +Barrocas +Česká Třebová +Salesópolis +Monroe +Huasca de Ocampo +Arnedo +Chelsea +Zubin Potok +Hallstahammar +Gagarin Shahri +Northenden +Pyāpali +Kumiyama +Davidson +Chinsali +Chellaston +Ahram +Mahaly +Seshambe +Gombe +Mering +Verwood +Imerimandroso +Adilcevaz +Gölmarmara +Bangassi-Nangou +Longwy +Uchiko +Melouza +Jangīd +Tondangi +Bellavista +Hebli +San Vito al Tagliamento +Dougouni +Nakanojōmachi +Taşucu +Azpeitia +Domaniç +Schwyz +Xiangyuncun +Beech Grove +Dorfen +Adjud +Gulf Shores +Cessnock +Wakuya +Montagu +Fray Luis A. Beltrán +Petlāwad +Espumoso +Seven Pagodas +Salua +Gayéri +Pâ +Niederkrüchten +Redruth +Cumbum +Greenlawn +Waremme +Río San Juan +Puliyūr +Hathīaundha +Moura +Ewa Beach +Sobreda +Douar El Arbaa Bou Quorra +Yauco +Lakhaura +Gaspé +Meruoca +Palmers Green +Totteridge +Nazaré +Gurramkonda +Kontiolahti +Blaydon +Kenmore +San Pedro Tapanatepec +Biatorbágy +Kawaminami +Berkley +Florencia +New Brighton +Biritinga +Kuusamo +Whitman +Mallāpuram +Mashpee +Alice +Vicovu de Sus +Telua +Roanoke Rapids +Depew +Vandalia +América Dourada +Castiglione del Lago +Weißwasser/Oberlausitz +Şefaatlı +Västerhaninge +Horsham +Kawasaki +Pargas +Grodzisk Wielkopolski +Presidente Dutra +Vesoul +Ferndale +Gangāpur +Majiagoucha +Ambohimierambe-Andranofito +New Cassel +Bella Vista +Sansepolcro +Swampscott +Bayserke +Raynham +Ban Na Kham +Warni +Srīvardhan +Kutchan +Jaguapitã +Zacualpan +Klimavichy +Mazagran +Xihuangni +Newport Pagnell +Mahikeng +Vize +Rumst +Koduman +Oulad Bou Rahmoun +Tamaki +Gloversville +Radviliškis +Sakabansi +Miraí +Maesawa +Bhoj +Itki Thākurgaon +Khaira +Piratininga +Chautham +Doumanaba +Tredegar +Kulunda +Bilaua +Hendersonville +Silvino Lobos +Putyvl +Nopala de Villagran +Çifteler +Pacific Grove +Huitzilan +Wülflingen +Tonawanda +Galatone +Brake +Ban Ton Thong Chai +Babhani Bholwa +Tagoloan +Schriesheim +Al Madāmūd +Bhatranha +Kastsyukovichy +Changamkari +Canyon +Cernavodă +Putaparti +Kidal +Capotille +Sooke +Tabhka Khās +Hasanpur +Jadia +Mellila +Bina +Bonheiden +Makapanstad +Sultandağı +Eggertsville +Kohīr +Natividade do Carangola +West Park +Hatton +Durham +Campodarsego +Hasanganj +Talladega +Clevelândia +Ipauçu +Mani +Peddapalle +Devendranagar +Hazel Park +Leninsk +Neustadt bei Coburg +Front Royal +Ut Bulag +Spring Creek +Bad Wurzach +Olonne-sur-Mer +Montargis +Sabou +Alvinópolis +Andondabe +Pedara +Tatarikan +Kanungu +Echuca +Bolivia +Markgröningen +Patnanungan +Rizal +Royse City +Rajni +Mineral Wells +Ekma +Kawagoe +Perchtoldsdorf +Amlash +La Magdalena Tlaltelulco +Pontinia +Boskoop +Saint-Avold +Tubod +Murray Bridge +Langelsheim +Gondomar +Glasgow +Revūr +Kamitonda +Burshtyn +Ylivieska +Ochanthururtha +Carrières-sur-Seine +El Arenal +Villa Ocampo +Chépica +Grenzach-Wyhlen +Mollerusa +Frederick +Contamana +Monroe +Tone +Le Hochet +Corupá +Ritterhude +Capela +Satyāmangala +Zozocolco de Hidalgo +Filiaşi +Fritzlar +Sabbah +Udiyāvara +Ban Ho Mae Salong +South Farmingdale +Ferreiros +Cuevas del Almanzora +Lebanon +Swallownest +Midar +Kutavettūr +Brasilândia +Bangui +Ban Mae Sun Luang +Puerto Salgar +Islāmpur +Boa Esperança do Sul +Netherton +Aruvikkara +Lockhart +Kaintragarh +Hudiksvall +Landsberg +Konārka +Shamsa +Potsdam +Westervoort +Busko-Zdrój +Issoire +Andorinha +Canet de Mar +Cassano delle Murge +Struga +Dionísio Cerqueira +Dembecha +Naduvattam +Saidpur +Alpedrete +Witzenhausen +Wallan +Novyi Buh +Sárvár +Barajor +Pavannur +Verdal +California City +Acala +Kezi +Râs Baalbek +Quthing +Manambondro +Milenaka +Soalala +Ambodiriana +Befasy +Kopoky +Ramainandro +Ambinanindrano +Ambatomanjaka +Andranovelona +Ianantsony +Analamary +Imanombo +Beroy Atsimo +Alarobia Bemaha +Talata Ampano +Ambatoharanana +Sahave +Bevoay +Anahidrano +Ambahive +Ifatsy +Ankisabe +Anjoma-Ramartina +Lokomby +Behisatse +Iharan̈a +Manandona +Antanimenabaka +Marofototra +Tsiatajavona-Ankaratra +Antsoso +Ambesisika +Ankilimivory +Antanifotsy +Wān Long +Kyaukmyaung +Aiyetoro Gbede +Amawom +Rāmechhāp +Bhimphedi +Salyan +Richmond +Mian Sahib +Awan Patti +Koungheul +Bakel +Yufle +Kuljibrīn +Sarmadā +Gammarth +Özdere +Kalongo +Matuga +Zombo +Mutukula +Chaguaramas +Clarines +Fayrōz Kōh +Taywarah +Barakī +Spitak +Villa Ojo de Agua +Bāisāri +Jamaica +Guayos +Villaviciosa +Saint-Avertin +Hessle +Tillor Khurd +Chettikulam +Aivanallur +Shafinagar +Damalcheruvu +Cortalim +Majhgawān +Hombal +Bellatti +Singhānwāla +Hullahalli +Muttamtura +Sathamba +Valattūr +Nedumpura +Turori +Khāndhār +Shirud +Galatge +Vasa +Barţalah +Amirlī +Yinhua +Winkfield +Talpa de Allende +Worthington +Henderson +Buda +Highland Park +Sanyi +Shambu +Huchuan +Anororo +Santa +Şüvəlan +Büttelborn +Antequera +Kisvárda +Shklow +Djambala +La Gloria +Pyryatyn +Kaguchi +Salinas da Margarida +Esbiaat +Sant’Arpino +Calanogas +Pestovo +Lapseki +Yelur +Māndleshwar +Āndipālaiyam +Obando +Kurichchi +Belkheir +Bouchegouf +Texenna +Petersfield +Casalmaggiore +Candói +Távros +Chirpan +Porcia +Castelnuovo Rangone +Laurinburg +Chrysoúpoli +Avanos +Great Falls +Mastic +Kenora +Kenley +Hārohalli +Douar Souk L‘qolla +Santa Brígida +El Hadjira +Tabant +Paralímni +Saint-Servan-sur-Mer +West University Place +Baucau +Cold Lake +’Tlat Bni Oukil +Veliki Preslav +Goluwāli +Lakeland North +Weigelstown +Santa Luzia +Metuchen +Bludenz +Vianópolis +Ādra +Paris +Monkey Bay +Sidi Zouine +Çatalpınar +Dolo +Coconuco +Finale Emilia +Sudbury +Wyke +Ramonville-Saint-Agne +Lambidou +Vallūr +Mitane +Hereford +Mendrisio +Bissendorf +Baiersbronn +Joaíma +Serhetabat +Grande Saline +Restinga Sêca +Majholi +Newtown +Avrillé +Ganjām +Świdwin +Kimyogarlar +La Flèche +Oued Jdida +Schiffdorf +Fairview +Calkiní +Chāndi +Riverdale +Iṭaharā +Jisr ez Zarqā +Malsch +Ahigbé Koffikro +Beckingen +Chemmanam +Gourrama +Nalerigu +Usingen +East Rancho Dominguez +Brooks +Yellāreddi +Lānjī +Sembedu +Lakkundi +Tecuala +Castañuelas +Nakagawa +Nerchinsk +Pursa +Washington +Kunnumēl +Krasnohorivka +Escaldes-Engordany +Lolotique +Lālejīn +Mykolaiv +Kew Green +Hickory Hills +Lagangilang +San Juan +Barra do Sul +Sardinal +Badarpur +Kela Khera +Ammūr +Aghbal +Vinanivao +Sindhnūr +Aizubange +Kentville +Castanet-Tolosan +Morlaix +Poděbrady +Torelló +Aiyampuzha +Holliston +Kurate +Lake Arbor +Vakhsh +Qumqo‘rg‘on +Chapelle-lez-Herlaimont +Beizhou +Quan’ancun +Cumayeri +Tsabit +Sisian +Coquimatlán +Naxxar +Nastola +Valangimān +Dimiao +Stolac +Swansea +Sassenheim +Jhandāpur +Sahakevo +Chemax +West Wickham +Parapatti +Cerro Maggiore +Kizel +Bohodukhiv +Tarumã +Branchburg +Bacuag +Przeworsk +Doukouya +Champāpur +Highland Springs +Ngolobougou +Grefrath +San Tomas +Lidzbark Warmiński +Sera +Le Raincy +Ālampur +Oldsmar +Greensburg +Shepshed +Nisko +Hanamsāgar +Fiorenzuola d’Arda +Sopelana +Breaza +Ravels +Udelnaya +Tayum +Harchoune +Bailleul +Hedehusene +Boulder City +Yuchi +Cujubim +Vellālāpuram +Barharwā +Ayní +Grecia +Tamani +Kondrovo +Chāilāha +Drahichyn +Chegdomyn +Ambérieu-en-Bugey +Nagarūr +Red Oak +Sterling +Qiaoyang +Mori +Forest City +Bromborough +Berlare +Salida +Niquinohomo +Jever +Chīpurupalle +Niedernhausen +Madhuban +Tremelo +Terra Rica +Gabane +Belmont +Avalpūndurai +Koumaïra +Huitán +Nzalat Laadam +Varnsdorf +San Mateo del Mar +Isny im Allgäu +San Vito +Bela Vista do Paraíso +Haga +Le Bourget +Chislehurst +Navashino +Jinta +Taurianova +Timissa +Illzach +Botelhos +Monterrey +Betsukai +Hariharpāra +Grândola +Tall Abyaḑ +Hückeswagen +Mercaderes +Kumāramangalam +Lemon Hill +Cabral +Vuhledar +Tendūkheda +Tadjourah +Nevel +Ponto Novo +Schwabmünchen +Cabañas +Cherrapunji +Port Antonio +Kumārīpur +Nenmini +Fort Payne +Tanque Verde +Kochkor-Ata +Warwick +Huixcolotla +Petrovaradin +Cândido de Abreu +Ilkley +Patrocínio Paulista +Józefosław +Radzyń Podlaski +Benipati +Comox +Astravyets +Ighrem n’Ougdal +Cerritos +Buerarema +Whitefish Bay +Ogíjares +Dehmoí +La Carolina +San Julian +Anta +Gryazovets +Al Mālikīyah +Weizhou +Muthallath al Azraq +Fameck +Sullivan +Devarapalle +Merate +Pālod +Città Sant’Angelo +Baguley +Waunakee +Kapiri Mposhi +Shuichecun +Dęblin +Stony Point +Łapy +Pattensen +Sozopol +Āfdem +Alexander City +New Paltz +Konina +Araputanga +Itamonte +Fiadanana +Lampa +Bni Darkoul +Oulad Dahmane +Armagh +Amasra +Sanquelim +Hilchenbach +Montmagny +Pontivy +Sítio do Quinto +Hanover +Laterza +Williamstown +Tabatinga +Washington +Clarksdale +Romsey +Kamrāwān +Piney Green +Adams +Romilly-sur-Seine +Zítsa +Curtorim +Harhorin +Hasanpur Juned +Shlisselburg +Selb +Hudson +Chitila +Lummen +Krasnogvardeyskoye +Villers-lès-Nancy +Diankabou +Bo’ness +Obanazawa +Tavares +Cherupazhasshi +Much +Luduş +Cumpăna +Haubourdin +Hirono +Matungao +Penrith +Maqat +Deming +Tiltil +El Ateuf +Vohipeno +Briniamaro +Balham +Pincourt +Mozarlândia +Teignmouth +Perunkolattūr +Sinmpérékou +Sasso Marconi +Danilov +Masallı +Entre Rios de Minas +Ijra +Eshowe +Friedland +Banbridge +Cocorná +Havre de Grace +Punata +Dennis +Driouch +San Juan del Sur +Törökbálint +Garhpura +Lilburn +Larkhall +Mount Vernon +Mississippi Mills +Ramsey +Youdiou +Vaddāpalli +Tepetzintla +Breukelen +Sukhinichi +Bodmin +Andūrkonam +Belokurikha +Çiçekdağı +Pilar +Labiod Medjadja +Sakhā +Río Negro +Hammonton +Pindaí +Chaabat el Leham +Pallasovka +Joubb Jannîne +Pine +Rellingen +Roseau +Great Bend +Loreto +Conwy +Neqāb +Matsushige +Arzgir +Greendale +Isla Vista +Muy Muy +Bāladharmāram +San Ġwann +Katyr-Yurt +Prestwick +Tsivilsk +Alagoinha +Douar Oulad Driss +Oulad Driss +Riofrío +Neustadt an der Donau +Sāhit +Antioch +Cēsis +Mediouna +Troon +Chhāpia +Androrangavola +Tarumirim +Paola +San Ramón +Uch-Korgon +Ochakiv +Triunfo +Purísima de la Concepción +Plérin +Shimubi +Santa Croce sull’ Arno +Cuarte de Huerva +Hima +Tirumalaiyampālaiyam +Hooksett +Gladeview +Kōteshwar +Harsefeld +Villa Alegre +Surbo +Ospitaletto +Nishinoomote +Onklou +Guilford +Tlaxcala +Carmen de Areco +Lope de Vega +Kodāngipatti +Baie du Tombeau +Groß-Zimmern +Kurumbalūr +Ankadinandriana +Collecchio +Coremas +Masty +Paramati +Hershey +Rubiera +Owosso +Melksham +Mahatsinjo +Ngoulemakong +Dinan +Ranomafana +Thuin +Laxou +Wibsey +Corridonia +Bar-le-Duc +Fraser +Lake Stickney +Mānantheri +Béré +Bellaa +Pudur +Malvik +Las Guáranas +Santa Marta de Tormes +Saint-Omer +Kushimoto +Dzuunmod +Kysucké Nové Mesto +Condoto +Ifrane +Piraziz +Tapes +Kamalganj +St. Clair +Rasulpur Dhuria +Złotoryja +Capinópolis +Mmopone +Djanet +At-Bashy +Langwedel +Malo +Kujūkuri +North New Hyde Park +Mulakād +Lognes +Great Baddow +Boguszów-Gorce +Kaonke +Sprimont +Ferrier +Mangamila +Mineral del Monte +Vubatalai +Gouré +Sisa +Técpan de Galeana +Limanowa +Néa Alikarnassós +Woudrichem +Mahinog +Bilozerske +Ibitiara +Tiruvāsaladi +Bílina +Sepīdān +Terrace +Ternitz +Cómbita +Farnborough +Rosà +Rio Piracicaba +Teixeira +Flower Hill +Pinia +Djebahia +Misaki +Mercier +Parlier +Lumino +Skipton +Chippewa Falls +Narragansett +Bahçesaray +Dahé +Abony +Alangānallūr +Zontecomatlán de López y Fuentes +Port Glasgow +Magione +Vredefort +Kalocsa +Groveton +Boston +Negreşti-Oaş +Cambuci +Guajiquiro +Kankipādu +Vemulūru +Roncade +Kiri +Plochingen +Paliaturutu +Bartabwa +Batuan +Huasuo +Castellammare del Golfo +Anzegem +Lapua +Langenselbold +Hatten +İspir +Tullamore +Lowton +Carmignano +Suō-Ōshima +Río Branco +Saint-Maurice +Sinha +Sveti Ivan Zelina +Hanover +Agidel +Arroio dos Ratos +Saint-Jean-de-Luz +Uzun +Cabarete +Nova Ponte +Verrières-le-Buisson +Montabaur +Wilbraham +Holalagondi +Jędrzejów +Tonya +Guastalla +Sātyūn +Villa Yapacaní +Yokoshiba +Kelamangalam +Dinmānpur +Hutchinson +Sangota +Palmeirais +Čajetina +Arnouville-lès-Gonesse +Sigulda +Thillangéri +Tostado +Balīgaon +Broadlands +Lucao +Ząbkowice Śląskie +Ágios Athanásios +Lauda-Königshofen +Tostedt +Aleksandrovka +Severínia +Red Bluff +Falls Church +Talya +Port Royal +Kānjikkovil +Key Biscayne +Tzaneen +Jitwārpur Nizāmat +Pineto +Wawizaght +Lakkampatti +Salem Lakes +Burbage +Edenburg +Münster +Palayad +Akora +Benfreha +Paniem +Breza +Kottacheruvu +Naivasha +Qazyqurt +Mocha +Jastrebarsko +Darpa +Debar +Essau +Tiruppāchūr +San Francisco +Relangi +Saint-Genis-Pouilly +Belvedere Park +Ban San Phak Wan Luang +Loviisa +Stein bei Nürnberg +Thorpe Saint Andrew +Andoain +Bijaipur +Bicas +Solila +Ratzeburg +Clarkston +Adekar Kebouche +Anamorós +El Paisnal +Wilsdruff +Biscarrosse +Halwāra +Altınekin +Iakora +Cecil +Marofinaritra +Gundlapelle +Merimandroso +Les Sables-d’Olonne +Ayt ’Attou ou L’Arbi +Stanytsia Luhanska +Ottweiler +Ban Du +Pindorama +Blidet Amor +Australind +Ust’-Ordynskiy +Jun Bel +Bom Jesus do Galho +Arbon +Bakun +Siswa +Abensberg +Nāgireddipalli +Moultrie +Rio Paranaíba +Falagueira +Sarmīn +Aïn Nouissy +Kusāha +Ban Kaeng +Tsimlyansk +Pualas +Kannamanāyakkanūr +Reidsville +Cadaval +Dargahān +Middlesex +Água Boa +Vitomiricë +Sha Kok Mei +Pandhāna +Herselt +Minignan +Corinth +Anapoima +Moston +Sonora +Saint-Fargeau +Pakaryā Harsidhi +Tabuse +Lebanon +Diéramana +Rebouças +Guachochi +Mbuyapey +Neu-Anspach +Immenstadt im Allgäu +Mosina +Montesson +Valea Lupului +Olsberg +McCalla +Quinapundan +Chelsfield +Oria +Aberdare +Suwāsra +San Martín de Loba +Eberbach +Farap +Angus +Nadisāl +Gavinivāripālem +Surajpura +Sadhoa +Sokone +Oyam +Guanduqiao +West Lincoln +Ceres +Yanhewan +Ouled Sidi Brahim +Ludvika +Tenente Portela +Água Fria +San Gabriel +Lingāl +Thornbury +Morton +Chinnavādampatti +Santa Catalina +Poço das Trincheiras +Uckfield +Lākho +Goshen +Uhingen +Barhni +Morris +Deysbrook +Harduli +Ahmed Rachedi +Askim +Murra +Madagh +Boula’wane +Araruna +Cehegín +Burglengenfeld +Krasnyy Kut +Flers +Valenton +San Carlos +Babhangāwān +Fujisaki +Mésa Geitoniá +Eisenstadt +Barroquinha +Nawada +Buggenhout +Turnov +Paraíso +Nampicuan +Qobustan +Haacht +Tlayacapan +Pākala +Markacho +Roh +Huizúcar +Khallikot +Lockhart +Santaquin +Ormeau +Tiruvalanjuli +Sommacampagna +Plumtree +Ichikawamisato +Armthorpe +Lagunia Surajkanth +Ankaramena +Yangasso +Lopik +Sassenberg +Santo Domingo Xenacoj +Larena +Southgate +Tarlapalli +Srīnagar +Scottsbluff +Sopetrán +Jasper +Santa María +Shatrāna +Robbinsdale +Gwanda +Jacaraú +Narahia +Bāra +Neubiberg +Brwinów +Roquebrune-sur-Argens +Asagiri +Short Hills +West Freehold +Tavagnacco +Monticello +Anderson Creek +Tulchyn +Chenôve +Nolensville +Lagoa +Alginet +Alloa +Aït Yaïch +Vinci +Verona +Eggenfelden +Chatham +Black Forest +Claxton Bay +Pahou +Jacaraci +Bokod +Ban Ao Nang +Barranco de Loba +Sirmaur +Araceli +Rauch +Ampohibe +Perai +Sainte-Maxime +Nether Providence +Busembatia +Eching +Kolwāra +Caln +Ascensión +Morroa +Baqiābād +Bagulin +Pilisvörösvár +Szarvas +Satwās +Aartselaar +Davorlim +Alūr +Ulchin +Dollis Hill +Painan +Dornakal +Lavaltrie +Villa Vásquez +Kalývia Thorikoú +Tirkarūr +Tagalft +Kharki +Cayey +Polyarnyye Zori +Mantaly +Korsør +Barhi +Spenge +Vadugapatti +Măgurele +Gorbea +Killarney +Brainerd +General MacArthur +San Sebastián +Saint-Brevin-les-Pins +Château-d’Olonne +Hopatcong +Halawa +Ghora Gali +Skippack +Pomorie +Chik Bānavar +Yéréré +Valbom +Paidiipalli +Itaú de Minas +Mutyālapalle +Minneola +Wymondham +Nagra +Haldībāri +Dumas +North Auburn +Lindenhurst +Baoshan +Hetton le Hole +Bo +Alindao +Tūprān +Wangjiaxian +San Antonio +Alexandria +Choszczno +Sierra Vista Southeast +Gernsbach +Sorso +Muqui +West Bradford +Chiconquiaco +Edgewater +Lubbeek +Lohfelden +Kihoku +Majia +Hargāwān +Üzümlü +Liestal +San Cristóbal +Stäfa +Rheydt +Anomabu +Zaysan +Mohanpur Gaughāta +Yamada +Küsnacht +Washington Court House +Maria +Kārempūdi +Amersham +Vāsad +West Derby +Lake Wylie +East Bridgewater +Ourtzagh +Puraini +Kamatgi +Natchez +Valday +Impruneta +Moorestown-Lenola +New Hamburg +Opwijk +Villa Rica +Saint Joseph +Zolote +Tezu +Ożarów Mazowiecki +Elizabethton +Doria Sonāpur +Penuganchiprolu +Ozark +Sailāna +Cowes +West Drayton +Nacozari Viejo +Rosarno +Churumuco de Morelos +Patiāli +Miena +Mercerville +West Nipissing / Nipissing Ouest +Barela +Riegelsberg +Santa Rosalía +Pineville +Sidi Azzouz +Markdorf +Volgorechensk +Serinhisar +Artsyz +Jitaúna +Miho +Alamo +Löbau +Thondiamannu +Simões +Tornesch +Rehlingen-Siersburg +Breyten +Zaouiat Moulay Bouchta El Khammar +Ihaddadene +Niederzier +Baulia +Bihpuriāgaon +Bradley Gardens +Livingston +Zhutang +Jiaoxiyakou +Arlington +Balangiga +Tianguistengo +Medvezhyegorsk +Narhan +Bhānukumāri +Wilkinsburg +Alto Longá +Strathmore +Pont-à-Mousson +Leno +Hindalgi +Monte Alegre de Sergipe +San Andrés Timilpan +Pazar +Conisbrough +Muttukūru +Belazao +Mittweida +Lakhsetipet +Hasami +Horta +Yanshuiguan +Brookside +Zapolyarnyy +Lakinsk +Mascali +Anpachi +Baia-Sprie +Saldaña +Pālda +Wālājābād +Vil’nyans’k +Klášterec nad Ohří +Rottingdean +High River +Gua +Jori Kalān +Tepecoyo +Polāia Kalān +Chikhli Kalān +Ustka +Sadovoye +Kottavalasa +Tenerife +Méru +Kizhariyūr +Saddle Brook +Balangkas +Estremoz +Saint-Paul-lès-Dax +Doctor Juan Eulogio Estigarribia +Kārkūdalpatti +Vīraghattam +Radzymin +Lotte +Salīmpur +Peumo +Iflissen +Rokycany +Sumbas +Lengede +Mūrak +Māngoli +Tsukawaki +Amay +Sarqan +Santo Antônio dos Lopes +Huliyār +Woippy +Fakola +Novohrodivka +Nagongera +Romitan Shahri +Sariosiyo +Kidbrooke +Roldán +Kambainellūr +Rock Ferry +Baruun-Urt +Coronel Bogado +Dayr al Barshā +Shirley +Neutraubling +Pollokshaws +Iona +Algarrobo +Algarrobo +Bad Camberg +Korangal +Omegna +Eski Īkan +Ambohimanga Atsimo +Orbetello +Našice +Sison +Chiaravalle +Chard +Anantarāzupeta +Bariariyā +Loganville +Bousso +Ban Don Kaeo +Grafing bei München +Brandermill +East Greenwich +Chicago Ridge +Shimada +Gualdo Tadino +Jericho +Ungutūru +Benito Juárez +Biały Kamień +Bikkavolu +Somerton +El Barrio de la Soledad +Puxinanã +Patcham +Santa Maria a Vico +West Lealman +Gantt +Yakhroma +Razan +Nkhata Bay +Mongeri +Ban Nong Kula +Ucar +Ghaura +Vedasandūr +Bedford +Laï +Pak Thong Chai +Ban Tha Thong +Ciénega de Flores +Farmington +Bökönbaev +Manoharpur +Det Udom +Saint-Gilles +Mionica +Bollullos par del Condado +Weston +Mannūr +Marechal Floriano +Bois-Guillaume +Morokweng +Poynton +Ait Yazza +La Carlota +Chikitigarh +Ben Taieb +Langerwehe +Haramachida +Levoča +Mondolfo +Svrljig +Imbaú +Rāje +Aïbongo +Maria da Fé +Prieska +Tafrant +Brazópolis +Seacroft +Kukdeshwar +Opera +Van Buren +Arvika +Kōdanād +Wingene +Horw +Brühl +Kelafo +Greenwood +Neftçala +Padavēdu +Manuel Ribas +Sabinópolis +Toubakoro +Sines +Saren +North Mankato +Knić +Mahavanona +Kāshti +Mapanas +Bainbridge +Ömerli +Pannimadai +Zhabinka +San Giorgio Ionico +Forfar +Nagardevla Budrukh +Little Falls +Bou Izakarn +Al Mu‘aḑḑamīyah +Uxbridge +Douar Hammadi +Jacksonville +Ochër +Borborema +Elk Plain +Kouroussa +Auray +Ishikawa +Pelham +Maldon +Terkuvengānallūr +Barkuhi +Bennane +Lich +Caldas +Crépy-en-Valois +Shichinohe +Aqköl +Wennigsen +Zeven +Chebrolu +Oleggio +Cedar Lake +Willowick +Aḑ Ḑab‘ah +Kearsley +Venëv +Mykolaivka +Mittegroßefehn +Wulong +Luling +Campos Altos +Antas +Tapolca +Kartuzy +Siddāpur +Ālangudi +Rescaldina +Minamiaizu +Fallsburg +Náfplio +Bensville +Pānr +Kaoma +Bochil +Assenede +Adustina +Midlothian +Boa Esperança +Maisach +Mill Valley +Saraykent +Feldkirchen +Tranås +Almoloya de Alquisiras +Miraíma +Kawaii +Haaren +Oschatz +Odlābāri +Shintō +Ayomi +Kalkar +Chesterton +Newport +Covington +Tamarakulam +Hobe Sound +Montelupo Fiorentino +Mankera +Juan de Acosta +Leyton +Puerto Deseado +Hautmont +Pānsemāl +Vinto +Murrhardt +Mackworth +Grenaa +Mnagueur +Huron +Castelsarrasin +Nallagunta +Tālbahat +Coolidge +Uslar +Pirangut +Bhulwāl +Edingen-Neckarhausen +Federal Heights +Bamble +Birqāsh +Sanlúcar la Mayor +Hythe +Feucht +Ashtead +Bua Yai +São José do Cedro +Mers el Hadjad +Orumanayūr +Santol +Mirandiba +Barwon Heads +Raghudebbati +Forest Park +Kātrāvulapalle +Douarnenez +Juan Aldama +Antarvedipālem +Dippoldiswalde +Plewiska +Jitwārpur Kumhra +Taki +Grajales +Staszów +Wombourn +Pulūr +Alto Santo +Shergarh +Buhuşi +Kutavūr +Clearview +Beronono +Narvik +São Martinho do Bispo +Sanjiang Nongchang +Sun Lakes +Nesebar +Rambha +Yuscarán +Lauchhammer +East Whiteland +Boutilimit +Ipiranga +Beekman +Thong Pha Phum +Ústí nad Orlicí +Massalubrense +Kerben +Massaranduba +Omiš +Storozhynets +Astolfo Dutra +Kakunodatemachi +Westmont +Sai Buri +Shepherdsville +Santiago Jocotepec +Collingswood +Uzhur +Sur Singh +Bad Ischl +Ipanguaçu +Villasanta +Tepoztlán +Belison +Kīlattingal +Luino +Valença +Gurinhém +Leirvik +Dallas +El Rodeo +Bovenden +Chāprā +Thônex +Naţanz +Matias Barbosa +Landau an der Isar +Port Lincoln +Lakewood Park +Charcas +Curuá +Nowy Tomyśl +Noya +Kisanuki +Candelaria +College Park +Powell +Siroda +Geldagana +Phulwār +Gudūr +Capitão Enéas +Varde +Fergus Falls +Lagoa Real +Pierre +Sibundoy +Wittstock +Jacksonville +Eraurā +Mŭ’minobod +Pélézi +Baños +Lachute +Trepuzzi +Niška Banja +Valentim Gentil +Kemp Mill +Doranahalli +Byāhatti +Castel San Giovanni +Oneonta +Belm +Bougzoul +Bela +Siderópolis +Titiribí +Hohenstein-Ernstthal +Kinogitan +Athens +Rājim +Rosemère +Beilen +Emerald +Adakplamé +Allouez +El Guetar +Sungai Guntung +Tân Vạn +Sidi Ben Adda +Indiana +Dunmore +Aldenhoven +Tamār +Ershui +Jodoigne +Aiuaba +Koundian +Hidalgo +Ardmore +Oostakker +Italva +Lagoa dos Gatos +Bezou +Neuenkirchen +Jefferson Valley-Yorktown +Ponnampatti +Caudry +Andalgalá +Bishops Cleeve +Ban Mueang Nga +Santiago de Anaya +Rotenburg an der Fulda +East Wenatchee +Nantucket +Sumbal +Tibasosa +Zazafotsy +Arenoso +Talwat +Sjenica +Nina Rodrigues +Montalvânia +Vammanal +Arboga +Grünstadt +Kerugoya +Pedro Afonso +Bēylul +Teploklyuchenka +New Ulm +Sāsan +Ezequiel Montes +Fisciano +Ayni +Moudjbara +Pilas +Thonotosassa +Ahrensfelde +El Socorro +El Carmen de Atrato +Karugamād +Frunze +Gouveia +Chełmża +Karlivka +Khadra +Nantwich +Cojedes +Mazamitla +Río de Oro +Berettyóújfalu +Wauconda +Verona +Santa Catalina +Itakura +Sidi Abdelkarim +Nelas +Águas Vermelhas +Daean +Ostrzeszów +Balassagyarmat +Kottaiyūr +Mbini +Amāri +Beloeil +Cirò Marina +Suknadānga +Kārai +Ūttukkottai +Rio Azul +Mignouré +Barāri +Primrose +Itaguaçu +Sharonville +Hazel Grove +Kīāshahr +Gafanha da Nazaré +Wezembeek-Oppem +Petrolândia +Tierra Amarilla +Fāmenīn +Santa Adélia +Esquipulas Palo Gordo +Morpeth +Circleville +Antohobe +Lakoucun +St. Helens +Uttoxeter +Sibirila +Barjora +Taguatinga +Leuna +Ollioules +Ilampillai +Hawaiian Gardens +Haivoron +Keāl +Hokuei +Turuttiyad +Selmana +Rānāpur +Riposto +Córdoba +Ricaurte +Solhan +Marlow +Alewah +Fujikawa +Martinho Campos +Rājāsūr +Busto Garolfo +Candeias +Beraketa +Ambahita +Mahavelona +Marotsiraka +Mahajamba +Ambatomarina +Antanambaobe +Kalandy +Bekipay +Marokarima +Fiadanana +Mahatsinjony +Vanono +Talata-Vohimena +Vatolatsaka +Belambo +Miarinarivo +Beharona +Ambohimitombo +Tsarahasina +Bevato +Ankiliabo +Amborondra +Bealanana +Sahalanona +Ambodihara +Ilha de Moçambique +O‘nhayot +Shofirkon Shahri +Rafaï +Takerbouzt +Thouars +Brahmānandapuram +Tall Banāt +Milhã +Meilen +Montfoort +Persan +Kamituga +Beach Park +Schneeberg +Annāram +Şaḩnāyā +Cristópolis +Lone Tree +Tulle +Powell +Novoulyanovsk +Coribe +Koundara +Bandraboua +Lorsch +Dubovka +Pathum Thani +Taiyong +Shāndīz +Matane +Donji Vakuf +Mirzāpur +São João d’Aliança +Kongarapalli +Pāli +Ambohimiera +Chumpak +Bebra +Fleury-Mérogis +East Norriton +Pemberton +Kuraymah +Ganguvārpatti +Beiwusidui +Thames Centre +Felixlândia +Mirinzal +Oud-Turnhout +Jardim de Piranhas +Erbach +Sutihār +Boha +Santa Branca +Kambila +Mankal +East Milton +Söğütlü +Raydah +McFarland +Beasain +Ovidiu +Merošina +Thala +Soledade +Drapetsóna +Goianápolis +Sakaki +Lübben (Spreewald) +Canteleu +Rājnagar +Grass Valley +Roselle Park +Pacaembu +Hajdúsámson +Bedfordview +Mjölby +Kargıpınar +Méridjonou +Chaugāin +Detva +Eynesil +Nova Ipixuna +Alfredo Chaves +McPherson +Bolívar +Lyndhurst +Kępno +Belwāra +Amāha +Havelock North +Kanākir +Bambang +La Entrada +Belsandi Tāra +Llanera +Cassina de’ Pecchi +Misano Adriatico +Bothell East +Perdūr +Warrenville +Audincourt +Narasingapuram +Powell River +Furukawamen +Wells Branch +Marostica +Carleton Place +Ichtegem +Castellanza +San José Acatempa +Bang Racham +Attibele +Aracatu +Sesquilé +Camp Pendleton South +Plumstead +Brierley Hill +Tsingoni +Ibicuí +Tarhzout +Montévrain +Streetly +Lower Moreland +Vöhringen +Hunasagi +Waimalu +Höchstadt an der Aisch +Grünberg +Locorotondo +Nachikatsuura +Zhipingxiang +Cossato +Nyzhnia Krynka +Khe Sanh +Abre Campo +Gesuba +Sukma +East Cleveland +Julianadorp +Diego de Almagro +Aßlar +Destin +Çaybaşı +Vīraganūr +Temsamane +Papagaios +Mansidão +Royal Kunia +Oued Taria +Alterosa +Lons +Maracaí +Weißenhorn +Huntington +Berre-l’Étang +Muttunāyakkanpatti +Khergām +Denzlingen +Kelangāh +Chudovo +Alto Paraná +Oberhaching +Sankt Leon-Rot +Debre Werk’ +Melsungen +Midleton +Moralzarzal +Buchloe +Bickley +Kubādupuram +Guelph/Eramosa +Krishnarāyapuram +Wood Dale +Santo Augusto +Tucacas +Grão Mogol +Bukedea +Mogeiro +Hall in Tirol +Orikhiv +Dumri +Bhogpur +Salaverry +Shiloh +Jīran +Olean +Bog Walk +Galmi +Meerane +Tidjelabine +Joaquim Pires +Torrijos +Polukallu +Quakenbrück +Rustington +Tumbippādi +Philippsburg +Eastham +Areado +Simplício Mendes +Makokou +Cefalù +Jabbeke +Lauterbach +Aurora +Sāgar +Caselle Torinese +Hockessin +Sido +Sunset +Matiçan +Friesenheim +Beacon +Tāti +New Franklin +Kettering +Hòa Thượng +Ettenheim +Torre del Campo +Ping’anbao +Villalba +Linganaboyinacherla +Alcanena +Taphan Hin +Hilpoltstein +Ocaña +Binkolo +Tracunhaém +Wakasa +Richland +Oulad Chikh +Billère +Porto Alegre do Norte +Ibipitanga +Tamalameque +Kishanpur Ratwāra +Artondale +Polavaram +Qiblaí +Manoel Vitorino +Tarauna +Avanhandava +Erbach +Shtërpcë +Kingstown +Huangyadong +Guamal +Weno +Waycross +Luozi +Saboeiro +Solaro +Zhashkiv +Carmópolis +Markt Schwaben +Grand Falls +Toulal +Zhovkva +Iskapalli +Millbury +Polotitlán de la Ilustración +San Rafael Las Flores +Amantea +Bellair-Meadowbrook Terrace +Parihāra +Dogāchi +Dryden +Carapebus +Ōki +Itaguara +Beachwood +Batuan +Michendorf +Māndalgarh +Trinitapoli +Fujimi +Mount Barker +Kāuriya +Ribeiro do Amparo +Hīdaj +Khmis Sidi al ’Aydi +Primavera +Worthington +Gangaikondān +Gekhi +Saloá +Barra do Mendes +Tomiño +North Battleford +Paripueira +Valayam +Fara in Sabina +Kamigōri +South Sioux City +Haidarnagar +Vellodu +Cosham +Sauk Rapids +Vembārpatti +Strada +Nules +Mayrtup +Pedro Velho +Olympia Heights +Maumee +Bad Soden-Salmünster +Enniskillen +Khajawa +Seirō +Trbovlje +Pigüé +Clemencia +Wayland +Irikkūr +Haßfurt +Teays Valley +Skoczów +eManzimtoti +Wanzleben +Wörgl +Anadia +Lakeland +Schwaz +Colangute +Forest Hill +Turuvanūr +Dowbarān +Lieusaint +Calafat +Magalhães de Almeida +Meckenbeuren +Krumbach +Littleborough +Ewarton +Channahon +Nawāgarh +Plav +San Antonio de las Vueltas +Pedernales +Passo de Camarajibe +Tako +Braselton +Koppies +Itagi +Gangavalli +Bedford +Graça +Villas +Kamnik +Boyovut +Tachov +Unión de Tula +Horodyshche +Pierrelatte +Kivertsi +Rønne +Achuapa +San Juan +Assaí +Vargem da Roça +Carmo de Minas +Iguatemi +Löningen +Bideipur +Acajutiba +Rixheim +Sarāyān +Tibri +Arbaa Laaounate +Anapurus +Lys-lès-Lannoy +San Ġiljan +Oftringen +Ipswich +Itapetim +Hünxe +Ban Bang Muang +San Rafael Petzal +Ban Tha Luang Lang +Akropong +Bellefontaine +Roncq +Siemiatycze +Couvin +Jinmingsi +Rosyth +Sannicandro Garganico +Mont-Laurier +Kupino +Higashimiyoshi +Yulee +Madānpur +Simri +Ampasinambo +Zhongliao +Caçu +Chaoyangdicun +Auburn +Lomma +Guapé +Torul +Morwell +Santa Luzia +Gräfelfing +Varedo +Arugollu +Berceni +Mariánské Lázně +Saint-Orens-de-Gameville +Kirkwood +Gouka +Feliz +Leverano +Snoqualmie +Tampamolón Corona +Taggia +Kodigenahalli +Willow Grove +Eppstein +Kashin +Singalāndāpuram +McMinnville +São Pedro do Piauí +Gülchö +Cayce +Bandarbeyla +Amrābād +Travagliato +Lipno +Nehrəm +Chityāl +Megarine +Orange Walk +Frankenberg +Holzgerlingen +Kannivādi +Waianae +Douar Lehgagcha +Jardín +Settara +Moissac +Uruoca +Rostamābād +Central Elgin +Itinga +Flores de Goiás +Urupês +Nawāda +Manavālakurichi +Barghāt +Msata +Forster +Hawick +Mata +Badarwās +Tacaimbó +Beverstedt +Gopālpur +Bondeno +Ephrata +Zarghūn Shahr +Sidmouth +Ermoúpoli +Hazel Crest +Ataléia +Futrono +Lyaskovets +Guaraniaçu +Priverno +Enghien +Urbino +Kudachi +Palkūr +Bodagudipādu +St. James +York +Angical +Ibateguara +Taglio +Darihat +Uruana +Saint-Martin-de-Crau +Miami Springs +Malepur +Nova Trento +São João do Triunfo +Alagoinha +Milford Haven +Xireg +Kidlington +Arcadia +Sobrāon +Nonoai +North Fair Oaks +Mistassini +Tāmaraikkulam +Rocky Point +Wezep +Nova Canaã +Lamont +Saugeen Shores +Eichstätt +Sher Chakla +Marienheide +Knottingley +Ipecaetá +Tummalapenta +Moberly +Mions +Shorewood +Kovilūr +Crevalcore +Cêrro Largo +Ndélé +Kaleyānpur +Coldwater +Colesville +Biedenkopf +Quatá +Kingston +South Park +Montataire +Toyloq Qishlog’i +Sariq +Papágos +Mohda +Presidente Kennedy +Tiruppanandāl +Arona +Hinabangan +Ingersoll +Kuleshovka +Auriflama +Angermünde +Valencia West +Diaï Koura +Vempalle +Kraainem +Boa Nova +Itapagipe +Uarini +Las Rosas +Mangha +Bergen +Santa Cruz de Bezana +Castel San Giorgio +Tarumizu +Marshall +San Pedro Pochutla +Radomyshl +Genthin +Chak Husaini +Schmölln +Glenpool +Quatis +Palmito +Motupe +Cambados +Karma +Maribondo +Hettstedt +Kannadiparamba +Copalchí +Kalādgi +Slobozhanske +Madanpur +Sansare +Sale +Sendenhorst +Saint Ann’s Bay +Yongcong +Normandia +Altos del Rosario +Bhīmadolu +Duvergé +Otley +Río Caribe +San Ferdinando di Puglia +Chiran +Mucambo +Poté +Nova Veneza +Svetlogorsk +Aldama +Jindayris +Nikolayevsk +Qantīr +Avon +Latham +Bad Dürrheim +Namīn +Fiesole +Warrensville Heights +Xikou +Isāgarh +Smithfield +El Crucero +Saint-Jacques-de-la-Lande +Chōsei +Piên +Barahari +Ajjampur +Bilaspur +Glen Carbon +Mirabela +Retirolândia +Avalēpalli +San Agustín de Guadalix +University Heights +Jurema +Domkonda +Curiúva +Marshall +Shōdoshima +Speedway +Lanuza +Umburanas +Alexandria +Helensburgh +Childwall +Woudenberg +Pedreiras +Beauharnois +Kostolac +El Kerma +Beeville +Salisbury +Frei Miguelinho +Abadla +Marion +Port Neches +California +Hammam el Rhezez +Milovice +Santa Coloma de Farnés +Bunhe +Manta +Kunjatturu +Dantewāra +Uitgeest +Trzebnica +Pitlam +Spring Garden +Sampaloc +Jiquiriçá +Šamorín +Oak Park +Solonytsivka +Balhāpur +Rockland +Bamafélé +Boninal +Engenheiro Caldas +Allestree +Ottaikkālmantapam +Mahuwa Singhrai +Saimbeyli +Yeşilli +Jaca +Maglie +Babhanganwa +Brecksville +Ihtiman +Santa Luzia do Itanhy +Pfullendorf +Artena +Shamalgan +Serra Branca +Baianópolis +Primeira Cruz +Formello +Trubchevsk +Orocó +Brejo do Cruz +Lumberton +São Félix do Araguaia +Mantenópolis +Verín +Kyzyl-Adyr +Castilla La Nueva +Sóller +Kauhajoki +Yamanobe +Rožaje +Tejutla +Elesbão Veloso +Karpi +Kerepestarcsa +Masangshy +Combarbalá +Bollène +San Javier +Marchtrenk +Qingxicun +Chengara +Amboasary-Gara +Dongshicuo +Barßel +Atner +Mohania +Wyandanch +Marhamat +Vedi +Vázquez +Nighoj +Jannat Shahr +Daniëlskuil +Rāyapalle +Rāzole +Guerrero Negro +Sisai +Duvva +Cañasgordas +Middlewich +Okinoshima +New Providence +Whitby +Amīngarh +Tapilula +Doumé +Ixcatepec +Ráquira +Łęczyca +Nybro +Pirallahı +Camapuã +Atomé-Avégamé +Beaufort +Ak-Dovurak +Rommerskirchen +Sūrān +New Carrollton +Pama +Gonzalez +West End +Zhukovo +San José Villanueva +Wanze +Neckargemünd +Gondalga +Dueville +East Islip +Piquete +Marghita +Cervignano del Friuli +Tokoroa +Upanema +Patālia +Royal Wootton Bassett +South Stormont +Bridport +Gran +Presidente Bernardes +Lappersdorf +Serui +Bardstown +Latiano +Dattapulia +Pegnitz +Sharm ash Shaykh +Dhāna +Bécancour +Winsum +Palestina +Newington +Asperg +Ashiya +Talne +Nālatvād +Seabrook +Rossington +Bandar-e ‘Asalūyeh +Western Springs +Lāla +Echelon +Haselünne +Hilsea +Kurtkoti +Stolin +Nesconset +Plover +Clifton +Bishenpur +Chinique +Mór +Ugo +Oosterzele +Niaogho +Rahui +Karnāwad +Tamanique +Hola Prystan +Kaharlyk +Dinant +Mascote +Alagoinha +Castelfranco di Sotto +Endicott +Wentorf bei Hamburg +Rukhāe +Martinsville +Kheri Naru +Lexington Park +Bexley +Beur +Kharv-e Soflá +Amriswil +Thisted +Wschowa +Hemsworth +Albertirsa +Jānapādu +Spaichingen +Koubel-Koundia +Shangping +‘Alem T’ēna +Rheinfelden +Corabia +South Charleston +Bridgetown +Dārat ‘Izzah +San Jorge +Llanes +Antigua +Pfarrkirchen +Eatontown +Tovuz +Bad Salzdetfurth +Borgaon +Conway +Vaires-sur-Marne +General Belgrano +Novi Iskar +Calolziocorte +Kafr Nabūdah +Tauberbischofsheim +Çayıralan +Adh Dhakhīrah +Nynäshamn +Menaa +São Ludgero +Lourdes +Lewisville +Nova Varoš +Ban Bung Kha +Strabane +Kodriva +Głowno +Hlučín +Avidha +Mqam at Tolba +Ban Mae Kaluang +Corozal +Wiesmoor +Calderara di Reno +Kudrovo +Perungala +Mŭynoq +Siriāri +Karuvellūr +Jefferson +Hard +Andasibe +Wolfhagen +Shawangunk +Ganxi +Chimá +Kenadsa +Sikat +Courcouronnes +Nemocón +Cajabamba +Hantsavichy +Gárdony +Chandla +Khānāpur +Bayt Jālā +Baras +Stezzano +Genas +El Hachimia +Marudūr +Squinzano +Kriva Palanka +Gines +Gudikallu +Vāghodia +Chalma +Schermbeck +Sukhāsan +Severn +Afzala +Fereydūnshahr +Ilamatlán +Strand +Al Ḩā’ir +Caapiranga +Plouzané +Bonita +Itaeté +Madakkathara +Fontenay-le-Comte +King City +Avocado Heights +Little Hulton +Jamira +Udayagiri +Elanad +Kesariyā +Yedapalli +Pālakkuzhi +Stroud +Bad Laasphe +Chembrasshēri +Sterling +São João do Araguaia +Dundigal +Panjgirāin Kalān +General Viamonte +Lake Forest Park +Fruita +Los Alamos +Nagnur +Nallajerla +Ascensión +Manatí +Gullapuram +Moncks Corner +San Juan de Limay +Fontenay-le-Fleury +Villanchirai +Irondale +Callaway +Barro Alto +Valdemorillo +Mamborê +Beesel +Dok Kham Tai +Hévié +Bou Sfer +Bhakua +Kulharia +Taneichi +Sébékoro +Plougastel-Daoulas +Clinton +São Pedro da Água Branca +São Simão +Kadattūr +Fort Lewis +Harwich +San Juan de Betulia +Dakit +Orkney +Péfka +Zábřeh +Englewood +Uibaí +Ouargaye +Tergnier +Mallet +Tucapel +San Jacinto del Cauca +Chinna Mushidivāda +Monteroni di Lecce +Franklin Park +Golyshmanovo +Jucuarán +Ādīs ‘Alem +Avenal +Versoix +Anzin +Germasógeia +Veglie +Neustadt +Dahāria +Ghordaur +Náfpaktos +Sultanpur Mor +Chaddesden +Kotgīr +Hopewell +Dinklage +San Rafael +Talegaon Dhamdhere +Srebrenica +Basāon +Sault Ste. Marie +Azle +Tuchola +Sítio do Mato +Sunjiayan +Vellarivalli +Benaulim +Melenki +Richterswil +Parihārpur +Zawodzie +Dyykan-Kyshtak +Alleroy +Akhty +Seyitgazi +Santa Bárbara +Chahbounia +San Juan +Vieste +Villa Unión +Ruza +Gaundrā +Inawashiro +Ban Don Thong +Heswall +Kalārdasht +Mosgiel +Kaabong +Kaiwen +Dalkeith +San Juan La Laguna +Amarāvati +Kilgore +Arklow +Uppidamangalam +Panapākkam +Velānganni +Testour +Lacombe +Balsa Nova +Connersville +Goudomp +Kokri +Drøbak +Amblecote +Arruda dos Vinhos +Vikravāndi +Joppatowne +Targuist +Kissane Ltouqi +Abhwar +Alsager +Gien +Telmar +Butler +Pottsville +Lislique +Besārh +Palmetto +Bouzina +Sanankoro Djitoumou +Aconibe +Fåberg +San Jacinto +Atlantic Beach +Urziceni +Amondara +Canton +Chīmalapādu +Gołdap +Luís Antônio +Sülüktü +Várzea Nova +San José de Maipo +Ribeira Brava +Paruchūru +Sainte-Sophie +Wake +Urbana +Boechout +Lincoln +Margraten +Kawatana +Feldbach +Saint Budeaux +Corsham +Oxford +Grez-Doiceau +Bāgli +Zollikon +Calle Larga +Marietta +Barka Parbatta +Hatoyama +El Almendro +Arzachena +River Ridge +Yengema +Washington +Jupiter Farms +Zehak +Hösbach +Słupca +Mangalapur +Amity +Qigexingcun +Lake Station +Makwassie +Egg Buckland +Mucur +Tiorpāra +Port-Alfred +Bijai +Sabana Iglesia +Kotor +Cadereyta +Zbarazh +Peabiru +Nattappettai +Sigli +Shetpe +El Carmen +Vemulapūdi +Carnot-Moon +Payyanadam +Człuchów +Andrews +Buli +Bedburg +Barlinek +Oboyan +Karapürçek +Pazhanji +Henderson +Charlton +Mangalāpuram +Rezzato +Serrolândia +Yantzaza +Marungūr +Weilburg +Rājpur +Alzano Lombardo +Mountain Park +Kumlu +Ubstadt-Weiher +Chandi +La Grange Park +Sant’Angelo Lodigiano +Sweden +Hillcrest +Puerto Morazán +Itapuí +Val-des-Monts +Tórshavn +Amarpura +Santa Maria a Monte +Ashton +Dambal +Blue Ash +Okkerneutboom +Tiruvārpu +Pataili +Bacup +Dohta +Beamsville +Hanımçiftliği +Broussard +Saint-Amable +Bachhauta +Kiiminki +Carluke +Kiskőrös +Franconia +Manerbio +Kuurne +Santa Marcela +Morąg +Wąbrzeźno +Dumariā +Farādonbeh +Kingston +Shibām +Auburn +Coatesville +Buşrá al Ḩarīr +Düzköy +Nosivka +Ostwald +Chifubu +Ampthill +Sidi Abd el Moumene +Nārāyangarh +Ban Na Chom Thian +Coomera +White House +Ambodilazana +Grimstad +Velen +Kāgvād +Rosas +Manching +Saarwellingen +Bouskene +Torredonjimeno +Makarska +Kadena +Woodinville +Nishon Tumani +Charxin +Shirebrook +Shiremoor +Mount Vernon +Berck-sur-Mer +Tounfit +Goh +Reeuwijk +Ponte San Giovanni +Elfers +Penrith +Sirhāli Kalān +Pushing +Ratnāpuram +Undrājavaram +Clayton +Dębno +Maní +Argentan +Woodland Park +Soyaniquilpan +Badhoevedorp +San Rafael Oriente +Arendonk +Weinsberg +Cremlingen +Oued Tlélat +Padaivedu +El Tabo +Berezne +Catemu +Reggada +Zehdenick +Aginiparru +Rogers +Aguilar +Bayt Sāḩūr +Bocaiúva do Sul +Hüllhorst +Annāmalainagar +Kūhbil +Pānchgani +Terebovlya +Guillena +Fatehpur +Vetralla +Gura Humorului +Standish +Ang Thong +Carros +Xylókastro +İkizce +Ettāpur +Blytheville +Tummanatti +Montepulciano +Schüttorf +Thame +Ergolding +Ŭrtaowul +West Boldon +Raghunāthpur +Outreau +Portage La Prairie +Joaquim Nabuco +Buttar +Żnin +Sulingen +Modakkurichchi +Lincolnwood +Sečanj +Amilly +Ban Chomphu Nuea +Bugugoucun +Skoghall +Tarhūnah +Tanagura +Rābor +North Greenbush +Los Chiles +Peringom +Naranja +Baş Göynük +Linlithgow +Knutsford +Aldeia de Paio Pires +Torquay +Liangwancun +Karivalamvandanallūr +Doddipatla +El Tablón +Tala +Īnderbor +Orange City +Kings Park West +Olfen +Peshkopi +Arês +Steamboat Springs +Trophy Club +Montespertoli +Muragācha +Khoyniki +La Victoria +Herbrechtingen +Fehmarnsund +New Kingman-Butler +Loveland +Dingle +Sumbha +Empedrado +Paraíso do Norte +Usumatlán +Cornelius +Ad Duraykīsh +Kuttyattur +Puerto San Martín +Pé de Serra +Ortaklar +Chhapra +Östringen +Lubsko +Gangelt +Manivilundān +Šternberk +Dharmaram +Beverungen +Lawang Bato +Ulvila +Daulatnagar +Moody +Aïn Youcef +Nanjai Kilābādi +Dharphari +Casandrino +Casatenovo +Kasumkent +Borodyanka +Damaishan +Andrésy +Perladka +Ivaí +Santa Juana +Gvardeysk +Glendale +Sebt Labrikiyne +Sābang +Pervomaysk +Afir +Mahalpur +Gopālasamudram +Mesudiye +Slobozhanske +Sarria +Chiroqchi +Nioaque +Basseterre +Orangeburg +Beelitz +Jūla Buzarg +Palos Verdes Estates +Yakage +Muriedas +Pácora +Arsali +Mathurāpur +Bichkunda +Shin'onsen +Fátima +Blegny +Lariano +Morangis +Yamato +El Kansera +Kathevaram +Khiria +San Martino di Lupari +Dorado +Walsall Wood +Ambohidronono +Bondāda +Chulumani +Beyla +Værløse +Novellara +Noceto +Douar Sidi Laaroussi +Xaafuun +Çamardı +Benairia +Tonakkal +Guttal +Kuressaare +Trebur +Aïn Lechiakh +Tempio Pausania +Southwick +Las Vegas +Bombarral +Chenggong +Bundāla +Gmunden +Nemours +Hissāramuruvani +Cheval +Liedekerke +Jobat +Vila Pouca de Aguiar +Carpinteria +Ban Khlong +Rio de Contas +Villacidro +Castelnuovo di Verona +Mārathalli +Zayda +San Clemente +Belëv +Oncativo +Parvomay +Fraserburgh +Püspökladány +Cedar Grove +Kingersheim +Sovetskoe +Auria +Portland +Bischofsheim +Hashikami +Cariamanga +Santa Teresa +Bagadó +Mānikpur +Mouvaux +Weddington +Newton +Plaza Huincul +Melilli +Druskininkai +Bou Arada +Penamalūru +La Llagosta +Qal‘eh Ganj +Casale sul Sile +Uyar +Graulhet +Leżajsk +Medway +Hājan +Canals +Santa María de Ipire +Ceyu +Samālsar +Ridgefield Park +Santa Margarita +Miahuatlán +Vestby +San Jerónimo +Ban Chorakhe Samphan +’Aïn Mouilah +Zabaykalsk +Harrison +Villa Juárez +Villa Sandino +Mulungu do Morro +Capaya +Igrapiúna +Mahao +Matsushima +Drochia +Karabanovo +South Glengarry +Hulkoti +Santa María Jalapa del Marqués +Tinglayan +Caerfyrddin +Pell City +Nako +Rio do Antônio +Superior +Autun +Ban Nong Hoi +Singuilucan +Głuchołazy +Chañaral +Vigodarzere +Sharon +Alovera +Balya +Hamworthy +Bajala +Asjen +Mutterstadt +Crispiano +Bålsta +Sali +Pacatuba +Radomir +Kaua Kol +Sainte-Marie +Novi Bečej +Latisana +Trenton +Bom Princípio +Shīnīlē +Gothva +South Daytona +Bensekrane +North Perth +Monteux +Sarezzo +Ketsch +Qulan +Kofelē +Tetāri +Kaspiyskiy +Saktipur +Ksibet el Mediouni +Ba Chúc +Sankt Georgen im Schwarzwald +Sátoraljaújhely +Ayodhyāpattanam +Plattling +Cicuco +Chino Valley +Berkeley Heights +Sidmant al Jabal +San Vicente +General Enrique Mosconi +Brieselang +Dover +Giporlos +Alvorada D’Oeste +Silago +Koregaon +Mahaboboka +Maqsūda +Tubmanburg +Altos +Iraci +Wehr +Betatao +Treuchtlingen +Barhī +Toura +Rosbach vor der Höhe +Miarinarivo +Brig-Glis +Quattro Castella +Phalaborwa +Bergen +Sargūr +Shitāb Diāra +Kanabūr +Kallūr +Gland +Wantage +Rājupālem +Grand Terrace +São Domingos +Tirumakūdal Narsipur +Pavona +Mounds View +Fyzabad +Kozy +Miranda do Corvo +Mazatlán Villa de Flores +Kavitāl +Medapādu +Lake Los Angeles +La Grande +Barsbüttel +San Martín Zapotitlán +Kottāram +Mercedes Umaña +Chos Malal +Albatera +Wollaston +Taishi +North Palm Beach +Güçlükonak +Soddy-Daisy +Stoughton +Wolvega +Joure +Pomfret +Itano +Harrison +Al Jumaylīyah +Bocholt +La Vega +Tōnoshō +Akseki +Küssnacht +San Antonio del Tequendama +New Hanover +Phra Samut Chedi +Betanzos +Darłowo +Ionia +Horst +Andaraí +Caldeirão Grande +Great Driffield +Gex +Gurlapeta +Takkolam +Çavdır +Simijaca +Chandhaus +Udaipur Bithwār +Kamikawa +Krasnozavodsk +Peddavadlapūdi +Ekwāri +Huguan Nongchang +Nasiyanūr +Hungen +Motobu +Oatfield +Gouandé +Fannūj +Cherry Hill Mall +Dărmăneşti +Apostolove +Pendlebury +Goodmayes +Gorakhpur +Makabana +Killai +Scheeßel +Kalikiri +Pallappālaiyam +Cotegipe +Sudbury +Jālhalli +Dinbéla +Adi Keyh +Milnrow +Ribeirão do Pinhal +Paina +West Carrollton +Cambridge +Kuruman +Hajdúhadház +Balua +Mohgaon +Norwalk +Kafr ‘Awān +On Top of the World Designated Place +Lamaçães +Muri +Castlebar +Rabot +Balatonfüred +Nidzica +Alto Garças +Dom Feliciano +Vetlanda +Godella +Gamboula +Forlimpopoli +Kani-Bonzon +Alcácer do Sal +Chernigovka +Afanyangan +Monte Belo +Danga +La Crucecita +Manturovo +Turvo +Pandireddigūdem +Bedford +Hadamar +Fatehpur +Hawaiian Paradise Park +Aberystwyth +Drongen +Rasauli +Mettet +Velykodolynske +Dahu +Charābidya +Thompson +Turbihāl +Palmital +Olivar Bajo +Olivar +Rödental +Tezontepec +Stjørdalshalsen +Lowshān +Shahr-e Herāt +Nova Gorica +Capo d’Orlando +Ajas +Fernandina Beach +Dārāsuram +Neykkārappatti +Missões +Holborn +San Pietro Vernotico +Dayālpur Sāpha +Barāon +Caledon +Shīn +Bolongongo +Neuri +Dinshawāy +Brackley +Claremont +Ubaporanga +Fatehpur +Bārah +Candiba +Tetiiv +Linnich +Leibnitz +Peddakūrapādu +Gangoli +Bohmte +Kalaiyamputtūr +Belpukur +Forrest City +Ampanavoana +Thara +Montgomeryville +Chandauli +Sidhwān +Kaji +Wasserburg am Inn +Lawaan +Quzanlı +Webb City +Kahhalé +Ambararata +Marovandrika +Morafeno +Andreba +Marovato +Ampitasimo +Ambohimahavelona +Isaka-Ivondro +Ambodiampana +Andranomamy +Ihorombe +Mahatsinjo +Antongomena-Bevary +Antsirabe Afovoany +Sahavalanina-Antenina +Belemoka +Mavorano +Evato +Tranovaho +Amborompotsy +Ambalakindresy +Ambahoabe +Vohitrindry +Befandriana +Ampanefena +Ankilivalo +Anjiajia +Ambatondrakalavao +Kirano +Sakoabe +Maroviro +Ambakireny +Tsiately +Ambohitsilaozana +Ambazoa +Ambodisakoana +Bemanevika +Ambondrona +Ambatolampy +Bejofo +Manambolo +Mangindrano +Ankilimalinika +Sandrakatsy +Marojala +Ilafy +Morarano +Mandritsara +Befeta +Amboaboa +Manambidala +Andohajango +Ḩarmah +Sunne +Kumi +Alaverdi +Neunkirchen +Midsomer Norton +Galashiels +Jalam +Ghorādongri +Moviya +Amauna +Dammennu +Timberlake +Divnoye +Lavello +Bhalil +Ksar Sghir +Vieira do Minho +Bocas del Toro +Jennings +Manalalondo +Miami +Sebt Bni Garfett +Anandāpuram +Waconia +Gornalwood +Lohiyār Ujain +Ficarazzi +Baduriātola +Kottapadi +Kara-Kyshtak +Chhāra +Chāwalhāti +Nacozari de García +Noyon +Ridge +West Monroe +Korneuburg +Steinkjer +Paso de los Toros +Zandhoven +Sai Wan Ho +Kibiito +Ivanić-Grad +Kollipara +Vrbovec +Bisee +Chã da Alegria +Antônio Prado +Green Valley +Yiewsley +Chāng +Rochester +Schleiden +Höör +Jiānganj +San Lucas +Kanel +Fouriesburg +Pretoria-Noord +Culaba +Roding +Sitalpur +Ben +Turi +Barwat Pasrāin +Phulwaria +Bachrā +Senmayachō-senmaya +Larkspur +An Thành B +Wanderley +Rovinj +Chapantongo +Casinhas +Wickede +Lingamparti +Itatiaiuçu +Abarán +Uppāda +Troy +Juan de Herrera +Palangarai +Mizil +Garhi +Shenley Church End +Campo de Criptana +Montesarchio +Cardoso Moreira +Kingsbury +Shanyincun +Wicklow +Kūdangulam +Santa Ana +Schodack +Pingtiancun +Jhaua +Montefiascone +Pucioasa +Mogocha +Flint +Saposoa +Mirdaul +Bocşa +Mulakalūru +Libertad +Wächtersbach +Vinings +Jaitpur +Solana Beach +Svirsk +Tartarugalzinho +Sant Sadurní d’Anoia +Lakkavaram +Carpenedolo +Cherutana Tekku +Brejões +Pelham +Maktar +Shiwan +Saint-André +Camponogara +Elandsdoorn +Bou Fekrane +Nossa Senhora do Livramento +Gibraleón +Kent +Sākhmohan +Grantsville +Fokino +Japoatã +Amboise +Rāmpur Shāmchand +North Adams +Matinilla +Trebaseleghe +Gomparou +Morungaba +’Aïn Tolba +Newcastle +Bni Khloug +Isalo +San Pablo +Meadville +Kachavaram +Song Phi Nong +Ātmakūru +Qal‘at al Maḑīq +Lynnfield +Nova Londrina +Fengdeng +Byram +D'Iberville +Paranhos +Woolton +Sint-Gillis-bij-Dendermonde +Tarnos +Amarwā Khurd +Tezze sul Brenta +Valparaíso +Chamical +Holly Hill +Buritirama +Möckern +Castiglion Fiorentino +Bujari +Berja +Statte +St. Ann +Messadine +Kalanaur +Tonoshō +Balbalan +Odder +Schinnen +Anolaima +Leagrave +Besigheim +Châteaudun +Cusset +Český Krumlov +Quierschied +Lahaina +San Mateo +Barra de Santa Rosa +Tashi +Fostoria +Karāhal +Dardenne Prairie +Khomām +Bijelo Polje +Amolatar +Kapchorwa +Goonellabah +Corat +Mayenne +Cliftonville +Kankandighi +Trent Hills +Vellakkinar +Tirmaigiri +Loreto +Chợ Mới +Roßdorf +Gurgunta +Sisauna +Bairia +Kalappālangulam +Monteprandone +Bonneville +Yuza +Petrus Steyn +Sim +Wommelgem +Apuiarés +Saghar Sultānpur +Bāgewādi +Moreira +Buckingham +Vyazemskiy +Esneux +Elavanasūr +Pentapādu Kasba +Misaki +Barja +Mándra +Kalavai +Crissiumal +Uzwil +Ambalarondra +Brønderslev +Highlands +Kapelle +Sangão +El Dorado +Ricaurte +Ayutla +Khombole +Ringnod +Edattirutti +Daru +Neunkirchen +Suzu +Cidelândia +Athens +Suamico +Moorreesburg +Nurkot +Frutillar +Koturkolkara +Keisen +Mountain Home +Căuşeni +Kalush +Lontras +Palombara Sabina +Harrison +Kuala Kurun +Smyrna +Finneytown +Alāyaman +Colares +Purén +Red Bank +Agutaya +Tanakkangulam +Woodhaven +Vejer de la Frontera +Chilwell +Vadnais Heights +Wadersloh +Trail +Múggia +Calcinato +Salisbury +Akayu +Pôrto Murtinho +Mansāpur +Rehti +Mūlaikkaraippatti +Ganapavaram +Lanuvio +Dhutauli +Tehachapi +Mora +Ecublens +Saint-André-de-Cubzac +Chinnasekkadu +Daparkha +Nuevo Ideal +Malaryta +Baláo +Abrera +Saunshi +Cheney +Argentona +Vedappatti +Niandjila +Zhongling +Palmares do Sul +Rahika +Medfield +Aldoar +Bihārīganj +Sidlice +Acasusso +Sugauna +Meriç +Florida City +Dedemsvaart +Guéret +Emeryville +Lansdowne +Auriol +Cavallino +Kallād +Fuldatal +Janāi +Meddappakkam +Puerto Jiménez +Bloomsburg +Seclin +San Pietro in Casale +Terrasini Favarotta +Santa Rosa de Calamuchita +Kādachchinallūr +Quartucciu +Vicente Guerrero +Herzberg am Harz +Sattar +Barhauna +Oxapampa +Sagay +Santuario +Kaul +Palacagüina +San Juan Tecuaco +Spilamberto +Syasstroy +Canelinha +Samé +Raymond Terrace +Mullasshēri +Nieuw Nickerie +Salempur +Fontanafredda +Cornwall +Sugarland Run +Juan L. Lacaze +Tega Cay +Nova Crixás +Frederiksværk +Santa Cruz Amilpas +M’dhilla +Leopold +Arakere +Nartan +Castellbisbal +Antonivka +Bad Urach +Ganga +Spiez +Qazmalar +Buenos Aires +The Nation / La Nation +Bolintin Vale +Nova Timboteua +Ziro +Pueblo Nuevo +Bela Simri +Bhagwānpur Khurd +Douar Oulad Youssef +Aš +Brenes +Syston +Little Lever +Chiatura +Venkatagirikota +Rosario del Tala +Bāzidpur +Ban Krang +Bag‘dod +Yozyovon +Santo Tomás La Unión +Govindgarh +Yelmalla +Rose Belle +Gorokhovets +General Las Heras +Teror +Salzano +Kachchippalli +Spiesen-Elversberg +Chinnakkāmpālaiyam +Milngavie +Tucson Estates +Kalecik +Arohi +Overlea +Toukoroba +Burgos +Kurwa Mathiā +Santa Fe +Springbok +Lokāpur +Florham Park +Kyotera +Rio Casca +Gaura +Santa Maria do Suaçuí +Rāmpurwā +Concepción de Ataco +Hulyaypole +Mallāpur +Lumberton +Yavoriv +Mesolóngi +Kasba Tanora +Santa Ana de Yacuma +Juvignac +Aghbala +Franeker +Peißenberg +Jasauli +Oudenbosch +Twistringen +Kannudaiyāmpatti +Taldom +Sanderstead +Mudhol +Kanbara +Pichilemu +Ocós +Saint-André-les-Vergers +Bayeux +Ashibetsu +Tizgane +Donwari +Nangavalli +Landeh +Festus +Velilla de San Antonio +Chojnów +Loyish Shaharchasi +Gavere +Lagoa Dourada +Sørum +Harpur Bochaha +Nandyālampeta +Greenville +Perez +Huazalingo +Chalfont Saint Peter +Magdalena Milpas Altas +Brzeg Dolny +Agdangan +Novo Lino +Kaufungen +Chodavaram +Zag +Perehinske +San Anselmo +Ban Tat +Dhubaria +Chāhatpur +Sedriano +Sarahandrano +Rodeio +Bariyārpur +Maheswa +Granarolo del l’Emilia +Grover Beach +Anaikal +Antanandava +Mahārājpur +Valbonne +Big Bear City +Casteel +Kaeng Khoi +Villa San Giovanni +Kouti +Vadasseri +Nawāda Gobindganj +Barud +Kolappalūr +Florence +Roudnice nad Labem +Serra Azul +Kāmrej +Maroli +Eufaula +Adygeysk +Accokeek +Rokupr +Keerbergen +Guymon +Beaufort +Wietmarschen +Begampur +Ilicínia +Dharampur Bānde +Cavarzere +Terrabona +Amherst +Ban Sop Tia +Bahādurpur +Kochłowice +Samashki +Majārhāt +Chinna Gollapālem +Calcinaia +Mahābaleshwar +Yemva +Sebiston +Vilanova del Camí +Surkhakhi +Bandlagūda +Oakland +San Salvador +Chodov +Aţ Ţūr +Jāmi +Almirante +Gärtringen +Sonbarsa +Köprübaşı +Sete Barras +Châlette-sur-Loing +Duvvūru +Joanópolis +Les Ponts-de-Cé +Obalāpuram +Sulz am Neckar +Canillá +Ainsdale +Ivanec +Mar de Espanha +Richton Park +Oulad Rahmoun +Staryye Atagi +Khorol +Brus Laguna +Emmiganūru +San Francisco de Mostazal +Laamarna +Alcalá +Debbache el Hadj Douadi +San Antonio Aguas Calientes +Bakhtāwarpur +Mahtha +Kirchheim bei München +Varzaneh +Kyōtamba +Pīrnagar +Bāri +Annapolis Neck +Hvardiiske +Chaiyo +Novi Pazar +Krupka +Playa Grande +Dāmarcherla +Seïada +Kaspi +São Félix da Marinha +Pennsville +Sivalārkulam +Mādugula +Buffelshoek +Woolwich +Miranorte +Nirakpurpāli +Serere +Honggu +Lymm +Flitwick +Zelzate +Umag +Patti +Samāi +Battulapalle +Sason +Puerto Ayora +Caió +Betton +Sante Bennūr +Zelenodolsk +Bāsmenj +Librazhd-Qendër +St. Marys +Brad +Peraiyūr +Gricignano d’Aversa +Altenstadt +Buharkent +Chüy +Mānākondūr +Bamhnī +Sangtŭda +Ālampur Gonpura +Nicosia +Bou Adel +Dianguirdé +Dianké +Challapata +Santiago Amoltepec +Ấp Bình Thành +Feuchtwangen +Mechtras +Northlake +Wawarsing +Delémont +Saint-Hilaire-de-Riez +Hersbruck +Maniyur +Itayanagi +Manorville +Marysville +Derventa +Hedensted +Daharia +Luchong +Cuisnahuat +Brownhills +Amos +Beausoleil +Aït Youssef Ou Ali +Morazán +Paradise Valley +Winterberg +Comines +Olgiate Olona +Neosho +Geneva +Taguaí +Wilmington +Ceuti +Dunkirk +Bad Abbach +Diari +Blaubeuren +Mèze +Shilka +Shirataka +Fords +Vineyard +Herk-de-Stad +Kotturu +Wickliffe +Kelso +Gerpinnes +Pūdūru +Cairo Montenotte +Hornsey +Tamm +Mugutkhan Hubli +Valverde del Camino +Santo Stino di Livenza +Ahermoumou +Kuçovë +Malmédy +Balpyq Bī +Pasadena Hills +Malhador +Lukoyanov +Nakhla +San Biagio di Callalta +Sheopuria +Gaffney +Branson +Waltershausen +Ouzera +Sinincay +Takamori +Bom Repouso +Qiaotouba +Alpen +Sutton on Hull +Tilāri +Schongau +Fulton +Novhorod-Siverskyi +Awantipur +Newington Forest +Robertsville +Market Warsop +Warsop +Bad Windsheim +Nangola +Isla Mujeres +Petrovske +Ziama Mansouria +El Menzel +Al Muzayrīb +Fortaleza dos Nogueiras +Saltcoats +Pondūru +Los Hidalgos +Horndean +Holiday City-Berkeley +Melvindale +Groutville +Rio Vermelho +Koyulhisar +Puttānattam +Kākan +Tenmalai +De Haan +North Walsham +Adukam +Kanniyambram +San Marco in Lamis +Souakene +Artesia +Dores do Indaiá +Tomball +Enumclaw +Baykalsk +Shchastia +Jaroměř +Naduhatti +Costa Marques +Victoria +Knittelfeld +Burj al ‘Arab +Kādiyāmpatti +Ấp Phú Hải +Sirūr +Bonito +Castel Goffredo +Teroual +Maxcanú +Junín de los Andes +Presidente Jânio Quadros +Jalpura +Cunda diá Baze +Simri +Ulster +Cedral +Gürgentepe +Villeneuve-lès-Avignon +Motkūr +Xalpatlahuac +Concepción Las Minas +Ottawa +Summerstrand +Sagopshi +Parigi +Rehoboth +Apía +Isla Ratón +Buchs +Steinheim +Jüterbog +Üllő +Saka +Mamakating +Tamsaout +Santa Bárbara de Pinto +Topliţa +Chariyakulam +Oulad Ouchchih +Yenipazar +Bretzfeld +Levelland +Winnetka +Minooka +Lakeland South +Kharak Kalān +Magsaysay +Road Town +Brunsbüttel +Garh Sisai +Belagal +Muttanampālaiyam +Mendota +Tagoloan +Sarıveliler +Luchenza +Galaosiyo Shahri +Eski Arab +Ələt +Queluz +Santiago +Angādikkal Tekkekara +Hessisch Lichtenau +Puerto López +Yzeure +Canet-en-Roussillon +Hosir +Yuzha +Stupava +Lamphun +Khagra +Grenada +Wetaskiwin +Diéli +Brown Deer +New Germany +Dossenheim +Mīnākshipuram +Sandy +Ibiraçu +Jeppe’s Reef +Chropaczów +Zimnicea +Viotá +Cevicos +Ban Tom Klang +Kortemark +Vilsbiburg +Mahuākherāganj +Koppal +Hayashima +Găeşti +General Acha +Sangar +Wordsley +Granville +Lindsay +Jensen Beach +Chandwā +San Vicente +Lamballe +Vatra Dornei +San Rafael +Tuzdybastaū +Wieringerwerf +Pago Pago +Apricena +Dabat +Dingman +Vidauban +Karedu +Dongyuancun +Osečina +Adré +Saint-Jean-de-Védas +Kamalāpuram +Āppukkudal +Chok Chai +Vasylivka +Duartina +Gueltat Sidi Saad +Tirukkāttuppalli +Kanra +El Fuerte +Campbelltown +Lipari +Tərtər +Quirihue +Niefern-Öschelbronn +Salobreña +Croxley Green +Upper +Ancuabe +Fene +Prymorskyi +Olen +Lucena +Maba +Vohimarina +Birni +Cloquet +Progreso +Wadhraf +Rochefort +Mandrāmo +Rong Kwang +Murud +Nohsa +Parasurāmpūr +Diamou +Calanasan +Cuers +Armadale +Pilich +Marikal +Devāpur +Osiān +Sankt Veit an der Glan +Viera East +Fonsorbes +Pajo +Lakhipur +Dysselsdorp +Sabugal +Petrov Val +Rantoul +Monte Quemado +Hirschaid +Kwīhā +Monóvar +Cascades +Brunswick +Ban Laem +Chai Nat +Conceição do Rio Verde +Makuyu +Baraboo +Lüderitz +La Carlota +Palos de la Frontera +Kawamata +Petushki +Sarare +Emstek +North Smithfield +Avrig +Nakhtarāna +Varazze +Kantang +Jiuduhe +Turki +Hisarcık +Röthenbach an der Pegnitz +Preußisch Oldendorf +Mablethorpe +Chiampo +Betma +Mahrail +Brock Hall +Māyamānkurichchi +Bacalar +Chikura +Fortuna +Lake Norman of Catawba +Villa Sola de Vega +Hansot +Justice +Iconha +Montegranaro +Tola Khadda +Fort Atkinson +Montividiu +Eloxochitlán +Santo Niño +Champādānga +Kewatgāwān +Ereymentaū +West Grey +Ladenburg +Ialoveni +Teulada +Asbury Lake +Zella-Mehlis +Creutzwald +Kłobuck +Gladenbach +Goražde +Buchach +Fort Bliss +Campinorte +Borgo San Dalmazzo +Qārah +Marabella +Kashasha +Beydağ +Pilar +Edemissen +Gumani +Sāvalgi +Borger +Wolsztyn +Pannaikkādu +Falmouth +Sattēgālam +Elkhotovo +Campo Alegre +Stony Brook +Miary +Włodawa +Panj +Culfa +Usmānpur +Dhanupra +Sarasota Springs +Anjahambe +Paithān Kawai +Kameshkovo +Xiaping +Giánnouli +Rionero in Vulture +Goldenrod +Codegua +Nanzhai +Coringa +Pütürge +Wolverton +Zuvvaladinne +Gosaingaon +Hînceşti +Uludere +Canegrate +Baūyrzhan Momyshuly +Georgetown +Kingsburg +Negotino +Devsar +Laarne +Grave +El Adjiba +Saint David’s +Beaumont +Vikāsnagar +Ālwārkurichchi +Xavantes +Alto do Rodrigues +Kotwāpatti Rāmpur +Rozhyshche +Bang Phlat +Ingeniero Maschwitz +Okinawa Número Uno +Neuenburg am Rhein +’Aïn el Assel +Boone +Jerome +Ocna Mureş +Santañy +Domahani +Nāysar +Thair +Poquoson +Mariental +Kamin-Kashyrskyi +Tiruppālai +Chabāl Kalān +Lana +Kathāniān +Pidigan +La Argentina +San Miguel Panán +Arhribs +Upper Uwchlan +Kuttiyēri +Andernos-les-Bains +Shāhpura +Bheja +Zaladanki +Logan +Made +Raamsdonksveer +Robinson +Sedro-Woolley +Rānranagudipeta +Canóvanas +Lakshmīnārāyanapuram +Somerville +Matatiele +Santa Ana Maya +Voerendaal +Ban Bang Non +Parker +Sîngerei +Bryne +Mira +Hacılar +Sylacauga +North St. Paul +Kuhsān +Costessey +Baker +Chaval +Mongat +Barton upon Irwell +Pātiram +Eyvānekey +eXobho +Ounagha +Reshuijie +Xinyingheyan +Cetinje +Sântana +Busogo +Iferhounene +Pont-du-Château +San Bartolo +Putussibau +Guruvarājukuppam +El Tambo +Cromer +Refahiye +Santana do Matos +Nakskov +Bickenhill +Haddonfield +Highland City +Rozenburg +Vernouillet +Engenheiro Beltrão +Macará +Sillamäe +Bad Sassendorf +Graben-Neudorf +Bandi̇̄pur +Uren +Tilbury +Chigwell +Castelnaudary +Anna Regina +Ahirauliyā +Harrai +Fagnano Olona +Bagnolo Mella +Port Washington +Kobiri +Zonnebeke +Boumia +Sátão +Gamarra +Čelákovice +Prairie Ridge +Ozatlán +Bhanas Hivre +Sangān +San Marino +Upper Montclair +Finspång +Kanoni +Hanumantanpatti +Wimauma +Nelmadūr +Villa Literno +Shichuanxiang +Gravatal +Bischwiller +Matsukawa +Kānkon +Gogui +Goiatins +Los Santos +Gohpur +Viterbo +Koszutka +Bandalli +Balchik +Kallupatti +Campiglia Marittima +Sint-Michiels +Bairia +Velten +Dhansura +Oshikango +Guática +Pueblo Rico +Palmer +Ambatomainty +Titara +Massena +Provadia +Jequeri +Chachagüí +Warman +Gulshan +Taiynsha +El Ayote +El Ayote +Mallappulasseri +Los Bellosos +Hersham +Maglód +Huodoushancun +Hizan +Gaildorf +Hullatti +Bayona +Grammichele +Madiama +Meerzorg +Aywaille +Kadiana +Vallejuelo +Escanaba +Boussé +Kolattūr +Mehnatobod +Kegeyli Shahar +Mango +Las Lomitas +Prilly +Hagenow +Maraiyūr +Hinundayan +Siki +Kika +Neerijnen +Edgewood +Koluszki +Xinbocun +Mikashevichy +Xinchangcun +Ponnai +Buttāyagūdem +Arcozelo +Trogir +Sarābleh +Ambinanynony +Khvalynsk +Payyanpalli +Calvizzano +Poço Branco +Titisee-Neustadt +Riverview +Kalingiyam +Brignais +Triel-sur-Seine +Orzinuovi +Amelia +San Pedro Jicayán +Ebersberg +Ammavārikuppam +Kamtaul +El Aouana +Bollnäs +Tendūkheda +Chennampatti +Boortmeerbeek +Quinta de Tilcoco +Kallamalai +Lyelchytsy +Pira +Spondon +Attanūr +Anzola dell’Emilia +Panjīpāra +College +Lewisburg +Las Parejas +Sher +Złocieniec +Estepa +Derby +Santa Ana +Saboyá +Arma +Shamsābād +Conneaut +Asfarvarīn +Tyngsborough +Avigliana +Nanakuli +Martinsville +Ilmajoki +Olagadam +Oissel +Villafranca de los Barros +Dokkum +Ribeirão Claro +San Antonio +Issum +Seravezza +Vardenis +Dharhara +Bad Freienwalde +Aubenas +Mi‘rabah +Sarrebourg +Moka +Essenbach +L’Union +Forécariah +Ichora +Coseley +Sever do Vouga +Fojnica +Torroella de Montgrí +Porto Recanati +Higashiagatsuma +Gonzales +Taraclia +Biliaivka +Pola de Laviana +Ierápetra +Reẕvānshahr +Piano di Sorrento +Arluno +Tüp +Nitte +Bayanaūyl +Sydney Mines +Gaimersheim +Nobeji +Vobkent Shahri +Ovenden +Tenambākkam +Chepstow +Sabinov +Drouin +Dubak +Blackfoot +Kladanj +Koskāpur +Cobh +Lye +Payariq Shahri +Jork +Herrin +Patchogue +Rinconada de Malloa +Alampur +Oulad Fares +San Miguel Xoxtla +Kataysk +Union +Alkhan-Kala +Razlog +Bad Fallingbostel +Capdepera +Mandalgovĭ +Tiszavasvári +Huai Yot +Mutoko +Bourem Inali +Nong Khae +Bandwār +Amersfoort +Kalajoki +Laguna Paiva +Foča +Maqu +Vysoké Mýto +Pontecorvo +Soubala +Mecatlán +Yoko +Oulad Aïssa +Bozkurt +Aphaur +Leonforte +Jaidte Lbatma +Ḩawsh al Baḩdalīyah +Periyakoduveri +Boumalne +Dehqonobod +Valencia +Dragør +Diamniadio +Enkesen +Kibuye +Manchester +El Carmen +Kálymnos +Kāttukkottai +Desri +Bulgan +Capul +Navelim +Dawson Creek +Shuangxianxiang +Teotepeque +Valga +Jānkinagar +Sidney +Harnes +Aubergenville +Bodaybo +Mende +Crestwood +Dasraha Bhogrājpur +Cottonwood +North Castle +Sędziszów Małopolski +Cambuquira +Quimperlé +Cypress Lake +Bou Arkoub +Anklam +Ocean Pines +Kotia +Río Grande +Gravenhurst +Enniscorthy +Emiliano Zapata +Heliópolis +Sūreshjān +Shamaldy-Say +Lake City +Nkheila +Wernau +Chettipulam +Pandalkudi +Frohburg +Biassono +Makeni +Aj Jourf +Susa +Hasanpur +Tonyrefail +Garden City +Madison +Obikiik +Qorao‘zak +G’oliblar Qishlog’i +Giffnock +Prince Rupert +Sacacoyo +Vöcklabruck +La Motte-Servolex +La Chapelle-Saint-Luc +Kakching Khunou +Paikpar +Sendafa +Ar Rommani +Acarlar +Atmākūr +Webster +Lavagna +Jefferson Hills +Veurne +McComb +Bom Retiro do Sul +Nawāda +Kot Shamir +Rivarolo Canavese +Narman +Arbeláez +Sidi Makhlouf +Charmahīn +Leeds +Ain Kansara +Pont-Sainte-Maxence +New Mills +Melavāyi +Guisser +Sala +Cananéia +Pebberu +Gandorhun +Acalá del Río +Lavínia +German Flatts +Claye-Souilly +Lodhīkheda +Eraniel +Kasaishi +Penal +Teningen +Bouca +Haslev +Thatto Heath +Benisa +Hathwān +Streator +Soklogbo +Pendências +Home Gardens +Doctor Phillips +Erumaippatti +Yenkuvārigūdem +Lower Pottsgrove +Fairfax Station +Kafr Rūmā +Baikunthpur +Kulattūr +Wołów +Newman +Gharbia +Polās +Burladingen +Sevūr +Baños +Hatillo de Loba +Ludwigslust +Harrow on the Hill +Béjar +Dagmāra +Spearfish +Dinkelsbühl +Pantepec +Córdoba +Razua +Jerônimo Monteiro +Kamalnagar +Villa Unión +Beyləqan +Cicciano +Doi Lo +Perth East +New Britain +Tzintzuntzán +Godohou +Neuhausen auf den Fildern +Nurhak +Teixeiras +Gandara West +Anderlues +Gavardo +Commerce +Oulad Hamdane +Ban Tap Tao +Belén +Abū Dīs +Juchipila +Marumori +Malloussa +Alucra +Chasiv Yar +Laichingen +Pāiker +Mekra +Mahespur +Khujner +West Deer +West Plains +Senjān +Eral +Pital +Ogulin +Ouénou +Kallanai +Zābolī +Boloso +Effingham +Doddanahalli +Manamodu +Engenheiro Paulo de Frontin +Spresiano +El Campo +Porto Valter +Lila +Selston +Ban Huai So Nuea +Carnaubeira da Penha +Neralakaje +Narala +Scotts Valley +Cuichapa +Nordstemmen +Linkenheim-Hochstetten +Tempoal de Sánchez +Sala Consilina +Beatrice +Itiquira +La Palma +Sidi Aoun +North Saanich +Ramabitsa +Kinrooi +Zetel +Newhaven +Gopālnagar +Chāmarru +Presidencia de la Plaza +Morbegno +Hattem +Steinheim am der Murr +Bhachhi Asli +Karrāpur +Affoltern am Albis +Apen +Emboscada +Barra do Ribeiro +Maxhütte-Haidhof +Mesker-Yurt +Warwick +Sernovodsk +Hassi Fedoul +Bully-les-Mines +Ammāpettai +Dharmastala +Pathra +Újfehértó +Bampūr +Haaren +Obernai +Birstall +Puduvayal +Malone +Currimao +Chêne-Bougeries +Krasnyy Yar +Fómeque +Hanūr +Cedarburg +Bom Lugar +Arara +Tsuruta +Yakoma +Chichli +Okabechō-okabe +Anao +Hengshan +Kumirimora +Ghogha +Lauriyā Nandangarh +Rottofreno +Josefina +Bershad +Vrchlabí +Profondeville +Kolanpāk +Yakouren +Koriukivka +Brejinho +Kottagudi Muttanād +Montecorvino Rovella +Karaburun +Paxtaobod +Kuyganyor +Andijon +Yangiariq +Sabbavaram +Belwa +Lobería +Paranatama +Sogndal +Loiyo +Concepción Batres +Cristais +Santa Leopoldina +Rudrūr +Diamond Springs +Bukkapatnam +Tamalpais-Homestead Valley +Lake Tapps +Te Awamutu +Mariyammanahalli +Dorandā +Lewisboro +Kafr Buhum +Port Victoria +La Magdalena Chichicaspa +Unguía +North Merrick +Adelaide +Hnivan +Hobro +Turki +Namchi +Russi +Châteaubriant +Karimkunnum +Malvinas Argentinas +Saraiya +San Mauro Pascoli +Vulcăneşti +Oftersheim +Richland +Santo Domingo +’Aïn Kerma +Bashtanka +Nevele +Kuttūr +Kewanee +Caledonia +Pianiga +Pasca +Rognac +Bhaisālotan +Katagon +Uppukkottai +Wrentham +Moss Point +Vylgort +Osterhofen +Prévost +Tömük +Rüti +Ghorādal +Sakawa +Tiadiaye +Rafína +Olton +Srīnagar +Tioribougou +Nemili +Villamartín +Cheadle +Bhankarpur +Riedisheim +Bonyhád +New Kensington +Le Grand-Saconnex +Santa Elena +Matāla +Kayattār +Brattleboro +Puerto Nare +Kōttāya +Vannivedu +Na Wa +Sagon +Tholey +Vandithāvalam +Grafton +Botlikh +Khonobod +Huétor Vega +Claiborne +Ebéjico +Raipur +Encamp +Barentin +Choctaw +Dranesville +Gajhara +Błonie +Morab +Oyón +Liperi +Rāghopur +Samādh Bhai +Wasilków +Rielasingen-Worblingen +Marquetalia +Arganil +Gyomaendrőd +Kesarimangalam +Ban Bo Luang +Cocotitlán +Havixbeck +Panzgām +Grumo Appula +Tranent +Eklahra +Barsaun +As Sars +Mucugê +Xiushuicun +Muthuswāmipuram +Minabe +Sainte-Adèle +Ban Bang Sai +Ban Noen Phoem +Sapna +Sainte-Agathe-des-Monts +Justo Daract +Mulug +Marsaskala +Meitingen +Bømlo +Camp Verde +Strzelin +Salgado de São Félix +Pachchaimalaiyankottai +Mangarwāra +Eura +Māndu +El Sobrante +Bela Palanka +Bamber Bridge +Macedonia +Hagfors +Lakeside +Socuéllamos +Ampasimbe +Cherlak +Antri +Pornichet +Velair +Riviera Beach +Ishkāshim +Kuzhippilli +Hassi el Ghella +Kharar +Saclepea +Brzeziny +Kamianka-Dniprovska +Kök-Janggak +Gornyak +North Middleton +Maili +Choró +Chāmpāhāti +San Prisco +Wyndham +Quesnel +Citlaltépec +Yecuatla +Perleberg +Huntington +Gistel +Santa Filomena +Pulakurti +Sonupur +Punnila +Yedtare +New Baltimore +Jericó +Saint-Cyr-sur-Mer +Bharwelī +Mitchellville +Tahannawt +Kinkala +Mayate +San Carlos Yautepec +Datoda +Waikanae +Głubczyce +Gulbahor +Taltal +El Marsa +Montrose +Mānegaon +Lenyenye +Tring +Crossville +Umm ar Rizam +Mattenhof +Benoy +Lehre +Gierałtowice +Münchenstein +Sablé-sur-Sarthe +Kīrippatti +Centralia +Acandí +Bhairāpura +Anndevarapeta +Myrtle Grove +Diré +Villars-sur-Glâne +Sassenburg +Pillānallūr +Ōsako +Kosjerić +Steenokkerzeel +Mostardas +North Tidworth +Narhat +Zlatograd +Si Mustapha +Albox +Sedgley +Baozhong +Mmadinare +Glen Rock +Durmersheim +Portales +Lower Gwynedd +Ban Muang Ngam +Pāpampeta +Ganapatipālaiyam +Paal +Ipaumirim +Miesbach +Louvres +Mugalivakkam +Birdāban +Kodusseri +Dalby +Mettlach +La Queue-en-Brie +Beaconsfield +Motta Sant’Anastasia +Solliès-Pont +Rāmpur Kudarkatti +Nihāl Singhwāla +Borgosesia +Hasbrouck Heights +Bridgnorth +Viswanāthaperi +Bhagwānpur Desua +Unebichō +East Renton Highlands +Iwate +Uzyn +Caimito +Washington +Piketberg +Ugento +Făleşti +Pasłęk +Kalaidasht +Nova Laranjeiras +Kesabpur +Valley Falls +Tábua +Dhaula +Fenton +Liuba +Sinalunga +Woodward +Filandia +Le Chambon-Feugerolles +Khānpur +Al Majma‘ah +Poranga +Curití +Ciudad-Rodrigo +São Francisco do Maranhão +Oiba +Bishnāh +Bharokhara +Pharkia +Ponte da Barca +Hōdatsushimizu +Mays Chapel +Arroio do Tigre +Jacala +Destrehan +Gardnerville Ranchos +Nāttarampalli +Tall Dhahab +Wolgast +Võru +Raismes +Walton-on-the-Naze +Chalgeri +Eiras +Solofra +Nilo Peçanha +Porto +Bangāwān +Ban Pae +Erfelek +Goner +Toropets +Novalukoml’ +Bentley +Rosdorf +Snihurivka +Karagwe +Gbanhi +Lajia +Honeygo +Vălenii de Munte +Alavus +Berwick-Upon-Tweed +Sarmastpur +Vilāngurichchi +North Lebanon +Hwlffordd +Pyrzyce +Rocca Priora +Baxiangshan +Manne Ekeli +Bāgra +St. Peter +Mato Verde +Pittalavānipālem +Steha +Kongsvinger +Imassogo +Mettuppālaiyam +Kārvetnagar +Paramanandal +Iapu +Sabaur +Celebration +Ronneby +Villa Berthet +Edamon +Sławno +Assomada +Gulni +Liberty Lake +Rosaryville +Theux +Marly +Chudamani +Utehia +River Edge +Huité +Kumarkhāli +Nariman +Key Largo +Beyne-Heusay +Velivennu +San José El Ídolo +Yeadon +Occhiobello +Balha +Fort Campbell North +Saddlebrooke +Budakalász +Tomar do Geru +Sahtāh +Monfort Heights +Al Fayd +Les Îles-de-la-Madeleine +Opmeer +Monte San Giovanni Campano +Raffadali +Eureka +Sam +Verde Village +Jardim Alegre +Fuensalida +Warka +Singhbāri +Viyapuram +San Gennaro Vesuviano +Basantpur +Islamey +El Carmen +Keimoes +Hasroûn +El Qâa +Chaqra +Bteghrîne +Qoubaiyat +Ambolomoty +Fanambana +Ivoamba +Ankafina Tsarafidy +Ambohimandroso +Belobaka +Andonabe +Sorombo +Itondy +Iarinarivo +Saharefo +Vohindava +Beandrarezona +Andranovao +Sendrisoa +Maromiandra +Ambalavero +Bekapaika +Anorombato +Ambaliha +Ambohinamboarina +Anjanazana +Andrembesoa +Mahazoarivo +Anjiamangirana I +Nosiarina +Antanamalaza +Andramy +Basibasy +Ampondra +Antaritarika +Befody +Maromby +Omatjete +Saidpur +Umm Badr +Buqkoosaar +Kévé +Bilovodsk +Ḩukūmatī Gīzāb +Jajce +Karrānah +Ngou +Tefam +Mettingen +Wells +Madina do Boé +Princetown +Petit-Goâve +Huvin Hippargi +Khānda +Pinneli +Dahivel +Jai +Rāmachandrapuram +Sadalgi +Halgar +Arni ka Khera +Pramatam +Cecchina +Weatherford +View Park-Windsor Hills +Floreşti +Sokouhoué +Oberschleißheim +Urakawa +Somerset +Barberton +Cimişlia +Ārutla +Talen +Arkansas City +Manuel Urbano +Galvarino +Boskovice +Gladstone +Somersworth +Węgrów +Doranāla +Wang Saphung +Mugdampalli +Krasnousol’skiy +Bolaños de Calatrava +Alajuelita +Mikkelin Maalaiskunta +Volosovo +Martuni +Shiotachō-matsusaki +Rapho +Husepur +Winton +Nagykáta +Tundhul +Msambweni +Yazıhan +Escazú +Benifayó +Kaviti +Arth +Iwanai +Ifs +Minehead +Pāta Putrela +Klazienaveen +Boldājī +Tabocas do Brejo Velho +Oulad Daoud +Ain Beida +Tryavna +Gundelfingen +Arakvāz-e Malekshāhī +Belampona +Siruvāchchūr +Minnāl +Kuangfu +Rāsingapuram +Hathauri +Erbaocun +Santiago del Teide +Marauatpur +Kyzyl-Kyshtak +Star +Hadim +Erkner +Eraclea +Kasaji +Murnau am Staffelsee +Froha +Nueva Era +Mālthone +Bernalda +Mariana +Sremska Kamenica +Tetagunta +Fenton +Souq Jamaa Fdalate +Welver +Stidia +Tāran +Palos Heights +Bissorã +Béna +Tigzirt +Niagadina +Saksohāra +Ballston +Virālippatti +Leominster +Awānkh +Terranuova Bracciolini +Kountouri +Paispamba +Provins +Phước Long +Karaund +Adalaj +Ibaretama +Pudūr +Sidi Yahia +Selimpaşa +Norīa +Vijayāpati +Spencer +Jiajin +Arrigorriaga +Umurlu +Blaricum +Tori-Cada +Jadayāmpālaiyam +Nong Bua +Sondho Dullāh +Konāje +Trezzo sull’Adda +Pecica +Seberi +Amarāpuuram +El Parral +Avesta +Mykhailivka +Darabani +Guidel +Umri +Aït I’yach +Zlaté Moravce +Joaquim Távora +South Miami +Goulds +Alijó +Kozloduy +Caño Martin Peña +Dalmatovo +Governador Dix-Sept Rosado +Sheerness +Khem Karan +Enns +Cinisi +Lienz +Don Sak +Şalpazarı +Distracción +Lagoa do Ouro +Rijkevorsel +Parappukara +Pfäffikon +Richmond +Bačka Topola +Dhanauri +Manchester +Matmata +Tectitán +Pánuco de Coronado +Totogalpa +Çüngüş +Andrelândia +Heddesheim +Saint-Avé +Sai Kung Tuk +Chaital +Pedda Adsarlapalli +Tosashimizu +Schoonhoven +Bueu +Vehkalahti +Mullurkara +Patarrá +Athol +Gisors +Sandridge +Sansalé +Red Bank +Tizi Nisly +‘Anadān +Pacé +Mandasa +Gig Harbor +Bilauri +Hātod +Martinsville +Taché +Poselikha +Brejetuba +Wellington North +Zhdanivka +Paramankurichi +St. Andrews +Fort Bonifacio +Edattala +Grand Baie +Lalmatie +Aheqi +Harrislee +Bairo +Huanian +Kotla +Kronshagen +Tanakallu +Kirikera +Mamarappatti +Halstead +Bound Brook +Williams Lake +Chāndpura +Box Elder +Żebbuġ +Ried im Innkreis +Craponne +Tabontabon +Ambātturai +East Bethel +Oqqo‘rg‘on +Qorashina +Bargoed +Ajjanahalli +Chinna Orampādu +Kampenhout +Bhansia +Baohe +Enamadala +Zemamra +Halásztelek +Arkadak +Wanding +Zumbagua +Belūr +Gundugolanu +Talant +Hamilton Square +Mamqān +Aragoiânia +Shamshernagar +Pakra +Neustadt +Góra Kalwaria +São João +Sultanhanı +Coussé +Dudley +Rutherford +Cachoeira de Minas +Dom Basílio +Nagar +Lauria Inferiore +Kagamino +Ojuelos de Jalisco +Imaruí +Mayilādi +San Severino Marche +Hattian Bala +Gander +Novaya Lyalya +Kamlāpur +Puliyampatti +Benaguacil +Gerstetten +Prattipādu +Jaltenango +Onet Village +Archdale +Maisaka +Badamdar +Rushall +Niles +Comasagua +Linganore +Mahazoarivo +Möhnesee +Épinay-sous-Sénart +Florange +Mehsāri +Bernissart +Snaresbrook +Altavilla Vicentina +Iwaka +San Fernando +Eichenau +Oulad Amrane el Mekki +El Arba Des Bir Lenni +Yuxiaguan +Xincheng +Rudrāngi +Sant’Agata di Militello +Brunn am Gebirge +Monschau +Vanimo +Abasolo +Levashi +La Puebla del Río +Olgiate Comasco +Merāl +Salem +Lake Elmo +Malar +Iacanga +Ban +Laurel +Big Lake +Aguasay +Lissegazoun +Richland +San Juan del Rio del Centauro del Norte +Rankweil +Lauenburg +Eckington +Khajuri +Whistler +Horodnia +Hoyland Nether +Chainpur +Monte Compatri +Çamaş +Ivybridge +Freeport +São Gonçalo do Rio Abaixo +Zriba-Village +Imaculada +Āvadattūr +Miller Place +Recreo +Sixaola +Vendas Novas +Gbéroubouè +L’Isle-Adam +Pedda Vegi +Dendulūru +Sant’Ambrogio di Valpolicella +Myrne +Monte di Procida +Lapinig +Bad Vöslau +Palmilla +Dishāshah +Brighton +Péonga +Pokrovskoye +Vellallūr +Torton +Biltine +Bībīpet +Lizzanello +Kālipatnam +Wallington +Middleburg +Angalakurichchi +Chợ Lách +Trentham +Chero +Bordentown +Wolnzach +Son Servera +Lahra Muhabbat +Guābāri +Itāmāti +Sirsia Hanumānganj +Licínio de Almeida +Paulista +Locri +Andraitx +Bataredh +Spilimbergo +Bibbiena +Mangpa +Raesfeld +Tiddas +San Andrés de Llevaneras +Ratanpur +Hirao +Alum Rock +Premnagar +Bou Merdès +La Tour-de-Peilz +Areal +Hemsbach +San Pedro La Laguna +Korahia +Ōiwa +Pilis +Endwell +Rasūlpur +Vecchiano +Ukrainsk +Poulsbo +Oestrich-Winkel +Baranzate +North Union +Groß-Enzersdorf +Camposampiero +Chilonga +Tapiratiba +Leingarten +Lauffen am Neckar +Wath upon Dearne +Toualet +Barokhar +Sidi Amer El Hadi +Mountougoula +Wargal +Menfi +Jataìzinho +Langgöns +Walldürn +Barrafranca +Befandefa +Tīkar +Holalu +Senirkent +Castle Pines +Bocaina +Dolo Bay +Yakushima +Portela +Mboro +Sonosari +Château-Gontier +Street +Elizabethtown +South Yarmouth +Virgem da Lapa +Oberderdingen +Parsa +Winfield +Picayune +Oswaldtwistle +Kākalūr +Chaplygin +Ghabāghib +Thogapalle +Muscoy +Serra do Salitre +Evanston +Jalalaqsi +Hobyo +Beladi +Little Chute +Portoferraio +Barapiré +Deerlijk +Gulfport +Oued Cheham +Novi Marof +Sânpetru +Neuenrade +Fenoughil +Oued Seguin +Maizières-lès-Metz +Susegana +Le Relecq-Kerhuon +Srīrāmpuram +Khānaqīn +Mountain Top +Santa Cruz Michapa +Axixá +Somain +Zaō +Muping +Minden +Spreitenbach +Kete Krachi +Tortoreto +Biknūr +Tiny +Zwönitz +Ryūō +Comalapa +Cafayate +Aougrout +Vegarai +Roda +Hauzenberg +Ngerengere +Ronchi dei Legionari +Portomaggiore +Oak Hills +Villecresnes +Kehen +Fiume Veneto +Baitoa +Yeniçiftlik +Pritzwalk +Leutenbach +Santa Ana +Chiautla de Tapia +Sidi Ladjel +Olivenza +Tarrytown +Bechloul +Sahasmal +Strunino +Vauvert +Khānsāhibpuram +Market Drayton +Borgaro Torinese +Alamedin +Putnam Valley +Negēlē +Green River +Pragatinagar +Burgthann +São Gonçalo do Pará +Kankaanpää +Allūr +San Pedro +Sīpālakottai +Kotha Gurū +Bitetto +Show Low +Amherst +Baranivka +Brotas de Macaúbas +Guttenberg +Mack +Drolshagen +Campos del Puerto +Cogolin +Hankey +Söderhamn +Tifni +Batočina +Picaña +Owk +Agcogon +Tornquist +Weston +Jaitwār +Kornepādu +Alken +Annakāttumūla +Pastpār +Richfield +Largo +Gillingham +Sher Muhammadpuram +Mapleton +Bopfingen +Hawkesbury +Blace +Elektrėnai +Kuchinarai +Monción +Pößneck +Bad Dürrenberg +Agadi +José María Morelos +Waldniel +Tiruvādānai +Rājāram +Padinjāremuri +Murukondapādu +Ganapavaram +Lawrenceburg +Abhia +Edéia +Chināval +Tolcayuca +Francofonte +Bajiao +Cernay +Konand +Bilopillya +New Baltimore +Rossmoor +Kamianka +Ovidiopol +An Cabhán +Bajestān +Mương Theng +Serravalle Pistoiese +Carignan +Magdagachi +Ban Phan Don +Scharbeutz +Lindenberg im Allgäu +Vasylkivka +Medina Sidonia +Chāltābāria +Vengavasal +Pallejá +Yamamoto +Lunenburg +San Nicolás de los Ranchos +General Cabrera +Trinidad +Septèmes-les-Vallons +Hackney +Chintapalle +Río Colorado +Dināra +Chaumont-Gistoux +Zhetibay +Altstätten +Hardiyā +Sveti Nikole +Mestrino +East Greenwich +Los Alamitos +Mutia +Crowley +Ambatofisaka II +Cossimbāzār +Shady Hills +Irupi +Kőszeg +Golub-Dobrzyń +Baghauni +Appingedam +Guatajiagua +Krujë +Deutschlandsberg +Nellipoyil +Sandy +Carmen +Villefranche-de-Rouergue +Carmiano +Soalandy +Aleksandrów Kujawski +Chūndal +Puente Nacional +Zayukovo +Auta +Brookhaven +Milford +Alegría +Piranhas +Wetherby +Nandimandalam +Sääminki +Spring Lake +Ubaí +Macusani +Costa de Caparica +Sindalakkundu +Malkā +Lantana +Hanover +Bithān +Sowerby Bridge +Semri +Lantana +Rattihalli +Lansing +Lower Burrell +Bol +Nakasongola +Gatumba +Chakai +Geisenheim +Tamezmout +Sengurichchi +Ūjhāna +Rangsdorf +Olhanpur +Douglas +Risca +Tibbar +Elma +Ringwood +Kissing +Vellār +Zārach +Ibirá +Waltikon +Nova Gradiška +Ángel R. Cabada +Óbidos +Hildburghausen +Barkāgaon +James Island +Schwaigern +Rostam Kolā +Dolinsk +Lom Sak +Jacó +Irmo +São Bento do Sapucaí +Luís Alves +Maliāl +Mallikkundam +Izola +Peiting +Hollabrunn +Conceição do Castelo +Billerbeck +Canton +Seven Hills +Saint-Pierre-du-Perray +Venkidanga +Tirodi +Torri di Quartesolo +Ulverston +Sothgaon +Cornedo Vicentino +Signal Hill +Center +Kibi +Bellmawr +Udachnyy +Peligros +Elland +Prudhoe +Kiskunmajsa +Vilandai +Bokākhāt +Alahina +Bolsover +Oliva +Franklin +Randaberg +Škofja Loka +Talakād +Fgura +São Sebastião do Uatumã +Kautālam +Limburgerhof +Keolāri +Nellipāka +Kāranchedu +Vermillion +Befotaka +Bayyanagūdem +Dent +Elavalli +Chittāttukara +Bullas +Tiszakécske +Narasāpuram +Hallbergmoos +Bryn +Lanham +Woodmere +Sassenage +Ponte San Pietro +Marotta +Bagaura +Stokke +Sandy +Berlaar +Bhainsahi +Jardim do Seridó +Zofingen +San Pedro Ixcatlán +Lajosmizse +La Riviera +Raubling +Nandavaram +Panamaram +Yirol +Sukurhutu +Hidaka +Lakri +Jangy-Kyshtak +Lessogou +Mixtla de Altamirano +Samesi +Isaszeg +Fatehābād +Newport East +Emmaus +Norton +Bucyrus +Isaka +Ansião +Kāttakampāla +Isāpur +Mitai +Mendota Heights +Brock +Mount Sinai +Carver +Cowdenbeath +Zaoqiao +Kizhakkanela +Miami Shores +L’Île-Perrot +Durbuy +Dhanaura +Kunkalagunta +Azcoitia +Lundazi +Candelaria +Bolbec +Sonāda +Hemiksem +Karmauli +Siur +Nzeto +Guaiçara +Thiers +Knin +Half Moon Bay +Angicos +Utiel +Diao’ecun +La Esperanza +Motegi +Tlachichilco +Dérassi +Burnham +Ermenek +Dammapeta +Weiz +Pongode +Chebrolu +Kallakkudi +Pepperell +Lakeville +Porecatu +Bayou Blue +Tepetzintla +Ostrhauderfehn +Ichinomiya +Nawā Nagar Nizāmat +Wakefield +Lubaczów +Henley on Thames +Middle Valley +Lenvik +Annappes +Ban Mae Tuen +Māhta +Nallūr +Santa Cruz Itundujia +Moulay Driss Zerhoun +Balaxanı +Ielmo Marinho +Kotra +Summerland +Mala Vyska +Baghambarpur +Saint-Gaudens +Manabo +Ibicuitinga +Xexéu +Castelló de Ampurias +Ziyodin Shaharchasi +Piraúba +Ontario +Veyrier +Rokiškis +Ambohimahasoa +Sint Anthonis +Betmangala +Geisenfeld +Qaşr-e Qand +Kem +Rāyavaram +Kalmiuske +Ascot +Sunninghill +Wolmirstedt +Gararu +Abertillery +Sewāi +Kolnād +Cadale +Cruzeiro do Sul +Tafaraoui +Wallingford +Schiller Park +Fuente de Oro +Devipattinam +Gansbaai +Shuinancun +Ādūru +Santa Comba Dão +Jiquipilas +Cangas de Narcea +Renāpur +Hartsville +Likhoslavl +Mömbris +Guraahai +Chatham +Phon +Bassersdorf +Halsūr +Ankli +Huandacareo +Zero Branco +Markham +Lawrenceburg +Loreto +Santa Lucía +Chambray-lès-Tours +Sablan +Ross-Bétio +Tummalacheruvu +Weeze +Sākib +St. Clements +Khimlāsa +Morūr +Casteldaccia +Gainza +Santa Lucía +Vadakkumbāgam +Mangabe +Kurabalakota +Novoīshīmskīy +Roessleville +Yercaud +Minnehaha +Moss Bluff +Oulad Friha +Santa Genoveva de Docordó +San Josecito +Wichelen +Oulad Hamdane +Patterson +Chegem Vtoroy +Ipaporanga +Town and Country +View Royal +Nazareth +Melle +Gopālapuram +Le Haillan +Naīgarhi +Jethuli +Castenedolo +Bahādarpur +Pettaivāyttalai +Jarābulus +Haradok +Jīdigunta +Okuizumo +Ban Mae Kham Lang Wat +Ban Wiang Phan +Caraguatay +Schwieberdingen +River Forest +Santa Cruz da Baixa Verde +Oñate +Isola della Scala +Pampas +La Unión +Kennebunk +Eijsden +Landsmeer +Nieuwpoort +Gold Canyon +Gardere +Puerto Suárez +Überherrn +Loutráki +Ghal Kalān +Kushmanchi +Severnyy +Navarro +Kopervik +Yangiqo‘rg‘on +Xiaoba +Meßstetten +Ghinda’e +Yorktown +Mistelbach +Silves +Sathmalpur +Khandpara +Forest +Belgrave +Araçás +Perches +Gulgam +Cisneros +Esperanza +Anatolí +Stuarts Draft +Molteno +Kundiawa +Leāma +Espita +Itainópolis +Perumbakkam +Tadapurambākkam +Esil +Saint-Estève +Dąbrowa Tarnowska +Krosūru +Sussex +Derdara +Bugongi +Broome +Carmo da Cachoeira +Amelia +Patera +Downpatrick +Ghambiraopet +Port Lavaca +Wanstead +Muroto-misakicho +Platteville +Den Chai +Chennūr +Khorramābād +Chintalavādi +Nyazepetrovsk +Holešov +Labbaikkudikkādu +Sidi Kasem +Kibungo +Dharmāram +Mangalkot +Port Morant +Matca +Pieve di Soligo +Lamosina +Weinfelden +Sinzheim +Nālwār +Roma +Taïneste +Krapina +Kantilo +Saint Helena Bay +Doda +Mīt Damsīs +Sunkarevu +Bāhāgalpur +Ichhāpur +Smithfield +Norfolk +Vohilava +Moparipālaiyam +Maniago +Okpo +Nandipeta +Ekerö +Quatipuru +Budha Thēh +Golet +Stelle +Nīdāmangalam +Epazoyucan +Sahri +Ingurti +Ramena +Calheta +Noeux-les-Mines +Doddappanāyakkanūr +Shāhpur Baghauni +Giffoni Valle Piana +Cholpon-Ata +Loyalsock +Olintla +Jucati +Velké Meziříčí +Gorey +Kundurpi +Drawsko Pomorskie +Raun +Blundellsands +Cachoeira Alta +Desanagi +Mirik +Grosse Pointe Park +Dolores +San Carlos de Guaroa +Hlaingbwe +Valdivia +Brislington +Orchha +Kathu +Doukombo +Sagada +Nova Odesa +Coronel Dorrego +Belp +San Lázaro +Pākkam +Piprāhi +Żejtun +Newcastle +Sultānpur +Xuân Trùng +Burley +Radnevo +Four Corners +Badou +Hàng Trạm +Slatina +Al M’aziz +Estiva +Gospić +Mexico +Dzouz +Beniel +Fort Morgan +Liubashivka +Dang‘ara +Liman +Strombeek-Bever +Kaboua +Unterföhring +Ostbevern +Elgóibar +Lençóis +’Aïn Roua +Devikāpuram +Taviano +Nova Ubiratã +Rabat +Barhi +Chauny +Baruāri +Lovington +Bouabout +Sonāpur +Kemigawa +Elk City +Kamalāpuram +Cherdakly +Mercogliano +Oskaloosa +Aginskoye +Zeuthen +Atmākūr +Montmagny +Ihumwa +Guayabal +Wittingen +Mount Fletcher +Tawnza +Oxelösund +Coswig +Salisbury +Sathiāla +Farmington +Ridgefield +Moyamba +Lokhvytsya +Tinogasta +Nový Bor +Westerkappeln +San Gregorio di Catania +Leon Valley +Revúca +Diósd +Bānk +Peringōttukurusshi +Yakymivka +Gaurihar Khāliqnagar +Healdsburg +Fatehpur Shāhbāz +Alto Alegre dos Parecis +Myronivka +Jamsaut +Pānāpur Langa +Lindon +Alfonsine +East Glenville +Palestina +Bek-Abad +Rača +Sárbogárd +Satyavedu +Kuriyama +Götzis +Tadley +Kavaratti +Valea Adâncă +Lebon Régis +Vengikkal +Poldasht +Bath +Sun Village +Gonubie +Pirangi +Sinkolo +Kishanganj +Muna +El Ançor +Mios +Hœnheim +Kāri +Arasūr +Rupenaguntla +Shanmukhasundarapuram +Vlasenica +Cidade Gaúcha +Prudente de Morais +Agamé +Bhabānipur +Ridgefield +Fuller Heights +Ḑurumā +Mariehamn +Loran +Ninga +Kalakada +Rengāli +Kashaf +Douar Trougout +Libertad +Vedène +Eningen unter Achalm +Fourmies +Khāngāon +Maruttuvakkudi +Burām +Vitry-le-François +Culcheth +Shingbwiyang +Mogilno +Egelsbach +Pike Creek Valley +Ahlaf +Cocentaina +Chakwai +Wilton Manors +Pontiac +Bellegarde-sur-Valserine +Jódar +Cantley +Esmoriz +Paro +Chitauria +Florestópolis +Ouro Branco +Gräfenhainichen +Sidi Moussa Ben Ali +Kirchhundem +Odatturai +El Khemis des Beni Chegdal +Ban Saeo +Satuek +Montanhas +Trostberg an der Alz +Baroni Khurd +North Wantagh +Covington +Sidéradougou +Cumandá +La Londe-les-Maures +Milići +New Garden +University of California-Santa Barbara +Sonoita +Enghien-les-Bains +Port Salerno +Ajijic +Dhalaa +Erin +Amdel +Varzobkala +Saubara +Vlašim +Harsum +Lendinara +Nikel +Caetanópolis +Gloucester City +Campbellsville +Egersund +Puerto Rico +Barahkurwa +Gandhāri +Woods Cross +Tlacolulan +Hato Corozal +Méricourt +Holyhead +Dobbs Ferry +Greensburg +Er Regueb +Bad Schwalbach +La Libertad +Shāhpur +Ramallo +Notre-Dame-de-l'Île-Perrot +San José de Guaribe +Mogogelo +Kumari +Stradella +Koori +Dorog +Kuse +Pallipattu +Ain Legdah +Malo Crniće +Höhenkirchen-Siegertsbrunn +Bridgeton +Vakhrusheve +Nemyriv +Velimeşe +Laqraqra +Kinattukkadavu +Hanover +Dautphe +Kondhāli +Sorsk +Haydock +Casièr +Sanniquellie +Yuryuzan +Qax +Naliya +Bytča +Cadolzburg +Jimaní +Tourougoumbé +Mahāgama +Kostinbrod +Guinagourou +Sales Oliveira +Pothia +Senduriā +Rāibāri Mahuawa +Ulricehamn +Florennes +Sào Amaro das Brotas +Cabo Verde +Barro Alto +Sociedad +Lopon +Pratāparāmpuram +Tysvær +Lumaco +Majdal Shams +Gänserndorf +Scottburgh +Pelileo +Laren +Buzhum +Dawley +Saint-Cyprien +Rostraver +Plan-de-Cuques +Babayevo +Byerazino +Gundrājukuppam +Wealdstone +San Michele al Tagliamento +Enebakk +São João das Lampas +Montegrotto Terme +Saverne +Yāllūru +Greetland +Higashiizu +Kincardine +Marktheidenfeld +Nyírbátor +Simrāhi +Clawson +Douar Sgarta +Saint-Junien +Newport +Eldorado +Sidi Tabet +Guachetá +Yvetot +Falimāri +Oak Grove +East Grand Rapids +Anjuna +Lakhipur +Chekmagush +Hejiaji +Grünwald +Konakondla +Campobello di Mazara +Lijiacha +Samayanallūr +Halavāgalu +Fulton +Buckhurst Hill +Baghmaria +Harji +Bind +Hirnyk +Onoto +Santa Fé +Sarjāpur +Snyder +Rosario de Mora +Campo do Meio +Sālamedu +Pīr Maker +Santa Clara +Sevilla +Staden +Harrow Weald +Suffern +Gornozavodsk +Mancha Real +Great Bookham +Little Bookham +Lahfayr +Bānsbāri +Hamilton +Boudenib +Buuhoodle +Uchchangidurgam +Kochkor +Morgan City +Tilmi +Musile di Piave +Elliot Lake +Douar Oulad Naoual +Pelsall +Woodbury +Recke +Kamiita +Humahuaca +Alcântaras +Ploufragan +Bhagwatpur +Biddupur +Puyehue +Zambrano +Parora +Okmulgee +Castalla +Baghra +Ātharga +Wells +Resende +Yangirabot +San José del Fragua +Lonate Pozzolo +Progress +Arumbākkam +Meghraj +Altdorf +Jamhor +Pachāhi +Manpaur +Zierikzee +Lyuban +Sidi Baizid +Carnoustie +Gardone Val Trompia +Belén +Bankya +Rudersberg +Phulparās +Manappakkam +Kalinagar +Newtown +Bromont +Engen +Parvatgiri +Perāmpuzha +Medulla +Zaragoza +Bargaon +Bishunpur +Monte Sant’Angelo +Rodenbach +Akola +Catskill +Spencer +Klyetsk +Talaigua Nuevo +Bataiporã +Rothenburg ob der Tauber +Charouine +Maltby +Ochsenfurt +Vaal Reefs +Chkalovsk +Cardoso +Handewitt +Taurisano +Tegueste +Nalambūr +Rheinau +Knowsley +Calatrava +Cherlagandlapālem +Pimenteiras +Lamsabih +Capaci +Ouaklim Oukider +Teniet el Abed +Holbrook +Domneşti +Kurgunta +Somerville +Welzheim +Dharmaj +Cocoa Beach +Yanahuanca +Gustavsberg +Waidhofen an der Ybbs +Machados +Humpolec +Tököl +Besalampy +Gouvêa +Nußloch +Ialysós +Natshal +Pemmpéréna +El Quisco +Santa Rosa de Viterbo +Pāpireddippatti +Dugny +Tiruvennanallūr +Langarivo +Māshyāl +Rio Novo do Sul +Ban Bang Lamung +Bārīgarh +Virton +Tabapuã +Ravenna +Lardero +Masinigudi +Capitán Bado +Varadarājampettai +Taylorville +Tosagua +Capitán Sarmiento +Leatherhead +Gracemere +Bitritto +Mărăşeşti +Oxted +Burslem +Drezna +Pionerskiy +Mülheim-Kärlich +Worb +Ténenkou +Bruay-sur-l’Escaut +Tāzhakudi +Janów Lubelski +Hipperholme +Edasseri +Dimmbal +Zimna Voda +Naryn +Saint-Germain-lès-Arpajon +Arnprior +Tudela +Villa Purificación +Denkendorf +Honmachi +Ikhlāspur +Sabana Yegua +Jem’at Oulad ’Abbou +Periya Soragai +Lafrayta +Sebba +Inhassoro +Lieksa +Caldogno +Miasskoye +Ichinohe +Estiva Gerbi +Gualcince +Batemans Bay +Caotan +Singura +Commune Sidi Youssef Ben Ahmed +El Ghourdane +Arslanbob +Drochtersen +Shiloh +Bad Nenndorf +Panpuli +Teano +Getulina +Chorleywood +Antsambalahy +Golfito +Bátonyterenye +Tikota +Amatenango del Valle +Ban Kat +Stamboliyski +Meru +Svitlodarsk +Pedro de Toledo +Arpajon +Norwell +Dourdan +Limavady +Stanwell +De Doorns +Beldibi +North Dundas +Eichenzell +Tramore +Lakeland Highlands +Pipariya +Somavārappatti +Biri +Majanji +Sajószentpéter +Kanhāipur +Caimanera +Bhilavadi +Seneffe +Dammartin-en-Goële +Iskapālem +Curimatá +Coveñas +Astley +Fallersleben +Riebeeckstad +Simeria +Sinor +Asthal Bohar +Anderson +Caetano +Bicske +Samahuta +Burtonwood +Bānāvar +Trecastagni +Lowes Island +Manvel +Derecik +Kūshk +Kuřim +La Roche-sur-Foron +Sīrpanandal +Santa Cruz +Maryport +Bara Belun +De Witt +Ventersburg +Søgne +Beclean +Largs +Westphalia +Ocean City +Wellesley +Sosenskiy +Edd +Arcachon +Brooklyn +Boultham +Tāmba +Datiāna +Kovūrupalli +Sant’Ilario d’Enza +Hillsborough +Niasso +North Valley +Jādopur Shukul +Lansing +Groton +Poko +Nārāyanavanam +El Playón +Kin +Two Rivers +Jamaat Shaim +Roncador +Deodha +Tetyushi +Lang Suan +Priolo Gargallo +Quebrangulo +Farciennes +Pulpí +Malkanūr +Alburquerque +São João do Manhuaçu +Scalea +Kings Mountain +Sahsaul +Möglingen +Barrington +Willistown +Touama +Prien am Chiemsee +Las Charcas +Saint-Jean +Kingsnorth +Makhmālpur +Alpu +Männedorf +Eranāpuram +Greasley +Cranleigh +Westwood +Retie +Oregon +Kpandae +Chintakunta +Bramhabarada +Bardīha Turki +Attippattu +Gethaura +Kishunpur +San Pablo Atlazalpan +Akjoujt +Sankt Johann im Pongau +Pueblo Viejo +Lavandevīl +Kourouma +Derbisek +Hagen im Bremischen +Beniaján +Tentena +Bora +Boguchany +Betânia +Mineiros do Tietê +Resende Costa +Mountain Ash +Inzago +Werther +Lauingen +Porto-Vecchio +Moyuta +Pasaco +Monteforte Irpino +Sidi Abdellah Ben Taazizt +Anenecuilco +Ortakent +Rahiār Kunchi +Saint Ives +Crayford +West Point +Koog aan de Zaan +Amarchinta +Jagdīshpur +Lincolnton +Aratuba +Antônio Carlos +Herbolzheim +Hormigueros +Gravelines +Belauncha +Vaḩdattīyeh +Korablino +Kassa +Djemmorah +Amala +Granbury +Kaset Wisai +Vanj +Castle Bromwich +Wanaque +Chulym +Kédougou +Hamadānak +Miechów +Kursavka +Şaydā +Sanzana +Holíč +Pinheiro Machado +Mannarai +Hambantota +Marquette-lès-Lille +Dhakaich +Talupula +Abbeville +González +Rānti +Emba +Prachatice +Diez +Montechiarugolo +Nembro +Schöningen +Beni Ounif +Khargrām +Isselburg +Temamatla +Tittachcheri +Kummarapurugupālem +Sonseca +Lathasepura +Carbonera +Ichikai +Hanover +Zvenigovo +Guilherand +Bom Jesus +Laukaria +Lommedalen +Būdili +Tagami +Northbrook +Namli +Kalasa +Nelson +Iygli +Lloró +Sanjiaocheng +Tissa +Valkeala +Sarāb-e Tāveh-ye ‘Olyā +Borjomi +Sirgora +Chamestān +Storm Lake +Ladysmith +Chikni +Bhisho +Pihuamo +Faxinal dos Guedes +Tournon-sur-Rhône +Shahmīrzād +Kazarman +Boiling Springs +Feldkirchen-Westerham +Mpraeso +Busumbala +Tādepalle +Siniscola +Nambour +Guntupalle +Damonojodi +Ārambākkam +Pacoti +Linslade +Berkley +Ilfracombe +Prescot +Bucheya +Barka Gaon +Montopoli in Val d’Arno +Los Almácigos +Hernando +Capilla del Monte +Armstrong +Kranenburg +Parbata +Salaya +Wootton +Malkhaid +Aurelino Leal +Hinwil +Pūngulam +Harsinghpur +Kawadgaon +Baryshivka +Rychnov nad Kněžnou +Chikkārampālaiyam +Satellite Beach +Mhangura +Leek +Moreira Sales +Vaux-le-Pénil +Góra +Arvand Kenār +Arvand Kenār +Hoeilaart +Grobbendonk +Belzig +Kuzuculu +Seringueiras +Westtown +Tucson Mountains +Coldstream +Galbois +Stonehaven +New Port Richey East +Potukonda +Douar Jwalla +Romanshorn +Boujediane +Nāgalāpuram +Douar Ain Maatouf +Rasaunk +Penne +Marginea +Zakamensk +Palukudoddi +Târgu Lăpuş +Wellington +Batesville +San José de Aerocuar +Säter +Kumbadāje +Margherita di Savoia +Piedmont +Elon +Zaouiet Says +Bollullos de la Mitación +Creazzo +Padre Burgos +Vosselaar +Capela de Santana +Areiópolis +Dorking +Grand Rapids +Prymorsk +Cacequi +Bernardino de Campos +Cherry Creek +Sada +Chikha +Honiton +Urbana +Inwood +Mangalmé +Gerasdorf bei Wien +North Lindenhurst +Tambaga +Baley +Kriftel +Aylestone +Bhandārso +Sierra Madre +Zaragoza +Villepreux +Aukštieji Paneriai +Somnāha +Hauterive +Begogo +Antônio Cardoso +Finale Ligure +Planura +Bailin +Mortugaba +Waldkirchen +Balve +Sihaul +Sonbāri +Bannewitz +Mayūreswar +Okhargara +Birch Bay +Atru +Pulsano +Cerese +Lloyd +Barbadanes +Cesson +Dorridge +Olaippatti +Kirensk +Stollberg +Hexham +Cisternino +Enfida +Saādatpur Aguāni +Waipio +Guebwiller +Novska +Banagi +Bālehonnūr +Oberwil +Pongalūr +Kīlkottai +Écaussinnes-Lalaing +Kanamadi +Udawantnagar +Kurman +Fīnch’a’ā +Murapāka +Manatí +Roscoe +Ambinanin’i Sakaleona +Evington +Achankovil +Jamapa +Sheron +Iazizatene +Braunfels +Kowdalli +Valmadrera +Burr Ridge +Fagersta +Palmerston +Kumharsan +De Panne +Brugg +Quintanar de la Orden +Orono +Itanhomi +Panhar +Trofaiach +Southborough +Sultānpur +Camisano Vicentino +Elwood +Congaz +Shahrinav +Mortād +Kachnār +White City +Langeloop +Puerto Caicedo +Uničov +Candelaria +São José do Campestre +Nandayure +Nawalpur +Morant Bay +Matsuo +Mineral de Angangueo +Hasbergen +Iver +Iuiú +Saint-Saulve +Warren +Gengenbach +Kāttupputtūr +La Massana +Phulgāchhi +Plano +Kall +Oporapa +Salcedo +Alto Parnaíba +Ikkādu +Waupun +Vila Frescainha +Tha Chang +An Phú +Caorle +Canyon Lake +Sorontona +Firoza +Murska Sobota +Marilândia +Comarnic +Peri-Mirim +Yamanouchi +Mierlo +’Aïn Taghrout +Ollerton +Port Wentworth +Hatwāns +Kārīz +East Hanover +Chuguyevka +Nazyvayevsk +San Bernardo +Castelvetro di Modena +Capitão de Campos +Georgian Bluffs +Oud-Heverlee +Nāgojanahalli +Parapuã +Duggirāla +Ararendá +Gucheng +Vilyuysk +Illintsi +Antônio Carlos +Ksar Sbahi +Biganos +Yargatti +Bishunpur +Alcoa +Potosí +Fortuna +Raceland +Melsele +Calçado +Fairview +Bang Ban +Chassieu +Bhattiprolu +Ban Wang Daeng +Panguipulli +Wulingshancun +San Luis de La Loma +Si Wilai +Terku Valliyūr +Aydıncık +Herrsching am Ammersee +Kariat Ben Aouda +Céu Azul +Bagamanoc +El Trébol +Divinolândia +Gachetá +Canandaigua +Juruaia +Pedersöre +Congonhal +Şā’īn Qal‘eh +Iguaraci +Rāmanāyakkanpālaiyam +Cleveland +Belén de los Andaquíes +Pāta Ellamilli +Moorslede +Paullo +Narimanov +Piazzola sul Brenta +Konnūr +Pirapetinga +Basaithi +Wen’anyi +Pontchâteau +Río Cuarto +Arenzano +Citrus Springs +Berane +Lālsaraia +Dayālpur +Karebilachi +Codigoro +Nossa Senhora dos Milagres +Hebri +Elchūru +Asahi +Clayton +Merriam +Niémasson +El Águila +Týrnavos +Szprotawa +Passy +Union City +Kać +Dois Riachos +Stiring-Wendel +Selma +Wyomissing +Santa Mariana +Barton upon Humber +Cologno al Serio +Lake Grove +Leicester +Shamunpet +Marinette +Doesburg +Mahīn +Nörvenich +Panazol +Kaniyambādi +Villa La Angostura +Longtaixiang +Planegg +Pēnagam +General Carneiro +La Calamine +Timperley +Whitchurch +Great Wyrley +San Giustino +Great Neck +Jayaque +Korb +Dalippur +Lower Saucon +Mainvilliers +Hāthidāh Buzurg +Bangramanjēshvara +Rutesheim +Devanakavundanūr +La Trinitaria +San Carlos Centro +Floresta Azul +Aba +Shankarpalli +Chhabila +Kadūr Sāhib +Coshocton +Monmouth +Mandal +Zirə +Āwash +Le Luc +Nanpala +Pharāha +Pompton Lakes +Novoazovsk +Thanh Xuân +Lansdowne +Moita Bonita +Wangjiabian +Larbert +Sturgis +Brzeszcze +Fagundes +Glyká Nerá +Boguchar +Montlouis-sur-Loire +Ballymoney +Kisara +Epping +Dumri +Mādhopur +Petal +De Pinte +Riorges +Mukāsi Pidāriyūr +Andacollo +Magnolia +Ráckeve +Puliyara +Joquicingo +Jacinto +Möhlin +Bithlo +Feira +São Sebastião de Lagoa de Roça +La Esperanza +Chornomorske +Sankhavaram +Sakkamapatti +Bottesford +Konen Agrahār +Hikawadai +Yuasa +Lindome +Columbia +Summit +Athy +Koch +Perali +Tezoatlán de Segura y Luna +Aperibé +Kenduadīh +Murgod +Rezina +Phanat Nikhom +Tonse West +Delvāda +Anguera +Hornsby Bend +Fanlu +Riedlingen +Waihee-Waiehu +Cold Springs +Veľký Krtíš +Sosnovka +São Félix +Tekkumbāgam +Bertinoro +Milicz +Botuporã +Gernsheim +Maromme +Amha +Qal‘at an Nakhl +Kongupatti +Ichikawa +Tirumayam +Balingoan +Rolla +Fredericksburg +Brumunddal +Corinda +Carmo da Mata +Weyburn +Ekuvukeni +El Hamel +Tavistock +Allāhdurg +Velddrif +Kalyazin +Nedelišće +Sannieshof +Itatuba +Bir Ghbalou +Greentree +Gloucester Point +Mawu +Mangalam +Antanandava +Kiwoko +Allonnes +La Palma +Waterloo +Chatteris +Sarauni Kalān +Fairview Shores +Xinyaoshang +Vijes +Domažlice +Patu +Waynesboro +Damme +Wālūr +Dolhasca +Franklin Lakes +Chinna Annalūru +Sebring +Regen +Solymár +Saucillo +Shalushka +Siyāna +Älmhult +Lorch +Chauki +Collegedale +La Tuque +Norwich +Abasingammedda +Morafeno +Ambotaka +Kalafotsy +Antsoha +Maroambihy +Voloina +Ambatomasina +Ambodiampana +Antsakanalabe +Antsahabe +Antakotako +Tsararano +Mahazony +Fotsialanana +Ambinanindovoka +Ranomafana +Ankavandra +Manambolosy +Ambohidranandriana +Tsinjomitondraka +Amporoforo +Ambodimangavolo +Analamitsivalana +Bevata +Antsambahara +Androndrona Anava +Sampona +Marolinta +Andranomeva +Miandrarivo +Ambodimanary +Maroamalona +Marovantaza +Marotandrano +Antanandava +Efatsy-Anandroza +Manandroy +Tranomaro +Vinaninkarena +Soaserana +Soamanova +Loikaw +Side +Cerro Corá +Zhamog +Pingcha +Mahād +Al ‘Amādīyah +Santa Flavia +Burlington +Karabash +Itiruçu +Saint-Martin-Boulogne +Byelaazyorsk +Lyndon +Oak Ridge +Edlapādu +Bāgnān +Jagannāthpur +Shagonar +Agua de Dios +Srīpur +Patori +Vengapalli +Farkhâna +Llandybie +Matino +Issoudun +Westview +Dhilwān Kalān +Springdale +Meaford +Komorniki +Churchdown +Guspini +Ribeirão Bonito +Schkopau +Ma’ai +Bardipuram +Mānsinghpur Bijrauli +Summerfield +Myjava +Akyaka +Dayr ‘Aţīyah +Sabalito +Wildau +Nagar Nahusa +Argostóli +Colwyn Bay +Santa Cruz Balanyá +Honwāda +North Logan +Belousovo +Paraúna +Duas Barras +Santa Croce Camerina +Burkburnett +Citrus +Fao Rai +Pingtouchuanxiang +Bargas +Sendurai +Paura Madan Singh +Warden +Cudworth +Singoli +Junín +Pebble Creek +Chicureo Abajo +Oakham +Yelpur +Sesto Calende +Totowa +Easttown +Adjala-Tosorontio +Koronowo +Əhmədli +Piraí do Norte +Xintianfeng +Celina +Manaíra +Staryya Darohi +Rekovac +Punjai Turaiyāmpālaiyam +Cáchira +Aş Şabbūrah +Bīrpur +Mallagunta +Satoshō +Takad Sahel +Tixkokob +Acanceh +Haigerloch +Cabanillas del Campo +Bāwāli +North Branch +Champua +Vochaïkó +Bhangha +Campagnano di Roma +Sarafand +Ongwediva +Guiratinga +Mêdog +Zhydachiv +Três Cachoeiras +Rāmabhadrapuram +Álamos +Vengūr +Masakkavundanchettipālaiyam +Peschiera del Garda +Grand Haven +Volda +Mēmunda +Boekel +Szydłowiec +Rogoźno +Quimilí +Dek’emhāre +Matias Olímpio +Tarrá +El Tarra +Eisenberg +Rüthen +Hellesdon +Nacajuca +Punitaqui +Adendorf +Neuhof +Keles +Highgate +Tirupporūr +Iioka +Little Ferry +Cunha Porã +Burgkirchen an der Alz +Tortolì +Lézignan-Corbières +Longford +Canton +Bishunpur Hakīmābād +Palsud +Rosario +Borsbeek +Devgeri +Satai +Al Ghayz̧ah +Ibiraci +Ūttukkuli +Mahmūda +Völkermarkt +Lichtenstein +Nao Kothi +Cepagatti +Timahdit +Vadamugam Vellodu +Pottireddippatti +Ruisui +Chevigny-Saint-Sauveur +Nallamada +Cacaopera +Ebreichsdorf +Ḩaşşeh +Pleasant View +Hamilton Township +Kalavapūdi +Pompton Plains +Belgrade +Rialma +Ban Yang Hom +Vashon +Rokytne +Quilombo +Itamarati +Rumburk +The Hills +Pedappai +Mena +Semuto +Nādendla +Bni Drar +Texcatepec +Vimmerby +Cantagalo +Kabīrpur +Garmeh +Shōō +Beachwood +Bedford Heights +Corbas +Mazzarino +Sângeorz-Băi +Attard +Malden +Étaples +Kaniyūr +Chatham +Ørsta +Malente +Chāoke +Valley Center +Ingelmunster +Swarna +Donzdorf +Karakthal +West Caldwell +Stratford +Minamiise +Sisia +Hakone +Sankhavaram +Chinnatadāgam +Bariārpur Kāndh +Basbiti +Madna +Memphis +Wustermark +Grandview +Ponteland +Mossley +Ferney-Voltaire +Hollinwood +Kuttappatti +Pellezzano +Barberino di Mugello +Troy +Berriozar +Tibubeneng +Brandon +Wronki +Guéoul +Meliana +Sontha +Altensteig +Karlsdorf-Neuthard +College +Blitta +Tizi +Prineville +Arniya +Venosa +Timberlane +Bueno Brandão +Groaíras +Rincon +Kamen’-Rybolov +Kavaklıdere +Kenzingen +Costeşti +Zasechnoye +Meulebeke +Krosno Odrzańskie +Oued Sebbah +Keila +Ogose +Lehman +Yairipok +Koilakh +Roque Pérez +Chenango +Muswellbrook +Khānjahānpur +Sangrām +Nishi +Pocono +Bobrynets +Osterwieck +Karikād +Chiltiupán +Gages Lake +Passa e Fica +Tarwāra +Minamisanriku +Delhi +Imeni Chapayeva +Bobrovytsia +Xudat +Castel Mella +Nyakosoba +Gilbués +Santoña +Kodmiāl +Manville +Berthoud +Alto Rio Doce +Kiratpur Rājārām +Haysville +Soyaló +Great Harwood +Hardia +Erraguntla +Ghanpur +Qaşr-e Qomsheh +Terryville +Bernardo de Irigoyen +Wisła +Sairé +Yacopí +Langenzenn +Erstein +Fife +Triangle +Kandry +San Roque +Gottmadingen +Glückstadt +Beni Abbès +Inverurie +Garden City +Gentio do Ouro +Coroaci +Yungay +La Puebla de Cazalla +Lincoln Park +Mesyagutovo +Hammelburg +Nova Vodolaha +Itarana +Conceição dos Ouros +Rāmbilli +Chandūr +Węgorzewo +Mae Wang +Bofete +Harri +Garkha +Petrovka +Serravalle +Sahoria Subhai +Khān Bebīn +Nivala +Castelginest +Siversk +Rush +Pallarimangalam +Schönaich +Kothri Kalān +Shing +Santa Rosa de Río Primero +Figuig +Anenii Noi +Herxheim +Estanzuela +Pānetha +Guthrie +Sant Joan de Vilatorrada +Sagarejo +Ankasakasabe +Arouca +Governador Lindenberg +Puck +Arapgir +Neman +Lichtenau +Avelino Lopes +Rāmchandarpur +Rio dos Cedros +Phrai Bueng +Guantingzhan +Bistān +Tanippādi +Amjhera +Mataili Khemchand +Burrel +Etoumbi +Davos +Bondoufle +Peru +Geldermalsen +Khorol +Sanjiangkou +Mogotes +Soham +Whitburn +Wan Tau Tong +Nirpur +Malvern +Worth +Sarmiento +Ukal +Shamsābād +Belmonte Mezzagno +Adda-Douéni +Wantage +Risch +Hambühren +Chirak +Rianxo +Rainhill +Mudki +Jõhvi +Grand Gosier +Venafro +Asahi +Onna +Pīr Bakrān +Estevan +Anuppampattu +Tiruppālaikudi +Gol Tappeh +Laredo +Venmani Padinjāra +Dolbeau +Pālakollu +Maryānaj +Martinópole +Steinbach am Taunus +Sucúa +Aurāhi +Kapaa +Travilah +Brunete +Kyjov +Pātrasāer +Yellayapālem +Phibun Mangsahan +Danville +Villa Corzo +Pattanam +Nauheim +Afonso Bezerra +Ghagga +Kulgo +Avintes +Amarpur +Vargaūr +Ngorongoro +Tatarbunary +Cassá de la Selva +Khlung +Mount Kisco +Urubici +Lake Monticello +Atchison +Pottipuram +South Dundas +Dabiya +Roseira +Centenário do Sul +Pua +Mutlūru +Chiyoda +Khaţţāb +Sítio Novo de Goiás +São Jerônimo da Serra +Igaratinga +Lavaur +Earlestown +Khasanya +Buenavista +Boizenburg +Jitwārpur Chauth +Reguengos de Monsaraz +Amnéville +Jauli +Van Wert +Rājghāt Garail +Probištip +Laranja da Terra +Gamharia +Kurwār +Snovsk +Manevychi +Rāmpur Kalān +Żurrieq +Martin +São Luís do Curu +Bānu Chhapra +Sugarmill Woods +Hudson +Union Park +Sušice +East Cocalico +Amaturá +Sérékali +Oliveirinha +Dário Meira +Stephanskirchen +Biggin Hill +Kurikuppi +Montgomery +Alberique +Cividale del Friuli +Sohwāl +San Valentino Torio +Yuncos +Hejamādi +Alipur +Olivença +Taufkirchen +Mülsen +Keza +Shepton Mallet +Kaurihār +Călăraşi +Bālupur +Ugrinovci +Bileća +Rejiche +Holmen +Le Pont-de-Claix +Chhātāpur +Andhana +Tyāmagondal +Borshchiv +Gympie +Matomou +Darmahā +Eugenópolis +Icononzo +Pālamedu +Māngobandar +Abbigeri +Castano Primo +Amuru +Eski Yakkabog‘ +Tallimarjon Shahri +Bouchagroun +Methil +Bāra +Terra Boa +Wambrechies +Fox Lake +Panaon +Papraur +Kara-Tash +South Union +Guaraciaba +Scorniceşti +Barbosa Ferraz +Capena +Río Segundo +Cornate d’Adda +Muzaffarnagar +Scaggsville +Timonium +Argelès-sur-Mer +Wooburn +Zafarābād +Arakawa +Wald-Michelbach +Binbrook +Totolapan +Elmira +Seonār +Marreddipalli +Paduma +Telkap +Kuppachchipālaiyam +Ambohidanerana +Flixton +Villa Nougues +Los Corrales de Buelna +Nurmo +Sanson +Kondakomarla +Ravutulapūdi +Emiliano Zapata +Ousseltia +Thouaré-sur-Loire +Miyato +Cantillana +Ānavatti +Belle Chasse +Bougoula +Aleksandrovsk +Annoeullin +Tamiang Layang +Sītalpur +Bolivar +Parkstone +Paceco +Ovada +Guaraci +Nekarikallu +Cave +Chiramanangād +Nilavārappatti +Guaitarilla +Matulji +Bhanghi +Nuvem +Raymond +Villamarchante +Nāranāpuram +Itamogi +Nīrkunnam +Akhnūr +Pipalrawān +Bhaurādah +Waasmunster +Errahalli +Punjai Kālāmangalam +Ban Bang Yai +Gounarou +DeForest +Russellville +Suyo +Morro Bay +Valentigney +Mutukūru +Langhirano +Kirchseeon +Qal‘eh Chan‘ān +Bāsht +Gleisdorf +Agouna +Khrystynivka +Vire +Sarsai Nāwar +Kūhbanān +Gori +Épinay-sur-Orge +Kājhi Hridenagar +Jhundo +Burgos +Ñiquén +Santo Domingo +Antanandehibe +Jarjanāz +Kuruvambalam +Rudra Nagar +Del Aire +Lulhaul +Sāmbre +Odugattūr +Pragadavaram +Kīlrājakularāman +Alakamisy Anativato +Ilıcaköy +East Bakersfield +Villa Unión +St. Albans +Bendougouba +Iramaia +Barnoldswick +Tiszafüred +Moda +Sunadkuppi +Lyngdal +Fürth +Suhāgi +Kattāri +Ogano +Doi Saket +Imi Mokorn +Kuttattuppatti +Jaladurgam +Jackson +Kelilalina +Wang Sombun +Kleinblittersdorf +Kingri +Babhnoul +Komarolu +Lieshout +Déville-lès-Rouen +Lehigh +Itacurubí de la Cordillera +Capela do Alto Alegre +Goasi +Placerville +Mogwase +Campo Largo +Na Sceirí +Racale +Juruá +Fondettes +Sárospatak +Karuvelampatti +Pādiyūr +Munhall +Freeport +Selsey +Brdovec +Crestwood +Chanteloup-les-Vignes +Kumāravādi +Isola del Liri +West Hanover +Borovsk +Pia +Chandreru +Riverton +Nandasmo +Bhālpatti +Rāybāg +Vellavādanparappu +Vidalia +Santa María +Martinengo +Motta di Livenza +Middle Island +Linthicum +Tuktukan +Choachí +Surazh +Chapeltique +Le Pradet +Royston +Kerāi +Le Taillan-Médoc +La Palma del Condado +Deh Bakrī +Uropá +Gaohucun +Bad Orb +Panamarattuppatti +Maniamkulam +Monte San Pietro +Westwood Lakes +Douar Bouchfaa +Amesbury +Forestville +Andovoranto +Ankarabato +Taimali +Rogatica +Bāzid Chak Kasturi +Lowell +Zwettl +Rājānagaram +Grezzana +Santa Bárbara +Praskoveya +Zavitinsk +Ripoll +Voisins-le-Bretonneux +Sapahi +Edwards +Săcueni +Asālem +Fujino +Milton +Alagappapuram +Ōtsuchi +Ubalá +Gülbaar +Dharmavaram +Sharg‘un +Campolongo Maggiore +Novomyrhorod +Ymittós +Ormesby +Diss +Īmani +Meiwa +Richmond Heights +Qamīnis +Villers-la-Ville +Xiaozui +Parnera +Tigrāna +Nandiala +Thevūr +Sivrice +Louvain-la-Neuve +Candiota +Ichnia +Frenštát pod Radhoštěm +Enumulapalle +Léognan +Sütçüler +Raeren +Tamarana +Rewtith +Tanant +Chittārkottal +Sidhap Kalān +Pleasanton +Waggaman +Arbaa Sahel +Sesori +Diedorf +Göynücek +Botticino Sera +Santa Catarina Ayotzingo +Sonoma +Morbach +Jyllinge +Bou Khadra +Marudūr +Loano +Shŭrobod +Aduku +Lwakhakha +Bog’ot +Əliabad +Mara Rosa +Ross on Wye +Marcali +Galsi +Tafalla +Sangam +Qal‘eh Tall +Malibu +Pine Hill +Ambohinihaonana +Borgloon +Desborough +Tolna +San Felice sul Panaro +Potomac Park +Rancho Mission Viejo +Sam Ko +Villahermosa +Tarboro +Nadezhda +Şebin Karahisar +Bestwig +Chettipālaiyam +Milattūr +Ville-d’Avray +Kurdi +Madison Heights +Saray +Hatch End +Sangalbahīta +Trevignano +Maryville +Doraville +Bāghūz Fawqānī +Bogalusa +San Juan +Sidi Namane +Chesterfield +Lachhmīpur +Sahuli +Dallgow-Döberitz +Santa Ana Huista +Medesano +Hartford +Lyons +Bischofswerda +Querência do Norte +Darfield +Gairtganj +Corning +Iretama +Orthez +Jhundpura +Taouloukoult +Peralillo +Gambettola +Matsuda-sōryō +Baetov +Darby +Newberry +Agdz +Tisma +Victoria +Tālsur +Kattipūdi +Yampil +Valadares +Trets +Knowle +Cerreto Guidi +Powdersville +Fô-Bouré +Primavera +Uzda +Sebt Ait Ikkou +Mathigeri +Graçanicë +Bela Crkva +Cazzago San Martino +Iwai +Fountain Inn +Huétor-Tájar +Bhaur +Dakhrām +Maynard +Lohariandava +Ardrossan +Konganāpuram +Hemāvati +Darb-e Behesht +Clute +Cricova +Itārhi +Singapperumālkovil +Katra +Besagarahalli +Hosahalli +Anoviara +Jeseník +Kivistö +Kānkōl +Sālotgi +Dakhān +Cameri +Capim Branco +Broomall +São Brás de Alportel +Lexington +Betsiaka +La Homa +Monte Alegre do Piauí +Aylesford +Chuqung +Joutseno +Chettimangurichchi +Ponnampatti +Al Atārib +Gürün +Yeghvard +Plan-les-Ouates +Aulla +Puranāttukara +Kāla Diāra +Malapannanagudi +Leninskoe +Myers Corner +Nakonde +Chantilly +Kuršėnai +Lamhadi +Bharra +Teus +Daganzo de Arriba +Beaumont +Myślibórz +Ponte Serrada +West Haverstraw +Antsaravibe +Nowa Dęba +Santo André +Novotroitske +Corocoro +Rāmāreddi +Cookstown +Essex Junction +Hrebinka +Santa Terezinha de Goiás +Kadwa +Sant’Antìoco +Filipstad +Tinchlik +Coité do Nóia +Gudibanda +Ambato +Veselí nad Moravou +Vienna +Yuzhno-Sukhokumsk +Gobardhanpur Kanāp +Karadichittūr +Galena Park +Atlit +Amāyan +Friendly +Almoloya +Laćarak +Ruppichteroth +Sedaví +Bellefontaine Neighbors +Pernes-les-Fontaines +Kumbhāri +Sirugudi +Maghra +Felsberg +Ngaputaw +Asfour +Hajeb el Aïoun +San Nicolás +Lambton Shores +Delareyville +Nueva Helvecia +Barmstedt +Bel Air +Sânnicolau Mare +Svedala +Lubawa +Emsbüren +Escuintla +Jacinto Machado +Jiwachhpur +Kendall Park +Little Canada +Chinnamandem +Adohoun +Pāma +Monroe +Blackhawk +Dinagat +Mount Airy +Kralendijk +Schleusingen +Paimio +Groot-Brakrivier +Villa Jaragua +Opatija +Hanson +North Dumfries +Hetane +Altamirano +Dießen am Ammersee +Longbenton +Nakayama +Kilibo +Oloron-Sainte-Marie +Usuppūr +Partāp Tānr +Kanur +Mittahalli +Urcos +Bouhmama +Avigliano +Itzer +Lyakhavichy +Cadelbosco di Sopra +Calçoene +Standerton +Jilava +Ouédo-Aguéko +Antardipa +Canápolis +Ghattu +Khilok +Höllviken +Felton +Englefield Green +Sabnima +Munnūru +Toundout +San Ignacio Cohuirimpo +Lunca Cetăţuii +Pires Ferreira +Barharia +Nanticoke +Mantasoa +Küçükkuyu +Aranda +Massa Lombarda +Bajpe +Abadou +Malaya Vishera +Tubará +Aïn Zora +Khovaling +Küçük Dalyan +Urucânia +Pont-Saint-Esprit +Kingsteignton +Killiney +Khokri Kalān +Tangerhütte +Sokhodewara +Douglass +Acari +West Perrine +Ironton +Pinto +İnebolu +Akbarpur +Al Maḩwīt +Peschanokopskoye +La Maddalena +Gölpazarı +Lake Barcroft +Miro Khan +Karpuzlu +Lymanka +Monte Dourado +Ghoswāri +Dasai +Kabira +Kurhani +Sumner +Ninheira +Aït Hani +Hoogland +Kremenki +Rānko +Buşayrā +Camden +Vysokovsk +Murtosa +Tamanar +Iaciara +Linluo +Böhl-Iggelheim +Vellipālaiyam +Cottage Grove +Fairview +Maida Babhangāwān +Sonakhal +San Gaspar Ixchil +Kartāl +Kombai +Had Laaounate +Jablanica +São João de Ver +Songo +Chorrochó +Jaguari +Yacuanquer +Tenango del Aire +Grijó +Kimpese +Trofarello +Tourza +Pasil +Abergele +Sirūr Tājband +Lejanías +Acate +Nakagawa +Wendell +Amtar +Rocafuerte +Raghunāthpur +Bodippatti +Paricônia +’Aïn Fekan +Zapotitlán +Yazoo City +Kiełczów +Kolárovo +Lagoa do Mato +Jurbarkas +Schönwalde-Siedlung +Sawādah +Shāmpur +Tekkāttūr +Aerzen +Alachua +Airway Heights +Mulungu +Pôrto Firme +Lenzburg +Longuenesse +Gajiginhālu +Daşkəsən +Catanduvas +Scottdale +Tarazona de Aragón +Kasavanampatti +Lakeland Village +Vouzela +Monsenhor Gil +Pūliguntā +Yorkshire +Corumbá de Goiás +Flămânzi +Ban Ko +São Tiago +Bangshang +Neuenhaus +Briançon +Flers-lez-Lille +Trabia +Ambohitromby +Ambolotarakely +Ascope +Koppāka +Acushnet +Bad Iburg +Las Matas de Santa Cruz +Kiến Giang +Millington +Kamikawa +Kanagichō +Puente de Piedra +Pachauth +Pella +Campton Hills +Sawla +Damascus +Chitagá +Pélissanne +Lohārda +Darauli +Kuiyibagecun +Fenglin +Tinqueux +Nave +Don Galo +Beverly Hills +Weinböhla +Le Mars +Martensville +‘Utaybah +Sihma +Monument +Máncora +Ada +Paddhari +Usmate Velate +Niel +São José do Calçado +Büdelsdorf +Mathila +Sweetwater +Excelsior Springs +Mokrisset +Sabaneta de Yásica +Tarabha +Sadovoye +Tilougguit +Phaphot +Kulriān +Red Bank +Yoko +Bir Ben Laabed +Urrugne +Paranã +Chervyen +Wendeburg +Sambalhera +Bischofshofen +Ormesson-sur-Marne +Werlte +Lasht-e Neshā +Shiloh +Marotaolana +Grevesmühlen +Torpa +Madathapatti +Montalegre +Saint-Gély-du-Fesc +Arāvelli +Chota Mollakhāli +Jhonkar +Antenetibe +Apt +Pallattūr +San Juanito +Torotoro +Southwick +Maevka +Weingarten +Nāgambhotlapālem +The Pinery +Zmeinogorsk +Mfou +Leninaul +Kākhandiki +River Grove +Pineville +Mouans-Sartoux +Tāmarankottai +North Bellport +Rabta +Sidi Bousber +Garag +Riverdale +Pazaryeri +Reiskirchen +Reading +Mapleton +Cotacachi +Alcora +Tárnok +Skilloúnta +Alderwood Manor +Dhilwan +Tulshia +Karukkalvādi +Saks +Wanderlândia +La Virgen +Frontera +Benedito Novo +Recreio +Flawil +Felida +Rasebetsane +Parczew +Sahuria +Nāhargarh +Buttar Khurd +Montale +Cedro +Xambioá +Paittūr +Simpelveld +Gölyaka +Flöha +New Albany +Sainte-Savine +Pierre-Bénite +Herīs +Naganuma +Fairview +Loudoun Valley Estates +Forest Acres +Shumanay +Perūr +Vargem +Boudouaou el Bahri +Stansbury Park +Plankstadt +Hilter +Al Karak +Neuhausen am Rheinfall +Obuse +Winterville +Burgau +Bagrīnagar +Monmouth +Nallippālaiyam +Surinam +Santiago Chimaltenango +San Josecito +Murata +Morsand +Soquel +Imst +Andonabe Atsimo +Heule +Ertvelde +Cristino Castro +Tierra Colorada +Čelić +Agramonte +Riesi +Jiménez +San Ricardo +Ban Thung Khao Phuang +Usmat Shaharchasi +Dehqonobod +Nuriston +Bibala +Court-Saint-Étienne +Poção +Angostura +Vembūr +Balwa +Sāmākhiāli +Yedappalli +Kamifurano +Rājāpur +Paina +Presidente Vargas +Markt Indersdorf +Candelaria Loxicha +Susuz +Rio do Pires +Sadon +Lighthouse Point +Buriti Alegre +Bad Wildbad +Kibichūō +Hillcrest +Delta +Marck +Bhopālia +Naini +Adalpur +Devanakonda +Nowe Miasto Lubawskie +Krishnamsettipalle +Heath +Santa Maria de Itabira +Griñón +Gudlavalleru +Hōki +Kearney +Olëkminsk +Soledar +Likiškiai +Regidor +Whitnash +Souq Sebt Says +Chencha +Duraiswāmipuram +Begampur +Ingeniero White +Rājpur Kalān +Gommern +Bonham +Ryhope +Shelton +Ouolodo +El Paraíso +Coacoatzintla +Leidschendam +Attleborough +Somers Point +Sidi Abdallah +Alfredo Wagner +Buraan +Ban Lueak +Lake Hopatcong +Bellmead +Pitkyaranta +Folomana +Las Veredas +Saúde +La Escala +Héricourt +Ambhua +Ontario +Bolekhiv +Cacimbinhas +Arkalochóri +Burgstädt +Clermont +Tiruvalam +Machulishchy +Rokunohe +Española +Hulshout +Taormina +Palatka +Nová Dubnica +Corzuela +Luanco +Balua Rāmpur +Tokigawa +Ambahy +Čáslav +Krèmiss +Bordj Okhriss +Al Musayfirah +Dáli +Hartswater +Belāo +Dighāwāni +Santiago Tangamandapio +Novodnistrovsk +Itaipé +Wepangandla +Vaddepalli +Dhanwār +Gemona del Friuli +Bluffton +Macajuba +Vermilion +Floresta +Olbernhau +Friedeburg +Holbeach +Waimea +East Bradford +Karahallı +Vikrutamāla +Burhia Dhanghatta +Lake Morton-Berrydale +Chalco +Teotlaltzingo +Santa Margarita de Mombúy +Pleasant Hill +Gökçe +Palestina +Lollar +Villers-Cotterêts +Kopparam +Pedras de Maria da Cruz +Launceston +Lakhnā +Standish +Khurmi +Phai Sali +Valpoy +Portage +Minanba +Santiago +Sylva +Flat Rock +Zuyevka +Braine-le-Château +Da +Catanduvas +Vieux-Condé +Bakwa +Lonkly +Fervedouro +El Chol +Biržai +Catunda +Burton Latimer +Saidapet +Plaine Magnien +Timrå +Muquém de São Francisco +Wildberg +Sudogda +Valley +Santa Teresinha +São Sebastião da Grama +Litomyšl +Ulft +Thilogne +Mochizuki +Minobu +Wapienica +Ivankiv +Nova Europa +Koth +Laukāha +Abay +Silverton +Sidi Boushab +Yelm +Manakana +Kāmthi +Dumri +Sisai +Bālia +Dnestrovsc +Yeşilköy +Karkamış +Zawyat Ahançal +Antsahadinta +Choyr +Difficult Run +Le Locle +Eccleston +Melito di Porto Salvo +Plattekill +Fatehpur +Vengānellūr +Ibiassucê +Kiso +Lovejoy +Králŭv Dvŭr +Tarare +Awfouss +Estaimpuis +Takon +Suhr +Labin +Warr Acres +Sotkamo +Fatehpur +Kamalāpuram +Portes-lès-Valence +Worcester +Nevelsk +Southborough +South Lebanon +Darling +Rifle +Firminópolis +Nideggen +Valatt +Nagtala +Roca Sales +Coriano +Libānggaon +Nahulingo +Jurbise +Salò +Wabash +Simbach am Inn +Smithville +Rawdon +Bogué +Ciechocinek +Altenberge +Chandera +Kragerø +Trat +Dona Inês +Shenjiaba +Phangnga +Kalanak +Fairmont +Waterford +Oulad Slim +Târgu Ocna +Prestonpans +Kingston +Grafton +Scartho +Māchalpur +Cunha Alta +Aydıncık +Corral de Bustos +Telsang +Bāghīn +Belaya Kholunitsa +Uraí +Planalto +Oued Amlil +Villeneuve-lès-Maguelone +Thorigny-sur-Marne +Bradford-on-Avon +Barhi +Prakhon Chai +Northfield +Kotharpettai +Kihō +Scituate +Opglabbeek +Podstrana +Marlton +Koffiefontein +Nordkirchen +Kodūru +Ban Ueam +Plombières +Braunsbedra +Cislago +Fayzobod +Masindi Port +Terra Alta +Banta +Cadillac +Brikcha +Croissy-sur-Seine +Mount Vista +Waverly +Hithadhoo +Hachīrūd +Montecchio Emilia +Fairmount +Santiago Suchilquitongo +Kamianka-Buzka +Sāīnkhera +Fanjā’ +Great Dunmow +Charlton Kings +Sleepy Hollow +Cuatro Ciénegas de Carranza +Lemmer +Demmin +Mādhopur +Velappādi +Eriyodu +Gateway +Turmānīn +Kangaroo Flat +Uchoa +Narkatpalli +Neustadt +Jhāua +Farmersville +Suchanino +Puerto Quijarro +Palestina +Tripurāntakam +Leones +Santa Clara La Laguna +Nossen +Jigani +Coronel Freitas +Kaufering +Gelves +Mātsavaram +Dougba +Ickenham +Alaçatı +Gokinepalle +Molango +Constantina +Morinville +Senhora dos Remédios +Caém +Paramoti +Telkapalli +Nakasato +Spout Springs +Gayāspur +Kennett +Cholchol +Faradābād +Jālihalli +Truşeni +Zdzieszowice +Capitólio +Akim Swedru +Pāraippatti +Sangrāmpur +Comstock Park +Spa +Belém de Maria +Altusried +Galion +Fasintsara +Steinfeld +Desuri +Nūkān +Ban Non Sombun +Nidamānūru +Pilar +Mercês +Nalgora +Ordubad +Neuenstadt am Kocher +Mādhopur Hazāri +Raghunāthpur +Winchendon +Douar Echbanat +Conceição da Aparecida +Steinau an der Straße +Sidi Brahim +Phek +Millstone +Czarnków +Mānkur +Sarapuí +Villeneuve-Tolosane +Gharyāla +Plymouth +Sarnen +Haikoucun +Puduppatti +Lima +Nova Olinda +Atripalda +Klipphausen +Kottapuram +Cori +Calimesa +Tnine Sidi Lyamani +Libanté +Augustdorf +Kalgi +Bommārbettu +Momanpet +Corleone +Ortaköy +Ambalanūr +Peravali +Itabirinha de Mantena +Nieder-Olm +Fakirtaki +Shasta Lake +Tavriisk +Bassian +Taksimo +Anröchte +Phon Charoen +Itri +Dan +Jaguaribara +Phulmālik +Bonate di Sopra +Blandford Forum +Khawaspur +Banga +Kemin +Arkadelphia +Fairview +Bārah +Kelandis +Scotchtown +Aesch +Siktiāhi +Hisar +Garden City +Krasnoilsk +Rio do Fogo +Kiklah +Nijoní +Sartana +Gourock +Hirehadagalli +Rounia +Hârlău +Ravanusa +El Refugio +Mallan +Coroneo +Vellatūru +Woodlyn +Delportshoop +Māruteru +Kiridh +Srikrishnapur +Villacarrillo +Shahrak-e Enqelāb +María Pinto +Brikama Ba +Mānikpur +Silea +Canatlán +Jeumont +Mokarrampur +Konkavāripalle +Itapé +Cheruvannūr +Northampton +Brewster +Hoek van Holland +Salempur +Ganga Sāgar +Førde +Natonin +Palmeiras +Steinen +Chestnut Ridge +Aulendorf +Cabestany +Sonwān +Atessa +São Luís do Paraitinga +Tirkha +White Marsh +Garrucha +Caspe +Letychiv +Bowral +Trumbull Center +São Miguel das Matas +Wittelsheim +Levanger +Dăbuleni +Magas +Thạnh Phú +Firou +Aydarken +Benalla +Ahogbeya +Matina +Ben Nasseur +Teddington +Oppatavādi +Ban Dan Na Kham +Melres +Gagnef +Santo Antônio do Jacinto +São Domingos +Qārī Kolā-ye Araţeh +Exeter +El Jicaral +Alvorada do Sul +Erlenbach am Main +Ratnagiri +Oneida +Sirakoro +Ananás +Pintadas +Inhangapi +La Riche +Babhniyāwān +Watervliet +Beni Oulid +Vytegra +Meerhout +Weilheim an der Teck +Vila Franca do Campo +Buzdyak +Itaueira +Wallaceburg +Àrvorezinha +El Álamo +Villebon-sur-Yvette +Riano +Alexandria +Astorga +Arimalam +Appenweier +Stranraer +Ranchos +Höchst im Odenwald +Harsola +Dombāchcheri +Hariāna +Kāmepalle +Newport +Caracol +Berwick +Teocuitatlán de Corona +Karuzi +Peñarroya-Pueblonuevo +Yādavolu +Āzamnagar +Chong-Aryk +Geneseo +Etropole +London +Burtonsville +São Romão +Mildenhall +Clay +West Vero Corridor +Blackfalds +Virginópolis +Úmbita +Aghbalou n’Kerdous +Agua Blanca Iturbide +Amurrio +Bacliff +Wood River +General Salgado +Pola de Lena +Rāmchandrapur +Brookdale +Tyukalinsk +Solim +Paris +Bounaamane +Haspra +Qiushanxiang +Auhar Sheikh +Motibennur +Chester +Riolândia +Rodelas +Southampton +Kurşunlu +Buriti do Tocantins +Khiram +South Huntington +Waynesville +Queens +Jaqma +Großburgwedel +Moldava nad Bodvou +Mwaya +Maurilândia +Jordânia +Qanliko‘l +Pyetrykaw +Broadstone +Lakkireddipalle +Trajano de Morais +Merzenich +Limoux +Knezha +Baran +Caparrapí +Bel Imour +Sabana Grande +Raymondville +Örkelljunga +Santa Inês +Kangning +Birsfelden +Rancho Arriba +Kalamūla +Boldeşti-Scăeni +Alto Paraíso de Goiás +Rubim +Nāna +Shahar Telpa +Bad Lauterberg +Locate di Triulzi +Versailles +Murrells Inlet +Armanāz +Bonfinópolis +Bordj Zemoura +Lyuboml’ +Kirchlinteln +Castelli Calepio +Ouroeste +Ratauli +Castelnovo ne’ Monti +Argayash +Morsbach +Balaungi +Zāwal +Fort Madison +Dalgān +Vilkaviškis +Jordbro +Seridó +Lenoir City +Forestville +Santana +Ma‘rabā +Ekinözü +Guimarães +Billdal +Lutry +Międzychód +Srīsailain +Simarwāra Durgāpur +Arraias +Lishuping +Zaozërnyy +Terra de Areia +’Aïn Tellout +Spitalfields +Rāyen +Hecelchakán +Irineópolis +Cheam +Arlöv +Schalksmühle +Jankampet +Tangermünde +Kandrāwān +La Plata +Bandrele +Sidi Bou Ali +San José de Feliciano +São Geraldo +São Carlos +Sant’Agata de’ Goti +Sidi Embarek +Candelaria +Ganvié +Venecia +Shirako +Itapitanga +Bāgh-e Bahādorān +Oppeano +Ban Wisit +Bogen +San Maurizio Canavese +Selkirk +Saint-Félicien +Kambarka +La Trinité +Mallapuram +Dora +Nanbu +Potiraguá +Salvatierra de Miño +Mehdauli +Peddāpuram +Meghaul +Marina del Rey +Tello +Bela +Tremonton +Gafour +Tekkēkara +Kīlminnal +Gaunivāripalle +Tabubil +Guadalupe +Ullūr +Carroll +Estreito de Câmara de Lobos +Bhikkiwind Uttār +Mel Seval +Pine Ridge +Lenguazaque +Somireddipalle +Māli +Dar Si Aissa +Villa Elisa +Ludlow +Reddipalle +Tipp City +Jaltocan +Ertil +Saudade +Alcaudete +Appleton +Rockport +Chivhu +Goldenstedt +Indalvai +Tenente Ananias Gomes +Axixá do Tocantins +Nazária +Lahstedt +North Lakes +Oliveira de Frades +Rio Acima +Ericeira +Tettuppatti +Alpine +Hopetown +Westonaria +Kut Chap +Fronteiras +Jaipur +Chavinda +Gerzat +Hämeenkyrö +Gohuma Bairia +Querfurt +Blumberg +Sint-Lievens-Houtem +Maxaranguape +Popovača +Körmend +Shahmīrpet +Tārar +Barai +Siparia +Enriquillo +Milton +Whitestown +Elkhorn +Bonito de Santa Fé +Kirchzarten +Bougaribaya +Lonquimay +Ostercappeln +Fenggeling +Goldbach +North Bend +Puerto Santander +Süßen +Alberobello +Boaz +East Whittier +Murowana Goślina +Jaqueira +Nayānagar +Rovinari +Davenport +Robstown +Sgamna +Badru Khān +Induno Olona +Galimuyod +Santa Teresinha (2) +Vairampatti +San Marzano sul Sarno +Catarina +Palmácia +Lūgovoy +Santa Isabel Ishuatán +Angelim +Vila Muriqui +Maheshrām +San Diego Country Estates +Jean-Mermoz +Avranches +Khair Khān +Vellur +Sucupira do Norte +Spelle +Brumath +Ksar Lmajaz +Pfastatt +Kīramangalam +Appārāopeta +Königsbach-Stein +Borgampād +New Hyde Park +Marawī +Pūvalūr +East Setauket +Olifantshoek +Agudos do Sul +Bernex +Rotonda +Głogów Małopolski +Santa Maria Madalena +Chantepie +Pārtibanūr +Minatitlán +Gislaved +Igarapé Grande +Treillières +Raibhīr +Vigasio +Concordia Sagittaria +Akbez +Samux +Governador Archer +Lemington +Jītpur +Muttam +Isola Vicentina +Roberval +Canápolis +Villanueva de Arosa +Miribel +Monte San Juan +Potunūru +Duque Bacelar +Betzdorf +Luathaha +Āhiro +Benyahia Abderrahmane +Koila Dewa +São Miguel de Touros +Halfway +Néo Karlovási +Tha Muang +Dinard +Alguazas +La Chapelle-Saint-Mesmin +Vadakku Ariyanāyakipuram +Kowary +Dangriga +Algarrobo +Milford +Alhendín +Năsăud +Campo Redondo +Santa María +Csömör +Multi +Highland +Tanggemu Nongchang +Nāgasamudram +Divisópolis +Lystrup +Igny +Pingree Grove +Moimenta da Beira +Pântano Grande +Duga Resa +Kandulāpuram +Minamiaso +Charalá +Zumaia +Aubière +Snodland +Ramacca +Oignies +Cordele +Tlalixtac de Cabrera +Cedral +Varre-Sai +Centralina +Huittinen +Douchy-les-Mines +Rideau Lakes +Bonthe +Vejen +Borzna +Medina +Pôrto Esperidião +Flowood +Ouangani +Mosquera +Miāni +Columbia +Fort Oglethorpe +Liberty +Pintuyan +Shyroke +Kastav +Rāmannapeta +Oudewater +Çanta +Tefenni +Navabad +Chavkandak +Kazo +Ellon +Alpena +Sechelt +Tetela del Volcán +Rehburg-Loccum +Courrières +Cortês +Garhi +Inkerman +Bosanska Krupa +Florânia +Tarashcha +Beilngries +Douar Mzoura +New Silksworth +Kottapālem +Barāgaon +Tokunoshima +Carencro +Niebüll +Eleşkirt +Arataca +Claymont +Phra Pradaeng +Radyvyliv +Al Jazīrah al Ḩamrā’ +Pescaria Brava +Narasingam +Barāhi +Lake Arrowhead +Jemaat Oulad Mhamed +San Blas +São José do Jacuípe +Mirante +Blain +Gudofredo Viana +Carmo do Rio Verde +Potosí +Venkatāpuram +Celano +Randazzo +Balangkayan +Załęże +Rainbow City +Astoria +Biandanshan +Poirino +Pechea +Chaungtha +Nanfang +Carice +Jimbolia +Münchberg +Amgachia +Birao +Angwāli +Aliganj +Kothi +Darwa +Akil +Kaynaşlı +Vera Cruz +Shirbadgi +Halgūr +Kendallville +Băcioi +Olovo +Gaillard +Fort William +Mikhaylov +Remada +Chikni +Surla +Birkenfeld +Jhakhra +Pānchi +Jandiāla +Kulundu +Kranuan +Jesenice +Madridejos +Ajjipuram +Pipra Naurangiā +Bellamkonda +Svidník +Ban Bong Tai +Marlton +Bela Vista de Minas +Canteras +Bomporto +Evander +Mörlenbach +Cedartown +Korolevo +Fanzhao +Lābhgaon +Katālpur +Ban Bang Toei +Roddam +Biskupiec +Balikumbat +Bleicherode +Foz +Vorsma +Itapiranga +San Pablo +Ware +Mexicaltzingo +Tut +Zelfana +Calasparra +Jādupatti +Port Townsend +Neuville-en-Ferrain +Bordighera +Castleton +Bois-des-Filion +Rogerstone +New Richmond +Ambalavao +Toca +Sobral de Monte Agraço +Pabégou +Togamalai +Penn +Corte Madera +Vūtukūru +Msila +Sidi Abdelaziz +Akhaltsikhe +Batán +Narot Mehra +Shioya +Higashikagura +Aïn Zohra +Valaparla +Kilkunda +Hazle +Opochka +Teplodar +Maur +Tiruchchuli +Kanteru +Telnāl +Arcola +Molalla +Pilar +Choele Choel +Werneck +Lenggries +Masanasa +Caudete +Aizenay +Kāza +Msoga +Busca +Ban Klang +Paris +Gakuch +Zhengdong +Ouled Rabah +Parempuyre +Visbek +Whitchurch +Mungod +Periyanegamam +Vernal +Jefferson +Franklin +Bibbiano +Alella +Ban Pa Hung +Great Missenden +North Gates +Za’roura +Divonne-les-Bains +Néo Psychikó +Villasāgar +San Felice Circeo +Cabo Rojo +Montignies-le-Tilleul +Okondja +Caudebec-lès-Elbeuf +Rignano Flaminio +Hermantown +Elattūr +Iizuna +Liminka +Corfe Mullen +Fílippoi +Dhanur Kalyānwādi +Snohomish +Siswār +Haldipur +Urlaţi +Aigle +Rompicherla +Solindābād +Rāparla +Hire Megalageri +Qovlar +Potavaram +Hobart +Greenville +Plaridel +Kirkel +Serebryansk +Scherpenzeel +Génova +Deūlgaon Māhi +Auterive +Serra Caiada +Bilga +Kondalahalli +Bhagirathpur +Hillsdale +Doorn +Borim +Mawai +Garden Acres +Monaragala +Pocklington +Beccles +Manglūr +Sirigeri +Ankily +Eidsberg +Zavolzhsk +Cajapió +Belagola +Sūlagiri +Yermolino +Oggaz +Meymand +Kabataş +Altötting +Granada +Meuselwitz +Rettanai +Hipparga +Begowāl +Nāthpur +Sedico +Hull +Fuveau +Aroāli +Rāsak +Tolbazy +Torre Santa Susanna +Sylva +Verkhniy Tagil +Vaddādi +Kalakeri +Anandnagar +Horti +Ardal +Corcuera +Komorowice +Struer +Safford +Masdi +Kondakindi Agrahāram +Adigappādi +Hackettstown +Warrenton +Garliava +Marondry +Uchtepa Qishlog’i +Bandixon +Isabela +Baker City +North Glengarry +Türkan +Gunbarrel +Videle +M’Chouneche +Raghunāthpur +Tutzing +Mori +Harrison +Zérizer +Buxerolles +Daruvar +Mashhad Rīzeh +Perumuchchi +Parnaguá +Kittery +Syców +San Simón +Gambissara +Cuapiaxtla de Madero +Havanūr +Nizza Monferrato +Nkokonjeru +Jomasho‘y +Shohimardon +Naftalan +Forres +Chauki Hasan Chauki Makhdum +Glenwood Springs +Rokkasho +Nogliki +Sarız +Roboré +Fouesnant +Padiham +Machchand +Shāhpur Chaumukhi +Muurame +La Misión +Talugai +Korosavāda +Progress Village +South Huron +Guémoukouraba +Kumçatı +Sahidganj +Marieville +Kadalādi +Procida +Cairo +Candelaria +Worsley +Ekamba +Zhatay +Nong Ki +Quartz Hill +Warfield +Jangalapalle +Advi Devalpalli +Brandywine +Mellieħa +Kapyl +Erutukada +Cambridge +Miḩqan +Hardās Bigha +Karapa +Ōnan +Alexandria +Vaals +Kafr Takhārīm +Kele +Padugaipattu +Littleton +Roßtal +Gignac-la-Nerthe +Spanish Fort +Primeiro de Maio +Fiuggi +Cody +Zuidlaren +Bingham +Kilsyth +Thikriwāla +Chichihualco +São Sebastião do Maranhão +Hongliuwan +Tympáki +Pińczów +Umarizal +Weil im Schönbuch +Abergavenny +Ráth Tó +Eumseong +Penetanguishene +Santa Catarina Masahuat +Hozin +Saladoblanco +Kouinine +Cabañaquinta +Mondeville +Mālīnagar +Sapkyo +Rio Vista +Naters +Saint-Max +Kuroshio +La Grange +Williston +Sax +Ghatāwān +Novi di Modena +San Elizario +Çeltik +Khaira +Roelofarendsveen +Bieber +Binéfar +Cabriès +Yaotsu +Atoka +East Rockaway +Villerupt +Bee Ridge +Neves +San Vicente de Castellet +Mesrā +Badia Polesine +Waldwick +Stropkov +La Leonesa +Göytəpə +Ouédo +Porangaba +Kasba +Howell +Antanananivo +Mondaí +Bāgalūr +Vrnjačka Banja +Kidira +Avelgem +Swieqi +Valozhyn +Willstätt +Mazamet +Lake Hiawatha +La’tamna +Ban Bu Sung +Mstsislaw +Heubach +Kwale +West Point +Olaine +Bobenheim-Roxheim +Were Īlu +Auchel +Kosh-Agach +Sung Noen +Struthers +Jafra +Jocoro +Radlett +Browns Mills +Clinton +Orange Lake +Dudhpura +Shāhpur Undi +Bāra Khurd +Mocharim +Alassio +Scenic Oaks +Burgum +Parthenay +Mold +Rupāna +Abjīj +Macerata Campania +Jiji +Călan +Kisújszállás +Dhāmua +Taghbalt +San Ignacio de Moxo +Rüdesheim am Rhein +’Aïn Naga +Dalāwarpur +Begijnendijk +Satipo +Verucchio +Krivodanovka +Sāha +Rangasamudram +Vange +Lysá nad Labem +La Bañeza +Takahama +Blackwells Mills +Namorona +Levski +Méry-sur-Oise +Al Hāmah +Vysokyi +Schotten +Oakbrook +İliç +Francisville +Ciudad Tula +Chapeltown +Lydney +Taiyūr +Gauli Palāsiya +Petmanhalli +Pájaros +Elgin +Büyükorhan +Tinkoni +Lepākshi +Sakuho +Makaha +Mikuszowice +Mengibar +Lipova +Maywood +Tiszaföldvár +Glocester +Zaniéna +Abaiara +Nallikodūr +Sermoneta +Cross Lanes +Parilla +Ikryanoye +Bou’nane +Vembaditālam +Cheat Lake +Mahārājapuram +Baldeogarh +Volpago del Montello +Tay +Zaggota +Olevsk +Houthulst +Suthālia +Puduparambubhāgam +Başmakçı +Sirugamani +Nikaidō-kaminoshōchō +Massi +Hājīpur +Red Hook +Ganapavaram +Castlegar +Lauterach +Munagapāka +Bela +Goito +Benemérito +Novooleksiivka +Tomboutou +Pānrepatti +Lālmunia Munhāra +Kūcheşfahān +Bierbeek +Steinhaus +Kaldenkirchen +Vernouillet +Southwater +Kirundo +Kīl Perambalūr +Harrisonville +Dumont +Canelli +Toukoto +Kingaroy +Airmont +East Rutherford +Kuldīga +Corozal +Reedsburg +An Nayrab +Grosse Pointe Farms +Vernon +Vuktyl +George Mason +Trebbin +Belpāra +Cavan Monaghan +Huejuquilla el Alto +Ramiriquí +Montignoso +Chesapeake Ranch Estates +Pajacuarán +San Pedro Huamelula +Dylym +Dhangaraha +Manahari̇̄ +Pakka Kalān +Sīlamalai +Juripiranga +Mayfield +Roslyn +Fort Meade +Piedrahita +Saint-Laurent-de-la-Salanque +Dagiāpāra +North Versailles +Platón Sánchez +Strasshof an der Nordbahn +Vandamettu +Dores de Campos +Le Beausset +Capodrise +Moba +Suaita +Alajärvi +Senanga +Zaruma +Saint-Loubès +Lowell +Villiersdorp +Horbury +Tiri +Amwa Majhār +Soahany +Haider Khel +Krynica +Shengping +Kolagallu +Srîfa +Chartoûn +Qâna +Amioûn +Râs el Metn +Ed Dâmoûr +Butha-Buthe +Ghadāmis +Belavabary +Mahabako +Boanamary +Morafeno +Esira +Sandravinany +Bedidy +Vohitrafeno +Daraina +Masiaboay +Ambatomivary +Ambodisikidy +Ambohimiarivo +Bekodoka +Maroharatra +Ambararatabe +Ambatomifanongoa +Ambohitrambo +Ebelo +Tsararano +Analalava +Lohafary +Antsoantany +Ambovonomby +Isahara +Ambodivoara +Vodiriana +Ambohimahazo +Ambodimadiro +Andranambolava +Marosakoa +Amborompotsy +Soavimbahoaka +Erada +Mahabe +Mahabo-Mananivo +Miary-Taheza +Ankadindambo +Antaretra +Betrandraka +Amparihy +Tanamarina +Sahanivotry-Manandona +Andranomenatsa +Ambodimandresy +Anontsibe-Sakalava +Amparihitsokatra +Ambatolava +Ankerana +Sihanamaro +Vinanitelo +Vinanitelo +Ifarantsa +Miarinarivo +Ampasimazava +Vohitany +Vohitsaoka +Andranopasy +Beheloka +Ankirondro +Tamponala +Ambatolahy +Katsepy +Vondrozo +Tanambao-Daoud +Sahatona-Tamboharivo +Beanana +Soatanana +Ampitahana +Anosimparihy +Vatana +Ambalanjanakomby +Zoma-Bealoka +Jangany +Ianapera +Ambahatrazo +Fanjakana +Mora +Putao +China +Padang Besar +Závora +Outjo +Al Mazyūnah +Surmon Chogga Grong +Basla +Gadani +Bunji +Ghota Fatehgarh +Setúbal +Diabougou +Koumpentoum +Gadoon +Murgap +Khunays +Kadama +Bukomansimbi +Xishrov +Oyim +Tujg +Boladı +Fatikchari +Puerto America +Mboki +Gar +Ziketan +Sola +Mataguá +Morayra +Karaga +Rebola +Pont Sondé +Haria +Waghāi +Ghargaon +Deh +Medarametla +Hanzviur +Amsin +Muttalakanpatti +Isnapuram +Karumūlaikkal +Dhalai +Nidamalūru +Budwan +Khānpur +Venkatāpuram +Chhimluang +Dhīrwās +Siddarāmpuram +Reha Mota +Paravākkottai +Mevāni +Chhatarpur +Thariāl +Dewal Thal +Lakshmīpuram +Gāndhali +Fatehgarh +Kambhāladinne +Kerwāda +Ulipuram +Kochhor +Betnoti +Bālāgām +Mangalam +Sotik +Kargi +Kourani +Kolno +Rāmamangalam +Bishunpur +Wahlstedt +Pierrelaye +Bomareddipalli +Czersk Pomorski +Aniche +Rakhwāri +Atri +Melendugno +Bad Frankenhausen +Mengen +Soyaux +Digora +Downham Market +Vilpatti +San Marcos +Euxton +Erraballa +Pāikpāra +Fatehābād +Lambesc +Yādwād +Monteriggioni +Marton +Ketugrām +Marshall +Älta +Tarhjicht +Lillers +Praia do Carvoeiro +Stenungsund +Rangamāti +Barkly East +Pavlikeni +Salemi +Kinnelon +Ben N’Choud +Fateha +Kengarai +Pullambādi +Chada +Dilra +Aşağı Ayıblı +Gudensberg +Inungūr +Simri +Budd Lake +Maḩajjah +Lapinlahti +Galleh Dār +Lenīnskīy +Brentwood +Gūlyam +Hosur +Woodbury +Independence +Conway +Chambly +Crikvenica +Itikalapalle +Cape Canaveral +Paināl +Madhuban +Penn Forest +Sulęcin +Wood-Ridge +Fairmount +Yueyaquan +Dettingen an der Erms +Cedar Hills +El Cairo +Shildon +Kanyāna +Maḩalleh-ye Shīrīnū +Ainring +Ringkøbing +Tansandra +Fairfield +Bolsward +Hamilton +Eybens +Bishopstoke +Erenler +Valdobbiadene +Quinto di Treviso +Walker Mill +Marysville +San Nicolas Buenos Aires +São Tomé +Inami +Tsunō +Willoughby Hills +Přelouč +Ottendorf-Okrilla +Marly +Bhawānīpur +Barano d’Ischia +Boundji +Bananal +Dumri +Māmobihāt +Colts Neck +East Liverpool +Casino +Kottaipatti +Tzucacab +Gaolingcun +Sîngera +Tân Sơn +Dujiashigou +Vegachí +Erraguntlakota +Detroit Lakes +Altenholz +Cuesmes +Aberaman +Tokkavādi +Hiranai +Los Ríos +Kishunpur +Kambaliyampatti +Şūfīān +Iwashita +Anamã +Chākicherla +San Calixto +Birchington +Judenburg +Sagurē +Nairn +Makale +Sūndekuppam +Kapasiāwān +Woodburn +Padinjārebāgam +Khāndsa +Bastak +Aībak +Bertem +Friedrichsthal +Mahem +Siechnice +Sankt Andrä +Handsworth +Conselve +Ettimadai +Khurān Milik +Ratne +Kawara +Bastrop +DuPont +Halls +Souama +Saharbani +Muskegon Heights +Koloti +Leppävirta +Kapuvár +Anáhuac +Fallston +Kargopol +Aich +Bad König +Oelsnitz +Sorkheh +Picnic Point +Hooglede +Coal +Fiľakovo +Verkhivtseve +Qufādah +Sellersburg +Arauá +Torrejón de la Calzada +Winfield +Birni Lafia +Puttige +Ennamangalam +Cuicatlan +Heeze +Aboso +Chavusy +Tamzoura +Bhado Khara +Ban Ngao +Payerne +Bad Bevensen +Balatonalmádi +Sparta +Mount Holly +Snezhnogorsk +Kamalasai +Sniatyn +Thị Trấn Mậu A +San Antonio +Consuegra +Aldenham +Bellavista +Ócsa +Erquelinnes +Caraíbas +Nariār +Fino Mornasco +P’yŏngch’ang +Pachchāmpālaiyam +Dubove +Pôrto Xavier +Ammanabrolu +Gossau +Padilla +Kenafif +Coycoyan de las Flores +Bad Ems +Ipupiara +Dongou +La Sierra +Marpingen +Burscough +Kamdoli +Santa Maria +Nohfelden +Kraaipan +Waltenhofen +Mīāndasht +Mulungu +Telwa +Hingyon +La Pointe +Akalāpura +Telpur +Kinālūr +Santa Clara +Fosses +Lālganj +Khāpdeh +Bucine +Morden +Birkenau +Karimunjawa +Kalimala +Kadrābād +Parwāha +Villas +Farsund +Grossos +Ţālkhvoncheh +Heves +Vedurupāvalūru +Rockcreek +Ban Pong Yaeng Nai +Oldenburg in Holstein +Kargahiā Purab +Nanzhou +Maxéville +Bajwāra +Capitola +Welkenraedt +Dongcha +Angalakudūru Malepalle +Rye Brook +Temiskaming Shores +Urzhum +Nové Město na Moravě +Dharmavaram +Minnāmpalli +Jilotlán de los Dolores +Novgorodskoye +Setubinha +Bekkaria +Balderton +Pavittiram +Fair Oaks Ranch +Honwāda +Saarijärvi +Barni +Ellisville +Varzedo +Pipraun +Mussomeli +Uniontown +Strzelce Krajeńskie +Liskeard +Pūdimadaka +Dar El Kebdani +Mandello del Lario +Pokrovske +Manduri +Epanomí +Kunnūr +Karajgi +San Isidro +Polistena +Arroyohondo +Sidi Rahhal +Boufatis +Kaunra +Vaiano +Phak Hai +Holsbeek +Glanmire +Bharhopur +Lomazzo +Coweta +Kaith +Ogdensburg +Maceira +Latifpur +Zefýri +Nāvinipatti +Panjāb +Sursee +Baldock +Kirkland +Matadepera +Carmaux +Suhiya +Kourimat +Maisenhausen +Pachalum +Shankarampet +Tonse East +Nenagh +Wāngi +Kümmersbruck +Bilehra +Mission +Pliezhausen +Wilsele +Huldenberg +Schlitz +Dera Baba Nanak +Ippagūdem +Asola +Golden Hills +Rödinghausen +Brinkmann +Frýdlant nad Ostravicí +Diavatá +Siruvalūr +Urgnano +Miadanandriana +Messíni +Baghānt +Jettihalli +Köflach +Ivančice +Worth +Belmont +Sūknah +Coello +Pizarra +Gudgeri +Souleï +Namakadu +Campi Salentina +River Vale +Qiziltepa +Muthābana +Bhadsara +Saquisilí +St. Augustine Shores +Mohlanapeng +Kaimāti +Kadanganeri +Chintapalle +Gurwaliā Biswās +Hinton +Itapeva +Petorca +Sultānpur +Saint-Sauveur +Ankazotsifantatra +Vardenik +Biot +Beckett Ridge +Ga-Kgapane +Kaiken +Ploërmel +Meldola +Wapakoneta +Trancoso +Hosahalli +Ech Chaïbat +Chupaca +Barahra +Margarita +Baltāra +Kösching +Heilsbronn +Krasnyy Yar +Widhwidh +Ban Pha Bong +Vétraz-Monthoux +Foum Jam’a +Ban Phan Chali +Beneditinos +Nayāgaon +Reddigūdem +Heerlerbaan +Ruoqiang +Santa María de Palautordera +Kanjiža +Saint-Pierre-du-Mont +Qāzigund +Douar Snada +Kushnarënkovo +Metsamor +Alcorta +Ouled Brahim +Montigny-en-Gohelle +Chegūr +Ommangi +Varna +Stocksbridge +San Miguel Sigüilá +Sarkeghāṭ +Krzeszowice +Keokuk +Therwil +Lajes +Pālepalli +Iwamuro-onsen +Greencastle +Berd +Swan Hill +Muttattuteruvu +Boudinar +Ntorosso +Roche-la-Molière +Poggio a Caiano +Richmond Heights +Sauk Village +Ambodiriana +Belomorsk +Laakirchen +Vettaikkāraniruppu +Celldömölk +Lingampet +Mahisānrh +Geylegphug +Independent Hill +Nueva Palmira +Majhgawān +Tanichchiyam +Outa Bouabane +Zinkiv +Paradarāmi +Humlebæk +Abram +Bērikai +Ciudad de Loreto +Aranzazu +Mittenwalde +Dandoli +Huichapan +Ii +Sovicille +Nhandeara +Narasimharājapura +Sweet Home +Grigny +Fundeni +Rodynske +Pailón +Renaico +Norosí +Fuente Palmera +Feyzin +DeRidder +Juru +Achchippatti +Kadoli +Santo Stefano di Magra +Cuencamé de Ceniceros +Altofonte +Plains +Mariluz +Tīgaon +Anjahamana +Lambertville +Eerbeek +Berezivka +Barcs +Surīr +Hochdorf +Bisingen +Tūlin +Boriguma +Mosjøen +Tha Mai +Merchweiler +Katarmāla +Cavriago +Sturbridge +Kobeliaky +Chimay +Hānsa +Dindanko +Masquefa +Khariāl +Kokiladānga +Pedda Kotayalanka +Itamukkala +Kaimūh +Shāhzādpur +Manubolu +Partanna +Qarabalyq +Saint-Grégoire +Patsanda +Philipstown +Makariv +Chandankiāri +Ozieri +Fort Salonga +Carregal do Sal +Touwu +Karghar +Vigonovo +Succasunna +Tekit +Bardmoor +Çıldır +Aramari +Cachipay +Tolmezzo +Sieverne +Parkes +Etchojoa +Iraiyūr +Pushpattūr +Terku Narippaiyūr +Bīrpur Bārāpatti Pindraun +Peru +Mudgee +Bockenem +Kodivalasa +Kamikita-kita +Ribadeo +Couzeix +Basso +Toudja +Gangāpur Athar +Suntar +Berilo +Ilsfeld +Pādarti +Nisarpur +Loudonville +Kusugal +Guia Lopes da Laguna +Alfaro +Nödinge-Nol +Jixian +Pithaura +Baragaon +Mogoşoaia +San Rafael Obrajuelo +Nāgulapādu +Amjhār +Castelletto sopra Ticino +Jesup +San Vicente +Jennings +Nong Wua So +Píllaro +Indūrti +Morrovalle +Oulad ’Azzouz +Gorha +Little River +El Espinar +Plainville +Serafimovskiy +Caldicot +General Alvear +Socotá +Haapsalu +Kiáto +Apiúna +Pasewalk +Vettweiß +Chuhal +Kostrzyń +Santa Bárbara +Kouarfa +Samabouro +Altlandsberg +Köngen +Aurāhi +Basāpatna +Pasupatikovil +Jerissa +Sasaima +Nordwalde +Nūrpur +Kalas +Vlist +Banino +San Sebastián +Coamo +Vidor +Sande +Totma +Portet-sur-Garonne +Arden Hills +Pālkot +San Vendemiano +Grey Highlands +Dumri +Gangaur +Sorab +Ban Mae Sam Laep +Kinhālu +Kalyānpur +Paravāda +Bergambacht +Laubach +Kīl Vālūr +Keshwāri +Alden +Djangoa +Olmos +Drezdenko +Rasht +Hönow +Mānushmuria +Mae O +Bauska +Imlil +Pisac +Mikun +Velpūru +College Place +Reşadiye +Bad Liebenzell +Sukhsena +Boscotrecase +Pleasant Valley +Sabana Larga +Madera Acres +Dorogobuzh +Altmünster +Silvārpatti +Khathjari +Hawera +Łobez +Santa Rosa +Dangcheng +Visselhövede +Alamosa +Bukowno +Veppattūr +Kominato +Lincoln City +Magstadt +Seysses +Avon Park +Chevy Chase +Marathon +Tiztoutine +Trescore Balneario +Bagnolo in Piano +Bay St. Louis +Alcarraz +Choppington +Chak Thāt +Bāg +Beverly Hills +Nyurba +El Roble +Kippax +Bamora +Ghāriyah al Gharbīyah +Valpovo +Kami-kawabe +Alkhan-Yurt +Gökçeada +Tottington +Kotli Ablu +Mora +Jhitkahiyā +Kiban +Albert +Alagarai +Koini +Terrace Heights +Helston +Rute +Neshannock +Štúrovo +Chom Thong +Bueng Khong Long +Ronda Alta +Dodworth +Charne +Gangania +Nueva Toltén +San Fernando +San Fernando +Bavānāt +Muddanūru +Biei +Repatriación +Nallamadu +Rāmnagar Bankat +Jalālpur +Semri +Derazhnia +Oulunsalo +Heath +Miastko +Figeac +Stonegate +Farako +Xincun +Manalūrpettai +Cittanova +Urdorf +Pakri +Vālāntaravai +Tesalia +Pepinster +Sugbongkogon +Perket +Karankot +Garrison +Puerto Tirol +Zell am See +Wölfersheim +Loudéac +Montemarciano +Mahīnāthpur +Keansburg +Plüderhausen +Çamoluk +Barracão +El Molar +Washington +Agatogba +Wald +Voreppe +Kanchanpur +Jaisinghnagar +Kāttāgaram +Green Cove Springs +Gangūru +Salkhua +Fultondale +Ncora +Gaszowice +Pobiedziska +Ingré +Erravaram +Aramangalam +Kolnūr +Xiba +Oberstdorf +Shepperton +Pembroke Dock +Gorom-Gorom +Dhamsāin +Croydon +Mesetas +Sant’Egidio alla Vibrata +Grigiškės +Tadla +Glencoe +Włoszczowa +Sankt Johann in Tirol +Chegurumomadi +Jagatpur +Monmouth Junction +Suzdal +Byalynichy +Sātulūru +Shāhganj +Ambinanintromby +Lakha Nëvre +Ghabrah +Dubliany +Alayor +Tsaramasoandro +Liesveld +Radekhiv +Felpham +Beiuş +Hacarí +Urlāha +Yamaguchi +Puerto Nariño +Dulce Nombre de Jesús +Undavalli +Dhanwāda +Andrainjato +Fandrandava +Ban Mae Chedi +Basavilbaso +Skidal’ +Sirdala +Hunasamaranhalli +Ciudad Cuauhtémoc +Ribeirão do Largo +Bad Breisig +Cobham +Sedona +Brownsville +Ain Karma +Novyye Atagi +Redentora +Twist +Darnétal +Raynes Park +Lykóvrysi +Chausa +Murungattoluvu +Birżebbuġa +Fürstenau +Osthofen +Ghusiya +Motīpur +Eagle Point +Everswinkel +Semmarikulan +Calca +Quiculungo +Giesen +Bou Nouh +Kaithinia +Non Sung +Bom Jesus da Serra +Lágos +Gambolò +Moyogalpa +Aleksandrov Gay +Alto Piquiri +Kitee +Rangasamudram +San Giorgio del Sannio +San Pedro +Grand-Couronne +Cambridge +Kusumha +Hadiāya +East Brandywine +East St. Paul +Nova Floresta +Atlapadu +Rāmpur +Nolinsk +Drăgăneşti-Olt +Chiang Klang +Morrisville +Seforong +Thomaston +Vesele +Karattuppālaiyam +Elambalūr +Zāhed Shahr +Terralba +Decatur +Oudenburg +Idanha-a-Nova +Ledegem +Tayakou +Bareh +Kakkat +Tivim +Aghbalou Aqourar +Mahuver +Carnaubais +La Ferté-sous-Jouarre +Panganiban +Bondues +Tellār +Ingleside +Portland +Estavayer-le-Lac +Litovel +Qahjāvarestān +Shchuchye +Wijnegem +Pine Lake Park +Haraiyā +Ayvacık +Oberhausen-Rheinhausen +Haraiyā +Aqadyr +Fredonia +Lanškroun +Kottampatti +Sundarapāndiyam +Poggio Renatico +Zengjiaba +Worpswede +Lāpangā +Mentone +Wakoro +Vitorino +Serris +Douar Lehouifrat +Ranomafana +Volodarsk +Tiruvengadam +Harvard +Kokologo +Periyapuliyūr +Kannāndahalli +Vanipenta +Gołuchów +Sovata +Lovendegem +Punnavalli +Belsara +Bararam +Rāmpura +Lake Mohawk +Mount Evelyn +Schwaikheim +Pipra Dewās +Madhubani +Āttūrkuppam +Eksjö +Polorós +Purkersdorf +Genemuiden +Huari +Chilanga +Sirka +Wadgira +Tungāvi +Flowery Branch +Mae Ai +Imías +Asuke +Dassel +Zafargarh +Rombas +Pāra +Rolesville +Aklim +Pai Bigha +Sant Julià de Lòria +Neu Bleckede +Rhosllanerchrugog +Kokoszki +Dodóni +Latteri +Cypress Gardens +White Horse +Kola +Imām Şāḩib +Talachyn +Wittenbach +Loreto +Pakhtaobod +Neves Paulista +Belalcázar +Gorgāb +Oostzaan +Sigtuna +Ban Bueng Kok +Sidi Ahmed El Khadir +Santamāgulūru +Mohdra +Malhārgarh +Velakkuttai +Raseiniai +Guifões +Saint-Lys +Pórto Ráfti +Country Club +Hoeselt +Moravská Třebová +Bohechío +Eidson Road +Sävja +Avalūrpet +Santo Tomás de los Plátanos +Pueblo Viejo +Saint-Vith +Tanaina +Stoneham-et-Tewkesbury +Fuli +Ventania +Concordia +Lentvaris +Amritpur +Klötze +Benkovac +Csorna +Sunbury +Hyrum +Alfred and Plantagenet +Alberdi +Großröhrsdorf +Borgo +Pullūru +Pondalūru +Perumbalam +Jibou +Ak-Suu +Thap Khlo +Ban Kang +Ingichka +Brandis +Makri +Piprai +Mońki +Chuy +Lambeth +Pindra +Crosia +Lurate Caccivio +Madanpur +Dināra +Ottappidāram +Castellamonte +Zoudjamé +Tuta +Lindesberg +Canonsburg +San Gregorio Atzompa +Pathāri +Pechory +Inácio Martins +Mākhar +’Aïn Leuh +Kenzhe +Donabate +Lisbon +Tepetlán +Zumárraga +Middleton +Valsequillo de Gran Canaria +Villarrubia de los Ojos +Parmānpur +Laligam +Velpūru +Bithauli +Mount Airy +Langar +Mānrar +Oued Laou +Huachipato +Revel +San Francisco la Unión +Čepin +Orotina +Pinos Puente +Aleşd +Thepaha Rāja Rām +Reddippatti +Pareo +Palafolls +Karīmpur +Kishanpūra Kalān +San Juan del Puerto +Luza +Kadriye +La Farlède +Dundankop +Byarozawka +Bradwell +Kannamangalam +Dahua +Masku +Talapalli +Salmānshahr +Jucuruçu +Arques +Inverell +Bni Boufrah +Barahbatta +Merville +Dandkhora +Pike Road +Palmares Paulista +Sallaumines +Hardia +Tiruvambalapuram +Konidena +Silver City +Comala +Nova Bassano +Dhorgaon +Sangonera la Verde +University of Virginia +Tuam +Simrol +Le Muy +Countryside +Mont-Tremblant +Saint-Doulchard +Ikkarai Boluvāmpatti +Delčevo +Tirúa +Akabira +Glenfield +Nanjundāpuram +Kataha +Torihama +Ban Dong Mada +Immingham +Beltangadi +Ban Lao Yao +Frøn +Willow Street +Pereshchepyne +Bendrahallī +Piploda +Kathūrah +San Lorenzo della Costa +Venecia +Adamankottai +Nueva Esparta +Santa Ana +Bhāgsar +Broni +Argelato +Orange Cove +Veitshöchheim +Racconigi +Dombasle-sur-Meurthe +Brewer +Monett +Morehead City +Godhra +Mādāri Hāt +Filadelfia +Dobre Miasto +El Haouaria +Banská Štiavnica +Bochaha +Kudowa-Zdrój +Pinhel +Itasca +Armutlu +Uracoa +Gundi +Nambutalai +Colonia Nicolich +Kauniainen +Selfoss +Kushijima +St. Stephens +Campo Erê +Bastrop +Aweitancun +Sigatoka +Bernay +Sabangan +Caldas de Reyes +Anantpur +Bilāspur +Sturgeon Bay +Saint-Rémy-de-Provence +Bluefield +Port Elgin +Nowy Dwór Gdański +Flexeiras +Saint-Zotique +Krasnogvardeyskoye +Tadhwa Nandpur +Babhantoli +South Strabane +Widnau +Südlohn +Grado +Neuville-lès-Dieppe +Hockley +Datori +Caernarfon +Boves +Saint-Raymond +Oulad Imloul +Zadonsk +Middleton +Fair Oaks +Kfar Aabîda +Władysławowo +Ohrdruf +Masar +Bowen +Alcanar +Rāmpur +Epalinges +Nersingen +Fernán-Núñez +Gāndlapenta +Agareb +Harīpur +Mangalam +Tila +Ćuprija +Izium +Muyinga +Thogadūru +Kirlampūdi +Tottenham +Cuéllar +Herkimer +Mortágua +Dasso +Butler +Yazıkonak +Postojna +Dessel +Sannicandro di Bari +Sandy Hook +Branquinha +Guateque +Bhawānandpur +Nakaechi +Gibsons +Levokumskoye +Eschenbach +North College Hill +Jessup +Swanage +Hindoli +Nurobod Shahri +Yarm +Hemau +Khesht +Oil City +Hartland +Yalagüina +Târgu Frumos +Sofiivka +Bálsamo +Hlinsko +Petua +Ḩās +Dobhāwān +Szigetvár +Middletown +Xicoténcatl +Ban Nam Dip Luang +Höchberg +Gonikoppal +Chavuttahalli +Trzebiatów +Chilpur +Ferros +Beaumont-sur-Oise +Kudayattūr +Manhattan +Agoué +Cavalcante +’Aïn Kihal +Soanpeta +Jacinto City +Leers +Majali +Wiang Sa +Sūlibele +Casaluce +Grimmen +Sarahs +Henderson +Lüchow +Aire-sur-la-Lys +Pāchhāpur +Banāso +Greenville +Valerik +Wielsbeke +Ratnahalli +Ekma +Puduppattanam +Cingoli +Southport +Bou Zemou +Shiyuan +Ramree +Rellivalasa +Tālavādi +Osterburg +Kensington +Buñol +Perumbālai +Pagidyāla +Avanāshipālaiyam +Lizzano +Bourg-de-Péage +Aytré +Vasiliká +New Square +Saint-Sulpice-la-Pointe +Nāgathān +Photharam +Lago Ranco +Schulzendorf +Gamharia +Bladensburg +Villa Aldama +Petrolina de Goiás +Ézanville +Cuervos +Fauske +Ban Wiang Ka Long +Parūr +Indianola +Sarmera +Jaisinghnagar +Cesa +Aiea +Sānampūdi +Bakaly +Gawān +Ittikelakunta +Mae Rim +Mizhhiria +Bolívar +Kochgāwān +Oulad Ayyad +Karczew +Miltenberg +Nandamūru +Topsham +McKee City +Bilozerka +Daulatpur +Girard +West Glens Falls +Roanoke +Sitebe +Erdőkertes +Parsons +Szubin +Maliaño +Savignano sul Panaro +Sorbolo +Borogani +Šurany +Baretha +LaSalle +Pérols +Chansolme +Kayyngdy +La Paz +Xiada +Adesar +Miānpur Dubauli +Koranampatti +Traversetolo +Lititz +Palankottai +Bisaria +Zymohiria +Paranacity +Semri +Dombarovskiy +Vareš +Parauli +Vīrapāndiyanpattanam +Rathdrum +Pine Castle +Lower Swatara +Basse-Goulaine +Dumra +Kamargani +Velyka Dymerka +Boxley +Vemulanarva +Wepener +Lincoln Village +Port Perry +Bad Gandersheim +Nāzira +Sevilla La Nueva +Kondaparti +Fontoura Xavier +Ekalbehri +Pleasant Grove +Sirsa +Vardhamānkota +Amherst +Teixeira Soares +Gobindpura +Dākpatthar +Kannūlu +Sāngi +Boulder Hill +Fitampito +Sālehpur +Arrapalli +Matawan +Igrim +Mahomet +Elizabethtown-Kitley +Harding +Ashukino +Cunday +Thīkri +Dabhaura +Naruār +Greenwood +Paso Canoas +Kadıköy +Rauco +Canoas +Berchha +Rāmasingavaram +Gangādhar +Bjärred +Chita +Lorgues +Lototla +Nieuw-Lekkerland +Dodarasinakere +Conselice +Ehringshausen +El Cacao +Capitán Mauricio José Troche +Chaplynka +Hohenhameln +Mīnākshipuram +Kanhai +Udburu +Listowel +Kakamas +Mezőberény +Khundāwandpur +Volterra +Bethel +Jinshui +Māmā Khēl +Newburn +Le Rheu +Navani +Ekhari +Khāspur +Maravilha +Wilkau-Haßlau +Colmenarejo +Jalkaura +Hillsborough +Bohemia +Chanal +Piedras Blancas +Barskoon +Menzel Kamel +Jianshi +Crosne +Kaikaram +Vatakemuri +Rāmpur Rajwa +Crystal Beach +Tounfafi +Pagqên +Pedra Badejo +Somvārpet +Yamakita +Falam +Santa Rosa del Peñón +Psychikó +Mallampalli +Xinpi +Meridianville +Tatoufet +Barwādih +Madhopur +Castel Bolognese +Tomah +Ankadimanga +Santa María +Środa Śląska +La Reina +Raun +Middletown +Mooresville +Lescar +Cuorgnè +Esopus +Atāri +Burayevo +Sebnitz +Tadworth +Zawyat Sidi Ben Hamdoun +Eurajoki +Mānbāzār +Valaiyāmpattu +Pahārpur +Bargersville +Águia Branca +Fairview +Cape Elizabeth +Puigcerdá +Madhura +Steger +Tlahualilo de Zaragoza +Basco +Shevington +Smiths Falls +Soldato-Aleksandrovskoye +Worsborough +Castelfranco di Sopra +Seybaplaya +Sztum +Janāpul +Ādivāla +Bni Gmil +Salcea +Byureghavan +Sendamangalam +Ban Nong Tong +Săbăoani +Kalladai +Grinnell +Oosterwolde +Sikandarpur +Manchenahalli +Rāmpur Parhat +Höhr-Grenzhausen +Nagyatád +Khagam +Vəndam +London Colney +Trovagunta +Amityville +Elhovo +Vaprio d’Adda +Bougou +Kujri +Ānjukulippatti +Aleksandrovsk-Sakhalinskiy +Garlasco +Wagner +Dhāntola +Arenápolis +Hickam Housing +Lorraine +Douar Messassa +Mūḩ Ḩasan +Sonsoro +Luckau +San Sebastián de la Gomera +Bisignano +Ngaparou +Tambura +Bulisa +Jingjiazhuang +Bāgor +Nathāna +Rānigaon +Mangrāwān +Louisville +Iowa Colony +Dagbé +Großhansdorf +South Abington +Fochville +Gaada +Muddāda +Ilāmi +Devmaudaldal +Oakwood +Əliabad +Pedro Luro +Saldus +Sokotindji +Tixter +Bāghduma +Kanchanadit +Emsworth +Kaithwār +Valtoha +Saltsjöbaden +Madhuban Bediban +Néa Artáki +Karath +Mehdīpur +Åstorp +Ramara +Ivangorod +Maizal +Llantwit Major +Nārāyanraopet +Carácuaro +Hesarghatta +Malaudh +Berlin +Rudnya +Katigang +Nadimpālem +Luçon +Deh-e Shū +Ekchāri +Virālimalai +Nova Veneza +Tamentit +Tepperumālnallūr +Durgi +Saūmalköl +Pryor Creek +Corella +Cherniakhiv +The Village +Periya Pattanam +Columbia City +Zhangping +Ilsenburg +Quincy-sous-Sénart +Gūdalūr +Bimun +Molagavalli +Santa María Jacatepec +Highfields +Senmanat +Léguevin +Fairfield +Foix +Musāpur +Malaimāchchampatti +Isrāna +Ban Krot +Sundarsi +Notre-Dame-des-Prairies +Puszczykowo +Wertingen +Bewdley +Anan’evo +Helena-West Helena +Berkine +Molbergen +Cervelló +Elūrpatti +Asahni +Vallet +Kemberg +Rafelbuñol +Marne +Alāwalpur +Salem +Woodfield +Casca +Töging am Inn +Cherasco +Leeds and the Thousand Islands +Dényékoro +Nehoiu +Uppūr +Koufália +Halen +Quixabeira +Inole +Bridge City +Brockton +Costeşti +Syurte +Nyzhnohirskyi +Cambira +Saint-Barthélemy-d’Anjou +Saint-Amand-Montrond +Gangāpur +Sultan-Yangiyurt +Legnaro +Runkel +Hohenmölsen +Frouzins +Tabernes Blanques +Mareno di Piave +El Amim +Burela de Cabo +Ban Sathan +Cervera +Gold +Clarksville +Kranídi +Kerap +Shahrak-e Ja‘farīyeh +Dolianova +Winchester +Laurentian Valley +Nittenau +Idumbāvanam +Bijeraghogarh +Nārsingi +Shira +Güney +Khāwad +Erikolam +Kadanādu +Ćićevac +Negrine +South Normanton +Killamarsh +Tissaf +Kommūru +Gonghaur +Novi Banovci +Dachengzicun +Wau +Aksay +Jisrayn +Deruta +Tavarede +Raitar +Monnickendam +Jantho +Eunice +Rorschach +Tarmount +Dhānga +Kankanālapalle +Adolfo Gonzáles Chaves +Cosne sur Loire +Bezliudivka +Pipra +Alma +Assi-Ben Okba +Anaconda +Tissint +Ban Bang Phlap +Villacañas +Dānesfahān +Borovskoy +Banikane +San Juanito de Escobedo +Villa Cañás +Wiener Neudorf +Chewara +Elne +Yutsa +Olivares +Harlākhi +Rāsol +Ghosrāwān +Saidoke +Huinca Renancó +Braslaw +Medleri +Madeira +Ban San Pong +Abra Pampa +Segorbe +Lerici +Dubrovytsya +Mohelnice +Khānpur Khairanti +Bairiyā +Hertzogville +Santa Monica +Odobeşti +Åhus +Soubakaniédougou +Sabiñánigo +Elūrupādu +Lugoff +Carneirinho +Teisendorf +Brockworth +Aurahi +Dibrāghani +Vadakēthara +Ghanīpur Bejha +Fishersville +Sidi El Hattab +Basni +Mono +Ipiranga do Piauí +Tocina +Būdalūr +Anjēhalli +Naurhiya +Andergrove +Embrach +Radstock +Sādiqpur Maraul +Bendarhalli +Simarbani +Sivamalai +Glenshaw +Estrêla d’Oeste +Carqueiranne +Rochelle +San Francisco Libre +An Châu +Jawāsa +Bobil +Sarpamāri +Nirna +Barga +Coral Hills +Bystrzyca Kłodzka +Iāwar +Kharī +Cavriglia +Aschheim +Arenys de Munt +Halachó +Ngọc Sơn +Sa Pa +Muhammadganj +Dharir +Ostróda +Dunblane +Kallayi +Mohanpur +Gümüşova +Benbutucun +Kurort Steinbach-Hallenberg +Orivesi +San Giovanni in Marignano +Anísio de Abreu +Kovilpatti +Siano +Bellinzago Novarese +Chahār Borj-e Qadīm +Elmas +Aniva +Flossmoor +San Juan Bautista +Hani i Elezit +Voitsberg +Danau Kändimarg +Ramdeora +Mechanicsburg +Cusseta +Altdorf +Ponneri +Mutis +Thames Ditton +Hayle +Newmarket +Rāmkali +Recco +Woodway +Dushanovë +Pettāmpālaiyam +Krasnoslobodsk +Devarāpalle +Uppalaguptam +Piombino Dese +Kapelle-op-den-Bos +Makamba +Condé-sur-l’Escaut +Pokotylivka +Negrete +Singhāna +Taisar +Hazrat Shiura +Denham Springs +Manchester +Hsenwi +Novopskov +Resana +Magnago +Cetraro +Sint Willebrord +Capriolo +Gammasa +Tazarka +Saint-Philbert-de-Grand-Lieu +Köse +Närpes +Jamunāmukh +Vempatti +Ja‘farīyeh +Oakville +Mhâjâr +Magny-les-Hameaux +Ukwā +Gaurdah +Cutro +Verkhneyarkeyevo +Horsell +Florence +Middlesborough +Ashland +Kungsängen +Kadimetla +Grigoriopol +Nepi +Curepto +Saint-Jean-le-Blanc +Raunds +Marvast +São Jorge d’Oeste +Nové Město nad Metují +Salzhemmendorf +Jhabrera +Sarakkayhalli +Cermenate +Kharagbani +Kākarāti +Acton +Dymka +Umbrete +San Giorgio di Piano +Rangāpuram +Jarville-la-Malgrange +Tirubhuvane +Helena Valley Southeast +Topoloveni +Le Passage +Broadwater +Pūmalakkundu +Bakhariā +Douar Oulad Bouziane +Pustomyty +Ichenhausen +Ukhāi Purbāri Patti +Maḑāyā +Sierning +Audenge +Zacualpan de Amilpas +Kargat +Pau Brasil +Mēga +Barjhar +Hamīra +Ecatzingo +Zorneding +Rehau +Werneuchen +Hathaura +Chhapera +Tivat +Locust Grove +Frankfort Square +Langnau +Petersberg +Tandarāmpattu +Baisuhalli +Barahpur +Lānghnaj +Shahr-e Majlesī +Eemnes +Punta Indio +Eisenberg +Tiruvāduturai +Muppālla +Burlington +Hastings +Opalenica +Sebastião Laranjeiras +Obernkirchen +Tadangam +Diamondhead +Maraial +Miajadas +Hattula +Molsheim +Mīrjāveh +Ubbergen +Wallerfangen +Tassera +Wilnecote +Southside +Ntchisi +Schlangen +Bāgchīni +Mahālgaon +Canal Winchester +Sutton +Bāyaram +Kirangūr +Awans +Lutterworth +Chinnāmpālaiyam +Ruffano +Warren +Adelsdorf +Aidlingen +Gorē +Ameskroud +Orlu +Savenay +Queensferry +Sherborne +Asudapuram +Igaratá +Aucamville +Chilmil +Kolkwitz +Siteía +Chiman +Oraviţa +Modra +Palhano +Schaafheim +Valréas +Qutubpur +East Stroudsburg +Suan +Barpathār +Kalaīkunda +Laanoussar +Harqalah +San Agustín de las Juntas +Santa Comba +Néa Moudaniá +Lādhuka +Yezhi +Nogent-le-Rotrou +Chandwārā +Bhogāpuram +Verkhneuralsk +Sankt Valentin +Pirpirituba +Wehrheim +Lançon-Provence +Doctor Arroyo +Parol +Barrington +Minano +Meadowbrook +Rum +Tonneins +Nattakkādaiyūr +Kātūria +Takkali +South Amboy +Torrinha +Água Branca +Mallappādi +Santa Teresa di Riva +Crestline +Charter Oak +Blachownia +Ban Khi Lek +Macomer +Rodeo +Zwenkau +St. Anthony +Havre +Tres Ríos +Ouistreham +Kesli +Manteswar +Nūlivedu +Sainte-Julienne +Heiligenhafen +Sheffield +Chinnakkavundanūr +Jāffar Khānpet +Boddikūrapādu +Dowlatābād +Harpur +Tarawān +Pelāgor +Nort-sur-Erdre +Moore +Studénka +Samdrup Jongkhar +Bruchhausen-Vilsen +Irthlingborough +Sujāpur +Vanzago +Gatteo +Concepcion +Chupinguaia +L’Isle-Jourdain +Sosale +Kaleybar +Zafferana Etnea +Fort Stewart +Lubuagan +Pesca +Hagondange +Borna +Hasanpura +Nāgāyalanka +Kopong +Lac des Oiseaux +Unāo +Telkathu +Kalvārpatti +Oued Essalem +Maihma Sarja +Jahāngīrpur Sālkhani +Bull Mountain +Moisei +Peixe +Baisa +Angola +Santa María de Cayón +Laghzawna +Adaklı +Ehningen +Timmāpuram +Boali +Shanhūr +San Pablo Huixtepec +Imielin +Rudraprayāg +Jānpur +Moḩammad Yār +Riverdale +Monserrat +Redon +Chiankī +Bang Khla +Rosario +Ouled Rached +Ralla +Pangunattam +Altınyayla +Dornstadt +Quakertown +East Franklin +Nor Hachn +Torgelow +Rupahi +Choix +Quirino +Sədərək +Pfedelbach +Shimizu +Saint-Jean-d’Illac +Hualañe +Patchūr +Mariyādau +Khajuri +Satravāda +Qualicum Beach +Nieuwleusen +Chechen-Aul +San José Guayabal +Frodsham +Polegate +Pasrāha +Plymouth +Ilvesheim +Drākshārāma +Livron-sur-Drôme +Fársala +Urangānpatti +Gadzhiyevo +Mumaradikop +Barros Cassal +Honganur +Porto de Pedras +Rosário do Catete +Le Crès +Isua +Bo‘z +Magdalena +Shendē +Kanajanahalli +Khandāich +Ikeda +Ecorse +Skidaway Island +Newfane +Malahide +Titu +Poienile de sub Munte +Perwez +Modavāndisatyamangalam +Kharahara +Gassino Torinese +Kißlegg +Ledbury +Síndos +Kruszwica +Juprelle +Tecklenburg +La Jigua +Dahi +Mīlājerd +St. Francis +Tysmenytsia +Betania +Asārhi +Bernalillo +Jandaíra +Marano Vicentino +Ventnor City +Bad Liebenwerda +Lagunia Raghukanth +Kollankulam +Mabeskraal +Analaroa +Kunnattūr +Uppalapādu +Ban Bo Phlap +San Pancrazio Salentino +Jackson +Bethalto +Frickenhausen +Bagnara Calabra +Moldova Nouă +Nakhon Thai +Herculândia +Chicholi +Punta del Este +Pozo Almonte +Laurens +Elsenfeld +Catral +Majhariyā +Bhachhi +Āltūn Kawbrī +Nakoushi +Thakurainia +Almagro +Coleford +Charlotte +Leonia +Mascota +Skwierzyna +Abūz̄ar-e Ghaffārī +Gaggiano +Nakao +Mound +Crigglestone +Teplohirsk +Ānandpur +Gainrha +Goldach +Clermont-l’Hérault +Deokali +Joghtāy +Washington +Rājapūdi +Punnaikkāyal +Wasilla +Güneysınır +Oppicherla +Merrill +Freystadt +Pāppampatti +Tlahuiltepa +Niederhasli +Macedon +Padinska Skela +Didymóteicho +Alukkuli +Chilakhāna +Khotyn +Walworth +Ochsenhausen +Piru +Rāmpur +Douar Oulad Sidi Moussa +Aïn el Hadjar +Launaguet +Sidi Lahsene +Rîşcani +Barei +Rinópolis +Piamonte +Weißenthurm +Edelény +Itiki +Barnāon +Picture Rocks +Aljustrel +Fairfield Glade +Pokrovsk +Sucre +Bojacá +Pedda Tumbalam +Las Tablas +Velykyi Bychkiv +Bridgeport +Risaralda +Bures-sur-Yvette +Lansdowne +Granada +Borgholzhausen +Muro del Alcoy +Escaudain +Augusta +San Pedro Nonualco +Gomaringen +Towcester +Pasian di Prato +Rensselaer +Sugar Grove +Kudelstaart +Keuruu +Ganāram +Algūn +Samalpur +Douar Ezzerarda +Schübelbach +Niesky +San José La Arada +Gandikunta +Vittuone +Manzanares el Real +Bendapūdi +Katteragandla +Sītānagaram +Ban Son Loi +Ratangarh +Mātar +Magalia +Haiku-Pauwela +Diouna +Ħamrun +Capilla del Señor +Benahavís +Southwick +Zavyalovo +Nizhniye Sergi +Smoline +Wunsiedel +Fallon +Otumba +Mels +Ahmadpur +Harbatpur +Loria +Lesquin +Chunakhali +Montescaglioso +Talata-Angavo +Chala +Reshetylivka +Mādhopur +Fatao +Paray-le-Monial +Belley +Barleben +Rain +Iarpur +Raipur Buzurg +Kawai +Hailey +Oulad Cherif +Bandio +Romang +Tanakoub +Santa Isabel Cholula +Gooik +Zoubiria +Māmidipalli +Aranya Kalān +Nūtakki +Tanamarina-Sakay +Momchilgrad +Mirante da Serra +Tasso +Jūraqān +Kahla +Nossa Senhora Aparecida +Dielheim +Sandalpur +Bahābād +Rethen +Giardini +Neuenkirchen +Stevenston +Karsaut +Vallapuram +Ryki +Brugnera +Philippeville +Carrillos +La Victoria de Acentejo +Bowdon +Kondrukota +Vaikuntam +Castelleone +Keşap +San Lorenzo de Descardazar +Kaujalgi +Lesnoy Gorodok +Hlyboka +La Bruyère +São Domingos +Fazendinha +I-n-Amenas +Riverside +Aslanapa +Kalanchak +Baía da Traição +Kondayampālaiyam +Tišnov +Jājireddigūdem +White Meadow Lake +Oromocto +Borja +Clay Cross +Bude +Shannon +Gudimūlakhandrika +Bad Laer +Baluntaicun +Gandhwāni +Vallahbhāpuram +Badagabettu +Gangaura Behra +Washington Terrace +Japaratinga +Antônio Dias +Mejillones +Joigny +Inverigo +Mikhaylovskoye +Badnor +Nonea +Saraunja +Kandiyankovil +Ottappārai +Swāmimalai +Évian-les-Bains +Totnes +Mount Pleasant +Melgaço +Babadag +Nong Kung Si +Ghattupal +Sholaqqorghan +Altenbeken +Kandel +Kharika +Kodakkal +Castrolibero +Qarqaraly +Shawano +Cape St. Claire +Kannavam +Pong Nam Ron +Pudukkottai +Ban Kham Pom +Pohrebyshche +Jambukuttaippatti +Chokkalingapuram +Bādanahatti +Covasna +Aniskino +Llagostera +Sūrak +Waseca +Dhāmnod +O'Hara +Gnarrenburg +Golbāf +Palm Beach +Falan +Elsfleth +Arlesheim +Mont-Saint-Martin +Cullercoats +Vadavālam +Irungalūr +Xalqobod +Qorovulbozor +Mudhol +Gothurutha +Rāmāyipatti +Araújos +Saßnitz +Laheji +Freetown +Paredes de Coura +Tiana +Spáta +Aliquippa +San Fausto de Campcentellas +Bīkē +Dāmargidda +Panthersville +Une +Jamhra +Susāri +Valkurti +La Cruz +Kodigenahalli +Blackstone +Whitecourt +San Lorenzo +Nowra +Tenedla +Leichi +Landivisiau +Ban Chang Phuak +Muli +Vignate +Çobanlar +Støvring +Shirguppi +Chalkāri +Jogaili +Māmidipalli +As Sidrah +Podstepki +Tibaná +Tepe-Korgon +Richmond Heights +Santa María Ajoloapan +Capbreton +Tilehurst +Chikkāla +Sewa +Aberbargoed +Olds +Suwannaphum +Jagannādapuram +Himmatpura +Rājepur +Sukkāmpatti +Roux +Canela Baja +Cistérniga +Tiptree +Conshohocken +Salisbury +Sidi Bou Othmane +Hirehalli +Maidencreek +Guntramsdorf +Harpur Bhindi +Vega Alta +Cêrro Grande +Alsbach-Hähnlein +Douar El Mellaliyine +Arceburgo +Galten +Mādepalli +Nelali +Ḩorr-e Rīāḩī +Grants +Ahuimanu +Willowbrook +Elze +Hacine +Yatton +Budhma +Nashtīfān +Obukhivka +Itapebi +Yaxley +Ivins +Rockingham +Maków Mazowiecki +Murfatlar +Tuskegee +Binisalem +Onchan +Gūdalūr +Waiuku +Ban Wat Chan +Jerez de los Caballeros +Solsona +Sarkad +Ban Yaeng +Trittau +Biblis +Dörverden +Marale +Bangaon +Matelica +Verdejante +Xiangping +Ville-la-Grand +Woodbury +Littleport +Monte Rico +Boekenhouthoek +Foammulah +Pencoed +West Manheim +Wa +Dommasandra +Waterford +Corumbaíba +Waldfeucht +Micco +Flanders +Irshava +Yvoir +Abalessa +Incline Village +Springs +Žabalj +Gədəbəy +Palomares del Río +Reggiolo +Beauraing +Ifigha +Op +Ussel +Banbhāg +Bariariya Tola Rājpur +Entre Ijuís +Beauchamp +Halgeri +Santo Domingo Petapa +Gualaquiza +San Fructuoso de Bagés +Sungal +Pilikōdu +Wysokie Mazowieckie +Yeşilyurt +Fateh Nangal +Mikhaylovka +Zörbig +Županja +Imotski +Piripá +Grünheide +Kyritz +Morubāgalu +Anjūr +Nārāyanpur +Cachoeira dos Índios +Vallendar +Belakvādi +Ražanj +Buenópolis +Chinnāyagūdem +Felino +Lavis +Al Bardīyah +Sângeorgiu de Mureş +Sabie +Gondizalves +Ust’-Nera +Kondūru +Sansa +Veinticinco de Diciembre +Mangasamudram +Bichura +Sauzal +Brandon +Maserada sul Piave +Japurá +Chesterfield +Santa Lucia di Piave +Kaithāhi +Bir Tam Tam +Dāmu +Sibkund +Nerinjippettai +Seven Corners +Audubon +Helotes +Des Peres +Cajvana +Chadan +Caluco +Solita +Oakland +Copceac +Lagbé +Pleternica +Dihri +Bhargaon +Forestdale +Huron East +Stryzhavka +Delta +Bilenke +Laufenburg (Baden) +Pepillo Salcedo +Guano +Gavirate +Ipuiúna +Smithville +Tecoh +Ban Wang Krachae +Nagykálló +Tafersit +Ciudad Insurgentes +Cajobi +Mālingaon +North Codorus +West Athens +Dazhuangzi +Haddington +Yenmangandla +Govindapalle +Malalbergo +Perkasie +Mwaline al Oued +Lanta +Bāsudebpur +Mokri +Mendig +Jandola +San Manuel Chaparrón +Maserà di Padova +Elsmere +Denekamp +Montoro +Umburetama +Crawford +Marlboro Village +Amatlán de los Reyes +Hostivice +Shanklin +Middlebury +Chtiba +Peresecina +Olesno +Raipur +Chitrāda +Nandiyālam +Currumbin +Rothrist +Guatapé +Tettu +Temperance +Sunset Hills +Piranguinho +Palocabildo +Groenlo +Dodji-Bata +Bamaiya Harlāl +Killimangalam +Bad Schussenried +Kongnolli +East Grand Forks +Hurzuf +Alawandi +Kaglipur +Koheda +Dospat +San Jorge +San Jorge +Sauce +Phagu +Sihāli Jāgīr +Eshkanān +Miramar Beach +Tiburon +Kudūru +Istrana +Horodenka +Mata Verde +Nechmeya +Dumri +Pattīswaram +Stillwater +Tunari +Zeydābād +Fujisawachō-niinuma +Nizhniy Odes +Montes Altos +Beuvry +Hawthorn Woods +Zarbdor Shaharchasi +André Fernandes +Reinfeld +Miryal +Odayārpatti +Herenthout +Carmen de Carupa +Chotěboř +Prabhāt Pattan +Fairless Hills +Flemington +Brejolândia +Loeches +Uchti +Satghara +Dallas +Weare +Embalse +San Zenón +Tekpanja +Steynsrus +Rebordosa +Govindāpuram +Kod +Cresskill +Kottapālem +McFarland +Westampton +Chaukhata +Belek +Datian +Rutland +Oborniki Śląskie +Tarusa +Cameron +Benton Harbor +Iguidiy +Hirske +Katakwi +Nalbach +Usworth +Gok +Orosi +Kharovsk +Ouédémè +Consacá +Rivesaltes +Guryongpo +Rada Tilly +Rincão +Park Ridge +McCordsville +Rondon +Ambara +Springfield +Navoloki +Tineo +Urbach +Coatetelco +Fehrbellin +Pithiviers +Sogām +Zeerust +Kenār +Riverside +Bonnievale +La Matanza de Acentejo +Dāvulūru +Nagaoki +Bemarivo +Logatec +Campamento +Calamar +Suances +Chillicothe +Greytown +Ouarégou +Portlethen +Kiskunlacháza +Koila Belwā +Yeldūrti +Huntertown +Marinka +August +Mendon +Dasaut +Umreth +Hokur Badasgom +Haripura +Sidi Ouassay +Paraparaumu Beach +Lynwood +New Scotland +Kożuchów +Bimāwān +Absecon +Olalapādi +Mauji +Yui +Beecher +Gtarna +Majhaulia +Periyamuttūr +Little Falls +Hussepur +Dāita +Midland +Velampatti +Hooper +Vinsady +Brejão +Bāgeshwar +Andiyappanūr +Commerce +Dinnington +Mirzānagar +Banārūyeh +Kanasānapalle +Gurmia +Carignano +Newark +Cedar Hills +Ban Tha Phra +Mainaschaff +Jāmunia +Karayılan +Mendicino +Jumlā +Großbeeren +Pontardulais +Suganwān +Fiumefreddo di Sicilia +Notodden +Kirchberg +Mosciano Sant’Angelo +Sinaia +Sibilia +Pedda Muppāram +Marāi Kalān +Mbuzini +Sergiyevsk +Luís Gomes +Hagaranahalli +Townsend +Fatehpur Bāla +Valley Cottage +Nykøbing Mors +Viravāda +Gidha +Ghāt Borūl +Ālampur +Vinhais +Carregado +Paulo Lopes +Morada Nova de Minas +Auerbach +Chalástra +Chāndpur +Åmål +Pūttai +Orte +Kawara +Berndorf +Adjido +Íquira +Magny-le-Hongre +Venkatādripālem +Oggiono +Economy +Ewo +Campobello di Licata +Sarauni +Wollert +Saraiya +Uppugunduru +Strehaia +Scionzier +Harrodsburg +Country Club Estates +Roxborough Park +Tāla +Lacchiarella +Toccoa +Northwest Harborcreek +Chaponost +São Francisco +Januário Cicco +Udarband +Ayanikkād +Salto Grande +Bonhill +Lanark +Kegen +Bemiss +Colac +Intich’o +Mohon +Mānoke +Poiana Mare +La Florida +Mamnūr +Borgosatollo +Orange Park +Abū Khashab +Khāsbalanda +Livno +Zwiesel +Baniré Koré +Berching +Bolokhovo +Harahan +Andilana Avaratra +La Ravoire +Janhapāra +Fossombrone +Breckerfeld +Rye +Podenzano +San Sebastián +Sanger +Ban Ngio Ngam +Santa Sylvina +Leven +Warkan +Dadrewa +Old Orchard Beach +Verkhnyaya Tura +Chārakunda +Monteroni d’Arbia +Iijima +Méridiala +Travis Ranch +Bérégadougou +Aadorf +Tājpur +Villa Castelli +Nová Paka +Bockhorn +Breinigsville +Ādamī Tulu +Gohi Bishunpur +Lapeer +Waldheim +Ksar Belezma +North Merritt Island +Çayırlı +Westerland +Doberlug-Kirchhain +Furth im Wald +Highland Park +Bougival +Les Sorinières +Porto Tolle +Dunbar +Nanzhuang +Dharampur +Monticello Conte Otto +Tuscumbia +Velyki Luchky +Nhân Trạch +Kurichedu +Kannāl +Katsuyama +Booneville +Pullach im Isartal +Hemmoor +Pivnichne +Sint-Martens-Lennik +Rāmpur Khajuriyā +Douglas +Ampasimpotsy-Gara +Ceelbuur +Coqueiral +Manatuto +Barwell +Sāhāpur +Westwood +Odžaci +Zalishchyky +Beckwith +Arico el Nuevo +Blairgowrie +Cupar +Nādol +Bala Cynwyd +Muhos +Tomblaine +Kaniwāra +Māli +Foiano della Chiana +Gretna +Moman Barodiya +Hampstead +Neustadt +San Francisco +Ban Wang Pradu +Karlıova +San Ignacio +Mandīshah +Bābai Kalān +Aplao +Estanzuelas +Coronel Du Graty +Lakhna +Dhauni +Madhurāpur +Bāsdeopur +Hatti Mattūr +Nārsingi +Akat Amnuai +Treia +Craig +Kaeng Khro +Mburucuyá +Hārua +Gerstungen +Labrador City +Argudan +Brand-Erbisdorf +Morānha +Blacklick Estates +Derby +Kasane +Caxias +Rio del Mar +Burgos +Tutrakan +Mishrikot +Perondi +Seneca Falls +Rafard +Furtwangen im Schwarzwald +Le Teich +Venturina +Lunner +Tha Luang +Chanco +Chanco +Kambaneri Pudukkudi +Crvenka +Mādhavaram +Lago Vista +Aïn el Mediour +Chiţcani +Maropaika +Morafeno +Soamahamanina +Ambodivoanio +Tsimafana +Sahatsiho-Ambohimanjaka +Ranopiso +Ivandrika +Marotolana +Ambatoria +Lanivo +Sarasambo +Antambohobe +Ambalajia +Nato +Mahamaibe +Mitanty +Salobe +Ambariokorano +Vohilava +Vatananto +Iara +Ampary +Ambalaromba +Ambatoharanana +Befotaka +Soamanonga +Bemaharivo +Anteza +Bekopaka +Antaly +Anjialava +Ankarana-Miraihina +Tsaratanana +Antsaidoha-Bebao +Nosibe +Soanierana +Ambatolahy +Soanenga +Mahabo +Manampaneva +Manja +Ambinanin’ Andravory +Belinta +Marovatolena +Morarano +Antsahavaribe +Antseza +Andribavontsona +Ankiliabo +Antanankambano +Alakamisy-Ambohimahazo +Benato-Toby +Ankirihitra +Antsatramidola +Amboronabo +Manevy +Beparasy +Tandrano +Fierenana +Ambarimaninga +Ambodimahabibo +’s-Gravendeel +Dhībān +Dahbed +Qahramon +Lo Miranda +Bovingdon +Diabugu +Jangalapalli +Urpāar +Lohara +Rohera +Ugamedi +Tikar +Gisborne +Carneiros +Marcação +Puerto Octay +Patūt +Hetanpur +Kalicherla +Rarz +San Pedro Atocpan +Turín +Mbamba Bay +Neuötting +Dholbāja +Novyi Svit +Zschopau +Almusafes +Hirehāluhosahalli +Lake Park +Glens Falls North +Guichen +Rājod +Olney +Pomichna +Panasapādu +Druento +Yelnya +Lamorlaye +Settivāripalle +Peddannavāripalle +Ixtapa Zihuatanejo +Podu Iloaiei +Perl +Veauche +Harleysville +Säffle +Icaraíma +Devanāngurichchi +Gacko +Kāndra +Rice Lake +Had Dra +Apahida +Kozova +Iscuandé +Gudlūru +Chundale +Shelburne +Ardooie +Togou +Dulce Nombre de María +Santana do Manhuaçu +Wenzenbach +Kanchanpalli +East Nottingham +Foum Zguid +Urdinarrain +Bassenge +Denbigh +Hirayama +Kosum Phisai +Arboledas +Telaprolu +Yarmouth +Almargem +Tiou +Seydunganallūr +Chilón +Kirs +Puerto Lleras +Hilzingen +Khiriāwān +Pulaski +Yapraklı +Brooksville +Lopatcong +Stanley +San Francisco Ixhuatan +Acobamba +Kattamūru +Bayabas +Akpassi +Hosūru +Sanganakallu +Pulimākkal +Taber +Huasco +Sarzeau +Pedda Pendyāla +Higuera de Zaragoza +Leisure World +Uspenka +Linares +Ponnāda +Bhirua +Barwān +Grabels +Iseo +Saline +Tepechitlán +Dzhalka +Pena Forte +Yekāmbarakuppam +Fitzgerald +Evergreen +Lerma +Thung Sai +Roztoky +Talevad +Mahamda +Pararia +Tulbagh +Valea lui Mihai +Ianca +Vrhnika +Borgoricco +Kelso +Miradouro +Lolokhur +Perkiomen +Al Yādūdah +Neuried +Fort Irwin +Tzitzio +Saint Sampson +Kharsāwān +Siachoque +Cloverdale +Plainedge +Ortenberg +Cheste +Mudgere +Park Forest Village +Aver-o-Mar +Gonfreville-l’Orcher +Grenade +Tovāla +Fredensborg +Sileby +Segni +Nuquí +Ūnagatla +Sheffield Lake +Sarenja +Gāzulapalle +Oak Grove +Hlobyne +Rio das Flores +Wangdue Phodrang +Villamediana de Iregua +Sānchi +San Francisco Chimalpa +Borskoye +Fuldabrück +Zacháro +Bayyavaram +Kusmaul +Tvrdošín +Velden am Wörthersee +Yaguará +Noventa Vicentina +Bazimini +Donnacona +Sucha Beskidzka +Emirgazi +Mnichovo Hradiště +Karadge +Phulhara +Vanavāsi +Groß Kreutz +Ouled Rahou +Sambhu Chak +Bawāna +Aviano +Villa Aberastain +Angelópolis +Ben Chicao +Cébazat +Bāba Bakāla +Bloomingdale +Natuba +Bhelsi +Jasauli Patti +Dalavāypattanam +West Donegal +Haledon +Attnang-Puchheim +Séné +Rāmnagar +Indian Harbour Beach +Czarna Białostocka +Yasenivskyi +Açucena +Chitvel +Winslow +Nanmucun +Ferryhill +Munagāla +Harwood Heights +Colméia +Tena +Plön +Corgao +Bikkatti +Esanai +Mālior +Kotabommāli +Yellanda +Colorno +Peebles +Broughton Astley +Bogota +Almoloya del Río +Viale +Tshabong +Bad Lauchstädt +Borio +Nawāda +Rāmgarha +Belma +Juncos +Montagnana +Ban Nikhom Phatthana +Caputira +Sampgaon +Kafr Sajnah +Khagaur +Ladue +Beaver Falls +Chinna Kalaiyamputtūr +Bestensee +Glastonbury +Monteforte d’Alpone +Thap Than +Seddouk Oufella +Guttikonda +Qashyr +Bni Sidel +La Junta +West Caln +Hürtgenwald +Nunchía +Purcellville +Edgewater +Zhur +Neuhaus am Rennweg +Shahr-e Pīr +Florø +Monastyryshche +Horokhiv +Monistrol-sur-Loire +Kovvali +Gouvieux +Balvādi +Castelnuovo Berardenga +Vila Nova de Cerveira +Sai Ngam +Cholavaram +Kara-Bak +Thị Trấn Đồng Đăng +Libonik +Morières-lès-Avignon +Edgewater Park +Mikhaylovsk +Rāmapattanam +Hope +Chirongui +Zawyat Sidi al Mekki +Suoyarvi +Terra Nova +Eslohe +Mangalpur Gudaria +Nānguneri +Māldah +Somero +Khorāgāchhi +Upper Leacock +Village St. George +Santa María del Tule +Bayport +Fair Lakes +Filottrano +Kui Buri +Florida +Weilmünster +Barhagarh +Asolo +Penaballi +Kilānkundal +Sępólno Krajeńskie +Serafimovich +Redlands +Dashouping +Eceabat +Santa Isabel do Ivaí +Ingenbohl +Brownfield +Argelia +Dayr as Sanqūrīyah +Hernando +Polička +Dumri +Periyapōdu +Kodikkulam +Santa Cruz Atizapán +Osicala +Corman Park No. 344 +Virgínia +Felling +Great Cornard +Segarai +Litchfield Beach +Clinton +Almagro +Basāha +Channubanda +Plymouth +Topchikha +Helsinge +Ayas +Enkakād +Bhadwār +Nueva Guadalupe +Kulu +Devnya +Belvedere Marittimo +Makhambet +St. Pete Beach +Kratovo +Lakhanāpuram +Rock Falls +Palmeira d’Oeste +Árgos Orestikó +Potangal +Tullukuttināyakkanūr +Florstadt +Le Teil +Caister-on-Sea +Wanaka +Amuria +Yangiobod +Vadasīkarambattu +Karor +Sandpoint +Nangis +Orting +Pudozh +Le Portel +Caldwell +San José de Gracia +Ibirapuã +Punjai Lakkāpuram +Kishtwār +Maddūr +Matias Cardoso +Bösel +Wābāgai +Prienai +Crozet +Tepetitlan +San Marzano di San Giuseppe +Kanhauli +Oststeinbek +Sandiacre +Tummalacheruvu +Douar Ait Taleb +Zunilito +Whippany +Napoleon +Tiachiv +Ấp Tân Ngãi +Shoshong +Allāhpur +Barhauna +Tarcento +Tlumach +Holywell +Melpanaikkādu +Bīdkhūn +Ladan Kara +Chachersk +Francisco Caballero Álvarez +Metsemotlhaba +Partick +Belišće +Tharīke +Bargara +North Londonderry +L’Epiphanie +San Antonio +Ifield +Rewāhi +Mansfield +Rio Claro +Carmen de Apicalá +Sucre +Palangavāngudi +Halikko +Majhariyā Sheikh +Edgemere +Liteni +Oberriet +Kurichchi +Polakala +Pomona +Makaya +Gurmaila +Teruel +Hallstadt +Silleda +Alwa Tirunagari +Kulpsville +Zuchwil +Khem Karan Saray +Bālumāth +Nānan +Bhagatpur +Padakanti +Alvarado +Breuillet +Kharsod B +Mosrāh +Camenca +Hohenbrunn +Khandrauli +Thief River Falls +Imilchil +Bhatauliā +Āgadāllanka +Minerbio +Pearsall +Diamou +Tataltepec de Valdés +Quétigny +Ghorbanki +Unterägeri +La Fare-les-Oliviers +Irigny +Mallāram +Gangapatnam +Dāra +Iskourane +Msemrir +Hunduan +Rabo de Peixe +Papara +Schleiz +Kambūr +Golakpur +Chiranellūr +Cumberland Hill +Greenville +Ait Ikkou +Neya +Maipú +Aināpur +Katahra +Kanakpur +Teolo +Collingdale +West Perth +Ayapango +Yakakent +Yelsk +Ratanpur +Kusterdingen +Mannamangalam +Muriyād +Ponta do Sol +Tasso Fragoso +Kéllé +Sorisole +Al Abraq +Pullalacheruvu +Sirikonda +Jogiāra +Gondauli +Viagrande +Rocas de Santo Domingo +Striano +Yanchep +González +Woodmoor +Collier +Japurá +Le Thor +Kuvshinovo +Achacachi +Ak’ordat +Vannikkonendal +Reni +Pandino +Bellheim +El Valle +Bellerive-sur-Allier +Ilarionove +Amtala +Sulahpet +East York +Poteau +Gilgit +Kilchberg +Mandalavādi +Sakaddi +Australia +Bersenbrück +Keora +Kadiyadda +Khetko +Aït Ouaoumana +Hlevakha +Landquart +Golbey +Shankarpur +Agadir Melloul +Fontaine-lès-Dijon +Malangām +Aradeo +Moka +Ban Pong Tao +Jaimalpura +Karariyā +Rhymney +Tirumalaippatti +Sewāri +Kālkuni +Duvvūru +Nimmekal +Casorate Primo +Zoeterwoude +Şabanözü +Volkach +Bansang +Drazinda +Nellutla +Pallippatti +Coffeyville +Caturama +Madnūr +Andalusia +Chak Habib +Pā’īn Chāf +Highland Park +Naunhof +Dayton +Smižany +Ban Noen Kum Nueng +Ban Muang Kham +Vinjam +Psyzh +Sæby +Finestrat +Timmapuram +Madanāncheri +Machadodorp +El Realejo +Povarovo +Armazém +Ospina +Steinheim am Albuch +Seneca +Potengi +Pedrinhas +Urânia +Sānwas +Moslem Ebn-e ‘Aqīl +Signal Mountain +Campbellton +Al Buwayḑah +Bīrpur +Cortez +San Juan de la Costa +Dobříš +Maysville +Piriápolis +Qızılhacılı +Heek +Cumnock +Ablu +Tāmganj +Maria Enzersdorf +Kressbronn am Bodensee +Sanatoga +Dardilly +Hamsāvaram +Tirano +Kaï +Côn Đảo +Memmelsdorf +Gibsonville +Hucclecote +Montmeló +Mahāgaon +Reyes +Baía Formosa +Neuenhof +Satwār +Rāmgarh +Missaglia +Bouati Mahmoud +Sabáudia +Vert-Saint-Denis +Pleasant Hill +Trujillo +Jonnagiri +Chakla Waini +Kodavatipūdi +Sekimachi +Fort Valley +Amarzgane +Entrerríos +Toppenish +Summit +Baciu +Valasa +Kukraun +Carbondale +Ḩīsh +Bāsmanpur +Vadapalanji +Albinea +Adigoppula +Soresina +Mahela +Takua Pa +São Sebastião do Curral +Upper Makefield +Baramandougou +Yacimiento Río Turbio +Rangvāsa +Ban Si Don Chai +Oak Hills Place +San Martín de Valdeiglesias +Sarlat-la-Canéda +Mānsong +Takouta +Hoyo de Manzanares +Paramé +Bārun +Sorala +Jolfā +Porto Santo Stefano +Mokhotlong +Kampong Tunah Jambu +Boucau +Bolszewo +Mühlhausen +Chécy +Bainbridge +Ineu +Hünenberg +Mālipākar +Mousoulou +San Miguel +Lusca +Ala +Tagapul-an +Pitman +Soltsy +Rrëshen +Lovosice +Iklod +Dhobipet +Alvorada +Ranjal +Bernolákovo +Beni Hassane +Angor +Tausa +Obernburg am Main +Tillaivilāgam +Clayton +North Haledon +G‘ozg‘on +Dehri +Taragi +Veľké Kapušany +La Ferté-Bernard +Dunavarsány +Pittsgrove +London Grove +Ulstein +Cristuru Secuiesc +Rouvroy +Penugolanu +Vanduvāncheri +San Ignacio +Madhuban +Bommayapālaiyam +Uta +Santa María Xadani +Gopālpur +Maisaram +Ballenstedt +Gudibanda +Baikunthapur +Ntossoni +Strijen +Haţeg +Lichtervelde +Entraigues-sur-la-Sorgue +Puraini +Chīchkah +Abcoude +Gudivāda +Rautara +Engerwitzdorf +Lontra +Quéven +Jeannette +Bridgewater +Kukrahill +Falla +Nagykovácsi +Miyār +Hassi Berkane +Kryzhopil +Brimington +Varatanapalli +Gholia Kalān +Porcari +Treze Tílias +El Outaya +Karis +Khānāpur +Glencoe +Belozërsk +Tlagasana +Soeda +Toulou +Sowān +Madhubani +La Loggia +Ban Sai Yoi +Koekelare +Dharāwat +Schuylkill +Cofimvaba +Lienen +Costa Volpino +Sodankylä +Essey-lès-Nancy +Belsh +Chahana +Garsekurti +Bhāsaula Dānāpur +Boonton +Saidia +Cherry Hinton +Annan +Nueva Ocotepeque +Kampel +Waldenbuch +Bachchannapet +Yelandūr +Kūnimedu +Moe +Garching an der Alz +La Mujer +Bundehra +Barth +Monforte del Cid +Cinderford +Greenville +Cowley +Adiyakkamangalam +Komījān +Clanton +Néa Michanióna +Deodora +Bath +Alíartos +Somarasampettai +Kusumbe +Mahopac +Tiqqi +Pereiras +Efringen-Kirchen +Poisy +Gessate +Meadow Lakes +Amberomanga +Brevik +Luzzi +Presque Isle +Paratdiha +Bee Cave +Coaldale +Muturkha +Gorodoviki +Minyar +Cunupia +Vicentinópolis +Kirrāyach +Chartiers +Taşkent +Hirni +Chinna Mupparam +Boukhralfa +Srīrāmapuram +Hardiya +Aragona +Pizzo +Großenlüder +Amtala +Īdupugallu +Monmouth +Spring Valley Lake +Bertrix +Rāmpatti +Vidapanakallu +Āshtīān +Wesley Chapel +Marrupa +Zapatoca +Abirāmam +Ōtaki +Perry Heights +Mascoutah +Borgentreich +Cockermouth +Borgo a Buggiano +Galela +Zūlakallu +Pukkulam +Kibaya +Fully +Pa Mok +Ottobeuren +Saint-Paul-Trois-Châteaux +Rāni Sāwargaon +San Pedro de Coche +Riacho dos Machados +Hombrechtikon +Pacuarito +Vohburg an der Donau +Aulnoye-Aymeries +Crest +Hiramandalam +Windsor +Mariinskiy Posad +Dāmal +Būdamangalam +Stony Brook University +Natividade +Lachen +Angichettippālaiyam +Brighton +Habo +Daping +Banak +San Juan Ixcaquixtla +Lenox +Pasivedalajimma +Sremski Karlovci +Tilvalli +Buenavista +Sant’Angelo in Lizzola +Mozzate +Coccaglio +Shopokov +Bouhlou +Afumaţi +Sānrha +Castagneto Carducci +Civitella in Val di Chiana +Summit View +Marlborough +Rudewa +Sonsbeck +Roccastrada +Wervershoof +Tanudan +Stary Sącz +Lamarão +Jabera +Ranod +Franklin +Leopoldo de Bulhões +Kanavāypudūr +Rahta +Pararia +Höshööt +Koror +Uzundere +Biederitz +Notre-Dame-de-Gravenchon +Murillo +Porkhov +Teranikallu +Dhanauli +Nam Som +Río Jiménez +Wingles +Pullānvidudi +Vadakādu +Hoquiam +Corona de Tucson +Comendador Levy Gasparian +Périgny +Saint-Jean-de-Monts +Hakka +Pedda Nindrakolanu +Parabita +Doornkop +Lichana +Rudravaram +Hollymead +Krompachy +Sanjāt +Jackson +Queimada Nova +Hârşova +Meßkirch +Mālaimārpuram +Mirchpur +Aktepe +Wattwil +Bussy +Rauenberg +Moranbah +Igana +Bhui +Ekangar Sarai +Velakalnattam +Bharno +Ellicott +Gundumāl +Folignano +Karuveppampatti +Sātgāchia +Hostotipaquillo +Gremyachinsk +Bad Bergzabern +Löwenberg +Jalālkhera +Maiquinique +Herzberg +Majra +Obertraubling +Lillebonne +Nāgaiyampatti +Faro +San Juan de Arama +Càbras +Carlosama +Roetgen +Saint-Claude +Tsrār Sharīf +Pendekallu +Graham +Galmaarden +Nārona +Montalto di Castro +Port Jervis +Gendou +Stará Turá +Buved +Rāgampet +Pont-Rouge +Volchansk +Güneysu +Pillutla +Siġġiewi +Cutrofiano +Hualaihué +Junín +Vīrapalle +Wyoming +Aransas Pass +Onnaing +La Chapelle d’Armentières +Navappatti +South Londonderry +Ustrzyki Dolne +Punnappatti +Ponte Buggianese +Santanópolis +Margny-lès-Compiègne +Iaboutene +Akālgarh +Angallu +Barbana +Bommagondanahalli +Sarbīsheh +Inékar +Azīzpur Chānde +Tomeşti +Velaux +Uchen +Chanute +Talsi +Gigmoto +Al Quway‘īyah +Ouando +Bishunpur +Besozzo +Hamlin +Kolbuszowa +Perevoz +Califórnia +Sohta +Doiwāla +São José do Cerrito +Choceň +Gangājalghāti +Blanchard +Anthony +Summit Park +Nanzhangcheng +Dunn Loring +Tleta Taghramt +Paola +Gyümai +Bhānuvalli +Roccapiemonte +Champlain +Sidi el Mokhfi +Lázaro Cárdenas +San Sebastian +Janglot +Sidi Dahbi +Havsa +Aşağı Quşçu +Iles +Richterich +Lake Villa +Bududa +Jondor Shaharchasi +Tashir +Siklós +Sini +Freeport +Volodymyrets +Pardanjān +Ogden +Innsbrook +Zawiat Moulay Brahim +Koppunur +Vadacheri +Raia +Pulivalam +Flero +Caprino Veronese +Coaticook +Marcy +Phimai +Ortaköy +Simón Bolívar +Tonk Khurd +Gonzaga +Karadipāra +Roverbella +Audubon +Stăuceni +Pokhraira +Pāppākudi +Torre Boldone +Cullinan +Måløv +Nāttarasankottai +Indūrti +Solebury +Mirdoddi +Conthey +Wietze +Mrakovo +São Pedro do Ivaí +Ergoldsbach +Goworowo +Binfield +Dharhwa +Heusden +Heikendorf +Le Petit-Couronne +Gadaul +Katrīdih +Painkulam +Koshanam +Lequile +Uglegorsk +Limeira d’Oeste +Newstead +Stainz +Titz +Zanica +Aigues-Mortes +Azandarīān +Oxford +Duchcov +Monte Escobedo +Murājpur +Bāgalvād +Gobindpur +Savoy +Cheviot +Kaldsletta +Katueté +Tordesillas +Kambhampādu +Hillview +Pyālakurti +Kursaha +Brandizzo +Sangaree +Embrun +Çamlıyayla +Suttamalli +Rompicherla +Kottūr +Kalinagar +Pibrac +Tecumseh +Aratuípe +Marilândia do Sul +Tilarán +Chetma +Chākand +Guntapalli +Castellabate +Glodeni +Longvic +Teotitlán +River Road +Catuípe +Kilcock +Aberdeen +Briceño +Flieden +Roquevaire +Herseh Chhīna +Bhatkhori +Parasbani +Triuggio +Ter Apel +Al Qardāḩah +Marāveh Tappeh +Minto +Malhada de Pedras +Montlhéry +Atherstone +Olmsted Falls +Bryan +Chełmek +Nörten-Hardenberg +Coutras +Ōwani +Wharton +Heartland +Avabodji +Passo do Sertão +Altavilla Milicia +North Cornwall +Baxter +Meine +Domérat +Amiāwār +Fort Mitchell +Yang Talat +Jujhārpur +Mustafābād +Rodeiro +L’Île-Saint-Denis +Pathrāha +San Sebastiano al Vesuvio +Perryton +Lempdes +Ōhata +Hirson +Harīke +Benner +Gillitts +Kościelisko +Chintakommadinne +Barvynkove +Paula Cândido +Chyhyryn +Nagdah +Clarendon Hills +Abū Ḩardūb +Demirözü +Aars +Tumberi +Dilāwarpur +Karavan +Najrīj +Zabok +Belhatti +Ballina +Tirschenreuth +Fort Knox +Campos Lindos +Eduttavāynattam +Bikrampur Bānde +Park Hills +Ankatafa +Sokyriany +Chak Pahār +Village Green-Green Ridge +Highland Heights +Deutsch-Wagram +Adjarra +Untergruppenbach +Løgten +Onda +Bedum +Farob +Seosaeng +Le Loroux-Bottereau +Isbergues +Vodice +Salar +Lihue +Tudela de Duero +Thāthūpur +Vanukūru +Kottadindulu +Warrenton +Sint-Job-in-’t-Goor +Ḩalāwah +Ōuda-daitō +Gulf Hills +Timmendorfer Strand +La Libertad +Bishamagiri +Pa Sang +Redlynch +Artigues-près-Bordeaux +Dirusumarru +Serramazzoni +Dobele +Nansio +Nandnāwān +Bovalino Marina +Guntersville +Covington +Sollefteå +Saint-Chamas +Chamonix-Mont-Blanc +San Bartolomé Milpas Altas +Lint +Vergiate +Buckie +Sant’Agnello +Budenheim +Sobhāpur +Anykščiai +Rakitovo +Kāoni +Mahadipur +Lourosa +Niederwerrn +Nayāgaon +Bisaul +Panfilovka +La Pêche +’s-Heerenberg +Bouaiche +Chapel en le Frith +Pinjranwān +Digar +Maina +Beibu +Solotvyno +Zuera +Rangwāsa +Manteno +Wiang Haeng +Slateng Dua +Parsād +Maddūr +Tokatippa +Long Hill +Pantelhó +Corella +Ulātu +Gokhulāpur +Gubden +Belo Vale +Monte Alegre do Sul +Kīlakkurichchi +Kattirippulam +Rājhanpur +Cradock +Chop +Salinas +Le Poiré-sur-Vie +Sa‘īdī +East Donegal +Vyetka +Midalam +Khandauli +Shahrak-e Pārs +Smithfield +Sredets +Garešnica +Fort Riley +Ustyuzhna +Beutelsbach +Sande +Basrūr +Mannegudam +Chettiyapatti +Nierstein +Stansted Mountfitchet +Hakubachō +Hamilton +Ouro Verde +Canford Cliffs +Segaon +Martano +Mechanicstown +Ferreira do Zêzere +Tārazu +Panjampatti +Hathiākān +Trissino +Buda-Kashalyova +Rāiparthi +Hire Vadvatti +Soverato Marina +Kanchanpur +Moribila +Tibro +Māgam +Saidābād +Chānp +Petilia Policastro +Templeton +Arealva +Santa Cruz do Monte Castelo +Bremgarten +Mānpur +Pirojgarh +Verkhoturye +Whitwick +Piliscsaba +San Ignacio +Barntrup +Vostochnyy +Corbin +Ammanford +New Ross +Antargangi +Tombos +Aurisina +Kappeln +Kharod +Carneys Point +Oulad Khallouf +Oulad Khallouf +Teghra +Socorro +Laishevo +Achchampeta +Nariño +Karkkila +Khaur +Skowhegan +Amalou +Pasaul +Jainagar +Sīlaiyampatti +Kanavāypatti +Bientina +Mudichchur +Shyamnagar +Zaandijk +Nakaseke +Schwarzenbruck +Nefasīt +Chamba +Velim +Jagannāthpur +Kennedy +Citrus Hills +Ueckermünde +Hāta +Bad Rothenfelde +Mauléon +Seffner +Egg +Egg +La Belleza +Peralta +Bālakrishnanpatti +Serramanna +Aibonito +Sopot +Amingaon +Pariyāri +Kennett +Kozlovka +Koila +Vráble +Miyada +La Huerta +Żuromin +Dobrada +Haibach +Bryans Road +Lancaster +Monona +Quezalguaque +La Cruz +Kanyākulam +Āmudālapalle +Piliv +Rayón +Verkhniye Achaluki +Jalhay +Yellāreddi +Kennedale +Plabennec +Roussillon +Srīrangāpur +Merksplas +Anantasāgaram +San Lorenzo +Swissvale +Eden Isle +Gundūr +Bargaon +Adalar +Rava-Rus’ka +Pallappālaiyam +Mareeba +Viechtach +El Ghomri +Vinica +Ardatov +Vif +Tarxien +Lakhzazra +Gidan Idèr +Heroldsberg +Thorigné-Fouillard +Jagta +Othello +Gering +Kızılcaşar +Dékanmé +Monte Porzio Catone +Gonzales +Tamza +Tougouni +Yasinia +Moss Vale +Vícam Pueblo +Liubymivka +Nuevo Paysandú +Sinimbu +Ouled Abbes +Kalaun +Yalí +Waltham Cross +Trebisacce +Bandamūrlanka +El Espinal +Ahumada +Fällanden +Karpenísi +Kāliganj +Hosuru +Seyyedān +La Grande-Motte +Nunihāt +Hale Dyāmavvanahalli +Vīrapperumānallūr +Torre de Moncorvo +Štětí +Bucksburn +Nettādahalli +Rāni Sāgar +Masandra +Lālam +Lamesa +Reinosa +Janzé +Kirk of Shotts +Charuānwān +Shiddāpūr +Ban Ratchakrut +Babhangaon +Bundāla +Gamail +Lāndupdīh +Locogahoué +Biberist +Castelnuovo di Porto +Coahuitlán +Sèmèrè +Vaucresson +Obersiggenthal +Millis +Anjahamarina +Kamień Pomorski +Na Yung +Youghal +Dharmājigūdem +Castel Gandolfo +Oak Island +Navipet +Vicopisano +Shediac +Loenen +Bushtyno +Hořice +Pöytyä +Midutūru +San Pedro Ixtlahuaca +Verkhniy Mamon +Usiacurí +Sompting +Kings Grant +Reeuwijksebrug +Tanmpègré +Chāpalamadugu +Lambarkiyine +Ayotoxco de Guerrero +Nerubaiske +Pedreguer +Dāla +Raonta +Paloma Creek South +Dougoufé +Brembate +Merrydale +Gretz-Armainvilliers +Buba +Harewa +Lohna +Independence +Closter +Takiéta +Kodaimangalam +Yaragol +Modachchūr +Nerk’in Getashen +Ergué-Gabéric +East Leake +Sakhua +Nesārg +Vairichettipālaiyam +Nūlvi +Arab +Conewago +Ad Darbāsīyah +Staufenberg +Sukand +Troina +Monte San Savino +San Fernando +Dachne +Fürstenfeld +Colindres +Pattanam +Iwaizumi +Dunn +Muzo +Tādināda +Tifra +Pāta Uppāl +West Long Branch +Barton +Ḩadībū +Imsida +Pochinok +Pásztó +Yamkanmardi +Novoselitskoye +Dubovskoye +Wissen +Siegsdorf +Aqsū +Milton +Bad Endorf +Mücheln +Glenwood +Lipki +Privas +Reddiyapatti +Kolumalapalle +Arizona City +Karmaskaly +Taftanāz +Bacobampo +Alfonso Castañeda +Santiponce +Zogno +Bifeng +Ağlasun +Kandern +Tsallagundla +Puran Bigha +Kandanāti +Clusone +Ortuella +Talwandi Chaudhriān +Nāngal Chaudhri +Perryville +Chak Thathi +Tālakulam +Guria +Folsom +Ban Charoen Mueang +Meltham +York +Ban Wat Phrik +Marcolândia +Rottenburg an der Laaber +Karuppūr +Bartica +Dattapāra +Hernani +Sulakyurt +Mangala +Bānki +Poninguinim +Bushkill +Chamusca +Worplesdon +Montecito +Keregodu +Hongtuliang +Khajuri +Montague +Sečovce +Nonnweiler +Penkridge +Severance +Malverne +Ararica +Nossa Senhora dos Remédios +Kasāp +Phopnār Kalān +Southampton +Möckmühl +La Salvetat-Saint-Gilles +Sallisaw +Le Mont-sur-Lausanne +Nijgaon Parānpur +Kosiv +Clayton le Moors +Pokrovka +Lewistown +Lanco +Nawānagar +Ra’s al Ma‘arrah +Qorovul +Woltersdorf +Hundested +Laitila +Cam +Thāndewāla +Khutha Baijnāth +Kandanūr +Medikunda +San Isidro +Pérenchies +Andanappettai +Delavan +Olamzé +Neuenbürg +Kond Rūd +Poniatowa +Reichelsheim +Möser +Hanko +Oakengates +Schnaittach +Perungulam +Dodvad +Silvārpatti +Santa Margherita Ligure +Wieruszów +Hāthāpur +Rāmpatti +Evergreen +Lycksele +Uedem +Thaon-les-Vosges +Sutherlin +Richland Hills +Carbonita +Sautron +Bedwas +Sāgarpur +Darsur +Whitehouse +Hueyotlipan +Takaharu +Kuchai Kot +Boshof +West Auckland +Chermen +El Dovio +Mandalapalle +Pachrukhi +Repala +Tionk Essil +Zhujiagua +Liffré +Pedda Penki +Orşova +Biloziria +Nottampatti +Altoona +Old Forge +Lieşti +Carlton Colville +Dala +Hausjärvi +Kalloní +Campogalliano +Rignano sull’Arno +West Earl +Dobanovci +Staufen im Breisgau +Saint-Vallier +Nālikkalpatti +Chinaur +Munnelli +Nalās +Tarīchar Kalān +Setana +Saruu +Rakai +Biryusinsk +Chapaev +Basarabeasca +Namsos +Joniškis +Orocué +Zərdab +As Sallūm +Gramsh +Būlaevo +Jesenice +Stans +Gadžin Han +Gunnedah +Kaišiadorys +Golubac +Pazin +Sorø +Cowra +Moengo +Olovyannaya +Slovenska Bistrica +Rubirizi +Ayr +Pampa del Infierno +Tweed Heads +Naujoji Akmenė +Shar +Kočevje +Koné +Gleno +Putina +Paide +Aguelhok +Hammerfest +Beočin +Qusmuryn +Osakarovka +Dimitrovgrad +Varėna +Charters Towers +Montpelier +Gżira +Kontcha +Oldeani +Nisporeni +Sokobanja +Ciudad Cortés +Greymouth +Katoomba +Obluchye +Amapá +Sharbaqty +Port Maria +Alebtong +San Julián +Monaghan +Auki +Dilolo +Sembabule +Ch’osan-ŭp +Bentiu +Falmouth +Ertis +Maryborough +Iqaluit +Luba +Kalabo +Young +Grosuplje +Qazaly +Bayghanīn +Lascano +Heyin +Ludza +Yeghegnadzor +Yardımlı +Mtskheta +Guadalupe +Kibale +Jacareacanga +Bairnsdale +San Pablo Villa de Mitla +Castillos +Kemijärvi +Kelmė +Sen Monorom +Gaoual +Zhänibek +Bački Petrovac +Leova +Leeton +Coracora +Kirkwall +Goranboy +Ādaži +Nangan +Aiquile +Ravne na Koroškem +Luân Châu +Atherton +Aračinovo +Briceni +Lerik +Thames +Puerto Baquerizo Moreno +Bossembele +Kičevo +Mongomo +Slovenj Gradec +Tranqueras +Teleneşti +Bestöbe +Obo +Mobaye +Tobyl +Lapovo +Ruyigi +Dowa +Novobërdë +Donduşeni +Debe +Ştefan Vodă +Zambezi +Moree +Skovorodino +Diekirch +In Guezzam +Wick +Thyolo +Rabaul +Ararat +Oğuz +Kapoeta +Krāslava +Kerikeri +Novi Kneževac +Kieta +Aizkraukle +Bongaree +Nicoadala +Librazhd +Santa Venera +Hola +Līvāni +Victoria +Kiruhura +Kiama +Lerwick +Zholymbet +Borgo Maggiore +Obiliq +Brežice +Ajdovščina +Šalčininkai +Forbes +Nata +Khandyga +Gulbene +Charagua +Kishkeneköl +Magugpo Poblacion +Criuleni +Limbaži +Litija +Madona +Trindade +Carnarvon +Awjilah +Seymour +Makarov +Port Augusta +Mazoe +Ros Comáin +Kerema +Northam +Cliza +Mae Hong Son +Roma +Bogatić +Oficina María Elena +Newman +Ingeniero Guillermo N. Juárez +Cooma +Port Saint John’s +Ndendé +Zouar +Deniliquin +Pasvalys +Melut +Comandante Luis Piedra Buena +Siteki +Medveđa +Sal Rei +San Carlos +Dalaba +Yeppoon +Verkhnevilyuysk +Lorengau +Derzhavīnsk +Omaruru +Vanrhynsdorp +Alūksne +Punakha +Ingeniero Jacobacci +Bir Anzarane +Jakar +Phalombe +Queanbeyan +Tumut +Kavadarci +Palikir +Moss +Ub +Kupiškis +Espargos +Gizo +Bella Vista +Veintiocho de Noviembre +Umba +Mengeš +Bač +Junik +Viqueque +Yamba +Kolonia +Alausí +Cəbrayıl +Dinguiraye +San Javier +Sežana +Funafuti +Zagorje +Chepes +Lucea +Maltahöhe +Mitoma +Gyangzê +Schaan +Glarus +Tazovskiy +Radovljica +Veinticinco de Mayo +Preiļi +Luqa +Përmet +Zarasai +Trakai +Şoldăneşti +Echternach +Mundybash +Kaitaia +Rutana +Berovo +Idrija +Širvintos +Ranillug +Lobamba +Aiyomojok +Molėtai +Biloela +Piggs Peak +Appenzell +Stratford +Uncia +Marigot +Tiksi +Xocavənd +Vaduz +Masunga +Cacheu +Balvi +Nieuw Amsterdam +Chonchi +Stawell +Hermanus +Babək +Sisimiut +Muisne +Vossevangen +Okhotsk +Fort-Shevchenko +Mwatate +Põlva +Eenhana +Byron Bay +Mamushë +Kazlų Rūda +Namanga +Narrabri +Črnomelj +General Conesa +Petnjica +San Antonio de los Cobres +Mali +Mali Iđoš +Muramvya +Tura +Šakiai +Goondiwindi +Ouadda +San Quintín +Wiltz +Thaba-Tseka +Richmond +Kratovo +Kovačica +Cospicua +Saint-Pierre +Cobram +San Ramón +Medvode +Witu +San Matías +Rapla +Skuodas +Bajram Curri +Bilibino +Hohenau +Napak +Torghay +Triesen +Albina +Otavi +Tarrafal +Thinadhoo +Jõgeva +Mayumba +Kalangala +Jinzhong +Canillo +Slovenske Konjice +Danilovgrad +Liquiçá +Chernyshevskiy +Karibib +Villa del Rosario +Smiltene +Rogaška Slatina +Roatán +Ķekava +Punta Gorda +McMinns Lagoon +Scone +Palé +Žalec +Puerto Casado +Singleton +Qaşr al Farāfirah +Ignalina +Grevenmacher +Samtse +Igarka +Gevgelija +Wonthaggi +Hrastnik +Sémbé +Lithgow +Valdez +Šentjur +Ust’-Kamchatsk +Bled +Mitzic +Vadsø +Mékambo +Xagħra +Vrapčište +Ordino +Irig +Bolama +Albury +Brownsweg +Turukhansk +Tuzi +Carrick on Shannon +Ponta do Sol +Ilulissat +Bagdarin +Halba +Għaxaq +Fdérik +Čoka +Šilalė +Svolvær +Komatipoort +Radoviš +Klaksvík +Westport +Finnsnes +Balzers +Sangar +Betanzos +Bongandanga +Khatanga +Prevalje +Perito Moreno +Outapi +Valka +Opovo +Otar +Sevnica +Kununurra +Nadur +Camargo +Fuerte Olimpo +Gobernador Gregores +Bueng Kan +Pakruojis +Švenčionys +Bururi +Al Qaşr +Eschen +Victorica +Şuşa +Qıvraq +Susuman +Mauren +Marsa +Karasburg +Samaipata +Magdalena +Saryshaghan +Tepelenë +Ingham +Ilirska Bistrica +Saint George’s +Dehiba +Nwoya +Bekily +Comandante Fontana +Narrogin +Batagay +Black River +Kuala Belait +Victor Harbor +I-n-Amguel +Ruše +La Palma +Omsukchan +Novyy Uoyan +Manjimup +Calheta de São Miguel +Kruševo +Naifaru +Bensonville +Berri +Port Hedland +Las Lajas +Wabag +Pevek +Çorovodë +San Marino +Kalvarija +Pietà +Cerknica +Remich +El Maitén +Avarua +Manica +Aliwal North +Balzan +Qobustan +Robertsport +Karmah an Nuzul +Trebnje +Trzin +Oranjemund +Bethanie +Bîr Mogreïn +Lazdijai +Butalangu +Neiafu +Vitim +P’ungsan +Esperanza +Plandište +Sicasica +Vergara +Miklavž na Dravskem Polju +Deçan +Omuthiya +Piran +Ağdam +Teseney +Ersekë +Ulaan-Uul +Cherskiy +Grand Turk +Padilla +Lavumisa +Šempeter pri Gorici +Massenya +Palana +Tržič +Žiri +Pembroke +Makedonski Brod +Katanning +Imġarr +Zyryanka +Cankuzo +De-Kastri +Tessalit +Ribnica +Dingli +Pukë +São João dos Angolares +Mojkovac +Janjanbureh +Lismore +Villa Ygatimí +Domagnano +Merimbula +Marsaxlokk +Kirkenes +Tolmin +Ceduna +Port Douglas +Mongar +Ligonha +Paita +Kirakira +La Paloma +Srednekolymsk +Wallaroo +Proserpine +Uspallata +Alibunar +Cantemir +Darregueira +Kaberamaido +Zhigansk +Malishevë +Trancas +Bukachacha +Ugol’nyye Kopi +Lukulu +Fish Town +Clare +Turangi +Imqabba +Krasnogorsk +Xewkija +Weipa +Laško +Pofadder +Lenart v Slovenskih Goricah +Smithton +Demir Kapija +The Valley +Mezen +Rietavas +Ljutomer +Juradó +Domžale +Metlika +Rørvik +Ankaran +Brezovica +Għajnsielem +Teeli +Sinnamary +Mežica +Evinayong +Brandfort +Ocniţa +Kudahuvadhoo +Saulkrasti +Iklin +Colonia +Šenčur +Golubovci +Birštonas +Dravograd +Gornja Radgona +Ainaro +Lija +Železniki +Aasiaat +Mopipi +Ust’-Maya +Porto Inglês +Arroyos y Esteros +Qaqortoq +Tearce +Trashigang +Ulbroka +Škofljica +Abaí +Taoudenni +Kärdla +Kalkara +Tifariti +Mahibadhoo +San Lorenzo +Lethem +Gudja +Saranpaul +Al Jaghbūb +Żebbuġ +Lendava +Bogdanci +Rogašovci +Šoštanj +Zreče +Sowa Town +Bopolu +Žitište +Hokitika +Nautla +Tom Price +Radlje ob Dravi +Bordertown +Villalonga +Viligili +Mangbwalu +Groningen +São Domingos +Buala +Entre Ríos +Río Mayo +Cochrane +Senglea +Għargħur +Qrendi +Kerewan +Hlatikulu +Saint-Georges +Longreach +Trashi Yangtse +Barclayville +Kolašin +Vila Velha +Urubamba +Trongsa +Rače +Borovnica +Eydhafushi +Triesenberg +Vittoriosa +Rodeo +Ísafjörður +Donegal +Sauðárkrókur +Tofol +Cestos City +Imtarfa +Mkokotoni +Chumbicha +Mahdia +Kllokot +Rosoman +Charleville +Fiorentino +Provideniya +Baltasar Brum +Cloncurry +Exmouth +Chokurdakh +Nauta +Mariscal José Félix Estigarribia +Capitol Hill +Severo-Kuril’sk +Brokopondo +Vojnik +Aiguá +Tarabuco +Quime +Demir Hisar +Beltinci +Al ‘Alamayn +Höfn +Jaqué +Nida +Merredin +El Dorado +Karungu +Vevčani +Polzela +Bloemhof +Sohano +Zhemgang +Boffa +Egilsstaðir +Coroico +Saskylakh +Krško +Gustavia +Ypejhú +Ruggell +Toltén +Muta +Sveta Ana +Qala +Lehututu +Şahbuz +Štore +Te Anau +Egvekinot +Ig +Marādah +Roura +Onverwacht +Gradsko +Desaguadero +Sorata +Mwenga +El Manteco +Stanley +Kaikoura +Floriana +Ivančna Gorica +José Batlle y Ordóñez +Črna na Koroškem +Puerto Villamil +Kirkop +Laçın +Radenci +Vianden +Totness +Cidade Velha +Acquaviva +Pozo Colorado +Baures +Safi +Apolo +Sannat +Spodnje Hoče +Funadhoo +Vipava +Same +Esperance +Pivka +Omboué +Mozirje +Manadhoo +Evensk +Pukekohe East +Waitakere +Waitangi +Semič +Ambrolauri +Damongo +Konza +Altata +Heydərabad +Djibloho +Sofifi +Afega +Radeče +Valandovo +Lovrenc na Pohorju +Capellen +Tasiilaq +Scottsdale +Ormož +Borgarnes +Katwe +Straža +Kerċem +Žabljak +Abunã +Amudat +Mount Barker +Philipsburg +Maitland +Taedong +Krivogaštani +Mislinja +Beringovskiy +Balakən +Ta’ Xbiex +Novyy Port +Naklo +Queenstown +Bohinjska Bistrica +Nokaneng +Šmarje +Longyearbyen +Nasir +Partesh +Divača +Xgħajra +Cerklje na Gorenjskem +Vodice +Varakļāni +Spodnji Duplek +Pehčevo +Ropaži +Gusinje +Tabor +Gamprin +Pārūn +Puerto Williams +Cuevo +Capitán Pablo Lagerenza +Odranci +Lifford +Prebold +Flying Fish Cove +Zgornja Kungota +Xızı +Bovec +Plasnica +Chiradzulu +Alto Río Senguer +Sierra Colorada +Rogatec +Għarb +Iracoubo +Bourke +Zrnovci +Oktyabr’skiy +Kipili +Ungoofaaru +Vuzenica +Ust’-Kuyga +Eldikan +Tumby Bay +Turnišče +Miren +Chibemba +Alexander Bay +Halls Creek +Tajarhī +Artëmovsk +Nova Crnja +Lokwabe +Clervaux +Dragomer +Munxar +Kranjska Gora +Šentjernej +Peterborough +Cerkno +Oplotnica +Machinga +Port Denison +Tsau +Uummannaq +Xocalı +Šmartno +Penola +Mirna +Kazachye +Nakhodka +Selnica ob Dravi +Kingston South East +Nyimba +Veymandoo +Lubutu +Wagin +Fulacunda +Paamiut +Greytown +Bala Cangamba +Tarutung +Santo António +Novaci +Bosilovo +Safotu +Kalbarri +Villa Rumipal +Dornava +Mogila +Kidričevo +Katherine +Mabaruma +Tulagi +Novo Selo +Barcaldine +Villa Martín Colchak +Ubombo +Regedor Quissico +Çeleken +Isangel +Buluko +Leulumoega +Faetano +Horjul +Ağdam +Črenšovci +Daga +Los Blancos +Kanal +Asau +Gorenja Vas +Lavrentiya +Puerto Acosta +Verkhoyansk +Mirbāţ +Ñacunday +Poljčane +Dikson +Uad Damran +Plužine +Ljubno +Susques +Upernavik +Schellenberg +Chumikan +Innisfail +Klyuchi +Kobarid +Qasigiannguit +Benedikt +Mazatán +Hagåtña +Fulin +Andrijevica +Oranjestad +Mata-Utu +Ouyen +Gornji Grad +Mirna Peč +Hughenden +Haya +Cowell +Yélimané +Središče ob Dravi +General Eugenio A. Garay +Montegiardino +Streaky Bay +Moravče +Príncipe da Beira +Lufilufi +Dobrovnik +Daraj +Fontana +Dobrova +Ayan +Konče +Shamva +Laverton +Veržej +Komenda +Dolenjske Toplice +Nazarje +Rostuša +Hoskins +Velika Polana +Luanza +Meningie +Vitanje +Gorišnica +Winton +Hamilton +Yulara +Gingin +Jegunovce +Ozurgeti +Pesnica +Sodražica +Godhavn +Stari Trg +Preddvor +Vatican City +Charaña +Onslow +Zgornja Hajdina +Bicheno +Omolon +Vailoa +Starše +Muhembo +Sveta Trojica v Slovenskih Goricah +Moravske-Toplice +San Lawrenz +Yaren +Yerëma +Wyndham +Rankovce +Comallo +Velike Lašče +Jamestown +Hvalba +Zhilinda +Satadougou +Lakatoro +Mokronog +Roebourne +Manily +Zhaltyr +Sopište +Kostanjevica na Krki +Pannawonica +Linxi +Ituni +Meekatharra +Obleševo +Qubadlı +Leonora +Massangena +Gawler +Qaanaaq +Komen +Šmartno +Kozje +Puconci +Vasilevo +Calatrava +Bangar +Grad +Uelen +Nkurenkuru +Tigoa +Villa O’Higgins +Kimba +Majšperk +Dibaya +Panda +Gastre +Saleaula +Kəlbəcər +Alofi +Quilpie +Videm +Podčetrtek +Karbinci +Sabaya +Mikhalkino +Oatlands +Zgornje Jezersko +Chiramba +Norseman +Lata +Llica +Mereeg +Telsen +Apače +Kobilje +Wilcannia +Dobrna +Zgornje Gorje +Calenga +Southern Cross +Lozovo +Rečica +Caluula +Tournavista +Felidhoo +Tmassah +Puerto Pinasco +Oymyakon +Tchitado +Yakossi +Križevci +Markovci +Staro Nagoričane +Šmarješke Toplice +Karumba +Planken +Kempsey +Mount Magnet +Vreed-en-Hoop +The Bottom +Richmond +Kullorsuaq +Cirkulane +Videm pri Ptuju +Woomera +Brvenica +Dhuusamarreeb +Skopun +Morawa +Lukovica +Theodore +Crna Trava +Kuzma +Eidsvold +Għasri +Buabidi +Montes Claros +Cankova +Hvannasund +Tsavo +Sherlovaya Gora +Gornji Petrovci +Tišina +Ribnica +Luče +Nizhneyansk +Tandil +Espungabera +Šalovci +Brades +Juršinci +Podlehnik +Braslovče +Toconao +Trnovska Vas +Šavnik +Rinconada +Jurovski Dol +Three Springs +Centar Župa +Hrib-Loški Potok +Ravensthorpe +Scoresbysund +Kingston +Vitomarci +Burubaytal +Dobrovo +Leava +Pine Creek +Keflavík +Šentrupert +Basse-Terre +Umm al ‘Abīd +Dolneni +Araouane +Halfmoon Bay +Bugrino +Shoyna +Buur Gaabo +Podvelka +Put’ Lenina +Cazombo +Belčišta +Enurmino +Porkeri +Nova Vas +Yaupi +Imdina +Ikela +Amderma +Hodoš +Dol +Čučer-Sandevo +Zelenikovo +Melekeok +Ngerulmud +Andamooka +Tomaž pri Ormožu +Tasiusaq +Adelaide River +Kulusuk +Burketown +Bistrica ob Sotli +Škocjan +Kanyato +Amau +Kairaki +Georgetown +Makole +Boulia +Sveti Jurij +Solčava +Carnarvon +Thargomindah +Destrnik +Kraulshavn +Tamworth +Lusanga +Hurdiyo +Port Pirie +Korf +Androka +Cerkvenjak +Ivanhoe +Al Qunayţirah +Camooweal +Bafwasende +Progress +Razkrižje +Buton +Bifoun +Kangersuatsiaq +Narsarsuaq +Bedourie +Petrovec +Mount Isa +Fort Wellington +Dobje +Punta Prieta +Il’pyrskiy +Birdsville +Star Dojran +Želino +Windorah +Al ‘Uqaylah +Lemsid +Mukhomornoye +Vorontsovo +Grytviken +Füzuli +Venado Tuerto +Fámjin +Osilnica +Piso Firme +Studeničani +Pagėgiai +Savissivik +Adamstown +Samamea +Cauquenes +Rocafuerte +Bogovinje +Kovda +Cuya +Vransko +Zillah +Chegga +Djado +Gaigirgordub +Andoas +Puca Urco +Soldado Bartra +Güeppí +Matochkin Shar +Siglan +Omchak +Shalaurova +Khorgo +Tiyerbes +Peregrebnoye +Komsa +Gyda +Khakhar +Menkerya +Ust’-Nyukzha +Zvëzdnyy +Pakhachi +Indiga +Starorybnoye +Laryak +Ulkan +Strelka +Chagda +Sagastyr +Zemlya Bunge +Trofimovsk +Tunguskhaya +Agapa +Podkamennaya Tunguska +Tukchi +Varnek +Numto +Ust’-Olenëk +Bol’sheretsk +Olenëk +Utkholok +Yessey +Karamken +Kostel +Puerto Heath +Lagunas +Barnīs +Gamba +Nord +Timmiarmiut +Ambarchik +Kingoonya +Sabhā +‘Amrān +Al Jabīn +Nelspruit +Lupane +Anouvông +Xékong +Phôn-Hông +Qacha’s Nek +Mersch +Redange-sur-Attert +Idrī +Cocieri +Lipkovo +Ilinden +Resen +Makedonska Kamenica +Dalandzadgad +Tevragh Zeina +Plymouth +Santa Luċija +Rasdhoo +Muli +Dhihdhoo +Fonadhoo +Nilandhoo +Thulusdhoo +Balaka +Neno +Chikwawa +Usakos +Wé +Abakaliki +Yenagoa +Isemi-Ile +Şūr +Haymā’ +Şuḩār +Unión Chocó +Sieyik +Kurumul +Buka +Pili +Tabuk +San Jose +Santa Cruz +Koronadal +Az̧ Z̧a‘āyin +Umm Şalāl ‘Alī +Madīnat ash Shamāl +Bosilegrad +Žagubica +Požega +Doljevac +Boljevac +Ljubovija +Babušnica +Preševo +Ljig +Mali Zvornik +Priboj +Bojnik +Koceljeva +Žabari +Trgovište +Nordvik +Logashkino +Taro +Rabak +El Fula +Edinburgh of the Seven Seas +Georgetown +Žetale +Šentilj +Žužemberk +Zavrč +Chiesanuova +Sédhiou +Ceerigaabo +Laascaanood +Boorama +Nhlangano +Pala +Bardaï +Kara +Ban Huai Hin +Lospalos +Aileu +Pante Macassar +Suai +Aranguez +Banqiao +Mahonda +Vwawa +Koani +Namutumba +Maracha +Namayingo +Luuka Town +Kasanda +Kinoni +Busesa +Bulambuli +Ntoroko +Otuke +Bupoto +Agago +Kitamilo +Nsiika +Kalaki +Kasaali +Nakapiripirit +Pader +Kakumiro +Mparo +Lamwo +Kyankwanzi +Ntara +Bukwo +Butebo +Binyin +Palenga +Kibingo +Kole +Nabilatuk +Rubanda +Kalungu +Kon Tum +Đà Nẵng +Sola +Saratamata +Safotulafai +Mulifanua +Satupa‘itea +Sharan +Nīlī +Dəvəçi +Şərur +Qəbələ +Isale +Dogbo +Tutong +San Rafael +Sarpang +Pemagatshel +Tsimasham +Gasa +Haa +Lhuentse +Tsirang +Loango +Bangolo +Chuquicamata +Panying +Chengde +Nanyangcun +Huinan +Picos +João Teves +Igreja +Ribeira Brava +Nova Sintra +Pombas +Cova Figueira +Erfurt +Sandur +Fuglafjørður +Hov +Vágur +Saltangará +Kvívík +Sumba +Viðareiði +Norðragøta +Toftir +Kirkja +Eiði +Sandavágur +Skúvoy +Skálavík +Sørvágur +Vestmanna +Strendur +Tvøroyri +Húsavík +Kunoy +Oyrarbakki +Goaso +Dambai +Sefwi Wiawso +Kanifing +King Edward Point +Tanjung Selor +Trim +Jaitpura +Navsāri +Tonk +Hubli +Sārī +Īlām +Nyamira +Siaya +Murang’a +Ol Kalou +Sotik Post +Kapenguria +Kabarnet +Migori +Pailin +Ta Khmau +Sariwŏn-si +Munha-dong +Sil-li +Muan +Hongseong +Charlotte Amalie diff --git a/tests/data/v2/cities.zarr/.zarray b/tests/data/v2/cities.zarr/.zarray new file mode 100644 index 00000000..f459a409 --- /dev/null +++ b/tests/data/v2/cities.zarr/.zarray @@ -0,0 +1,18 @@ +{ + "chunks": [ + 1000 + ], + "compressor": null, + "dtype": "|O", + "fill_value": "", + "filters": [ + { + "id": "vlen-utf8" + } + ], + "order": "C", + "shape": [ + 47868 + ], + "zarr_format": 2 +} \ No newline at end of file diff --git a/tests/data/v2/cities.zarr/0 b/tests/data/v2/cities.zarr/0 new file mode 100644 index 00000000..a6c19e33 Binary files /dev/null and b/tests/data/v2/cities.zarr/0 differ diff --git a/tests/data/v2/cities.zarr/1 b/tests/data/v2/cities.zarr/1 new file mode 100644 index 00000000..04ab2fec Binary files /dev/null and b/tests/data/v2/cities.zarr/1 differ diff --git a/tests/data/v2/cities.zarr/10 b/tests/data/v2/cities.zarr/10 new file mode 100644 index 00000000..5e2b2084 Binary files /dev/null and b/tests/data/v2/cities.zarr/10 differ diff --git a/tests/data/v2/cities.zarr/11 b/tests/data/v2/cities.zarr/11 new file mode 100644 index 00000000..06662497 Binary files /dev/null and b/tests/data/v2/cities.zarr/11 differ diff --git a/tests/data/v2/cities.zarr/12 b/tests/data/v2/cities.zarr/12 new file mode 100644 index 00000000..f0c7c618 Binary files /dev/null and b/tests/data/v2/cities.zarr/12 differ diff --git a/tests/data/v2/cities.zarr/13 b/tests/data/v2/cities.zarr/13 new file mode 100644 index 00000000..2f3fbba8 Binary files /dev/null and b/tests/data/v2/cities.zarr/13 differ diff --git a/tests/data/v2/cities.zarr/14 b/tests/data/v2/cities.zarr/14 new file mode 100644 index 00000000..35e157e7 Binary files /dev/null and b/tests/data/v2/cities.zarr/14 differ diff --git a/tests/data/v2/cities.zarr/15 b/tests/data/v2/cities.zarr/15 new file mode 100644 index 00000000..88e2b1f2 Binary files /dev/null and b/tests/data/v2/cities.zarr/15 differ diff --git a/tests/data/v2/cities.zarr/16 b/tests/data/v2/cities.zarr/16 new file mode 100644 index 00000000..703de528 Binary files /dev/null and b/tests/data/v2/cities.zarr/16 differ diff --git a/tests/data/v2/cities.zarr/17 b/tests/data/v2/cities.zarr/17 new file mode 100644 index 00000000..ca9a7c40 Binary files /dev/null and b/tests/data/v2/cities.zarr/17 differ diff --git a/tests/data/v2/cities.zarr/18 b/tests/data/v2/cities.zarr/18 new file mode 100644 index 00000000..55461057 Binary files /dev/null and b/tests/data/v2/cities.zarr/18 differ diff --git a/tests/data/v2/cities.zarr/19 b/tests/data/v2/cities.zarr/19 new file mode 100644 index 00000000..7e24a4f3 Binary files /dev/null and b/tests/data/v2/cities.zarr/19 differ diff --git a/tests/data/v2/cities.zarr/2 b/tests/data/v2/cities.zarr/2 new file mode 100644 index 00000000..586ba5f4 Binary files /dev/null and b/tests/data/v2/cities.zarr/2 differ diff --git a/tests/data/v2/cities.zarr/20 b/tests/data/v2/cities.zarr/20 new file mode 100644 index 00000000..19336a68 Binary files /dev/null and b/tests/data/v2/cities.zarr/20 differ diff --git a/tests/data/v2/cities.zarr/21 b/tests/data/v2/cities.zarr/21 new file mode 100644 index 00000000..3d27b331 Binary files /dev/null and b/tests/data/v2/cities.zarr/21 differ diff --git a/tests/data/v2/cities.zarr/22 b/tests/data/v2/cities.zarr/22 new file mode 100644 index 00000000..fd7fad06 Binary files /dev/null and b/tests/data/v2/cities.zarr/22 differ diff --git a/tests/data/v2/cities.zarr/23 b/tests/data/v2/cities.zarr/23 new file mode 100644 index 00000000..99fa74b5 Binary files /dev/null and b/tests/data/v2/cities.zarr/23 differ diff --git a/tests/data/v2/cities.zarr/24 b/tests/data/v2/cities.zarr/24 new file mode 100644 index 00000000..1c2b8269 Binary files /dev/null and b/tests/data/v2/cities.zarr/24 differ diff --git a/tests/data/v2/cities.zarr/25 b/tests/data/v2/cities.zarr/25 new file mode 100644 index 00000000..1a150efc Binary files /dev/null and b/tests/data/v2/cities.zarr/25 differ diff --git a/tests/data/v2/cities.zarr/26 b/tests/data/v2/cities.zarr/26 new file mode 100644 index 00000000..54beb664 Binary files /dev/null and b/tests/data/v2/cities.zarr/26 differ diff --git a/tests/data/v2/cities.zarr/27 b/tests/data/v2/cities.zarr/27 new file mode 100644 index 00000000..85091567 Binary files /dev/null and b/tests/data/v2/cities.zarr/27 differ diff --git a/tests/data/v2/cities.zarr/28 b/tests/data/v2/cities.zarr/28 new file mode 100644 index 00000000..ac872e6c Binary files /dev/null and b/tests/data/v2/cities.zarr/28 differ diff --git a/tests/data/v2/cities.zarr/29 b/tests/data/v2/cities.zarr/29 new file mode 100644 index 00000000..a780160e Binary files /dev/null and b/tests/data/v2/cities.zarr/29 differ diff --git a/tests/data/v2/cities.zarr/3 b/tests/data/v2/cities.zarr/3 new file mode 100644 index 00000000..5cc0ad76 Binary files /dev/null and b/tests/data/v2/cities.zarr/3 differ diff --git a/tests/data/v2/cities.zarr/30 b/tests/data/v2/cities.zarr/30 new file mode 100644 index 00000000..4b53762c Binary files /dev/null and b/tests/data/v2/cities.zarr/30 differ diff --git a/tests/data/v2/cities.zarr/31 b/tests/data/v2/cities.zarr/31 new file mode 100644 index 00000000..80df42a3 Binary files /dev/null and b/tests/data/v2/cities.zarr/31 differ diff --git a/tests/data/v2/cities.zarr/32 b/tests/data/v2/cities.zarr/32 new file mode 100644 index 00000000..39261e88 Binary files /dev/null and b/tests/data/v2/cities.zarr/32 differ diff --git a/tests/data/v2/cities.zarr/33 b/tests/data/v2/cities.zarr/33 new file mode 100644 index 00000000..61d0859b Binary files /dev/null and b/tests/data/v2/cities.zarr/33 differ diff --git a/tests/data/v2/cities.zarr/34 b/tests/data/v2/cities.zarr/34 new file mode 100644 index 00000000..53ea6b6d Binary files /dev/null and b/tests/data/v2/cities.zarr/34 differ diff --git a/tests/data/v2/cities.zarr/35 b/tests/data/v2/cities.zarr/35 new file mode 100644 index 00000000..296d0d0e Binary files /dev/null and b/tests/data/v2/cities.zarr/35 differ diff --git a/tests/data/v2/cities.zarr/36 b/tests/data/v2/cities.zarr/36 new file mode 100644 index 00000000..f64ae10f Binary files /dev/null and b/tests/data/v2/cities.zarr/36 differ diff --git a/tests/data/v2/cities.zarr/37 b/tests/data/v2/cities.zarr/37 new file mode 100644 index 00000000..bb262941 Binary files /dev/null and b/tests/data/v2/cities.zarr/37 differ diff --git a/tests/data/v2/cities.zarr/38 b/tests/data/v2/cities.zarr/38 new file mode 100644 index 00000000..9f695451 Binary files /dev/null and b/tests/data/v2/cities.zarr/38 differ diff --git a/tests/data/v2/cities.zarr/39 b/tests/data/v2/cities.zarr/39 new file mode 100644 index 00000000..23f36cd3 Binary files /dev/null and b/tests/data/v2/cities.zarr/39 differ diff --git a/tests/data/v2/cities.zarr/4 b/tests/data/v2/cities.zarr/4 new file mode 100644 index 00000000..cee2f5c6 Binary files /dev/null and b/tests/data/v2/cities.zarr/4 differ diff --git a/tests/data/v2/cities.zarr/40 b/tests/data/v2/cities.zarr/40 new file mode 100644 index 00000000..c2bc2b6d Binary files /dev/null and b/tests/data/v2/cities.zarr/40 differ diff --git a/tests/data/v2/cities.zarr/41 b/tests/data/v2/cities.zarr/41 new file mode 100644 index 00000000..7cf3e0a8 Binary files /dev/null and b/tests/data/v2/cities.zarr/41 differ diff --git a/tests/data/v2/cities.zarr/42 b/tests/data/v2/cities.zarr/42 new file mode 100644 index 00000000..93198803 Binary files /dev/null and b/tests/data/v2/cities.zarr/42 differ diff --git a/tests/data/v2/cities.zarr/43 b/tests/data/v2/cities.zarr/43 new file mode 100644 index 00000000..e685e49f Binary files /dev/null and b/tests/data/v2/cities.zarr/43 differ diff --git a/tests/data/v2/cities.zarr/44 b/tests/data/v2/cities.zarr/44 new file mode 100644 index 00000000..05fe0bca Binary files /dev/null and b/tests/data/v2/cities.zarr/44 differ diff --git a/tests/data/v2/cities.zarr/45 b/tests/data/v2/cities.zarr/45 new file mode 100644 index 00000000..16669856 Binary files /dev/null and b/tests/data/v2/cities.zarr/45 differ diff --git a/tests/data/v2/cities.zarr/46 b/tests/data/v2/cities.zarr/46 new file mode 100644 index 00000000..f4c39865 Binary files /dev/null and b/tests/data/v2/cities.zarr/46 differ diff --git a/tests/data/v2/cities.zarr/47 b/tests/data/v2/cities.zarr/47 new file mode 100644 index 00000000..09682c9c Binary files /dev/null and b/tests/data/v2/cities.zarr/47 differ diff --git a/tests/data/v2/cities.zarr/5 b/tests/data/v2/cities.zarr/5 new file mode 100644 index 00000000..81706c83 Binary files /dev/null and b/tests/data/v2/cities.zarr/5 differ diff --git a/tests/data/v2/cities.zarr/6 b/tests/data/v2/cities.zarr/6 new file mode 100644 index 00000000..6307ce3a Binary files /dev/null and b/tests/data/v2/cities.zarr/6 differ diff --git a/tests/data/v2/cities.zarr/7 b/tests/data/v2/cities.zarr/7 new file mode 100644 index 00000000..e2d072c8 Binary files /dev/null and b/tests/data/v2/cities.zarr/7 differ diff --git a/tests/data/v2/cities.zarr/8 b/tests/data/v2/cities.zarr/8 new file mode 100644 index 00000000..37a7255e Binary files /dev/null and b/tests/data/v2/cities.zarr/8 differ diff --git a/tests/data/v2/cities.zarr/9 b/tests/data/v2/cities.zarr/9 new file mode 100644 index 00000000..e4c90e83 Binary files /dev/null and b/tests/data/v2/cities.zarr/9 differ diff --git a/tests/data/v2_cities.py b/tests/data/v2_cities.py new file mode 100644 index 00000000..716a5bef --- /dev/null +++ b/tests/data/v2_cities.py @@ -0,0 +1,19 @@ +import zarr # v2 +import pandas as pd + +print(zarr.__version__) + +df = pd.read_csv("tests/data/cities.csv", header=None) +cities = df[0] + +path_out = 'tests/data/v2/cities.zarr' +array = zarr.open(path_out, mode='w', dtype=str, shape=(len(cities),), chunks=(1000,), compressor = None, fill_value='') +array[:] = cities.values +print(array.info) + +for i in range(48): + v2 = open(f'tests/data/v2/cities.zarr/{i}', 'rb').read() + v3 = open(f'tests/data/v3/cities.zarr/c/{i}', 'rb').read() + assert v2 == v3 + +print("V2 and V3 chunks are identical!") diff --git a/tests/data/v3/cities.zarr/c/0 b/tests/data/v3/cities.zarr/c/0 new file mode 100644 index 00000000..a6c19e33 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/0 differ diff --git a/tests/data/v3/cities.zarr/c/1 b/tests/data/v3/cities.zarr/c/1 new file mode 100644 index 00000000..04ab2fec Binary files /dev/null and b/tests/data/v3/cities.zarr/c/1 differ diff --git a/tests/data/v3/cities.zarr/c/10 b/tests/data/v3/cities.zarr/c/10 new file mode 100644 index 00000000..5e2b2084 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/10 differ diff --git a/tests/data/v3/cities.zarr/c/11 b/tests/data/v3/cities.zarr/c/11 new file mode 100644 index 00000000..06662497 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/11 differ diff --git a/tests/data/v3/cities.zarr/c/12 b/tests/data/v3/cities.zarr/c/12 new file mode 100644 index 00000000..f0c7c618 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/12 differ diff --git a/tests/data/v3/cities.zarr/c/13 b/tests/data/v3/cities.zarr/c/13 new file mode 100644 index 00000000..2f3fbba8 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/13 differ diff --git a/tests/data/v3/cities.zarr/c/14 b/tests/data/v3/cities.zarr/c/14 new file mode 100644 index 00000000..35e157e7 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/14 differ diff --git a/tests/data/v3/cities.zarr/c/15 b/tests/data/v3/cities.zarr/c/15 new file mode 100644 index 00000000..88e2b1f2 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/15 differ diff --git a/tests/data/v3/cities.zarr/c/16 b/tests/data/v3/cities.zarr/c/16 new file mode 100644 index 00000000..703de528 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/16 differ diff --git a/tests/data/v3/cities.zarr/c/17 b/tests/data/v3/cities.zarr/c/17 new file mode 100644 index 00000000..ca9a7c40 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/17 differ diff --git a/tests/data/v3/cities.zarr/c/18 b/tests/data/v3/cities.zarr/c/18 new file mode 100644 index 00000000..55461057 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/18 differ diff --git a/tests/data/v3/cities.zarr/c/19 b/tests/data/v3/cities.zarr/c/19 new file mode 100644 index 00000000..7e24a4f3 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/19 differ diff --git a/tests/data/v3/cities.zarr/c/2 b/tests/data/v3/cities.zarr/c/2 new file mode 100644 index 00000000..586ba5f4 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/2 differ diff --git a/tests/data/v3/cities.zarr/c/20 b/tests/data/v3/cities.zarr/c/20 new file mode 100644 index 00000000..19336a68 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/20 differ diff --git a/tests/data/v3/cities.zarr/c/21 b/tests/data/v3/cities.zarr/c/21 new file mode 100644 index 00000000..3d27b331 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/21 differ diff --git a/tests/data/v3/cities.zarr/c/22 b/tests/data/v3/cities.zarr/c/22 new file mode 100644 index 00000000..fd7fad06 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/22 differ diff --git a/tests/data/v3/cities.zarr/c/23 b/tests/data/v3/cities.zarr/c/23 new file mode 100644 index 00000000..99fa74b5 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/23 differ diff --git a/tests/data/v3/cities.zarr/c/24 b/tests/data/v3/cities.zarr/c/24 new file mode 100644 index 00000000..1c2b8269 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/24 differ diff --git a/tests/data/v3/cities.zarr/c/25 b/tests/data/v3/cities.zarr/c/25 new file mode 100644 index 00000000..1a150efc Binary files /dev/null and b/tests/data/v3/cities.zarr/c/25 differ diff --git a/tests/data/v3/cities.zarr/c/26 b/tests/data/v3/cities.zarr/c/26 new file mode 100644 index 00000000..54beb664 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/26 differ diff --git a/tests/data/v3/cities.zarr/c/27 b/tests/data/v3/cities.zarr/c/27 new file mode 100644 index 00000000..85091567 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/27 differ diff --git a/tests/data/v3/cities.zarr/c/28 b/tests/data/v3/cities.zarr/c/28 new file mode 100644 index 00000000..ac872e6c Binary files /dev/null and b/tests/data/v3/cities.zarr/c/28 differ diff --git a/tests/data/v3/cities.zarr/c/29 b/tests/data/v3/cities.zarr/c/29 new file mode 100644 index 00000000..a780160e Binary files /dev/null and b/tests/data/v3/cities.zarr/c/29 differ diff --git a/tests/data/v3/cities.zarr/c/3 b/tests/data/v3/cities.zarr/c/3 new file mode 100644 index 00000000..5cc0ad76 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/3 differ diff --git a/tests/data/v3/cities.zarr/c/30 b/tests/data/v3/cities.zarr/c/30 new file mode 100644 index 00000000..4b53762c Binary files /dev/null and b/tests/data/v3/cities.zarr/c/30 differ diff --git a/tests/data/v3/cities.zarr/c/31 b/tests/data/v3/cities.zarr/c/31 new file mode 100644 index 00000000..80df42a3 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/31 differ diff --git a/tests/data/v3/cities.zarr/c/32 b/tests/data/v3/cities.zarr/c/32 new file mode 100644 index 00000000..39261e88 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/32 differ diff --git a/tests/data/v3/cities.zarr/c/33 b/tests/data/v3/cities.zarr/c/33 new file mode 100644 index 00000000..61d0859b Binary files /dev/null and b/tests/data/v3/cities.zarr/c/33 differ diff --git a/tests/data/v3/cities.zarr/c/34 b/tests/data/v3/cities.zarr/c/34 new file mode 100644 index 00000000..53ea6b6d Binary files /dev/null and b/tests/data/v3/cities.zarr/c/34 differ diff --git a/tests/data/v3/cities.zarr/c/35 b/tests/data/v3/cities.zarr/c/35 new file mode 100644 index 00000000..296d0d0e Binary files /dev/null and b/tests/data/v3/cities.zarr/c/35 differ diff --git a/tests/data/v3/cities.zarr/c/36 b/tests/data/v3/cities.zarr/c/36 new file mode 100644 index 00000000..f64ae10f Binary files /dev/null and b/tests/data/v3/cities.zarr/c/36 differ diff --git a/tests/data/v3/cities.zarr/c/37 b/tests/data/v3/cities.zarr/c/37 new file mode 100644 index 00000000..bb262941 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/37 differ diff --git a/tests/data/v3/cities.zarr/c/38 b/tests/data/v3/cities.zarr/c/38 new file mode 100644 index 00000000..9f695451 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/38 differ diff --git a/tests/data/v3/cities.zarr/c/39 b/tests/data/v3/cities.zarr/c/39 new file mode 100644 index 00000000..23f36cd3 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/39 differ diff --git a/tests/data/v3/cities.zarr/c/4 b/tests/data/v3/cities.zarr/c/4 new file mode 100644 index 00000000..cee2f5c6 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/4 differ diff --git a/tests/data/v3/cities.zarr/c/40 b/tests/data/v3/cities.zarr/c/40 new file mode 100644 index 00000000..c2bc2b6d Binary files /dev/null and b/tests/data/v3/cities.zarr/c/40 differ diff --git a/tests/data/v3/cities.zarr/c/41 b/tests/data/v3/cities.zarr/c/41 new file mode 100644 index 00000000..7cf3e0a8 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/41 differ diff --git a/tests/data/v3/cities.zarr/c/42 b/tests/data/v3/cities.zarr/c/42 new file mode 100644 index 00000000..93198803 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/42 differ diff --git a/tests/data/v3/cities.zarr/c/43 b/tests/data/v3/cities.zarr/c/43 new file mode 100644 index 00000000..e685e49f Binary files /dev/null and b/tests/data/v3/cities.zarr/c/43 differ diff --git a/tests/data/v3/cities.zarr/c/44 b/tests/data/v3/cities.zarr/c/44 new file mode 100644 index 00000000..05fe0bca Binary files /dev/null and b/tests/data/v3/cities.zarr/c/44 differ diff --git a/tests/data/v3/cities.zarr/c/45 b/tests/data/v3/cities.zarr/c/45 new file mode 100644 index 00000000..16669856 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/45 differ diff --git a/tests/data/v3/cities.zarr/c/46 b/tests/data/v3/cities.zarr/c/46 new file mode 100644 index 00000000..f4c39865 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/46 differ diff --git a/tests/data/v3/cities.zarr/c/47 b/tests/data/v3/cities.zarr/c/47 new file mode 100644 index 00000000..09682c9c Binary files /dev/null and b/tests/data/v3/cities.zarr/c/47 differ diff --git a/tests/data/v3/cities.zarr/c/5 b/tests/data/v3/cities.zarr/c/5 new file mode 100644 index 00000000..81706c83 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/5 differ diff --git a/tests/data/v3/cities.zarr/c/6 b/tests/data/v3/cities.zarr/c/6 new file mode 100644 index 00000000..6307ce3a Binary files /dev/null and b/tests/data/v3/cities.zarr/c/6 differ diff --git a/tests/data/v3/cities.zarr/c/7 b/tests/data/v3/cities.zarr/c/7 new file mode 100644 index 00000000..e2d072c8 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/7 differ diff --git a/tests/data/v3/cities.zarr/c/8 b/tests/data/v3/cities.zarr/c/8 new file mode 100644 index 00000000..37a7255e Binary files /dev/null and b/tests/data/v3/cities.zarr/c/8 differ diff --git a/tests/data/v3/cities.zarr/c/9 b/tests/data/v3/cities.zarr/c/9 new file mode 100644 index 00000000..e4c90e83 Binary files /dev/null and b/tests/data/v3/cities.zarr/c/9 differ diff --git a/tests/data/v3/cities.zarr/zarr.json b/tests/data/v3/cities.zarr/zarr.json new file mode 100644 index 00000000..f4e5a16e --- /dev/null +++ b/tests/data/v3/cities.zarr/zarr.json @@ -0,0 +1,28 @@ +{ + "zarr_format": 3, + "node_type": "array", + "shape": [ + 47868 + ], + "data_type": "string", + "chunk_grid": { + "name": "regular", + "configuration": { + "chunk_shape": [ + 1000 + ] + } + }, + "chunk_key_encoding": { + "name": "default", + "configuration": { + "separator": "/" + } + }, + "fill_value": "", + "codecs": [ + { + "name": "https://codec.zarrs.dev/array_to_bytes/vlen_v2" + } + ] +} \ No newline at end of file