typograf 6.14.1 → 6.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3143 @@
1
+ /*! typograf | © 2022 Denis Seleznev | MIT License | https://github.com/typograf/typograf */
2
+ function _typeof(obj) {
3
+ "@babel/helpers - typeof";
4
+
5
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
6
+ return typeof obj;
7
+ } : function (obj) {
8
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
9
+ }, _typeof(obj);
10
+ }
11
+
12
+ function _classCallCheck(instance, Constructor) {
13
+ if (!(instance instanceof Constructor)) {
14
+ throw new TypeError("Cannot call a class as a function");
15
+ }
16
+ }
17
+
18
+ function _defineProperties(target, props) {
19
+ for (var i = 0; i < props.length; i++) {
20
+ var descriptor = props[i];
21
+ descriptor.enumerable = descriptor.enumerable || false;
22
+ descriptor.configurable = true;
23
+ if ("value" in descriptor) descriptor.writable = true;
24
+ Object.defineProperty(target, descriptor.key, descriptor);
25
+ }
26
+ }
27
+
28
+ function _createClass(Constructor, protoProps, staticProps) {
29
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
30
+ if (staticProps) _defineProperties(Constructor, staticProps);
31
+ Object.defineProperty(Constructor, "prototype", {
32
+ writable: false
33
+ });
34
+ return Constructor;
35
+ }
36
+
37
+ function _slicedToArray(arr, i) {
38
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
39
+ }
40
+
41
+ function _arrayWithHoles(arr) {
42
+ if (Array.isArray(arr)) return arr;
43
+ }
44
+
45
+ function _iterableToArrayLimit(arr, i) {
46
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
47
+
48
+ if (_i == null) return;
49
+ var _arr = [];
50
+ var _n = true;
51
+ var _d = false;
52
+
53
+ var _s, _e;
54
+
55
+ try {
56
+ for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
57
+ _arr.push(_s.value);
58
+
59
+ if (i && _arr.length === i) break;
60
+ }
61
+ } catch (err) {
62
+ _d = true;
63
+ _e = err;
64
+ } finally {
65
+ try {
66
+ if (!_n && _i["return"] != null) _i["return"]();
67
+ } finally {
68
+ if (_d) throw _e;
69
+ }
70
+ }
71
+
72
+ return _arr;
73
+ }
74
+
75
+ function _unsupportedIterableToArray(o, minLen) {
76
+ if (!o) return;
77
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
78
+ var n = Object.prototype.toString.call(o).slice(8, -1);
79
+ if (n === "Object" && o.constructor) n = o.constructor.name;
80
+ if (n === "Map" || n === "Set") return Array.from(o);
81
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
82
+ }
83
+
84
+ function _arrayLikeToArray(arr, len) {
85
+ if (len == null || len > arr.length) len = arr.length;
86
+
87
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
88
+
89
+ return arr2;
90
+ }
91
+
92
+ function _nonIterableRest() {
93
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
94
+ }
95
+
96
+ var groupIndexes = {
97
+ symbols: 110,
98
+ space: 210,
99
+ dash: 310,
100
+ punctuation: 410,
101
+ nbsp: 510,
102
+ 'number': 610,
103
+ money: 710,
104
+ date: 810,
105
+ other: 910,
106
+ optalign: 1010,
107
+ typo: 1110,
108
+ html: 1210
109
+ };
110
+
111
+ // http://www.w3.org/TR/html4/sgml/entities
112
+ var visibleEntities = [['iexcl', 161], ['cent', 162], ['pound', 163], ['curren', 164], ['yen', 165], ['brvbar', 166], ['sect', 167], ['uml', 168], ['copy', 169], ['ordf', 170], ['laquo', 171], ['not', 172], ['reg', 174], ['macr', 175], ['deg', 176], ['plusmn', 177], ['sup2', 178], ['sup3', 179], ['acute', 180], ['micro', 181], ['para', 182], ['middot', 183], ['cedil', 184], ['sup1', 185], ['ordm', 186], ['raquo', 187], ['frac14', 188], ['frac12', 189], ['frac34', 190], ['iquest', 191], ['Agrave', 192], ['Aacute', 193], ['Acirc', 194], ['Atilde', 195], ['Auml', 196], ['Aring', 197], ['AElig', 198], ['Ccedil', 199], ['Egrave', 200], ['Eacute', 201], ['Ecirc', 202], ['Euml', 203], ['Igrave', 204], ['Iacute', 205], ['Icirc', 206], ['Iuml', 207], ['ETH', 208], ['Ntilde', 209], ['Ograve', 210], ['Oacute', 211], ['Ocirc', 212], ['Otilde', 213], ['Ouml', 214], ['times', 215], ['Oslash', 216], ['Ugrave', 217], ['Uacute', 218], ['Ucirc', 219], ['Uuml', 220], ['Yacute', 221], ['THORN', 222], ['szlig', 223], ['agrave', 224], ['aacute', 225], ['acirc', 226], ['atilde', 227], ['auml', 228], ['aring', 229], ['aelig', 230], ['ccedil', 231], ['egrave', 232], ['eacute', 233], ['ecirc', 234], ['euml', 235], ['igrave', 236], ['iacute', 237], ['icirc', 238], ['iuml', 239], ['eth', 240], ['ntilde', 241], ['ograve', 242], ['oacute', 243], ['ocirc', 244], ['otilde', 245], ['ouml', 246], ['divide', 247], ['oslash', 248], ['ugrave', 249], ['uacute', 250], ['ucirc', 251], ['uuml', 252], ['yacute', 253], ['thorn', 254], ['yuml', 255], ['fnof', 402], ['Alpha', 913], ['Beta', 914], ['Gamma', 915], ['Delta', 916], ['Epsilon', 917], ['Zeta', 918], ['Eta', 919], ['Theta', 920], ['Iota', 921], ['Kappa', 922], ['Lambda', 923], ['Mu', 924], ['Nu', 925], ['Xi', 926], ['Omicron', 927], ['Pi', 928], ['Rho', 929], ['Sigma', 931], ['Tau', 932], ['Upsilon', 933], ['Phi', 934], ['Chi', 935], ['Psi', 936], ['Omega', 937], ['alpha', 945], ['beta', 946], ['gamma', 947], ['delta', 948], ['epsilon', 949], ['zeta', 950], ['eta', 951], ['theta', 952], ['iota', 953], ['kappa', 954], ['lambda', 955], ['mu', 956], ['nu', 957], ['xi', 958], ['omicron', 959], ['pi', 960], ['rho', 961], ['sigmaf', 962], ['sigma', 963], ['tau', 964], ['upsilon', 965], ['phi', 966], ['chi', 967], ['psi', 968], ['omega', 969], ['thetasym', 977], ['upsih', 978], ['piv', 982], ['bull', 8226], ['hellip', 8230], ['prime', 8242], ['Prime', 8243], ['oline', 8254], ['frasl', 8260], ['weierp', 8472], ['image', 8465], ['real', 8476], ['trade', 8482], ['alefsym', 8501], ['larr', 8592], ['uarr', 8593], ['rarr', 8594], ['darr', 8595], ['harr', 8596], ['crarr', 8629], ['lArr', 8656], ['uArr', 8657], ['rArr', 8658], ['dArr', 8659], ['hArr', 8660], ['forall', 8704], ['part', 8706], ['exist', 8707], ['empty', 8709], ['nabla', 8711], ['isin', 8712], ['notin', 8713], ['ni', 8715], ['prod', 8719], ['sum', 8721], ['minus', 8722], ['lowast', 8727], ['radic', 8730], ['prop', 8733], ['infin', 8734], ['ang', 8736], ['and', 8743], ['or', 8744], ['cap', 8745], ['cup', 8746], ['int', 8747], ['there4', 8756], ['sim', 8764], ['cong', 8773], ['asymp', 8776], ['ne', 8800], ['equiv', 8801], ['le', 8804], ['ge', 8805], ['sub', 8834], ['sup', 8835], ['nsub', 8836], ['sube', 8838], ['supe', 8839], ['oplus', 8853], ['otimes', 8855], ['perp', 8869], ['sdot', 8901], ['lceil', 8968], ['rceil', 8969], ['lfloor', 8970], ['rfloor', 8971], ['lang', 9001], ['rang', 9002], ['spades', 9824], ['clubs', 9827], ['hearts', 9829], ['diams', 9830], ['loz', 9674], ['OElig', 338], ['oelig', 339], ['Scaron', 352], ['scaron', 353], ['Yuml', 376], ['circ', 710], ['tilde', 732], ['ndash', 8211], ['mdash', 8212], ['lsquo', 8216], ['rsquo', 8217], ['sbquo', 8218], ['ldquo', 8220], ['rdquo', 8221], ['bdquo', 8222], ['dagger', 8224], ['Dagger', 8225], ['permil', 8240], ['lsaquo', 8249], ['rsaquo', 8250], ['euro', 8364], ['NestedGreaterGreater', 8811], ['NestedLessLess', 8810]];
113
+
114
+ var invisibleEntities = [['nbsp', 160], ['thinsp', 8201], ['ensp', 8194], ['emsp', 8195], ['shy', 173], ['zwnj', 8204], ['zwj', 8205], ['lrm', 8206], ['rlm', 8207]];
115
+
116
+ var HtmlEntities = /*#__PURE__*/function () {
117
+ function HtmlEntities() {
118
+ _classCallCheck(this, HtmlEntities);
119
+
120
+ this._entities = this._prepareEntities([].concat(visibleEntities, invisibleEntities));
121
+ this._entitiesByName = {};
122
+ this._entitiesByNameEntity = {};
123
+ this._entitiesByDigitEntity = {};
124
+ this._entitiesByUtf = {};
125
+
126
+ this._entities.forEach(function (entity) {
127
+ this._entitiesByName[entity.name] = entity;
128
+ this._entitiesByNameEntity[entity.nameEntity] = entity;
129
+ this._entitiesByDigitEntity[entity.digitEntity] = entity;
130
+ this._entitiesByUtf[entity.utf] = entity;
131
+ }, this);
132
+
133
+ this._invisibleEntities = this._prepareEntities(invisibleEntities);
134
+ }
135
+ /**
136
+ * Entities as name or digit to UTF-8.
137
+ *
138
+ * @param {Object} context
139
+ */
140
+
141
+
142
+ _createClass(HtmlEntities, [{
143
+ key: "toUtf",
144
+ value: function toUtf(context) {
145
+ var _this = this;
146
+
147
+ if (context.text.search(/&#/) !== -1) {
148
+ context.text = this.decHexToUtf(context.text);
149
+ }
150
+
151
+ if (context.text.search(/&[a-z]/i) !== -1) {
152
+ // 2 - min length of entity without & and ;. Example: &DD;
153
+ // 31 - max length of entity without & and ;. Example: &CounterClockwiseContourIntegral;
154
+ context.text = context.text.replace(/&[a-z\d]{2,31};/gi, function (key) {
155
+ var entity = _this._entitiesByNameEntity[key];
156
+ return entity ? entity.utf : key;
157
+ });
158
+ }
159
+ }
160
+ /**
161
+ * Entities in decimal or hexadecimal form to UTF-8.
162
+ *
163
+ * @param {string} text
164
+ * @returns {string}
165
+ */
166
+
167
+ }, {
168
+ key: "decHexToUtf",
169
+ value: function decHexToUtf(text) {
170
+ return text.replace(/&#(\d{1,6});/gi, function ($0, $1) {
171
+ return String.fromCharCode(parseInt($1, 10));
172
+ }).replace(/&#x([\da-f]{1,6});/gi, function ($0, $1) {
173
+ return String.fromCharCode(parseInt($1, 16));
174
+ });
175
+ }
176
+ /**
177
+ * Restore HTML entities in text.
178
+ *
179
+ * @param {Object} context
180
+ */
181
+
182
+ }, {
183
+ key: "restore",
184
+ value: function restore(context) {
185
+ var params = context.prefs.htmlEntity;
186
+ var type = params.type;
187
+ var entities = this._entities;
188
+
189
+ if (type === 'name' || type === 'digit') {
190
+ if (params.onlyInvisible || params.list) {
191
+ entities = [];
192
+
193
+ if (params.onlyInvisible) {
194
+ entities = entities.concat(this._invisibleEntities);
195
+ }
196
+
197
+ if (params.list) {
198
+ entities = entities.concat(this._prepareListParam(params.list));
199
+ }
200
+ }
201
+
202
+ context.text = this._restoreEntitiesByIndex(context.text, type + 'Entity', entities);
203
+ }
204
+ }
205
+ /**
206
+ * Get a entity by utf using the type.
207
+ *
208
+ * @param {string} symbol
209
+ * @param {string} [type]
210
+ * @returns {string}
211
+ */
212
+
213
+ }, {
214
+ key: "getByUtf",
215
+ value: function getByUtf(symbol, type) {
216
+ var result = '';
217
+
218
+ switch (type) {
219
+ case 'digit':
220
+ result = this._entitiesByDigitEntity[symbol];
221
+ break;
222
+
223
+ case 'name':
224
+ result = this._entitiesByNameEntity[symbol];
225
+ break;
226
+
227
+ default:
228
+ result = symbol;
229
+ break;
230
+ }
231
+
232
+ return result;
233
+ }
234
+ }, {
235
+ key: "_prepareEntities",
236
+ value: function _prepareEntities(entities) {
237
+ var result = [];
238
+ entities.forEach(function (entity) {
239
+ var _entity = _slicedToArray(entity, 2),
240
+ name = _entity[0],
241
+ digit = _entity[1];
242
+
243
+ var utf = String.fromCharCode(digit);
244
+ result.push({
245
+ name: name,
246
+ nameEntity: '&' + name + ';',
247
+ // &nbsp;
248
+ digitEntity: '&#' + digit + ';',
249
+ // &#160;
250
+ utf: utf,
251
+ // \u00A0
252
+ reName: new RegExp('&' + name + ';', 'g'),
253
+ reUtf: new RegExp(utf, 'g')
254
+ });
255
+ }, this);
256
+ return result;
257
+ }
258
+ }, {
259
+ key: "_prepareListParam",
260
+ value: function _prepareListParam(list) {
261
+ var result = [];
262
+ list.forEach(function (name) {
263
+ var entity = this._entitiesByName[name];
264
+
265
+ if (entity) {
266
+ result.push(entity);
267
+ }
268
+ }, this);
269
+ return result;
270
+ }
271
+ }, {
272
+ key: "_restoreEntitiesByIndex",
273
+ value: function _restoreEntitiesByIndex(text, type, entities) {
274
+ entities.forEach(function (entity) {
275
+ text = text.replace(entity.reUtf, entity[type]);
276
+ });
277
+ return text;
278
+ }
279
+ }]);
280
+
281
+ return HtmlEntities;
282
+ }();
283
+
284
+ var HtmlEntities$1 = new HtmlEntities();
285
+ /**
286
+ * @typedef HtmlEntity
287
+ *
288
+ * @property {string} type - 'default' - UTF-8, 'digit' - &#160;, 'name' - &nbsp;
289
+ * @property {boolean} [onlyInvisible]
290
+ * @property {string[]} [list]
291
+ */
292
+
293
+ var locales = [];
294
+ /**
295
+ * Add a locale.
296
+ *
297
+ * @param {string} locale
298
+ */
299
+
300
+ function addLocale(locale) {
301
+ var code = (locale || '').split('/')[0];
302
+
303
+ if (code && code !== 'common' && !hasLocale(code)) {
304
+ locales.push(code);
305
+ locales.sort();
306
+ }
307
+ }
308
+ /**
309
+ * Get locales.
310
+ *
311
+ * @returns {Array}
312
+ */
313
+
314
+ function getLocales() {
315
+ return locales;
316
+ }
317
+ /**
318
+ * Has a locale.
319
+ *
320
+ * @param {string} locale
321
+ *
322
+ * @returns {boolean}
323
+ */
324
+
325
+ function hasLocale(locale) {
326
+ return locale === 'common' || locales.indexOf(locale) !== -1;
327
+ }
328
+ function prepareLocale(locale1, locale2) {
329
+ var locale = locale1 || locale2;
330
+ var result = locale;
331
+
332
+ if (!Array.isArray(locale)) {
333
+ result = [locale];
334
+ }
335
+
336
+ return result;
337
+ }
338
+
339
+ var data = {};
340
+ /**
341
+ * Get data for use in rules.
342
+ *
343
+ * @param {string} key
344
+ *
345
+ * @returns {*}
346
+ */
347
+
348
+ function getData(key) {
349
+ return data[key];
350
+ }
351
+ /**
352
+ * Set data for use in rules.
353
+ *
354
+ * @param {string|Object} key
355
+ * @param {*} [value]
356
+ */
357
+
358
+ function setData(key, value) {
359
+ if (typeof key === 'string') {
360
+ addLocale(key);
361
+ data[key] = value;
362
+ } else if (_typeof(key) === 'object') {
363
+ Object.keys(key).forEach(function (k) {
364
+ addLocale(k);
365
+ data[k] = key[k];
366
+ });
367
+ }
368
+ }
369
+
370
+ var inlineElements = ['a', 'abbr', 'acronym', 'b', 'bdo', 'big', 'br', 'button', 'cite', 'code', 'dfn', 'em', 'i', 'img', 'input', 'kbd', 'label', 'map', 'object', 'q', 'samp', 'script', 'select', 'small', 'span', 'strong', 'sub', 'sup', 'textarea', 'time', 'tt', 'var'];
371
+
372
+ var regExpUrl = new RegExp('(https?|file|ftp)://([a-zA-Z0-9/+-=%&:_.~?]+[a-zA-Z0-9#+]*)', 'g');
373
+ var regExpNumber = '\\d+([.,]\\d+)?';
374
+ var regExpDigit = /\d/;
375
+ function isDigit(symbol) {
376
+ return symbol.search(regExpDigit) > -1;
377
+ }
378
+
379
+ var privateLabel = "\uF000";
380
+ var privateSeparateLabel = "\uF001";
381
+
382
+ var SafeTags = /*#__PURE__*/function () {
383
+ function SafeTags() {
384
+ _classCallCheck(this, SafeTags);
385
+
386
+ var html = [['<!--', '-->'], ['<!ENTITY', '>'], ['<!DOCTYPE', '>'], ['<\\?xml', '\\?>'], ['<!\\[CDATA\\[', '\\]\\]>']];
387
+ ['code', 'kbd', 'object', 'pre', 'samp', 'script', 'style', 'var'].forEach(function (tag) {
388
+ html.push(['<' + tag + '(\\s[^>]*?)?>', '</' + tag + '>']);
389
+ }, this);
390
+ this._tags = {
391
+ own: [],
392
+ html: html.map(this._prepareRegExp),
393
+ url: [regExpUrl]
394
+ };
395
+ this._groups = ['own', 'html', 'url'];
396
+ }
397
+ /**
398
+ * Add own safe tag.
399
+ *
400
+ * @param {RegExp|string[]} tag
401
+ */
402
+
403
+
404
+ _createClass(SafeTags, [{
405
+ key: "add",
406
+ value: function add(tag) {
407
+ this._tags.own.push(this._prepareRegExp(tag));
408
+ }
409
+ /**
410
+ * Show safe tags.
411
+ *
412
+ * @param {Object} context
413
+ * @param {string} group
414
+ */
415
+
416
+ }, {
417
+ key: "show",
418
+ value: function show(context, group) {
419
+ var reReplace = new RegExp(privateLabel + 'tf\\d+' + privateLabel, 'g');
420
+ var reSearch = new RegExp(privateLabel + 'tf\\d');
421
+
422
+ var replaceLabel = function replaceLabel(match) {
423
+ return context.safeTags.hidden[group][match] || match;
424
+ };
425
+
426
+ for (var i = 0, len = this._tags[group].length; i < len; i++) {
427
+ context.text = context.text.replace(reReplace, replaceLabel);
428
+
429
+ if (context.text.search(reSearch) === -1) {
430
+ break;
431
+ }
432
+ }
433
+ }
434
+ /**
435
+ * Hide safe tags.
436
+ *
437
+ * @param {Object} context
438
+ * @param {string} group
439
+ */
440
+
441
+ }, {
442
+ key: "hide",
443
+ value: function hide(context, group) {
444
+ context.safeTags = context.safeTags || {
445
+ hidden: {},
446
+ i: 0
447
+ };
448
+ context.safeTags.hidden[group] = {};
449
+
450
+ var pasteLabel = this._pasteLabel.bind(this, context, group);
451
+
452
+ this._tags[group].forEach(function (tag) {
453
+ context.text = context.text.replace(this._prepareRegExp(tag), pasteLabel);
454
+ }, this);
455
+ }
456
+ /**
457
+ * Hide HTML tags.
458
+ *
459
+ * @param {Object} context
460
+ */
461
+
462
+ }, {
463
+ key: "hideHTMLTags",
464
+ value: function hideHTMLTags(context) {
465
+ if (context.isHTML) {
466
+ var pasteLabel = this._pasteLabel.bind(this, context, 'html');
467
+
468
+ context.text = context.text.replace(/<\/?[a-z][^]*?>/gi, pasteLabel) // Tags
469
+ .replace(/&lt;\/?[a-z][^]*?&gt;/gi, pasteLabel) // Escaping tags
470
+ .replace(/&[gl]t;/gi, pasteLabel);
471
+ }
472
+ }
473
+ /**
474
+ * Get previous label.
475
+ *
476
+ * @param {string} text
477
+ * @param {number} position
478
+ *
479
+ * @returns {string|false}
480
+ */
481
+
482
+ }, {
483
+ key: "getPrevLabel",
484
+ value: function getPrevLabel(text, position) {
485
+ for (var i = position - 1; i >= 0; i--) {
486
+ if (text[i] === privateLabel) {
487
+ return text.slice(i, position + 1);
488
+ }
489
+ }
490
+
491
+ return false;
492
+ }
493
+ /**
494
+ * Get next label.
495
+ *
496
+ * @param {string} text
497
+ * @param {number} position
498
+ *
499
+ * @returns {string|false}
500
+ */
501
+
502
+ }, {
503
+ key: "getNextLabel",
504
+ value: function getNextLabel(text, position) {
505
+ for (var i = position + 1; i < text.length; i++) {
506
+ if (text[i] === privateLabel) {
507
+ return text.slice(position, i + 1);
508
+ }
509
+ }
510
+
511
+ return false;
512
+ }
513
+ /**
514
+ * Get a tag by a label.
515
+ *
516
+ * @param {Object} context
517
+ * @param {string} label
518
+ *
519
+ * @returns {Object|boolean}
520
+ */
521
+
522
+ }, {
523
+ key: "getTagByLabel",
524
+ value: function getTagByLabel(context, label) {
525
+ var result = false;
526
+
527
+ this._groups.some(function (group) {
528
+ var value = context.safeTags.hidden[group][label];
529
+
530
+ if (typeof value !== 'undefined') {
531
+ result = {
532
+ group: group,
533
+ value: value
534
+ };
535
+ }
536
+
537
+ return result;
538
+ });
539
+
540
+ return result;
541
+ }
542
+ /**
543
+ * Get info about a tag.
544
+ *
545
+ * @param {Object|undefined} tag
546
+ *
547
+ * @returns {Object|undefined}
548
+ */
549
+
550
+ }, {
551
+ key: "getTagInfo",
552
+ value: function getTagInfo(tag) {
553
+ if (!tag) {
554
+ return;
555
+ }
556
+
557
+ var result = {
558
+ group: tag.group
559
+ };
560
+
561
+ switch (tag.group) {
562
+ case 'html':
563
+ result.name = tag.value.split(/[<\s>]/)[1];
564
+ result.isInline = inlineElements.indexOf(result.name) > -1;
565
+ result.isClosing = tag.value.search(/^<\//) > -1;
566
+ break;
567
+
568
+ case 'url':
569
+ result.isInline = true;
570
+ break;
571
+
572
+ case 'own':
573
+ result.isInline = false;
574
+ break;
575
+ }
576
+
577
+ return result;
578
+ }
579
+ }, {
580
+ key: "_pasteLabel",
581
+ value: function _pasteLabel(context, group, match) {
582
+ var safeTags = context.safeTags;
583
+ var key = privateLabel + 'tf' + safeTags.i + privateLabel;
584
+ safeTags.hidden[group][key] = match;
585
+ safeTags.i++;
586
+ return key;
587
+ }
588
+ }, {
589
+ key: "_prepareRegExp",
590
+ value: function _prepareRegExp(tag) {
591
+ var re;
592
+
593
+ if (tag instanceof RegExp) {
594
+ re = tag;
595
+ } else {
596
+ var _tag = _slicedToArray(tag, 3),
597
+ startTag = _tag[0],
598
+ endTag = _tag[1],
599
+ middle = _tag[2];
600
+
601
+ if (typeof middle === 'undefined') {
602
+ middle = '[^]*?';
603
+ }
604
+
605
+ re = new RegExp(startTag + middle + endTag, 'gi');
606
+ }
607
+
608
+ return re;
609
+ }
610
+ }]);
611
+
612
+ return SafeTags;
613
+ }();
614
+
615
+ function repeat(symbol, count) {
616
+ var result = '';
617
+
618
+ for (;;) {
619
+ if ((count & 1) === 1) {
620
+ result += symbol;
621
+ }
622
+
623
+ count >>>= 1;
624
+
625
+ if (count === 0) {
626
+ break;
627
+ }
628
+
629
+ symbol += symbol;
630
+ }
631
+
632
+ return result;
633
+ }
634
+ function replaceNbsp(text) {
635
+ return text.replace(/\u00A0/g, ' ');
636
+ }
637
+ function replace(text, re) {
638
+ for (var i = 0; i < re.length; i++) {
639
+ text = text.replace(re[i][0], re[i][1]);
640
+ }
641
+
642
+ return text;
643
+ }
644
+ function isHTML(text) {
645
+ return text.search(/(<\/?[a-z]|<!|&[lg]t;)/i) !== -1;
646
+ }
647
+ function removeCR(text) {
648
+ return text.replace(/\r\n?/g, '\n');
649
+ }
650
+ function fixLineEnding(text, type) {
651
+ if (type === 'CRLF') {
652
+ // Windows
653
+ return text.replace(/\n/g, '\r\n');
654
+ } else if (type === 'CR') {
655
+ // Mac
656
+ return text.replace(/\n/g, '\r');
657
+ }
658
+
659
+ return text;
660
+ }
661
+
662
+ /**
663
+ * Get a deep copy of a object.
664
+ *
665
+ * @param {*} obj
666
+ *
667
+ * @returns {*}
668
+ */
669
+ function deepCopy(obj) {
670
+ return _typeof(obj) === 'object' ? JSON.parse(JSON.stringify(obj)) : obj;
671
+ }
672
+
673
+ /**
674
+ * @constructor
675
+ * @param {Object} [prefs]
676
+ * @param {string} [prefs.locale] Locale
677
+ * @param {string} [prefs.lineEnding] Line ending. 'LF' (Unix), 'CR' (Mac) or 'CRLF' (Windows). Default: 'LF'.
678
+ * @param {HtmlEntity} [prefs.htmlEntity]
679
+ * @param {boolean} [prefs.live] Live mode
680
+ * @param {string|string[]} [prefs.enableRule] Enable a rule
681
+ * @param {string|string[]} [prefs.disableRule] Disable a rule
682
+ */
683
+
684
+ var Typograf = /*#__PURE__*/function () {
685
+ function Typograf(prefs) {
686
+ _classCallCheck(this, Typograf);
687
+
688
+ this._prefs = _typeof(prefs) === 'object' ? prefs : {};
689
+ this._prefs.locale = prepareLocale(this._prefs.locale);
690
+ this._prefs.live = this._prefs.live || false;
691
+ this._safeTags = new SafeTags();
692
+ this._settings = {};
693
+ this._enabledRules = {};
694
+ this._innerRulesByQueues = {};
695
+ this._innerRules = [].concat(this._innerRules);
696
+
697
+ this._innerRules.forEach(function (rule) {
698
+ var q = rule.queue || 'default';
699
+ this._innerRulesByQueues[q] = this._innerRulesByQueues[q] || [];
700
+
701
+ this._innerRulesByQueues[q].push(rule);
702
+ }, this);
703
+
704
+ this._rulesByQueues = {};
705
+ this._rules = [].concat(this._rules);
706
+
707
+ this._rules.forEach(function (rule) {
708
+ var q = rule.queue || 'default';
709
+
710
+ this._prepareRule(rule);
711
+
712
+ this._rulesByQueues[q] = this._rulesByQueues[q] || [];
713
+
714
+ this._rulesByQueues[q].push(rule);
715
+ }, this);
716
+
717
+ this._prefs.disableRule && this.disableRule(this._prefs.disableRule);
718
+ this._prefs.enableRule && this.enableRule(this._prefs.enableRule);
719
+ this._separatePartsTags = ['title', 'p', 'h[1-6]', 'select', 'legend'];
720
+ }
721
+ /**
722
+ * Add a rule.
723
+ *
724
+ * @static
725
+ * @param {TypografRule} rule
726
+ *
727
+ * @returns {Typograf} this
728
+ */
729
+
730
+
731
+ _createClass(Typograf, [{
732
+ key: "execute",
733
+ value:
734
+ /**
735
+ * Execute typographical rules for text.
736
+ *
737
+ * @param {string} text
738
+ * @param {Object} [prefs]
739
+ * @param {string} [prefs.locale] Locale
740
+ * @param {HtmlEntity} [prefs.htmlEntity] Type of HTML entities
741
+ * @param {string} [prefs.lineEnding] Line ending. 'LF' (Unix), 'CR' (Mac) or 'CRLF' (Windows). Default: 'LF'.
742
+ *
743
+ * @returns {string}
744
+ */
745
+ function execute(text, prefs) {
746
+ text = '' + text;
747
+
748
+ if (!text) {
749
+ return '';
750
+ }
751
+
752
+ var context = this._prepareContext(text);
753
+
754
+ this._preparePrefs(context, prefs);
755
+
756
+ return this._process(context);
757
+ }
758
+ }, {
759
+ key: "_prepareContext",
760
+ value: function _prepareContext(text) {
761
+ return {
762
+ text: text,
763
+ isHTML: isHTML(text),
764
+ prefs: deepCopy(this._prefs),
765
+ getData: function getData$$1(key) {
766
+ if (key === 'char') {
767
+ return this.prefs.locale.map(function (item) {
768
+ return getData(item + '/' + key);
769
+ }).join('');
770
+ } else {
771
+ return getData(this.prefs.locale[0] + '/' + key);
772
+ }
773
+ }
774
+ };
775
+ }
776
+ }, {
777
+ key: "_preparePrefs",
778
+ value: function _preparePrefs(context, prefs) {
779
+ prefs = prefs || {};
780
+ var contextPrefs = context.prefs;
781
+
782
+ for (var _i = 0, _arr = ['htmlEntity', 'lineEnding', 'processingSeparateParts', 'ruleFilter']; _i < _arr.length; _i++) {
783
+ var name = _arr[_i];
784
+
785
+ if (name in prefs) {
786
+ contextPrefs[name] = prefs[name];
787
+ } else if (name in this._prefs) {
788
+ contextPrefs[name] = this._prefs[name];
789
+ }
790
+ }
791
+
792
+ contextPrefs.htmlEntity = contextPrefs.htmlEntity || {};
793
+ contextPrefs.locale = prepareLocale(prefs.locale, this._prefs.locale);
794
+ var locale = contextPrefs.locale;
795
+ var locale0 = locale[0];
796
+
797
+ if (!locale.length || !locale0) {
798
+ throw Error('Not defined the property "locale".');
799
+ }
800
+
801
+ if (!hasLocale(locale0)) {
802
+ throw Error('"' + locale0 + '" is not supported locale.');
803
+ }
804
+ }
805
+ }, {
806
+ key: "_splitBySeparateParts",
807
+ value: function _splitBySeparateParts(context) {
808
+ if (!context.isHTML || context.prefs.processingSeparateParts === false) {
809
+ return [context.text];
810
+ }
811
+
812
+ var text = [],
813
+ reTags = new RegExp('<(' + this._separatePartsTags.join('|') + ')(\\s[^>]*?)?>[^]*?</\\1>', 'gi');
814
+ var position = 0;
815
+ context.text.replace(reTags, function ($0, $1, $2, itemPosition) {
816
+ if (position !== itemPosition) {
817
+ text.push((position ? privateSeparateLabel : '') + context.text.slice(position, itemPosition) + privateSeparateLabel);
818
+ }
819
+
820
+ text.push($0);
821
+ position = itemPosition + $0.length;
822
+ return $0;
823
+ });
824
+ text.push(position ? privateSeparateLabel + context.text.slice(position, context.text.length) : context.text);
825
+ return text;
826
+ }
827
+ }, {
828
+ key: "_process",
829
+ value: function _process(context) {
830
+ var _this = this;
831
+
832
+ context.text = removeCR(context.text);
833
+
834
+ this._executeRules(context, 'start');
835
+
836
+ this._safeTags.hide(context, 'own');
837
+
838
+ this._executeRules(context, 'hide-safe-tags-own');
839
+
840
+ this._safeTags.hide(context, 'html');
841
+
842
+ this._executeRules(context, 'hide-safe-tags-html');
843
+
844
+ var isRootHTML = context.isHTML,
845
+ re = new RegExp(privateSeparateLabel, 'g');
846
+ context.text = this._splitBySeparateParts(context).map(function (item) {
847
+ context.text = item;
848
+ context.isHTML = isHTML(item);
849
+
850
+ _this._safeTags.hideHTMLTags(context);
851
+
852
+ _this._safeTags.hide(context, 'url');
853
+
854
+ _this._executeRules(context, 'hide-safe-tags-url');
855
+
856
+ _this._executeRules(context, 'hide-safe-tags');
857
+
858
+ HtmlEntities$1.toUtf(context);
859
+
860
+ if (_this._prefs.live) {
861
+ context.text = replaceNbsp(context.text);
862
+ }
863
+
864
+ _this._executeRules(context, 'utf');
865
+
866
+ _this._executeRules(context);
867
+
868
+ HtmlEntities$1.restore(context);
869
+
870
+ _this._executeRules(context, 'html-entities');
871
+
872
+ _this._safeTags.show(context, 'url');
873
+
874
+ _this._executeRules(context, 'show-safe-tags-url');
875
+
876
+ return context.text.replace(re, '');
877
+ }).join('');
878
+ context.isHTML = isRootHTML;
879
+
880
+ this._safeTags.show(context, 'html');
881
+
882
+ this._executeRules(context, 'show-safe-tags-html');
883
+
884
+ this._safeTags.show(context, 'own');
885
+
886
+ this._executeRules(context, 'show-safe-tags-own');
887
+
888
+ this._executeRules(context, 'end');
889
+
890
+ return fixLineEnding(context.text, context.prefs.lineEnding);
891
+ }
892
+ /**
893
+ * Get a setting.
894
+ *
895
+ * @param {string} ruleName
896
+ * @param {string} setting
897
+ *
898
+ * @returns {*}
899
+ */
900
+
901
+ }, {
902
+ key: "getSetting",
903
+ value: function getSetting(ruleName, setting) {
904
+ return this._settings[ruleName] && this._settings[ruleName][setting];
905
+ }
906
+ /**
907
+ * Set a setting.
908
+ *
909
+ * @param {string} ruleName
910
+ * @param {string} setting
911
+ * @param {*} [value]
912
+ *
913
+ * @returns {Typograf}
914
+ */
915
+
916
+ }, {
917
+ key: "setSetting",
918
+ value: function setSetting(ruleName, setting, value) {
919
+ this._settings[ruleName] = this._settings[ruleName] || {};
920
+ this._settings[ruleName][setting] = value;
921
+ return this;
922
+ }
923
+ /**
924
+ * Is enabled a rule.
925
+ *
926
+ * @param {string} ruleName
927
+ *
928
+ * @returns {boolean}
929
+ */
930
+
931
+ }, {
932
+ key: "isEnabledRule",
933
+ value: function isEnabledRule(ruleName) {
934
+ return this._enabledRules[ruleName];
935
+ }
936
+ /**
937
+ * Is disabled a rule.
938
+ *
939
+ * @param {string} ruleName
940
+ *
941
+ * @returns {boolean}
942
+ */
943
+
944
+ }, {
945
+ key: "isDisabledRule",
946
+ value: function isDisabledRule(ruleName) {
947
+ return !this._enabledRules[ruleName];
948
+ }
949
+ /**
950
+ * Enable a rule.
951
+ *
952
+ * @param {string|string[]} ruleName
953
+ *
954
+ * @returns {Typograf} this
955
+ */
956
+
957
+ }, {
958
+ key: "enableRule",
959
+ value: function enableRule(ruleName) {
960
+ return this._enable(ruleName, true);
961
+ }
962
+ /**
963
+ * Disable a rule.
964
+ *
965
+ * @param {string|string[]} ruleName
966
+ *
967
+ * @returns {Typograf} this
968
+ */
969
+
970
+ }, {
971
+ key: "disableRule",
972
+ value: function disableRule(ruleName) {
973
+ return this._enable(ruleName, false);
974
+ }
975
+ /**
976
+ * Add safe tag.
977
+ *
978
+ * @example
979
+ * // var t = new Typograf({locale: 'ru'});
980
+ * // t.addSafeTag('<mytag>', '</mytag>');
981
+ * // t.addSafeTag('<mytag>', '</mytag>', '.*?');
982
+ * // t.addSafeTag(/<mytag>.*?</mytag>/gi);
983
+ *
984
+ * @param {string|RegExp} startTag
985
+ * @param {string} [endTag]
986
+ * @param {string} [middle]
987
+ *
988
+ * @returns {Typograf} this
989
+ */
990
+
991
+ }, {
992
+ key: "addSafeTag",
993
+ value: function addSafeTag(startTag, endTag, middle) {
994
+ var tag = startTag instanceof RegExp ? startTag : [startTag, endTag, middle];
995
+
996
+ this._safeTags.add(tag);
997
+
998
+ return this;
999
+ }
1000
+ }, {
1001
+ key: "_executeRules",
1002
+ value: function _executeRules(context, queue) {
1003
+ queue = queue || 'default';
1004
+ var rules = this._rulesByQueues[queue];
1005
+ var innerRules = this._innerRulesByQueues[queue];
1006
+ innerRules && innerRules.forEach(function (rule) {
1007
+ this._ruleIterator(context, rule);
1008
+ }, this);
1009
+ rules && rules.forEach(function (rule) {
1010
+ this._ruleIterator(context, rule);
1011
+ }, this);
1012
+ }
1013
+ }, {
1014
+ key: "_ruleIterator",
1015
+ value: function _ruleIterator(context, rule) {
1016
+ var rlocale = rule._locale;
1017
+ var live = this._prefs.live;
1018
+
1019
+ if (live === true && rule.live === false || live === false && rule.live === true) {
1020
+ return;
1021
+ }
1022
+
1023
+ if ((rlocale === 'common' || rlocale === context.prefs.locale[0]) && this.isEnabledRule(rule.name)) {
1024
+ if (context.prefs.ruleFilter && !context.prefs.ruleFilter(rule)) {
1025
+ return;
1026
+ }
1027
+
1028
+ this._onBeforeRule && this._onBeforeRule(rule.name, context.text, context);
1029
+ context.text = rule.handler.call(this, context.text, this._settings[rule.name], context);
1030
+ this._onAfterRule && this._onAfterRule(rule.name, context.text, context);
1031
+ }
1032
+ }
1033
+ }, {
1034
+ key: "_prepareRule",
1035
+ value: function _prepareRule(rule) {
1036
+ var name = rule.name;
1037
+
1038
+ var t = _typeof(rule.settings);
1039
+
1040
+ var settings = {};
1041
+
1042
+ if (t === 'object') {
1043
+ settings = deepCopy(rule.settings);
1044
+ } else if (t === 'function') {
1045
+ settings = rule.settings(rule);
1046
+ }
1047
+
1048
+ this._settings[name] = settings;
1049
+ this._enabledRules[name] = rule._enabled;
1050
+ }
1051
+ }, {
1052
+ key: "_enable",
1053
+ value: function _enable(rule, enabled) {
1054
+ if (Array.isArray(rule)) {
1055
+ rule.forEach(function (el) {
1056
+ this._enableByMask(el, enabled);
1057
+ }, this);
1058
+ } else {
1059
+ this._enableByMask(rule, enabled);
1060
+ }
1061
+
1062
+ return this;
1063
+ }
1064
+ }, {
1065
+ key: "_enableByMask",
1066
+ value: function _enableByMask(rule, enabled) {
1067
+ if (!rule) {
1068
+ return;
1069
+ }
1070
+
1071
+ if (rule.search(/\*/) !== -1) {
1072
+ var re = new RegExp(rule.replace(/\//g, '\\/').replace(/\*/g, '.*'));
1073
+
1074
+ this._rules.forEach(function (el) {
1075
+ var name = el.name;
1076
+
1077
+ if (re.test(name)) {
1078
+ this._enabledRules[name] = enabled;
1079
+ }
1080
+ }, this);
1081
+ } else {
1082
+ this._enabledRules[rule] = enabled;
1083
+ }
1084
+ }
1085
+ }, {
1086
+ key: "_getRule",
1087
+ value: function _getRule(name) {
1088
+ var rule = null;
1089
+
1090
+ this._rules.some(function (item) {
1091
+ if (item.name === name) {
1092
+ rule = item;
1093
+ return true;
1094
+ }
1095
+
1096
+ return false;
1097
+ });
1098
+
1099
+ return rule;
1100
+ }
1101
+ }], [{
1102
+ key: "addRule",
1103
+ value: function addRule(rule) {
1104
+ var _rule$name$split = rule.name.split('/'),
1105
+ _rule$name$split2 = _slicedToArray(_rule$name$split, 3),
1106
+ locale = _rule$name$split2[0],
1107
+ group = _rule$name$split2[1],
1108
+ name = _rule$name$split2[2];
1109
+
1110
+ rule._enabled = rule.disabled === true ? false : true;
1111
+ rule._locale = locale;
1112
+ rule._group = group;
1113
+ rule._name = name;
1114
+ this.addLocale(rule._locale);
1115
+
1116
+ this._setIndex(rule);
1117
+
1118
+ this.prototype._rules.push(rule);
1119
+
1120
+ this._sortRules(this.prototype._rules);
1121
+
1122
+ return this;
1123
+ }
1124
+ /**
1125
+ * Add rules.
1126
+ *
1127
+ * @static
1128
+ * @param {TypografRule[]} rules
1129
+ *
1130
+ * @returns {Typograf} this
1131
+ */
1132
+
1133
+ }, {
1134
+ key: "addRules",
1135
+ value: function addRules(rules) {
1136
+ var _this2 = this;
1137
+
1138
+ rules.forEach(function (item) {
1139
+ _this2.addRule(item);
1140
+ });
1141
+ return this;
1142
+ }
1143
+ /**
1144
+ * Add internal rule.
1145
+ * Internal rules are executed before main.
1146
+ *
1147
+ * @static
1148
+ * @param {TypografRule} rule
1149
+ *
1150
+ * @returns {Typograf} this
1151
+ */
1152
+
1153
+ }, {
1154
+ key: "addInnerRule",
1155
+ value: function addInnerRule(rule) {
1156
+ this.prototype._innerRules.push(rule);
1157
+
1158
+ rule._locale = rule.name.split('/')[0];
1159
+ return this;
1160
+ }
1161
+ /**
1162
+ * Add internal rules.
1163
+ * Internal rules are executed before main.
1164
+ *
1165
+ * @static
1166
+ * @param {TypografRule[]} rules
1167
+ *
1168
+ * @returns {Typograf} this
1169
+ */
1170
+
1171
+ }, {
1172
+ key: "addInnerRules",
1173
+ value: function addInnerRules(rules) {
1174
+ var _this3 = this;
1175
+
1176
+ rules.forEach(function (item) {
1177
+ _this3.addInnerRule(item);
1178
+ });
1179
+ return this;
1180
+ }
1181
+ }, {
1182
+ key: "_setIndex",
1183
+ value: function _setIndex(rule) {
1184
+ var index = rule.index;
1185
+
1186
+ var t = _typeof(index);
1187
+
1188
+ var groupIndex = groupIndexes[rule._group];
1189
+
1190
+ if (t === 'undefined') {
1191
+ index = groupIndex;
1192
+ } else if (t === 'string') {
1193
+ index = (groupIndex || 0) + parseInt(rule.index, 10);
1194
+ }
1195
+
1196
+ rule._index = index;
1197
+ }
1198
+ }, {
1199
+ key: "_sortRules",
1200
+ value: function _sortRules(rules) {
1201
+ rules.sort(function (a, b) {
1202
+ return a._index > b._index ? 1 : -1;
1203
+ });
1204
+ }
1205
+ }]);
1206
+
1207
+ return Typograf;
1208
+ }();
1209
+ Typograf.version = '6.15.0';
1210
+ Typograf.addLocale = addLocale;
1211
+ Typograf.getLocales = getLocales;
1212
+ Typograf.hasLocale = hasLocale;
1213
+ Typograf.setData = setData;
1214
+ Typograf.getData = getData; // @deprecated
1215
+
1216
+ Typograf.deepCopy = deepCopy;
1217
+ Typograf.prototype._rules = [];
1218
+ Typograf.prototype._innerRules = [];
1219
+ /**
1220
+ * @typedef TypografRule
1221
+ * @type {object}
1222
+ *
1223
+ * @property {string} name Name of rule
1224
+ * @property {Function} handler Processing function
1225
+ * @property {number} [index] Sorting index for rule
1226
+ * @property {boolean} [disabled] Rule is disabled by default
1227
+ * @property {boolean} [live] Live mode
1228
+ * @property {Object} [settings] Settings for rule
1229
+ */
1230
+
1231
+ var common = {
1232
+ 'common/char': 'a-z',
1233
+ 'common/dash': '--?|‒|–|—',
1234
+ // --, &#8210, &ndash, &mdash
1235
+ 'common/quote': '«‹»›„“‟”"'
1236
+ };
1237
+
1238
+ var be = {
1239
+ 'be/char': 'абвгдежзйклмнопрстуфхцчшыьэюяёіўґ',
1240
+ 'be/quote': {
1241
+ left: '«“',
1242
+ right: '»”'
1243
+ }
1244
+ };
1245
+
1246
+ var bg = {
1247
+ 'bg/char': 'абвгдежзийклмнопрстуфхцчшщъьюя',
1248
+ 'bg/quote': {
1249
+ left: '„’',
1250
+ right: '“’'
1251
+ }
1252
+ };
1253
+
1254
+ var ca = {
1255
+ 'ca/char': 'abcdefghijlmnopqrstuvxyzàçèéíïòóúü',
1256
+ 'ca/quote': {
1257
+ left: '«“',
1258
+ right: '»”'
1259
+ }
1260
+ };
1261
+
1262
+ var da = {
1263
+ 'da/char': 'a-zåæø',
1264
+ 'da/quote': {
1265
+ left: '»›',
1266
+ right: '«‹'
1267
+ }
1268
+ };
1269
+
1270
+ var de = {
1271
+ 'de/char': 'a-zßäöü',
1272
+ 'de/quote': {
1273
+ left: '„‚',
1274
+ right: '“‘'
1275
+ }
1276
+ };
1277
+
1278
+ var el = {
1279
+ 'el/char': 'ΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϲάέήίόύώ',
1280
+ 'el/quote': {
1281
+ left: '«“',
1282
+ right: '»”'
1283
+ }
1284
+ };
1285
+
1286
+ var enGB = {
1287
+ 'en-GB/char': 'a-z',
1288
+ 'en-GB/quote': {
1289
+ left: '‘“',
1290
+ right: '’”'
1291
+ }
1292
+ };
1293
+
1294
+ var enUS = {
1295
+ 'en-US/char': 'a-z',
1296
+ 'en-US/quote': {
1297
+ left: '“‘',
1298
+ right: '”’'
1299
+ }
1300
+ };
1301
+
1302
+ var eo = {
1303
+ 'eo/char': 'abcdefghijklmnoprstuvzĉĝĥĵŝŭ',
1304
+ 'eo/quote': {
1305
+ left: '“‘',
1306
+ right: '”’'
1307
+ }
1308
+ };
1309
+
1310
+ var es = {
1311
+ 'es/char': 'a-záéíñóúü',
1312
+ 'es/quote': {
1313
+ left: '«“',
1314
+ right: '»”'
1315
+ }
1316
+ };
1317
+
1318
+ var et = {
1319
+ 'et/char': 'abdefghijklmnoprstuvzäõöüšž',
1320
+ 'et/quote': {
1321
+ left: '„«',
1322
+ right: '“»'
1323
+ }
1324
+ };
1325
+
1326
+ var fi = {
1327
+ 'fi/char': 'abcdefghijklmnopqrstuvyöäå',
1328
+ 'fi/quote': {
1329
+ left: '”’',
1330
+ right: '”’'
1331
+ }
1332
+ };
1333
+
1334
+ var fr = {
1335
+ 'fr/char': 'a-zàâçèéêëîïôûüœæ',
1336
+ 'fr/quote': {
1337
+ left: '«‹',
1338
+ right: '»›',
1339
+ spacing: true
1340
+ }
1341
+ };
1342
+
1343
+ var ga = {
1344
+ 'ga/char': 'abcdefghilmnoprstuvwxyzáéíóú',
1345
+ 'ga/quote': {
1346
+ left: '“‘',
1347
+ right: '”’'
1348
+ }
1349
+ };
1350
+
1351
+ var hu = {
1352
+ 'hu/char': 'a-záäéíóöúüőű',
1353
+ 'hu/quote': {
1354
+ left: '„»',
1355
+ right: '”«'
1356
+ }
1357
+ };
1358
+
1359
+ var it = {
1360
+ 'it/char': 'a-zàéèìòù',
1361
+ 'it/quote': {
1362
+ left: '«“',
1363
+ right: '»”'
1364
+ }
1365
+ };
1366
+
1367
+ var lv = {
1368
+ 'lv/char': 'abcdefghijklmnopqrstuvxzæœ',
1369
+ 'lv/quote': {
1370
+ left: '«„',
1371
+ right: '»“'
1372
+ }
1373
+ };
1374
+
1375
+ var nl = {
1376
+ 'nl/char': 'a-zäçèéêëîïñöûü',
1377
+ 'nl/quote': {
1378
+ left: '‘“',
1379
+ right: '’”'
1380
+ }
1381
+ };
1382
+
1383
+ var no = {
1384
+ 'no/char': 'a-zåæèéêòóôø',
1385
+ 'no/quote': {
1386
+ left: '«’',
1387
+ right: '»’'
1388
+ }
1389
+ };
1390
+
1391
+ var pl = {
1392
+ 'pl/char': 'abcdefghijklmnoprstuvwxyzóąćęłńśźż',
1393
+ 'pl/quote': {
1394
+ left: '„«',
1395
+ right: '”»'
1396
+ }
1397
+ };
1398
+
1399
+ var ro = {
1400
+ 'ro/char': 'abcdefghijklmnoprstuvxzîășț',
1401
+ 'ro/quote': {
1402
+ left: '„«',
1403
+ right: '”»'
1404
+ }
1405
+ };
1406
+
1407
+ var ru = {
1408
+ 'ru/char': 'а-яё',
1409
+ 'ru/dashBefore': '(^| |\\n)',
1410
+ 'ru/dashAfter': "(?=[\xA0 ,.?:!]|$)",
1411
+ 'ru/dashAfterDe': "(?=[,.?:!]|[\xA0 ][^\u0410-\u042F\u0401]|$)",
1412
+ 'ru/l': 'а-яёa-z',
1413
+ 'ru/L': 'А-ЯЁA-Z',
1414
+ 'ru/month': 'январь|февраль|март|апрель|май|июнь|июль|август|сентябрь|октябрь|ноябрь|декабрь',
1415
+ 'ru/monthGenCase': 'января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря',
1416
+ 'ru/monthPreCase': 'январе|феврале|марте|апреле|мае|июне|июле|августе|сентябре|октябре|ноябре|декабре',
1417
+ 'ru/quote': {
1418
+ left: '«„‚',
1419
+ right: '»“‘',
1420
+ removeDuplicateQuotes: true
1421
+ },
1422
+ 'ru/shortMonth': 'янв|фев|мар|апр|ма[ейя]|июн|июл|авг|сен|окт|ноя|дек',
1423
+ 'ru/weekday': 'понедельник|вторник|среда|четверг|пятница|суббота|воскресенье'
1424
+ };
1425
+
1426
+ var sk = {
1427
+ 'sk/char': 'abcdefghijklmnoprstuvwxyzáäéíóôúýčďľňŕšťž',
1428
+ 'sk/quote': {
1429
+ left: '„‚',
1430
+ right: '“‘'
1431
+ }
1432
+ };
1433
+
1434
+ var sl = {
1435
+ 'sl/char': 'a-zčšž',
1436
+ 'sl/quote': {
1437
+ left: '„‚',
1438
+ right: '“‘'
1439
+ }
1440
+ };
1441
+
1442
+ var sr = {
1443
+ 'sr/char': 'abcdefghijklmnoprstuvzćčđšž',
1444
+ 'sr/quote': {
1445
+ left: '„’',
1446
+ right: '”’'
1447
+ }
1448
+ };
1449
+
1450
+ var sv = {
1451
+ 'sv/char': 'a-zäåéö',
1452
+ 'sv/quote': {
1453
+ left: '”’',
1454
+ right: '”’'
1455
+ }
1456
+ };
1457
+
1458
+ var tr = {
1459
+ 'tr/char': 'abcdefghijklmnoprstuvyzâçîöûüğış',
1460
+ 'tr/quote': {
1461
+ left: '“‘',
1462
+ right: '”’'
1463
+ }
1464
+ };
1465
+
1466
+ var uk = {
1467
+ 'uk/char': 'абвгдежзийклмнопрстуфхцчшщьюяєіїґ',
1468
+ 'uk/quote': {
1469
+ left: '«„',
1470
+ right: '»“'
1471
+ }
1472
+ };
1473
+
1474
+ var data$1 = [common, be, bg, ca, da, de, el, enGB, enUS, eo, es, et, fi, fr, ga, hu, it, lv, nl, no, pl, ro, ru, sk, sl, sr, sv, tr, uk];
1475
+ data$1.forEach(function (item) {
1476
+ return setData(item);
1477
+ });
1478
+
1479
+ var eMail = {
1480
+ name: 'common/html/e-mail',
1481
+ queue: 'end',
1482
+ handler: function handler(text, settings, context) {
1483
+ return context.isHTML ? text : text.replace(/(^|[\s;(])([\w\-.]{2,64})@([\w\-.]{2,64})\.([a-z]{2,64})([)\s.,!?]|$)/gi, '$1<a href="mailto:$2@$3.$4">$2@$3.$4</a>$5');
1484
+ },
1485
+ disabled: true,
1486
+ htmlAttrs: false
1487
+ };
1488
+
1489
+ var escape = {
1490
+ name: 'common/html/escape',
1491
+ index: '+100',
1492
+ queue: 'end',
1493
+ handler: function handler(text) {
1494
+ var entityMap = {
1495
+ '&': '&amp;',
1496
+ '<': '&lt;',
1497
+ '>': '&gt;',
1498
+ '"': '&quot;',
1499
+ '\'': '&#39;',
1500
+ '/': '&#x2F;'
1501
+ };
1502
+ return text.replace(/[&<>"'/]/g, function (s) {
1503
+ return entityMap[s];
1504
+ });
1505
+ },
1506
+ disabled: true
1507
+ };
1508
+
1509
+ var nbr = {
1510
+ name: 'common/html/nbr',
1511
+ index: '+10',
1512
+ queue: 'end',
1513
+ handler: function handler(text) {
1514
+ return text.replace(/([^\n>])\n(?=[^\n])/g, '$1<br/>\n');
1515
+ },
1516
+ disabled: true,
1517
+ htmlAttrs: false
1518
+ };
1519
+
1520
+ var blockElements = ['address', 'article', 'aside', 'blockquote', 'canvas', 'dd', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'main', 'nav', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table', 'tfoot', 'ul', 'video'];
1521
+
1522
+ var p = {
1523
+ name: 'common/html/p',
1524
+ index: '+5',
1525
+ queue: 'end',
1526
+ handler: function handler(text) {
1527
+ var blockRe = new RegExp('<(' + blockElements.join('|') + ')[>\\s]');
1528
+ var separator = '\n\n';
1529
+ var buffer = text.split(separator);
1530
+ buffer.forEach(function (text, i, data) {
1531
+ if (!text.trim()) {
1532
+ return;
1533
+ }
1534
+
1535
+ if (!blockRe.test(text)) {
1536
+ data[i] = text.replace(/^(\s*)/, '$1<p>').replace(/(\s*)$/, '</p>$1');
1537
+ }
1538
+ });
1539
+ return buffer.join(separator);
1540
+ },
1541
+ disabled: true,
1542
+ htmlAttrs: false
1543
+ };
1544
+
1545
+ var processingAttrs = {
1546
+ name: 'common/html/processingAttrs',
1547
+ queue: 'hide-safe-tags-own',
1548
+ // After "hide-safe-tags-own", before "hide-safe-tags-html".
1549
+ handler: function handler(text, settings, context) {
1550
+ var that = this;
1551
+ var reAttrs = new RegExp('(^|\\s)(' + settings.attrs.join('|') + ')=("[^"]*?"|\'[^\']*?\')', 'gi');
1552
+ var prefs = deepCopy(context.prefs);
1553
+
1554
+ prefs.ruleFilter = function (rule) {
1555
+ return rule.htmlAttrs !== false;
1556
+ };
1557
+
1558
+ return text.replace(/(<[-\w]+\s)([^>]+?)(?=>)/g, function (match, tagName, attrs) {
1559
+ var resultAttrs = attrs.replace(reAttrs, function (submatch, space, attrName, attrValue) {
1560
+ var lquote = attrValue[0];
1561
+ var rquote = attrValue[attrValue.length - 1];
1562
+ var value = attrValue.slice(1, -1);
1563
+ return space + attrName + '=' + lquote + that.execute(value, prefs) + rquote;
1564
+ });
1565
+ return tagName + resultAttrs;
1566
+ });
1567
+ },
1568
+ settings: {
1569
+ attrs: ['title', 'placeholder']
1570
+ },
1571
+ disabled: true,
1572
+ htmlAttrs: false
1573
+ };
1574
+
1575
+ var quot = {
1576
+ name: 'common/html/quot',
1577
+ queue: 'hide-safe-tags',
1578
+ handler: function handler(text) {
1579
+ return text.replace(/&quot;/g, '"');
1580
+ }
1581
+ };
1582
+
1583
+ var stripTags = {
1584
+ name: 'common/html/stripTags',
1585
+ index: '+99',
1586
+ queue: 'end',
1587
+ handler: function handler(text) {
1588
+ return text.replace(/<[^>]+>/g, '');
1589
+ },
1590
+ disabled: true
1591
+ };
1592
+
1593
+ var url = {
1594
+ name: 'common/html/url',
1595
+ queue: 'end',
1596
+ handler: function handler(text, settings, context) {
1597
+ return context.isHTML ? text : text.replace(regExpUrl, function ($0, protocol, path) {
1598
+ path = path.replace(/([^/]+\/?)(\?|#)$/, '$1') // Remove ending ? and #
1599
+ .replace(/^([^/]+)\/$/, '$1'); // Remove ending /
1600
+
1601
+ if (protocol === 'http') {
1602
+ path = path.replace(/^([^/]+)(:80)([^\d]|\/|$)/, '$1$3'); // Remove 80 port
1603
+ } else if (protocol === 'https') {
1604
+ path = path.replace(/^([^/]+)(:443)([^\d]|\/|$)/, '$1$3'); // Remove 443 port
1605
+ }
1606
+
1607
+ var url = path;
1608
+ var fullUrl = protocol + '://' + path;
1609
+ var firstPart = '<a href="' + fullUrl + '">';
1610
+
1611
+ if (protocol === 'http' || protocol === 'https') {
1612
+ url = url.replace(/^www\./, '');
1613
+ return firstPart + (protocol === 'http' ? url : protocol + '://' + url) + '</a>';
1614
+ }
1615
+
1616
+ return firstPart + fullUrl + '</a>';
1617
+ });
1618
+ },
1619
+ disabled: true,
1620
+ htmlAttrs: false
1621
+ };
1622
+
1623
+ Typograf.addRules([eMail, escape, nbr, p, processingAttrs, quot, stripTags, url]);
1624
+
1625
+ var afterNumber = {
1626
+ name: 'common/nbsp/afterNumber',
1627
+ handler: function handler(text, settings, context) {
1628
+ var re = '(^|\\s)(\\d{1,5}) ([' + context.getData('char') + ']+)';
1629
+ return text.replace(new RegExp(re, 'gi'), "$1$2\xA0$3");
1630
+ },
1631
+ disabled: true
1632
+ };
1633
+
1634
+ var afterParagraphMark = {
1635
+ name: 'common/nbsp/afterParagraphMark',
1636
+ handler: function handler(text) {
1637
+ return text.replace(/¶ ?(?=\d)/g, "\xB6\xA0");
1638
+ }
1639
+ };
1640
+
1641
+ var afterSectionMark = {
1642
+ name: 'common/nbsp/afterSectionMark',
1643
+ handler: function handler(text, settings, context) {
1644
+ // \u2009 - THIN SPACE
1645
+ // \u202F - NARROW NO-BREAK SPACE
1646
+ var locale = context.prefs.locale[0];
1647
+ return text.replace(/§[ \u00A0\u2009]?(?=\d|I|V|X)/g, locale === 'ru' ? "\xA7\u202F" : "\xA7\xA0");
1648
+ }
1649
+ };
1650
+
1651
+ var afterShortWord = {
1652
+ name: 'common/nbsp/afterShortWord',
1653
+ handler: function handler(text, settings, context) {
1654
+ var len = settings.lengthShortWord;
1655
+ var before = " \xA0(" + privateLabel + getData('common/quote');
1656
+ var subStr = '(^|[' + before + '])([' + context.getData('char') + ']{1,' + len + '}) ';
1657
+ var newSubStr = "$1$2\xA0";
1658
+ var re = new RegExp(subStr, 'gim');
1659
+ return text.replace(re, newSubStr).replace(re, newSubStr);
1660
+ },
1661
+ settings: {
1662
+ lengthShortWord: 2
1663
+ }
1664
+ };
1665
+
1666
+ var beforeShortLastNumber = {
1667
+ name: 'common/nbsp/beforeShortLastNumber',
1668
+ handler: function handler(text, settings, context) {
1669
+ var ch = context.getData('char');
1670
+ var CH = ch.toUpperCase();
1671
+ var re = new RegExp('([' + ch + CH + ']) (?=\\d{1,' + settings.lengthLastNumber + '}[-+−%\'"' + context.getData('quote').right + ')]?([.!?…]( [' + CH + ']|$)|$))', 'gm');
1672
+ return text.replace(re, "$1\xA0");
1673
+ },
1674
+ live: false,
1675
+ settings: {
1676
+ lengthLastNumber: 2
1677
+ }
1678
+ };
1679
+
1680
+ var beforeShortLastWord = {
1681
+ name: 'common/nbsp/beforeShortLastWord',
1682
+ handler: function handler(text, settings, context) {
1683
+ var ch = context.getData('char');
1684
+ var CH = ch.toUpperCase();
1685
+ var re = new RegExp('([' + ch + '\\d]) ([' + ch + CH + ']{1,' + settings.lengthLastWord + '}[.!?…])( [' + CH + ']|$)', 'g');
1686
+ return text.replace(re, "$1\xA0$2$3");
1687
+ },
1688
+ settings: {
1689
+ lengthLastWord: 3
1690
+ }
1691
+ };
1692
+
1693
+ var dpi = {
1694
+ name: 'common/nbsp/dpi',
1695
+ handler: function handler(text) {
1696
+ return text.replace(/(\d) ?(lpi|dpi)(?!\w)/, "$1\xA0$2");
1697
+ }
1698
+ };
1699
+
1700
+ function replaceNbsp$1($0, $1, $2, $3) {
1701
+ return $1 + $2.replace(/([^\u00A0])\u00A0([^\u00A0])/g, '$1 $2') + $3;
1702
+ }
1703
+
1704
+ var nowrap = {
1705
+ name: 'common/nbsp/nowrap',
1706
+ queue: 'end',
1707
+ handler: function handler(text) {
1708
+ return text.replace(/(<nowrap>)(.*?)(<\/nowrap>)/g, replaceNbsp$1).replace(/(<nobr>)(.*?)(<\/nobr>)/g, replaceNbsp$1);
1709
+ }
1710
+ };
1711
+
1712
+ var replaceNbsp$2 = {
1713
+ name: 'common/nbsp/replaceNbsp',
1714
+ queue: 'utf',
1715
+ live: false,
1716
+ handler: replaceNbsp,
1717
+ disabled: true
1718
+ };
1719
+
1720
+ Typograf.addRules([afterNumber, afterParagraphMark, afterSectionMark, afterShortWord, beforeShortLastNumber, beforeShortLastWord, dpi, nowrap, replaceNbsp$2]);
1721
+
1722
+ var digitGrouping = {
1723
+ name: 'common/number/digitGrouping',
1724
+ index: '310',
1725
+ disabled: true,
1726
+ handler: function handler(text, settings) {
1727
+ return text.replace(new RegExp("(^ ?|\\D |".concat(privateLabel, ")(\\d{1,3}([ \xA0\u202F\u2009]\\d{3})+)(?! ?[\\d-])"), 'gm'), function ($0, $1, $2) {
1728
+ return $1 + $2.replace(/\s/g, settings.space);
1729
+ }) // https://www.bipm.org/utils/common/pdf/si-brochure/SI-Brochure-9-EN.pdf #5.4.4
1730
+ .replace(/(\d{5,}([.,]\d+)?)/g, function ($0, $1) {
1731
+ var decimalMarker = $1.match(/[.,]/);
1732
+
1733
+ var _ref = decimalMarker ? $1.split(decimalMarker) : [$1],
1734
+ _ref2 = _slicedToArray(_ref, 2),
1735
+ integerPart = _ref2[0],
1736
+ fractionalPart = _ref2[1];
1737
+
1738
+ integerPart = integerPart.replace(/(\d)(?=(\d{3})+([^\d]|$))/g, '$1' + settings.space);
1739
+ return decimalMarker ? integerPart + decimalMarker + fractionalPart : integerPart;
1740
+ });
1741
+ },
1742
+ settings: {
1743
+ space: "\u202F"
1744
+ }
1745
+ };
1746
+
1747
+ var fraction = {
1748
+ name: 'common/number/fraction',
1749
+ handler: function handler(text) {
1750
+ return text.replace(/(^|\D)1\/2(\D|$)/g, '$1½$2').replace(/(^|\D)1\/4(\D|$)/g, '$1¼$2').replace(/(^|\D)3\/4(\D|$)/g, '$1¾$2');
1751
+ }
1752
+ };
1753
+
1754
+ var mathSigns = {
1755
+ name: 'common/number/mathSigns',
1756
+ handler: function handler(text) {
1757
+ return replace(text, [[/!=/g, '≠'], [/<=/g, '≤'], [/(^|[^=])>=/g, '$1≥'], [/<=>/g, '⇔'], [/<</g, '≪'], [/>>/g, '≫'], [/~=/g, '≅'], [/(^|[^+])\+-/g, '$1±']]);
1758
+ }
1759
+ };
1760
+
1761
+ var times = {
1762
+ name: 'common/number/times',
1763
+ handler: function handler(text) {
1764
+ return text.replace(/(\d)[ \u00A0]?[xх][ \u00A0]?(\d)/g, '$1×$2');
1765
+ }
1766
+ };
1767
+
1768
+ Typograf.addRules([digitGrouping, fraction, mathSigns, times]);
1769
+
1770
+ var delBOM = {
1771
+ name: 'common/other/delBOM',
1772
+ queue: 'start',
1773
+ index: -1,
1774
+ handler: function handler(text) {
1775
+ if (text.charCodeAt(0) === 0xFEFF) {
1776
+ return text.slice(1);
1777
+ }
1778
+
1779
+ return text;
1780
+ }
1781
+ };
1782
+
1783
+ var repeatWord = {
1784
+ name: 'common/other/repeatWord',
1785
+ handler: function handler(text, settings, context) {
1786
+ var punc = '[;:,.?! \n' + getData('common/quote') + ']';
1787
+ var re = new RegExp('(' + punc + '|^)' + '([' + context.getData('char') + ']{' + settings.min + ',}) ' + '\\2(' + punc + '|$)', 'gi');
1788
+ return text.replace(re, '$1$2$3');
1789
+ },
1790
+ settings: {
1791
+ min: 2
1792
+ },
1793
+ disabled: true
1794
+ };
1795
+
1796
+ Typograf.addRules([delBOM, repeatWord]);
1797
+
1798
+ var apostrophe = {
1799
+ name: 'common/punctuation/apostrophe',
1800
+ handler: function handler(text, settings, context) {
1801
+ var letters = '([' + context.getData('char') + '])';
1802
+ var re = new RegExp(letters + '\'' + letters, 'gi');
1803
+ return text.replace(re, '$1’$2');
1804
+ }
1805
+ };
1806
+
1807
+ var delDoublePunctuation = {
1808
+ name: 'common/punctuation/delDoublePunctuation',
1809
+ handler: function handler(text) {
1810
+ return text.replace(/(^|[^,]),,(?!,)/g, '$1,').replace(/(^|[^:])::(?!:)/g, '$1:').replace(/(^|[^!?.])\.\.(?!\.)/g, '$1.').replace(/(^|[^;]);;(?!;)/g, '$1;').replace(/(^|[^?])\?\?(?!\?)/g, '$1?');
1811
+ }
1812
+ };
1813
+
1814
+ var hellip = {
1815
+ name: 'common/punctuation/hellip',
1816
+ handler: function handler(text, settings, context) {
1817
+ return context.prefs.locale[0] === 'ru' ? text.replace(/(^|[^.])\.{3,4}(?=[^.]|$)/g, '$1…') : text.replace(/(^|[^.])\.{3}(\.?)(?=[^.]|$)/g, '$1…$2');
1818
+ }
1819
+ };
1820
+
1821
+ var MAX_LEVEL_WITH_ERRORS = 2;
1822
+ var Quote = {
1823
+ bufferQuotes: {
1824
+ left: "\uF005\uF006\uF007",
1825
+ right: "\uF008\uF009\uF0A0"
1826
+ },
1827
+ beforeLeft: " \n\t\xA0[(",
1828
+ afterRight: " \n\t\xA0!?.:;#*,\u2026)\\]",
1829
+ process: function process(params) {
1830
+ var text = params.context.text;
1831
+ var count = this.count(text);
1832
+
1833
+ if (!count.total) {
1834
+ return text;
1835
+ }
1836
+
1837
+ var originalSettings = params.settings;
1838
+ var isEqualQuotes = params.settings.left[0] === params.settings.right[0]; // For SW, FI
1839
+
1840
+ if (isEqualQuotes) {
1841
+ params.settings = deepCopy(params.settings);
1842
+ params.settings.left = this.bufferQuotes.left.slice(0, params.settings.left.length);
1843
+ params.settings.right = this.bufferQuotes.right.slice(0, params.settings.right.length);
1844
+ } // For FR
1845
+
1846
+
1847
+ if (params.settings.spacing) {
1848
+ text = this.removeSpacing(text, params.settings);
1849
+ }
1850
+
1851
+ text = this.set(text, params); // For FR
1852
+
1853
+ if (params.settings.spacing) {
1854
+ text = this.setSpacing(text, params.settings);
1855
+ } // For RU
1856
+
1857
+
1858
+ if (params.settings.removeDuplicateQuotes) {
1859
+ text = this.removeDuplicates(text, params.settings);
1860
+ } // For SW, FI
1861
+
1862
+
1863
+ if (isEqualQuotes) {
1864
+ text = this.returnOriginalQuotes(text, originalSettings, params.settings);
1865
+ params.settings = originalSettings;
1866
+ }
1867
+
1868
+ return text;
1869
+ },
1870
+ returnOriginalQuotes: function returnOriginalQuotes(text, originalSettings, bufferSettings) {
1871
+ var buffer = {};
1872
+
1873
+ for (var i = 0; i < bufferSettings.left.length; i++) {
1874
+ buffer[bufferSettings.left[i]] = originalSettings.left[i];
1875
+ buffer[bufferSettings.right[i]] = originalSettings.right[i];
1876
+ }
1877
+
1878
+ return text.replace(new RegExp('[' + bufferSettings.left + bufferSettings.right + ']', 'g'), function (quote) {
1879
+ return buffer[quote];
1880
+ });
1881
+ },
1882
+ count: function count(text) {
1883
+ var count = {
1884
+ total: 0
1885
+ };
1886
+ text.replace(new RegExp('[' + getData('common/quote') + ']', 'g'), function (quote) {
1887
+ if (!count[quote]) {
1888
+ count[quote] = 0;
1889
+ }
1890
+
1891
+ count[quote]++;
1892
+ count.total++;
1893
+ return quote;
1894
+ });
1895
+ return count;
1896
+ },
1897
+ removeDuplicates: function removeDuplicates(text, settings) {
1898
+ var lquote = settings.left[0];
1899
+ var lquote2 = settings.left[1] || lquote;
1900
+ var rquote = settings.right[0];
1901
+
1902
+ if (lquote !== lquote2) {
1903
+ return text;
1904
+ }
1905
+
1906
+ return text // ««word» word» -> «word» word»
1907
+ .replace(new RegExp(lquote + lquote, 'g'), lquote) // «word «word»» -> «word «word»
1908
+ .replace(new RegExp(rquote + rquote, 'g'), rquote);
1909
+ },
1910
+ removeSpacing: function removeSpacing(text, settings) {
1911
+ for (var i = 0, len = settings.left.length; i < len; i++) {
1912
+ var lquote = settings.left[i];
1913
+ var rquote = settings.right[i];
1914
+ text = text.replace(new RegExp(lquote + "([ \u202F\xA0])", 'g'), lquote).replace(new RegExp("([ \u202F\xA0])" + rquote, 'g'), rquote);
1915
+ }
1916
+
1917
+ return text;
1918
+ },
1919
+ setSpacing: function setSpacing(text, settings) {
1920
+ for (var i = 0, len = settings.left.length; i < len; i++) {
1921
+ var lquote = settings.left[i];
1922
+ var rquote = settings.right[i];
1923
+ text = text.replace(new RegExp(lquote + "([^\u202F])", 'g'), lquote + "\u202F$1").replace(new RegExp("([^\u202F])" + rquote, 'g'), "$1\u202F" + rquote);
1924
+ }
1925
+
1926
+ return text;
1927
+ },
1928
+ set: function set(text, params) {
1929
+ var quotes = getData('common/quote');
1930
+ var lquote = params.settings.left[0];
1931
+ var lquote2 = params.settings.left[1] || lquote;
1932
+ var rquote = params.settings.right[0];
1933
+ var reL = new RegExp('(^|[' + this.beforeLeft + '])([' + quotes + ']+)(?=[^\\s' + privateLabel + '])', 'gim');
1934
+ var reR = new RegExp('([^\\s' + privateLabel + '])([' + quotes + ']+)(?=[' + this.afterRight + ']|$)', 'gim');
1935
+ text = text.replace(reL, function ($0, $1, $2) {
1936
+ return $1 + repeat(lquote, $2.length);
1937
+ }).replace(reR, function ($0, $1, $2) {
1938
+ return $1 + repeat(rquote, $2.length);
1939
+ });
1940
+ text = this.setAboveTags(text, params);
1941
+
1942
+ if (lquote !== lquote2) {
1943
+ text = this.setInner(text, params.settings);
1944
+ }
1945
+
1946
+ return text;
1947
+ },
1948
+ setAboveTags: function setAboveTags(text, params) {
1949
+ var _this = this;
1950
+
1951
+ var quotes = getData('common/quote');
1952
+ var lquote = params.settings.left[0];
1953
+ var rquote = params.settings.right[0];
1954
+ return text.replace(new RegExp('(^|.)([' + quotes + '])(.|$)', 'gm'), function (original, prev, quote, next, pos) {
1955
+ if (prev !== privateLabel && next !== privateLabel) {
1956
+ return original;
1957
+ }
1958
+
1959
+ if (prev === privateLabel && next === privateLabel) {
1960
+ if (quote === '"') {
1961
+ return prev + _this.getAboveTwoTags(text, pos + 1, params) + next;
1962
+ }
1963
+
1964
+ return original;
1965
+ }
1966
+
1967
+ if (prev === privateLabel) {
1968
+ var hasRight = _this.afterRight.indexOf(next) > -1;
1969
+
1970
+ var prevInfo = _this.getPrevTagInfo(text, pos - 1, params);
1971
+
1972
+ if (hasRight && prevInfo && prevInfo.group === 'html') {
1973
+ return prev + (prevInfo.isClosing ? rquote : lquote) + next;
1974
+ }
1975
+
1976
+ return prev + (!next || hasRight ? rquote : lquote) + next;
1977
+ } else {
1978
+ var hasLeft = _this.beforeLeft.indexOf(prev) > -1;
1979
+
1980
+ var nextInfo = _this.getNextTagInfo(text, pos + 1, params);
1981
+
1982
+ if (hasLeft && nextInfo && nextInfo.group === 'html') {
1983
+ return prev + (nextInfo.isClosing ? rquote : lquote) + next;
1984
+ }
1985
+
1986
+ return prev + (!prev || hasLeft ? lquote : rquote) + next;
1987
+ }
1988
+ });
1989
+ },
1990
+ getAboveTwoTags: function getAboveTwoTags(text, pos, params) {
1991
+ var prevInfo = this.getPrevTagInfo(text, pos, params);
1992
+ var nextInfo = this.getNextTagInfo(text, pos, params);
1993
+
1994
+ if (prevInfo) {
1995
+ if (prevInfo.group === 'html') {
1996
+ if (!prevInfo.isClosing) {
1997
+ return params.settings.left[0];
1998
+ }
1999
+
2000
+ if (nextInfo && nextInfo.isClosing && prevInfo.isClosing) {
2001
+ return params.settings.right[0];
2002
+ }
2003
+ }
2004
+ }
2005
+
2006
+ return text[pos];
2007
+ },
2008
+ getPrevTagInfo: function getPrevTagInfo(text, pos, params) {
2009
+ var prevLabel = params.safeTags.getPrevLabel(text, pos - 1);
2010
+
2011
+ if (prevLabel) {
2012
+ var prevTag = params.safeTags.getTagByLabel(params.context, prevLabel);
2013
+
2014
+ if (prevTag) {
2015
+ return params.safeTags.getTagInfo(prevTag);
2016
+ }
2017
+ }
2018
+
2019
+ return null;
2020
+ },
2021
+ getNextTagInfo: function getNextTagInfo(text, pos, params) {
2022
+ var nextLabel = params.safeTags.getNextLabel(text, pos + 1);
2023
+
2024
+ if (nextLabel) {
2025
+ var nextTag = params.safeTags.getTagByLabel(params.context, nextLabel);
2026
+
2027
+ if (nextTag) {
2028
+ return params.safeTags.getTagInfo(nextTag);
2029
+ }
2030
+ }
2031
+
2032
+ return null;
2033
+ },
2034
+ setInner: function setInner(text, settings) {
2035
+ var lquote = settings.left[0];
2036
+ var rquote = settings.right[0];
2037
+ var minLevel = 0;
2038
+ var maxLevel = this.getMaxLevel(text, lquote, rquote, settings.left.length);
2039
+ var level = minLevel;
2040
+ var result = '';
2041
+
2042
+ for (var i = 0, len = text.length; i < len; i++) {
2043
+ var letter = text[i];
2044
+
2045
+ if (letter === lquote) {
2046
+ result += settings.left[level > maxLevel - 1 ? maxLevel - 1 : level];
2047
+ level++;
2048
+
2049
+ if (level > maxLevel) {
2050
+ level = maxLevel;
2051
+ }
2052
+ } else if (letter === rquote) {
2053
+ level--;
2054
+
2055
+ if (level < minLevel) {
2056
+ level = minLevel;
2057
+ }
2058
+
2059
+ result += settings.right[level];
2060
+ } else {
2061
+ if (letter === '"') {
2062
+ level = minLevel;
2063
+ }
2064
+
2065
+ result += letter;
2066
+ }
2067
+ }
2068
+
2069
+ return result;
2070
+ },
2071
+ getMaxLevel: function getMaxLevel(text, leftQuote, rightQuote, length) {
2072
+ var count = this.count(text);
2073
+ return count[leftQuote] === count[rightQuote] ? length : Math.min(length, MAX_LEVEL_WITH_ERRORS);
2074
+ }
2075
+ };
2076
+ var quote = {
2077
+ name: 'common/punctuation/quote',
2078
+ handler: function handler(text, commonSettings, context) {
2079
+ var locale = context.prefs.locale[0];
2080
+ var settings = commonSettings[locale];
2081
+
2082
+ if (!settings) {
2083
+ return text;
2084
+ }
2085
+
2086
+ return Quote.process({
2087
+ context: context,
2088
+ settings: settings,
2089
+ safeTags: this._safeTags
2090
+ });
2091
+ },
2092
+ settings: function settings() {
2093
+ var settings = {};
2094
+ getLocales().forEach(function (locale) {
2095
+ settings[locale] = deepCopy(getData(locale + '/quote'));
2096
+ });
2097
+ return settings;
2098
+ }
2099
+ };
2100
+
2101
+ var quoteLink = {
2102
+ name: 'common/punctuation/quoteLink',
2103
+ queue: 'show-safe-tags-html',
2104
+ index: '+5',
2105
+ handler: function handler(text, settings, context) {
2106
+ var quotes = this.getSetting('common/punctuation/quote', context.prefs.locale[0]);
2107
+
2108
+ if (!quotes) {
2109
+ return text;
2110
+ }
2111
+
2112
+ var lquote1 = HtmlEntities$1.getByUtf(quotes.left[0]);
2113
+ var rquote1 = HtmlEntities$1.getByUtf(quotes.right[0]);
2114
+ var lquote2 = HtmlEntities$1.getByUtf(quotes.left[1]);
2115
+ var rquote2 = HtmlEntities$1.getByUtf(quotes.right[1]);
2116
+ lquote2 = lquote2 ? '|' + lquote2 : '';
2117
+ rquote2 = rquote2 ? '|' + rquote2 : '';
2118
+ var re = new RegExp('(<[aA]\\s[^>]*?>)(' + lquote1 + lquote2 + ')([^]*?)(' + rquote1 + rquote2 + ')(</[aA]>)', 'g');
2119
+ return text.replace(re, '$2$1$3$5$4');
2120
+ }
2121
+ };
2122
+
2123
+ Typograf.addRules([apostrophe, delDoublePunctuation, hellip, quote, quoteLink]);
2124
+
2125
+ var beforeBracket = {
2126
+ name: 'common/space/beforeBracket',
2127
+ handler: function handler(text, settings, context) {
2128
+ var re = new RegExp('([' + context.getData('char') + '.!?,;…)])\\(', 'gi');
2129
+ return text.replace(re, '$1 (');
2130
+ }
2131
+ };
2132
+
2133
+ var bracket = {
2134
+ name: 'common/space/bracket',
2135
+ handler: function handler(text) {
2136
+ return text.replace(/(\() +/g, '(').replace(/ +\)/g, ')');
2137
+ }
2138
+ };
2139
+
2140
+ var delBeforePercent = {
2141
+ name: 'common/space/delBeforePercent',
2142
+ handler: function handler(text) {
2143
+ return text.replace(/(\d)( |\u00A0)(%|‰|‱)/g, '$1$3');
2144
+ }
2145
+ };
2146
+
2147
+ var delBeforePunctuation = {
2148
+ name: 'common/space/delBeforePunctuation',
2149
+ handler: function handler(text) {
2150
+ return text.replace(/(^|[^!?:;,.…]) ([!?:;,])(?!\))/g, '$1$2');
2151
+ }
2152
+ };
2153
+
2154
+ var delBetweenExclamationMarks = {
2155
+ name: 'common/space/delBetweenExclamationMarks',
2156
+ handler: function handler(text) {
2157
+ return text.replace(/([!?]) (?=[!?])/g, '$1');
2158
+ }
2159
+ };
2160
+
2161
+ var delBeforeDot = {
2162
+ name: 'common/space/delBeforeDot',
2163
+ handler: function handler(text) {
2164
+ return text.replace(/(^|[^!?:;,.…]) (\.|\.\.\.)(\s|$)/g, '$1$2$3');
2165
+ }
2166
+ };
2167
+
2168
+ var delLeadingBlanks = {
2169
+ name: 'common/space/delLeadingBlanks',
2170
+ handler: function handler(text) {
2171
+ return text.replace(/^[ \t]+/mg, '');
2172
+ },
2173
+ disabled: true
2174
+ };
2175
+
2176
+ var delRepeatN = {
2177
+ name: 'common/space/delRepeatN',
2178
+ index: '-1',
2179
+ handler: function handler(text, settings) {
2180
+ var maxConsecutiveLineBreaks = settings.maxConsecutiveLineBreaks;
2181
+ var consecutiveLineBreaksRegex = new RegExp("\n{".concat(maxConsecutiveLineBreaks + 1, ",}"), 'g');
2182
+ var replaceValue = repeat('\n', maxConsecutiveLineBreaks);
2183
+ return text.replace(consecutiveLineBreaksRegex, replaceValue);
2184
+ },
2185
+ settings: {
2186
+ maxConsecutiveLineBreaks: 2
2187
+ }
2188
+ };
2189
+
2190
+ var delRepeatSpace = {
2191
+ name: 'common/space/delRepeatSpace',
2192
+ index: '-1',
2193
+ handler: function handler(text) {
2194
+ return text.replace(/([^\n \t])[ \t]{2,}(?![\n \t])/g, '$1 ');
2195
+ }
2196
+ };
2197
+
2198
+ var delTrailingBlanks = {
2199
+ name: 'common/space/delTrailingBlanks',
2200
+ index: '-3',
2201
+ handler: function handler(text) {
2202
+ return text.replace(/[ \t]+\n/g, '\n');
2203
+ }
2204
+ };
2205
+
2206
+ var insertFinalNewline = {
2207
+ name: 'common/space/insertFinalNewline',
2208
+ live: false,
2209
+ disabled: true,
2210
+ queue: 'end',
2211
+ handler: function handler(text) {
2212
+ return text[text.length - 1] === '\n' ? text : text + '\n';
2213
+ }
2214
+ };
2215
+
2216
+ var replaceTab = {
2217
+ name: 'common/space/replaceTab',
2218
+ index: '-5',
2219
+ handler: function handler(text) {
2220
+ return text.replace(/\t/g, ' ');
2221
+ }
2222
+ };
2223
+
2224
+ var squareBracket = {
2225
+ name: 'common/space/squareBracket',
2226
+ handler: function handler(text) {
2227
+ return text.replace(/(\[) +/g, '[').replace(/ +\]/g, ']');
2228
+ }
2229
+ };
2230
+
2231
+ var trimLeft = {
2232
+ name: 'common/space/trimLeft',
2233
+ index: '-4',
2234
+ handler: String.prototype.trimLeft ? function (text) {
2235
+ return text.trimLeft();
2236
+ } :
2237
+ /* istanbul ignore next */
2238
+ function (text) {
2239
+ return text.replace(/^[\s\uFEFF\xA0]+/g, '');
2240
+ }
2241
+ };
2242
+
2243
+ var trimRight = {
2244
+ name: 'common/space/trimRight',
2245
+ index: '-3',
2246
+ live: false,
2247
+ handler: String.prototype.trimRight ? function (text) {
2248
+ return text.trimRight();
2249
+ } :
2250
+ /* istanbul ignore next */
2251
+ function (text) {
2252
+ return text.replace(/[\s\uFEFF\xA0]+$/g, '');
2253
+ }
2254
+ };
2255
+
2256
+ var reColon = new RegExp('(\\D):([^)",:.?\\s\\/\\\\' + privateLabel + '])', 'g');
2257
+ var afterColon = {
2258
+ name: 'common/space/afterColon',
2259
+ handler: function handler(text) {
2260
+ return text.replace(reColon, '$1: $2');
2261
+ }
2262
+ };
2263
+
2264
+ var reComma = new RegExp('(.),([^)",:.?\\s\\/\\\\' + privateLabel + '])', 'g');
2265
+ var afterComma = {
2266
+ name: 'common/space/afterComma',
2267
+ handler: function handler(text) {
2268
+ return text.replace(reComma, function ($0, $1, $2) {
2269
+ return isDigit($1) && isDigit($2) ? $0 : $1 + ', ' + $2;
2270
+ });
2271
+ }
2272
+ };
2273
+
2274
+ var reQuestionMark = new RegExp('\\?([^).…!;?\\s[\\])' + privateLabel + getData('common/quote') + '])', 'g');
2275
+ var afterQuestionMark = {
2276
+ name: 'common/space/afterQuestionMark',
2277
+ handler: function handler(text) {
2278
+ return text.replace(reQuestionMark, '? $1');
2279
+ }
2280
+ };
2281
+
2282
+ var reExclamationMark = new RegExp('!([^).…!;?\\s[\\])' + privateLabel + getData('common/quote') + '])', 'g');
2283
+ var afterExclamationMark = {
2284
+ name: 'common/space/afterExclamationMark',
2285
+ handler: function handler(text) {
2286
+ return text.replace(reExclamationMark, '! $1');
2287
+ }
2288
+ };
2289
+
2290
+ var reSemicolon = new RegExp(';([^).…!;?\\s[\\])' + privateLabel + getData('common/quote') + '])', 'g');
2291
+ var afterSemicolon = {
2292
+ name: 'common/space/afterSemicolon',
2293
+ handler: function handler(text) {
2294
+ return text.replace(reSemicolon, '; $1');
2295
+ }
2296
+ };
2297
+
2298
+ Typograf.addRules([afterColon, afterComma, afterQuestionMark, afterExclamationMark, afterSemicolon, beforeBracket, bracket, delBeforeDot, delBeforePercent, delBeforePunctuation, delBetweenExclamationMarks, delLeadingBlanks, delRepeatN, delRepeatSpace, delTrailingBlanks, insertFinalNewline, replaceTab, squareBracket, trimLeft, trimRight]);
2299
+
2300
+ var arrow = {
2301
+ name: 'common/symbols/arrow',
2302
+ handler: function handler(text) {
2303
+ return replace(text, [[/(^|[^-])->(?!>)/g, '$1→'], [/(^|[^<])<-(?!-)/g, '$1←']]);
2304
+ }
2305
+ };
2306
+
2307
+ var cf = {
2308
+ name: 'common/symbols/cf',
2309
+ handler: function handler(text) {
2310
+ var re = new RegExp("(^|[\\s(\\[+\u2248\xB1\u2212\u2014\u2013\\-])(\\d+(?:[.,]\\d+)?)[ \xA0\u2009]?(C|F)([\\W\\s.,:!?\")\\]]|$)", 'mg');
2311
+ return text.replace(re, "$1$2\u2009\xB0$3$4");
2312
+ }
2313
+ };
2314
+
2315
+ var copy = {
2316
+ name: 'common/symbols/copy',
2317
+ handler: function handler(text) {
2318
+ return replace(text, [[/\(r\)/gi, '®'], [/(copyright )?\((c|с)\)/gi, '©'], [/\(tm\)/gi, '™']]);
2319
+ }
2320
+ };
2321
+
2322
+ Typograf.addRules([arrow, cf, copy]);
2323
+
2324
+ var main = {
2325
+ name: 'en-US/dash/main',
2326
+ index: '-5',
2327
+ handler: function handler(text) {
2328
+ var dashes = getData('common/dash');
2329
+ var nonBreakingSpace = "\xA0";
2330
+ var emDash = "\u2014";
2331
+ var spaceBefore = "[ ".concat(nonBreakingSpace, "]"); // white space or a non-breaking space
2332
+
2333
+ var spaceAfter = "[ ".concat(nonBreakingSpace, "\n]"); // same as spaceBefore, but includes line break
2334
+
2335
+ var re = new RegExp("".concat(spaceBefore, "(").concat(dashes, ")(").concat(spaceAfter, ")"), 'g');
2336
+ return text.replace(re, "".concat(nonBreakingSpace).concat(emDash, "$2"));
2337
+ }
2338
+ };
2339
+
2340
+ Typograf.addRules([main]);
2341
+
2342
+ var centuries = {
2343
+ name: 'ru/dash/centuries',
2344
+ handler: function handler(text, settings) {
2345
+ var dashes = '(' + getData('common/dash') + ')';
2346
+ var re = new RegExp("(X|I|V)[ |\xA0]?" + dashes + "[ |\xA0]?(X|I|V)", 'g');
2347
+ return text.replace(re, '$1' + settings.dash + '$3');
2348
+ },
2349
+ settings: {
2350
+ dash: "\u2013" // &ndash;
2351
+
2352
+ }
2353
+ };
2354
+
2355
+ var daysMonth = {
2356
+ name: 'ru/dash/daysMonth',
2357
+ handler: function handler(text, settings) {
2358
+ var re = new RegExp('(^|\\s)([123]?\\d)' + '(' + getData('common/dash') + ')' + "([123]?\\d)[ \xA0]" + '(' + getData('ru/monthGenCase') + ')', 'g');
2359
+ return text.replace(re, '$1$2' + settings.dash + "$4\xA0$5");
2360
+ },
2361
+ settings: {
2362
+ dash: "\u2013" // &ndash;
2363
+
2364
+ }
2365
+ };
2366
+
2367
+ var de$1 = {
2368
+ name: 'ru/dash/de',
2369
+ handler: function handler(text) {
2370
+ var re = new RegExp('([a-яё]+) де' + getData('ru/dashAfterDe'), 'g');
2371
+ return text.replace(re, '$1-де');
2372
+ },
2373
+ disabled: true
2374
+ };
2375
+
2376
+ var decade = {
2377
+ name: 'ru/dash/decade',
2378
+ handler: function handler(text, settings) {
2379
+ var re = new RegExp('(^|\\s)(\\d{3}|\\d)0' + '(' + getData('common/dash') + ')' + "(\\d{3}|\\d)0(-\u0435[ \xA0])" + "(?=\u0433\\.?[ \xA0]?\u0433|\u0433\u043E\u0434)", 'g');
2380
+ return text.replace(re, '$1$20' + settings.dash + '$40$5');
2381
+ },
2382
+ settings: {
2383
+ dash: "\u2013" // &ndash;
2384
+
2385
+ }
2386
+ };
2387
+
2388
+ var directSpeech = {
2389
+ name: 'ru/dash/directSpeech',
2390
+ handler: function handler(text) {
2391
+ var dashes = getData('common/dash');
2392
+ var re1 = new RegExp("([\"\xBB\u2018\u201C,])[ |\xA0]?(".concat(dashes, ")[ |\xA0]"), 'g');
2393
+ var re2 = new RegExp("(^|".concat(privateLabel, ")(").concat(dashes, ")( |\xA0)"), 'gm');
2394
+ var re3 = new RegExp("([.\u2026?!])[ \xA0](".concat(dashes, ")[ \xA0]"), 'g');
2395
+ return text.replace(re1, "$1\xA0\u2014 ").replace(re2, "$1\u2014\xA0").replace(re3, "$1 \u2014\xA0");
2396
+ }
2397
+ };
2398
+
2399
+ var izpod = {
2400
+ name: 'ru/dash/izpod',
2401
+ handler: function handler(text) {
2402
+ var re = new RegExp(getData('ru/dashBefore') + '(И|и)з под' + getData('ru/dashAfter'), 'g');
2403
+ return text.replace(re, '$1$2з-под');
2404
+ }
2405
+ };
2406
+
2407
+ var izza = {
2408
+ name: 'ru/dash/izza',
2409
+ handler: function handler(text) {
2410
+ var re = new RegExp(getData('ru/dashBefore') + '(И|и)з за' + getData('ru/dashAfter'), 'g');
2411
+ return text.replace(re, '$1$2з-за');
2412
+ }
2413
+ };
2414
+
2415
+ var ka = {
2416
+ name: 'ru/dash/ka',
2417
+ handler: function handler(text) {
2418
+ var re = new RegExp('([a-яё]+) ка(сь)?' + getData('ru/dashAfter'), 'g');
2419
+ return text.replace(re, '$1-ка$2');
2420
+ }
2421
+ };
2422
+
2423
+ var koe = {
2424
+ name: 'ru/dash/koe',
2425
+ handler: function handler(text) {
2426
+ var re = new RegExp(getData('ru/dashBefore') + '([Кк]о[ей])\\s([а-яё]{3,})' + getData('ru/dashAfter'), 'g');
2427
+ return text.replace(re, '$1$2-$3');
2428
+ }
2429
+ };
2430
+
2431
+ var main$1 = {
2432
+ name: 'ru/dash/main',
2433
+ index: '-5',
2434
+ handler: function handler(text) {
2435
+ var dashes = getData('common/dash');
2436
+ var re = new RegExp("([ \xA0])(" + dashes + ")([ \xA0\\n])", 'g');
2437
+ return text.replace(re, "\xA0\u2014$3");
2438
+ }
2439
+ };
2440
+
2441
+ var month = {
2442
+ name: 'ru/dash/month',
2443
+ handler: function handler(text, settings) {
2444
+ var months = '(' + getData('ru/month') + ')';
2445
+ var monthsPre = '(' + getData('ru/monthPreCase') + ')';
2446
+ var dashes = getData('common/dash');
2447
+ var re = new RegExp(months + ' ?(' + dashes + ') ?' + months, 'gi');
2448
+ var rePre = new RegExp(monthsPre + ' ?(' + dashes + ') ?' + monthsPre, 'gi');
2449
+ var newSubStr = '$1' + settings.dash + '$3';
2450
+ return text.replace(re, newSubStr).replace(rePre, newSubStr);
2451
+ },
2452
+ settings: {
2453
+ dash: "\u2013" // &ndash;
2454
+
2455
+ }
2456
+ };
2457
+
2458
+ var surname = {
2459
+ name: 'ru/dash/surname',
2460
+ handler: function handler(text) {
2461
+ var re = new RegExp('([А-ЯЁ][а-яё]+)\\s-([а-яё]{1,3})(?![^а-яё]|$)', 'g');
2462
+ return text.replace(re, "$1\xA0\u2014$2");
2463
+ }
2464
+ };
2465
+
2466
+ var taki = {
2467
+ name: 'ru/dash/taki',
2468
+ handler: function handler(text) {
2469
+ var re = new RegExp('(верно|довольно|опять|прямо|так|вс[её]|действительно|неужели)\\s(таки)' + getData('ru/dashAfter'), 'g');
2470
+ return text.replace(re, '$1-$2');
2471
+ }
2472
+ };
2473
+
2474
+ var time = {
2475
+ name: 'ru/dash/time',
2476
+ handler: function handler(text, settings) {
2477
+ var re = new RegExp(getData('ru/dashBefore') + '(\\d?\\d:[0-5]\\d)' + getData('common/dash') + '(\\d?\\d:[0-5]\\d)' + getData('ru/dashAfter'), 'g');
2478
+ return text.replace(re, '$1$2' + settings.dash + '$3');
2479
+ },
2480
+ settings: {
2481
+ dash: "\u2013" // &ndash;
2482
+
2483
+ }
2484
+ };
2485
+
2486
+ var to = {
2487
+ name: 'ru/dash/to',
2488
+ handler: function handler(text) {
2489
+ var words = '[Оо]ткуда|[Кк]уда|[Гг]де|[Кк]огда|[Зз]ачем|[Пп]очему|[Кк]ак|[Кк]ако[ейм]|[Кк]акая|[Кк]аки[емх]|[Кк]акими|[Кк]акую|[Чч]то|[Чч]его|[Чч]е[йм]|[Чч]ьим?|[Кк]то|[Кк]ого|[Кк]ому|[Кк]ем';
2490
+ var re = new RegExp('(^|[^А-ЯЁа-яё\\w])(' + words + ')( | -|- )(то|либо|нибудь)' + getData('ru/dashAfter'), 'g');
2491
+ return text.replace(re, function ($0, $1, $2, $3, $4) {
2492
+ var kakto = $2 + $3 + $4; // Отдельно обрабатываем в ru/dash/kakto
2493
+
2494
+ if (kakto === 'как то' || kakto === 'Как то') {
2495
+ return $0;
2496
+ }
2497
+
2498
+ return $1 + $2 + '-' + $4;
2499
+ });
2500
+ }
2501
+ };
2502
+
2503
+ var kakto = {
2504
+ name: 'ru/dash/kakto',
2505
+ handler: function handler(text) {
2506
+ var re = new RegExp('(^|[^А-ЯЁа-яё\\w])([Кк]ак) то' + getData('ru/dashAfter'), 'g');
2507
+ return text.replace(re, '$1$2-то');
2508
+ }
2509
+ };
2510
+
2511
+ var weekday = {
2512
+ name: 'ru/dash/weekday',
2513
+ handler: function handler(text, settings) {
2514
+ var part = '(' + getData('ru/weekday') + ')';
2515
+ var re = new RegExp(part + ' ?(' + getData('common/dash') + ') ?' + part, 'gi');
2516
+ return text.replace(re, '$1' + settings.dash + '$3');
2517
+ },
2518
+ settings: {
2519
+ dash: "\u2013" // &ndash;
2520
+
2521
+ }
2522
+ };
2523
+
2524
+ var years = {
2525
+ name: 'ru/dash/years',
2526
+ handler: function handler(text, settings) {
2527
+ var dashes = getData('common/dash');
2528
+ var re = new RegExp("(\\D|^)(\\d{4})[ \xA0]?(" + dashes + ")[ \xA0]?(\\d{4})(?=[ \xA0]?\u0433)", 'g');
2529
+ return text.replace(re, function ($0, $1, $2, $3, $4) {
2530
+ if (parseInt($2, 10) < parseInt($4, 10)) {
2531
+ return $1 + $2 + settings.dash + $4;
2532
+ }
2533
+
2534
+ return $0;
2535
+ });
2536
+ },
2537
+ settings: {
2538
+ dash: "\u2013" // &ndash;
2539
+
2540
+ }
2541
+ };
2542
+
2543
+ Typograf.addRules([centuries, daysMonth, de$1, decade, directSpeech, izpod, izza, ka, koe, main$1, month, surname, taki, time, to, kakto, weekday, years]);
2544
+
2545
+ var fromISO = {
2546
+ name: 'ru/date/fromISO',
2547
+ handler: function handler(text) {
2548
+ var sp1 = '(-|\\.|\\/)';
2549
+ var sp2 = '(-|\\/)';
2550
+ var re1 = new RegExp('(^|\\D)(\\d{4})' + sp1 + '(\\d{2})' + sp1 + '(\\d{2})(\\D|$)', 'gi');
2551
+ var re2 = new RegExp('(^|\\D)(\\d{2})' + sp2 + '(\\d{2})' + sp2 + '(\\d{4})(\\D|$)', 'gi');
2552
+ return text.replace(re1, '$1$6.$4.$2$7').replace(re2, '$1$4.$2.$6$7');
2553
+ }
2554
+ };
2555
+
2556
+ var weekday$1 = {
2557
+ name: 'ru/date/weekday',
2558
+ handler: function handler(text) {
2559
+ var space = "( |\xA0)";
2560
+ var monthCase = getData('ru/monthGenCase');
2561
+ var weekday = getData('ru/weekday');
2562
+ var re = new RegExp('(\\d)' + space + '(' + monthCase + '),' + space + '(' + weekday + ')', 'gi');
2563
+ return text.replace(re, function () {
2564
+ var a = arguments;
2565
+ return a[1] + a[2] + a[3].toLowerCase() + ',' + a[4] + a[5].toLowerCase();
2566
+ });
2567
+ }
2568
+ };
2569
+
2570
+ Typograf.addRules([fromISO, weekday$1]);
2571
+
2572
+ var currency = {
2573
+ name: 'ru/money/currency',
2574
+ handler: function handler(text) {
2575
+ var currency = '([$€¥Ұ£₤₽])';
2576
+ var space = "[ \xA0\u2009\u202F]";
2577
+ var re1 = new RegExp('(^|[\\D]{2})' + currency + ' ?(' + regExpNumber + '(' + space + '\\d{3})*)(' + space + '?(тыс\\.|млн|млрд|трлн))?', 'gm');
2578
+ var re2 = new RegExp('(^|[\\D])(' + regExpNumber + ') ?' + currency, 'gm');
2579
+ return text.replace(re1, function ($0, $1, $2, $3, $4, $5, $6, $7) {
2580
+ return $1 + $3 + ($7 ? "\xA0" + $7 : '') + "\xA0" + $2;
2581
+ }).replace(re2, "$1$2\xA0$4");
2582
+ },
2583
+ disabled: true
2584
+ };
2585
+
2586
+ var ruble = {
2587
+ name: 'ru/money/ruble',
2588
+ handler: function handler(text) {
2589
+ var newSubstr = "$1\xA0\u20BD";
2590
+ var commonPart = "(\\d+)( |\xA0)?(\u0440|\u0440\u0443\u0431)\\.";
2591
+ var re1 = new RegExp('^' + commonPart + '$', 'g');
2592
+ var re2 = new RegExp(commonPart + '(?=[!?,:;])', 'g');
2593
+ var re3 = new RegExp(commonPart + '(?=\\s+[A-ЯЁ])', 'g');
2594
+ return text.replace(re1, newSubstr).replace(re2, newSubstr).replace(re3, newSubstr + '.');
2595
+ },
2596
+ disabled: true
2597
+ };
2598
+
2599
+ Typograf.addRules([currency, ruble]);
2600
+
2601
+ var abbr = {
2602
+ name: 'ru/nbsp/abbr',
2603
+ handler: function handler(text) {
2604
+ function abbr($0, $1, $2, $3) {
2605
+ // дд.мм.гггг
2606
+ if ($2 === 'дд' && $3 === 'мм') {
2607
+ return $0;
2608
+ } // Являются ли сокращения ссылкой
2609
+
2610
+
2611
+ if (['рф', 'ру', 'рус', 'орг', 'укр', 'бг', 'срб'].indexOf($3) > -1) {
2612
+ return $0;
2613
+ }
2614
+
2615
+ return $1 + $2 + '.' + "\xA0" + $3 + '.';
2616
+ }
2617
+
2618
+ var re = new RegExp("(^|\\s|".concat(privateLabel, ")([\u0430-\u044F\u0451]{1,3})\\. ?([\u0430-\u044F\u0451]{1,3})\\."), 'g');
2619
+ return text.replace(re, abbr) // Для тройных сокращений - а.е.м.
2620
+ .replace(re, abbr);
2621
+ }
2622
+ };
2623
+
2624
+ var addr = {
2625
+ name: 'ru/nbsp/addr',
2626
+ handler: function handler(text) {
2627
+ return text.replace(/(\s|^)(дом|д\.|кв\.|под\.|п-д) *(\d+)/gi, "$1$2\xA0$3").replace(/(\s|^)(мкр-н|мк-н|мкр\.|мкрн)\s/gi, "$1$2\xA0") // микрорайон
2628
+ .replace(/(\s|^)(эт\.) *(-?\d+)/gi, "$1$2\xA0$3").replace(/(\s|^)(\d+) +этаж([^а-яё]|$)/gi, "$1$2\xA0\u044D\u0442\u0430\u0436$3").replace(/(\s|^)литер\s([А-Я]|$)/gi, "$1\u043B\u0438\u0442\u0435\u0440\xA0$2")
2629
+ /*
2630
+ область, край, станция, поселок, село,
2631
+ деревня, улица, переулок, проезд, проспект,
2632
+ бульвар, площадь, набережная, шоссе,
2633
+ тупик, офис, комната, участок, владение, строение, корпус
2634
+ */
2635
+ .replace(/(\s|^)(обл|кр|ст|пос|с|д|ул|пер|пр|пр-т|просп|пл|бул|б-р|наб|ш|туп|оф|комн?|уч|вл|влад|стр|кор)\. *([а-яёa-z\d]+)/gi, "$1$2.\xA0$3") // город
2636
+ .replace(/(\D[ \u00A0]|^)г\. ?([А-ЯЁ])/gm, "$1\u0433.\xA0$2");
2637
+ }
2638
+ };
2639
+
2640
+ var afterNumberSign = {
2641
+ name: 'ru/nbsp/afterNumberSign',
2642
+ handler: function handler(text) {
2643
+ // \u2009 - THIN SPACE
2644
+ // \u202F - NARROW NO-BREAK SPACE
2645
+ return text.replace(/№[ \u00A0\u2009]?(\d|п\/п)/g, "\u2116\u202F$1");
2646
+ }
2647
+ };
2648
+
2649
+ var beforeParticle = {
2650
+ name: 'ru/nbsp/beforeParticle',
2651
+ index: '+5',
2652
+ handler: function handler(text) {
2653
+ var particles = '(ли|ль|же|ж|бы|б)';
2654
+ var re1 = new RegExp('([А-ЯЁа-яё]) ' + particles + '(?=[,;:?!"‘“»])', 'g');
2655
+ var re2 = new RegExp("([\u0410-\u042F\u0401\u0430-\u044F\u0451])[ \xA0]" + particles + "[ \xA0]", 'g');
2656
+ return text.replace(re1, "$1\xA0$2").replace(re2, "$1\xA0$2 ");
2657
+ }
2658
+ };
2659
+
2660
+ var centuries$1 = {
2661
+ name: 'ru/nbsp/centuries',
2662
+ handler: function handler(text) {
2663
+ var dashes = getData('common/dash');
2664
+ var before = '(^|\\s)([VIX]+)';
2665
+ var after = '(?=[,;:?!"‘“»]|$)';
2666
+ var re1 = new RegExp(before + "[ \xA0]?\u0432\\.?" + after, 'gm');
2667
+ var re2 = new RegExp(before + '(' + dashes + ')' + "([VIX]+)[ \xA0]?\u0432\\.?([ \xA0]?\u0432\\.?)?" + after, 'gm');
2668
+ return text.replace(re1, "$1$2\xA0\u0432.").replace(re2, "$1$2$3$4\xA0\u0432\u0432.");
2669
+ }
2670
+ };
2671
+
2672
+ var dayMonth = {
2673
+ name: 'ru/nbsp/dayMonth',
2674
+ handler: function handler(text) {
2675
+ var re = new RegExp('(\\d{1,2}) (' + getData('ru/shortMonth') + ')', 'gi');
2676
+ return text.replace(re, "$1\xA0$2");
2677
+ }
2678
+ };
2679
+
2680
+ var initials = {
2681
+ name: 'ru/nbsp/initials',
2682
+ handler: function handler(text) {
2683
+ var spaces = "\xA0\u202F "; // nbsp, thinsp
2684
+
2685
+ var quote = getData('ru/quote');
2686
+ var re = new RegExp('(^|[' + spaces + quote.left + privateLabel + '"])([А-ЯЁ])\\.[' + spaces + ']?([А-ЯЁ])\\.[' + spaces + ']?([А-ЯЁ][а-яё]+)', 'gm');
2687
+ return text.replace(re, "$1$2.\xA0$3.\xA0$4");
2688
+ }
2689
+ };
2690
+
2691
+ var m = {
2692
+ name: 'ru/nbsp/m',
2693
+ index: '+5',
2694
+ handler: function handler(text) {
2695
+ var re = new RegExp('(^|[\\s,.\\(' + privateLabel + '])' + "(\\d+)[ \xA0]?(\u043C\u043C?|\u0441\u043C|\u043A\u043C|\u0434\u043C|\u0433\u043C|mm?|km|cm|dm)([23\xB2\xB3])?([\\s\\).!?,;" + privateLabel + ']|$)', 'gm');
2696
+ return text.replace(re, function ($0, $1, $2, $3, $4, $5) {
2697
+ var pow = {
2698
+ '2': '²',
2699
+ '²': '²',
2700
+ '3': '³',
2701
+ '³': '³',
2702
+ '': ''
2703
+ }[$4 || ''];
2704
+ return $1 + $2 + "\xA0" + $3 + pow + ($5 === "\xA0" ? ' ' : $5);
2705
+ });
2706
+ }
2707
+ };
2708
+
2709
+ var mln = {
2710
+ name: 'ru/nbsp/mln',
2711
+ handler: function handler(text) {
2712
+ return text.replace(/(\d) ?(тыс|млн|млрд|трлн)(\.|\s|$)/gi, "$1\xA0$2$3");
2713
+ }
2714
+ };
2715
+
2716
+ var ooo = {
2717
+ name: 'ru/nbsp/ooo',
2718
+ handler: function handler(text) {
2719
+ return text.replace(/(^|[^a-яёA-ЯЁ])(ООО|ОАО|ЗАО|НИИ|ПБОЮЛ) /g, "$1$2\xA0");
2720
+ }
2721
+ };
2722
+
2723
+ var page = {
2724
+ name: 'ru/nbsp/page',
2725
+ handler: function handler(text) {
2726
+ var re = new RegExp('(^|[)\\s' + privateLabel + '])' + '(стр|гл|рис|илл?|ст|п|c)\\. *(\\d+)([\\s.,?!;:]|$)', 'gim');
2727
+ return text.replace(re, "$1$2.\xA0$3$4");
2728
+ }
2729
+ };
2730
+
2731
+ var ps = {
2732
+ name: 'ru/nbsp/ps',
2733
+ handler: function handler(text) {
2734
+ var re = new RegExp("(^|\\s|".concat(privateLabel, ")[p\u0437]\\.[ \xA0]?([p\u0437]\\.[ \xA0]?)?[s\u044B]\\.:? "), 'gim');
2735
+ return text.replace(re, function ($0, $1, $2) {
2736
+ return $1 + ($2 ? "P.\xA0P.\xA0S. " : "P.\xA0S. ");
2737
+ });
2738
+ }
2739
+ };
2740
+
2741
+ var rubleKopek = {
2742
+ name: 'ru/nbsp/rubleKopek',
2743
+ handler: function handler(text) {
2744
+ return text.replace(/(\d) ?(?=(руб|коп)\.)/g, "$1\xA0");
2745
+ }
2746
+ };
2747
+
2748
+ var see = {
2749
+ name: 'ru/nbsp/see',
2750
+ handler: function handler(text) {
2751
+ var re = new RegExp("(^|\\s|".concat(privateLabel, "|\\()(\u0441\u043C|\u0438\u043C)\\.[ \xA0]?([\u0430-\u044F\u04510-9a-z]+)([\\s.,?!]|$)"), 'gi');
2752
+ return text.replace(re, function ($0, $1, $2, $3, $4) {
2753
+ return ($1 === "\xA0" ? ' ' : $1) + $2 + ".\xA0" + $3 + $4;
2754
+ });
2755
+ }
2756
+ };
2757
+
2758
+ var year = {
2759
+ name: 'ru/nbsp/year',
2760
+ handler: function handler(text) {
2761
+ return text.replace(/(^|\D)(\d{4}) ?г([ ,;.\n]|$)/g, "$1$2\xA0\u0433$3");
2762
+ }
2763
+ };
2764
+
2765
+ var years$1 = {
2766
+ name: 'ru/nbsp/years',
2767
+ index: '+5',
2768
+ handler: function handler(text) {
2769
+ var dashes = getData('common/dash');
2770
+ var re = new RegExp('(^|\\D)(\\d{4})(' + dashes + ")(\\d{4})[ \xA0]?\u0433\\.?([ \xA0]?\u0433\\.)?(?=[,;:?!\"\u2018\u201C\xBB\\s]|$)", 'gm');
2771
+ return text.replace(re, "$1$2$3$4\xA0\u0433\u0433.");
2772
+ }
2773
+ };
2774
+
2775
+ Typograf.addRules([abbr, addr, afterNumberSign, beforeParticle, centuries$1, dayMonth, initials, m, mln, ooo, page, ps, rubleKopek, see, year, years$1]);
2776
+
2777
+ var comma = {
2778
+ name: 'ru/number/comma',
2779
+ handler: function handler(text) {
2780
+ // \u00A0 - NO-BREAK SPACE
2781
+ // \u2009 - THIN SPACE
2782
+ // \u202F - NARROW NO-BREAK SPACE
2783
+ return text.replace(/(^|\s)(\d+)\.(\d+[\u00A0\u2009\u202F ]*?[%‰°×x])/gim, '$1$2,$3');
2784
+ }
2785
+ };
2786
+
2787
+ var ordinals = {
2788
+ name: 'ru/number/ordinals',
2789
+ handler: function handler(text, settings, context) {
2790
+ var re = new RegExp('(\\d[%‰]?)-(ый|ой|ая|ое|ые|ым|ом|ых|ого|ому|ыми)(?![' + context.getData('char') + '])', 'g');
2791
+ return text.replace(re, function ($0, $1, $2) {
2792
+ var parts = {
2793
+ 'ой': 'й',
2794
+ 'ый': 'й',
2795
+ 'ая': 'я',
2796
+ 'ое': 'е',
2797
+ 'ые': 'е',
2798
+ 'ым': 'м',
2799
+ 'ом': 'м',
2800
+ 'ых': 'х',
2801
+ 'ого': 'го',
2802
+ 'ому': 'му',
2803
+ 'ыми': 'ми'
2804
+ };
2805
+ return $1 + '-' + parts[$2];
2806
+ });
2807
+ }
2808
+ };
2809
+
2810
+ Typograf.addRules([comma, ordinals]);
2811
+
2812
+ function removeOptAlignTags(text, classNames) {
2813
+ var re = new RegExp('<span class="(' + classNames.join('|') + ')">([^]*?)</span>', 'g');
2814
+ return text.replace(re, '$2');
2815
+ }
2816
+ function removeOptAlignTagsFromTitle(text, classNames) {
2817
+ return text.replace(/<title>[^]*?<\/title>/i, function (text) {
2818
+ return removeOptAlignTags(text, classNames);
2819
+ });
2820
+ }
2821
+
2822
+ var classNames = ['typograf-oa-lbracket', 'typograf-oa-n-lbracket', 'typograf-oa-sp-lbracket'];
2823
+ var name = 'ru/optalign/bracket';
2824
+ var bracket$1 = {
2825
+ name: name,
2826
+ handler: function handler(text) {
2827
+ return text.replace(/( |\u00A0)\(/g, '<span class="typograf-oa-sp-lbracket">$1</span><span class="typograf-oa-lbracket">(</span>').replace(/^\(/gm, '<span class="typograf-oa-n-lbracket">(</span>');
2828
+ },
2829
+ disabled: true,
2830
+ htmlAttrs: false
2831
+ };
2832
+ var innerStartBracket = {
2833
+ name: name,
2834
+ queue: 'start',
2835
+ handler: function handler(text) {
2836
+ return removeOptAlignTags(text, classNames);
2837
+ }
2838
+ };
2839
+ var innerEndBracket = {
2840
+ name: name,
2841
+ queue: 'end',
2842
+ handler: function handler(text) {
2843
+ return removeOptAlignTagsFromTitle(text, classNames);
2844
+ }
2845
+ };
2846
+
2847
+ var classNames$1 = ['typograf-oa-comma', 'typograf-oa-comma-sp'];
2848
+ var name$1 = 'ru/optalign/comma';
2849
+ var comma$1 = {
2850
+ name: name$1,
2851
+ handler: function handler(text, settings, context) {
2852
+ var re = new RegExp('([' + context.getData('char') + "\\d\u0301]+), ", 'gi');
2853
+ return text.replace(re, '$1<span class="typograf-oa-comma">,</span><span class="typograf-oa-comma-sp"> </span>');
2854
+ },
2855
+ disabled: true,
2856
+ htmlAttrs: false
2857
+ };
2858
+ var innerStartComma = {
2859
+ name: name$1,
2860
+ queue: 'start',
2861
+ handler: function handler(text) {
2862
+ return removeOptAlignTags(text, classNames$1);
2863
+ }
2864
+ };
2865
+ var innerEndComma = {
2866
+ name: name$1,
2867
+ queue: 'end',
2868
+ handler: function handler(text) {
2869
+ return removeOptAlignTagsFromTitle(text, classNames$1);
2870
+ }
2871
+ };
2872
+
2873
+ var classNames$2 = ['typograf-oa-lquote', 'typograf-oa-n-lquote', 'typograf-oa-sp-lquote'];
2874
+ var name$2 = 'ru/optalign/quote';
2875
+ var quote$1 = {
2876
+ name: name$2,
2877
+ handler: function handler(text) {
2878
+ var quote = this.getSetting('common/punctuation/quote', 'ru');
2879
+ var lquotes = '([' + quote.left[0] + (quote.left[1] || '') + '])';
2880
+ var reNewLine = new RegExp('(^|\n\n|' + privateLabel + ')(' + lquotes + ')', 'g');
2881
+ var reInside = new RegExp('([^\n' + privateLabel + "])([ \xA0\n])(" + lquotes + ')', 'gi');
2882
+ return text.replace(reNewLine, '$1<span class="typograf-oa-n-lquote">$2</span>').replace(reInside, '$1<span class="typograf-oa-sp-lquote">$2</span><span class="typograf-oa-lquote">$3</span>');
2883
+ },
2884
+ disabled: true,
2885
+ htmlAttrs: false
2886
+ };
2887
+ var innerStartQuote = {
2888
+ name: name$2,
2889
+ queue: 'start',
2890
+ handler: function handler(text) {
2891
+ return removeOptAlignTags(text, classNames$2);
2892
+ }
2893
+ };
2894
+ var innerEndQuote = {
2895
+ name: name$2,
2896
+ queue: 'end',
2897
+ handler: function handler(text) {
2898
+ return removeOptAlignTagsFromTitle(text, classNames$2);
2899
+ }
2900
+ };
2901
+
2902
+ Typograf.addRules([bracket$1, comma$1, quote$1]);
2903
+ Typograf.addInnerRules([innerStartBracket, innerEndBracket, innerStartComma, innerEndComma, innerStartQuote, innerEndQuote]);
2904
+
2905
+ var accent = {
2906
+ name: 'ru/other/accent',
2907
+ handler: function handler(text) {
2908
+ return text.replace(/([а-яё])([АЕЁИОУЫЭЮЯ])([^А-ЯЁ\w]|$)/g, function ($0, $1, $2, $3) {
2909
+ return $1 + $2.toLowerCase() + "\u0301" + $3;
2910
+ });
2911
+ },
2912
+ disabled: true
2913
+ };
2914
+
2915
+ var defaultCityCodeLength = 5;
2916
+ var countryCode = '7';
2917
+ var exceptions = [];
2918
+ var exceptionsMax = 8;
2919
+ var exceptionsMin = 2;
2920
+ [4162, 416332, 8512, 851111, 4722, 4725, 391379, 8442, 4732, 4152, 4154451, 4154459, 4154455, 41544513, 8142, 8332, 8612, 8622, 3525, 812, 8342, 8152, 3812, 4862, 3422, 342633, 8112, 9142, 8452, 3432, 3434, 3435, 4812, 8432, 8439, 3822, 4872, 3412, 3511, 3512, 3022, 4112, 4852, 4855, 3852, 3854, 8182, 818, 90, 3472, 4741, 4764, 4832, 4922, 8172, 8202, 8722, 4932, 493, 3952, 3951, 3953, 411533, 4842, 3842, 3843, 8212, 4942, '39131-39179', '39190-39199', 391, 4712, 4742, 8362, 495, 499, 4966, 4964, 4967, 498, 8312, 8313, 3832, 383612, 3532, 8412, 4232, 423370, 423630, 8632, 8642, 8482, 4242, 8672, 8652, 4752, 4822, 482502, 4826300, 3452, 8422, 4212, 3466, 3462, 8712, 8352, '901-934', '936-939', '950-953', 958, '960-969', '977-989', '991-997', 999].forEach(function (num) {
2921
+ if (typeof num === 'string') {
2922
+ var buf = num.split('-');
2923
+
2924
+ for (var i = +buf[0]; i <= +buf[1]; i++) {
2925
+ exceptions.push(i);
2926
+ }
2927
+ } else {
2928
+ exceptions.push(num);
2929
+ }
2930
+ });
2931
+
2932
+ function phone(num) {
2933
+ var firstSym = num[0];
2934
+ var cityCode = '';
2935
+ var hasPlusWithCode;
2936
+ var hasEight;
2937
+
2938
+ if (num.length < 8) {
2939
+ return phoneBlocks(num);
2940
+ } // 8 495 123-45-67, +7 495 123-45-67
2941
+
2942
+
2943
+ if (num.length > 10) {
2944
+ if (firstSym === '+') {
2945
+ if (num[1] === countryCode) {
2946
+ hasPlusWithCode = true;
2947
+ num = num.substr(2);
2948
+ } else {
2949
+ return num;
2950
+ }
2951
+ } else if (firstSym === '8') {
2952
+ hasEight = true;
2953
+ num = num.substr(1);
2954
+ }
2955
+ }
2956
+
2957
+ for (var cityCodeLen = exceptionsMax; cityCodeLen >= exceptionsMin; cityCodeLen--) {
2958
+ var code = +num.substr(0, cityCodeLen);
2959
+
2960
+ if (exceptions.indexOf(code) > -1) {
2961
+ cityCode = num.substr(0, cityCodeLen);
2962
+ num = num.substr(cityCodeLen);
2963
+ break;
2964
+ }
2965
+ }
2966
+
2967
+ if (!cityCode) {
2968
+ cityCode = num.substr(0, defaultCityCodeLength);
2969
+ num = num.substr(defaultCityCodeLength);
2970
+ }
2971
+
2972
+ return (hasPlusWithCode ? '+' + countryCode + "\xA0" : '') + (hasEight ? "8\xA0" : '') + prepareCode(cityCode) + "\xA0" + phoneBlocks(num);
2973
+ }
2974
+
2975
+ function prepareCode(code) {
2976
+ var numCode = +code;
2977
+ var len = code.length;
2978
+ var result = [code];
2979
+ var withoutBrackets = false;
2980
+
2981
+ if (len > 3) {
2982
+ switch (len) {
2983
+ case 4:
2984
+ result = [code.substr(0, 2), code.substr(2, 2)];
2985
+ break;
2986
+
2987
+ case 5:
2988
+ result = [code.substr(0, 3), code.substr(3, 3)];
2989
+ break;
2990
+
2991
+ case 6:
2992
+ result = [code.substr(0, 2), code.substr(2, 2), code.substr(4, 2)];
2993
+ break;
2994
+ }
2995
+ } else {
2996
+ // Мобильные и московские номера без скобок
2997
+ withoutBrackets = numCode > 900 && numCode <= 999 || numCode === 495 || numCode === 499;
2998
+ }
2999
+
3000
+ result = result.join('-');
3001
+ return withoutBrackets ? result : '(' + result + ')';
3002
+ }
3003
+
3004
+ function phoneBlocks(num) {
3005
+ var add = '';
3006
+
3007
+ if (num.length % 2) {
3008
+ add = num[0];
3009
+ add += num.length <= 5 ? '-' : '';
3010
+ num = num.substr(1, num.length - 1);
3011
+ }
3012
+
3013
+ return add + num.split(/(?=(?:\d\d)+$)/).join('-');
3014
+ }
3015
+
3016
+ function clearPhone(text) {
3017
+ return text.replace(/[^\d+]/g, '');
3018
+ }
3019
+
3020
+ var phoneNumber = {
3021
+ name: 'ru/other/phone-number',
3022
+ live: false,
3023
+ handler: function handler(text) {
3024
+ var re = new RegExp('(^|,| |' + privateLabel + ")(\\+7[\\d\\(\\) \xA0-]{10,18})(?=,|;|" + privateLabel + '|$)', 'gm');
3025
+ return text.replace(re, function ($0, $1, $2) {
3026
+ var buf = clearPhone($2);
3027
+ return buf.length === 12 ? $1 + phone(buf) : $0;
3028
+ }).replace( // eslint-disable-next-line no-misleading-character-class
3029
+ /(^|[^а-яё])([☎☏✆📠📞📱]|т\.|тел\.|ф\.|моб\.|факс|сотовый|мобильный|телефон)(:?\s*?)([+\d(][\d \u00A0\-()]{3,}\d)/gi, function ($0, $1, $2, $3, $4) {
3030
+ var buf = clearPhone($4);
3031
+
3032
+ if (buf.length >= 5) {
3033
+ return $1 + $2 + $3 + phone(buf);
3034
+ }
3035
+
3036
+ return $0;
3037
+ });
3038
+ }
3039
+ };
3040
+
3041
+ Typograf.addRules([accent, phoneNumber]);
3042
+
3043
+ var ano = {
3044
+ name: 'ru/punctuation/ano',
3045
+ handler: function handler(text) {
3046
+ var re = new RegExp('([^«„[(!?,:;\\-‒–—\\s' + privateLabel + "])(\\s+)(\u0430|\u043D\u043E)(?= |\xA0|\\n)", 'g');
3047
+ return text.replace(re, '$1,$2$3');
3048
+ }
3049
+ };
3050
+
3051
+ var exclamation = {
3052
+ name: 'ru/punctuation/exclamation',
3053
+ live: false,
3054
+ handler: function handler(text) {
3055
+ return text.replace(/(^|[^!])!{2}($|[^!])/gm, '$1!$2').replace(/(^|[^!])!{4}($|[^!])/gm, '$1!!!$2');
3056
+ }
3057
+ };
3058
+
3059
+ var exclamationQuestion = {
3060
+ name: 'ru/punctuation/exclamationQuestion',
3061
+ index: '+5',
3062
+ handler: function handler(text) {
3063
+ var re = new RegExp('(^|[^!])!\\?([^?]|$)', 'g');
3064
+ return text.replace(re, '$1?!$2');
3065
+ }
3066
+ };
3067
+
3068
+ var hellipQuestion = {
3069
+ name: 'ru/punctuation/hellipQuestion',
3070
+ handler: function handler(text) {
3071
+ return text.replace(/(^|[^.])(\.\.\.|…),/g, '$1…').replace(/(!|\?)(\.\.\.|…)(?=[^.]|$)/g, '$1..');
3072
+ }
3073
+ };
3074
+
3075
+ Typograf.addRules([ano, exclamation, exclamationQuestion, hellipQuestion]);
3076
+
3077
+ var afterHellip = {
3078
+ name: 'ru/space/afterHellip',
3079
+ handler: function handler(text) {
3080
+ return text.replace(/([а-яё])(\.\.\.|…)([А-ЯЁ])/g, '$1$2 $3').replace(/([?!]\.\.)([а-яёa-z])/gi, '$1 $2');
3081
+ }
3082
+ };
3083
+
3084
+ var year$1 = {
3085
+ name: 'ru/space/year',
3086
+ handler: function handler(text, settings, context) {
3087
+ var re = new RegExp("(^| |\xA0)(\\d{3,4})(\u0433\u043E\u0434([\u0430\u0443\u0435]|\u043E\u043C)?)([^" + context.getData('char') + ']|$)', 'g');
3088
+ return text.replace(re, '$1$2 $3$5');
3089
+ }
3090
+ };
3091
+
3092
+ Typograf.addRules([afterHellip, year$1]);
3093
+
3094
+ var nn = {
3095
+ name: 'ru/symbols/NN',
3096
+ handler: function handler(text) {
3097
+ return text.replace(/№№/g, '№');
3098
+ }
3099
+ };
3100
+
3101
+ Typograf.addRules([nn]);
3102
+
3103
+ var replacements = {
3104
+ A: 'А',
3105
+ // Latin: Russian
3106
+ a: 'а',
3107
+ B: 'В',
3108
+ E: 'Е',
3109
+ e: 'е',
3110
+ K: 'К',
3111
+ M: 'М',
3112
+ H: 'Н',
3113
+ O: 'О',
3114
+ o: 'о',
3115
+ P: 'Р',
3116
+ p: 'р',
3117
+ C: 'С',
3118
+ c: 'с',
3119
+ T: 'Т',
3120
+ y: 'у',
3121
+ X: 'Х',
3122
+ x: 'х'
3123
+ };
3124
+ var keys = Object.keys(replacements).join('');
3125
+ var switchingKeyboardLayout = {
3126
+ name: 'ru/typo/switchingKeyboardLayout',
3127
+ handler: function handler(text) {
3128
+ var re = new RegExp('([' + keys + ']{1,3})(?=[А-ЯЁа-яё]+?)', 'g');
3129
+ return text.replace(re, function (str, $1) {
3130
+ var result = '';
3131
+
3132
+ for (var i = 0; i < $1.length; i++) {
3133
+ result += replacements[$1[i]];
3134
+ }
3135
+
3136
+ return result;
3137
+ });
3138
+ }
3139
+ };
3140
+
3141
+ Typograf.addRules([switchingKeyboardLayout]);
3142
+
3143
+ export default Typograf;