guide 0.7.0 → 0.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9ecdd35516494ffde39a8b63923030fda139746eb6117f3f5e77dec91f0a18a
4
- data.tar.gz: f49f70bd07c1694242e737d58f8f178cc69f14bd838c811b1de7ef64acc52fab
3
+ metadata.gz: e16bc443fc8ef63b16a46d8ccdfde8659f7d6fc6285539e402af99d140f84571
4
+ data.tar.gz: 38f412d0da66483df051b5e6a8be761f7748e08dbf2f2944beba96687ce54b40
5
5
  SHA512:
6
- metadata.gz: 9bf4cb51a939a00e5b770adf521f30859f05958498c26c7256137e946a2ff186b6f73ebbf6e053f33cb87c942cb1365687a5bab8004afb7303f64b996791b1ac
7
- data.tar.gz: a3e735e79f2c0cb0db15f1118cd8fa8b0291bad4e1c5827192ac476226cbfdf27b7d2ae827b5843a0f248c6be27599a36f23d52f61b769986819b74dbe9f7bff
6
+ metadata.gz: 958c597a15af220c11de53c8f9e3edc73d5a09676ba685aef95262d98dd667e2161c101bfb617db7c91e7f6776bcf9d0967bb0f93e1856d7fa07f2b7b98169b8
7
+ data.tar.gz: 298143a1c3dfb085d017a63fe3a0454b722abc5347a370c283a03af5b772d9e4b29f90a9f7bd6d06bf49f7c352eb77c52bfd5621dae70f36e0a67f07d632affc
data/Rakefile CHANGED
@@ -1,7 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
6
+ assets_target = 'app/assets'
7
+ js_target = "#{assets_target}/javascripts/guide"
8
+ css_target = "#{assets_target}/stylesheets/guide"
9
+
10
+ CLEAN << assets_target
4
11
  RSpec::Core::RakeTask.new(:spec)
