hayfork 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,132 @@
1
+ require "hayfork/binding"
2
+ require "hayfork/insert_sql"
3
+ require "hayfork/update_sql"
4
+ require "hayfork/delete_sql"
5
+
6
+ module Hayfork
7
+ class Statement
8
+ attr_reader :haystack, :relation, :value
9
+ attr_accessor :weight, :dictionary
10
+
11
+ def initialize(haystack, relation, field, options={})
12
+ @haystack = haystack
13
+ @relation = relation.all
14
+ @weight = options.fetch(:weight, Hayfork.default_weight) # TODO: validate weight
15
+ @dictionary = options.fetch(:dictionary, Hayfork.default_dictionary)
16
+ @attributes = {}.with_indifferent_access
17
+ @unnest = false
18
+ @unsearchable = false
19
+
20
+ case field
21
+ when Arel::Predications
22
+ @value = field
23
+ when String
24
+ @value = model.arel_table[field]
25
+ when Symbol
26
+ @value = model.arel_table[field.to_s]
27
+ when Hash
28
+ reflection = reflection_for(field.keys.first)
29
+ joins field.keys.first
30
+ @value = reflection.klass.arel_table[field.values.first.to_s]
31
+ else
32
+ fail ArgumentError, "Unrecognized value for `field`: #{field.inspect}"
33
+ end
34
+ end
35
+
36
+
37
+
38
+ def joins(join_value)
39
+ @relation = Hayfork.join(relation, join_value)
40
+ self
41
+ end
42
+
43
+ def where(where_value)
44
+ @relation = relation.where(where_value)
45
+ self
46
+ end
47
+
48
+ def merge(attrs = {})
49
+ attributes.merge! attrs.stringify_keys.except(
50
+ Hayfork::SEARCH_VECTOR,
51
+ Hayfork::TEXT,
52
+ Hayfork::SOURCE_TYPE,
53
+ Hayfork::SOURCE_ID)
54
+ self
55
+ end
56
+
57
+ def unsearchable
58
+ @unsearchable = true
59
+ self
60
+ end
61
+
62
+ def unnest
63
+ @unnest = true
64
+ self
65
+ end
66
+
67
+
68
+
69
+ def unsearchable?
70
+ @unsearchable == true
71
+ end
72
+
73
+ def unnest?
74
+ @unnest == true
75
+ end
76
+
77
+ def may_change_on_update?
78
+ !update.values_to_check_on_update.empty?
79
+ end
80
+
81
+
82
+
83
+ def insert
84
+ InsertSql.new(haystack, relation, bindings)
85
+ end
86
+
87
+ def update
88
+ UpdateSql.new(haystack, relation, bindings)
89
+ end
90
+
91
+ def delete
92
+ DeleteSql.new(haystack, relation, bindings)
93
+ end
94
+
95
+
96
+
97
+ def bindings
98
+ @bindings ||= (haystack.columns.each_with_object([]) do |column, bindings|
99
+ next if column.name == Hayfork::SEARCH_VECTOR && unsearchable?
100
+
101
+ value = attributes.fetch column.name do
102
+ case column.name
103
+ when Hayfork::SEARCH_RESULT_TYPE then model.name
104
+ when Hayfork::SEARCH_RESULT_ID then model.arel_table["id"]
105
+ when Hayfork::SEARCH_VECTOR, Hayfork::TEXT then self.value
106
+ when Hayfork::SOURCE_TYPE then self.value.relation.send(:type_caster).send(:types).name
107
+ when Hayfork::SOURCE_ID then self.value.relation["id"]
108
+ when Hayfork::FIELD then self.value.name
109
+ end
110
+ end
111
+
112
+ next unless value
113
+ value = model.arel_table[value] if value.is_a? Symbol
114
+ bindings.push Hayfork::Binding.new(self, column, value)
115
+ end)
116
+ end
117
+
118
+
119
+
120
+ private
121
+ attr_reader :attributes
122
+
123
+ def model
124
+ relation.model
125
+ end
126
+
127
+ def reflection_for(association)
128
+ Hayfork.reflection_for(model, association)
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,78 @@
1
+ require "hayfork/statement"
2
+
3
+ module Hayfork
4
+ class StatementBuilder
5
+ attr_reader :row
6
+
7
+ def initialize(haystack, relation, attributes: {})
8
+ @haystack = haystack
9
+ @relation = relation
10
+ @attributes = attributes
11
+ @statements = []
12
+ @row = model.arel_table
13
+ end
14
+
15
+
16
+ def set(key, value)
17
+ @attributes.merge!(key => value)
18
+ end
19
+
20
+ def joins(join_value, &block) # reject SQL literals?
21
+ apply? Hayfork.join(relation, join_value), &block
22
+ end
23
+
24
+ def where(*args, &block) # reject SQL literals?
25
+ apply? relation.where(*args), &block
26
+ end
27
+
28
+
29
+ def insert(field, options={})
30
+ Statement.new(haystack, relation, field, options).tap do |statement|
31
+ statement.merge(attributes) if attributes.any?
32
+ statements << statement
33
+ end
34
+ end
35
+
36
+
37
+ def to_insert_sql(**args)
38
+ statements.map { |statement| " " << statement.insert.to_sql(**args) }.join.strip
39
+ end
40
+
41
+ def to_update_sql
42
+ updates = statements.select(&:may_change_on_update?)
43
+ return "-- nothing to update" if updates.empty?
44
+ updates.map { |statement| " " << statement.update.to_sql.lstrip }.join.strip
45
+ end
46
+
47
+ def to_delete_sql
48
+ statements.map { |statement| " " << statement.delete.to_sql }.join.strip
49
+ end
50
+
51
+
52
+ def to_a
53
+ statements
54
+ end
55
+
56
+ private
57
+ attr_reader :haystack, :relation, :statements, :attributes
58
+
59
+ def apply?(modified_relation, &block)
60
+ if block_given?
61
+ statements = StatementBuilder.new(haystack, modified_relation, attributes: attributes.dup)
62
+ if block.arity.zero?
63
+ statements.instance_eval(&block)
64
+ else
65
+ yield statements
66
+ end
67
+ @statements.concat statements.to_a
68
+ else
69
+ @relation = modified_relation
70
+ end
71
+ end
72
+
73
+ def model
74
+ relation.model
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,17 @@
1
+ require "hayfork/statement_builder"
2
+
3
+ module Hayfork
4
+ class TriggerBuilder
5
+
6
+ def initialize(triggers)
7
+ @triggers = triggers
8
+ end
9
+
10
+ def foreach(model, options={}, &block)
11
+ statements = StatementBuilder.new(@triggers.haystack, model.unscope(:order, :select, :group, :having, :offset, :limit))
12
+ statements.instance_eval(&block)
13
+ @triggers << [model, statements, options]
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,76 @@
1
+ module Hayfork
2
+ class Triggers
3
+ attr_reader :haystack
4
+
5
+ def initialize(haystack)
6
+ @haystack = haystack
7
+ @_triggers = []
8
+ end
9
+
10
+ def <<(trigger)
11
+ _triggers << trigger
12
+ end
13
+
14
+ def create
15
+ _triggers.map { |args| psql_create_triggers_for(*args) }.join
16
+ end
17
+
18
+ def drop
19
+ _triggers.map { |model, _, options| psql_drop_triggers_for(model, options) }.join
20
+ end
21
+
22
+ def replace
23
+ [drop, create].join
24
+ end
25
+
26
+ def truncate
27
+ "TRUNCATE #{haystack.table_name};\n"
28
+ end
29
+
30
+ def rebuild
31
+ ([truncate] + _triggers.map { |args| psql_inserts_for(*args) }).join
32
+ end
33
+
34
+ private
35
+ attr_reader :_triggers
36
+
37
+ def psql_create_triggers_for(model, statements, options)
38
+ name = function_name(model, options)
39
+ <<~SQL
40
+ CREATE FUNCTION #{name}() RETURNS trigger AS $$
41
+ BEGIN
42
+ IF TG_OP = 'DELETE' THEN
43
+ #{statements.to_delete_sql}
44
+ RETURN OLD;
45
+ ELSIF TG_OP = 'UPDATE' THEN
46
+ #{statements.to_update_sql}
47
+ RETURN NEW;
48
+ ELSIF TG_OP = 'INSERT' THEN
49
+ #{statements.to_insert_sql}
50
+ RETURN NEW;
51
+ END IF;
52
+ RETURN NULL; -- result is ignored since this is an AFTER trigger
53
+ END;
54
+ $$ LANGUAGE plpgsql;
55
+ CREATE TRIGGER #{name}_trigger BEFORE INSERT OR UPDATE OR DELETE ON #{model.table_name}
56
+ FOR EACH ROW EXECUTE PROCEDURE #{name}();
57
+ SQL
58
+ end
59
+
60
+ def psql_inserts_for(model, statements, options)
61
+ "#{statements.to_insert_sql(from: false)}\n" if options.fetch(:rebuild, true)
62
+ end
63
+
64
+ def psql_drop_triggers_for(model, options)
65
+ name = function_name(model, options)
66
+ <<~SQL
67
+ DROP FUNCTION IF EXISTS #{name}() CASCADE;
68
+ SQL
69
+ end
70
+
71
+ def function_name(model, options)
72
+ options.fetch(:name, "maintain_#{model.table_name}_in_#{haystack.table_name}")
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,12 @@
1
+ module Hayfork
2
+ module Unaccent
3
+
4
+ def unaccent(string)
5
+ string.each_char.map { |char| RULES.fetch(char, char) }.join
6
+ end
7
+
8
+ # Use Postgres's own rules so this method's behavior matches Postgres's `unaccent` function.
9
+ RULES = Hash[File.read(File.expand_path("../../../postgres/unaccent.rules", __FILE__)).scan(/^([^\t]+)\t(.*)$/)].freeze
10
+
11
+ end
12
+ end
@@ -0,0 +1,112 @@
1
+ require "hayfork/delete_sql"
2
+ require "hayfork/insert_sql"
3
+
4
+ module Hayfork
5
+ class UpdateSql
6
+ attr_reader :haystack, :relation, :bindings
7
+
8
+ def initialize(haystack, relation, bindings)
9
+ @haystack = haystack
10
+ @relation = relation
11
+ @bindings = bindings
12
+ end
13
+
14
+ def to_sql
15
+ sql = values_to_check_on_update.map { |field| "OLD.#{field} IS DISTINCT FROM NEW.#{field}" }.join(" OR ")
16
+
17
+ <<-SQL
18
+ IF #{sql} THEN
19
+ #{delete.to_sql.strip}
20
+ #{insert.to_sql.strip}
21
+ END IF;
22
+ SQL
23
+ end
24
+ alias to_s to_sql
25
+
26
+ def model
27
+ relation.model
28
+ end
29
+
30
+ def values_to_check_on_update
31
+ foreign_keys_by_table_name = {}
32
+ (relation.joins_values + relation.left_outer_joins_values).each do |join_value|
33
+ if join_value.is_a? String
34
+ fail NotImplementedError, "Unhandled literal join: #{join_value.inspect}"
35
+ end
36
+
37
+ reflection = reflection_for(join_value)
38
+ table_name = reflection.table_name
39
+ reflection = reflection.through_reflection if reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
40
+
41
+ case reflection
42
+ when ActiveRecord::Reflection::BelongsToReflection
43
+ foreign_keys_by_table_name[table_name] = [ reflection.foreign_key.to_s ]
44
+ when ActiveRecord::Reflection::HasManyReflection
45
+ foreign_keys_by_table_name[table_name] = [] # assume identity keys won't change
46
+ when ActiveRecord::Reflection::HasAndBelongsToManyReflection
47
+ foreign_keys_by_table_name[reflection.join_table] = [] # assume identity keys won't change
48
+ foreign_keys_by_table_name[table_name] = [] # assume identity keys won't change
49
+ else
50
+ fail NotImplementedError, "Unhandled reflection: #{reflection.class} (join_value: #{join_value.inspect})"
51
+ end
52
+ end
53
+
54
+
55
+ values_being_written = bindings.pluck(:raw_value) + predicate_fields
56
+ values_to_check_on_update = Set.new
57
+
58
+ values_being_written.each do |value|
59
+ next if value.is_a?(String) # constant
60
+ if value.relation.name == relation.table_name
61
+ values_to_check_on_update << value.name.to_s
62
+ else
63
+ # The value isn't a field of the current record but of a joined record.
64
+ # That record hasn't changed so we don't care about its value; but we
65
+ # do care whether this record's foreign keys have changed (which would
66
+ # cause it to be associated with a different joined record).
67
+ values_to_check_on_update.merge foreign_keys_by_table_name.fetch(value.relation.name)
68
+ end
69
+ end
70
+
71
+ values_to_check_on_update - model.readonly_attributes
72
+ end
73
+
74
+ private
75
+
76
+ def insert
77
+ InsertSql.new(haystack, relation, bindings)
78
+ end
79
+
80
+ def delete
81
+ DeleteSql.new(haystack, relation, bindings)
82
+ end
83
+
84
+ def predicate_fields
85
+ relation.where_clause.send(:predicates).map(&method(:field_from_predicate))
86
+ end
87
+
88
+ def field_from_predicate(predicate)
89
+ case predicate
90
+ when Arel::Nodes::Between,
91
+ Arel::Nodes::Equality,
92
+ Arel::Nodes::GreaterThan,
93
+ Arel::Nodes::GreaterThanOrEqual,
94
+ Arel::Nodes::In,
95
+ Arel::Nodes::LessThan,
96
+ Arel::Nodes::LessThanOrEqual,
97
+ Arel::Nodes::NotEqual,
98
+ Arel::Nodes::NotIn
99
+ field_from_predicate(predicate.left)
100
+ when Arel::Attributes::Attribute
101
+ predicate
102
+ else
103
+ fail NotImplementedError, "Unhandled predicate: #{predicate.class}: #{predicate.inspect}"
104
+ end
105
+ end
106
+
107
+ def reflection_for(association)
108
+ Hayfork.reflection_for(model, association)
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,3 @@
1
+ module Hayfork
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,1049 @@
1
+ © (C)
2
+ « <<
3
+ ­ -
4
+ ® (R)
5
+ » >>
6
+ ¼ 1/4
7
+ ½ 1/2
8
+ ¾ 3/4
9
+ À A
10
+ Á A
11
+ Â A
12
+ Ã A
13
+ Ä A
14
+ Å A
15
+ Æ AE
16
+ Ç C
17
+ È E
18
+ É E
19
+ Ê E
20
+ Ë E
21
+ Ì I
22
+ Í I
23
+ Î I
24
+ Ï I
25
+ Ð D
26
+ Ñ N
27
+ Ò O
28
+ Ó O
29
+ Ô O
30
+ Õ O
31
+ Ö O
32
+ × *
33
+ Ø O
34
+ Ù U
35
+ Ú U
36
+ Û U
37
+ Ü U
38
+ Ý Y
39
+ Þ TH
40
+ ß ss
41
+ à a
42
+ á a
43
+ â a
44
+ ã a
45
+ ä a
46
+ å a
47
+ æ ae
48
+ ç c
49
+ è e
50
+ é e
51
+ ê e
52
+ ë e
53
+ ì i
54
+ í i
55
+ î i
56
+ ï i
57
+ ð d
58
+ ñ n
59
+ ò o
60
+ ó o
61
+ ô o
62
+ õ o
63
+ ö o
64
+ ÷ /
65
+ ø o
66
+ ù u
67
+ ú u
68
+ û u
69
+ ü u
70
+ ý y
71
+ þ th
72
+ ÿ y
73
+ Ā A
74
+ ā a
75
+ Ă A
76
+ ă a
77
+ Ą A
78
+ ą a
79
+ Ć C
80
+ ć c
81
+ Ĉ C
82
+ ĉ c
83
+ Ċ C
84
+ ċ c
85
+ Č C
86
+ č c
87
+ Ď D
88
+ ď d
89
+ Đ D
90
+ đ d
91
+ Ē E
92
+ ē e
93
+ Ĕ E
94
+ ĕ e
95
+ Ė E
96
+ ė e
97
+ Ę E
98
+ ę e
99
+ Ě E
100
+ ě e
101
+ Ĝ G
102
+ ĝ g
103
+ Ğ G
104
+ ğ g
105
+ Ġ G
106
+ ġ g
107
+ Ģ G
108
+ ģ g
109
+ Ĥ H
110
+ ĥ h
111
+ Ħ H
112
+ ħ h
113
+ Ĩ I
114
+ ĩ i
115
+ Ī I
116
+ ī i
117
+ Ĭ I
118
+ ĭ i
119
+ Į I
120
+ į i
121
+ İ I
122
+ ı i
123
+ IJ IJ
124
+ ij ij
125
+ Ĵ J
126
+ ĵ j
127
+ Ķ K
128
+ ķ k
129
+ ĸ q
130
+ Ĺ L
131
+ ĺ l
132
+ Ļ L
133
+ ļ l
134
+ Ľ L
135
+ ľ l
136
+ Ŀ L
137
+ ŀ l
138
+ Ł L
139
+ ł l
140
+ Ń N
141
+ ń n
142
+ Ņ N
143
+ ņ n
144
+ Ň N
145
+ ň n
146
+ ʼn 'n
147
+ Ŋ N
148
+ ŋ n
149
+ Ō O
150
+ ō o
151
+ Ŏ O
152
+ ŏ o
153
+ Ő O
154
+ ő o
155
+ Œ OE
156
+ œ oe
157
+ Ŕ R
158
+ ŕ r
159
+ Ŗ R
160
+ ŗ r
161
+ Ř R
162
+ ř r
163
+ Ś S
164
+ ś s
165
+ Ŝ S
166
+ ŝ s
167
+ Ş S
168
+ ş s
169
+ Š S
170
+ š s
171
+ Ţ T
172
+ ţ t
173
+ Ť T
174
+ ť t
175
+ Ŧ T
176
+ ŧ t
177
+ Ũ U
178
+ ũ u
179
+ Ū U
180
+ ū u
181
+ Ŭ U
182
+ ŭ u
183
+ Ů U
184
+ ů u
185
+ Ű U
186
+ ű u
187
+ Ų U
188
+ ų u
189
+ Ŵ W
190
+ ŵ w
191
+ Ŷ Y
192
+ ŷ y
193
+ Ÿ Y
194
+ Ź Z
195
+ ź z
196
+ Ż Z
197
+ ż z
198
+ Ž Z
199
+ ž z
200
+ ſ s
201
+ ƀ b
202
+ Ɓ B
203
+ Ƃ B
204
+ ƃ b
205
+ Ƈ C
206
+ ƈ c
207
+ Ɖ D
208
+ Ɗ D
209
+ Ƌ D
210
+ ƌ d
211
+ Ɛ E
212
+ Ƒ F
213
+ ƒ f
214
+ Ɠ G
215
+ ƕ hv
216
+ Ɩ I
217
+ Ɨ I
218
+ Ƙ K
219
+ ƙ k
220
+ ƚ l
221
+ Ɲ N
222
+ ƞ n
223
+ Ơ O
224
+ ơ o
225
+ Ƣ OI
226
+ ƣ oi
227
+ Ƥ P
228
+ ƥ p
229
+ ƫ t
230
+ Ƭ T
231
+ ƭ t
232
+ Ʈ T
233
+ Ư U
234
+ ư u
235
+ Ʋ V
236
+ Ƴ Y
237
+ ƴ y
238
+ Ƶ Z
239
+ ƶ z
240
+ DŽ DZ
241
+ Dž Dz
242
+ dž dz
243
+ LJ LJ
244
+ Lj Lj
245
+ lj lj
246
+ NJ NJ
247
+ Nj Nj
248
+ nj nj
249
+ Ǎ A
250
+ ǎ a
251
+ Ǐ I
252
+ ǐ i
253
+ Ǒ O
254
+ ǒ o
255
+ Ǔ U
256
+ ǔ u
257
+ Ǥ G
258
+ ǥ g
259
+ Ǧ G
260
+ ǧ g
261
+ Ǩ K
262
+ ǩ k
263
+ Ǫ O
264
+ ǫ o
265
+ ǰ j
266
+ DZ DZ
267
+ Dz Dz
268
+ dz dz
269
+ Ǵ G
270
+ ǵ g
271
+ Ǹ N
272
+ ǹ n
273
+ Ȁ A
274
+ ȁ a
275
+ Ȃ A
276
+ ȃ a
277
+ Ȅ E
278
+ ȅ e
279
+ Ȇ E
280
+ ȇ e
281
+ Ȉ I
282
+ ȉ i
283
+ Ȋ I
284
+ ȋ i
285
+ Ȍ O
286
+ ȍ o
287
+ Ȏ O
288
+ ȏ o
289
+ Ȑ R
290
+ ȑ r
291
+ Ȓ R
292
+ ȓ r
293
+ Ȕ U
294
+ ȕ u
295
+ Ȗ U
296
+ ȗ u
297
+ Ș S
298
+ ș s
299
+ Ț T
300
+ ț t
301
+ Ȟ H
302
+ ȟ h
303
+ ȡ d
304
+ Ȥ Z
305
+ ȥ z
306
+ Ȧ A
307
+ ȧ a
308
+ Ȩ E
309
+ ȩ e
310
+ Ȯ O
311
+ ȯ o
312
+ Ȳ Y
313
+ ȳ y
314
+ ȴ l
315
+ ȵ n
316
+ ȶ t
317
+ ȷ j
318
+ ȸ db
319
+ ȹ qp
320
+ Ⱥ A
321
+ Ȼ C
322
+ ȼ c
323
+ Ƚ L
324
+ Ⱦ T
325
+ ȿ s
326
+ ɀ z
327
+ Ƀ B
328
+ Ʉ U
329
+ Ɇ E
330
+ ɇ e
331
+ Ɉ J
332
+ ɉ j
333
+ Ɍ R
334
+ ɍ r
335
+ Ɏ Y
336
+ ɏ y
337
+ ɓ b
338
+ ɕ c
339
+ ɖ d
340
+ ɗ d
341
+ ɛ e
342
+ ɟ j
343
+ ɠ g
344
+ ɡ g
345
+ ɢ G
346
+ ɦ h
347
+ ɧ h
348
+ ɨ i
349
+ ɪ I
350
+ ɫ l
351
+ ɬ l
352
+ ɭ l
353
+ ɱ m
354
+ ɲ n
355
+ ɳ n
356
+ ɴ N
357
+ ɶ OE
358
+ ɼ r
359
+ ɽ r
360
+ ɾ r
361
+ ʀ R
362
+ ʂ s
363
+ ʈ t
364
+ ʉ u
365
+ ʋ v
366
+ ʏ Y
367
+ ʐ z
368
+ ʑ z
369
+ ʙ B
370
+ ʛ G
371
+ ʜ H
372
+ ʝ j
373
+ ʟ L
374
+ ʠ q
375
+ ʣ dz
376
+ ʥ dz
377
+ ʦ ts
378
+ ʪ ls
379
+ ʫ lz
380
+ Ё Е
381
+ ё е
382
+ ᴀ A
383
+ ᴁ AE
384
+ ᴃ B
385
+ ᴄ C
386
+ ᴅ D
387
+ ᴆ D
388
+ ᴇ E
389
+ ᴊ J
390
+ ᴋ K
391
+ ᴌ L
392
+ ᴍ M
393
+ ᴏ O
394
+ ᴘ P
395
+ ᴛ T
396
+ ᴜ U
397
+ ᴠ V
398
+ ᴡ W
399
+ ᴢ Z
400
+ ᵫ ue
401
+ ᵬ b
402
+ ᵭ d
403
+ ᵮ f
404
+ ᵯ m
405
+ ᵰ n
406
+ ᵱ p
407
+ ᵲ r
408
+ ᵳ r
409
+ ᵴ s
410
+ ᵵ t
411
+ ᵶ z
412
+ ᵺ th
413
+ ᵻ I
414
+ ᵽ p
415
+ ᵾ U
416
+ ᶀ b
417
+ ᶁ d
418
+ ᶂ f
419
+ ᶃ g
420
+ ᶄ k
421
+ ᶅ l
422
+ ᶆ m
423
+ ᶇ n
424
+ ᶈ p
425
+ ᶉ r
426
+ ᶊ s
427
+ ᶌ v
428
+ ᶍ x
429
+ ᶎ z
430
+ ᶏ a
431
+ ᶑ d
432
+ ᶒ e
433
+ ᶓ e
434
+ ᶖ i
435
+ ᶙ u
436
+ Ḁ A
437
+ ḁ a
438
+ Ḃ B
439
+ ḃ b
440
+ Ḅ B
441
+ ḅ b
442
+ Ḇ B
443
+ ḇ b
444
+ Ḋ D
445
+ ḋ d
446
+ Ḍ D
447
+ ḍ d
448
+ Ḏ D
449
+ ḏ d
450
+ Ḑ D
451
+ ḑ d
452
+ Ḓ D
453
+ ḓ d
454
+ Ḙ E
455
+ ḙ e
456
+ Ḛ E
457
+ ḛ e
458
+ Ḟ F
459
+ ḟ f
460
+ Ḡ G
461
+ ḡ g
462
+ Ḣ H
463
+ ḣ h
464
+ Ḥ H
465
+ ḥ h
466
+ Ḧ H
467
+ ḧ h
468
+ Ḩ H
469
+ ḩ h
470
+ Ḫ H
471
+ ḫ h
472
+ Ḭ I
473
+ ḭ i
474
+ Ḱ K
475
+ ḱ k
476
+ Ḳ K
477
+ ḳ k
478
+ Ḵ K
479
+ ḵ k
480
+ Ḷ L
481
+ ḷ l
482
+ Ḻ L
483
+ ḻ l
484
+ Ḽ L
485
+ ḽ l
486
+ Ḿ M
487
+ ḿ m
488
+ Ṁ M
489
+ ṁ m
490
+ Ṃ M
491
+ ṃ m
492
+ Ṅ N
493
+ ṅ n
494
+ Ṇ N
495
+ ṇ n
496
+ Ṉ N
497
+ ṉ n
498
+ Ṋ N
499
+ ṋ n
500
+ Ṕ P
501
+ ṕ p
502
+ Ṗ P
503
+ ṗ p
504
+ Ṙ R
505
+ ṙ r
506
+ Ṛ R
507
+ ṛ r
508
+ Ṟ R
509
+ ṟ r
510
+ Ṡ S
511
+ ṡ s
512
+ Ṣ S
513
+ ṣ s
514
+ Ṫ T
515
+ ṫ t
516
+ Ṭ T
517
+ ṭ t
518
+ Ṯ T
519
+ ṯ t
520
+ Ṱ T
521
+ ṱ t
522
+ Ṳ U
523
+ ṳ u
524
+ Ṵ U
525
+ ṵ u
526
+ Ṷ U
527
+ ṷ u
528
+ Ṽ V
529
+ ṽ v
530
+ Ṿ V
531
+ ṿ v
532
+ Ẁ W
533
+ ẁ w
534
+ Ẃ W
535
+ ẃ w
536
+ Ẅ W
537
+ ẅ w
538
+ Ẇ W
539
+ ẇ w
540
+ Ẉ W
541
+ ẉ w
542
+ Ẋ X
543
+ ẋ x
544
+ Ẍ X
545
+ ẍ x
546
+ Ẏ Y
547
+ ẏ y
548
+ Ẑ Z
549
+ ẑ z
550
+ Ẓ Z
551
+ ẓ z
552
+ Ẕ Z
553
+ ẕ z
554
+ ẖ h
555
+ ẗ t
556
+ ẘ w
557
+ ẙ y
558
+ ẚ a
559
+ ẜ s
560
+ ẝ s
561
+ ẞ SS
562
+ Ạ A
563
+ ạ a
564
+ Ả A
565
+ ả a
566
+ Ẹ E
567
+ ẹ e
568
+ Ẻ E
569
+ ẻ e
570
+ Ẽ E
571
+ ẽ e
572
+ Ỉ I
573
+ ỉ i
574
+ Ị I
575
+ ị i
576
+ Ọ O
577
+ ọ o
578
+ Ỏ O
579
+ ỏ o
580
+ Ụ U
581
+ ụ u
582
+ Ủ U
583
+ ủ u
584
+ Ỳ Y
585
+ ỳ y
586
+ Ỵ Y
587
+ ỵ y
588
+ Ỷ Y
589
+ ỷ y
590
+ Ỹ Y
591
+ ỹ y
592
+ Ỻ LL
593
+ ỻ ll
594
+ Ỽ V
595
+ ỽ v
596
+ Ỿ Y
597
+ ỿ y
598
+ ‐ -
599
+ ‑ -
600
+ ‒ -
601
+ – -
602
+ — -
603
+ ― -
604
+ ‖ ||
605
+ ‘ '
606
+ ’ '
607
+ ‚ ,
608
+ ‛ '
609
+ “ "
610
+ ” "
611
+ „ ,,
612
+ ‟ "
613
+ ․ .
614
+ ‥ ..
615
+ … ...
616
+ ′ '
617
+ ″ "
618
+ ‹ <
619
+ › >
620
+ ‼ !!
621
+ ⁄ /
622
+ ⁅ [
623
+ ⁆ ]
624
+ ⁇ ??
625
+ ⁈ ?!
626
+ ⁉ !?
627
+ ⁎ *
628
+ ₠ CE
629
+ ₢ Cr
630
+ ₣ Fr.
631
+ ₤ L.
632
+ ₧ Pts
633
+ ₹ Rs
634
+ ₺ TL
635
+ ℀ a/c
636
+ ℁ a/s
637
+ ℂ C
638
+ ℃ °C
639
+ ℅ c/o
640
+ ℆ c/u
641
+ ℉ °F
642
+ ℊ g
643
+ ℋ H
644
+ ℌ x
645
+ ℍ H
646
+ ℎ h
647
+ ℐ I
648
+ ℑ I
649
+ ℒ L
650
+ ℓ l
651
+ ℕ N
652
+ № No
653
+ ℗ (P)
654
+ ℙ P
655
+ ℚ Q
656
+ ℛ R
657
+ ℜ R
658
+ ℝ R
659
+ ℞ Rx
660
+ ℡ TEL
661
+ ℤ Z
662
+ ℨ Z
663
+ ℬ B
664
+ ℭ C
665
+ ℯ e
666
+ ℰ E
667
+ ℱ F
668
+ ℳ M
669
+ ℴ o
670
+ ℹ i
671
+ ℻ FAX
672
+ ⅅ D
673
+ ⅆ d
674
+ ⅇ e
675
+ ⅈ i
676
+ ⅉ j
677
+ ⅓ 1/3
678
+ ⅔ 2/3
679
+ ⅕ 1/5
680
+ ⅖ 2/5
681
+ ⅗ 3/5
682
+ ⅘ 4/5
683
+ ⅙ 1/6
684
+ ⅚ 5/6
685
+ ⅛ 1/8
686
+ ⅜ 3/8
687
+ ⅝ 5/8
688
+ ⅞ 7/8
689
+ ⅟ 1/
690
+ Ⅰ I
691
+ Ⅱ II
692
+ Ⅲ III
693
+ Ⅳ IV
694
+ Ⅴ V
695
+ Ⅵ VI
696
+ Ⅶ VII
697
+ Ⅷ VIII
698
+ Ⅸ IX
699
+ Ⅹ X
700
+ Ⅺ XI
701
+ Ⅻ XII
702
+ Ⅼ L
703
+ Ⅽ C
704
+ Ⅾ D
705
+ Ⅿ M
706
+ ⅰ i
707
+ ⅱ ii
708
+ ⅲ iii
709
+ ⅳ iv
710
+ ⅴ v
711
+ ⅵ vi
712
+ ⅶ vii
713
+ ⅷ viii
714
+ ⅸ ix
715
+ ⅹ x
716
+ ⅺ xi
717
+ ⅻ xii
718
+ ⅼ l
719
+ ⅽ c
720
+ ⅾ d
721
+ ⅿ m
722
+ − -
723
+ ∕ /
724
+ ∖ \
725
+ ∣ |
726
+ ∥ ||
727
+ ≪ <<
728
+ ≫ >>
729
+ ⑴ (1)
730
+ ⑵ (2)
731
+ ⑶ (3)
732
+ ⑷ (4)
733
+ ⑸ (5)
734
+ ⑹ (6)
735
+ ⑺ (7)
736
+ ⑻ (8)
737
+ ⑼ (9)
738
+ ⑽ (10)
739
+ ⑾ (11)
740
+ ⑿ (12)
741
+ ⒀ (13)
742
+ ⒁ (14)
743
+ ⒂ (15)
744
+ ⒃ (16)
745
+ ⒄ (17)
746
+ ⒅ (18)
747
+ ⒆ (19)
748
+ ⒇ (20)
749
+ ⒈ 1.
750
+ ⒉ 2.
751
+ ⒊ 3.
752
+ ⒋ 4.
753
+ ⒌ 5.
754
+ ⒍ 6.
755
+ ⒎ 7.
756
+ ⒏ 8.
757
+ ⒐ 9.
758
+ ⒑ 10.
759
+ ⒒ 11.
760
+ ⒓ 12.
761
+ ⒔ 13.
762
+ ⒕ 14.
763
+ ⒖ 15.
764
+ ⒗ 16.
765
+ ⒘ 17.
766
+ ⒙ 18.
767
+ ⒚ 19.
768
+ ⒛ 20.
769
+ ⒜ (a)
770
+ ⒝ (b)
771
+ ⒞ (c)
772
+ ⒟ (d)
773
+ ⒠ (e)
774
+ ⒡ (f)
775
+ ⒢ (g)
776
+ ⒣ (h)
777
+ ⒤ (i)
778
+ ⒥ (j)
779
+ ⒦ (k)
780
+ ⒧ (l)
781
+ ⒨ (m)
782
+ ⒩ (n)
783
+ ⒪ (o)
784
+ ⒫ (p)
785
+ ⒬ (q)
786
+ ⒭ (r)
787
+ ⒮ (s)
788
+ ⒯ (t)
789
+ ⒰ (u)
790
+ ⒱ (v)
791
+ ⒲ (w)
792
+ ⒳ (x)
793
+ ⒴ (y)
794
+ ⒵ (z)
795
+ ⦅ ((
796
+ ⦆ ))
797
+ ⩴ ::=
798
+ ⩵ ==
799
+ ⩶ ===
800
+ 、 ,
801
+ 。 .
802
+ 〇 0
803
+ 〈 <
804
+ 〉 >
805
+ 《 <<
806
+ 》 >>
807
+ 〔 [
808
+ 〕 ]
809
+ 〘 [
810
+ 〙 ]
811
+ 〚 [
812
+ 〛 ]
813
+ 〝 "
814
+ 〞 "
815
+ ㍱ hPa
816
+ ㍲ da
817
+ ㍳ AU
818
+ ㍴ bar
819
+ ㍵ oV
820
+ ㍶ pc
821
+ ㍷ dm
822
+ ㍺ IU
823
+ ㎀ pA
824
+ ㎁ nA
825
+ ㎃ mA
826
+ ㎄ kA
827
+ ㎅ KB
828
+ ㎆ MB
829
+ ㎇ GB
830
+ ㎈ cal
831
+ ㎉ kcal
832
+ ㎊ pF
833
+ ㎋ nF
834
+ ㎎ mg
835
+ ㎏ kg
836
+ ㎐ Hz
837
+ ㎑ kHz
838
+ ㎒ MHz
839
+ ㎓ GHz
840
+ ㎔ THz
841
+ ㎙ fm
842
+ ㎚ nm
843
+ ㎜ mm
844
+ ㎝ cm
845
+ ㎞ km
846
+ ㎧ m/s
847
+ ㎩ Pa
848
+ ㎪ kPa
849
+ ㎫ MPa
850
+ ㎬ GPa
851
+ ㎭ rad
852
+ ㎮ rad/s
853
+ ㎰ ps
854
+ ㎱ ns
855
+ ㎳ ms
856
+ ㎴ pV
857
+ ㎵ nV
858
+ ㎷ mV
859
+ ㎸ kV
860
+ ㎹ MV
861
+ ㎺ pW
862
+ ㎻ nW
863
+ ㎽ mW
864
+ ㎾ kW
865
+ ㎿ MW
866
+ ㏂ a.m.
867
+ ㏃ Bq
868
+ ㏄ cc
869
+ ㏅ cd
870
+ ㏆ C/kg
871
+ ㏇ Co.
872
+ ㏈ dB
873
+ ㏉ Gy
874
+ ㏊ ha
875
+ ㏋ HP
876
+ ㏌ in
877
+ ㏍ KK
878
+ ㏎ KM
879
+ ㏏ kt
880
+ ㏐ lm
881
+ ㏑ ln
882
+ ㏒ log
883
+ ㏓ lx
884
+ ㏔ mb
885
+ ㏕ mil
886
+ ㏖ mol
887
+ ㏗ pH
888
+ ㏘ p.m.
889
+ ㏙ PPM
890
+ ㏚ PR
891
+ ㏛ sr
892
+ ㏜ Sv
893
+ ㏝ Wb
894
+ ㏞ V/m
895
+ ㏟ A/m
896
+ ff ff
897
+ fi fi
898
+ fl fl
899
+ ffi ffi
900
+ ffl ffl
901
+ ſt st
902
+ st st
903
+ ︐ ,
904
+ ︑ ,
905
+ ︒ .
906
+ ︓ :
907
+ ︔ ;
908
+ ︕ !
909
+ ︖ ?
910
+ ︙ ...
911
+ ︰ ..
912
+ ︱ -
913
+ ︲ -
914
+ ︵ (
915
+ ︶ )
916
+ ︷ {
917
+ ︸ }
918
+ ︹ [
919
+ ︺ ]
920
+ ︽ <<
921
+ ︾ >>
922
+ ︿ <
923
+ ﹀ >
924
+ ﹇ [
925
+ ﹈ ]
926
+ ﹐ ,
927
+ ﹑ ,
928
+ ﹒ .
929
+ ﹔ ;
930
+ ﹕ :
931
+ ﹖ ?
932
+ ﹗ !
933
+ ﹘ -
934
+ ﹙ (
935
+ ﹚ )
936
+ ﹛ {
937
+ ﹜ }
938
+ ﹝ [
939
+ ﹞ ]
940
+ ﹟ #
941
+ ﹠ &
942
+ ﹡ *
943
+ ﹢ +
944
+ ﹣ -
945
+ ﹤ <
946
+ ﹥ >
947
+ ﹦ =
948
+ ﹨ \
949
+ ﹩ $
950
+ ﹪ %
951
+ ﹫ @
952
+ ! !
953
+ " "
954
+ # #
955
+ $ $
956
+ % %
957
+ & &
958
+ ' '
959
+ ( (
960
+ ) )
961
+ * *
962
+ + +
963
+ , ,
964
+ - -
965
+ . .
966
+ / /
967
+ 0 0
968
+ 1 1
969
+ 2 2
970
+ 3 3
971
+ 4 4
972
+ 5 5
973
+ 6 6
974
+ 7 7
975
+ 8 8
976
+ 9 9
977
+ : :
978
+ ; ;
979
+ < <
980
+ = =
981
+ > >
982
+ ? ?
983
+ @ @
984
+ A A
985
+ B B
986
+ C C
987
+ D D
988
+ E E
989
+ F F
990
+ G G
991
+ H H
992
+ I I
993
+ J J
994
+ K K
995
+ L L
996
+ M M
997
+ N N
998
+ O O
999
+ P P
1000
+ Q Q
1001
+ R R
1002
+ S S
1003
+ T T
1004
+ U U
1005
+ V V
1006
+ W W
1007
+ X X
1008
+ Y Y
1009
+ Z Z
1010
+ [ [
1011
+ \ \
1012
+ ] ]
1013
+ ^ ^
1014
+ _ _
1015
+ ` `
1016
+ a a
1017
+ b b
1018
+ c c
1019
+ d d
1020
+ e e
1021
+ f f
1022
+ g g
1023
+ h h
1024
+ i i
1025
+ j j
1026
+ k k
1027
+ l l
1028
+ m m
1029
+ n n
1030
+ o o
1031
+ p p
1032
+ q q
1033
+ r r
1034
+ s s
1035
+ t t
1036
+ u u
1037
+ v v
1038
+ w w
1039
+ x x
1040
+ y y
1041
+ z z
1042
+ { {
1043
+ | |
1044
+ } }
1045
+ ~ ~
1046
+ ⦅ ((
1047
+ ⦆ ))
1048
+ 。 .
1049
+ 、 ,