-
Notifications
You must be signed in to change notification settings - Fork 108
/
locale.html
445 lines (399 loc) · 23.8 KB
/
locale.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
<emu-clause id="locale-objects">
<h1>Locale Objects</h1>
<emu-clause id="sec-intl-locale-constructor">
<h1>The Intl.Locale Constructor</h1>
<p>
The Locale constructor is the <dfn>%Intl.Locale%</dfn> intrinsic object and a standard built-in property of the Intl object.
</p>
<emu-clause id="sec-Intl.Locale">
<h1>Intl.Locale ( _tag_ [ , _options_ ] )</h1>
<p>
When the `Intl.Locale` function is called with an argument _tag_ and an optional argument _options_, the following steps are taken:
</p>
<emu-alg>
1. If NewTarget is *undefined*, throw a *TypeError* exception.
1. Let _relevantExtensionKeys_ be %Intl.Locale%.[[RelevantExtensionKeys]].
1. Let _internalSlotsList_ be « [[InitializedLocale]], [[Locale]], [[Calendar]], [[Collation]], [[HourCycle]], [[NumberingSystem]] ».
1. If _relevantExtensionKeys_ contains *"kf"*, then
1. Append [[CaseFirst]] to _internalSlotsList_.
1. If _relevantExtensionKeys_ contains *"kn"*, then
1. Append [[Numeric]] to _internalSlotsList_.
1. Let _locale_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%Intl.Locale.prototype%"*, _internalSlotsList_).
1. If Type(_tag_) is not String or Object, throw a *TypeError* exception.
1. If Type(_tag_) is Object and _tag_ has an [[InitializedLocale]] internal slot, then
1. Let _tag_ be _tag_.[[Locale]].
1. Else,
1. Let _tag_ be ? ToString(_tag_).
1. Set _options_ to ? CoerceOptionsToObject(_options_).
1. Set _tag_ to ? ApplyOptionsToTag(_tag_, _options_).
1. Let _opt_ be a new Record.
1. Let _calendar_ be ? GetOption(_options_, *"calendar"*, ~string~, ~empty~, *undefined*).
1. If _calendar_ is not *undefined*, then
1. If _calendar_ cannot be matched by the <code>type</code> Unicode locale nonterminal, throw a *RangeError* exception.
1. Set _opt_.[[ca]] to _calendar_.
1. Let _collation_ be ? GetOption(_options_, *"collation"*, ~string~, ~empty~, *undefined*).
1. If _collation_ is not *undefined*, then
1. If _collation_ cannot be matched by the <code>type</code> Unicode locale nonterminal, throw a *RangeError* exception.
1. Set _opt_.[[co]] to _collation_.
1. Let _hc_ be ? GetOption(_options_, *"hourCycle"*, ~string~, « *"h11"*, *"h12"*, *"h23"*, *"h24"* », *undefined*).
1. Set _opt_.[[hc]] to _hc_.
1. Let _kf_ be ? GetOption(_options_, *"caseFirst"*, ~string~, « *"upper"*, *"lower"*, *"false"* », *undefined*).
1. Set _opt_.[[kf]] to _kf_.
1. Let _kn_ be ? GetOption(_options_, *"numeric"*, ~boolean~, ~empty~, *undefined*).
1. If _kn_ is not *undefined*, set _kn_ to ! ToString(_kn_).
1. Set _opt_.[[kn]] to _kn_.
1. Let _numberingSystem_ be ? GetOption(_options_, *"numberingSystem"*, ~string~, ~empty~, *undefined*).
1. If _numberingSystem_ is not *undefined*, then
1. If _numberingSystem_ cannot be matched by the <code>type</code> Unicode locale nonterminal, throw a *RangeError* exception.
1. Set _opt_.[[nu]] to _numberingSystem_.
1. Let _r_ be ApplyUnicodeExtensionToTag(_tag_, _opt_, _relevantExtensionKeys_).
1. Set _locale_.[[Locale]] to _r_.[[locale]].
1. Set _locale_.[[Calendar]] to _r_.[[ca]].
1. Set _locale_.[[Collation]] to _r_.[[co]].
1. Set _locale_.[[HourCycle]] to _r_.[[hc]].
1. If _relevantExtensionKeys_ contains *"kf"*, then
1. Set _locale_.[[CaseFirst]] to _r_.[[kf]].
1. If _relevantExtensionKeys_ contains *"kn"*, then
1. If SameValue(_r_.[[kn]], *"true"*) is *true* or _r_.[[kn]] is the empty String, then
1. Set _locale_.[[Numeric]] to *true*.
1. Else,
1. Set _locale_.[[Numeric]] to *false*.
1. Set _locale_.[[NumberingSystem]] to _r_.[[nu]].
1. Return _locale_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-apply-options-to-tag" type="abstract operation">
<h1>
ApplyOptionsToTag (
_tag_: a String,
_options_: an Object,
): either a normal completion containing a Unicode canonicalized locale identifier or a throw completion
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If IsStructurallyValidLanguageTag(_tag_) is *false*, throw a *RangeError* exception.
1. Let _language_ be ? GetOption(_options_, *"language"*, ~string~, ~empty~, *undefined*).
1. If _language_ is not *undefined*, then
1. If _language_ cannot be matched by the <code>unicode_language_subtag</code> Unicode locale nonterminal, throw a *RangeError* exception.
1. Let _script_ be ? GetOption(_options_, *"script"*, ~string~, ~empty~, *undefined*).
1. If _script_ is not *undefined*, then
1. If _script_ cannot be matched by the <code>unicode_script_subtag</code> Unicode locale nonterminal, throw a *RangeError* exception.
1. Let _region_ be ? GetOption(_options_, *"region"*, ~string~, ~empty~, *undefined*).
1. If _region_ is not *undefined*, then
1. If _region_ cannot be matched by the <code>unicode_region_subtag</code> Unicode locale nonterminal, throw a *RangeError* exception.
1. Set _tag_ to CanonicalizeUnicodeLocaleId(_tag_).
1. Assert: _tag_ can be matched by the <code>unicode_locale_id</code> Unicode locale nonterminal.
1. Let _languageId_ be the longest prefix of _tag_ matched by the <code>unicode_language_id</code> Unicode locale nonterminal.
1. If _language_ is *undefined*, set _language_ to GetLocaleLanguage(_languageId_).
1. If _script_ is *undefined*, set _script_ to GetLocaleScript(_languageId_).
1. If _region_ is *undefined*, set _region_ to GetLocaleRegion(_languageId_).
1. Let _variants_ be GetLocaleVariants(_languageId_).
1. Set _languageId_ to _language_.
1. If _script_ is not *undefined*, set _languageId_ to the string-concatenation of _languageId_, *"-"*, and _script_.
1. If _region_ is not *undefined*, set _languageId_ to the string-concatenation of _languageId_, *"-"*, and _region_.
1. If _variants_ is not *undefined*, set _languageId_ to the string-concatenation of _languageId_, *"-"*, and _variants_.
1. Set _tag_ to _tag_ with the <emu-not-ref>substring</emu-not-ref> matched by the <code>unicode_language_id</code> Unicode locale nonterminal replaced by the string _languageId_.
1. Return CanonicalizeUnicodeLocaleId(_tag_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-apply-unicode-extension-to-tag" type="abstract operation">
<h1>
ApplyUnicodeExtensionToTag (
_tag_: a String,
_options_: a Record,
_relevantExtensionKeys_: a List of Strings,
): a Record
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _tag_ can be matched by the <code>unicode_locale_id</code> Unicode locale nonterminal.
1. If _tag_ contains a <emu-not-ref>substring</emu-not-ref> that is a Unicode locale extension sequence, then
1. Let _extension_ be the String value consisting of the <emu-not-ref>substring</emu-not-ref> of the Unicode locale extension sequence within _tag_.
1. Let _components_ be UnicodeExtensionComponents(_extension_).
1. Let _attributes_ be _components_.[[Attributes]].
1. Let _keywords_ be _components_.[[Keywords]].
1. Else,
1. Let _attributes_ be a new empty List.
1. Let _keywords_ be a new empty List.
1. Let _result_ be a new Record.
1. For each element _key_ of _relevantExtensionKeys_, do
1. Let _value_ be *undefined*.
1. If _keywords_ contains an element whose [[Key]] is the same as _key_, then
1. Let _entry_ be the element of _keywords_ whose [[Key]] is the same as _key_.
1. Set _value_ to _entry_.[[Value]].
1. Else,
1. Let _entry_ be ~empty~.
1. Assert: _options_ has a field [[<_key_>]].
1. Let _optionsValue_ be _options_.[[<_key_>]].
1. If _optionsValue_ is not *undefined*, then
1. Assert: Type(_optionsValue_) is String.
1. Set _value_ to _optionsValue_.
1. If _entry_ is not ~empty~, then
1. Set _entry_.[[Value]] to _value_.
1. Else,
1. Append the Record { [[Key]]: _key_, [[Value]]: _value_ } to _keywords_.
1. Set _result_.[[<_key_>]] to _value_.
1. Let _locale_ be the String value that is _tag_ with any Unicode locale extension sequences removed.
1. Let _newExtension_ be a Unicode BCP 47 U Extension based on _attributes_ and _keywords_.
1. If _newExtension_ is not the empty String, then
1. Set _locale_ to InsertUnicodeExtensionAndCanonicalize(_locale_, _newExtension_).
1. Set _result_.[[locale]] to _locale_.
1. Return _result_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-intl-locale-constructor">
<h1>Properties of the Intl.Locale Constructor</h1>
<p>
The Intl.Locale constructor has the following properties:
</p>
<emu-clause id="sec-Intl.Locale.prototype">
<h1>Intl.Locale.prototype</h1>
<p>
The value of `Intl.Locale.prototype` is %Intl.Locale.prototype%.
</p>
<p>
This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.
</p>
</emu-clause>
<emu-clause id="sec-intl.locale-internal-slots">
<h1>Internal slots</h1>
<p>
The value of the [[RelevantExtensionKeys]] internal slot is « *"ca"*, *"co"*, *"hc"*, *"kf"*, *"kn"*, *"nu"* ». If %Intl.Collator%.[[RelevantExtensionKeys]] does not contain *"kf"*, then remove *"kf"* from %Intl.Locale%.[[RelevantExtensionKeys]]. If %Intl.Collator%.[[RelevantExtensionKeys]] does not contain *"kn"*, then remove *"kn"* from %Intl.Locale%.[[RelevantExtensionKeys]].
</p>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-intl-locale-prototype-object">
<h1>Properties of the Intl.Locale Prototype Object</h1>
<p>
The Intl.Locale prototype object is itself an ordinary object. <dfn>%Intl.Locale.prototype%</dfn> is not an Intl.Locale instance and does not have an [[InitializedLocale]] internal slot or any of the other internal slots of Intl.Locale instance objects.
</p>
<emu-clause id="sec-Intl.Locale.prototype.constructor">
<h1>Intl.Locale.prototype.constructor</h1>
<p>
The initial value of `Intl.Locale.prototype.constructor` is %Intl.Locale%.
</p>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype-@@tostringtag">
<h1>Intl.Locale.prototype[ @@toStringTag ]</h1>
<p>
The initial value of the @@toStringTag property is the String value *"Intl.Locale"*.
</p>
<p>
This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
</p>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.maximize">
<h1>Intl.Locale.prototype.maximize ( )</h1>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Let _maximal_ be the result of the <a href="https://unicode.org/reports/tr35/#Likely_Subtags">Add Likely Subtags</a> algorithm applied to _loc_.[[Locale]]. If an error is signaled, set _maximal_ to _loc_.[[Locale]].
1. Return ! Construct(%Intl.Locale%, _maximal_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.minimize">
<h1>Intl.Locale.prototype.minimize ( )</h1>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Let _minimal_ be the result of the <a href="https://unicode.org/reports/tr35/#Likely_Subtags">Remove Likely Subtags</a> algorithm applied to _loc_.[[Locale]]. If an error is signaled, set _minimal_ to _loc_.[[Locale]].
1. Return ! Construct(%Intl.Locale%, _minimal_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.toString">
<h1>Intl.Locale.prototype.toString ( )</h1>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return _loc_.[[Locale]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.baseName">
<h1>get Intl.Locale.prototype.baseName</h1>
<p>`Intl.Locale.prototype.baseName` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Let _locale_ be _loc_.[[Locale]].
1. Return the longest prefix of _locale_ matched by the <code>unicode_language_id</code> Unicode locale nonterminal.
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.calendar">
<h1>get Intl.Locale.prototype.calendar</h1>
<p>`Intl.Locale.prototype.calendar` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return _loc_.[[Calendar]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.caseFirst">
<h1>get Intl.Locale.prototype.caseFirst</h1>
<p>This property only exists if %Intl.Locale%.[[RelevantExtensionKeys]] contains *"kf"*.</p>
<p>`Intl.Locale.prototype.caseFirst` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return _loc_.[[CaseFirst]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.collation">
<h1>get Intl.Locale.prototype.collation</h1>
<p>`Intl.Locale.prototype.collation` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return _loc_.[[Collation]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.hourCycle">
<h1>get Intl.Locale.prototype.hourCycle</h1>
<p>`Intl.Locale.prototype.hourCycle` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return _loc_.[[HourCycle]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.numeric">
<h1>get Intl.Locale.prototype.numeric</h1>
<p>This property only exists if %Intl.Locale%.[[RelevantExtensionKeys]] contains *"kn"*.</p>
<p>`Intl.Locale.prototype.numeric` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return _loc_.[[Numeric]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.numberingSystem">
<h1>get Intl.Locale.prototype.numberingSystem</h1>
<p>`Intl.Locale.prototype.numberingSystem` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return _loc_.[[NumberingSystem]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.language">
<h1>get Intl.Locale.prototype.language</h1>
<p>`Intl.Locale.prototype.language` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return GetLocaleLanguage(_loc_.[[Locale]]).
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.script">
<h1>get Intl.Locale.prototype.script</h1>
<p>`Intl.Locale.prototype.script` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return GetLocaleScript(_loc_.[[Locale]]).
</emu-alg>
</emu-clause>
<emu-clause id="sec-Intl.Locale.prototype.region">
<h1>get Intl.Locale.prototype.region</h1>
<p>`Intl.Locale.prototype.region` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _loc_ be the *this* value.
1. Perform ? RequireInternalSlot(_loc_, [[InitializedLocale]]).
1. Return GetLocaleRegion(_loc_.[[Locale]]).
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-intl-locale-instances">
<h1>Properties of Intl.Locale Instances</h1>
<p>
Intl.Locale instances are ordinary objects that inherit properties from %Intl.Locale.prototype%.
</p>
<p>
Intl.Locale instances have an [[InitializedLocale]] internal slot.
</p>
<p>
Intl.Locale instances also have several internal slots that are computed by the constructor:
</p>
<ul>
<li>[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.</li>
<li>[[Calendar]] is a String value that is a syntactically valid type value as given in <a href="https://unicode.org/reports/tr35/#Unicode_locale_identifier">Unicode Technical Standard #35 Part 1 Core, Section 3.2 Unicode Locale Identifier</a>, or is *undefined*.</li>
<li>[[Collation]] is a String value that is a syntactically valid type value as given in <a href="https://unicode.org/reports/tr35/#Unicode_locale_identifier">Unicode Technical Standard #35 Part 1 Core, Section 3.2 Unicode Locale Identifier</a>, or is *undefined*.</li>
<li>[[HourCycle]] is a String value that is a syntactically valid type value as given in <a href="https://unicode.org/reports/tr35/#Unicode_locale_identifier">Unicode Technical Standard #35 Part 1 Core, Section 3.2 Unicode Locale Identifier</a>, or is *undefined*.</li>
<li>[[NumberingSystem]] is a String value that is a syntactically valid type value as given in <a href="https://unicode.org/reports/tr35/#Unicode_locale_identifier">Unicode Technical Standard #35 Part 1 Core, Section 3.2 Unicode Locale Identifier</a>, or is *undefined*.</li>
<li>[[CaseFirst]] is a String value that is a syntactically valid type value as given in <a href="https://unicode.org/reports/tr35/#Unicode_locale_identifier">Unicode Technical Standard #35 Part 1 Core, Section 3.2 Unicode Locale Identifier</a>, or is *undefined*. This internal slot only exists if the [[RelevantExtensionKeys]] internal slot of %Intl.Locale% contains *"kf"*.</li>
<li>[[Numeric]] is a Boolean value specifying whether numeric sorting is used by the locale, or is *undefined*. This internal slot only exists if the [[RelevantExtensionKeys]] internal slot of %Intl.Locale% contains *"kn"*.</li>
</ul>
</emu-clause>
<emu-clause id="sec-intl-locale-abstracts">
<h1>Abstract Operations for Locale Objects</h1>
<emu-clause id="sec-getlocalelanguage" type="abstract operation">
<h1>
GetLocaleLanguage (
_locale_: a String,
): a String
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _locale_ can be matched by the <code>unicode_locale_id</code> Unicode locale nonterminal.
1. Let _languageId_ be the longest prefix of _locale_ matched by the <code>unicode_language_id</code> Unicode locale nonterminal.
1. Assert: The first subtag of _languageId_ can be matched by the <code>unicode_language_subtag</code> Unicode locale nonterminal.
1. Return the first subtag of _languageId_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-getlocalescript" type="abstract operation">
<h1>
GetLocaleScript (
_locale_: a String,
): a String or *undefined*
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _locale_ can be matched by the <code>unicode_locale_id</code> Unicode locale nonterminal.
1. Let _languageId_ be the longest prefix of _locale_ matched by the <code>unicode_language_id</code> Unicode locale nonterminal.
1. Assert: _languageId_ contains at most one subtag that can be matched by the <code>unicode_script_subtag</code> Unicode locale nonterminal.
1. If _languageId_ contains a subtag matched by the <code>unicode_script_subtag</code> Unicode locale nonterminal, return that subtag.
1. Return *undefined*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-getlocaleregion" type="abstract operation">
<h1>
GetLocaleRegion (
_locale_: a String,
): a String or *undefined*
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _locale_ can be matched by the <code>unicode_locale_id</code> Unicode locale nonterminal.
1. Let _languageId_ be the longest prefix of _locale_ matched by the <code>unicode_language_id</code> Unicode locale nonterminal.
1. NOTE: A <code>unicode_region_subtag</code> subtag is only valid immediately after an initial <code>unicode_language_subtag</code> subtag, optionally with a single <code>unicode_script_subtag</code> subtag between them. In that position, <code>unicode_region_subtag</code> cannot be confused with any other valid subtag because all their productions are disjoint.
1. Assert: The first subtag of _languageId_ can be matched by the <code>unicode_language_subtag</code> Unicode locale nonterminal.
1. Let _languageIdTail_ be the suffix of _languageId_ following the first subtag.
1. Assert: _languageIdTail_ contains at most one subtag that can be matched by the <code>unicode_region_subtag</code> Unicode locale nonterminal.
1. If _languageIdTail_ contains a subtag matched by the <code>unicode_region_subtag</code> Unicode locale nonterminal, return that subtag.
1. Return *undefined*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-getlocalevariants" type="abstract operation">
<h1>
GetLocaleVariants (
_locale_: a String,
): a String or *undefined*
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _locale_ can be matched by the <code>unicode_locale_id</code> Unicode locale nonterminal.
1. Let _languageId_ be the longest prefix of _locale_ matched by the <code>unicode_language_id</code> Unicode locale nonterminal.
1. If there is a non-empty suffix of _languageId_ that is a consecutive sequence of <emu-not-ref>substrings</emu-not-ref> in which each element is a *"-"* followed by a <emu-not-ref>substring</emu-not-ref> that is matched by the <code>unicode_variant_subtag</code> Unicode locale nonterminal, then
1. Let _variants_ be the longest such suffix.
1. Return the substring of _variants_ from 1.
1. Return *undefined*.
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>