12
+ task spec: %w[generate_assets]
13
+ task build: %w[clean generate_assets]
14
+ task generate_assets: %W[
15
+ #{js_target}/application.js
16
+ #{js_target}/scenario.js
17
+ #{css_target}/application.css
18
+ ]
19
+
20
+ rule(%r{^#{js_target}/.+\.js$} => [->(n) { n.sub(js_target, 'javascript') }, 'node_modules/.install']) do |t|
21
+ sh "yarn browserify #{t.source} -o #{t.name}"
22
+ end
23
+
24
+ rule(%r{^#{css_target}/.+\.css$} => [->(n) { n.sub(css_target, 'styles') }, 'node_modules/.install']) do |t|
25
+ sh "yarn postcss #{t.source} -o #{t.name}"
26
+ end
27
+
28
+ file 'node_modules/.install' => %w[package.json yarn.lock] do
29
+ sh 'yarn install'
30
+ touch 'node_modules/.install'
31
+ end
5
32
 
6
33
  task :setup_test_app, [:rails_version] do |_task, args|
7
34
  require_relative './spec/test_apps/setup'
@@ -1,4 +1,4 @@
1
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
1
+ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
2
  var $ = window.jQuery = require('jquery')
3
3
  require('prismjs')
4
4
 
@@ -14319,446 +14319,1175 @@ return jQuery;
14319
14319
  return MicroPlugin;
14320
14320
  }));
14321
14321
  },{}],18:[function(require,module,exports){
14322
- (function (global){
14322
+ (function (global){(function (){
14323
14323
 
14324
14324
  /* **********************************************
14325
14325
  Begin prism-core.js
14326
14326
  ********************************************** */
14327
14327
 
14328
+ /// <reference lib="WebWorker"/>
14329
+
14328
14330
  var _self = (typeof window !== 'undefined')
14329
14331
  ? window // if in browser
14330
14332
  : (
14331
14333
  (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
14332
- ? self // if in worker
14333
- : {} // if in node js
14334
+ ? self // if in worker
14335
+ : {} // if in node js
14334
14336
  );
14335
14337
 
14336
14338
  /**
14337
14339
  * Prism: Lightweight, robust, elegant syntax highlighting
14338
- * MIT license http://www.opensource.org/licenses/mit-license.php/
14339
- * @author Lea Verou http://lea.verou.me
14340
+ *
14341
+ * @license MIT <https://opensource.org/licenses/MIT>
14342
+ * @author Lea Verou <https://lea.verou.me>
14343
+ * @namespace
14344
+ * @public
14340
14345
  */
14346
+ var Prism = (function (_self) {
14341
14347
 
14342
- var Prism = (function(){
14348
+ // Private helper vars
14349
+ var lang = /\blang(?:uage)?-([\w-]+)\b/i;
14350
+ var uniqueId = 0;
14343
14351
 
14344
- // Private helper vars
14345
- var lang = /\blang(?:uage)?-(\w+)\b/i;
14346
- var uniqueId = 0;
14352
+ // The grammar object for plaintext
14353
+ var plainTextGrammar = {};
14347
14354
 
14348
- var _ = _self.Prism = {
14349
- util: {
14350
- encode: function (tokens) {
14351
- if (tokens instanceof Token) {
14352
- return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
14353
- } else if (_.util.type(tokens) === 'Array') {
14354
- return tokens.map(_.util.encode);
14355
- } else {
14356
- return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
14357
- }
14358
- },
14359
14355
 
14360
- type: function (o) {
14361
- return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
14362
- },
14356
+ var _ = {
14357
+ /**
14358
+ * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
14359
+ * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
14360
+ * additional languages or plugins yourself.
14361
+ *
14362
+ * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
14363
+ *
14364
+ * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
14365
+ * empty Prism object into the global scope before loading the Prism script like this:
14366
+ *
14367
+ * ```js
14368
+ * window.Prism = window.Prism || {};
14369
+ * Prism.manual = true;
14370
+ * // add a new <script> to load Prism's script
14371
+ * ```
14372
+ *
14373
+ * @default false
14374
+ * @type {boolean}
14375
+ * @memberof Prism
14376
+ * @public
14377
+ */
14378
+ manual: _self.Prism && _self.Prism.manual,
14379
+ disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
14363
14380
 
14364
- objId: function (obj) {
14365
- if (!obj['__id']) {
14366
- Object.defineProperty(obj, '__id', { value: ++uniqueId });
14367
- }
14368
- return obj['__id'];
14369
- },
14381
+ /**
14382
+ * A namespace for utility methods.
14383
+ *
14384
+ * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
14385
+ * change or disappear at any time.
14386
+ *
14387
+ * @namespace
14388
+ * @memberof Prism
14389
+ */
14390
+ util: {
14391
+ encode: function encode(tokens) {
14392
+ if (tokens instanceof Token) {
14393
+ return new Token(tokens.type, encode(tokens.content), tokens.alias);
14394
+ } else if (Array.isArray(tokens)) {
14395
+ return tokens.map(encode);
14396
+ } else {
14397
+ return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
14398
+ }
14399
+ },
14370
14400
 
14371
- // Deep clone a language definition (e.g. to extend it)
14372
- clone: function (o) {
14373
- var type = _.util.type(o);
14401
+ /**
14402
+ * Returns the name of the type of the given value.
14403
+ *
14404
+ * @param {any} o
14405
+ * @returns {string}
14406
+ * @example
14407
+ * type(null) === 'Null'
14408
+ * type(undefined) === 'Undefined'
14409
+ * type(123) === 'Number'
14410
+ * type('foo') === 'String'
14411
+ * type(true) === 'Boolean'
14412
+ * type([1, 2]) === 'Array'
14413
+ * type({}) === 'Object'
14414
+ * type(String) === 'Function'
14415
+ * type(/abc+/) === 'RegExp'
14416
+ */
14417
+ type: function (o) {
14418
+ return Object.prototype.toString.call(o).slice(8, -1);
14419
+ },
14374
14420
 
14375
- switch (type) {
14376
- case 'Object':
14377
- var clone = {};
14421
+ /**
14422
+ * Returns a unique number for the given object. Later calls will still return the same number.
14423
+ *
14424
+ * @param {Object} obj
14425
+ * @returns {number}
14426
+ */
14427
+ objId: function (obj) {
14428
+ if (!obj['__id']) {
14429
+ Object.defineProperty(obj, '__id', { value: ++uniqueId });
14430
+ }
14431
+ return obj['__id'];
14432
+ },
14378
14433
 
14379
- for (var key in o) {
14380
- if (o.hasOwnProperty(key)) {
14381
- clone[key] = _.util.clone(o[key]);
14434
+ /**
14435
+ * Creates a deep clone of the given object.
14436
+ *
14437
+ * The main intended use of this function is to clone language definitions.
14438
+ *
14439
+ * @param {T} o
14440
+ * @param {Record<number, any>} [visited]
14441
+ * @returns {T}
14442
+ * @template T
14443
+ */
14444
+ clone: function deepClone(o, visited) {
14445
+ visited = visited || {};
14446
+
14447
+ var clone; var id;
14448
+ switch (_.util.type(o)) {
14449
+ case 'Object':
14450
+ id = _.util.objId(o);
14451
+ if (visited[id]) {
14452
+ return visited[id];
14382
14453
  }
14383
- }
14454
+ clone = /** @type {Record<string, any>} */ ({});
14455
+ visited[id] = clone;
14384
14456
 
14385
- return clone;
14457
+ for (var key in o) {
14458
+ if (o.hasOwnProperty(key)) {
14459
+ clone[key] = deepClone(o[key], visited);
14460
+ }
14461
+ }
14386
14462
 
14387
- case 'Array':
14388
- // Check for existence for IE8
14389
- return o.map && o.map(function(v) { return _.util.clone(v); });
14390
- }
14463
+ return /** @type {any} */ (clone);
14391
14464
 
14392
- return o;
14393
- }
14394
- },
14465
+ case 'Array':
14466
+ id = _.util.objId(o);
14467
+ if (visited[id]) {
14468
+ return visited[id];
14469
+ }
14470
+ clone = [];
14471
+ visited[id] = clone;
14395
14472
 
14396
- languages: {
14397
- extend: function (id, redef) {
14398
- var lang = _.util.clone(_.languages[id]);
14473
+ (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
14474
+ clone[i] = deepClone(v, visited);
14475
+ });
14399
14476
 
14400
- for (var key in redef) {
14401
- lang[key] = redef[key];
14402
- }
14477
+ return /** @type {any} */ (clone);
14403
14478
 
14404
- return lang;
14405
- },
14406
-
14407
- /**
14408
- * Insert a token before another token in a language literal
14409
- * As this needs to recreate the object (we cannot actually insert before keys in object literals),
14410
- * we cannot just provide an object, we need anobject and a key.
14411
- * @param inside The key (or language id) of the parent
14412
- * @param before The key to insert before. If not provided, the function appends instead.
14413
- * @param insert Object with the key/value pairs to insert
14414
- * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
14415
- */
14416
- insertBefore: function (inside, before, insert, root) {
14417
- root = root || _.languages;
14418
- var grammar = root[inside];
14419
-
14420
- if (arguments.length == 2) {
14421
- insert = arguments[1];
14422
-
14423
- for (var newToken in insert) {
14424
- if (insert.hasOwnProperty(newToken)) {
14425
- grammar[newToken] = insert[newToken];
14426
- }
14479
+ default:
14480
+ return o;
14427
14481
  }
14428
-
14429
- return grammar;
14430
- }
14431
-
14432
- var ret = {};
14433
-
14434
- for (var token in grammar) {
14482
+ },
14435
14483
 
14436
- if (grammar.hasOwnProperty(token)) {
14484
+ /**
14485
+ * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
14486
+ *
14487
+ * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
14488
+ *
14489
+ * @param {Element} element
14490
+ * @returns {string}
14491
+ */
14492
+ getLanguage: function (element) {
14493
+ while (element && !lang.test(element.className)) {
14494
+ element = element.parentElement;
14495
+ }
14496
+ if (element) {
14497
+ return (element.className.match(lang) || [, 'none'])[1].toLowerCase();
14498
+ }
14499
+ return 'none';
14500
+ },
14437
14501
 
14438
- if (token == before) {
14502
+ /**
14503
+ * Returns the script element that is currently executing.
14504
+ *
14505
+ * This does __not__ work for line script element.
14506
+ *
14507
+ * @returns {HTMLScriptElement | null}
14508
+ */
14509
+ currentScript: function () {
14510
+ if (typeof document === 'undefined') {
14511
+ return null;
14512
+ }
14513
+ if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) {
14514
+ return /** @type {any} */ (document.currentScript);
14515
+ }
14439
14516
 
14440
- for (var newToken in insert) {
14517
+ // IE11 workaround
14518
+ // we'll get the src of the current script by parsing IE11's error stack trace
14519
+ // this will not work for inline scripts
14441
14520
 
14442
- if (insert.hasOwnProperty(newToken)) {
14443
- ret[newToken] = insert[newToken];
14521
+ try {
14522
+ throw new Error();
14523
+ } catch (err) {
14524
+ // Get file src url from stack. Specifically works with the format of stack traces in IE.
14525
+ // A stack will look like this:
14526
+ //
14527
+ // Error
14528
+ // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
14529
+ // at Global code (http://localhost/components/prism-core.js:606:1)
14530
+
14531
+ var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1];
14532
+ if (src) {
14533
+ var scripts = document.getElementsByTagName('script');
14534
+ for (var i in scripts) {
14535
+ if (scripts[i].src == src) {
14536
+ return scripts[i];
14444
14537
  }
14445
14538
  }
14446
14539
  }
14540
+ return null;
14541
+ }
14542
+ },
14447
14543
 
14448
- ret[token] = grammar[token];
14544
+ /**
14545
+ * Returns whether a given class is active for `element`.
14546
+ *
14547
+ * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
14548
+ * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
14549
+ * given class is just the given class with a `no-` prefix.
14550
+ *
14551
+ * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
14552
+ * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
14553
+ * ancestors have the given class or the negated version of it, then the default activation will be returned.
14554
+ *
14555
+ * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
14556
+ * version of it, the class is considered active.
14557
+ *
14558
+ * @param {Element} element
14559
+ * @param {string} className
14560
+ * @param {boolean} [defaultActivation=false]
14561
+ * @returns {boolean}
14562
+ */
14563
+ isActive: function (element, className, defaultActivation) {
14564
+ var no = 'no-' + className;
14565
+
14566
+ while (element) {
14567
+ var classList = element.classList;
14568
+ if (classList.contains(className)) {
14569
+ return true;
14570
+ }
14571
+ if (classList.contains(no)) {
14572
+ return false;
14573
+ }
14574
+ element = element.parentElement;
14449
14575
  }
14576
+ return !!defaultActivation;
14450
14577
  }
14451
-
14452
- // Update references in other language definitions
14453
- _.languages.DFS(_.languages, function(key, value) {
14454
- if (value === root[inside] && key != inside) {
14455
- this[key] = ret;
14578
+ },
14579
+
14580
+ /**
14581
+ * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
14582
+ *
14583
+ * @namespace
14584
+ * @memberof Prism
14585
+ * @public
14586
+ */
14587
+ languages: {
14588
+ /**
14589
+ * The grammar for plain, unformatted text.
14590
+ */
14591
+ plain: plainTextGrammar,
14592
+ plaintext: plainTextGrammar,
14593
+ text: plainTextGrammar,
14594
+ txt: plainTextGrammar,
14595
+
14596
+ /**
14597
+ * Creates a deep copy of the language with the given id and appends the given tokens.
14598
+ *
14599
+ * If a token in `redef` also appears in the copied language, then the existing token in the copied language
14600
+ * will be overwritten at its original position.
14601
+ *
14602
+ * ## Best practices
14603
+ *
14604
+ * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
14605
+ * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
14606
+ * understand the language definition because, normally, the order of tokens matters in Prism grammars.
14607
+ *
14608
+ * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
14609
+ * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
14610
+ *
14611
+ * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
14612
+ * @param {Grammar} redef The new tokens to append.
14613
+ * @returns {Grammar} The new language created.
14614
+ * @public
14615
+ * @example
14616
+ * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
14617
+ * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
14618
+ * // at its original position
14619
+ * 'comment': { ... },
14620
+ * // CSS doesn't have a 'color' token, so this token will be appended
14621
+ * 'color': /\b(?:red|green|blue)\b/
14622
+ * });
14623
+ */
14624
+ extend: function (id, redef) {
14625
+ var lang = _.util.clone(_.languages[id]);
14626
+
14627
+ for (var key in redef) {
14628
+ lang[key] = redef[key];
14456
14629
  }
14457
- });
14458
14630
 
14459
- return root[inside] = ret;
14460
- },
14631
+ return lang;
14632
+ },
14461
14633
 
14462
- // Traverse a language definition with Depth First Search
14463
- DFS: function(o, callback, type, visited) {
14464
- visited = visited || {};
14465
- for (var i in o) {
14466
- if (o.hasOwnProperty(i)) {
14467
- callback.call(o, i, o[i], type || i);
14634
+ /**
14635
+ * Inserts tokens _before_ another token in a language definition or any other grammar.
14636
+ *
14637
+ * ## Usage
14638
+ *
14639
+ * This helper method makes it easy to modify existing languages. For example, the CSS language definition
14640
+ * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
14641
+ * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
14642
+ * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
14643
+ * this:
14644
+ *
14645
+ * ```js
14646
+ * Prism.languages.markup.style = {
14647
+ * // token
14648
+ * };
14649
+ * ```
14650
+ *
14651
+ * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
14652
+ * before existing tokens. For the CSS example above, you would use it like this:
14653
+ *
14654
+ * ```js
14655
+ * Prism.languages.insertBefore('markup', 'cdata', {
14656
+ * 'style': {
14657
+ * // token
14658
+ * }
14659
+ * });
14660
+ * ```
14661
+ *
14662
+ * ## Special cases
14663
+ *
14664
+ * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
14665
+ * will be ignored.
14666
+ *
14667
+ * This behavior can be used to insert tokens after `before`:
14668
+ *
14669
+ * ```js
14670
+ * Prism.languages.insertBefore('markup', 'comment', {
14671
+ * 'comment': Prism.languages.markup.comment,
14672
+ * // tokens after 'comment'
14673
+ * });
14674
+ * ```
14675
+ *
14676
+ * ## Limitations
14677
+ *
14678
+ * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
14679
+ * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
14680
+ * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
14681
+ * deleting properties which is necessary to insert at arbitrary positions.
14682
+ *
14683
+ * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
14684
+ * Instead, it will create a new object and replace all references to the target object with the new one. This
14685
+ * can be done without temporarily deleting properties, so the iteration order is well-defined.
14686
+ *
14687
+ * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
14688
+ * you hold the target object in a variable, then the value of the variable will not change.
14689
+ *
14690
+ * ```js
14691
+ * var oldMarkup = Prism.languages.markup;
14692
+ * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
14693
+ *
14694
+ * assert(oldMarkup !== Prism.languages.markup);
14695
+ * assert(newMarkup === Prism.languages.markup);
14696
+ * ```
14697
+ *
14698
+ * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
14699
+ * object to be modified.
14700
+ * @param {string} before The key to insert before.
14701
+ * @param {Grammar} insert An object containing the key-value pairs to be inserted.
14702
+ * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
14703
+ * object to be modified.
14704
+ *
14705
+ * Defaults to `Prism.languages`.
14706
+ * @returns {Grammar} The new grammar object.
14707
+ * @public
14708
+ */
14709
+ insertBefore: function (inside, before, insert, root) {
14710
+ root = root || /** @type {any} */ (_.languages);
14711
+ var grammar = root[inside];
14712
+ /** @type {Grammar} */
14713
+ var ret = {};
14714
+
14715
+ for (var token in grammar) {
14716
+ if (grammar.hasOwnProperty(token)) {
14717
+
14718
+ if (token == before) {
14719
+ for (var newToken in insert) {
14720
+ if (insert.hasOwnProperty(newToken)) {
14721
+ ret[newToken] = insert[newToken];
14722
+ }
14723
+ }
14724
+ }
14468
14725
 
14469
- if (_.util.type(o[i]) === 'Object' && !visited[_.util.objId(o[i])]) {
14470
- visited[_.util.objId(o[i])] = true;
14471
- _.languages.DFS(o[i], callback, null, visited);
14726
+ // Do not insert token which also occur in insert. See #1525
14727
+ if (!insert.hasOwnProperty(token)) {
14728
+ ret[token] = grammar[token];
14729
+ }
14472
14730
  }
14473
- else if (_.util.type(o[i]) === 'Array' && !visited[_.util.objId(o[i])]) {
14474
- visited[_.util.objId(o[i])] = true;
14475
- _.languages.DFS(o[i], callback, i, visited);
14731
+ }
14732
+
14733
+ var old = root[inside];
14734
+ root[inside] = ret;
14735
+
14736
+ // Update references in other language definitions
14737
+ _.languages.DFS(_.languages, function (key, value) {
14738
+ if (value === old && key != inside) {
14739
+ this[key] = ret;
14740
+ }
14741
+ });
14742
+
14743
+ return ret;
14744
+ },
14745
+
14746
+ // Traverse a language definition with Depth First Search
14747
+ DFS: function DFS(o, callback, type, visited) {
14748
+ visited = visited || {};
14749
+
14750
+ var objId = _.util.objId;
14751
+
14752
+ for (var i in o) {
14753
+ if (o.hasOwnProperty(i)) {
14754
+ callback.call(o, i, o[i], type || i);
14755
+
14756
+ var property = o[i];
14757
+ var propertyType = _.util.type(property);
14758
+
14759
+ if (propertyType === 'Object' && !visited[objId(property)]) {
14760
+ visited[objId(property)] = true;
14761
+ DFS(property, callback, null, visited);
14762
+ } else if (propertyType === 'Array' && !visited[objId(property)]) {
14763
+ visited[objId(property)] = true;
14764
+ DFS(property, callback, i, visited);
14765
+ }
14476
14766
  }
14477
14767
  }
14478
14768
  }
14479
- }
14480
- },
14481
- plugins: {},
14482
-
14483
- highlightAll: function(async, callback) {
14484
- var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');
14769
+ },
14485
14770
 
14486
- for (var i=0, element; element = elements[i++];) {
14487
- _.highlightElement(element, async === true, callback);
14488
- }
14489
- },
14771
+ plugins: {},
14490
14772
 
14491
- highlightElement: function(element, async, callback) {
14492
- // Find language
14493
- var language, grammar, parent = element;
14773
+ /**
14774
+ * This is the most high-level function in Prism’s API.
14775
+ * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
14776
+ * each one of them.
14777
+ *
14778
+ * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
14779
+ *
14780
+ * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
14781
+ * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
14782
+ * @memberof Prism
14783
+ * @public
14784
+ */
14785
+ highlightAll: function (async, callback) {
14786
+ _.highlightAllUnder(document, async, callback);
14787
+ },
14494
14788
 
14495
- while (parent && !lang.test(parent.className)) {
14496
- parent = parent.parentNode;
14497
- }
14789
+ /**
14790
+ * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
14791
+ * {@link Prism.highlightElement} on each one of them.
14792
+ *
14793
+ * The following hooks will be run:
14794
+ * 1. `before-highlightall`
14795
+ * 2. `before-all-elements-highlight`
14796
+ * 3. All hooks of {@link Prism.highlightElement} for each element.
14797
+ *
14798
+ * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
14799
+ * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
14800
+ * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
14801
+ * @memberof Prism
14802
+ * @public
14803
+ */
14804
+ highlightAllUnder: function (container, async, callback) {
14805
+ var env = {
14806
+ callback: callback,
14807
+ container: container,
14808
+ selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
14809
+ };
14498
14810
 
14499
- if (parent) {
14500
- language = (parent.className.match(lang) || [,''])[1];
14501
- grammar = _.languages[language];
14502
- }
14811
+ _.hooks.run('before-highlightall', env);
14503
14812
 
14504
- // Set language on the element, if not present
14505
- element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14813
+ env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
14506
14814
 
14507
- // Set language on the parent, for styling
14508
- parent = element.parentNode;
14815
+ _.hooks.run('before-all-elements-highlight', env);
14509
14816
 
14510
- if (/pre/i.test(parent.nodeName)) {
14511
- parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14512
- }
14817
+ for (var i = 0, element; (element = env.elements[i++]);) {
14818
+ _.highlightElement(element, async === true, env.callback);
14819
+ }
14820
+ },
14513
14821
 
14514
- var code = element.textContent;
14822
+ /**
14823
+ * Highlights the code inside a single element.
14824
+ *
14825
+ * The following hooks will be run:
14826
+ * 1. `before-sanity-check`
14827
+ * 2. `before-highlight`
14828
+ * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
14829
+ * 4. `before-insert`
14830
+ * 5. `after-highlight`
14831
+ * 6. `complete`
14832
+ *
14833
+ * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
14834
+ * the element's language.
14835
+ *
14836
+ * @param {Element} element The element containing the code.
14837
+ * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
14838
+ * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
14839
+ * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
14840
+ * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
14841
+ *
14842
+ * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
14843
+ * asynchronous highlighting to work. You can build your own bundle on the
14844
+ * [Download page](https://prismjs.com/download.html).
14845
+ * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
14846
+ * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
14847
+ * @memberof Prism
14848
+ * @public
14849
+ */
14850
+ highlightElement: function (element, async, callback) {
14851
+ // Find language
14852
+ var language = _.util.getLanguage(element);
14853
+ var grammar = _.languages[language];
14515
14854
 
14516
- var env = {
14517
- element: element,
14518
- language: language,
14519
- grammar: grammar,
14520
- code: code
14521
- };
14855
+ // Set language on the element, if not present
14856
+ element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14522
14857
 
14523
- if (!code || !grammar) {
14524
- _.hooks.run('complete', env);
14525
- return;
14526
- }
14858
+ // Set language on the parent, for styling
14859
+ var parent = element.parentElement;
14860
+ if (parent && parent.nodeName.toLowerCase() === 'pre') {
14861
+ parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14862
+ }
14527
14863
 
14528
- _.hooks.run('before-highlight', env);
14864
+ var code = element.textContent;
14529
14865
 
14530
- if (async && _self.Worker) {
14531
- var worker = new Worker(_.filename);
14866
+ var env = {
14867
+ element: element,
14868
+ language: language,
14869
+ grammar: grammar,
14870
+ code: code
14871
+ };
14532
14872
 
14533
- worker.onmessage = function(evt) {
14534
- env.highlightedCode = evt.data;
14873
+ function insertHighlightedCode(highlightedCode) {
14874
+ env.highlightedCode = highlightedCode;
14535
14875
 
14536
14876
  _.hooks.run('before-insert', env);
14537
14877
 
14538
14878
  env.element.innerHTML = env.highlightedCode;
14539
14879
 
14540
- callback && callback.call(env.element);
14541
14880
  _.hooks.run('after-highlight', env);
14542
14881
  _.hooks.run('complete', env);
14882
+ callback && callback.call(env.element);
14883
+ }
14884
+
14885
+ _.hooks.run('before-sanity-check', env);
14886
+
14887
+ // plugins may change/add the parent/element
14888
+ parent = env.element.parentElement;
14889
+ if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
14890
+ parent.setAttribute('tabindex', '0');
14891
+ }
14892
+
14893
+ if (!env.code) {
14894
+ _.hooks.run('complete', env);
14895
+ callback && callback.call(env.element);
14896
+ return;
14897
+ }
14898
+
14899
+ _.hooks.run('before-highlight', env);
14900
+
14901
+ if (!env.grammar) {
14902
+ insertHighlightedCode(_.util.encode(env.code));
14903
+ return;
14904
+ }
14905
+
14906
+ if (async && _self.Worker) {
14907
+ var worker = new Worker(_.filename);
14908
+
14909
+ worker.onmessage = function (evt) {
14910
+ insertHighlightedCode(evt.data);
14911
+ };
14912
+
14913
+ worker.postMessage(JSON.stringify({
14914
+ language: env.language,
14915
+ code: env.code,
14916
+ immediateClose: true
14917
+ }));
14918
+ } else {
14919
+ insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
14920
+ }
14921
+ },
14922
+
14923
+ /**
14924
+ * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
14925
+ * and the language definitions to use, and returns a string with the HTML produced.
14926
+ *
14927
+ * The following hooks will be run:
14928
+ * 1. `before-tokenize`
14929
+ * 2. `after-tokenize`
14930
+ * 3. `wrap`: On each {@link Token}.
14931
+ *
14932
+ * @param {string} text A string with the code to be highlighted.
14933
+ * @param {Grammar} grammar An object containing the tokens to use.
14934
+ *
14935
+ * Usually a language definition like `Prism.languages.markup`.
14936
+ * @param {string} language The name of the language definition passed to `grammar`.
14937
+ * @returns {string} The highlighted HTML.
14938
+ * @memberof Prism
14939
+ * @public
14940
+ * @example
14941
+ * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
14942
+ */
14943
+ highlight: function (text, grammar, language) {
14944
+ var env = {
14945
+ code: text,
14946
+ grammar: grammar,
14947
+ language: language
14543
14948
  };
14949
+ _.hooks.run('before-tokenize', env);
14950
+ env.tokens = _.tokenize(env.code, env.grammar);
14951
+ _.hooks.run('after-tokenize', env);
14952
+ return Token.stringify(_.util.encode(env.tokens), env.language);
14953
+ },
14544
14954
 
14545
- worker.postMessage(JSON.stringify({
14546
- language: env.language,
14547
- code: env.code,
14548
- immediateClose: true
14549
- }));
14550
- }
14551
- else {
14552
- env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
14955
+ /**
14956
+ * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
14957
+ * and the language definitions to use, and returns an array with the tokenized code.
14958
+ *
14959
+ * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
14960
+ *
14961
+ * This method could be useful in other contexts as well, as a very crude parser.
14962
+ *
14963
+ * @param {string} text A string with the code to be highlighted.
14964
+ * @param {Grammar} grammar An object containing the tokens to use.
14965
+ *
14966
+ * Usually a language definition like `Prism.languages.markup`.
14967
+ * @returns {TokenStream} An array of strings and tokens, a token stream.
14968
+ * @memberof Prism
14969
+ * @public
14970
+ * @example
14971
+ * let code = `var foo = 0;`;
14972
+ * let tokens = Prism.tokenize(code, Prism.languages.javascript);
14973
+ * tokens.forEach(token => {
14974
+ * if (token instanceof Prism.Token && token.type === 'number') {
14975
+ * console.log(`Found numeric literal: ${token.content}`);
14976
+ * }
14977
+ * });
14978
+ */
14979
+ tokenize: function (text, grammar) {
14980
+ var rest = grammar.rest;
14981
+ if (rest) {
14982
+ for (var token in rest) {
14983
+ grammar[token] = rest[token];
14984
+ }
14553
14985
 
14554
- _.hooks.run('before-insert', env);
14986
+ delete grammar.rest;
14987
+ }
14555
14988
 
14556
- env.element.innerHTML = env.highlightedCode;
14989
+ var tokenList = new LinkedList();
14990
+ addAfter(tokenList, tokenList.head, text);
14557
14991
 
14558
- callback && callback.call(element);
14992
+ matchGrammar(text, tokenList, grammar, tokenList.head, 0);
14559
14993
 
14560
- _.hooks.run('after-highlight', env);
14561
- _.hooks.run('complete', env);
14562
- }
14563
- },
14994
+ return toArray(tokenList);
14995
+ },
14996
+
14997
+ /**
14998
+ * @namespace
14999
+ * @memberof Prism
15000
+ * @public
15001
+ */
15002
+ hooks: {
15003
+ all: {},
15004
+
15005
+ /**
15006
+ * Adds the given callback to the list of callbacks for the given hook.
15007
+ *
15008
+ * The callback will be invoked when the hook it is registered for is run.
15009
+ * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
15010
+ *
15011
+ * One callback function can be registered to multiple hooks and the same hook multiple times.
15012
+ *
15013
+ * @param {string} name The name of the hook.
15014
+ * @param {HookCallback} callback The callback function which is given environment variables.
15015
+ * @public
15016
+ */
15017
+ add: function (name, callback) {
15018
+ var hooks = _.hooks.all;
15019
+
15020
+ hooks[name] = hooks[name] || [];
15021
+
15022
+ hooks[name].push(callback);
15023
+ },
15024
+
15025
+ /**
15026
+ * Runs a hook invoking all registered callbacks with the given environment variables.
15027
+ *
15028
+ * Callbacks will be invoked synchronously and in the order in which they were registered.
15029
+ *
15030
+ * @param {string} name The name of the hook.
15031
+ * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
15032
+ * @public
15033
+ */
15034
+ run: function (name, env) {
15035
+ var callbacks = _.hooks.all[name];
15036
+
15037
+ if (!callbacks || !callbacks.length) {
15038
+ return;
15039
+ }
15040
+
15041
+ for (var i = 0, callback; (callback = callbacks[i++]);) {
15042
+ callback(env);
15043
+ }
15044
+ }
15045
+ },
15046
+
15047
+ Token: Token
15048
+ };
15049
+ _self.Prism = _;
14564
15050
 
14565
- highlight: function (text, grammar, language) {
14566
- var tokens = _.tokenize(text, grammar);
14567
- return Token.stringify(_.util.encode(tokens), language);
14568
- },
14569
15051
 
14570
- tokenize: function(text, grammar, language) {
14571
- var Token = _.Token;
15052
+ // Typescript note:
15053
+ // The following can be used to import the Token type in JSDoc:
15054
+ //
15055
+ // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
15056
+
15057
+ /**
15058
+ * Creates a new token.
15059
+ *
15060
+ * @param {string} type See {@link Token#type type}
15061
+ * @param {string | TokenStream} content See {@link Token#content content}
15062
+ * @param {string|string[]} [alias] The alias(es) of the token.
15063
+ * @param {string} [matchedStr=""] A copy of the full string this token was created from.
15064
+ * @class
15065
+ * @global
15066
+ * @public
15067
+ */
15068
+ function Token(type, content, alias, matchedStr) {
15069
+ /**
15070
+ * The type of the token.
15071
+ *
15072
+ * This is usually the key of a pattern in a {@link Grammar}.
15073
+ *
15074
+ * @type {string}
15075
+ * @see GrammarToken
15076
+ * @public
15077
+ */
15078
+ this.type = type;
15079
+ /**
15080
+ * The strings or tokens contained by this token.
15081
+ *
15082
+ * This will be a token stream if the pattern matched also defined an `inside` grammar.
15083
+ *
15084
+ * @type {string | TokenStream}
15085
+ * @public
15086
+ */
15087
+ this.content = content;
15088
+ /**
15089
+ * The alias(es) of the token.
15090
+ *
15091
+ * @type {string|string[]}
15092
+ * @see GrammarToken
15093
+ * @public
15094
+ */
15095
+ this.alias = alias;
15096
+ // Copy of the full string this token was created from
15097
+ this.length = (matchedStr || '').length | 0;
15098
+ }
15099
+
15100
+ /**
15101
+ * A token stream is an array of strings and {@link Token Token} objects.
15102
+ *
15103
+ * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
15104
+ * them.
15105
+ *
15106
+ * 1. No adjacent strings.
15107
+ * 2. No empty strings.
15108
+ *
15109
+ * The only exception here is the token stream that only contains the empty string and nothing else.
15110
+ *
15111
+ * @typedef {Array<string | Token>} TokenStream
15112
+ * @global
15113
+ * @public
15114
+ */
14572
15115
 
14573
- var strarr = [text];
15116
+ /**
15117
+ * Converts the given token or token stream to an HTML representation.
15118
+ *
15119
+ * The following hooks will be run:
15120
+ * 1. `wrap`: On each {@link Token}.
15121
+ *
15122
+ * @param {string | Token | TokenStream} o The token or token stream to be converted.
15123
+ * @param {string} language The name of current language.
15124
+ * @returns {string} The HTML representation of the token or token stream.
15125
+ * @memberof Token
15126
+ * @static
15127
+ */
15128
+ Token.stringify = function stringify(o, language) {
15129
+ if (typeof o == 'string') {
15130
+ return o;
15131
+ }
15132
+ if (Array.isArray(o)) {
15133
+ var s = '';
15134
+ o.forEach(function (e) {
15135
+ s += stringify(e, language);
15136
+ });
15137
+ return s;
15138
+ }
14574
15139
 
14575
- var rest = grammar.rest;
15140
+ var env = {
15141
+ type: o.type,
15142
+ content: stringify(o.content, language),
15143
+ tag: 'span',
15144
+ classes: ['token', o.type],
15145
+ attributes: {},
15146
+ language: language
15147
+ };
14576
15148
 
14577
- if (rest) {
14578
- for (var token in rest) {
14579
- grammar[token] = rest[token];
15149
+ var aliases = o.alias;
15150
+ if (aliases) {
15151
+ if (Array.isArray(aliases)) {
15152
+ Array.prototype.push.apply(env.classes, aliases);
15153
+ } else {
15154
+ env.classes.push(aliases);
14580
15155
  }
15156
+ }
15157
+
15158
+ _.hooks.run('wrap', env);
15159
+
15160
+ var attributes = '';
15161
+ for (var name in env.attributes) {
15162
+ attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
15163
+ }
15164
+
15165
+ return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
15166
+ };
14581
15167
 
14582
- delete grammar.rest;
15168
+ /**
15169
+ * @param {RegExp} pattern
15170
+ * @param {number} pos
15171
+ * @param {string} text
15172
+ * @param {boolean} lookbehind
15173
+ * @returns {RegExpExecArray | null}
15174
+ */
15175
+ function matchPattern(pattern, pos, text, lookbehind) {
15176
+ pattern.lastIndex = pos;
15177
+ var match = pattern.exec(text);
15178
+ if (match && lookbehind && match[1]) {
15179
+ // change the match to remove the text matched by the Prism lookbehind group
15180
+ var lookbehindLength = match[1].length;
15181
+ match.index += lookbehindLength;
15182
+ match[0] = match[0].slice(lookbehindLength);
14583
15183
  }
15184
+ return match;
15185
+ }
14584
15186
 
14585
- tokenloop: for (var token in grammar) {
14586
- if(!grammar.hasOwnProperty(token) || !grammar[token]) {
15187
+ /**
15188
+ * @param {string} text
15189
+ * @param {LinkedList<string | Token>} tokenList
15190
+ * @param {any} grammar
15191
+ * @param {LinkedListNode<string | Token>} startNode
15192
+ * @param {number} startPos
15193
+ * @param {RematchOptions} [rematch]
15194
+ * @returns {void}
15195
+ * @private
15196
+ *
15197
+ * @typedef RematchOptions
15198
+ * @property {string} cause
15199
+ * @property {number} reach
15200
+ */
15201
+ function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
15202
+ for (var token in grammar) {
15203
+ if (!grammar.hasOwnProperty(token) || !grammar[token]) {
14587
15204
  continue;
14588
15205
  }
14589
15206
 
14590
15207
  var patterns = grammar[token];
14591
- patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
15208
+ patterns = Array.isArray(patterns) ? patterns : [patterns];
14592
15209
 
14593
15210
  for (var j = 0; j < patterns.length; ++j) {
14594
- var pattern = patterns[j],
14595
- inside = pattern.inside,
14596
- lookbehind = !!pattern.lookbehind,
14597
- lookbehindLength = 0,
14598
- alias = pattern.alias;
15211
+ if (rematch && rematch.cause == token + ',' + j) {
15212
+ return;
15213
+ }
15214
+
15215
+ var patternObj = patterns[j];
15216
+ var inside = patternObj.inside;
15217
+ var lookbehind = !!patternObj.lookbehind;
15218
+ var greedy = !!patternObj.greedy;
15219
+ var alias = patternObj.alias;
15220
+
15221
+ if (greedy && !patternObj.pattern.global) {
15222
+ // Without the global flag, lastIndex won't work
15223
+ var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
15224
+ patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
15225
+ }
14599
15226
 
14600
- pattern = pattern.pattern || pattern;
15227
+ /** @type {RegExp} */
15228
+ var pattern = patternObj.pattern || patternObj;
14601
15229
 
14602
- for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop
15230
+ for ( // iterate the token list and keep track of the current token/string position
15231
+ var currentNode = startNode.next, pos = startPos;
15232
+ currentNode !== tokenList.tail;
15233
+ pos += currentNode.value.length, currentNode = currentNode.next
15234
+ ) {
15235
+
15236
+ if (rematch && pos >= rematch.reach) {
15237
+ break;
15238
+ }
14603
15239
 
14604
- var str = strarr[i];
15240
+ var str = currentNode.value;
14605
15241
 
14606
- if (strarr.length > text.length) {
15242
+ if (tokenList.length > text.length) {
14607
15243
  // Something went terribly wrong, ABORT, ABORT!
14608
- break tokenloop;
15244
+ return;
14609
15245
  }
14610
15246
 
14611
15247
  if (str instanceof Token) {
14612
15248
  continue;
14613
15249
  }
14614
15250
 
14615
- pattern.lastIndex = 0;
14616
-
14617
- var match = pattern.exec(str);
15251
+ var removeCount = 1; // this is the to parameter of removeBetween
15252
+ var match;
14618
15253
 
14619
- if (match) {
14620
- if(lookbehind) {
14621
- lookbehindLength = match[1].length;
15254
+ if (greedy) {
15255
+ match = matchPattern(pattern, pos, text, lookbehind);
15256
+ if (!match) {
15257
+ break;
14622
15258
  }
14623
15259
 
14624
- var from = match.index - 1 + lookbehindLength,
14625
- match = match[0].slice(lookbehindLength),
14626
- len = match.length,
14627
- to = from + len,
14628
- before = str.slice(0, from + 1),
14629
- after = str.slice(to + 1);
14630
-
14631
- var args = [i, 1];
15260
+ var from = match.index;
15261
+ var to = match.index + match[0].length;
15262
+ var p = pos;
14632
15263
 
14633
- if (before) {
14634
- args.push(before);
15264
+ // find the node that contains the match
15265
+ p += currentNode.value.length;
15266
+ while (from >= p) {
15267
+ currentNode = currentNode.next;
15268
+ p += currentNode.value.length;
14635
15269
  }
15270
+ // adjust pos (and p)
15271
+ p -= currentNode.value.length;
15272
+ pos = p;
14636
15273
 
14637
- var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias);
15274
+ // the current node is a Token, then the match starts inside another Token, which is invalid
15275
+ if (currentNode.value instanceof Token) {
15276
+ continue;
15277
+ }
14638
15278
 
14639
- args.push(wrapped);
15279
+ // find the last node which is affected by this match
15280
+ for (
15281
+ var k = currentNode;
15282
+ k !== tokenList.tail && (p < to || typeof k.value === 'string');
15283
+ k = k.next
15284
+ ) {
15285
+ removeCount++;
15286
+ p += k.value.length;
15287
+ }
15288
+ removeCount--;
14640
15289
 
14641
- if (after) {
14642
- args.push(after);
15290
+ // replace with the new match
15291
+ str = text.slice(pos, p);
15292
+ match.index -= pos;
15293
+ } else {
15294
+ match = matchPattern(pattern, 0, str, lookbehind);
15295
+ if (!match) {
15296
+ continue;
14643
15297
  }
15298
+ }
15299
+
15300
+ // eslint-disable-next-line no-redeclare
15301
+ var from = match.index;
15302
+ var matchStr = match[0];
15303
+ var before = str.slice(0, from);
15304
+ var after = str.slice(from + matchStr.length);
14644
15305
 
14645
- Array.prototype.splice.apply(strarr, args);
15306
+ var reach = pos + str.length;
15307
+ if (rematch && reach > rematch.reach) {
15308
+ rematch.reach = reach;
14646
15309
  }
14647
- }
14648
- }
14649
- }
14650
15310
 
14651
- return strarr;
14652
- },
15311
+ var removeFrom = currentNode.prev;
14653
15312
 
14654
- hooks: {
14655
- all: {},
15313
+ if (before) {
15314
+ removeFrom = addAfter(tokenList, removeFrom, before);
15315
+ pos += before.length;
15316
+ }
14656
15317
 
14657
- add: function (name, callback) {
14658
- var hooks = _.hooks.all;
15318
+ removeRange(tokenList, removeFrom, removeCount);
14659
15319
 
14660
- hooks[name] = hooks[name] || [];
15320
+ var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
15321
+ currentNode = addAfter(tokenList, removeFrom, wrapped);
14661
15322
 
14662
- hooks[name].push(callback);
14663
- },
15323
+ if (after) {
15324
+ addAfter(tokenList, currentNode, after);
15325
+ }
14664
15326
 
14665
- run: function (name, env) {
14666
- var callbacks = _.hooks.all[name];
15327
+ if (removeCount > 1) {
15328
+ // at least one Token object was removed, so we have to do some rematching
15329
+ // this can only happen if the current pattern is greedy
14667
15330
 
14668
- if (!callbacks || !callbacks.length) {
14669
- return;
14670
- }
15331
+ /** @type {RematchOptions} */
15332
+ var nestedRematch = {
15333
+ cause: token + ',' + j,
15334
+ reach: reach
15335
+ };
15336
+ matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
14671
15337
 
14672
- for (var i=0, callback; callback = callbacks[i++];) {
14673
- callback(env);
15338
+ // the reach might have been extended because of the rematching
15339
+ if (rematch && nestedRematch.reach > rematch.reach) {
15340
+ rematch.reach = nestedRematch.reach;
15341
+ }
15342
+ }
15343
+ }
14674
15344
  }
14675
15345
  }
14676
15346
  }
14677
- };
14678
15347
 
14679
- var Token = _.Token = function(type, content, alias) {
14680
- this.type = type;
14681
- this.content = content;
14682
- this.alias = alias;
14683
- };
15348
+ /**
15349
+ * @typedef LinkedListNode
15350
+ * @property {T} value
15351
+ * @property {LinkedListNode<T> | null} prev The previous node.
15352
+ * @property {LinkedListNode<T> | null} next The next node.
15353
+ * @template T
15354
+ * @private
15355
+ */
14684
15356
 
14685
- Token.stringify = function(o, language, parent) {
14686
- if (typeof o == 'string') {
14687
- return o;
14688
- }
15357
+ /**
15358
+ * @template T
15359
+ * @private
15360
+ */
15361
+ function LinkedList() {
15362
+ /** @type {LinkedListNode<T>} */
15363
+ var head = { value: null, prev: null, next: null };
15364
+ /** @type {LinkedListNode<T>} */
15365
+ var tail = { value: null, prev: head, next: null };
15366
+ head.next = tail;
14689
15367
 
14690
- if (_.util.type(o) === 'Array') {
14691
- return o.map(function(element) {
14692
- return Token.stringify(element, language, o);
14693
- }).join('');
15368
+ /** @type {LinkedListNode<T>} */
15369
+ this.head = head;
15370
+ /** @type {LinkedListNode<T>} */
15371
+ this.tail = tail;
15372
+ this.length = 0;
14694
15373
  }
14695
15374
 
14696
- var env = {
14697
- type: o.type,
14698
- content: Token.stringify(o.content, language, parent),
14699
- tag: 'span',
14700
- classes: ['token', o.type],
14701
- attributes: {},
14702
- language: language,
14703
- parent: parent
14704
- };
15375
+ /**
15376
+ * Adds a new node with the given value to the list.
15377
+ *
15378
+ * @param {LinkedList<T>} list
15379
+ * @param {LinkedListNode<T>} node
15380
+ * @param {T} value
15381
+ * @returns {LinkedListNode<T>} The added node.
15382
+ * @template T
15383
+ */
15384
+ function addAfter(list, node, value) {
15385
+ // assumes that node != list.tail && values.length >= 0
15386
+ var next = node.next;
14705
15387
 
14706
- if (env.type == 'comment') {
14707
- env.attributes['spellcheck'] = 'true';
14708
- }
15388
+ var newNode = { value: value, prev: node, next: next };
15389
+ node.next = newNode;
15390
+ next.prev = newNode;
15391
+ list.length++;
14709
15392
 
14710
- if (o.alias) {
14711
- var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
14712
- Array.prototype.push.apply(env.classes, aliases);
15393
+ return newNode;
15394
+ }
15395
+ /**
15396
+ * Removes `count` nodes after the given node. The given node will not be removed.
15397
+ *
15398
+ * @param {LinkedList<T>} list
15399
+ * @param {LinkedListNode<T>} node
15400
+ * @param {number} count
15401
+ * @template T
15402
+ */
15403
+ function removeRange(list, node, count) {
15404
+ var next = node.next;
15405
+ for (var i = 0; i < count && next !== list.tail; i++) {
15406
+ next = next.next;
15407
+ }
15408
+ node.next = next;
15409
+ next.prev = node;
15410
+ list.length -= i;
15411
+ }
15412
+ /**
15413
+ * @param {LinkedList<T>} list
15414
+ * @returns {T[]}
15415
+ * @template T
15416
+ */
15417
+ function toArray(list) {
15418
+ var array = [];
15419
+ var node = list.head.next;
15420
+ while (node !== list.tail) {
15421
+ array.push(node.value);
15422
+ node = node.next;
15423
+ }
15424
+ return array;
14713
15425
  }
14714
15426
 
14715
- _.hooks.run('wrap', env);
14716
-
14717
- var attributes = '';
14718
15427
 
14719
- for (var name in env.attributes) {
14720
- attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"';
14721
- }
15428
+ if (!_self.document) {
15429
+ if (!_self.addEventListener) {
15430
+ // in Node.js
15431
+ return _;
15432
+ }
14722
15433
 
14723
- return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>';
15434
+ if (!_.disableWorkerMessageHandler) {
15435
+ // In worker
15436
+ _self.addEventListener('message', function (evt) {
15437
+ var message = JSON.parse(evt.data);
15438
+ var lang = message.language;
15439
+ var code = message.code;
15440
+ var immediateClose = message.immediateClose;
14724
15441
 
14725
- };
15442
+ _self.postMessage(_.highlight(code, _.languages[lang], lang));
15443
+ if (immediateClose) {
15444
+ _self.close();
15445
+ }
15446
+ }, false);
15447
+ }
14726
15448
 
14727
- if (!_self.document) {
14728
- if (!_self.addEventListener) {
14729
- // in Node.js
14730
- return _self.Prism;
15449
+ return _;
14731
15450
  }
14732
- // In worker
14733
- _self.addEventListener('message', function(evt) {
14734
- var message = JSON.parse(evt.data),
14735
- lang = message.language,
14736
- code = message.code,
14737
- immediateClose = message.immediateClose;
14738
15451
 
14739
- _self.postMessage(_.highlight(code, _.languages[lang], lang));
14740
- if (immediateClose) {
14741
- _self.close();
14742
- }
14743
- }, false);
15452
+ // Get current script and highlight
15453
+ var script = _.util.currentScript();
14744
15454
 
14745
- return _self.Prism;
14746
- }
15455
+ if (script) {
15456
+ _.filename = script.src;
14747
15457
 
14748
- //Get current script and highlight
14749
- var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
15458
+ if (script.hasAttribute('data-manual')) {
15459
+ _.manual = true;
15460
+ }
15461
+ }
14750
15462
 
14751
- if (script) {
14752
- _.filename = script.src;
15463
+ function highlightAutomaticallyCallback() {
15464
+ if (!_.manual) {
15465
+ _.highlightAll();
15466
+ }
15467
+ }
14753
15468
 
14754
- if (document.addEventListener && !script.hasAttribute('data-manual')) {
14755
- document.addEventListener('DOMContentLoaded', _.highlightAll);
15469
+ if (!_.manual) {
15470
+ // If the document state is "loading", then we'll use DOMContentLoaded.
15471
+ // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
15472
+ // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
15473
+ // might take longer one animation frame to execute which can create a race condition where only some plugins have
15474
+ // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
15475
+ // See https://github.com/PrismJS/prism/issues/2102
15476
+ var readyState = document.readyState;
15477
+ if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
15478
+ document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
15479
+ } else {
15480
+ if (window.requestAnimationFrame) {
15481
+ window.requestAnimationFrame(highlightAutomaticallyCallback);
15482
+ } else {
15483
+ window.setTimeout(highlightAutomaticallyCallback, 16);
15484
+ }
15485
+ }
14756
15486
  }
14757
- }
14758
15487
 
14759
- return _self.Prism;
15488
+ return _;
14760
15489
 
14761
- })();
15490
+ }(_self));
14762
15491
 
14763
15492
  if (typeof module !== 'undefined' && module.exports) {
14764
15493
  module.exports = Prism;
@@ -14769,30 +15498,106 @@ if (typeof global !== 'undefined') {
14769
15498
  global.Prism = Prism;
14770
15499
  }
14771
15500
 
15501
+ // some additional documentation/types
15502
+
15503
+ /**
15504
+ * The expansion of a simple `RegExp` literal to support additional properties.
15505
+ *
15506
+ * @typedef GrammarToken
15507
+ * @property {RegExp} pattern The regular expression of the token.
15508
+ * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
15509
+ * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
15510
+ * @property {boolean} [greedy=false] Whether the token is greedy.
15511
+ * @property {string|string[]} [alias] An optional alias or list of aliases.
15512
+ * @property {Grammar} [inside] The nested grammar of this token.
15513
+ *
15514
+ * The `inside` grammar will be used to tokenize the text value of each token of this kind.
15515
+ *
15516
+ * This can be used to make nested and even recursive language definitions.
15517
+ *
15518
+ * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
15519
+ * each another.
15520
+ * @global
15521
+ * @public
15522
+ */
15523
+
15524
+ /**
15525
+ * @typedef Grammar
15526
+ * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
15527
+ * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
15528
+ * @global
15529
+ * @public
15530
+ */
15531
+
15532
+ /**
15533
+ * A function which will invoked after an element was successfully highlighted.
15534
+ *
15535
+ * @callback HighlightCallback
15536
+ * @param {Element} element The element successfully highlighted.
15537
+ * @returns {void}
15538
+ * @global
15539
+ * @public
15540
+ */
15541
+
15542
+ /**
15543
+ * @callback HookCallback
15544
+ * @param {Object<string, any>} env The environment variables of the hook.
15545
+ * @returns {void}
15546
+ * @global
15547
+ * @public
15548
+ */
15549
+
14772
15550
 
14773
15551
  /* **********************************************
14774
15552
  Begin prism-markup.js
14775
15553
  ********************************************** */
14776
15554
 
14777
15555
  Prism.languages.markup = {
14778
- 'comment': /<!--[\w\W]*?-->/,
14779
- 'prolog': /<\?[\w\W]+?\?>/,
14780
- 'doctype': /<!DOCTYPE[\w\W]+?>/,
14781
- 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i,
15556
+ 'comment': /<!--[\s\S]*?-->/,
15557
+ 'prolog': /<\?[\s\S]+?\?>/,
15558
+ 'doctype': {
15559
+ // https://www.w3.org/TR/xml/#NT-doctypedecl
15560
+ pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
15561
+ greedy: true,
15562
+ inside: {
15563
+ 'internal-subset': {
15564
+ pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
15565
+ lookbehind: true,
15566
+ greedy: true,
15567
+ inside: null // see below
15568
+ },
15569
+ 'string': {
15570
+ pattern: /"[^"]*"|'[^']*'/,
15571
+ greedy: true
15572
+ },
15573
+ 'punctuation': /^<!|>$|[[\]]/,
15574
+ 'doctype-tag': /^DOCTYPE/,
15575
+ 'name': /[^\s<>'"]+/
15576
+ }
15577
+ },
15578
+ 'cdata': /<!\[CDATA\[[\s\S]*?\]\]>/i,
14782
15579
  'tag': {
14783
- pattern: /<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,
15580
+ pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
15581
+ greedy: true,
14784
15582
  inside: {
14785
15583
  'tag': {
14786
- pattern: /^<\/?[^\s>\/]+/i,
15584
+ pattern: /^<\/?[^\s>\/]+/,
14787
15585
  inside: {
14788
15586
  'punctuation': /^<\/?/,
14789
15587
  'namespace': /^[^\s>\/:]+:/
14790
15588
  }
14791
15589
  },
15590
+ 'special-attr': [],
14792
15591
  'attr-value': {
14793
- pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
15592
+ pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
14794
15593
  inside: {
14795
- 'punctuation': /[=>"']/
15594
+ 'punctuation': [
15595
+ {
15596
+ pattern: /^=/,
15597
+ alias: 'attr-equals'
15598
+ },
15599
+ /"|'/
15600
+ ]
14796
15601
  }
14797
15602
  },
14798
15603
  'punctuation': /\/?>/,
@@ -14805,75 +15610,193 @@ Prism.languages.markup = {
14805
15610
 
14806
15611
  }
14807
15612
  },
14808
- 'entity': /&#?[\da-z]{1,8};/i
15613
+ 'entity': [
15614
+ {
15615
+ pattern: /&[\da-z]{1,8};/i,
15616
+ alias: 'named-entity'
15617
+ },
15618
+ /&#x?[\da-f]{1,8};/i
15619
+ ]
14809
15620
  };
14810
15621
 
15622
+ Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
15623
+ Prism.languages.markup['entity'];
15624
+ Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
15625
+
14811
15626
  // Plugin to make entity title show the real entity, idea by Roman Komarov
14812
- Prism.hooks.add('wrap', function(env) {
15627
+ Prism.hooks.add('wrap', function (env) {
14813
15628
 
14814
15629
  if (env.type === 'entity') {
14815
15630
  env.attributes['title'] = env.content.replace(/&amp;/, '&');
14816
15631
  }
14817
15632
  });
14818
15633
 
14819
- Prism.languages.xml = Prism.languages.markup;
15634
+ Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
15635
+ /**
15636
+ * Adds an inlined language to markup.
15637
+ *
15638
+ * An example of an inlined language is CSS with `<style>` tags.
15639
+ *
15640
+ * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
15641
+ * case insensitive.
15642
+ * @param {string} lang The language key.
15643
+ * @example
15644
+ * addInlined('style', 'css');
15645
+ */
15646
+ value: function addInlined(tagName, lang) {
15647
+ var includedCdataInside = {};
15648
+ includedCdataInside['language-' + lang] = {
15649
+ pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
15650
+ lookbehind: true,
15651
+ inside: Prism.languages[lang]
15652
+ };
15653
+ includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
15654
+
15655
+ var inside = {
15656
+ 'included-cdata': {
15657
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
15658
+ inside: includedCdataInside
15659
+ }
15660
+ };
15661
+ inside['language-' + lang] = {
15662
+ pattern: /[\s\S]+/,
15663
+ inside: Prism.languages[lang]
15664
+ };
15665
+
15666
+ var def = {};
15667
+ def[tagName] = {
15668
+ pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
15669
+ lookbehind: true,
15670
+ greedy: true,
15671
+ inside: inside
15672
+ };
15673
+
15674
+ Prism.languages.insertBefore('markup', 'cdata', def);
15675
+ }
15676
+ });
15677
+ Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
15678
+ /**
15679
+ * Adds an pattern to highlight languages embedded in HTML attributes.
15680
+ *
15681
+ * An example of an inlined language is CSS with `style` attributes.
15682
+ *
15683
+ * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
15684
+ * case insensitive.
15685
+ * @param {string} lang The language key.
15686
+ * @example
15687
+ * addAttribute('style', 'css');
15688
+ */
15689
+ value: function (attrName, lang) {
15690
+ Prism.languages.markup.tag.inside['special-attr'].push({
15691
+ pattern: RegExp(
15692
+ /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
15693
+ 'i'
15694
+ ),
15695
+ lookbehind: true,
15696
+ inside: {
15697
+ 'attr-name': /^[^\s=]+/,
15698
+ 'attr-value': {
15699
+ pattern: /=[\s\S]+/,
15700
+ inside: {
15701
+ 'value': {
15702
+ pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
15703
+ lookbehind: true,
15704
+ alias: [lang, 'language-' + lang],
15705
+ inside: Prism.languages[lang]
15706
+ },
15707
+ 'punctuation': [
15708
+ {
15709
+ pattern: /^=/,
15710
+ alias: 'attr-equals'
15711
+ },
15712
+ /"|'/
15713
+ ]
15714
+ }
15715
+ }
15716
+ }
15717
+ });
15718
+ }
15719
+ });
15720
+
14820
15721
  Prism.languages.html = Prism.languages.markup;
14821
15722
  Prism.languages.mathml = Prism.languages.markup;
14822
15723
  Prism.languages.svg = Prism.languages.markup;
14823
15724
 
15725
+ Prism.languages.xml = Prism.languages.extend('markup', {});
15726
+ Prism.languages.ssml = Prism.languages.xml;
15727
+ Prism.languages.atom = Prism.languages.xml;
15728
+ Prism.languages.rss = Prism.languages.xml;
15729
+
14824
15730
 
14825
15731
  /* **********************************************
14826
15732
  Begin prism-css.js
14827
15733
  ********************************************** */
14828
15734
 
14829
- Prism.languages.css = {
14830
- 'comment': /\/\*[\w\W]*?\*\//,
14831
- 'atrule': {
14832
- pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i,
14833
- inside: {
14834
- 'rule': /@[\w-]+/
14835
- // See rest below
14836
- }
14837
- },
14838
- 'url': /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
14839
- 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/,
14840
- 'string': /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,
14841
- 'property': /(\b|\B)[\w-]+(?=\s*:)/i,
14842
- 'important': /\B!important\b/i,
14843
- 'function': /[-a-z0-9]+(?=\()/i,
14844
- 'punctuation': /[(){};:]/
14845
- };
15735
+ (function (Prism) {
14846
15736
 
14847
- Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css);
15737
+ var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
14848
15738
 
14849
- if (Prism.languages.markup) {
14850
- Prism.languages.insertBefore('markup', 'tag', {
14851
- 'style': {
14852
- pattern: /(<style[\w\W]*?>)[\w\W]*?(?=<\/style>)/i,
14853
- lookbehind: true,
14854
- inside: Prism.languages.css,
14855
- alias: 'language-css'
14856
- }
14857
- });
14858
-
14859
- Prism.languages.insertBefore('inside', 'attr-value', {
14860
- 'style-attr': {
14861
- pattern: /\s*style=("|').*?\1/i,
15739
+ Prism.languages.css = {
15740
+ 'comment': /\/\*[\s\S]*?\*\//,
15741
+ 'atrule': {
15742
+ pattern: /@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,
14862
15743
  inside: {
14863
- 'attr-name': {
14864
- pattern: /^\s*style/i,
14865
- inside: Prism.languages.markup.tag.inside
15744
+ 'rule': /^@[\w-]+/,
15745
+ 'selector-function-argument': {
15746
+ pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
15747
+ lookbehind: true,
15748
+ alias: 'selector'
14866
15749
  },
14867
- 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
14868
- 'attr-value': {
14869
- pattern: /.+/i,
14870
- inside: Prism.languages.css
15750
+ 'keyword': {
15751
+ pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
15752
+ lookbehind: true
14871
15753
  }
14872
- },
14873
- alias: 'language-css'
14874
- }
14875
- }, Prism.languages.markup.tag);
14876
- }
15754
+ // See rest below
15755
+ }
15756
+ },
15757
+ 'url': {
15758
+ // https://drafts.csswg.org/css-values-3/#urls
15759
+ pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
15760
+ greedy: true,
15761
+ inside: {
15762
+ 'function': /^url/i,
15763
+ 'punctuation': /^\(|\)$/,
15764
+ 'string': {
15765
+ pattern: RegExp('^' + string.source + '$'),
15766
+ alias: 'url'
15767
+ }
15768
+ }
15769
+ },
15770
+ 'selector': {
15771
+ pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
15772
+ lookbehind: true
15773
+ },
15774
+ 'string': {
15775
+ pattern: string,
15776
+ greedy: true
15777
+ },
15778
+ 'property': {
15779
+ pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
15780
+ lookbehind: true
15781
+ },
15782
+ 'important': /!important\b/i,
15783
+ 'function': {
15784
+ pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
15785
+ lookbehind: true
15786
+ },
15787
+ 'punctuation': /[(){};:,]/
15788
+ };
15789
+
15790
+ Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
15791
+
15792
+ var markup = Prism.languages.markup;
15793
+ if (markup) {
15794
+ markup.tag.addInlined('style', 'css');
15795
+ markup.tag.addAttribute('style', 'css');
15796
+ }
15797
+
15798
+ }(Prism));
15799
+
14877
15800
 
14878
15801
  /* **********************************************
14879
15802
  Begin prism-clike.js
@@ -14882,27 +15805,32 @@ if (Prism.languages.markup) {
14882
15805
  Prism.languages.clike = {
14883
15806
  'comment': [
14884
15807
  {
14885
- pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
14886
- lookbehind: true
15808
+ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
15809
+ lookbehind: true,
15810
+ greedy: true
14887
15811
  },
14888
15812
  {
14889
15813
  pattern: /(^|[^\\:])\/\/.*/,
14890
- lookbehind: true
15814
+ lookbehind: true,
15815
+ greedy: true
14891
15816
  }
14892
15817
  ],
14893
- 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
15818
+ 'string': {
15819
+ pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
15820
+ greedy: true
15821
+ },
14894
15822
  'class-name': {
14895
- pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
15823
+ pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,
14896
15824
  lookbehind: true,
14897
15825
  inside: {
14898
- punctuation: /(\.|\\)/
15826
+ 'punctuation': /[.\\]/
14899
15827
  }
14900
15828
  },
14901
- 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
14902
- 'boolean': /\b(true|false)\b/,
14903
- 'function': /[a-z0-9_]+(?=\()/i,
14904
- 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
14905
- 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
15829
+ 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
15830
+ 'boolean': /\b(?:true|false)\b/,
15831
+ 'function': /\b\w+(?=\()/,
15832
+ 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
15833
+ 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
14906
15834
  'punctuation': /[{}[\];(),.:]/
14907
15835
  };
14908
15836
 
@@ -14912,25 +15840,95 @@ Prism.languages.clike = {
14912
15840
  ********************************************** */
14913
15841
 
14914
15842
  Prism.languages.javascript = Prism.languages.extend('clike', {
14915
- 'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,
14916
- 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,
15843
+ 'class-name': [
15844
+ Prism.languages.clike['class-name'],
15845
+ {
15846
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,
15847
+ lookbehind: true
15848
+ }
15849
+ ],
15850
+ 'keyword': [
15851
+ {
15852
+ pattern: /((?:^|\})\s*)catch\b/,
15853
+ lookbehind: true
15854
+ },
15855
+ {
15856
+ pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
15857
+ lookbehind: true
15858
+ },
15859
+ ],
14917
15860
  // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
14918
- 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i
15861
+ 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
15862
+ 'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,
15863
+ 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
14919
15864
  });
14920
15865
 
15866
+ Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/;
15867
+
14921
15868
  Prism.languages.insertBefore('javascript', 'keyword', {
14922
15869
  'regex': {
14923
- pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
14924
- lookbehind: true
14925
- }
15870
+ // eslint-disable-next-line regexp/no-dupe-characters-character-class
15871
+ pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,
15872
+ lookbehind: true,
15873
+ greedy: true,
15874
+ inside: {
15875
+ 'regex-source': {
15876
+ pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
15877
+ lookbehind: true,
15878
+ alias: 'language-regex',
15879
+ inside: Prism.languages.regex
15880
+ },
15881
+ 'regex-delimiter': /^\/|\/$/,
15882
+ 'regex-flags': /^[a-z]+$/,
15883
+ }
15884
+ },
15885
+ // This must be declared before keyword because we use "function" inside the look-forward
15886
+ 'function-variable': {
15887
+ pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
15888
+ alias: 'function'
15889
+ },
15890
+ 'parameter': [
15891
+ {
15892
+ pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
15893
+ lookbehind: true,
15894
+ inside: Prism.languages.javascript
15895
+ },
15896
+ {
15897
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
15898
+ lookbehind: true,
15899
+ inside: Prism.languages.javascript
15900
+ },
15901
+ {
15902
+ pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
15903
+ lookbehind: true,
15904
+ inside: Prism.languages.javascript
15905
+ },
15906
+ {
15907
+ pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
15908
+ lookbehind: true,
15909
+ inside: Prism.languages.javascript
15910
+ }
15911
+ ],
15912
+ 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
14926
15913
  });
14927
15914
 
14928
- Prism.languages.insertBefore('javascript', 'class-name', {
15915
+ Prism.languages.insertBefore('javascript', 'string', {
15916
+ 'hashbang': {
15917
+ pattern: /^#!.*/,
15918
+ greedy: true,
15919
+ alias: 'comment'
15920
+ },
14929
15921
  'template-string': {
14930
- pattern: /`(?:\\`|\\?[^`])*`/,
15922
+ pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
15923
+ greedy: true,
14931
15924
  inside: {
15925
+ 'template-punctuation': {
15926
+ pattern: /^`|`$/,
15927
+ alias: 'string'
15928
+ },
14932
15929
  'interpolation': {
14933
- pattern: /\$\{[^}]+\}/,
15930
+ pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
15931
+ lookbehind: true,
14934
15932
  inside: {
14935
15933
  'interpolation-punctuation': {
14936
15934
  pattern: /^\$\{|\}$/,
@@ -14945,100 +15943,170 @@ Prism.languages.insertBefore('javascript', 'class-name', {
14945
15943
  });
14946
15944
 
14947
15945
  if (Prism.languages.markup) {
14948
- Prism.languages.insertBefore('markup', 'tag', {
14949
- 'script': {
14950
- pattern: /(<script[\w\W]*?>)[\w\W]*?(?=<\/script>)/i,
14951
- lookbehind: true,
14952
- inside: Prism.languages.javascript,
14953
- alias: 'language-javascript'
14954
- }
14955
- });
15946
+ Prism.languages.markup.tag.addInlined('script', 'javascript');
15947
+
15948
+ // add attribute support for all DOM events.
15949
+ // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
15950
+ Prism.languages.markup.tag.addAttribute(
15951
+ /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,
15952
+ 'javascript'
15953
+ );
14956
15954
  }
14957
15955
 
14958
15956
  Prism.languages.js = Prism.languages.javascript;
14959
15957
 
15958
+
14960
15959
  /* **********************************************
14961
15960
  Begin prism-file-highlight.js
14962
15961
  ********************************************** */
14963
15962
 
14964
15963
  (function () {
14965
- if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) {
15964
+
15965
+ if (typeof Prism === 'undefined' || typeof document === 'undefined') {
14966
15966
  return;
14967
15967
  }
14968
15968
 
14969
- self.Prism.fileHighlight = function() {
15969
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
15970
+ if (!Element.prototype.matches) {
15971
+ Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
15972
+ }
14970
15973
 
14971
- var Extensions = {
14972
- 'js': 'javascript',
14973
- 'html': 'markup',
14974
- 'svg': 'markup',
14975
- 'xml': 'markup',
14976
- 'py': 'python',
14977
- 'rb': 'ruby',
14978
- 'ps1': 'powershell',
14979
- 'psm1': 'powershell'
14980
- };
15974
+ var LOADING_MESSAGE = 'Loading…';
15975
+ var FAILURE_MESSAGE = function (status, message) {
15976
+ return '✖ Error ' + status + ' while fetching file: ' + message;
15977
+ };
15978
+ var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty';
15979
+
15980
+ var EXTENSIONS = {
15981
+ 'js': 'javascript',
15982
+ 'py': 'python',
15983
+ 'rb': 'ruby',
15984
+ 'ps1': 'powershell',
15985
+ 'psm1': 'powershell',
15986
+ 'sh': 'bash',
15987
+ 'bat': 'batch',
15988
+ 'h': 'c',
15989
+ 'tex': 'latex'
15990
+ };
14981
15991
 
14982
- if(Array.prototype.forEach) { // Check to prevent error in IE8
14983
- Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
14984
- var src = pre.getAttribute('data-src');
15992
+ var STATUS_ATTR = 'data-src-status';
15993
+ var STATUS_LOADING = 'loading';
15994
+ var STATUS_LOADED = 'loaded';
15995
+ var STATUS_FAILED = 'failed';
14985
15996
 
14986
- var language, parent = pre;
14987
- var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i;
14988
- while (parent && !lang.test(parent.className)) {
14989
- parent = parent.parentNode;
14990
- }
15997
+ var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
15998
+ + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])';
14991
15999
 
14992
- if (parent) {
14993
- language = (pre.className.match(lang) || [, ''])[1];
14994
- }
16000
+ var lang = /\blang(?:uage)?-([\w-]+)\b/i;
14995
16001
 
14996
- if (!language) {
14997
- var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
14998
- language = Extensions[extension] || extension;
14999
- }
16002
+ /**
16003
+ * Sets the Prism `language-xxxx` or `lang-xxxx` class to the given language.
16004
+ *
16005
+ * @param {HTMLElement} element
16006
+ * @param {string} language
16007
+ * @returns {void}
16008
+ */
16009
+ function setLanguageClass(element, language) {
16010
+ var className = element.className;
16011
+ className = className.replace(lang, ' ') + ' language-' + language;
16012
+ element.className = className.replace(/\s+/g, ' ').trim();
16013
+ }
15000
16014
 
15001
- var code = document.createElement('code');
15002
- code.className = 'language-' + language;
15003
16015
 
15004
- pre.textContent = '';
16016
+ Prism.hooks.add('before-highlightall', function (env) {
16017
+ env.selector += ', ' + SELECTOR;
16018
+ });
15005
16019
 
15006
- code.textContent = 'Loading…';
16020
+ Prism.hooks.add('before-sanity-check', function (env) {
16021
+ var pre = /** @type {HTMLPreElement} */ (env.element);
16022
+ if (pre.matches(SELECTOR)) {
16023
+ env.code = ''; // fast-path the whole thing and go to complete
15007
16024
 
15008
- pre.appendChild(code);
16025
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading
15009
16026
 
15010
- var xhr = new XMLHttpRequest();
16027
+ // add code element with loading message
16028
+ var code = pre.appendChild(document.createElement('CODE'));
16029
+ code.textContent = LOADING_MESSAGE;
15011
16030
 
15012
- xhr.open('GET', src, true);
16031
+ var src = pre.getAttribute('data-src');
15013
16032
 
15014
- xhr.onreadystatechange = function () {
15015
- if (xhr.readyState == 4) {
16033
+ var language = env.language;
16034
+ if (language === 'none') {
16035
+ // the language might be 'none' because there is no language set;
16036
+ // in this case, we want to use the extension as the language
16037
+ var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1];
16038
+ language = EXTENSIONS[extension] || extension;
16039
+ }
15016
16040
 
15017
- if (xhr.status < 400 && xhr.responseText) {
15018
- code.textContent = xhr.responseText;
16041
+ // set language classes
16042
+ setLanguageClass(code, language);
16043
+ setLanguageClass(pre, language);
15019
16044
 
15020
- Prism.highlightElement(code);
15021
- }
15022
- else if (xhr.status >= 400) {
15023
- code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
15024
- }
15025
- else {
15026
- code.textContent = '✖ Error: File does not exist or is empty';
16045
+ // preload the language
16046
+ var autoloader = Prism.plugins.autoloader;
16047
+ if (autoloader) {
16048
+ autoloader.loadLanguages(language);
16049
+ }
16050
+
16051
+ // load file
16052
+ var xhr = new XMLHttpRequest();
16053
+ xhr.open('GET', src, true);
16054
+ xhr.onreadystatechange = function () {
16055
+ if (xhr.readyState == 4) {
16056
+ if (xhr.status < 400 && xhr.responseText) {
16057
+ // mark as loaded
16058
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADED);
16059
+
16060
+ // highlight code
16061
+ code.textContent = xhr.responseText;
16062
+ Prism.highlightElement(code);
16063
+
16064
+ } else {
16065
+ // mark as failed
16066
+ pre.setAttribute(STATUS_ATTR, STATUS_FAILED);
16067
+
16068
+ if (xhr.status >= 400) {
16069
+ code.textContent = FAILURE_MESSAGE(xhr.status, xhr.statusText);
16070
+ } else {
16071
+ code.textContent = FAILURE_EMPTY_MESSAGE;
15027
16072
  }
15028
16073
  }
15029
- };
15030
-
15031
- xhr.send(null);
15032
- });
16074
+ }
16075
+ };
16076
+ xhr.send(null);
15033
16077
  }
16078
+ });
16079
+
16080
+ Prism.plugins.fileHighlight = {
16081
+ /**
16082
+ * Executes the File Highlight plugin for all matching `pre` elements under the given container.
16083
+ *
16084
+ * Note: Elements which are already loaded or currently loading will not be touched by this method.
16085
+ *
16086
+ * @param {ParentNode} [container=document]
16087
+ */
16088
+ highlight: function highlight(container) {
16089
+ var elements = (container || document).querySelectorAll(SELECTOR);
15034
16090
 
16091
+ for (var i = 0, element; (element = elements[i++]);) {
16092
+ Prism.highlightElement(element);
16093
+ }
16094
+ }
15035
16095
  };
15036
16096
 
15037
- document.addEventListener('DOMContentLoaded', self.Prism.fileHighlight);
16097
+ var logged = false;
16098
+ /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */
16099
+ Prism.fileHighlight = function () {
16100
+ if (!logged) {
16101
+ console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.');
16102
+ logged = true;
16103
+ }
16104
+ Prism.plugins.fileHighlight.highlight.apply(this, arguments);
16105
+ };
15038
16106
 
15039
- })();
16107
+ }());
15040
16108
 
15041
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
16109
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
15042
16110
  },{}],19:[function(require,module,exports){
15043
16111
  /**
15044
16112
  * selectize.js (v0.12.1)
@@ -18576,7 +19644,7 @@ Prism.languages.js = Prism.languages.javascript;
18576
19644
  * URI.js - Mutating URLs
18577
19645
  * IPv6 Support
18578
19646
  *
18579
- * Version: 1.17.1
19647
+ * Version: 1.19.6
18580
19648
  *
18581
19649
  * Author: Rodney Rehm
18582
19650
  * Web: http://medialize.github.io/URI.js/
@@ -18589,7 +19657,7 @@ Prism.languages.js = Prism.languages.javascript;
18589
19657
  (function (root, factory) {
18590
19658
  'use strict';
18591
19659
  // https://github.com/umdjs/umd/blob/master/returnExports.js
18592
- if (typeof exports === 'object') {
19660
+ if (typeof module === 'object' && module.exports) {
18593
19661
  // Node
18594
19662
  module.exports = factory();
18595
19663
  } else if (typeof define === 'function' && define.amd) {
@@ -18665,8 +19733,6 @@ Prism.languages.js = Prism.languages.javascript;
18665
19733
  while (segments.length < total) {
18666
19734
  segments.splice(pos, 0, '0000');
18667
19735
  }
18668
-
18669
- length = segments.length;
18670
19736
  }
18671
19737
 
18672
19738
  // strip leading zeros
@@ -18750,7 +19816,7 @@ Prism.languages.js = Prism.languages.javascript;
18750
19816
  if (root.IPv6 === this) {
18751
19817
  root.IPv6 = _IPv6;
18752
19818
  }
18753
-
19819
+
18754
19820
  return this;
18755
19821
  }
18756
19822
 
@@ -18765,7 +19831,7 @@ Prism.languages.js = Prism.languages.javascript;
18765
19831
  * URI.js - Mutating URLs
18766
19832
  * Second Level Domain (SLD) Support
18767
19833
  *
18768
- * Version: 1.17.1
19834
+ * Version: 1.19.6
18769
19835
  *
18770
19836
  * Author: Rodney Rehm
18771
19837
  * Web: http://medialize.github.io/URI.js/
@@ -18778,7 +19844,7 @@ Prism.languages.js = Prism.languages.javascript;
18778
19844
  (function (root, factory) {
18779
19845
  'use strict';
18780
19846
  // https://github.com/umdjs/umd/blob/master/returnExports.js
18781
- if (typeof exports === 'object') {
19847
+ if (typeof module === 'object' && module.exports) {
18782
19848
  // Node
18783
19849
  module.exports = factory();
18784
19850
  } else if (typeof define === 'function' && define.amd) {
@@ -18936,7 +20002,12 @@ Prism.languages.js = Prism.languages.javascript;
18936
20002
  'ye':' co com gov ltd me net org plc ',
18937
20003
  'yu':' ac co edu gov org ',
18938
20004
  'za':' ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ',
18939
- 'zm':' ac co com edu gov net org sch '
20005
+ 'zm':' ac co com edu gov net org sch ',
20006
+ // https://en.wikipedia.org/wiki/CentralNic#Second-level_domains
20007
+ 'com': 'ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ',
20008
+ 'net': 'gb jp se uk ',
20009
+ 'org': 'ae',
20010
+ 'de': 'com '
18940
20011
  },
18941
20012
  // gorhill 2013-10-25: Using indexOf() instead Regexp(). Significant boost
18942
20013
  // in both performance and memory footprint. No initialization required.
@@ -19006,7 +20077,7 @@ Prism.languages.js = Prism.languages.javascript;
19006
20077
  /*!
19007
20078
  * URI.js - Mutating URLs
19008
20079
  *
19009
- * Version: 1.17.1
20080
+ * Version: 1.19.6
19010
20081
  *
19011
20082
  * Author: Rodney Rehm
19012
20083
  * Web: http://medialize.github.io/URI.js/
@@ -19018,7 +20089,7 @@ Prism.languages.js = Prism.languages.javascript;
19018
20089
  (function (root, factory) {
19019
20090
  'use strict';
19020
20091
  // https://github.com/umdjs/umd/blob/master/returnExports.js
19021
- if (typeof exports === 'object') {
20092
+ if (typeof module === 'object' && module.exports) {
19022
20093
  // Node
19023
20094
  module.exports = factory(require('./punycode'), require('./IPv6'), require('./SecondLevelDomains'));
19024
20095
  } else if (typeof define === 'function' && define.amd) {
@@ -19066,6 +20137,12 @@ Prism.languages.js = Prism.languages.javascript;
19066
20137
  }
19067
20138
  }
19068
20139
 
20140
+ if (url === null) {
20141
+ if (_urlSupplied) {
20142
+ throw new TypeError('null is not a valid argument for URI');
20143
+ }
20144
+ }
20145
+
19069
20146
  this.href(url);
19070
20147
 
19071
20148
  // resolve to base according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor
@@ -19076,7 +20153,11 @@ Prism.languages.js = Prism.languages.javascript;
19076
20153
  return this;
19077
20154
  }
19078
20155
 
19079
- URI.version = '1.17.1';
20156
+ function isInteger(value) {
20157
+ return /^[0-9]+$/.test(value);
20158
+ }
20159
+
20160
+ URI.version = '1.19.6';
19080
20161
 
19081
20162
  var p = URI.prototype;
19082
20163
  var hasOwn = Object.prototype.hasOwnProperty;
@@ -19196,17 +20277,22 @@ Prism.languages.js = Prism.languages.javascript;
19196
20277
  query: null,
19197
20278
  fragment: null,
19198
20279
  // state
20280
+ preventInvalidHostname: URI.preventInvalidHostname,
19199
20281
  duplicateQueryParameters: URI.duplicateQueryParameters,
19200
20282
  escapeQuerySpace: URI.escapeQuerySpace
19201
20283
  };
19202
20284
  };
20285
+ // state: throw on invalid hostname
20286
+ // see https://github.com/medialize/URI.js/pull/345
20287
+ // and https://github.com/medialize/URI.js/issues/354
20288
+ URI.preventInvalidHostname = false;
19203
20289
  // state: allow duplicate query parameters (a=1&a=1)
19204
20290
  URI.duplicateQueryParameters = false;
19205
20291
  // state: replaces + with %20 (space in query strings)
19206
20292
  URI.escapeQuerySpace = true;
19207
20293
  // static properties
19208
20294
  URI.protocol_expression = /^[a-z][a-z0-9.+-]*$/i;
19209
- URI.idn_expression = /[^a-z0-9\.-]/i;
20295
+ URI.idn_expression = /[^a-z0-9\._-]/i;
19210
20296
  URI.punycode_expression = /(xn--)/i;
19211
20297
  // well, 333.444.555.666 matches, but it sure ain't no IPv4 - do we care?
19212
20298
  URI.ip4_expression = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
@@ -19225,7 +20311,9 @@ Prism.languages.js = Prism.languages.javascript;
19225
20311
  // everything up to the next whitespace
19226
20312
  end: /[\s\r\n]|$/,
19227
20313
  // trim trailing punctuation captured by end RegExp
19228
- trim: /[`!()\[\]{};:'".,<>?«»“”„‘’]+$/
20314
+ trim: /[`!()\[\]{};:'".,<>?«»“”„‘’]+$/,
20315
+ // balanced parens inclusion (), [], {}, <>
20316
+ parens: /(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g,
19229
20317
  };
19230
20318
  // http://www.iana.org/assignments/uri-schemes.html
19231
20319
  // http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports
@@ -19237,10 +20325,16 @@ Prism.languages.js = Prism.languages.javascript;
19237
20325
  ws: '80',
19238
20326
  wss: '443'
19239
20327
  };
20328
+ // list of protocols which always require a hostname
20329
+ URI.hostProtocols = [
20330
+ 'http',
20331
+ 'https'
20332
+ ];
20333
+
19240
20334
  // allowed hostname characters according to RFC 3986
19241
20335
  // ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded
19242
- // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . -
19243
- URI.invalid_hostname_characters = /[^a-zA-Z0-9\.-]/;
20336
+ // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . - _
20337
+ URI.invalid_hostname_characters = /[^a-zA-Z0-9\.\-:_]/;
19244
20338
  // map DOM Elements to their URI attribute
19245
20339
  URI.domAttributes = {
19246
20340
  'a': 'href',
@@ -19472,7 +20566,9 @@ Prism.languages.js = Prism.languages.javascript;
19472
20566
  URI.parse = function(string, parts) {
19473
20567
  var pos;
19474
20568
  if (!parts) {
19475
- parts = {};
20569
+ parts = {
20570
+ preventInvalidHostname: URI.preventInvalidHostname
20571
+ };
19476
20572
  }
19477
20573
  // [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment]
19478
20574
 
@@ -19506,7 +20602,7 @@ Prism.languages.js = Prism.languages.javascript;
19506
20602
  if (parts.protocol && !parts.protocol.match(URI.protocol_expression)) {
19507
20603
  // : may be within the path
19508
20604
  parts.protocol = undefined;
19509
- } else if (string.substring(pos + 1, pos + 3) === '//') {
20605
+ } else if (string.substring(pos + 1, pos + 3).replace(/\\/g, '/') === '//') {
19510
20606
  string = string.substring(pos + 3);
19511
20607
 
19512
20608
  // extract "user:pass@host:port"
@@ -19525,6 +20621,10 @@ Prism.languages.js = Prism.languages.javascript;
19525
20621
  return parts;
19526
20622
  };
19527
20623
  URI.parseHost = function(string, parts) {
20624
+ if (!string) {
20625
+ string = '';
20626
+ }
20627
+
19528
20628
  // Copy chrome, IE, opera backslash-handling behavior.
19529
20629
  // Back slashes before the query string get converted to forward slashes
19530
20630
  // See: https://github.com/joyent/node/blob/386fd24f49b0e9d1a8a076592a404168faeecc34/lib/url.js#L115-L124
@@ -19572,6 +20672,14 @@ Prism.languages.js = Prism.languages.javascript;
19572
20672
  string = '/' + string;
19573
20673
  }
19574
20674
 
20675
+ if (parts.preventInvalidHostname) {
20676
+ URI.ensureValidHostname(parts.hostname, parts.protocol);
20677
+ }
20678
+
20679
+ if (parts.port) {
20680
+ URI.ensureValidPort(parts.port);
20681
+ }
20682
+
19575
20683
  return string.substring(pos) || '/';
19576
20684
  };
19577
20685
  URI.parseAuthority = function(string, parts) {
@@ -19580,17 +20688,22 @@ Prism.languages.js = Prism.languages.javascript;
19580
20688
  };
19581
20689
  URI.parseUserinfo = function(string, parts) {
19582
20690
  // extract username:password
20691
+ var _string = string
20692
+ var firstBackSlash = string.indexOf('\\');
20693
+ if (firstBackSlash !== -1) {
20694
+ string = string.replace(/\\/g, '/')
20695
+ }
19583
20696
  var firstSlash = string.indexOf('/');
19584
20697
  var pos = string.lastIndexOf('@', firstSlash > -1 ? firstSlash : string.length - 1);
19585
20698
  var t;
19586
20699
 
19587
- // authority@ must come before /path
20700
+ // authority@ must come before /path or \path
19588
20701
  if (pos > -1 && (firstSlash === -1 || pos < firstSlash)) {
19589
20702
  t = string.substring(0, pos).split(':');
19590
20703
  parts.username = t[0] ? URI.decode(t[0]) : null;
19591
20704
  t.shift();
19592
20705
  parts.password = t[0] ? URI.decode(t.join(':')) : null;
19593
- string = string.substring(pos + 1);
20706
+ string = _string.substring(pos + 1);
19594
20707
  } else {
19595
20708
  parts.username = null;
19596
20709
  parts.password = null;
@@ -19637,6 +20750,7 @@ Prism.languages.js = Prism.languages.javascript;
19637
20750
 
19638
20751
  URI.build = function(parts) {
19639
20752
  var t = '';
20753
+ var requireAbsolutePath = false
19640
20754
 
19641
20755
  if (parts.protocol) {
19642
20756
  t += parts.protocol + ':';
@@ -19644,12 +20758,13 @@ Prism.languages.js = Prism.languages.javascript;
19644
20758
 
19645
20759
  if (!parts.urn && (t || parts.hostname)) {
19646
20760
  t += '//';
20761
+ requireAbsolutePath = true
19647
20762
  }
19648
20763
 
19649
20764
  t += (URI.buildAuthority(parts) || '');
19650
20765
 
19651
20766
  if (typeof parts.path === 'string') {
19652
- if (parts.path.charAt(0) !== '/' && typeof parts.hostname === 'string') {
20767
+ if (parts.path.charAt(0) !== '/' && requireAbsolutePath) {
19653
20768
  t += '/';
19654
20769
  }
19655
20770
 
@@ -19690,11 +20805,13 @@ Prism.languages.js = Prism.languages.javascript;
19690
20805
 
19691
20806
  if (parts.username) {
19692
20807
  t += URI.encode(parts.username);
20808
+ }
19693
20809
 
19694
- if (parts.password) {
19695
- t += ':' + URI.encode(parts.password);
19696
- }
20810
+ if (parts.password) {
20811
+ t += ':' + URI.encode(parts.password);
20812
+ }
19697
20813
 
20814
+ if (t) {
19698
20815
  t += '@';
19699
20816
  }
19700
20817
 
@@ -19710,7 +20827,7 @@ Prism.languages.js = Prism.languages.javascript;
19710
20827
  var t = '';
19711
20828
  var unique, key, i, length;
19712
20829
  for (key in data) {
19713
- if (hasOwn.call(data, key) && key) {
20830
+ if (hasOwn.call(data, key)) {
19714
20831
  if (isArray(data[key])) {
19715
20832
  unique = {};
19716
20833
  for (i = 0, length = data[key].length; i < length; i++) {
@@ -19759,6 +20876,21 @@ Prism.languages.js = Prism.languages.javascript;
19759
20876
  throw new TypeError('URI.addQuery() accepts an object, string as the name parameter');
19760
20877
  }
19761
20878
  };
20879
+
20880
+ URI.setQuery = function(data, name, value) {
20881
+ if (typeof name === 'object') {
20882
+ for (var key in name) {
20883
+ if (hasOwn.call(name, key)) {
20884
+ URI.setQuery(data, key, name[key]);
20885
+ }
20886
+ }
20887
+ } else if (typeof name === 'string') {
20888
+ data[name] = value === undefined ? null : value;
20889
+ } else {
20890
+ throw new TypeError('URI.setQuery() accepts an object, string as the name parameter');
20891
+ }
20892
+ };
20893
+
19762
20894
  URI.removeQuery = function(data, name, value) {
19763
20895
  var i, length, key;
19764
20896
 
@@ -19883,6 +21015,39 @@ Prism.languages.js = Prism.languages.javascript;
19883
21015
  };
19884
21016
 
19885
21017
 
21018
+ URI.joinPaths = function() {
21019
+ var input = [];
21020
+ var segments = [];
21021
+ var nonEmptySegments = 0;
21022
+
21023
+ for (var i = 0; i < arguments.length; i++) {
21024
+ var url = new URI(arguments[i]);
21025
+ input.push(url);
21026
+ var _segments = url.segment();
21027
+ for (var s = 0; s < _segments.length; s++) {
21028
+ if (typeof _segments[s] === 'string') {
21029
+ segments.push(_segments[s]);
21030
+ }
21031
+
21032
+ if (_segments[s]) {
21033
+ nonEmptySegments++;
21034
+ }
21035
+ }
21036
+ }
21037
+
21038
+ if (!segments.length || !nonEmptySegments) {
21039
+ return new URI('');
21040
+ }
21041
+
21042
+ var uri = new URI('').segment(segments);
21043
+
21044
+ if (input[0].path() === '' || input[0].path().slice(0, 1) === '/') {
21045
+ uri.path('/' + uri.path());
21046
+ }
21047
+
21048
+ return uri.normalize();
21049
+ };
21050
+
19886
21051
  URI.commonPath = function(one, two) {
19887
21052
  var length = Math.min(one.length, two.length);
19888
21053
  var pos;
@@ -19912,6 +21077,7 @@ Prism.languages.js = Prism.languages.javascript;
19912
21077
  var _start = options.start || URI.findUri.start;
19913
21078
  var _end = options.end || URI.findUri.end;
19914
21079
  var _trim = options.trim || URI.findUri.trim;
21080
+ var _parens = options.parens || URI.findUri.parens;
19915
21081
  var _attributeOpen = /[a-z0-9-]=["']?$/i;
19916
21082
 
19917
21083
  _start.lastIndex = 0;
@@ -19931,13 +21097,43 @@ Prism.languages.js = Prism.languages.javascript;
19931
21097
  }
19932
21098
 
19933
21099
  var end = start + string.slice(start).search(_end);
19934
- var slice = string.slice(start, end).replace(_trim, '');
21100
+ var slice = string.slice(start, end);
21101
+ // make sure we include well balanced parens
21102
+ var parensEnd = -1;
21103
+ while (true) {
21104
+ var parensMatch = _parens.exec(slice);
21105
+ if (!parensMatch) {
21106
+ break;
21107
+ }
21108
+
21109
+ var parensMatchEnd = parensMatch.index + parensMatch[0].length;
21110
+ parensEnd = Math.max(parensEnd, parensMatchEnd);
21111
+ }
21112
+
21113
+ if (parensEnd > -1) {
21114
+ slice = slice.slice(0, parensEnd) + slice.slice(parensEnd).replace(_trim, '');
21115
+ } else {
21116
+ slice = slice.replace(_trim, '');
21117
+ }
21118
+
21119
+ if (slice.length <= match[0].length) {
21120
+ // the extract only contains the starting marker of a URI,
21121
+ // e.g. "www" or "http://"
21122
+ continue;
21123
+ }
21124
+
19935
21125
  if (options.ignore && options.ignore.test(slice)) {
19936
21126
  continue;
19937
21127
  }
19938
21128
 
19939
21129
  end = start + slice.length;
19940
21130
  var result = callback(slice, start, end, string);
21131
+ if (result === undefined) {
21132
+ _start.lastIndex = end;
21133
+ continue;
21134
+ }
21135
+
21136
+ result = String(result);
19941
21137
  string = string.slice(0, start) + result + string.slice(end);
19942
21138
  _start.lastIndex = start + result.length;
19943
21139
  }
@@ -19946,22 +21142,44 @@ Prism.languages.js = Prism.languages.javascript;
19946
21142
  return string;
19947
21143
  };
19948
21144
 
19949
- URI.ensureValidHostname = function(v) {
21145
+ URI.ensureValidHostname = function(v, protocol) {
19950
21146
  // Theoretically URIs allow percent-encoding in Hostnames (according to RFC 3986)
19951
21147
  // they are not part of DNS and therefore ignored by URI.js
19952
21148
 
19953
- if (v.match(URI.invalid_hostname_characters)) {
21149
+ var hasHostname = !!v; // not null and not an empty string
21150
+ var hasProtocol = !!protocol;
21151
+ var rejectEmptyHostname = false;
21152
+
21153
+ if (hasProtocol) {
21154
+ rejectEmptyHostname = arrayContains(URI.hostProtocols, protocol);
21155
+ }
21156
+
21157
+ if (rejectEmptyHostname && !hasHostname) {
21158
+ throw new TypeError('Hostname cannot be empty, if protocol is ' + protocol);
21159
+ } else if (v && v.match(URI.invalid_hostname_characters)) {
19954
21160
  // test punycode
19955
21161
  if (!punycode) {
19956
- throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-] and Punycode.js is not available');
21162
+ throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available');
19957
21163
  }
19958
-
19959
21164
  if (punycode.toASCII(v).match(URI.invalid_hostname_characters)) {
19960
- throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
21165
+ throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_]');
19961
21166
  }
19962
21167
  }
19963
21168
  };
19964
21169
 
21170
+ URI.ensureValidPort = function (v) {
21171
+ if (!v) {
21172
+ return;
21173
+ }
21174
+
21175
+ var port = Number(v);
21176
+ if (isInteger(port) && (port > 0) && (port < 65536)) {
21177
+ return;
21178
+ }
21179
+
21180
+ throw new TypeError('Port "' + v + '" is not a valid port');
21181
+ };
21182
+
19965
21183
  // noConflict
19966
21184
  URI.noConflict = function(removeAll) {
19967
21185
  if (removeAll) {
@@ -20106,10 +21324,14 @@ Prism.languages.js = Prism.languages.javascript;
20106
21324
  } else if (_URI || _object) {
20107
21325
  var src = _URI ? href._parts : href;
20108
21326
  for (key in src) {
21327
+ if (key === 'query') { continue; }
20109
21328
  if (hasOwn.call(this._parts, key)) {
20110
21329
  this._parts[key] = src[key];
20111
21330
  }
20112
21331
  }
21332
+ if (src.query) {
21333
+ this.query(src.query, false);
21334
+ }
20113
21335
  } else {
20114
21336
  throw new TypeError('invalid input');
20115
21337
  }
@@ -20190,16 +21412,15 @@ Prism.languages.js = Prism.languages.javascript;
20190
21412
  var _hostname = p.hostname;
20191
21413
 
20192
21414
  p.protocol = function(v, build) {
20193
- if (v !== undefined) {
20194
- if (v) {
20195
- // accept trailing ://
20196
- v = v.replace(/:(\/\/)?$/, '');
21415
+ if (v) {
21416
+ // accept trailing ://
21417
+ v = v.replace(/:(\/\/)?$/, '');
20197
21418
 
20198
- if (!v.match(URI.protocol_expression)) {
20199
- throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
20200
- }
21419
+ if (!v.match(URI.protocol_expression)) {
21420
+ throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
20201
21421
  }
20202
21422
  }
21423
+
20203
21424
  return _protocol.call(this, v, build);
20204
21425
  };
20205
21426
  p.scheme = p.protocol;
@@ -20219,9 +21440,7 @@ Prism.languages.js = Prism.languages.javascript;
20219
21440
  v = v.substring(1);
20220
21441
  }
20221
21442
 
20222
- if (v.match(/[^0-9]/)) {
20223
- throw new TypeError('Port "' + v + '" contains characters other than [0-9]');
20224
- }
21443
+ URI.ensureValidPort(v);
20225
21444
  }
20226
21445
  }
20227
21446
  return _port.call(this, v, build);
@@ -20232,14 +21451,18 @@ Prism.languages.js = Prism.languages.javascript;
20232
21451
  }
20233
21452
 
20234
21453
  if (v !== undefined) {
20235
- var x = {};
21454
+ var x = { preventInvalidHostname: this._parts.preventInvalidHostname };
20236
21455
  var res = URI.parseHost(v, x);
20237
21456
  if (res !== '/') {
20238
21457
  throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
20239
21458
  }
20240
21459
 
20241
21460
  v = x.hostname;
21461
+ if (this._parts.preventInvalidHostname) {
21462
+ URI.ensureValidHostname(v, this._parts.protocol);
21463
+ }
20242
21464
  }
21465
+
20243
21466
  return _hostname.call(this, v, build);
20244
21467
  };
20245
21468
 
@@ -20306,12 +21529,8 @@ Prism.languages.js = Prism.languages.javascript;
20306
21529
  }
20307
21530
 
20308
21531
  if (v === undefined) {
20309
- if (!this._parts.username) {
20310
- return '';
20311
- }
20312
-
20313
21532
  var t = URI.buildUserinfo(this._parts);
20314
- return t.substring(0, t.length -1);
21533
+ return t ? t.substring(0, t.length -1) : t;
20315
21534
  } else {
20316
21535
  if (v[v.length-1] !== '@') {
20317
21536
  v += '@';
@@ -20361,8 +21580,12 @@ Prism.languages.js = Prism.languages.javascript;
20361
21580
  v += '.';
20362
21581
  }
20363
21582
 
21583
+ if (v.indexOf(':') !== -1) {
21584
+ throw new TypeError('Domains cannot contain colons');
21585
+ }
21586
+
20364
21587
  if (v) {
20365
- URI.ensureValidHostname(v);
21588
+ URI.ensureValidHostname(v, this._parts.protocol);
20366
21589
  }
20367
21590
 
20368
21591
  this._parts.hostname = this._parts.hostname.replace(replace, v);
@@ -20401,7 +21624,11 @@ Prism.languages.js = Prism.languages.javascript;
20401
21624
  throw new TypeError('cannot set domain empty');
20402
21625
  }
20403
21626
 
20404
- URI.ensureValidHostname(v);
21627
+ if (v.indexOf(':') !== -1) {
21628
+ throw new TypeError('Domains cannot contain colons');
21629
+ }
21630
+
21631
+ URI.ensureValidHostname(v, this._parts.protocol);
20405
21632
 
20406
21633
  if (!this._parts.hostname || this.is('IP')) {
20407
21634
  this._parts.hostname = v;
@@ -20512,7 +21739,7 @@ Prism.languages.js = Prism.languages.javascript;
20512
21739
  return v === undefined ? '' : this;
20513
21740
  }
20514
21741
 
20515
- if (v === undefined || v === true) {
21742
+ if (typeof v !== 'string') {
20516
21743
  if (!this._parts.path || this._parts.path === '/') {
20517
21744
  return '';
20518
21745
  }
@@ -21012,7 +22239,10 @@ Prism.languages.js = Prism.languages.javascript;
21012
22239
  base = new URI(base);
21013
22240
  }
21014
22241
 
21015
- if (!resolved._parts.protocol) {
22242
+ if (resolved._parts.protocol) {
22243
+ // Directly returns even if this._parts.hostname is empty.
22244
+ return resolved;
22245
+ } else {
21016
22246
  resolved._parts.protocol = base._parts.protocol;
21017
22247
  }
21018
22248
 
@@ -21029,15 +22259,17 @@ Prism.languages.js = Prism.languages.javascript;
21029
22259
  if (!resolved._parts.query) {
21030
22260
  resolved._parts.query = base._parts.query;
21031
22261
  }
21032
- } else if (resolved._parts.path.substring(-2) === '..') {
21033
- resolved._parts.path += '/';
21034
- }
22262
+ } else {
22263
+ if (resolved._parts.path.substring(-2) === '..') {
22264
+ resolved._parts.path += '/';
22265
+ }
21035
22266
 
21036
- if (resolved.path().charAt(0) !== '/') {
21037
- basedir = base.directory();
21038
- basedir = basedir ? basedir : base.path().indexOf('/') === 0 ? '/' : '';
21039
- resolved._parts.path = (basedir ? (basedir + '/') : '') + resolved._parts.path;
21040
- resolved.normalizePath();
22267
+ if (resolved.path().charAt(0) !== '/') {
22268
+ basedir = base.directory();
22269
+ basedir = basedir ? basedir : base.path().indexOf('/') === 0 ? '/' : '';
22270
+ resolved._parts.path = (basedir ? (basedir + '/') : '') + resolved._parts.path;
22271
+ resolved.normalizePath();
22272
+ }
21041
22273
  }
21042
22274
 
21043
22275
  resolved.build();
@@ -21170,6 +22402,11 @@ Prism.languages.js = Prism.languages.javascript;
21170
22402
  };
21171
22403
 
21172
22404
  // state
22405
+ p.preventInvalidHostname = function(v) {
22406
+ this._parts.preventInvalidHostname = !!v;
22407
+ return this;
22408
+ };
22409
+
21173
22410
  p.duplicateQueryParameters = function(v) {
21174
22411
  this._parts.duplicateQueryParameters = !!v;
21175
22412
  return this;
@@ -21184,7 +22421,7 @@ Prism.languages.js = Prism.languages.javascript;
21184
22421
  }));
21185
22422
 
21186
22423
  },{"./IPv6":21,"./SecondLevelDomains":22,"./punycode":24}],24:[function(require,module,exports){
21187
- (function (global){
22424
+ (function (global){(function (){
21188
22425
  /*! https://mths.be/punycode v1.4.0 by @mathias */
21189
22426
  ;(function(root) {
21190
22427
 
@@ -21719,5 +22956,5 @@ Prism.languages.js = Prism.languages.javascript;
21719
22956
 
21720
22957
  }(this));
21721
22958
 
21722
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
22959
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
21723
22960
  },{}]},{},[1]);