Try your search with a different keyword or use * as a wildcard.
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.StaticFiles;
using Nop.Core;
using Nop.Core.Domain.Affiliates;
using Nop.Core.Domain.Blogs;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Directory;
using Nop.Core.Domain.Discounts;
using Nop.Core.Domain.Forums;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Logging;
using Nop.Core.Domain.Media;
using Nop.Core.Domain.News;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Polls;
using Nop.Core.Domain.Seo;
using Nop.Core.Domain.Shipping;
using Nop.Core.Domain.Stores;
using Nop.Core.Domain.Vendors;
using Nop.Services.Installation.SampleData;
namespace Nop.Services.Installation;
public partial class InstallationService
{
#region Fields
protected int? _defaultLanguageId;
protected int? _defaultStoreId;
protected int? _defaultCustomerId;
protected FileExtensionContentTypeProvider _fileExtensionContentTypeProvider;
#endregion
#region Utilities
///
/// Gets default language identifier
///
/// A task that represents the asynchronous operation
/// The task result contains the identifier of default language
protected virtual async Task GetDefaultLanguageIdAsync()
{
if (_defaultLanguageId.HasValue)
return _defaultLanguageId.Value;
var lang = await Table().FirstOrDefaultAsync() ?? throw new Exception("Default language could not be loaded");
_defaultLanguageId = lang.Id;
return lang.Id;
}
///
/// Gets default store identifier
///
/// A task that represents the asynchronous operation
/// The task result contains the identifier of default store
protected virtual async Task GetDefaultStoreIdAsync()
{
if (_defaultStoreId.HasValue)
return _defaultStoreId.Value;
var store = await Table().FirstOrDefaultAsync() ?? throw new Exception("No default store could be loaded");
_defaultStoreId = store.Id;
return store.Id;
}
///
/// Inserts search engine names fore entities
///
/// Entities fore insert search engine names
/// Function to getting the name fore creating the slug
/// The language identifier
/// A task that represents the asynchronous operation
protected virtual async Task InsertSearchEngineNamesAsync(IEnumerable entities, Func getName, int languageId = 0) where TEntity : BaseEntity
{
await _dataProvider.BulkInsertEntitiesAsync(await entities.SelectAwait(async entity => new UrlRecord
{
EntityId = entity.Id,
EntityName = typeof(TEntity).Name,
LanguageId = languageId,
IsActive = true,
Slug = await ValidateSeNameAsync(entity, getName(entity))
}).ToListAsync());
}
///
/// Get SE name
///
/// Name
///
/// A task that represents the asynchronous operation
/// The task result contains the result
///
protected virtual string GetSeName(string name)
{
if (string.IsNullOrEmpty(name))
return name;
var okChars = new HashSet("abcdefghijklmnopqrstuvwxyz1234567890 _-");
// stores unicode characters and their "normalized"
// values to a hash table. Character codes are referenced
// by hex numbers because that's the most common way to
// refer to them.
//
// upper-case comments are identifiers from the Unicode database.
// lower- and mixed-case comments are the author's
var seoCharacterTable = new Dictionary
{
{ '\u0041', "A" },
{ '\u0042', "B" },
{ '\u0043', "C" },
{ '\u0044', "D" },
{ '\u0045', "E" },
{ '\u0046', "F" },
{ '\u0047', "G" },
{ '\u0048', "H" },
{ '\u0049', "I" },
{ '\u004A', "J" },
{ '\u004B', "K" },
{ '\u004C', "L" },
{ '\u004D', "M" },
{ '\u004E', "N" },
{ '\u004F', "O" },
{ '\u0050', "P" },
{ '\u0051', "Q" },
{ '\u0052', "R" },
{ '\u0053', "S" },
{ '\u0054', "T" },
{ '\u0055', "U" },
{ '\u0056', "V" },
{ '\u0057', "W" },
{ '\u0058', "X" },
{ '\u0059', "Y" },
{ '\u005A', "Z" },
{ '\u0061', "a" },
{ '\u0062', "b" },
{ '\u0063', "c" },
{ '\u0064', "d" },
{ '\u0065', "e" },
{ '\u0066', "f" },
{ '\u0067', "g" },
{ '\u0068', "h" },
{ '\u0069', "i" },
{ '\u006A', "j" },
{ '\u006B', "k" },
{ '\u006C', "l" },
{ '\u006D', "m" },
{ '\u006E', "n" },
{ '\u006F', "o" },
{ '\u0070', "p" },
{ '\u0071', "q" },
{ '\u0072', "r" },
{ '\u0073', "s" },
{ '\u0074', "t" },
{ '\u0075', "u" },
{ '\u0076', "v" },
{ '\u0077', "w" },
{ '\u0078', "x" },
{ '\u0079', "y" },
{ '\u007A', "z" },
{ '\u00AA', "a" }, // FEMININE ORDINAL INDICATOR
{ '\u00BA', "o" }, // MASCULINE ORDINAL INDICATOR
{ '\u00C0', "A" }, // LATIN CAPITAL LETTER A WITH GRAVE
{ '\u00C1', "A" }, // LATIN CAPITAL LETTER A WITH ACUTE
{ '\u00C2', "A" }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
{ '\u00C3', "A" }, // LATIN CAPITAL LETTER A WITH TILDE
{ '\u00C4', "A" }, // LATIN CAPITAL LETTER A WITH DIAERESIS
{ '\u00C5', "A" }, // LATIN CAPITAL LETTER A WITH RING ABOVE
{ '\u00C6', "AE" }, // LATIN CAPITAL LETTER AE -- no decomposition
{ '\u00C7', "C" }, // LATIN CAPITAL LETTER C WITH CEDILLA
{ '\u00C8', "E" }, // LATIN CAPITAL LETTER E WITH GRAVE
{ '\u00C9', "E" }, // LATIN CAPITAL LETTER E WITH ACUTE
{ '\u00CA', "E" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
{ '\u00CB', "E" }, // LATIN CAPITAL LETTER E WITH DIAERESIS
{ '\u00CC', "I" }, // LATIN CAPITAL LETTER I WITH GRAVE
{ '\u00CD', "I" }, // LATIN CAPITAL LETTER I WITH ACUTE
{ '\u00CE', "I" }, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
{ '\u00CF', "I" }, // LATIN CAPITAL LETTER I WITH DIAERESIS
{ '\u00D0', "D" }, // LATIN CAPITAL LETTER ETH -- no decomposition // Eth [D for Vietnamese]
{ '\u00D1', "N" }, // LATIN CAPITAL LETTER N WITH TILDE
{ '\u00D2', "O" }, // LATIN CAPITAL LETTER O WITH GRAVE
{ '\u00D3', "O" }, // LATIN CAPITAL LETTER O WITH ACUTE
{ '\u00D4', "O" }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
{ '\u00D5', "O" }, // LATIN CAPITAL LETTER O WITH TILDE
{ '\u00D6', "O" }, // LATIN CAPITAL LETTER O WITH DIAERESIS
{ '\u00D8', "O" }, // LATIN CAPITAL LETTER O WITH STROKE -- no decom
{ '\u00D9', "U" }, // LATIN CAPITAL LETTER U WITH GRAVE
{ '\u00DA', "U" }, // LATIN CAPITAL LETTER U WITH ACUTE
{ '\u00DB', "U" }, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
{ '\u00DC', "U" }, // LATIN CAPITAL LETTER U WITH DIAERESIS
{ '\u00DD', "Y" }, // LATIN CAPITAL LETTER Y WITH ACUTE
{ '\u00DE', "Th" }, // LATIN CAPITAL LETTER THORN -- no decomposition; // Thorn - Could be nothing other than thorn
{ '\u00DF', "s" }, // LATIN SMALL LETTER SHARP S -- no decomposition
{ '\u00E0', "a" }, // LATIN SMALL LETTER A WITH GRAVE
{ '\u00E1', "a" }, // LATIN SMALL LETTER A WITH ACUTE
{ '\u00E2', "a" }, // LATIN SMALL LETTER A WITH CIRCUMFLEX
{ '\u00E3', "a" }, // LATIN SMALL LETTER A WITH TILDE
{ '\u00E4', "a" }, // LATIN SMALL LETTER A WITH DIAERESIS
{ '\u00E5', "a" }, // LATIN SMALL LETTER A WITH RING ABOVE
{ '\u00E6', "ae" }, // LATIN SMALL LETTER AE -- no decomposition
{ '\u00E7', "c" }, // LATIN SMALL LETTER C WITH CEDILLA
{ '\u00E8', "e" }, // LATIN SMALL LETTER E WITH GRAVE
{ '\u00E9', "e" }, // LATIN SMALL LETTER E WITH ACUTE
{ '\u00EA', "e" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX
{ '\u00EB', "e" }, // LATIN SMALL LETTER E WITH DIAERESIS
{ '\u00EC', "i" }, // LATIN SMALL LETTER I WITH GRAVE
{ '\u00ED', "i" }, // LATIN SMALL LETTER I WITH ACUTE
{ '\u00EE', "i" }, // LATIN SMALL LETTER I WITH CIRCUMFLEX
{ '\u00EF', "i" }, // LATIN SMALL LETTER I WITH DIAERESIS
{ '\u00F0', "d" }, // LATIN SMALL LETTER ETH -- no decomposition // small eth, "d" for benefit of Vietnamese
{ '\u00F1', "n" }, // LATIN SMALL LETTER N WITH TILDE
{ '\u00F2', "o" }, // LATIN SMALL LETTER O WITH GRAVE
{ '\u00F3', "o" }, // LATIN SMALL LETTER O WITH ACUTE
{ '\u00F4', "o" }, // LATIN SMALL LETTER O WITH CIRCUMFLEX
{ '\u00F5', "o" }, // LATIN SMALL LETTER O WITH TILDE
{ '\u00F6', "o" }, // LATIN SMALL LETTER O WITH DIAERESIS
{ '\u00F8', "o" }, // LATIN SMALL LETTER O WITH STROKE -- no decompo
{ '\u00F9', "u" }, // LATIN SMALL LETTER U WITH GRAVE
{ '\u00FA', "u" }, // LATIN SMALL LETTER U WITH ACUTE
{ '\u00FB', "u" }, // LATIN SMALL LETTER U WITH CIRCUMFLEX
{ '\u00FC', "u" }, // LATIN SMALL LETTER U WITH DIAERESIS
{ '\u00FD', "y" }, // LATIN SMALL LETTER Y WITH ACUTE
{ '\u00FE', "th" }, // LATIN SMALL LETTER THORN -- no decomposition // Small thorn
{ '\u00FF', "y" }, // LATIN SMALL LETTER Y WITH DIAERESIS
{ '\u0100', "A" }, // LATIN CAPITAL LETTER A WITH MACRON
{ '\u0101', "a" }, // LATIN SMALL LETTER A WITH MACRON
{ '\u0102', "A" }, // LATIN CAPITAL LETTER A WITH BREVE
{ '\u0103', "a" }, // LATIN SMALL LETTER A WITH BREVE
{ '\u0104', "A" }, // LATIN CAPITAL LETTER A WITH OGONEK
{ '\u0105', "a" }, // LATIN SMALL LETTER A WITH OGONEK
{ '\u0106', "C" }, // LATIN CAPITAL LETTER C WITH ACUTE
{ '\u0107', "c" }, // LATIN SMALL LETTER C WITH ACUTE
{ '\u0108', "C" }, // LATIN CAPITAL LETTER C WITH CIRCUMFLEX
{ '\u0109', "c" }, // LATIN SMALL LETTER C WITH CIRCUMFLEX
{ '\u010A', "C" }, // LATIN CAPITAL LETTER C WITH DOT ABOVE
{ '\u010B', "c" }, // LATIN SMALL LETTER C WITH DOT ABOVE
{ '\u010C', "C" }, // LATIN CAPITAL LETTER C WITH CARON
{ '\u010D', "c" }, // LATIN SMALL LETTER C WITH CARON
{ '\u010E', "D" }, // LATIN CAPITAL LETTER D WITH CARON
{ '\u010F', "d" }, // LATIN SMALL LETTER D WITH CARON
{ '\u0110', "D" }, // LATIN CAPITAL LETTER D WITH STROKE -- no decomposition // Capital D with stroke
{ '\u0111', "d" }, // LATIN SMALL LETTER D WITH STROKE -- no decomposition // small D with stroke
{ '\u0112', "E" }, // LATIN CAPITAL LETTER E WITH MACRON
{ '\u0113', "e" }, // LATIN SMALL LETTER E WITH MACRON
{ '\u0114', "E" }, // LATIN CAPITAL LETTER E WITH BREVE
{ '\u0115', "e" }, // LATIN SMALL LETTER E WITH BREVE
{ '\u0116', "E" }, // LATIN CAPITAL LETTER E WITH DOT ABOVE
{ '\u0117', "e" }, // LATIN SMALL LETTER E WITH DOT ABOVE
{ '\u0118', "E" }, // LATIN CAPITAL LETTER E WITH OGONEK
{ '\u0119', "e" }, // LATIN SMALL LETTER E WITH OGONEK
{ '\u011A', "E" }, // LATIN CAPITAL LETTER E WITH CARON
{ '\u011B', "e" }, // LATIN SMALL LETTER E WITH CARON
{ '\u011C', "G" }, // LATIN CAPITAL LETTER G WITH CIRCUMFLEX
{ '\u011D', "g" }, // LATIN SMALL LETTER G WITH CIRCUMFLEX
{ '\u011E', "G" }, // LATIN CAPITAL LETTER G WITH BREVE
{ '\u011F', "g" }, // LATIN SMALL LETTER G WITH BREVE
{ '\u0120', "G" }, // LATIN CAPITAL LETTER G WITH DOT ABOVE
{ '\u0121', "g" }, // LATIN SMALL LETTER G WITH DOT ABOVE
{ '\u0122', "G" }, // LATIN CAPITAL LETTER G WITH CEDILLA
{ '\u0123', "g" }, // LATIN SMALL LETTER G WITH CEDILLA
{ '\u0124', "H" }, // LATIN CAPITAL LETTER H WITH CIRCUMFLEX
{ '\u0125', "h" }, // LATIN SMALL LETTER H WITH CIRCUMFLEX
{ '\u0126', "H" }, // LATIN CAPITAL LETTER H WITH STROKE -- no decomposition
{ '\u0127', "h" }, // LATIN SMALL LETTER H WITH STROKE -- no decomposition
{ '\u0128', "I" }, // LATIN CAPITAL LETTER I WITH TILDE
{ '\u0129', "i" }, // LATIN SMALL LETTER I WITH TILDE
{ '\u012A', "I" }, // LATIN CAPITAL LETTER I WITH MACRON
{ '\u012B', "i" }, // LATIN SMALL LETTER I WITH MACRON
{ '\u012C', "I" }, // LATIN CAPITAL LETTER I WITH BREVE
{ '\u012D', "i" }, // LATIN SMALL LETTER I WITH BREVE
{ '\u012E', "I" }, // LATIN CAPITAL LETTER I WITH OGONEK
{ '\u012F', "i" }, // LATIN SMALL LETTER I WITH OGONEK
{ '\u0130', "I" }, // LATIN CAPITAL LETTER I WITH DOT ABOVE
{ '\u0131', "i" }, // LATIN SMALL LETTER DOTLESS I -- no decomposition
{ '\u0132', "I" }, // LATIN CAPITAL LIGATURE IJ
{ '\u0133', "i" }, // LATIN SMALL LIGATURE IJ
{ '\u0134', "J" }, // LATIN CAPITAL LETTER J WITH CIRCUMFLEX
{ '\u0135', "j" }, // LATIN SMALL LETTER J WITH CIRCUMFLEX
{ '\u0136', "K" }, // LATIN CAPITAL LETTER K WITH CEDILLA
{ '\u0137', "k" }, // LATIN SMALL LETTER K WITH CEDILLA
{ '\u0138', "k" }, // LATIN SMALL LETTER KRA -- no decomposition
{ '\u0139', "L" }, // LATIN CAPITAL LETTER L WITH ACUTE
{ '\u013A', "l" }, // LATIN SMALL LETTER L WITH ACUTE
{ '\u013B', "L" }, // LATIN CAPITAL LETTER L WITH CEDILLA
{ '\u013C', "l" }, // LATIN SMALL LETTER L WITH CEDILLA
{ '\u013D', "L" }, // LATIN CAPITAL LETTER L WITH CARON
{ '\u013E', "l" }, // LATIN SMALL LETTER L WITH CARON
{ '\u013F', "L" }, // LATIN CAPITAL LETTER L WITH MIDDLE DOT
{ '\u0140', "l" }, // LATIN SMALL LETTER L WITH MIDDLE DOT
{ '\u0141', "L" }, // LATIN CAPITAL LETTER L WITH STROKE -- no decomposition
{ '\u0142', "l" }, // LATIN SMALL LETTER L WITH STROKE -- no decomposition
{ '\u0143', "N" }, // LATIN CAPITAL LETTER N WITH ACUTE
{ '\u0144', "n" }, // LATIN SMALL LETTER N WITH ACUTE
{ '\u0145', "N" }, // LATIN CAPITAL LETTER N WITH CEDILLA
{ '\u0146', "n" }, // LATIN SMALL LETTER N WITH CEDILLA
{ '\u0147', "N" }, // LATIN CAPITAL LETTER N WITH CARON
{ '\u0148', "n" }, // LATIN SMALL LETTER N WITH CARON
{ '\u0149', "'n" }, // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
{ '\u014A', "NG" }, // LATIN CAPITAL LETTER ENG -- no decomposition
{ '\u014B', "ng" }, // LATIN SMALL LETTER ENG -- no decomposition
{ '\u014C', "O" }, // LATIN CAPITAL LETTER O WITH MACRON
{ '\u014D', "o" }, // LATIN SMALL LETTER O WITH MACRON
{ '\u014E', "O" }, // LATIN CAPITAL LETTER O WITH BREVE
{ '\u014F', "o" }, // LATIN SMALL LETTER O WITH BREVE
{ '\u0150', "O" }, // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
{ '\u0151', "o" }, // LATIN SMALL LETTER O WITH DOUBLE ACUTE
{ '\u0152', "OE" }, // LATIN CAPITAL LIGATURE OE -- no decomposition
{ '\u0153', "oe" }, // LATIN SMALL LIGATURE OE -- no decomposition
{ '\u0154', "R" }, // LATIN CAPITAL LETTER R WITH ACUTE
{ '\u0155', "r" }, // LATIN SMALL LETTER R WITH ACUTE
{ '\u0156', "R" }, // LATIN CAPITAL LETTER R WITH CEDILLA
{ '\u0157', "r" }, // LATIN SMALL LETTER R WITH CEDILLA
{ '\u0158', "R" }, // LATIN CAPITAL LETTER R WITH CARON
{ '\u0159', "r" }, // LATIN SMALL LETTER R WITH CARON
{ '\u015A', "S" }, // LATIN CAPITAL LETTER S WITH ACUTE
{ '\u015B', "s" }, // LATIN SMALL LETTER S WITH ACUTE
{ '\u015C', "S" }, // LATIN CAPITAL LETTER S WITH CIRCUMFLEX
{ '\u015D', "s" }, // LATIN SMALL LETTER S WITH CIRCUMFLEX
{ '\u015E', "S" }, // LATIN CAPITAL LETTER S WITH CEDILLA
{ '\u015F', "s" }, // LATIN SMALL LETTER S WITH CEDILLA
{ '\u0160', "S" }, // LATIN CAPITAL LETTER S WITH CARON
{ '\u0161', "s" }, // LATIN SMALL LETTER S WITH CARON
{ '\u0162', "T" }, // LATIN CAPITAL LETTER T WITH CEDILLA
{ '\u0163', "t" }, // LATIN SMALL LETTER T WITH CEDILLA
{ '\u0164', "T" }, // LATIN CAPITAL LETTER T WITH CARON
{ '\u0165', "t" }, // LATIN SMALL LETTER T WITH CARON
{ '\u0166', "T" }, // LATIN CAPITAL LETTER T WITH STROKE -- no decomposition
{ '\u0167', "t" }, // LATIN SMALL LETTER T WITH STROKE -- no decomposition
{ '\u0168', "U" }, // LATIN CAPITAL LETTER U WITH TILDE
{ '\u0169', "u" }, // LATIN SMALL LETTER U WITH TILDE
{ '\u016A', "U" }, // LATIN CAPITAL LETTER U WITH MACRON
{ '\u016B', "u" }, // LATIN SMALL LETTER U WITH MACRON
{ '\u016C', "U" }, // LATIN CAPITAL LETTER U WITH BREVE
{ '\u016D', "u" }, // LATIN SMALL LETTER U WITH BREVE
{ '\u016E', "U" }, // LATIN CAPITAL LETTER U WITH RING ABOVE
{ '\u016F', "u" }, // LATIN SMALL LETTER U WITH RING ABOVE
{ '\u0170', "U" }, // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
{ '\u0171', "u" }, // LATIN SMALL LETTER U WITH DOUBLE ACUTE
{ '\u0172', "U" }, // LATIN CAPITAL LETTER U WITH OGONEK
{ '\u0173', "u" }, // LATIN SMALL LETTER U WITH OGONEK
{ '\u0174', "W" }, // LATIN CAPITAL LETTER W WITH CIRCUMFLEX
{ '\u0175', "w" }, // LATIN SMALL LETTER W WITH CIRCUMFLEX
{ '\u0176', "Y" }, // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
{ '\u0177', "y" }, // LATIN SMALL LETTER Y WITH CIRCUMFLEX
{ '\u0178', "Y" }, // LATIN CAPITAL LETTER Y WITH DIAERESIS
{ '\u0179', "Z" }, // LATIN CAPITAL LETTER Z WITH ACUTE
{ '\u017A', "z" }, // LATIN SMALL LETTER Z WITH ACUTE
{ '\u017B', "Z" }, // LATIN CAPITAL LETTER Z WITH DOT ABOVE
{ '\u017C', "z" }, // LATIN SMALL LETTER Z WITH DOT ABOVE
{ '\u017D', "Z" }, // LATIN CAPITAL LETTER Z WITH CARON
{ '\u017E', "z" }, // LATIN SMALL LETTER Z WITH CARON
{ '\u017F', "s" }, // LATIN SMALL LETTER LONG S
{ '\u0180', "b" }, // LATIN SMALL LETTER B WITH STROKE -- no decomposition
{ '\u0181', "B" }, // LATIN CAPITAL LETTER B WITH HOOK -- no decomposition
{ '\u0182', "B" }, // LATIN CAPITAL LETTER B WITH TOPBAR -- no decomposition
{ '\u0183', "b" }, // LATIN SMALL LETTER B WITH TOPBAR -- no decomposition
{ '\u0184', "6" }, // LATIN CAPITAL LETTER TONE SIX -- no decomposition
{ '\u0185', "6" }, // LATIN SMALL LETTER TONE SIX -- no decomposition
{ '\u0186', "O" }, // LATIN CAPITAL LETTER OPEN O -- no decomposition
{ '\u0187', "C" }, // LATIN CAPITAL LETTER C WITH HOOK -- no decomposition
{ '\u0188', "c" }, // LATIN SMALL LETTER C WITH HOOK -- no decomposition
{ '\u0189', "D" }, // LATIN CAPITAL LETTER AFRICAN D -- no decomposition
{ '\u018A', "D" }, // LATIN CAPITAL LETTER D WITH HOOK -- no decomposition
{ '\u018B', "D" }, // LATIN CAPITAL LETTER D WITH TOPBAR -- no decomposition
{ '\u018C', "d" }, // LATIN SMALL LETTER D WITH TOPBAR -- no decomposition
{ '\u018D', "d" }, // LATIN SMALL LETTER TURNED DELTA -- no decomposition
{ '\u018E', "E" }, // LATIN CAPITAL LETTER REVERSED E -- no decomposition
{ '\u018F', "E" }, // LATIN CAPITAL LETTER SCHWA -- no decomposition
{ '\u0190', "E" }, // LATIN CAPITAL LETTER OPEN E -- no decomposition
{ '\u0191', "F" }, // LATIN CAPITAL LETTER F WITH HOOK -- no decomposition
{ '\u0192', "f" }, // LATIN SMALL LETTER F WITH HOOK -- no decomposition
{ '\u0193', "G" }, // LATIN CAPITAL LETTER G WITH HOOK -- no decomposition
{ '\u0194', "G" }, // LATIN CAPITAL LETTER GAMMA -- no decomposition
{ '\u0195', "hv" }, // LATIN SMALL LETTER HV -- no decomposition
{ '\u0196', "I" }, // LATIN CAPITAL LETTER IOTA -- no decomposition
{ '\u0197', "I" }, // LATIN CAPITAL LETTER I WITH STROKE -- no decomposition
{ '\u0198', "K" }, // LATIN CAPITAL LETTER K WITH HOOK -- no decomposition
{ '\u0199', "k" }, // LATIN SMALL LETTER K WITH HOOK -- no decomposition
{ '\u019A', "l" }, // LATIN SMALL LETTER L WITH BAR -- no decomposition
{ '\u019B', "l" }, // LATIN SMALL LETTER LAMBDA WITH STROKE -- no decomposition
{ '\u019C', "M" }, // LATIN CAPITAL LETTER TURNED M -- no decomposition
{ '\u019D', "N" }, // LATIN CAPITAL LETTER N WITH LEFT HOOK -- no decomposition
{ '\u019E', "n" }, // LATIN SMALL LETTER N WITH LONG RIGHT LEG -- no decomposition
{ '\u019F', "O" }, // LATIN CAPITAL LETTER O WITH MIDDLE TILDE -- no decomposition
{ '\u01A0', "O" }, // LATIN CAPITAL LETTER O WITH HORN
{ '\u01A1', "o" }, // LATIN SMALL LETTER O WITH HORN
{ '\u01A2', "OI" }, // LATIN CAPITAL LETTER OI -- no decomposition
{ '\u01A3', "oi" }, // LATIN SMALL LETTER OI -- no decomposition
{ '\u01A4', "P" }, // LATIN CAPITAL LETTER P WITH HOOK -- no decomposition
{ '\u01A5', "p" }, // LATIN SMALL LETTER P WITH HOOK -- no decomposition
{ '\u01A6', "YR" }, // LATIN LETTER YR -- no decomposition
{ '\u01A7', "2" }, // LATIN CAPITAL LETTER TONE TWO -- no decomposition
{ '\u01A8', "2" }, // LATIN SMALL LETTER TONE TWO -- no decomposition
{ '\u01A9', "S" }, // LATIN CAPITAL LETTER ESH -- no decomposition
{ '\u01AA', "s" }, // LATIN LETTER REVERSED ESH LOOP -- no decomposition
{ '\u01AB', "t" }, // LATIN SMALL LETTER T WITH PALATAL HOOK -- no decomposition
{ '\u01AC', "T" }, // LATIN CAPITAL LETTER T WITH HOOK -- no decomposition
{ '\u01AD', "t" }, // LATIN SMALL LETTER T WITH HOOK -- no decomposition
{ '\u01AE', "T" }, // LATIN CAPITAL LETTER T WITH RETROFLEX HOOK -- no decomposition
{ '\u01AF', "U" }, // LATIN CAPITAL LETTER U WITH HORN
{ '\u01B0', "u" }, // LATIN SMALL LETTER U WITH HORN
{ '\u01B1', "u" }, // LATIN CAPITAL LETTER UPSILON -- no decomposition
{ '\u01B2', "V" }, // LATIN CAPITAL LETTER V WITH HOOK -- no decomposition
{ '\u01B3', "Y" }, // LATIN CAPITAL LETTER Y WITH HOOK -- no decomposition
{ '\u01B4', "y" }, // LATIN SMALL LETTER Y WITH HOOK -- no decomposition
{ '\u01B5', "Z" }, // LATIN CAPITAL LETTER Z WITH STROKE -- no decomposition
{ '\u01B6', "z" }, // LATIN SMALL LETTER Z WITH STROKE -- no decomposition
{ '\u01B7', "Z" }, // LATIN CAPITAL LETTER EZH -- no decomposition
{ '\u01B8', "Z" }, // LATIN CAPITAL LETTER EZH REVERSED -- no decomposition
{ '\u01B9', "Z" }, // LATIN SMALL LETTER EZH REVERSED -- no decomposition
{ '\u01BA', "z" }, // LATIN SMALL LETTER EZH WITH TAIL -- no decomposition
{ '\u01BB', "2" }, // LATIN LETTER TWO WITH STROKE -- no decomposition
{ '\u01BC', "5" }, // LATIN CAPITAL LETTER TONE FIVE -- no decomposition
{ '\u01BD', "5" }, // LATIN SMALL LETTER TONE FIVE -- no decomposition
{ '\u01BF', "w" }, // LATIN LETTER WYNN -- no decomposition
{ '\u01C0', "!" }, // LATIN LETTER DENTAL CLICK -- no decomposition
{ '\u01C1', "!" }, // LATIN LETTER LATERAL CLICK -- no decomposition
{ '\u01C2', "!" }, // LATIN LETTER ALVEOLAR CLICK -- no decomposition
{ '\u01C3', "!" }, // LATIN LETTER RETROFLEX CLICK -- no decomposition
{ '\u01C4', "DZ" }, // LATIN CAPITAL LETTER DZ WITH CARON
{ '\u01C5', "DZ" }, // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
{ '\u01C6', "d" }, // LATIN SMALL LETTER DZ WITH CARON
{ '\u01C7', "Lj" }, // LATIN CAPITAL LETTER LJ
{ '\u01C8', "Lj" }, // LATIN CAPITAL LETTER L WITH SMALL LETTER J
{ '\u01C9', "lj" }, // LATIN SMALL LETTER LJ
{ '\u01CA', "NJ" }, // LATIN CAPITAL LETTER NJ
{ '\u01CB', "NJ" }, // LATIN CAPITAL LETTER N WITH SMALL LETTER J
{ '\u01CC', "nj" }, // LATIN SMALL LETTER NJ
{ '\u01CD', "A" }, // LATIN CAPITAL LETTER A WITH CARON
{ '\u01CE', "a" }, // LATIN SMALL LETTER A WITH CARON
{ '\u01CF', "I" }, // LATIN CAPITAL LETTER I WITH CARON
{ '\u01D0', "i" }, // LATIN SMALL LETTER I WITH CARON
{ '\u01D1', "O" }, // LATIN CAPITAL LETTER O WITH CARON
{ '\u01D2', "o" }, // LATIN SMALL LETTER O WITH CARON
{ '\u01D3', "U" }, // LATIN CAPITAL LETTER U WITH CARON
{ '\u01D4', "u" }, // LATIN SMALL LETTER U WITH CARON
{ '\u01D5', "U" }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
{ '\u01D6', "u" }, // LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
{ '\u01D7', "U" }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
{ '\u01D8', "u" }, // LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
{ '\u01D9', "U" }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
{ '\u01DA', "u" }, // LATIN SMALL LETTER U WITH DIAERESIS AND CARON
{ '\u01DB', "U" }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
{ '\u01DC', "u" }, // LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
{ '\u01DD', "e" }, // LATIN SMALL LETTER TURNED E -- no decomposition
{ '\u01DE', "A" }, // LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
{ '\u01DF', "a" }, // LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
{ '\u01E0', "A" }, // LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
{ '\u01E1', "a" }, // LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
{ '\u01E2', "AE" },// LATIN CAPITAL LETTER AE WITH MACRON
{ '\u01E3', "ae" },// LATIN SMALL LETTER AE WITH MACRON
{ '\u01E4', "G" }, // LATIN CAPITAL LETTER G WITH STROKE -- no decomposition
{ '\u01E5', "g" }, // LATIN SMALL LETTER G WITH STROKE -- no decomposition
{ '\u01E6', "G" }, // LATIN CAPITAL LETTER G WITH CARON
{ '\u01E7', "g" }, // LATIN SMALL LETTER G WITH CARON
{ '\u01E8', "K" }, // LATIN CAPITAL LETTER K WITH CARON
{ '\u01E9', "k" }, // LATIN SMALL LETTER K WITH CARON
{ '\u01EA', "O" }, // LATIN CAPITAL LETTER O WITH OGONEK
{ '\u01EB', "o" }, // LATIN SMALL LETTER O WITH OGONEK
{ '\u01EC', "O" }, // LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
{ '\u01ED', "o" }, // LATIN SMALL LETTER O WITH OGONEK AND MACRON
{ '\u01EE', "Z" }, // LATIN CAPITAL LETTER EZH WITH CARON
{ '\u01EF', "Z" }, // LATIN SMALL LETTER EZH WITH CARON
{ '\u01F0', "j" }, // LATIN SMALL LETTER J WITH CARON
{ '\u01F1', "DZ" }, // LATIN CAPITAL LETTER DZ
{ '\u01F2', "DZ" }, // LATIN CAPITAL LETTER D WITH SMALL LETTER Z
{ '\u01F3', "dz" }, // LATIN SMALL LETTER DZ
{ '\u01F4', "G" }, // LATIN CAPITAL LETTER G WITH ACUTE
{ '\u01F5', "g" }, // LATIN SMALL LETTER G WITH ACUTE
{ '\u01F6', "hv" }, // LATIN CAPITAL LETTER HWAIR -- no decomposition
{ '\u01F7', "w" }, // LATIN CAPITAL LETTER WYNN -- no decomposition
{ '\u01F8', "N" }, // LATIN CAPITAL LETTER N WITH GRAVE
{ '\u01F9', "n" }, // LATIN SMALL LETTER N WITH GRAVE
{ '\u01FA', "A" }, // LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
{ '\u01FB', "a" }, // LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
{ '\u01FC', "AE" }, // LATIN CAPITAL LETTER AE WITH ACUTE
{ '\u01FD', "ae" }, // LATIN SMALL LETTER AE WITH ACUTE
{ '\u01FE', "O" }, // LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
{ '\u01FF', "o" }, // LATIN SMALL LETTER O WITH STROKE AND ACUTE
{ '\u0200', "A" }, // LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
{ '\u0201', "a" }, // LATIN SMALL LETTER A WITH DOUBLE GRAVE
{ '\u0202', "A" }, // LATIN CAPITAL LETTER A WITH INVERTED BREVE
{ '\u0203', "a" }, // LATIN SMALL LETTER A WITH INVERTED BREVE
{ '\u0204', "E" }, // LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
{ '\u0205', "e" }, // LATIN SMALL LETTER E WITH DOUBLE GRAVE
{ '\u0206', "E" }, // LATIN CAPITAL LETTER E WITH INVERTED BREVE
{ '\u0207', "e" }, // LATIN SMALL LETTER E WITH INVERTED BREVE
{ '\u0208', "I" }, // LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
{ '\u0209', "i" }, // LATIN SMALL LETTER I WITH DOUBLE GRAVE
{ '\u020A', "I" }, // LATIN CAPITAL LETTER I WITH INVERTED BREVE
{ '\u020B', "i" }, // LATIN SMALL LETTER I WITH INVERTED BREVE
{ '\u020C', "O" }, // LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
{ '\u020D', "o" }, // LATIN SMALL LETTER O WITH DOUBLE GRAVE
{ '\u020E', "O" }, // LATIN CAPITAL LETTER O WITH INVERTED BREVE
{ '\u020F', "o" }, // LATIN SMALL LETTER O WITH INVERTED BREVE
{ '\u0210', "R" }, // LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
{ '\u0211', "r" }, // LATIN SMALL LETTER R WITH DOUBLE GRAVE
{ '\u0212', "R" }, // LATIN CAPITAL LETTER R WITH INVERTED BREVE
{ '\u0213', "r" }, // LATIN SMALL LETTER R WITH INVERTED BREVE
{ '\u0214', "U" }, // LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
{ '\u0215', "u" }, // LATIN SMALL LETTER U WITH DOUBLE GRAVE
{ '\u0216', "U" }, // LATIN CAPITAL LETTER U WITH INVERTED BREVE
{ '\u0217', "u" }, // LATIN SMALL LETTER U WITH INVERTED BREVE
{ '\u0218', "S" }, // LATIN CAPITAL LETTER S WITH COMMA BELOW
{ '\u0219', "s" }, // LATIN SMALL LETTER S WITH COMMA BELOW
{ '\u021A', "T" }, // LATIN CAPITAL LETTER T WITH COMMA BELOW
{ '\u021B', "t" }, // LATIN SMALL LETTER T WITH COMMA BELOW
{ '\u021C', "Z" }, // LATIN CAPITAL LETTER YOGH -- no decomposition
{ '\u021D', "z" }, // LATIN SMALL LETTER YOGH -- no decomposition
{ '\u021E', "H" }, // LATIN CAPITAL LETTER H WITH CARON
{ '\u021F', "h" }, // LATIN SMALL LETTER H WITH CARON
{ '\u0220', "N" }, // LATIN CAPITAL LETTER N WITH LONG RIGHT LEG -- no decomposition
{ '\u0221', "d" }, // LATIN SMALL LETTER D WITH CURL -- no decomposition
{ '\u0222', "OU" }, // LATIN CAPITAL LETTER OU -- no decomposition
{ '\u0223', "ou" }, // LATIN SMALL LETTER OU -- no decomposition
{ '\u0224', "Z" }, // LATIN CAPITAL LETTER Z WITH HOOK -- no decomposition
{ '\u0225', "z" }, // LATIN SMALL LETTER Z WITH HOOK -- no decomposition
{ '\u0226', "A" }, // LATIN CAPITAL LETTER A WITH DOT ABOVE
{ '\u0227', "a" }, // LATIN SMALL LETTER A WITH DOT ABOVE
{ '\u0228', "E" }, // LATIN CAPITAL LETTER E WITH CEDILLA
{ '\u0229', "e" }, // LATIN SMALL LETTER E WITH CEDILLA
{ '\u022A', "O" }, // LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
{ '\u022B', "o" }, // LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
{ '\u022C', "O" }, // LATIN CAPITAL LETTER O WITH TILDE AND MACRON
{ '\u022D', "o" }, // LATIN SMALL LETTER O WITH TILDE AND MACRON
{ '\u022E', "O" }, // LATIN CAPITAL LETTER O WITH DOT ABOVE
{ '\u022F', "o" }, // LATIN SMALL LETTER O WITH DOT ABOVE
{ '\u0230', "O" }, // LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
{ '\u0231', "o" }, // LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
{ '\u0232', "Y" }, // LATIN CAPITAL LETTER Y WITH MACRON
{ '\u0233', "y" }, // LATIN SMALL LETTER Y WITH MACRON
{ '\u0234', "l" }, // LATIN SMALL LETTER L WITH CURL -- no decomposition
{ '\u0235', "n" }, // LATIN SMALL LETTER N WITH CURL -- no decomposition
{ '\u0236', "t" }, // LATIN SMALL LETTER T WITH CURL -- no decomposition
{ '\u0250', "a" }, // LATIN SMALL LETTER TURNED A -- no decomposition
{ '\u0251', "a" }, // LATIN SMALL LETTER ALPHA -- no decomposition
{ '\u0252', "a" }, // LATIN SMALL LETTER TURNED ALPHA -- no decomposition
{ '\u0253', "b" }, // LATIN SMALL LETTER B WITH HOOK -- no decomposition
{ '\u0254', "o" }, // LATIN SMALL LETTER OPEN O -- no decomposition
{ '\u0255', "c" }, // LATIN SMALL LETTER C WITH CURL -- no decomposition
{ '\u0256', "d" }, // LATIN SMALL LETTER D WITH TAIL -- no decomposition
{ '\u0257', "d" }, // LATIN SMALL LETTER D WITH HOOK -- no decomposition
{ '\u0258', "e" }, // LATIN SMALL LETTER REVERSED E -- no decomposition
{ '\u0259', "e" }, // LATIN SMALL LETTER SCHWA -- no decomposition
{ '\u025A', "e" }, // LATIN SMALL LETTER SCHWA WITH HOOK -- no decomposition
{ '\u025B', "e" }, // LATIN SMALL LETTER OPEN E -- no decomposition
{ '\u025C', "e" }, // LATIN SMALL LETTER REVERSED OPEN E -- no decomposition
{ '\u025D', "e" }, // LATIN SMALL LETTER REVERSED OPEN E WITH HOOK -- no decomposition
{ '\u025E', "e" }, // LATIN SMALL LETTER CLOSED REVERSED OPEN E -- no decomposition
{ '\u025F', "j" }, // LATIN SMALL LETTER DOTLESS J WITH STROKE -- no decomposition
{ '\u0260', "g" }, // LATIN SMALL LETTER G WITH HOOK -- no decomposition
{ '\u0261', "g" }, // LATIN SMALL LETTER SCRIPT G -- no decomposition
{ '\u0262', "G" }, // LATIN LETTER SMALL CAPITAL G -- no decomposition
{ '\u0263', "g" }, // LATIN SMALL LETTER GAMMA -- no decomposition
{ '\u0264', "y" }, // LATIN SMALL LETTER RAMS HORN -- no decomposition
{ '\u0265', "h" }, // LATIN SMALL LETTER TURNED H -- no decomposition
{ '\u0266', "h" }, // LATIN SMALL LETTER H WITH HOOK -- no decomposition
{ '\u0267', "h" }, // LATIN SMALL LETTER HENG WITH HOOK -- no decomposition
{ '\u0268', "i" }, // LATIN SMALL LETTER I WITH STROKE -- no decomposition
{ '\u0269', "i" }, // LATIN SMALL LETTER IOTA -- no decomposition
{ '\u026A', "I" }, // LATIN LETTER SMALL CAPITAL I -- no decomposition
{ '\u026B', "l" }, // LATIN SMALL LETTER L WITH MIDDLE TILDE -- no decomposition
{ '\u026C', "l" }, // LATIN SMALL LETTER L WITH BELT -- no decomposition
{ '\u026D', "l" }, // LATIN SMALL LETTER L WITH RETROFLEX HOOK -- no decomposition
{ '\u026E', "lz" }, // LATIN SMALL LETTER LEZH -- no decomposition
{ '\u026F', "m" }, // LATIN SMALL LETTER TURNED M -- no decomposition
{ '\u0270', "m" }, // LATIN SMALL LETTER TURNED M WITH LONG LEG -- no decomposition
{ '\u0271', "m" }, // LATIN SMALL LETTER M WITH HOOK -- no decomposition
{ '\u0272', "n" }, // LATIN SMALL LETTER N WITH LEFT HOOK -- no decomposition
{ '\u0273', "n" }, // LATIN SMALL LETTER N WITH RETROFLEX HOOK -- no decomposition
{ '\u0274', "N" }, // LATIN LETTER SMALL CAPITAL N -- no decomposition
{ '\u0275', "o" }, // LATIN SMALL LETTER BARRED O -- no decomposition
{ '\u0276', "OE" }, // LATIN LETTER SMALL CAPITAL OE -- no decomposition
{ '\u0277', "o" }, // LATIN SMALL LETTER CLOSED OMEGA -- no decomposition
{ '\u0278', "ph" }, // LATIN SMALL LETTER PHI -- no decomposition
{ '\u0279', "r" }, // LATIN SMALL LETTER TURNED R -- no decomposition
{ '\u027A', "r" }, // LATIN SMALL LETTER TURNED R WITH LONG LEG -- no decomposition
{ '\u027B', "r" }, // LATIN SMALL LETTER TURNED R WITH HOOK -- no decomposition
{ '\u027C', "r" }, // LATIN SMALL LETTER R WITH LONG LEG -- no decomposition
{ '\u027D', "r" }, // LATIN SMALL LETTER R WITH TAIL -- no decomposition
{ '\u027E', "r" }, // LATIN SMALL LETTER R WITH FISHHOOK -- no decomposition
{ '\u027F', "r" }, // LATIN SMALL LETTER REVERSED R WITH FISHHOOK -- no decomposition
{ '\u0280', "R" }, // LATIN LETTER SMALL CAPITAL R -- no decomposition
{ '\u0281', "r" }, // LATIN LETTER SMALL CAPITAL INVERTED R -- no decomposition
{ '\u0282', "s" }, // LATIN SMALL LETTER S WITH HOOK -- no decomposition
{ '\u0283', "s" }, // LATIN SMALL LETTER ESH -- no decomposition
{ '\u0284', "j" }, // LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK -- no decomposition
{ '\u0285', "s" }, // LATIN SMALL LETTER SQUAT REVERSED ESH -- no decomposition
{ '\u0286', "s" }, // LATIN SMALL LETTER ESH WITH CURL -- no decomposition
{ '\u0287', "y" }, // LATIN SMALL LETTER TURNED T -- no decomposition
{ '\u0288', "t" }, // LATIN SMALL LETTER T WITH RETROFLEX HOOK -- no decomposition
{ '\u0289', "u" }, // LATIN SMALL LETTER U BAR -- no decomposition
{ '\u028A', "u" }, // LATIN SMALL LETTER UPSILON -- no decomposition
{ '\u028B', "u" }, // LATIN SMALL LETTER V WITH HOOK -- no decomposition
{ '\u028C', "v" }, // LATIN SMALL LETTER TURNED V -- no decomposition
{ '\u028D', "w" }, // LATIN SMALL LETTER TURNED W -- no decomposition
{ '\u028E', "y" }, // LATIN SMALL LETTER TURNED Y -- no decomposition
{ '\u028F', "Y" }, // LATIN LETTER SMALL CAPITAL Y -- no decomposition
{ '\u0290', "z" }, // LATIN SMALL LETTER Z WITH RETROFLEX HOOK -- no decomposition
{ '\u0291', "z" }, // LATIN SMALL LETTER Z WITH CURL -- no decomposition
{ '\u0292', "z" }, // LATIN SMALL LETTER EZH -- no decomposition
{ '\u0293', "z" }, // LATIN SMALL LETTER EZH WITH CURL -- no decomposition
{ '\u0294', "'" }, // LATIN LETTER GLOTTAL STOP -- no decomposition
{ '\u0295', "'" }, // LATIN LETTER PHARYNGEAL VOICED FRICATIVE -- no decomposition
{ '\u0296', "'" }, // LATIN LETTER INVERTED GLOTTAL STOP -- no decomposition
{ '\u0297', "C" }, // LATIN LETTER STRETCHED C -- no decomposition
{ '\u0299', "B" }, // LATIN LETTER SMALL CAPITAL B -- no decomposition
{ '\u029A', "e" }, // LATIN SMALL LETTER CLOSED OPEN E -- no decomposition
{ '\u029B', "G" }, // LATIN LETTER SMALL CAPITAL G WITH HOOK -- no decomposition
{ '\u029C', "H" }, // LATIN LETTER SMALL CAPITAL H -- no decomposition
{ '\u029D', "j" }, // LATIN SMALL LETTER J WITH CROSSED-TAIL -- no decomposition
{ '\u029E', "k" }, // LATIN SMALL LETTER TURNED K -- no decomposition
{ '\u029F', "L" }, // LATIN LETTER SMALL CAPITAL L -- no decomposition
{ '\u02A0', "q" }, // LATIN SMALL LETTER Q WITH HOOK -- no decomposition
{ '\u02A1', "'" }, // LATIN LETTER GLOTTAL STOP WITH STROKE -- no decomposition
{ '\u02A2', "'" }, // LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE -- no decomposition
{ '\u02A3', "dz" }, // LATIN SMALL LETTER DZ DIGRAPH -- no decomposition
{ '\u02A4', "dz" }, // LATIN SMALL LETTER DEZH DIGRAPH -- no decomposition
{ '\u02A5', "dz" }, // LATIN SMALL LETTER DZ DIGRAPH WITH CURL -- no decomposition
{ '\u02A6', "ts" }, // LATIN SMALL LETTER TS DIGRAPH -- no decomposition
{ '\u02A7', "ts" }, // LATIN SMALL LETTER TESH DIGRAPH -- no decomposition
{ '\u02A8', string.Empty }, // LATIN SMALL LETTER TC DIGRAPH WITH CURL -- no decomposition
{ '\u02A9', "fn" }, // LATIN SMALL LETTER FENG DIGRAPH -- no decomposition
{ '\u02AA', "ls" }, // LATIN SMALL LETTER LS DIGRAPH -- no decomposition
{ '\u02AB', "lz" }, // LATIN SMALL LETTER LZ DIGRAPH -- no decomposition
{ '\u02AC', "w" }, // LATIN LETTER BILABIAL PERCUSSIVE -- no decomposition
{ '\u02AD', "t" }, // LATIN LETTER BIDENTAL PERCUSSIVE -- no decomposition
{ '\u02AE', "h" }, // LATIN SMALL LETTER TURNED H WITH FISHHOOK -- no decomposition
{ '\u02AF', "h" }, // LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL -- no decomposition
{ '\u02B0', "h" }, // MODIFIER LETTER SMALL H
{ '\u02B1', "h" }, // MODIFIER LETTER SMALL H WITH HOOK
{ '\u02B2', "j" }, // MODIFIER LETTER SMALL J
{ '\u02B3', "r" }, // MODIFIER LETTER SMALL R
{ '\u02B4', "r" }, // MODIFIER LETTER SMALL TURNED R
{ '\u02B5', "r" }, // MODIFIER LETTER SMALL TURNED R WITH HOOK
{ '\u02B6', "R" }, // MODIFIER LETTER SMALL CAPITAL INVERTED R
{ '\u02B7', "w" }, // MODIFIER LETTER SMALL W
{ '\u02B8', "y" }, // MODIFIER LETTER SMALL Y
{ '\u02E1', "l" }, // MODIFIER LETTER SMALL L
{ '\u02E2', "s" }, // MODIFIER LETTER SMALL S
{ '\u02E3', "x" }, // MODIFIER LETTER SMALL X
{ '\u02E4', "'" }, // MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
{ '\u1D00', "A" }, // LATIN LETTER SMALL CAPITAL A -- no decomposition
{ '\u1D01', "AE" }, // LATIN LETTER SMALL CAPITAL AE -- no decomposition
{ '\u1D02', "ae" }, // LATIN SMALL LETTER TURNED AE -- no decomposition
{ '\u1D03', "B" }, // LATIN LETTER SMALL CAPITAL BARRED B -- no decomposition
{ '\u1D04', "C" }, // LATIN LETTER SMALL CAPITAL C -- no decomposition
{ '\u1D05', "D" }, // LATIN LETTER SMALL CAPITAL D -- no decomposition
{ '\u1D06', "TH" }, // LATIN LETTER SMALL CAPITAL ETH -- no decomposition
{ '\u1D07', "E" }, // LATIN LETTER SMALL CAPITAL E -- no decomposition
{ '\u1D08', "e" }, // LATIN SMALL LETTER TURNED OPEN E -- no decomposition
{ '\u1D09', "i" }, // LATIN SMALL LETTER TURNED I -- no decomposition
{ '\u1D0A', "J" }, // LATIN LETTER SMALL CAPITAL J -- no decomposition
{ '\u1D0B', "K" }, // LATIN LETTER SMALL CAPITAL K -- no decomposition
{ '\u1D0C', "L" }, // LATIN LETTER SMALL CAPITAL L WITH STROKE -- no decomposition
{ '\u1D0D', "M" }, // LATIN LETTER SMALL CAPITAL M -- no decomposition
{ '\u1D0E', "N" }, // LATIN LETTER SMALL CAPITAL REVERSED N -- no decomposition
{ '\u1D0F', "O" }, // LATIN LETTER SMALL CAPITAL O -- no decomposition
{ '\u1D10', "O" }, // LATIN LETTER SMALL CAPITAL OPEN O -- no decomposition
{ '\u1D11', "o" }, // LATIN SMALL LETTER SIDEWAYS O -- no decomposition
{ '\u1D12', "o" }, // LATIN SMALL LETTER SIDEWAYS OPEN O -- no decomposition
{ '\u1D13', "o" }, // LATIN SMALL LETTER SIDEWAYS O WITH STROKE -- no decomposition
{ '\u1D14', "oe" }, // LATIN SMALL LETTER TURNED OE -- no decomposition
{ '\u1D15', "ou" }, // LATIN LETTER SMALL CAPITAL OU -- no decomposition
{ '\u1D16', "o" }, // LATIN SMALL LETTER TOP HALF O -- no decomposition
{ '\u1D17', "o" }, // LATIN SMALL LETTER BOTTOM HALF O -- no decomposition
{ '\u1D18', "P" }, // LATIN LETTER SMALL CAPITAL P -- no decomposition
{ '\u1D19', "R" }, // LATIN LETTER SMALL CAPITAL REVERSED R -- no decomposition
{ '\u1D1A', "R" }, // LATIN LETTER SMALL CAPITAL TURNED R -- no decomposition
{ '\u1D1B', "T" }, // LATIN LETTER SMALL CAPITAL T -- no decomposition
{ '\u1D1C', "U" }, // LATIN LETTER SMALL CAPITAL U -- no decomposition
{ '\u1D1D', "u" }, // LATIN SMALL LETTER SIDEWAYS U -- no decomposition
{ '\u1D1E', "u" }, // LATIN SMALL LETTER SIDEWAYS DIAERESIZED U -- no decomposition
{ '\u1D1F', "m" }, // LATIN SMALL LETTER SIDEWAYS TURNED M -- no decomposition
{ '\u1D20', "V" }, // LATIN LETTER SMALL CAPITAL V -- no decomposition
{ '\u1D21', "W" }, // LATIN LETTER SMALL CAPITAL W -- no decomposition
{ '\u1D22', "Z" }, // LATIN LETTER SMALL CAPITAL Z -- no decomposition
{ '\u1D23', "EZH" }, // LATIN LETTER SMALL CAPITAL EZH -- no decomposition
{ '\u1D24', "'" }, // LATIN LETTER VOICED LARYNGEAL SPIRANT -- no decomposition
{ '\u1D25', "L" }, // LATIN LETTER AIN -- no decomposition
{ '\u1D2C', "A" }, // MODIFIER LETTER CAPITAL A
{ '\u1D2D', "AE" }, // MODIFIER LETTER CAPITAL AE
{ '\u1D2E', "B" }, // MODIFIER LETTER CAPITAL B
{ '\u1D2F', "B" }, // MODIFIER LETTER CAPITAL BARRED B -- no decomposition
{ '\u1D30', "D" }, // MODIFIER LETTER CAPITAL D
{ '\u1D31', "E" }, // MODIFIER LETTER CAPITAL E
{ '\u1D32', "E" }, // MODIFIER LETTER CAPITAL REVERSED E
{ '\u1D33', "G" }, // MODIFIER LETTER CAPITAL G
{ '\u1D34', "H" }, // MODIFIER LETTER CAPITAL H
{ '\u1D35', "I" }, // MODIFIER LETTER CAPITAL I
{ '\u1D36', "J" }, // MODIFIER LETTER CAPITAL J
{ '\u1D37', "K" }, // MODIFIER LETTER CAPITAL K
{ '\u1D38', "L" }, // MODIFIER LETTER CAPITAL L
{ '\u1D39', "M" }, // MODIFIER LETTER CAPITAL M
{ '\u1D3A', "N" }, // MODIFIER LETTER CAPITAL N
{ '\u1D3B', "N" }, // MODIFIER LETTER CAPITAL REVERSED N -- no decomposition
{ '\u1D3C', "O" }, // MODIFIER LETTER CAPITAL O
{ '\u1D3D', "OU" }, // MODIFIER LETTER CAPITAL OU
{ '\u1D3E', "P" }, // MODIFIER LETTER CAPITAL P
{ '\u1D3F', "R" }, // MODIFIER LETTER CAPITAL R
{ '\u1D40', "T" }, // MODIFIER LETTER CAPITAL T
{ '\u1D41', "U" }, // MODIFIER LETTER CAPITAL U
{ '\u1D42', "W" }, // MODIFIER LETTER CAPITAL W
{ '\u1D43', "a" }, // MODIFIER LETTER SMALL A
{ '\u1D44', "a" }, // MODIFIER LETTER SMALL TURNED A
{ '\u1D46', "ae" }, // MODIFIER LETTER SMALL TURNED AE
{ '\u1D47', "b" }, // MODIFIER LETTER SMALL B
{ '\u1D48', "d" }, // MODIFIER LETTER SMALL D
{ '\u1D49', "e" }, // MODIFIER LETTER SMALL E
{ '\u1D4A', "e" }, // MODIFIER LETTER SMALL SCHWA
{ '\u1D4B', "e" }, // MODIFIER LETTER SMALL OPEN E
{ '\u1D4C', "e" }, // MODIFIER LETTER SMALL TURNED OPEN E
{ '\u1D4D', "g" }, // MODIFIER LETTER SMALL G
{ '\u1D4E', "i" }, // MODIFIER LETTER SMALL TURNED I -- no decomposition
{ '\u1D4F', "k" }, // MODIFIER LETTER SMALL K
{ '\u1D50', "m" }, // MODIFIER LETTER SMALL M
{ '\u1D51', "g" }, // MODIFIER LETTER SMALL ENG
{ '\u1D52', "o" }, // MODIFIER LETTER SMALL O
{ '\u1D53', "o" }, // MODIFIER LETTER SMALL OPEN O
{ '\u1D54', "o" }, // MODIFIER LETTER SMALL TOP HALF O
{ '\u1D55', "o" }, // MODIFIER LETTER SMALL BOTTOM HALF O
{ '\u1D56', "p" }, // MODIFIER LETTER SMALL P
{ '\u1D57', "t" }, // MODIFIER LETTER SMALL T
{ '\u1D58', "u" }, // MODIFIER LETTER SMALL U
{ '\u1D59', "u" }, // MODIFIER LETTER SMALL SIDEWAYS U
{ '\u1D5A', "m" }, // MODIFIER LETTER SMALL TURNED M
{ '\u1D5B', "v" }, // MODIFIER LETTER SMALL V
{ '\u1D62', "i" }, // LATIN SUBSCRIPT SMALL LETTER I
{ '\u1D63', "r" }, // LATIN SUBSCRIPT SMALL LETTER R
{ '\u1D64', "u" }, // LATIN SUBSCRIPT SMALL LETTER U
{ '\u1D65', "v" }, // LATIN SUBSCRIPT SMALL LETTER V
{ '\u1D6B', "ue" }, // LATIN SMALL LETTER UE -- no decomposition
{ '\u1E00', "A" }, // LATIN CAPITAL LETTER A WITH RING BELOW
{ '\u1E01', "a" }, // LATIN SMALL LETTER A WITH RING BELOW
{ '\u1E02', "B" }, // LATIN CAPITAL LETTER B WITH DOT ABOVE
{ '\u1E03', "b" }, // LATIN SMALL LETTER B WITH DOT ABOVE
{ '\u1E04', "B" }, // LATIN CAPITAL LETTER B WITH DOT BELOW
{ '\u1E05', "b" }, // LATIN SMALL LETTER B WITH DOT BELOW
{ '\u1E06', "B" }, // LATIN CAPITAL LETTER B WITH LINE BELOW
{ '\u1E07', "b" }, // LATIN SMALL LETTER B WITH LINE BELOW
{ '\u1E08', "C" }, // LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
{ '\u1E09', "c" }, // LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
{ '\u1E0A', "D" }, // LATIN CAPITAL LETTER D WITH DOT ABOVE
{ '\u1E0B', "d" }, // LATIN SMALL LETTER D WITH DOT ABOVE
{ '\u1E0C', "D" }, // LATIN CAPITAL LETTER D WITH DOT BELOW
{ '\u1E0D', "d" }, // LATIN SMALL LETTER D WITH DOT BELOW
{ '\u1E0E', "D" }, // LATIN CAPITAL LETTER D WITH LINE BELOW
{ '\u1E0F', "d" }, // LATIN SMALL LETTER D WITH LINE BELOW
{ '\u1E10', "D" }, // LATIN CAPITAL LETTER D WITH CEDILLA
{ '\u1E11', "d" }, // LATIN SMALL LETTER D WITH CEDILLA
{ '\u1E12', "D" }, // LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
{ '\u1E13', "d" }, // LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
{ '\u1E14', "E" }, // LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
{ '\u1E15', "e" }, // LATIN SMALL LETTER E WITH MACRON AND GRAVE
{ '\u1E16', "E" }, // LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
{ '\u1E17', "e" }, // LATIN SMALL LETTER E WITH MACRON AND ACUTE
{ '\u1E18', "E" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
{ '\u1E19', "e" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
{ '\u1E1A', "E" }, // LATIN CAPITAL LETTER E WITH TILDE BELOW
{ '\u1E1B', "e" }, // LATIN SMALL LETTER E WITH TILDE BELOW
{ '\u1E1C', "E" }, // LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
{ '\u1E1D', "e" }, // LATIN SMALL LETTER E WITH CEDILLA AND BREVE
{ '\u1E1E', "F" }, // LATIN CAPITAL LETTER F WITH DOT ABOVE
{ '\u1E1F', "f" }, // LATIN SMALL LETTER F WITH DOT ABOVE
{ '\u1E20', "G" }, // LATIN CAPITAL LETTER G WITH MACRON
{ '\u1E21', "g" }, // LATIN SMALL LETTER G WITH MACRON
{ '\u1E22', "H" }, // LATIN CAPITAL LETTER H WITH DOT ABOVE
{ '\u1E23', "h" }, // LATIN SMALL LETTER H WITH DOT ABOVE
{ '\u1E24', "H" }, // LATIN CAPITAL LETTER H WITH DOT BELOW
{ '\u1E25', "h" }, // LATIN SMALL LETTER H WITH DOT BELOW
{ '\u1E26', "H" }, // LATIN CAPITAL LETTER H WITH DIAERESIS
{ '\u1E27', "h" }, // LATIN SMALL LETTER H WITH DIAERESIS
{ '\u1E28', "H" }, // LATIN CAPITAL LETTER H WITH CEDILLA
{ '\u1E29', "h" }, // LATIN SMALL LETTER H WITH CEDILLA
{ '\u1E2A', "H" }, // LATIN CAPITAL LETTER H WITH BREVE BELOW
{ '\u1E2B', "h" }, // LATIN SMALL LETTER H WITH BREVE BELOW
{ '\u1E2C', "I" }, // LATIN CAPITAL LETTER I WITH TILDE BELOW
{ '\u1E2D', "i" }, // LATIN SMALL LETTER I WITH TILDE BELOW
{ '\u1E2E', "I" }, // LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
{ '\u1E2F', "i" }, // LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
{ '\u1E30', "K" }, // LATIN CAPITAL LETTER K WITH ACUTE
{ '\u1E31', "k" }, // LATIN SMALL LETTER K WITH ACUTE
{ '\u1E32', "K" }, // LATIN CAPITAL LETTER K WITH DOT BELOW
{ '\u1E33', "k" }, // LATIN SMALL LETTER K WITH DOT BELOW
{ '\u1E34', "K" }, // LATIN CAPITAL LETTER K WITH LINE BELOW
{ '\u1E35', "k" }, // LATIN SMALL LETTER K WITH LINE BELOW
{ '\u1E36', "L" }, // LATIN CAPITAL LETTER L WITH DOT BELOW
{ '\u1E37', "l" }, // LATIN SMALL LETTER L WITH DOT BELOW
{ '\u1E38', "L" }, // LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
{ '\u1E39', "l" }, // LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
{ '\u1E3A', "L" }, // LATIN CAPITAL LETTER L WITH LINE BELOW
{ '\u1E3B', "l" }, // LATIN SMALL LETTER L WITH LINE BELOW
{ '\u1E3C', "L" }, // LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
{ '\u1E3D', "l" }, // LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
{ '\u1E3E', "M" }, // LATIN CAPITAL LETTER M WITH ACUTE
{ '\u1E3F', "m" }, // LATIN SMALL LETTER M WITH ACUTE
{ '\u1E40', "M" }, // LATIN CAPITAL LETTER M WITH DOT ABOVE
{ '\u1E41', "m" }, // LATIN SMALL LETTER M WITH DOT ABOVE
{ '\u1E42', "M" }, // LATIN CAPITAL LETTER M WITH DOT BELOW
{ '\u1E43', "m" }, // LATIN SMALL LETTER M WITH DOT BELOW
{ '\u1E44', "N" }, // LATIN CAPITAL LETTER N WITH DOT ABOVE
{ '\u1E45', "n" }, // LATIN SMALL LETTER N WITH DOT ABOVE
{ '\u1E46', "N" }, // LATIN CAPITAL LETTER N WITH DOT BELOW
{ '\u1E47', "n" }, // LATIN SMALL LETTER N WITH DOT BELOW
{ '\u1E48', "N" }, // LATIN CAPITAL LETTER N WITH LINE BELOW
{ '\u1E49', "n" }, // LATIN SMALL LETTER N WITH LINE BELOW
{ '\u1E4A', "N" }, // LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
{ '\u1E4B', "n" }, // LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
{ '\u1E4C', "O" }, // LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
{ '\u1E4D', "o" }, // LATIN SMALL LETTER O WITH TILDE AND ACUTE
{ '\u1E4E', "O" }, // LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
{ '\u1E4F', "o" }, // LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
{ '\u1E50', "O" }, // LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
{ '\u1E51', "o" }, // LATIN SMALL LETTER O WITH MACRON AND GRAVE
{ '\u1E52', "O" }, // LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
{ '\u1E53', "o" }, // LATIN SMALL LETTER O WITH MACRON AND ACUTE
{ '\u1E54', "P" }, // LATIN CAPITAL LETTER P WITH ACUTE
{ '\u1E55', "p" }, // LATIN SMALL LETTER P WITH ACUTE
{ '\u1E56', "P" }, // LATIN CAPITAL LETTER P WITH DOT ABOVE
{ '\u1E57', "p" }, // LATIN SMALL LETTER P WITH DOT ABOVE
{ '\u1E58', "R" }, // LATIN CAPITAL LETTER R WITH DOT ABOVE
{ '\u1E59', "r" }, // LATIN SMALL LETTER R WITH DOT ABOVE
{ '\u1E5A', "R" }, // LATIN CAPITAL LETTER R WITH DOT BELOW
{ '\u1E5B', "r" }, // LATIN SMALL LETTER R WITH DOT BELOW
{ '\u1E5C', "R" }, // LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
{ '\u1E5D', "r" }, // LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
{ '\u1E5E', "R" }, // LATIN CAPITAL LETTER R WITH LINE BELOW
{ '\u1E5F', "r" }, // LATIN SMALL LETTER R WITH LINE BELOW
{ '\u1E60', "S" }, // LATIN CAPITAL LETTER S WITH DOT ABOVE
{ '\u1E61', "s" }, // LATIN SMALL LETTER S WITH DOT ABOVE
{ '\u1E62', "S" }, // LATIN CAPITAL LETTER S WITH DOT BELOW
{ '\u1E63', "s" }, // LATIN SMALL LETTER S WITH DOT BELOW
{ '\u1E64', "S" }, // LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
{ '\u1E65', "s" }, // LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
{ '\u1E66', "S" }, // LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
{ '\u1E67', "s" }, // LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
{ '\u1E68', "S" }, // LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
{ '\u1E69', "s" }, // LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
{ '\u1E6A', "T" }, // LATIN CAPITAL LETTER T WITH DOT ABOVE
{ '\u1E6B', "t" }, // LATIN SMALL LETTER T WITH DOT ABOVE
{ '\u1E6C', "T" }, // LATIN CAPITAL LETTER T WITH DOT BELOW
{ '\u1E6D', "t" }, // LATIN SMALL LETTER T WITH DOT BELOW
{ '\u1E6E', "T" }, // LATIN CAPITAL LETTER T WITH LINE BELOW
{ '\u1E6F', "t" }, // LATIN SMALL LETTER T WITH LINE BELOW
{ '\u1E70', "T" }, // LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
{ '\u1E71', "t" }, // LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
{ '\u1E72', "U" }, // LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
{ '\u1E73', "u" }, // LATIN SMALL LETTER U WITH DIAERESIS BELOW
{ '\u1E74', "U" }, // LATIN CAPITAL LETTER U WITH TILDE BELOW
{ '\u1E75', "u" }, // LATIN SMALL LETTER U WITH TILDE BELOW
{ '\u1E76', "U" }, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
{ '\u1E77', "u" }, // LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
{ '\u1E78', "U" }, // LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
{ '\u1E79', "u" }, // LATIN SMALL LETTER U WITH TILDE AND ACUTE
{ '\u1E7A', "U" }, // LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
{ '\u1E7B', "u" }, // LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
{ '\u1E7C', "V" }, // LATIN CAPITAL LETTER V WITH TILDE
{ '\u1E7D', "v" }, // LATIN SMALL LETTER V WITH TILDE
{ '\u1E7E', "V" }, // LATIN CAPITAL LETTER V WITH DOT BELOW
{ '\u1E7F', "v" }, // LATIN SMALL LETTER V WITH DOT BELOW
{ '\u1E80', "W" }, // LATIN CAPITAL LETTER W WITH GRAVE
{ '\u1E81', "w" }, // LATIN SMALL LETTER W WITH GRAVE
{ '\u1E82', "W" }, // LATIN CAPITAL LETTER W WITH ACUTE
{ '\u1E83', "w" }, // LATIN SMALL LETTER W WITH ACUTE
{ '\u1E84', "W" }, // LATIN CAPITAL LETTER W WITH DIAERESIS
{ '\u1E85', "w" }, // LATIN SMALL LETTER W WITH DIAERESIS
{ '\u1E86', "W" }, // LATIN CAPITAL LETTER W WITH DOT ABOVE
{ '\u1E87', "w" }, // LATIN SMALL LETTER W WITH DOT ABOVE
{ '\u1E88', "W" }, // LATIN CAPITAL LETTER W WITH DOT BELOW
{ '\u1E89', "w" }, // LATIN SMALL LETTER W WITH DOT BELOW
{ '\u1E8A', "X" }, // LATIN CAPITAL LETTER X WITH DOT ABOVE
{ '\u1E8B', "x" }, // LATIN SMALL LETTER X WITH DOT ABOVE
{ '\u1E8C', "X" }, // LATIN CAPITAL LETTER X WITH DIAERESIS
{ '\u1E8D', "x" }, // LATIN SMALL LETTER X WITH DIAERESIS
{ '\u1E8E', "Y" }, // LATIN CAPITAL LETTER Y WITH DOT ABOVE
{ '\u1E8F', "y" }, // LATIN SMALL LETTER Y WITH DOT ABOVE
{ '\u1E90', "Z" }, // LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
{ '\u1E91', "z" }, // LATIN SMALL LETTER Z WITH CIRCUMFLEX
{ '\u1E92', "Z" }, // LATIN CAPITAL LETTER Z WITH DOT BELOW
{ '\u1E93', "z" }, // LATIN SMALL LETTER Z WITH DOT BELOW
{ '\u1E94', "Z" }, // LATIN CAPITAL LETTER Z WITH LINE BELOW
{ '\u1E95', "z" }, // LATIN SMALL LETTER Z WITH LINE BELOW
{ '\u1E96', "h" }, // LATIN SMALL LETTER H WITH LINE BELOW
{ '\u1E97', "t" }, // LATIN SMALL LETTER T WITH DIAERESIS
{ '\u1E98', "w" }, // LATIN SMALL LETTER W WITH RING ABOVE
{ '\u1E99', "y" }, // LATIN SMALL LETTER Y WITH RING ABOVE
{ '\u1E9A', "a" }, // LATIN SMALL LETTER A WITH RIGHT HALF RING
{ '\u1E9B', "s" }, // LATIN SMALL LETTER LONG S WITH DOT ABOVE
{ '\u1EA0', "A" }, // LATIN CAPITAL LETTER A WITH DOT BELOW
{ '\u1EA1', "a" }, // LATIN SMALL LETTER A WITH DOT BELOW
{ '\u1EA2', "A" }, // LATIN CAPITAL LETTER A WITH HOOK ABOVE
{ '\u1EA3', "a" }, // LATIN SMALL LETTER A WITH HOOK ABOVE
{ '\u1EA4', "A" }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
{ '\u1EA5', "a" }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
{ '\u1EA6', "A" }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
{ '\u1EA7', "a" }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
{ '\u1EA8', "A" }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
{ '\u1EA9', "a" }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
{ '\u1EAA', "A" }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
{ '\u1EAB', "a" }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
{ '\u1EAC', "A" }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
{ '\u1EAD', "a" }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
{ '\u1EAE', "A" }, // LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
{ '\u1EAF', "a" }, // LATIN SMALL LETTER A WITH BREVE AND ACUTE
{ '\u1EB0', "A" }, // LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
{ '\u1EB1', "a" }, // LATIN SMALL LETTER A WITH BREVE AND GRAVE
{ '\u1EB2', "A" }, // LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
{ '\u1EB3', "a" }, // LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
{ '\u1EB4', "A" }, // LATIN CAPITAL LETTER A WITH BREVE AND TILDE
{ '\u1EB5', "a" }, // LATIN SMALL LETTER A WITH BREVE AND TILDE
{ '\u1EB6', "A" }, // LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
{ '\u1EB7', "a" }, // LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
{ '\u1EB8', "E" }, // LATIN CAPITAL LETTER E WITH DOT BELOW
{ '\u1EB9', "e" }, // LATIN SMALL LETTER E WITH DOT BELOW
{ '\u1EBA', "E" }, // LATIN CAPITAL LETTER E WITH HOOK ABOVE
{ '\u1EBB', "e" }, // LATIN SMALL LETTER E WITH HOOK ABOVE
{ '\u1EBC', "E" }, // LATIN CAPITAL LETTER E WITH TILDE
{ '\u1EBD', "e" }, // LATIN SMALL LETTER E WITH TILDE
{ '\u1EBE', "E" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
{ '\u1EBF', "e" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
{ '\u1EC0', "E" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
{ '\u1EC1', "e" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
{ '\u1EC2', "E" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
{ '\u1EC3', "e" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
{ '\u1EC4', "E" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
{ '\u1EC5', "e" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
{ '\u1EC6', "E" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
{ '\u1EC7', "e" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
{ '\u1EC8', "I" }, // LATIN CAPITAL LETTER I WITH HOOK ABOVE
{ '\u1EC9', "i" }, // LATIN SMALL LETTER I WITH HOOK ABOVE
{ '\u1ECA', "I" }, // LATIN CAPITAL LETTER I WITH DOT BELOW
{ '\u1ECB', "i" }, // LATIN SMALL LETTER I WITH DOT BELOW
{ '\u1ECC', "O" }, // LATIN CAPITAL LETTER O WITH DOT BELOW
{ '\u1ECD', "o" }, // LATIN SMALL LETTER O WITH DOT BELOW
{ '\u1ECE', "O" }, // LATIN CAPITAL LETTER O WITH HOOK ABOVE
{ '\u1ECF', "o" }, // LATIN SMALL LETTER O WITH HOOK ABOVE
{ '\u1ED0', "O" }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
{ '\u1ED1', "o" }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
{ '\u1ED2', "O" }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
{ '\u1ED3', "o" }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
{ '\u1ED4', "O" }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
{ '\u1ED5', "o" }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
{ '\u1ED6', "O" }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
{ '\u1ED7', "o" }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
{ '\u1ED8', "O" }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
{ '\u1ED9', "o" }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
{ '\u1EDA', "O" }, // LATIN CAPITAL LETTER O WITH HORN AND ACUTE
{ '\u1EDB', "o" }, // LATIN SMALL LETTER O WITH HORN AND ACUTE
{ '\u1EDC', "O" }, // LATIN CAPITAL LETTER O WITH HORN AND GRAVE
{ '\u1EDD', "o" }, // LATIN SMALL LETTER O WITH HORN AND GRAVE
{ '\u1EDE', "O" }, // LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
{ '\u1EDF', "o" }, // LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
{ '\u1EE0', "O" }, // LATIN CAPITAL LETTER O WITH HORN AND TILDE
{ '\u1EE1', "o" }, // LATIN SMALL LETTER O WITH HORN AND TILDE
{ '\u1EE2', "O" }, // LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
{ '\u1EE3', "o" }, // LATIN SMALL LETTER O WITH HORN AND DOT BELOW
{ '\u1EE4', "U" }, // LATIN CAPITAL LETTER U WITH DOT BELOW
{ '\u1EE5', "u" }, // LATIN SMALL LETTER U WITH DOT BELOW
{ '\u1EE6', "U" }, // LATIN CAPITAL LETTER U WITH HOOK ABOVE
{ '\u1EE7', "u" }, // LATIN SMALL LETTER U WITH HOOK ABOVE
{ '\u1EE8', "U" }, // LATIN CAPITAL LETTER U WITH HORN AND ACUTE
{ '\u1EE9', "u" }, // LATIN SMALL LETTER U WITH HORN AND ACUTE
{ '\u1EEA', "U" }, // LATIN CAPITAL LETTER U WITH HORN AND GRAVE
{ '\u1EEB', "u" }, // LATIN SMALL LETTER U WITH HORN AND GRAVE
{ '\u1EEC', "U" }, // LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
{ '\u1EED', "u" }, // LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
{ '\u1EEE', "U" }, // LATIN CAPITAL LETTER U WITH HORN AND TILDE
{ '\u1EEF', "u" }, // LATIN SMALL LETTER U WITH HORN AND TILDE
{ '\u1EF0', "U" }, // LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
{ '\u1EF1', "u" }, // LATIN SMALL LETTER U WITH HORN AND DOT BELOW
{ '\u1EF2', "Y" }, // LATIN CAPITAL LETTER Y WITH GRAVE
{ '\u1EF3', "y" }, // LATIN SMALL LETTER Y WITH GRAVE
{ '\u1EF4', "Y" }, // LATIN CAPITAL LETTER Y WITH DOT BELOW
{ '\u1EF5', "y" }, // LATIN SMALL LETTER Y WITH DOT BELOW
{ '\u1EF6', "Y" }, // LATIN CAPITAL LETTER Y WITH HOOK ABOVE
{ '\u1EF7', "y" }, // LATIN SMALL LETTER Y WITH HOOK ABOVE
{ '\u1EF8', "Y" }, // LATIN CAPITAL LETTER Y WITH TILDE
{ '\u1EF9', "y" }, // LATIN SMALL LETTER Y WITH TILDE
{ '\u2071', "i" }, // SUPERSCRIPT LATIN SMALL LETTER I
{ '\u207F', "n" }, // SUPERSCRIPT LATIN SMALL LETTER N
{ '\u212A', "K" }, // KELVIN SIGN
{ '\u212B', "A" }, // ANGSTROM SIGN
{ '\u212C', "B" }, // SCRIPT CAPITAL B
{ '\u212D', "C" }, // BLACK-LETTER CAPITAL C
{ '\u212F', "e" }, // SCRIPT SMALL E
{ '\u2130', "E" }, // SCRIPT CAPITAL E
{ '\u2131', "F" }, // SCRIPT CAPITAL F
{ '\u2132', "F" }, // TURNED CAPITAL F -- no decomposition
{ '\u2133', "M" }, // SCRIPT CAPITAL M
{ '\u2134', "0" }, // SCRIPT SMALL O
{ '\u213A', "0" }, // ROTATED CAPITAL Q -- no decomposition
{ '\u2141', "G" }, // TURNED SANS-SERIF CAPITAL G -- no decomposition
{ '\u2142', "L" }, // TURNED SANS-SERIF CAPITAL L -- no decomposition
{ '\u2143', "L" }, // REVERSED SANS-SERIF CAPITAL L -- no decomposition
{ '\u2144', "Y" }, // TURNED SANS-SERIF CAPITAL Y -- no decomposition
{ '\u2145', "D" }, // DOUBLE-STRUCK ITALIC CAPITAL D
{ '\u2146', "d" }, // DOUBLE-STRUCK ITALIC SMALL D
{ '\u2147', "e" }, // DOUBLE-STRUCK ITALIC SMALL E
{ '\u2148', "i" }, // DOUBLE-STRUCK ITALIC SMALL I
{ '\u2149', "j" }, // DOUBLE-STRUCK ITALIC SMALL J
{ '\uFB00', "ff" }, // LATIN SMALL LIGATURE FF
{ '\uFB01', "fi" }, // LATIN SMALL LIGATURE FI
{ '\uFB02', "fl" }, // LATIN SMALL LIGATURE FL
{ '\uFB03', "ffi" }, // LATIN SMALL LIGATURE FFI
{ '\uFB04', "ffl" }, // LATIN SMALL LIGATURE FFL
{ '\uFB05', "st" }, // LATIN SMALL LIGATURE LONG S T
{ '\uFB06', "st" }, // LATIN SMALL LIGATURE ST
{ '\uFF21', "A" }, // FULLWIDTH LATIN CAPITAL LETTER B
{ '\uFF22', "B" }, // FULLWIDTH LATIN CAPITAL LETTER B
{ '\uFF23', "C" }, // FULLWIDTH LATIN CAPITAL LETTER C
{ '\uFF24', "D" }, // FULLWIDTH LATIN CAPITAL LETTER D
{ '\uFF25', "E" }, // FULLWIDTH LATIN CAPITAL LETTER E
{ '\uFF26', "F" }, // FULLWIDTH LATIN CAPITAL LETTER F
{ '\uFF27', "G" }, // FULLWIDTH LATIN CAPITAL LETTER G
{ '\uFF28', "H" }, // FULLWIDTH LATIN CAPITAL LETTER H
{ '\uFF29', "I" }, // FULLWIDTH LATIN CAPITAL LETTER I
{ '\uFF2A', "J" }, // FULLWIDTH LATIN CAPITAL LETTER J
{ '\uFF2B', "K" }, // FULLWIDTH LATIN CAPITAL LETTER K
{ '\uFF2C', "L" }, // FULLWIDTH LATIN CAPITAL LETTER L
{ '\uFF2D', "M" }, // FULLWIDTH LATIN CAPITAL LETTER M
{ '\uFF2E', "N" }, // FULLWIDTH LATIN CAPITAL LETTER N
{ '\uFF2F', "O" }, // FULLWIDTH LATIN CAPITAL LETTER O
{ '\uFF30', "P" }, // FULLWIDTH LATIN CAPITAL LETTER P
{ '\uFF31', "Q" }, // FULLWIDTH LATIN CAPITAL LETTER Q
{ '\uFF32', "R" }, // FULLWIDTH LATIN CAPITAL LETTER R
{ '\uFF33', "S" }, // FULLWIDTH LATIN CAPITAL LETTER S
{ '\uFF34', "T" }, // FULLWIDTH LATIN CAPITAL LETTER T
{ '\uFF35', "U" }, // FULLWIDTH LATIN CAPITAL LETTER U
{ '\uFF36', "V" }, // FULLWIDTH LATIN CAPITAL LETTER V
{ '\uFF37', "W" }, // FULLWIDTH LATIN CAPITAL LETTER W
{ '\uFF38', "X" }, // FULLWIDTH LATIN CAPITAL LETTER X
{ '\uFF39', "Y" }, // FULLWIDTH LATIN CAPITAL LETTER Y
{ '\uFF3A', "Z" }, // FULLWIDTH LATIN CAPITAL LETTER Z
{ '\uFF41', "a" }, // FULLWIDTH LATIN SMALL LETTER A
{ '\uFF42', "b" }, // FULLWIDTH LATIN SMALL LETTER B
{ '\uFF43', "c" }, // FULLWIDTH LATIN SMALL LETTER C
{ '\uFF44', "d" }, // FULLWIDTH LATIN SMALL LETTER D
{ '\uFF45', "e" }, // FULLWIDTH LATIN SMALL LETTER E
{ '\uFF46', "f" }, // FULLWIDTH LATIN SMALL LETTER F
{ '\uFF47', "g" }, // FULLWIDTH LATIN SMALL LETTER G
{ '\uFF48', "h" }, // FULLWIDTH LATIN SMALL LETTER H
{ '\uFF49', "i" }, // FULLWIDTH LATIN SMALL LETTER I
{ '\uFF4A', "j" }, // FULLWIDTH LATIN SMALL LETTER J
{ '\uFF4B', "k" }, // FULLWIDTH LATIN SMALL LETTER K
{ '\uFF4C', "l" }, // FULLWIDTH LATIN SMALL LETTER L
{ '\uFF4D', "m" }, // FULLWIDTH LATIN SMALL LETTER M
{ '\uFF4E', "n" }, // FULLWIDTH LATIN SMALL LETTER N
{ '\uFF4F', "o" }, // FULLWIDTH LATIN SMALL LETTER O
{ '\uFF50', "p" }, // FULLWIDTH LATIN SMALL LETTER P
{ '\uFF51', "q" }, // FULLWIDTH LATIN SMALL LETTER Q
{ '\uFF52', "r" }, // FULLWIDTH LATIN SMALL LETTER R
{ '\uFF53', "s" }, // FULLWIDTH LATIN SMALL LETTER S
{ '\uFF54', "t" }, // FULLWIDTH LATIN SMALL LETTER T
{ '\uFF55', "u" }, // FULLWIDTH LATIN SMALL LETTER U
{ '\uFF56', "v" }, // FULLWIDTH LATIN SMALL LETTER V
{ '\uFF57', "w" }, // FULLWIDTH LATIN SMALL LETTER W
{ '\uFF58', "x" }, // FULLWIDTH LATIN SMALL LETTER X
{ '\uFF59', "y" }, // FULLWIDTH LATIN SMALL LETTER Y
{ '\uFF5A', "z" }, // FULLWIDTH LATIN SMALL LETTER Z
{ '\u0410', "A" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0411', "B" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0412', "V" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0413', "G" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0414', "D" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0415', "E" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0401', "YO" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0416', "ZH" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0417', "Z" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0418', "I" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0419', "J" }, // RUSSIAN CAPITAL LETTER ?
{ '\u041A', "K" }, // RUSSIAN CAPITAL LETTER ?
{ '\u041B', "L" }, // RUSSIAN CAPITAL LETTER ?
{ '\u041C', "M" }, // RUSSIAN CAPITAL LETTER ?
{ '\u041D', "N" }, // RUSSIAN CAPITAL LETTER ?
{ '\u041E', "O" }, // RUSSIAN CAPITAL LETTER ?
{ '\u041F', "P" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0420', "R" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0421', "S" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0422', "T" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0423', "U" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0424', "F" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0425', "H" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0426', "C" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0427', "CH" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0428', "SH" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0429', "SHH" }, // RUSSIAN CAPITAL LETTER ?
{ '\u042A', string.Empty }, // RUSSIAN CAPITAL LETTER ?
{ '\u042B', "Y" }, // RUSSIAN CAPITAL LETTER ?
{ '\u042C', string.Empty }, // RUSSIAN CAPITAL LETTER ?
{ '\u042D', "E" }, // RUSSIAN CAPITAL LETTER ?
{ '\u042E', "YU" }, // RUSSIAN CAPITAL LETTER ?
{ '\u042F', "YA" }, // RUSSIAN CAPITAL LETTER ?
{ '\u0430', "a" }, // RUSSIAN SMALL LETTER ?
{ '\u0431', "b" }, // RUSSIAN SMALL LETTER ?
{ '\u0432', "v" }, // RUSSIAN SMALL LETTER ?
{ '\u0433', "g" }, // RUSSIAN SMALL LETTER ?
{ '\u0434', "d" }, // RUSSIAN SMALL LETTER ?
{ '\u0435', "e" }, // RUSSIAN SMALL LETTER ?
{ '\u0451', "yo" }, // RUSSIAN SMALL LETTER ?
{ '\u0436', "zh" }, // RUSSIAN SMALL LETTER ?
{ '\u0437', "z" }, // RUSSIAN SMALL LETTER ?
{ '\u0438', "i" }, // RUSSIAN SMALL LETTER ?
{ '\u0439', "j" }, // RUSSIAN SMALL LETTER ?
{ '\u043A', "k" }, // RUSSIAN SMALL LETTER ?
{ '\u043B', "l" }, // RUSSIAN SMALL LETTER ?
{ '\u043C', "m" }, // RUSSIAN SMALL LETTER ?
{ '\u043D', "n" }, // RUSSIAN SMALL LETTER ?
{ '\u043E', "o" }, // RUSSIAN SMALL LETTER ?
{ '\u043F', "p" }, // RUSSIAN SMALL LETTER ?
{ '\u0440', "r" }, // RUSSIAN SMALL LETTER ?
{ '\u0441', "s" }, // RUSSIAN SMALL LETTER ?
{ '\u0442', "t" }, // RUSSIAN SMALL LETTER ?
{ '\u0443', "u" }, // RUSSIAN SMALL LETTER ?
{ '\u0444', "f" }, // RUSSIAN SMALL LETTER ?
{ '\u0445', "h" }, // RUSSIAN SMALL LETTER ?
{ '\u0446', "c" }, // RUSSIAN SMALL LETTER ?
{ '\u0447', "ch" }, // RUSSIAN SMALL LETTER ?
{ '\u0448', "sh" }, // RUSSIAN SMALL LETTER ?
{ '\u0449', "shh" }, // RUSSIAN SMALL LETTER ?
{ '\u044A', string.Empty }, // RUSSIAN SMALL LETTER ?
{ '\u044B', "y" }, // RUSSIAN SMALL LETTER ?
{ '\u044C', string.Empty }, // RUSSIAN SMALL LETTER ?
{ '\u044D', "e" }, // RUSSIAN SMALL LETTER ?
{ '\u044E', "yu" }, // RUSSIAN SMALL LETTER ?
{ '\u044F', "ya" }, // RUSSIAN SMALL LETTER ?
{ '\u0406', "I" }, // Ukraine-Belorussian CAPITAL LETTER ?
{ '\u0456', "i" }, // Ukraine-Belorussian SMALL LETTER ?
{ '\u0407', "I" }, // Ukraine CAPITAL LETTER ?
{ '\u0457', "i" }, // Ukraine SMALL LETTER ?
{ '\u0404', "Ie" }, // Ukraine CAPITAL LETTER ?
{ '\u0454', "ie" }, // Ukraine SMALL LETTER ?
{ '\u0490', "G" }, // Ukraine CAPITAL LETTER ?
{ '\u0491', "g" }, // Ukraine SMALL LETTER ?
{ '\u040E', "U" }, // Belorussian CAPITAL LETTER ?
{ '\u045E', "u" } // Belorussian SMALL LETTER ?
};
var sb = new StringBuilder();
foreach (var c in name.Trim().ToLowerInvariant())
if (seoCharacterTable.TryGetValue(c, out var transliteration))
sb.Append(transliteration.ToLowerInvariant());
else if (okChars.Contains(c))
sb.Append(c);
var seName = new Regex(@"[\s-]+").Replace(sb.ToString(), "-");
seName = new Regex("_+").Replace(seName, "_");
return seName;
}
///
/// Inserts a picture
///
/// Picture file name
/// Picture name to create the SE name
///
/// A task that represents the asynchronous operation
/// The task result contains the identifier of inserted picture
///
protected virtual async Task InsertPictureAsync(string fileName, string name)
{
var sampleImagesPath = _fileProvider.GetAbsolutePath(NopInstallationDefaults.SampleImagesPath);
var pictureBinary = await _fileProvider.ReadAllBytesAsync(_fileProvider.Combine(sampleImagesPath, fileName));
var seName = CommonHelper.EnsureMaximumLength(GetSeName(name), 100);
_fileExtensionContentTypeProvider ??= new FileExtensionContentTypeProvider();
if (!_fileExtensionContentTypeProvider.TryGetContentType(fileName, out var contentType))
contentType = MimeTypes.ImageJpeg;
var picture = new Picture
{
MimeType = contentType,
SeoFilename = seName,
AltAttribute = null,
TitleAttribute = null,
IsNew = true
};
await _dataProvider.InsertEntityAsync(picture);
await _dataProvider.InsertEntityAsync(new PictureBinary { PictureId = picture.Id, BinaryData = pictureBinary });
return picture.Id;
}
///
/// Installs a sample customers
///
/// Sample customers to install
///
/// A task that represents the asynchronous operation
///
protected virtual async Task InstallSampleCustomersAsync(List sampleCustomers)
{
var customerRoles = await Table().ToDictionaryAsync(cr => cr.SystemName, cr => cr);
//default store ID
var storeId = await GetDefaultStoreIdAsync();
(Customer Customer, SampleCustomer jsonModel) createCustomer((Address address, SampleCustomer jsonModel) data)
{
var address = data.address;
return (new Customer
{
CustomerGuid = Guid.NewGuid(),
Email = address.Email,
Username = address.Email,
Active = data.jsonModel.Active,
CreatedOnUtc = DateTime.UtcNow,
LastActivityDateUtc = DateTime.UtcNow,
RegisteredInStoreId = storeId,
BillingAddressId = address.Id,
ShippingAddressId = address.Id,
FirstName = address.FirstName,
LastName = address.LastName
}, data.jsonModel);
}
async Task<(Address Address, SampleCustomer jsonModel)> createAddress(SampleCustomer model)
{
return (await CreateAddressAsync(model), model);
}
var addresses = await sampleCustomers.SelectAwait(async c => await createAddress(c)).ToListAsync();
await _dataProvider.BulkInsertEntitiesAsync(addresses.Select(a => a.Address));
var customers = addresses.Select(createCustomer).ToList();
await _dataProvider.BulkInsertEntitiesAsync(customers.Select(c => c.Customer));
await _dataProvider.BulkInsertEntitiesAsync(customers.Select(c => new CustomerAddressMapping
{
CustomerId = c.Customer.Id,
AddressId = c.Customer.BillingAddressId ?? 0
}));
await _dataProvider.BulkInsertEntitiesAsync(customers.SelectMany(c => c.jsonModel.CustomerRoleSystemNames.Distinct().Select(role => new CustomerCustomerRoleMapping
{
CustomerId = c.Customer.Id,
CustomerRoleId = customerRoles[role].Id
})));
await _dataProvider.BulkInsertEntitiesAsync(customers.Select(c => new CustomerPassword
{
CustomerId = c.Customer.Id,
Password = c.jsonModel.Password,
PasswordFormat = c.jsonModel.PasswordFormat,
PasswordSalt = c.jsonModel.PasswordSalt,
CreatedOnUtc = DateTime.UtcNow
}));
}
///
/// Installs a sample checkout attributes
///
/// Sample checkout attributes to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallCheckoutAttributesAsync(List sampleCheckoutAttributes)
{
foreach (var jsonModel in sampleCheckoutAttributes)
{
var checkoutAttribute = await _dataProvider.InsertEntityAsync(new CheckoutAttribute
{
Name = jsonModel.Name,
IsRequired = jsonModel.IsRequired,
ShippableProductRequired = jsonModel.ShippableProductRequired,
AttributeControlType = jsonModel.AttributeControlType,
DisplayOrder = jsonModel.DisplayOrder
});
if (!jsonModel.AttributeValues.Any())
continue;
await _dataProvider.BulkInsertEntitiesAsync(jsonModel.AttributeValues.Select(sav =>
new CheckoutAttributeValue
{
Name = sav.Name,
PriceAdjustment = sav.PriceAdjustment,
DisplayOrder = sav.DisplayOrder,
IsPreSelected = sav.IsPreSelected,
AttributeId = checkoutAttribute.Id
}));
}
}
///
/// Installs a sample specification attributes
///
/// Sample specification attributes to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallSpecificationAttributesAsync(SampleSpecificationAttributes sampleSpecificationAttributes)
{
var attributes = sampleSpecificationAttributes.Attributes.ToDictionary(data => data,
data => new SpecificationAttribute { Name = data.Name, DisplayOrder = data.DisplayOrder });
foreach (var jsonModel in sampleSpecificationAttributes.AttributeGroups)
{
var specificationAttributeGroup = await _dataProvider.InsertEntityAsync(
new SpecificationAttributeGroup { Name = jsonModel.Name });
foreach (var data in jsonModel.Attributes)
attributes.Add(data, new SpecificationAttribute
{
Name = data.Name,
DisplayOrder = data.DisplayOrder,
SpecificationAttributeGroupId = specificationAttributeGroup.Id
});
}
await _dataProvider.BulkInsertEntitiesAsync(attributes.Values);
await _dataProvider.BulkInsertEntitiesAsync(attributes.SelectMany(data =>
data.Key.AttributeOptions.Select(o => new SpecificationAttributeOption
{
Name = o.Name,
DisplayOrder = o.DisplayOrder,
ColorSquaresRgb = o.ColorSquaresRgb,
SpecificationAttributeId = data.Value.Id
})));
}
///
/// Installs a sample product attributes
///
/// Sample product attributes to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallProductAttributesAsync(IList sampleProductAttributes)
{
await _dataProvider.BulkInsertEntitiesAsync(sampleProductAttributes.Select(p => new ProductAttribute
{
Name = p.Name
}));
}
///
/// Installs a sample categories
///
/// Sample categories to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallCategoriesAsync(IList sampleCategories)
{
var categoryTemplateInGridAndLines = await Table().FirstOrDefaultAsync(pt => pt.Name == "Products in Grid or Lines") ?? throw new Exception("Category template cannot be loaded");
async Task createCategory(SampleCategory sample, int parentCategoryId = 0)
{
var category = new Category
{
Name = sample.Name,
CategoryTemplateId = categoryTemplateInGridAndLines.Id,
PageSize = sample.PageSize,
AllowCustomersToSelectPageSize = sample.AllowCustomersToSelectPageSize,
PageSizeOptions = sample.PageSizeOptions,
ParentCategoryId = parentCategoryId,
PictureId = await InsertPictureAsync(sample.ImageFileName, sample.Name),
Published = sample.Published,
DisplayOrder = sample.DisplayOrder,
CreatedOnUtc = DateTime.UtcNow,
UpdatedOnUtc = DateTime.UtcNow,
ShowOnHomepage = sample.ShowOnHomepage
};
if (!sample.PriceRangeFiltering)
return category;
category.PriceRangeFiltering = true;
category.ManuallyPriceRange = sample.ManuallyPriceRange;
category.PriceFrom = sample.PriceFrom;
category.PriceTo = sample.PriceTo;
return category;
}
var allCategories = new List();
var categoryToInsert = new List();
async Task saveCategory(SampleCategory sampleCategory, int parentCategoryId = 0)
{
var category = await createCategory(sampleCategory, parentCategoryId);
allCategories.Add(category);
if (sampleCategory.SubCategories.Any())
{
await _dataProvider.InsertEntityAsync(category);
foreach (var subCategory in sampleCategory.SubCategories)
await saveCategory(subCategory, category.Id);
}
else
categoryToInsert.Add(category);
}
foreach (var sampleCategory in sampleCategories)
await saveCategory(sampleCategory);
await _dataProvider.BulkInsertEntitiesAsync(categoryToInsert);
//search engine names
await InsertSearchEngineNamesAsync(allCategories, category => category.Name);
}
///
/// Installs a sample manufacturers
///
/// Sample manufacturers to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallManufacturersAsync(IList sampleManufacturers)
{
var manufacturerTemplateInGridAndLines = await Table()
.FirstOrDefaultAsync(pt => pt.Name == "Products in Grid or Lines") ?? throw new Exception("Manufacturer template cannot be loaded");
async Task createManufacturer(SampleManufacturer sampleManufacturer)
{
var manufacturer = new Manufacturer
{
Name = sampleManufacturer.Name,
ManufacturerTemplateId = manufacturerTemplateInGridAndLines.Id,
PageSize = sampleManufacturer.PageSize,
AllowCustomersToSelectPageSize = sampleManufacturer.AllowCustomersToSelectPageSize,
PageSizeOptions = sampleManufacturer.PageSizeOptions,
Published = sampleManufacturer.Published,
PictureId = await InsertPictureAsync(sampleManufacturer.ImageFileName, sampleManufacturer.Name),
DisplayOrder = sampleManufacturer.DisplayOrder,
CreatedOnUtc = DateTime.UtcNow,
UpdatedOnUtc = DateTime.UtcNow
};
if (!sampleManufacturer.PriceRangeFiltering)
return manufacturer;
manufacturer.PriceRangeFiltering = true;
manufacturer.ManuallyPriceRange = sampleManufacturer.ManuallyPriceRange;
manufacturer.PriceFrom = sampleManufacturer.PriceFrom;
manufacturer.PriceTo = sampleManufacturer.PriceTo;
return manufacturer;
}
var allManufacturers = await sampleManufacturers.SelectAwait(async sample => await createManufacturer(sample)).ToListAsync();
await _dataProvider.BulkInsertEntitiesAsync(allManufacturers);
//search engine names
await InsertSearchEngineNamesAsync(allManufacturers, manufacturer => manufacturer.Name);
}
///
/// Installs a sample forums
///
/// Sample forum groups to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallForumsAsync(List sampleForumGroups)
{
foreach (var sampleForumGroup in sampleForumGroups)
{
var forumGroup = await _dataProvider.InsertEntityAsync(new ForumGroup
{
Name = sampleForumGroup.Name,
DisplayOrder = sampleForumGroup.DisplayOrder,
CreatedOnUtc = DateTime.UtcNow,
UpdatedOnUtc = DateTime.UtcNow
});
if (!sampleForumGroup.Forums.Any())
continue;
await _dataProvider.BulkInsertEntitiesAsync(sampleForumGroup.Forums.Select(sf => new Forum
{
ForumGroupId = forumGroup.Id,
Name = sf.Name,
Description = sf.Description,
NumTopics = 0,
NumPosts = 0,
LastPostCustomerId = 0,
LastPostTime = null,
DisplayOrder = sf.DisplayOrder,
CreatedOnUtc = DateTime.UtcNow,
UpdatedOnUtc = DateTime.UtcNow
}));
}
}
///
/// Installs a sample discounts
///
/// Sample discounts to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallDiscountsAsync(IList sampleDiscounts)
{
await _dataProvider.BulkInsertEntitiesAsync(sampleDiscounts.Select(sd => new Discount
{
IsActive = sd.IsActive,
Name = sd.Name,
DiscountType = sd.DiscountType,
DiscountLimitation = sd.DiscountLimitation,
DiscountAmount = sd.DiscountAmount,
UsePercentage = sd.UsePercentage,
DiscountPercentage = sd.DiscountPercentage,
StartDateUtc = DateTime.UtcNow.AddYears(-5),
EndDateUtc = DateTime.UtcNow.AddYears(5),
RequiresCouponCode = sd.RequiresCouponCode,
CouponCode = sd.CouponCode
}));
}
///
/// Installs a sample blog posts
///
/// Sample blog posts to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallBlogPostsAsync(IList sampleBlogPosts)
{
var languageId = await GetDefaultLanguageIdAsync();
var customerId = await GetDefaultCustomerIdAsync();
var storeId = await GetDefaultStoreIdAsync();
var blogPosts = sampleBlogPosts.ToDictionary(sbp => new BlogPost
{
AllowComments = sbp.AllowComments,
LanguageId = languageId,
Title = sbp.Title,
BodyOverview = sbp.BodyOverview,
Body = sbp.Body,
Tags = sbp.Tags,
CreatedOnUtc = DateTime.UtcNow
}, sbp => sbp.Comments);
await _dataProvider.BulkInsertEntitiesAsync(blogPosts.Keys);
await InsertSearchEngineNamesAsync(blogPosts.Keys, blogPost => blogPost.Title, languageId);
await _dataProvider.BulkInsertEntitiesAsync(blogPosts.SelectMany(blogPost => blogPost.Value.Select(comment => new BlogComment
{
BlogPostId = blogPost.Key.Id,
CustomerId = customerId,
CommentText = comment,
IsApproved = true,
StoreId = storeId,
CreatedOnUtc = DateTime.UtcNow
})));
}
///
/// Installs a sample news
///
/// Sample news items to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallNewsAsync(IList sampleNewsItems)
{
var languageId = await GetDefaultLanguageIdAsync();
var customerId = await GetDefaultCustomerIdAsync();
var storeId = await GetDefaultStoreIdAsync();
var news = sampleNewsItems.ToDictionary(sni => new NewsItem
{
AllowComments = sni.AllowComments,
LanguageId = languageId,
Title = sni.Title,
Short = sni.Short,
Full = sni.Full,
Published = sni.Published,
CreatedOnUtc = DateTime.UtcNow
}, sni => sni.NewsComments);
await _dataProvider.BulkInsertEntitiesAsync(news.Keys);
await InsertSearchEngineNamesAsync(news.Keys, newsItem => newsItem.Title, languageId);
await _dataProvider.BulkInsertEntitiesAsync(news.SelectMany(newsItem => newsItem.Value.Select(comment => new NewsComment
{
NewsItemId = newsItem.Key.Id,
CustomerId = customerId,
CommentTitle = comment.CommentTitle,
CommentText = comment.CommentText,
IsApproved = comment.IsApproved,
StoreId = storeId,
CreatedOnUtc = DateTime.UtcNow
})));
}
///
/// Installs a sample polls
///
/// Sample polls to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallPollsAsync(IList samplePolls)
{
var languageId = await GetDefaultLanguageIdAsync();
var polls = samplePolls.ToDictionary(sp => new Poll
{
LanguageId = languageId,
Name = sp.Name,
SystemKeyword = sp.SystemKeyword,
Published = sp.Published,
ShowOnHomepage = sp.ShowOnHomepage,
DisplayOrder = sp.DisplayOrder
}, sp => sp.Answers);
await _dataProvider.BulkInsertEntitiesAsync(polls.Keys);
await _dataProvider.BulkInsertEntitiesAsync(
polls.SelectMany(sp => sp.Value.Select(spa => new PollAnswer
{
Name = spa.Name,
DisplayOrder = spa.DisplayOrder,
PollId = sp.Key.Id
}))
);
}
///
/// Create address by sample data
///
/// Sample address
///
/// A task that represents the asynchronous operation
/// The task contains created address
///
protected virtual async Task CreateAddressAsync(SampleAddress sampleAddress)
{
return new Address
{
Address1 = sampleAddress.Address1,
City = sampleAddress.City,
StateProvinceId = await GetFirstEntityIdAsync(sp => sp.Name == sampleAddress.StateProvince),
CountryId = await GetFirstEntityIdAsync(c => c.ThreeLetterIsoCode == sampleAddress.CountryThreeLetterIsoCode),
ZipPostalCode = sampleAddress.ZipPostalCode,
CreatedOnUtc = DateTime.UtcNow,
FirstName = sampleAddress.FirstName,
LastName = sampleAddress.LastName,
Email = sampleAddress.Email,
Company = sampleAddress.Company,
PhoneNumber = sampleAddress.PhoneNumber,
FaxNumber = sampleAddress.FaxNumber,
Address2 = sampleAddress.Address2
};
}
///
/// Installs a sample warehouses
///
/// Sample warehouses to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallWarehousesAsync(IList sampleWarehouses)
{
var warehouses = await sampleWarehouses.ToDictionaryAwaitAsync(
async sw => await CreateAddressAsync(sw), sw => new ValueTask(Task.FromResult(sw)));
await _dataProvider.BulkInsertEntitiesAsync(warehouses.Keys);
await _dataProvider.BulkInsertEntitiesAsync(warehouses.Select(w => new Warehouse
{
AddressId = w.Key.Id,
Name = w.Value.Name
}));
}
///
/// Installs a sample vendors
///
/// Sample vendors to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallVendorsAsync(IList sampleVendors)
{
var vendors = sampleVendors.Select(sv => new Vendor
{
Name = sv.Name,
Email = sv.Email,
Description = sv.Description,
AdminComment = sv.AdminComment,
Active = sv.Active,
DisplayOrder = sv.DisplayOrder,
PageSize = sv.PageSize,
AllowCustomersToSelectPageSize = sv.AllowCustomersToSelectPageSize,
PageSizeOptions = sv.PageSizeOptions,
PriceRangeFiltering = sv.PriceRangeFiltering,
ManuallyPriceRange = sv.ManuallyPriceRange,
PriceFrom = sv.PriceFrom,
PriceTo = sv.PriceTo,
}).ToList();
await _dataProvider.BulkInsertEntitiesAsync(vendors);
await InsertSearchEngineNamesAsync(vendors, vendor => vendor.Name);
}
///
/// Installs a sample affiliates
///
/// Sample affiliates to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallAffiliatesAsync(IList sampleAffiliates)
{
var affiliates = await sampleAffiliates.ToDictionaryAwaitAsync(
async sa => await CreateAddressAsync(sa), sa => new ValueTask(Task.FromResult(sa)));
await _dataProvider.BulkInsertEntitiesAsync(affiliates.Keys);
await _dataProvider.BulkInsertEntitiesAsync(affiliates.Select(a => new Affiliate
{
Active = a.Value.Active,
AddressId = a.Key.Id
}));
}
///
/// Installs a sample orders
///
/// Sample orders to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallOrdersAsync(IList sampleOrders)
{
var languageId = await GetDefaultLanguageIdAsync();
var defaultStoreId = await GetDefaultStoreIdAsync();
var customers = Table().AsEnumerable().GroupBy(p => p.Email, p => p).ToDictionary(p => p.Key, p => p.First());
static Address cloneAddress(Address address)
{
return new Address
{
FirstName = address.FirstName,
LastName = address.LastName,
Email = address.Email,
Company = address.Company,
CountryId = address.CountryId,
StateProvinceId = address.StateProvinceId,
County = address.County,
City = address.City,
Address1 = address.Address1,
Address2 = address.Address2,
ZipPostalCode = address.ZipPostalCode,
PhoneNumber = address.PhoneNumber,
FaxNumber = address.FaxNumber,
CustomAttributes = address.CustomAttributes,
CreatedOnUtc = address.CreatedOnUtc
};
}
var orders = await sampleOrders.ToDictionaryAwaitAsync(async so =>
{
var customer = customers[so.CustomerEmail];
var billingAddress = cloneAddress(await GetByIdAsync(customer.BillingAddressId));
await _dataProvider.InsertEntityAsync(billingAddress);
var order = new Order
{
StoreId = defaultStoreId,
OrderGuid = Guid.NewGuid(),
CustomerId = customer.Id,
CustomerLanguageId = languageId,
CustomerIp = so.CustomerIp,
OrderSubtotalInclTax = so.OrderSubtotalInclTax,
OrderSubtotalExclTax = so.OrderSubtotalExclTax,
OrderSubTotalDiscountInclTax = so.OrderSubTotalDiscountInclTax,
OrderSubTotalDiscountExclTax = so.OrderSubTotalDiscountExclTax,
OrderShippingInclTax = so.OrderShippingInclTax,
OrderShippingExclTax = so.OrderShippingExclTax,
PaymentMethodAdditionalFeeInclTax = so.PaymentMethodAdditionalFeeInclTax,
PaymentMethodAdditionalFeeExclTax = so.PaymentMethodAdditionalFeeExclTax,
TaxRates = so.TaxRates,
OrderTax = so.OrderTax,
OrderTotal = so.OrderTotal,
RefundedAmount = so.RefundedAmount,
OrderDiscount = so.OrderDiscount,
CheckoutAttributeDescription = so.CheckoutAttributeDescription,
CheckoutAttributesXml = so.CheckoutAttributesXml,
CustomerCurrencyCode = so.CustomerCurrencyCode,
CurrencyRate = so.CurrencyRate,
AffiliateId = so.AffiliateId,
OrderStatus = so.OrderStatus,
AllowStoringCreditCardNumber = so.AllowStoringCreditCardNumber,
CardType = so.CardType,
CardName = so.CardName,
CardNumber = so.CardNumber,
MaskedCreditCardNumber = so.MaskedCreditCardNumber,
CardCvv2 = so.CardCvv2,
CardExpirationMonth = so.CardExpirationMonth,
CardExpirationYear = so.CardExpirationYear,
PaymentMethodSystemName = so.PaymentMethodSystemName,
AuthorizationTransactionId = so.AuthorizationTransactionId,
AuthorizationTransactionCode = so.AuthorizationTransactionCode,
AuthorizationTransactionResult = so.AuthorizationTransactionResult,
CaptureTransactionId = so.CaptureTransactionId,
CaptureTransactionResult = so.CaptureTransactionResult,
SubscriptionTransactionId = so.SubscriptionTransactionId,
PaymentStatus = so.PaymentStatus,
PaidDateUtc = so.PaidDateUtc,
BillingAddressId = billingAddress.Id,
ShippingStatus = so.ShippingStatus,
ShippingMethod = so.ShippingMethod,
PickupInStore = so.PickupInStore,
ShippingRateComputationMethodSystemName = so.ShippingRateComputationMethodSystemName,
CustomValuesXml = so.CustomValuesXml,
VatNumber = so.VatNumber,
CreatedOnUtc = DateTime.UtcNow,
CustomOrderNumber = so.CustomOrderNumber
};
if (order.ShippingStatus != ShippingStatus.ShippingNotRequired)
{
var shippingAddress = cloneAddress(await GetByIdAsync(customer.ShippingAddressId));
await _dataProvider.InsertEntityAsync(shippingAddress);
order.ShippingAddressId = shippingAddress.Id;
}
return order;
}, so => new ValueTask(Task.FromResult(so)));
await _dataProvider.BulkInsertEntitiesAsync(orders.Keys);
foreach (var order in orders.Keys)
order.CustomOrderNumber = order.Id.ToString();
await _dataProvider.UpdateEntitiesAsync(orders.Keys);
var items = (await orders
.SelectAwait(async o => await o.Value.OrderItems.SelectAwait(async oi => new KeyValuePair(new OrderItem
{
OrderItemGuid = Guid.NewGuid(),
OrderId = o.Key.Id,
ProductId = await GetFirstEntityIdAsync(p => p.Name == oi.ProductName) ?? throw new Exception($"Product with name \"{oi.ProductName}\" cannot be loaded"),
UnitPriceInclTax = oi.UnitPriceInclTax,
UnitPriceExclTax = oi.UnitPriceExclTax,
PriceInclTax = oi.PriceInclTax,
PriceExclTax = oi.PriceExclTax,
OriginalProductCost = oi.OriginalProductCost,
AttributeDescription = oi.AttributeDescription,
AttributesXml = oi.AttributesXml,
Quantity = oi.Quantity,
DiscountAmountInclTax = oi.DiscountAmountInclTax,
DiscountAmountExclTax = oi.DiscountAmountExclTax,
DownloadCount = oi.DownloadCount,
IsDownloadActivated = oi.IsDownloadActivated,
LicenseDownloadId = oi.LicenseDownloadId,
ItemWeight = oi.ItemWeight,
RentalStartDateUtc = oi.RentalStartDateUtc,
RentalEndDateUtc = oi.RentalEndDateUtc
}, oi)).ToListAsync()).ToListAsync()).SelectMany(p => p).ToList();
await _dataProvider.BulkInsertEntitiesAsync(items.Select(i => i.Key));
var shipments = orders.Where(o => o.Value.Shipments.Any()).SelectMany(o =>
o.Value.Shipments.Select(ss => new KeyValuePair(new Shipment
{
OrderId = o.Key.Id,
TrackingNumber = ss.TrackingNumber,
TotalWeight = ss.TotalWeight,
ReadyForPickupDateUtc = DateTime.UtcNow,
DeliveryDateUtc = DateTime.UtcNow,
AdminComment = ss.AdminComment,
CreatedOnUtc = DateTime.UtcNow
}, ss))).ToList();
await _dataProvider.BulkInsertEntitiesAsync(shipments.Select(s => s.Key));
await _dataProvider.BulkInsertEntitiesAsync(shipments.SelectMany(s =>
s.Value.ShipmentItems.Select(si => new ShipmentItem
{
OrderItemId = items.First(i => i.Value.ProductName.Equals(si.ProductName)).Key.Id,
Quantity = si.Quantity,
WarehouseId = 0,
ShipmentId = s.Key.Id
})));
await _dataProvider.BulkInsertEntitiesAsync(orders.SelectMany(o =>
o.Value.OrderNotes.Select(note =>
new OrderNote { CreatedOnUtc = DateTime.UtcNow, Note = note, OrderId = o.Key.Id })));
}
///
/// Installs a sample activity logs
///
/// Sample activity logs to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallActivityLogsAsync(IList sampleActivityLogs)
{
var customerId = await GetDefaultCustomerIdAsync();
await _dataProvider.BulkInsertEntitiesAsync(await sampleActivityLogs.SelectAwait(async sal => new ActivityLog
{
ActivityLogTypeId = await GetFirstEntityIdAsync(alt => alt.SystemKeyword == sal.ActivityLogType) ?? throw new Exception($"Cannot load LogType: {sal.ActivityLogType}"),
Comment = sal.Comment,
CreatedOnUtc = DateTime.UtcNow,
CustomerId = customerId,
IpAddress = sal.IpAddress
}).ToListAsync());
}
///
/// Installs a sample search terms
///
/// Sample search terms to install
/// A task that represents the asynchronous operation
protected virtual async Task InstallSearchTermsAsync(IList sampleSearchTerms)
{
var storeId = await GetDefaultStoreIdAsync();
await _dataProvider.BulkInsertEntitiesAsync(sampleSearchTerms.Select(sst => new SearchTerm
{
Count = sst.Count,
Keyword = sst.Keyword,
StoreId = storeId
}));
}
#endregion
}